summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Documentation/networking/00-INDEX4
-rw-r--r--Documentation/networking/DLINK.txt203
-rw-r--r--Documentation/networking/depca.txt92
-rw-r--r--Documentation/networking/ewrk3.txt46
-rw-r--r--MAINTAINERS12
-rw-r--r--drivers/net/Space.c75
-rw-r--r--drivers/net/ethernet/3com/3c501.c897
-rw-r--r--drivers/net/ethernet/3com/3c501.h91
-rw-r--r--drivers/net/ethernet/3com/Kconfig14
-rw-r--r--drivers/net/ethernet/3com/Makefile1
-rw-r--r--drivers/net/ethernet/8390/3c503.c778
-rw-r--r--drivers/net/ethernet/8390/3c503.h91
-rw-r--r--drivers/net/ethernet/8390/Kconfig48
-rw-r--r--drivers/net/ethernet/8390/Makefile4
-rw-r--r--drivers/net/ethernet/8390/e2100.c489
-rw-r--r--drivers/net/ethernet/8390/hp-plus.c505
-rw-r--r--drivers/net/ethernet/8390/hp.c438
-rw-r--r--drivers/net/ethernet/Kconfig1
-rw-r--r--drivers/net/ethernet/Makefile1
-rw-r--r--drivers/net/ethernet/amd/Kconfig13
-rw-r--r--drivers/net/ethernet/amd/Makefile1
-rw-r--r--drivers/net/ethernet/amd/depca.c1910
-rw-r--r--drivers/net/ethernet/amd/depca.h183
-rw-r--r--drivers/net/ethernet/dec/Kconfig16
-rw-r--r--drivers/net/ethernet/dec/Makefile1
-rw-r--r--drivers/net/ethernet/dec/ewrk3.c1961
-rw-r--r--drivers/net/ethernet/dec/ewrk3.h322
-rw-r--r--drivers/net/ethernet/dlink/Kconfig32
-rw-r--r--drivers/net/ethernet/dlink/Makefile2
-rw-r--r--drivers/net/ethernet/dlink/de600.c529
-rw-r--r--drivers/net/ethernet/dlink/de600.h168
-rw-r--r--drivers/net/ethernet/dlink/de620.c987
-rw-r--r--drivers/net/ethernet/dlink/de620.h117
-rw-r--r--drivers/net/ethernet/fujitsu/Kconfig23
-rw-r--r--drivers/net/ethernet/fujitsu/Makefile2
-rw-r--r--drivers/net/ethernet/fujitsu/at1700.c791
-rw-r--r--drivers/net/ethernet/fujitsu/eth16i.c1483
-rw-r--r--drivers/net/ethernet/i825xx/3c505.c1672
-rw-r--r--drivers/net/ethernet/i825xx/3c505.h292
-rw-r--r--drivers/net/ethernet/i825xx/3c507.c939
-rw-r--r--drivers/net/ethernet/i825xx/82596.c94
-rw-r--r--drivers/net/ethernet/i825xx/Kconfig90
-rw-r--r--drivers/net/ethernet/i825xx/Makefile8
-rw-r--r--drivers/net/ethernet/i825xx/eepro.c1822
-rw-r--r--drivers/net/ethernet/i825xx/eexpress.c1661
-rw-r--r--drivers/net/ethernet/i825xx/eexpress.h179
-rw-r--r--drivers/net/ethernet/i825xx/lp486e.c1337
-rw-r--r--drivers/net/ethernet/i825xx/ni52.c1346
-rw-r--r--drivers/net/ethernet/i825xx/ni52.h310
-rw-r--r--drivers/net/ethernet/i825xx/znet.c928
-rw-r--r--drivers/net/ethernet/racal/Kconfig33
-rw-r--r--drivers/net/ethernet/racal/Makefile5
-rw-r--r--drivers/net/ethernet/racal/ni5010.c771
-rw-r--r--drivers/net/ethernet/racal/ni5010.h144
-rw-r--r--drivers/net/ethernet/seeq/Kconfig11
-rw-r--r--drivers/net/ethernet/seeq/Makefile1
-rw-r--r--drivers/net/ethernet/seeq/seeq8005.c749
-rw-r--r--drivers/net/ethernet/seeq/seeq8005.h156
58 files changed, 11 insertions, 24868 deletions
diff --git a/Documentation/networking/00-INDEX b/Documentation/networking/00-INDEX
index 1abfff26f8a..258d9b92c36 100644
--- a/Documentation/networking/00-INDEX
+++ b/Documentation/networking/00-INDEX
@@ -52,8 +52,6 @@ de4x5.txt
- the Digital EtherWORKS DE4?? and DE5?? PCI Ethernet driver
decnet.txt
- info on using the DECnet networking layer in Linux.
-depca.txt
- - the Digital DEPCA/EtherWORKS DE1?? and DE2?? LANCE Ethernet driver
dl2k.txt
- README for D-Link DL2000-based Gigabit Ethernet Adapters (dl2k.ko).
dm9000.txt
@@ -72,8 +70,6 @@ e1000e.txt
- README for the Intel Gigabit Ethernet Driver (e1000e).
eql.txt
- serial IP load balancing
-ewrk3.txt
- - the Digital EtherWORKS 3 DE203/4/5 Ethernet driver
fib_trie.txt
- Level Compressed Trie (LC-trie) notes: a structure for routing.
filter.txt
diff --git a/Documentation/networking/DLINK.txt b/Documentation/networking/DLINK.txt
deleted file mode 100644
index 55d24433d15..00000000000
--- a/Documentation/networking/DLINK.txt
+++ /dev/null
@@ -1,203 +0,0 @@
-Released 1994-06-13
-
-
- CONTENTS:
-
- 1. Introduction.
- 2. License.
- 3. Files in this release.
- 4. Installation.
- 5. Problems and tuning.
- 6. Using the drivers with earlier releases.
- 7. Acknowledgments.
-
-
- 1. INTRODUCTION.
-
- This is a set of Ethernet drivers for the D-Link DE-600/DE-620
- pocket adapters, for the parallel port on a Linux based machine.
- Some adapter "clones" will also work. Xircom is _not_ a clone...
- These drivers _can_ be used as loadable modules,
- and were developed for use on Linux 1.1.13 and above.
- For use on Linux 1.0.X, or earlier releases, see below.
-
- I have used these drivers for NFS, ftp, telnet and X-clients on
- remote machines. Transmissions with ftp seems to work as
- good as can be expected (i.e. > 80k bytes/sec) from a
- parallel port...:-) Receive speeds will be about 60-80% of this.
- Depending on your machine, somewhat higher speeds can be achieved.
-
- All comments/fixes to Bjorn Ekwall (bj0rn@blox.se).
-
-
- 2. LICENSE.
-
- This program is free software; you can redistribute it
- and/or modify it under the terms of the GNU General Public
- License as published by the Free Software Foundation; either
- version 2, or (at your option) any later version.
-
- This program is distributed in the hope that it will be
- useful, but WITHOUT ANY WARRANTY; without even the implied
- warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
- PURPOSE. See the GNU General Public License for more
- details.
-
- You should have received a copy of the GNU General Public
- License along with this program; if not, write to the Free
- Software Foundation, Inc., 675 Mass Ave, Cambridge, MA
- 02139, USA.
-
-
- 3. FILES IN THIS RELEASE.
-
- README.DLINK This file.
- de600.c The Source (may it be with You :-) for the DE-600
- de620.c ditto for the DE-620
- de620.h Macros for de620.c
-
- If you are upgrading from the d-link tar release, there will
- also be a "dlink-patches" file that will patch Linux 1.1.18:
- linux/drivers/net/Makefile
- linux/drivers/net/CONFIG
- linux/drivers/net/MODULES
- linux/drivers/net/Space.c
- linux/config.in
- Apply the patch by:
- "cd /usr/src; patch -p0 < linux/drivers/net/dlink-patches"
- The old source, "linux/drivers/net/d_link.c", can be removed.
-
-
- 4. INSTALLATION.
-
- o Get the latest net binaries, according to current net.wisdom.
-
- o Read the NET-2 and Ethernet HOWTOs and modify your setup.
-
- o If your parallel port has a strange address or irq,
- modify "linux/drivers/net/CONFIG" accordingly, or adjust
- the parameters in the "tuning" section in the sources.
-
- If you are going to use the drivers as loadable modules, do _not_
- enable them while doing "make config", but instead make sure that
- the drivers are included in "linux/drivers/net/MODULES".
-
- If you are _not_ going to use the driver(s) as loadable modules,
- but instead have them included in the kernel, remember to enable
- the drivers while doing "make config".
-
- o To include networking and DE600/DE620 support in your kernel:
- # cd /linux
- (as modules:)
- # make config (answer yes on CONFIG_NET and CONFIG_INET)
- (else included in the kernel:)
- # make config (answer yes on CONFIG _NET, _INET and _DE600 or _DE620)
- # make clean
- # make zImage (or whatever magic you usually do)
-
- o I use lilo to boot multiple kernels, so that I at least
- can have one working kernel :-). If you do too, append
- these lines to /etc/lilo/config:
-
- image = /linux/zImage
- label = newlinux
- root = /dev/hda2 (or whatever YOU have...)
-
- # /etc/lilo/install
-
- o Do "sync" and reboot the new kernel with a D-Link
- DE-600/DE-620 pocket adapter connected.
-
- o The adapter can be configured with ifconfig eth?
- where the actual number is decided by the kernel
- when the drivers are initialized.
-
-
- 5. "PROBLEMS" AND TUNING,
-
- o If you see error messages from the driver, and if the traffic
- stops on the adapter, try to do "ifconfig" and "route" once
- more, just as in "rc.inet1". This should take care of most
- problems, including effects from power loss, or adapters that
- aren't connected to the printer port in some way or another.
- You can somewhat change the behaviour by enabling/disabling
- the macro SHUTDOWN_WHEN_LOST in the "tuning" section.
- For the DE-600 there is another macro, CHECK_LOST_DE600,
- that you might want to read about in the "tuning" section.
-
- o Some machines have trouble handling the parallel port and
- the adapter at high speed. If you experience problems:
-
- DE-600:
- - The adapter is not recognized at boot, i.e. an Ethernet
- address of 00:80:c8:... is not shown, try to add another
- "; SLOW_DOWN_IO"
- at DE600_SLOW_DOWN in the "tuning" section. As a last resort,
- uncomment: "#define REALLY_SLOW_IO" (see <asm/io.h> for hints).
-
- - You experience "timeout" messages: first try to add another
- "; SLOW_DOWN_IO"
- at DE600_SLOW_DOWN in the "tuning" section, _then_ try to
- increase the value (original value: 5) at
- "if (tickssofar < 5)" near line 422.
-
- DE-620:
- - Your parallel port might be "sluggish". To cater for
- this, there are the macros LOWSPEED and READ_DELAY/WRITE_DELAY
- in the "tuning" section. Your first step should be to enable
- LOWSPEED, and after that you can "tune" the XXX_DELAY values.
-
- o If the adapter _is_ recognized at boot but you get messages
- about "Network Unreachable", then the problem is probably
- _not_ with the driver. Check your net configuration instead
- (ifconfig and route) in "rc.inet1".
-
- o There is some rudimentary support for debugging, look at
- the source. Use "-DDE600_DEBUG=3" or "-DDE620_DEBUG=3"
- when compiling, or include it in "linux/drivers/net/CONFIG".
- IF YOU HAVE PROBLEMS YOU CAN'T SOLVE: PLEASE COMPILE THE DRIVER
- WITH DEBUGGING ENABLED, AND SEND ME THE RESULTING OUTPUT!
-
-
- 6. USING THE DRIVERS WITH EARLIER RELEASES.
-
- The later 1.1.X releases of the Linux kernel include some
- changes in the networking layer (a.k.a. NET3). This affects
- these drivers in a few places. The hints that follow are
- _not_ tested by me, since I don't have the disk space to keep
- all releases on-line.
- Known needed changes to date:
- - release patchfile: some patches will fail, but they should
- be easy to apply "by hand", since they are trivial.
- (Space.c: d_link_init() is now called de600_probe())
- - de600.c: change "mark_bh(NET_BH)" to "mark_bh(INET_BH)".
- - de620.c: (maybe) change the code around "netif_rx(skb);" to be
- similar to the code around "dev_rint(...)" in de600.c
-
-
- 7. ACKNOWLEDGMENTS.
-
- These drivers wouldn't have been done without the base
- (and support) from Ross Biro, and D-Link Systems Inc.
- The driver relies upon GPL-ed source from D-Link Systems Inc.
- and from Russel Nelson at Crynwr Software <nelson@crynwr.com>.
-
- Additional input also from:
- Donald Becker <becker@super.org>, Alan Cox <A.Cox@swansea.ac.uk>
- and Fred N. van Kempen <waltje@uWalt.NL.Mugnet.ORG>
-
- DE-600 alpha release primary victim^H^H^H^H^H^Htester:
- - Erik Proper <erikp@cs.kun.nl>.
- Good input also from several users, most notably
- - Mark Burton <markb@ordern.demon.co.uk>.
-
- DE-620 alpha release victims^H^H^H^H^H^H^Htesters:
- - J. Joshua Kopper <kopper@rtsg.mot.com>
- - Olav Kvittem <Olav.Kvittem@uninett.no>
- - Germano Caronni <caronni@nessie.cs.id.ethz.ch>
- - Jeremy Fitzhardinge <jeremy@suite.sw.oz.au>
-
-
- Happy hacking!
-
- Bjorn Ekwall == bj0rn@blox.se
diff --git a/Documentation/networking/depca.txt b/Documentation/networking/depca.txt
deleted file mode 100644
index 24c6b26e565..00000000000
--- a/Documentation/networking/depca.txt
+++ /dev/null
@@ -1,92 +0,0 @@
-
-DE10x
-=====
-
-Memory Addresses:
-
- SW1 SW2 SW3 SW4
-64K on on on on d0000 dbfff
- off on on on c0000 cbfff
- off off on on e0000 ebfff
-
-32K on on off on d8000 dbfff
- off on off on c8000 cbfff
- off off off on e8000 ebfff
-
-DBR ROM on on dc000 dffff
- off on cc000 cffff
- off off ec000 effff
-
-Note that the 2K mode is set by SW3/SW4 on/off or off/off. Address
-assignment is through the RBSA register.
-
-I/O Address:
- SW5
-0x300 on
-0x200 off
-
-Remote Boot:
- SW6
-Disable on
-Enable off
-
-Remote Boot Timeout:
- SW7
-2.5min on
-30s off
-
-IRQ:
- SW8 SW9 SW10 SW11 SW12
-2 on off off off off
-3 off on off off off
-4 off off on off off
-5 off off off on off
-7 off off off off on
-
-DE20x
-=====
-
-Memory Size:
-
- SW3 SW4
-64K on on
-32K off on
-2K on off
-2K off off
-
-Start Addresses:
-
- SW1 SW2 SW3 SW4
-64K on on on on c0000 cffff
- on off on on d0000 dffff
- off on on on e0000 effff
-
-32K on on off off c8000 cffff
- on off off off d8000 dffff
- off on off off e8000 effff
-
-Illegal off off - - - -
-
-I/O Address:
- SW5
-0x300 on
-0x200 off
-
-Remote Boot:
- SW6
-Disable on
-Enable off
-
-Remote Boot Timeout:
- SW7
-2.5min on
-30s off
-
-IRQ:
- SW8 SW9 SW10 SW11 SW12
-5 on off off off off
-9 off on off off off
-10 off off on off off
-11 off off off on off
-15 off off off off on
-
diff --git a/Documentation/networking/ewrk3.txt b/Documentation/networking/ewrk3.txt
deleted file mode 100644
index 90e9e5f16e6..00000000000
--- a/Documentation/networking/ewrk3.txt
+++ /dev/null
@@ -1,46 +0,0 @@
-The EtherWORKS 3 driver in this distribution is designed to work with all
-kernels > 1.1.33 (approx) and includes tools in the 'ewrk3tools'
-subdirectory to allow set up of the card, similar to the MSDOS
-'NICSETUP.EXE' tools provided on the DOS drivers disk (type 'make' in that
-subdirectory to make the tools).
-
-The supported cards are DE203, DE204 and DE205. All other cards are NOT
-supported - refer to 'depca.c' for running the LANCE based network cards and
-'de4x5.c' for the DIGITAL Semiconductor PCI chip based adapters from
-Digital.
-
-The ability to load this driver as a loadable module has been included and
-used extensively during the driver development (to save those long reboot
-sequences). To utilise this ability, you have to do 8 things:
-
- 0) have a copy of the loadable modules code installed on your system.
- 1) copy ewrk3.c from the /linux/drivers/net directory to your favourite
- temporary directory.
- 2) edit the source code near line 1898 to reflect the I/O address and
- IRQ you're using.
- 3) compile ewrk3.c, but include -DMODULE in the command line to ensure
- that the correct bits are compiled (see end of source code).
- 4) if you are wanting to add a new card, goto 5. Otherwise, recompile a
- kernel with the ewrk3 configuration turned off and reboot.
- 5) insmod ewrk3.o
- [Alan Cox: Changed this so you can insmod ewrk3.o irq=x io=y]
- [Adam Kropelin: Multiple cards now supported by irq=x1,x2 io=y1,y2]
- 6) run the net startup bits for your new eth?? interface manually
- (usually /etc/rc.inet[12] at boot time).
- 7) enjoy!
-
- Note that autoprobing is not allowed in loadable modules - the system is
- already up and running and you're messing with interrupts.
-
- To unload a module, turn off the associated interface
- 'ifconfig eth?? down' then 'rmmod ewrk3'.
-
-The performance we've achieved so far has been measured through the 'ttcp'
-tool at 975kB/s. This measures the total TCP stack performance which
-includes the card, so don't expect to get much nearer the 1.25MB/s
-theoretical Ethernet rate.
-
-
-Enjoy!
-
-Dave
diff --git a/MAINTAINERS b/MAINTAINERS
index cd5b31fec01..a7aadea909d 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -2974,11 +2974,6 @@ S: Maintained
F: include/linux/netfilter_bridge/
F: net/bridge/
-ETHERTEAM 16I DRIVER
-M: Mika Kuoppala <miku@iki.fi>
-S: Maintained
-F: drivers/net/ethernet/fujitsu/eth16i.c
-
EXT2 FILE SYSTEM
M: Jan Kara <jack@suse.cz>
L: linux-ext4@vger.kernel.org
@@ -5370,13 +5365,6 @@ F: include/linux/sunrpc/
F: include/uapi/linux/nfs*
F: include/uapi/linux/sunrpc/
-NI5010 NETWORK DRIVER
-M: Jan-Pascal van Best <janpascal@vanbest.org>
-M: Andreas Mohr <andi@lisas.de>
-L: netdev@vger.kernel.org
-S: Maintained
-F: drivers/net/ethernet/racal/ni5010.*
-
NILFS2 FILESYSTEM
M: KONISHI Ryusuke <konishi.ryusuke@lab.ntt.co.jp>
L: linux-nilfs@vger.kernel.org
diff --git a/drivers/net/Space.c b/drivers/net/Space.c
index 5637c267141..3a8c7532ee0 100644
--- a/drivers/net/Space.c
+++ b/drivers/net/Space.c
@@ -40,26 +40,11 @@
extern struct net_device *hp100_probe(int unit);
extern struct net_device *ultra_probe(int unit);
extern struct net_device *wd_probe(int unit);
-extern struct net_device *el2_probe(int unit);
extern struct net_device *ne_probe(int unit);
-extern struct net_device *hp_probe(int unit);
-extern struct net_device *hp_plus_probe(int unit);
-extern struct net_device *express_probe(int unit);
-extern struct net_device *eepro_probe(int unit);
-extern struct net_device *at1700_probe(int unit);
extern struct net_device *fmv18x_probe(int unit);
-extern struct net_device *eth16i_probe(int unit);
extern struct net_device *i82596_probe(int unit);
-extern struct net_device *ewrk3_probe(int unit);
-extern struct net_device *el1_probe(int unit);
-extern struct net_device *el16_probe(int unit);
-extern struct net_device *elplus_probe(int unit);
-extern struct net_device *e2100_probe(int unit);
-extern struct net_device *ni5010_probe(int unit);
-extern struct net_device *ni52_probe(int unit);
extern struct net_device *ni65_probe(int unit);
extern struct net_device *sonic_probe(int unit);
-extern struct net_device *seeq8005_probe(int unit);
extern struct net_device *smc_init(int unit);
extern struct net_device *atarilance_probe(int unit);
extern struct net_device *sun3lance_probe(int unit);
@@ -74,9 +59,6 @@ extern struct net_device *mac89x0_probe(int unit);
extern struct net_device *cops_probe(int unit);
extern struct net_device *ltpc_probe(void);
-/* Detachable devices ("pocket adaptors") */
-extern struct net_device *de620_probe(int unit);
-
/* Fibre Channel adapters */
extern int iph5526_probe(struct net_device *dev);
@@ -120,18 +102,6 @@ static struct devprobe2 isa_probes[] __initdata = {
#ifdef CONFIG_WD80x3
{wd_probe, 0},
#endif
-#ifdef CONFIG_EL2 /* 3c503 */
- {el2_probe, 0},
-#endif
-#ifdef CONFIG_HPLAN
- {hp_probe, 0},
-#endif
-#ifdef CONFIG_HPLAN_PLUS
- {hp_plus_probe, 0},
-#endif
-#ifdef CONFIG_E2100 /* Cabletron E21xx series. */
- {e2100_probe, 0},
-#endif
#if defined(CONFIG_NE2000) || \
defined(CONFIG_NE_H8300) /* ISA (use ne2k-pci for PCI cards) */
{ne_probe, 0},
@@ -142,60 +112,20 @@ static struct devprobe2 isa_probes[] __initdata = {
#ifdef CONFIG_SMC9194
{smc_init, 0},
#endif
-#ifdef CONFIG_SEEQ8005
- {seeq8005_probe, 0},
-#endif
#ifdef CONFIG_CS89x0
#ifndef CONFIG_CS89x0_PLATFORM
{cs89x0_probe, 0},
#endif
#endif
-#ifdef CONFIG_AT1700
- {at1700_probe, 0},
-#endif
-#ifdef CONFIG_ETH16I
- {eth16i_probe, 0}, /* ICL EtherTeam 16i/32 */
-#endif
-#ifdef CONFIG_EEXPRESS /* Intel EtherExpress */
- {express_probe, 0},
-#endif
-#ifdef CONFIG_EEXPRESS_PRO /* Intel EtherExpress Pro/10 */
- {eepro_probe, 0},
-#endif
-#ifdef CONFIG_EWRK3 /* DEC EtherWORKS 3 */
- {ewrk3_probe, 0},
-#endif
-#if defined(CONFIG_APRICOT) || defined(CONFIG_MVME16x_NET) || defined(CONFIG_BVME6000_NET) /* Intel I82596 */
+#if defined(CONFIG_MVME16x_NET) || defined(CONFIG_BVME6000_NET) /* Intel I82596 */
{i82596_probe, 0},
#endif
-#ifdef CONFIG_EL1 /* 3c501 */
- {el1_probe, 0},
-#endif
-#ifdef CONFIG_EL16 /* 3c507 */
- {el16_probe, 0},
-#endif
-#ifdef CONFIG_ELPLUS /* 3c505 */
- {elplus_probe, 0},
-#endif
-#ifdef CONFIG_NI5010
- {ni5010_probe, 0},
-#endif
-#ifdef CONFIG_NI52
- {ni52_probe, 0},
-#endif
#ifdef CONFIG_NI65
{ni65_probe, 0},
#endif
{NULL, 0},
};
-static struct devprobe2 parport_probes[] __initdata = {
-#ifdef CONFIG_DE620 /* D-Link DE-620 adapter */
- {de620_probe, 0},
-#endif
- {NULL, 0},
-};
-
static struct devprobe2 m68k_probes[] __initdata = {
#ifdef CONFIG_ATARILANCE /* Lance-based Atari ethernet boards */
{atarilance_probe, 0},
@@ -234,8 +164,7 @@ static void __init ethif_probe2(int unit)
return;
(void)( probe_list2(unit, m68k_probes, base_addr == 0) &&
- probe_list2(unit, isa_probes, base_addr == 0) &&
- probe_list2(unit, parport_probes, base_addr == 0));
+ probe_list2(unit, isa_probes, base_addr == 0));
}
/* Statically configured drivers -- order matters here. */
diff --git a/drivers/net/ethernet/3com/3c501.c b/drivers/net/ethernet/3com/3c501.c
deleted file mode 100644
index 9abd9a738f8..00000000000
--- a/drivers/net/ethernet/3com/3c501.c
+++ /dev/null
@@ -1,897 +0,0 @@
-/* 3c501.c: A 3Com 3c501 Ethernet driver for Linux. */
-/*
- Written 1992,1993,1994 Donald Becker
-
- Copyright 1993 United States Government as represented by the
- Director, National Security Agency. This software may be used and
- distributed according to the terms of the GNU General Public License,
- incorporated herein by reference.
-
- This is a device driver for the 3Com Etherlink 3c501.
- Do not purchase this card, even as a joke. It's performance is horrible,
- and it breaks in many ways.
-
- The original author may be reached as becker@scyld.com, or C/O
- Scyld Computing Corporation
- 410 Severn Ave., Suite 210
- Annapolis MD 21403
-
- Fixed (again!) the missing interrupt locking on TX/RX shifting.
- Alan Cox <alan@lxorguk.ukuu.org.uk>
-
- Removed calls to init_etherdev since they are no longer needed, and
- cleaned up modularization just a bit. The driver still allows only
- the default address for cards when loaded as a module, but that's
- really less braindead than anyone using a 3c501 board. :)
- 19950208 (invid@msen.com)
-
- Added traps for interrupts hitting the window as we clear and TX load
- the board. Now getting 150K/second FTP with a 3c501 card. Still playing
- with a TX-TX optimisation to see if we can touch 180-200K/second as seems
- theoretically maximum.
- 19950402 Alan Cox <alan@lxorguk.ukuu.org.uk>
-
- Cleaned up for 2.3.x because we broke SMP now.
- 20000208 Alan Cox <alan@lxorguk.ukuu.org.uk>
-
- Check up pass for 2.5. Nothing significant changed
- 20021009 Alan Cox <alan@lxorguk.ukuu.org.uk>
-
- Fixed zero fill corner case
- 20030104 Alan Cox <alan@lxorguk.ukuu.org.uk>
-
-
- For the avoidance of doubt the "preferred form" of this code is one which
- is in an open non patent encumbered format. Where cryptographic key signing
- forms part of the process of creating an executable the information
- including keys needed to generate an equivalently functional executable
- are deemed to be part of the source code.
-
-*/
-
-
-/**
- * DOC: 3c501 Card Notes
- *
- * Some notes on this thing if you have to hack it. [Alan]
- *
- * Some documentation is available from 3Com. Due to the boards age
- * standard responses when you ask for this will range from 'be serious'
- * to 'give it to a museum'. The documentation is incomplete and mostly
- * of historical interest anyway.
- *
- * The basic system is a single buffer which can be used to receive or
- * transmit a packet. A third command mode exists when you are setting
- * things up.
- *
- * If it's transmitting it's not receiving and vice versa. In fact the
- * time to get the board back into useful state after an operation is
- * quite large.
- *
- * The driver works by keeping the board in receive mode waiting for a
- * packet to arrive. When one arrives it is copied out of the buffer
- * and delivered to the kernel. The card is reloaded and off we go.
- *
- * When transmitting lp->txing is set and the card is reset (from
- * receive mode) [possibly losing a packet just received] to command
- * mode. A packet is loaded and transmit mode triggered. The interrupt
- * handler runs different code for transmit interrupts and can handle
- * returning to receive mode or retransmissions (yes you have to help
- * out with those too).
- *
- * DOC: Problems
- *
- * There are a wide variety of undocumented error returns from the card
- * and you basically have to kick the board and pray if they turn up. Most
- * only occur under extreme load or if you do something the board doesn't
- * like (eg touching a register at the wrong time).
- *
- * The driver is less efficient than it could be. It switches through
- * receive mode even if more transmits are queued. If this worries you buy
- * a real Ethernet card.
- *
- * The combination of slow receive restart and no real multicast
- * filter makes the board unusable with a kernel compiled for IP
- * multicasting in a real multicast environment. That's down to the board,
- * but even with no multicast programs running a multicast IP kernel is
- * in group 224.0.0.1 and you will therefore be listening to all multicasts.
- * One nv conference running over that Ethernet and you can give up.
- *
- */
-
-#define DRV_NAME "3c501"
-#define DRV_VERSION "2002/10/09"
-
-
-static const char version[] =
- DRV_NAME ".c: " DRV_VERSION " Alan Cox (alan@lxorguk.ukuu.org.uk).\n";
-
-/*
- * Braindamage remaining:
- * The 3c501 board.
- */
-
-#include <linux/module.h>
-
-#include <linux/kernel.h>
-#include <linux/fcntl.h>
-#include <linux/ioport.h>
-#include <linux/interrupt.h>
-#include <linux/string.h>
-#include <linux/errno.h>
-#include <linux/spinlock.h>
-#include <linux/ethtool.h>
-#include <linux/delay.h>
-#include <linux/bitops.h>
-
-#include <asm/uaccess.h>
-#include <asm/io.h>
-
-#include <linux/netdevice.h>
-#include <linux/etherdevice.h>
-#include <linux/skbuff.h>
-#include <linux/init.h>
-
-#include "3c501.h"
-
-/*
- * The boilerplate probe code.
- */
-
-static int io = 0x280;
-static int irq = 5;
-static int mem_start;
-
-/**
- * el1_probe - probe for a 3c501
- * @dev: The device structure passed in to probe.
- *
- * This can be called from two places. The network layer will probe using
- * a device structure passed in with the probe information completed. For a
- * modular driver we use #init_module to fill in our own structure and probe
- * for it.
- *
- * Returns 0 on success. ENXIO if asked not to probe and ENODEV if asked to
- * probe and failing to find anything.
- */
-
-struct net_device * __init el1_probe(int unit)
-{
- struct net_device *dev = alloc_etherdev(sizeof(struct net_local));
- static const unsigned ports[] = { 0x280, 0x300, 0};
- const unsigned *port;
- int err = 0;
-
- if (!dev)
- return ERR_PTR(-ENOMEM);
-
- if (unit >= 0) {
- sprintf(dev->name, "eth%d", unit);
- netdev_boot_setup_check(dev);
- io = dev->base_addr;
- irq = dev->irq;
- mem_start = dev->mem_start & 7;
- }
-
- if (io > 0x1ff) { /* Check a single specified location. */
- err = el1_probe1(dev, io);
- } else if (io != 0) {
- err = -ENXIO; /* Don't probe at all. */
- } else {
- for (port = ports; *port && el1_probe1(dev, *port); port++)
- ;
- if (!*port)
- err = -ENODEV;
- }
- if (err)
- goto out;
- err = register_netdev(dev);
- if (err)
- goto out1;
- return dev;
-out1:
- release_region(dev->base_addr, EL1_IO_EXTENT);
-out:
- free_netdev(dev);
- return ERR_PTR(err);
-}
-
-static const struct net_device_ops el_netdev_ops = {
- .ndo_open = el_open,
- .ndo_stop = el1_close,
- .ndo_start_xmit = el_start_xmit,
- .ndo_tx_timeout = el_timeout,
- .ndo_set_rx_mode = set_multicast_list,
- .ndo_change_mtu = eth_change_mtu,
- .ndo_set_mac_address = eth_mac_addr,
- .ndo_validate_addr = eth_validate_addr,
-};
-
-/**
- * el1_probe1:
- * @dev: The device structure to use
- * @ioaddr: An I/O address to probe at.
- *
- * The actual probe. This is iterated over by #el1_probe in order to
- * check all the applicable device locations.
- *
- * Returns 0 for a success, in which case the device is activated,
- * EAGAIN if the IRQ is in use by another driver, and ENODEV if the
- * board cannot be found.
- */
-
-static int __init el1_probe1(struct net_device *dev, int ioaddr)
-{
- struct net_local *lp;
- const char *mname; /* Vendor name */
- unsigned char station_addr[6];
- int autoirq = 0;
- int i;
-
- /*
- * Reserve I/O resource for exclusive use by this driver
- */
-
- if (!request_region(ioaddr, EL1_IO_EXTENT, DRV_NAME))
- return -ENODEV;
-
- /*
- * Read the station address PROM data from the special port.
- */
-
- for (i = 0; i < 6; i++) {
- outw(i, ioaddr + EL1_DATAPTR);
- station_addr[i] = inb(ioaddr + EL1_SAPROM);
- }
- /*
- * Check the first three octets of the S.A. for 3Com's prefix, or
- * for the Sager NP943 prefix.
- */
-
- if (station_addr[0] == 0x02 && station_addr[1] == 0x60 &&
- station_addr[2] == 0x8c)
- mname = "3c501";
- else if (station_addr[0] == 0x00 && station_addr[1] == 0x80 &&
- station_addr[2] == 0xC8)
- mname = "NP943";
- else {
- release_region(ioaddr, EL1_IO_EXTENT);
- return -ENODEV;
- }
-
- /*
- * We auto-IRQ by shutting off the interrupt line and letting it
- * float high.
- */
-
- dev->irq = irq;
-
- if (dev->irq < 2) {
- unsigned long irq_mask;
-
- irq_mask = probe_irq_on();
- inb(RX_STATUS); /* Clear pending interrupts. */
- inb(TX_STATUS);
- outb(AX_LOOP + 1, AX_CMD);
-
- outb(0x00, AX_CMD);
-
- mdelay(20);
- autoirq = probe_irq_off(irq_mask);
-
- if (autoirq == 0) {
- pr_warning("%s probe at %#x failed to detect IRQ line.\n",
- mname, ioaddr);
- release_region(ioaddr, EL1_IO_EXTENT);
- return -EAGAIN;
- }
- }
-
- outb(AX_RESET+AX_LOOP, AX_CMD); /* Loopback mode. */
- dev->base_addr = ioaddr;
- memcpy(dev->dev_addr, station_addr, ETH_ALEN);
-
- if (mem_start & 0xf)
- el_debug = mem_start & 0x7;
- if (autoirq)
- dev->irq = autoirq;
-
- pr_info("%s: %s EtherLink at %#lx, using %sIRQ %d.\n",
- dev->name, mname, dev->base_addr,
- autoirq ? "auto":"assigned ", dev->irq);
-
-#ifdef CONFIG_IP_MULTICAST
- pr_warning("WARNING: Use of the 3c501 in a multicast kernel is NOT recommended.\n");
-#endif
-
- if (el_debug)
- pr_debug("%s", version);
-
- lp = netdev_priv(dev);
- memset(lp, 0, sizeof(struct net_local));
- spin_lock_init(&lp->lock);
-
- /*
- * The EL1-specific entries in the device structure.
- */
-
- dev->netdev_ops = &el_netdev_ops;
- dev->watchdog_timeo = HZ;
- dev->ethtool_ops = &netdev_ethtool_ops;
- return 0;
-}
-
-/**
- * el1_open:
- * @dev: device that is being opened
- *
- * When an ifconfig is issued which changes the device flags to include
- * IFF_UP this function is called. It is only called when the change
- * occurs, not when the interface remains up. #el1_close will be called
- * when it goes down.
- *
- * Returns 0 for a successful open, or -EAGAIN if someone has run off
- * with our interrupt line.
- */
-
-static int el_open(struct net_device *dev)
-{
- int retval;
- int ioaddr = dev->base_addr;
- struct net_local *lp = netdev_priv(dev);
- unsigned long flags;
-
- if (el_debug > 2)
- pr_debug("%s: Doing el_open()...\n", dev->name);
-
- retval = request_irq(dev->irq, el_interrupt, 0, dev->name, dev);
- if (retval)
- return retval;
-
- spin_lock_irqsave(&lp->lock, flags);
- el_reset(dev);
- spin_unlock_irqrestore(&lp->lock, flags);
-
- lp->txing = 0; /* Board in RX mode */
- outb(AX_RX, AX_CMD); /* Aux control, irq and receive enabled */
- netif_start_queue(dev);
- return 0;
-}
-
-/**
- * el_timeout:
- * @dev: The 3c501 card that has timed out
- *
- * Attempt to restart the board. This is basically a mixture of extreme
- * violence and prayer
- *
- */
-
-static void el_timeout(struct net_device *dev)
-{
- struct net_local *lp = netdev_priv(dev);
- int ioaddr = dev->base_addr;
-
- if (el_debug)
- pr_debug("%s: transmit timed out, txsr %#2x axsr=%02x rxsr=%02x.\n",
- dev->name, inb(TX_STATUS),
- inb(AX_STATUS), inb(RX_STATUS));
- dev->stats.tx_errors++;
- outb(TX_NORM, TX_CMD);
- outb(RX_NORM, RX_CMD);
- outb(AX_OFF, AX_CMD); /* Just trigger a false interrupt. */
- outb(AX_RX, AX_CMD); /* Aux control, irq and receive enabled */
- lp->txing = 0; /* Ripped back in to RX */
- netif_wake_queue(dev);
-}
-
-
-/**
- * el_start_xmit:
- * @skb: The packet that is queued to be sent
- * @dev: The 3c501 card we want to throw it down
- *
- * Attempt to send a packet to a 3c501 card. There are some interesting
- * catches here because the 3c501 is an extremely old and therefore
- * stupid piece of technology.
- *
- * If we are handling an interrupt on the other CPU we cannot load a packet
- * as we may still be attempting to retrieve the last RX packet buffer.
- *
- * When a transmit times out we dump the card into control mode and just
- * start again. It happens enough that it isn't worth logging.
- *
- * We avoid holding the spin locks when doing the packet load to the board.
- * The device is very slow, and its DMA mode is even slower. If we held the
- * lock while loading 1500 bytes onto the controller we would drop a lot of
- * serial port characters. This requires we do extra locking, but we have
- * no real choice.
- */
-
-static netdev_tx_t el_start_xmit(struct sk_buff *skb, struct net_device *dev)
-{
- struct net_local *lp = netdev_priv(dev);
- int ioaddr = dev->base_addr;
- unsigned long flags;
-
- /*
- * Avoid incoming interrupts between us flipping txing and flipping
- * mode as the driver assumes txing is a faithful indicator of card
- * state
- */
-
- spin_lock_irqsave(&lp->lock, flags);
-
- /*
- * Avoid timer-based retransmission conflicts.
- */
-
- netif_stop_queue(dev);
-
- do {
- int len = skb->len;
- int pad = 0;
- int gp_start;
- unsigned char *buf = skb->data;
-
- if (len < ETH_ZLEN)
- pad = ETH_ZLEN - len;
-
- gp_start = 0x800 - (len + pad);
-
- lp->tx_pkt_start = gp_start;
- lp->collisions = 0;
-
- dev->stats.tx_bytes += skb->len;
-
- /*
- * Command mode with status cleared should [in theory]
- * mean no more interrupts can be pending on the card.
- */
-
- outb_p(AX_SYS, AX_CMD);
- inb_p(RX_STATUS);
- inb_p(TX_STATUS);
-
- lp->loading = 1;
- lp->txing = 1;
-
- /*
- * Turn interrupts back on while we spend a pleasant
- * afternoon loading bytes into the board
- */
-
- spin_unlock_irqrestore(&lp->lock, flags);
-
- /* Set rx packet area to 0. */
- outw(0x00, RX_BUF_CLR);
- /* aim - packet will be loaded into buffer start */
- outw(gp_start, GP_LOW);
- /* load buffer (usual thing each byte increments the pointer) */
- outsb(DATAPORT, buf, len);
- if (pad) {
- while (pad--) /* Zero fill buffer tail */
- outb(0, DATAPORT);
- }
- /* the board reuses the same register */
- outw(gp_start, GP_LOW);
-
- if (lp->loading != 2) {
- /* fire ... Trigger xmit. */
- outb(AX_XMIT, AX_CMD);
- lp->loading = 0;
- if (el_debug > 2)
- pr_debug(" queued xmit.\n");
- dev_kfree_skb(skb);
- return NETDEV_TX_OK;
- }
- /* A receive upset our load, despite our best efforts */
- if (el_debug > 2)
- pr_debug("%s: burped during tx load.\n", dev->name);
- spin_lock_irqsave(&lp->lock, flags);
- } while (1);
-}
-
-/**
- * el_interrupt:
- * @irq: Interrupt number
- * @dev_id: The 3c501 that burped
- *
- * Handle the ether interface interrupts. The 3c501 needs a lot more
- * hand holding than most cards. In particular we get a transmit interrupt
- * with a collision error because the board firmware isn't capable of rewinding
- * its own transmit buffer pointers. It can however count to 16 for us.
- *
- * On the receive side the card is also very dumb. It has no buffering to
- * speak of. We simply pull the packet out of its PIO buffer (which is slow)
- * and queue it for the kernel. Then we reset the card for the next packet.
- *
- * We sometimes get surprise interrupts late both because the SMP IRQ delivery
- * is message passing and because the card sometimes seems to deliver late. I
- * think if it is part way through a receive and the mode is changed it carries
- * on receiving and sends us an interrupt. We have to band aid all these cases
- * to get a sensible 150kBytes/second performance. Even then you want a small
- * TCP window.
- */
-
-static irqreturn_t el_interrupt(int irq, void *dev_id)
-{
- struct net_device *dev = dev_id;
- struct net_local *lp;
- int ioaddr;
- int axsr; /* Aux. status reg. */
-
- ioaddr = dev->base_addr;
- lp = netdev_priv(dev);
-
- spin_lock(&lp->lock);
-
- /*
- * What happened ?
- */
-
- axsr = inb(AX_STATUS);
-
- /*
- * Log it
- */
-
- if (el_debug > 3)
- pr_debug("%s: el_interrupt() aux=%#02x\n", dev->name, axsr);
-
- if (lp->loading == 1 && !lp->txing)
- pr_warning("%s: Inconsistent state loading while not in tx\n",
- dev->name);
-
- if (lp->txing) {
- /*
- * Board in transmit mode. May be loading. If we are
- * loading we shouldn't have got this.
- */
- int txsr = inb(TX_STATUS);
-
- if (lp->loading == 1) {
- if (el_debug > 2)
- pr_debug("%s: Interrupt while loading [txsr=%02x gp=%04x rp=%04x]\n",
- dev->name, txsr, inw(GP_LOW), inw(RX_LOW));
-
- /* Force a reload */
- lp->loading = 2;
- spin_unlock(&lp->lock);
- goto out;
- }
- if (el_debug > 6)
- pr_debug("%s: txsr=%02x gp=%04x rp=%04x\n", dev->name,
- txsr, inw(GP_LOW), inw(RX_LOW));
-
- if ((axsr & 0x80) && (txsr & TX_READY) == 0) {
- /*
- * FIXME: is there a logic to whether to keep
- * on trying or reset immediately ?
- */
- if (el_debug > 1)
- pr_debug("%s: Unusual interrupt during Tx, txsr=%02x axsr=%02x gp=%03x rp=%03x.\n",
- dev->name, txsr, axsr,
- inw(ioaddr + EL1_DATAPTR),
- inw(ioaddr + EL1_RXPTR));
- lp->txing = 0;
- netif_wake_queue(dev);
- } else if (txsr & TX_16COLLISIONS) {
- /*
- * Timed out
- */
- if (el_debug)
- pr_debug("%s: Transmit failed 16 times, Ethernet jammed?\n", dev->name);
- outb(AX_SYS, AX_CMD);
- lp->txing = 0;
- dev->stats.tx_aborted_errors++;
- netif_wake_queue(dev);
- } else if (txsr & TX_COLLISION) {
- /*
- * Retrigger xmit.
- */
-
- if (el_debug > 6)
- pr_debug("%s: retransmitting after a collision.\n", dev->name);
- /*
- * Poor little chip can't reset its own start
- * pointer
- */
-
- outb(AX_SYS, AX_CMD);
- outw(lp->tx_pkt_start, GP_LOW);
- outb(AX_XMIT, AX_CMD);
- dev->stats.collisions++;
- spin_unlock(&lp->lock);
- goto out;
- } else {
- /*
- * It worked.. we will now fall through and receive
- */
- dev->stats.tx_packets++;
- if (el_debug > 6)
- pr_debug("%s: Tx succeeded %s\n", dev->name,
- (txsr & TX_RDY) ? "." : "but tx is busy!");
- /*
- * This is safe the interrupt is atomic WRT itself.
- */
- lp->txing = 0;
- /* In case more to transmit */
- netif_wake_queue(dev);
- }
- } else {
- /*
- * In receive mode.
- */
-
- int rxsr = inb(RX_STATUS);
- if (el_debug > 5)
- pr_debug("%s: rxsr=%02x txsr=%02x rp=%04x\n",
- dev->name, rxsr, inb(TX_STATUS), inw(RX_LOW));
- /*
- * Just reading rx_status fixes most errors.
- */
- if (rxsr & RX_MISSED)
- dev->stats.rx_missed_errors++;
- else if (rxsr & RX_RUNT) {
- /* Handled to avoid board lock-up. */
- dev->stats.rx_length_errors++;
- if (el_debug > 5)
- pr_debug("%s: runt.\n", dev->name);
- } else if (rxsr & RX_GOOD) {
- /*
- * Receive worked.
- */
- el_receive(dev);
- } else {
- /*
- * Nothing? Something is broken!
- */
- if (el_debug > 2)
- pr_debug("%s: No packet seen, rxsr=%02x **resetting 3c501***\n",
- dev->name, rxsr);
- el_reset(dev);
- }
- }
-
- /*
- * Move into receive mode
- */
-
- outb(AX_RX, AX_CMD);
- outw(0x00, RX_BUF_CLR);
- inb(RX_STATUS); /* Be certain that interrupts are cleared. */
- inb(TX_STATUS);
- spin_unlock(&lp->lock);
-out:
- return IRQ_HANDLED;
-}
-
-
-/**
- * el_receive:
- * @dev: Device to pull the packets from
- *
- * We have a good packet. Well, not really "good", just mostly not broken.
- * We must check everything to see if it is good. In particular we occasionally
- * get wild packet sizes from the card. If the packet seems sane we PIO it
- * off the card and queue it for the protocol layers.
- */
-
-static void el_receive(struct net_device *dev)
-{
- int ioaddr = dev->base_addr;
- int pkt_len;
- struct sk_buff *skb;
-
- pkt_len = inw(RX_LOW);
-
- if (el_debug > 4)
- pr_debug(" el_receive %d.\n", pkt_len);
-
- if (pkt_len < 60 || pkt_len > 1536) {
- if (el_debug)
- pr_debug("%s: bogus packet, length=%d\n",
- dev->name, pkt_len);
- dev->stats.rx_over_errors++;
- return;
- }
-
- /*
- * Command mode so we can empty the buffer
- */
-
- outb(AX_SYS, AX_CMD);
- skb = netdev_alloc_skb(dev, pkt_len + 2);
-
- /*
- * Start of frame
- */
-
- outw(0x00, GP_LOW);
- if (skb == NULL) {
- pr_info("%s: Memory squeeze, dropping packet.\n", dev->name);
- dev->stats.rx_dropped++;
- return;
- } else {
- skb_reserve(skb, 2); /* Force 16 byte alignment */
- /*
- * The read increments through the bytes. The interrupt
- * handler will fix the pointer when it returns to
- * receive mode.
- */
- insb(DATAPORT, skb_put(skb, pkt_len), pkt_len);
- skb->protocol = eth_type_trans(skb, dev);
- netif_rx(skb);
- dev->stats.rx_packets++;
- dev->stats.rx_bytes += pkt_len;
- }
-}
-
-/**
- * el_reset: Reset a 3c501 card
- * @dev: The 3c501 card about to get zapped
- *
- * Even resetting a 3c501 isn't simple. When you activate reset it loses all
- * its configuration. You must hold the lock when doing this. The function
- * cannot take the lock itself as it is callable from the irq handler.
- */
-
-static void el_reset(struct net_device *dev)
-{
- struct net_local *lp = netdev_priv(dev);
- int ioaddr = dev->base_addr;
-
- if (el_debug > 2)
- pr_info("3c501 reset...\n");
- outb(AX_RESET, AX_CMD); /* Reset the chip */
- /* Aux control, irq and loopback enabled */
- outb(AX_LOOP, AX_CMD);
- {
- int i;
- for (i = 0; i < 6; i++) /* Set the station address. */
- outb(dev->dev_addr[i], ioaddr + i);
- }
-
- outw(0, RX_BUF_CLR); /* Set rx packet area to 0. */
- outb(TX_NORM, TX_CMD); /* tx irq on done, collision */
- outb(RX_NORM, RX_CMD); /* Set Rx commands. */
- inb(RX_STATUS); /* Clear status. */
- inb(TX_STATUS);
- lp->txing = 0;
-}
-
-/**
- * el1_close:
- * @dev: 3c501 card to shut down
- *
- * Close a 3c501 card. The IFF_UP flag has been cleared by the user via
- * the SIOCSIFFLAGS ioctl. We stop any further transmissions being queued,
- * and then disable the interrupts. Finally we reset the chip. The effects
- * of the rest will be cleaned up by #el1_open. Always returns 0 indicating
- * a success.
- */
-
-static int el1_close(struct net_device *dev)
-{
- int ioaddr = dev->base_addr;
-
- if (el_debug > 2)
- pr_info("%s: Shutting down Ethernet card at %#x.\n",
- dev->name, ioaddr);
-
- netif_stop_queue(dev);
-
- /*
- * Free and disable the IRQ.
- */
-
- free_irq(dev->irq, dev);
- outb(AX_RESET, AX_CMD); /* Reset the chip */
-
- return 0;
-}
-
-/**
- * set_multicast_list:
- * @dev: The device to adjust
- *
- * Set or clear the multicast filter for this adaptor to use the best-effort
- * filtering supported. The 3c501 supports only three modes of filtering.
- * It always receives broadcasts and packets for itself. You can choose to
- * optionally receive all packets, or all multicast packets on top of this.
- */
-
-static void set_multicast_list(struct net_device *dev)
-{
- int ioaddr = dev->base_addr;
-
- if (dev->flags & IFF_PROMISC) {
- outb(RX_PROM, RX_CMD);
- inb(RX_STATUS);
- } else if (!netdev_mc_empty(dev) || dev->flags & IFF_ALLMULTI) {
- /* Multicast or all multicast is the same */
- outb(RX_MULT, RX_CMD);
- inb(RX_STATUS); /* Clear status. */
- } else {
- outb(RX_NORM, RX_CMD);
- inb(RX_STATUS);
- }
-}
-
-
-static void netdev_get_drvinfo(struct net_device *dev,
- struct ethtool_drvinfo *info)
-{
- strlcpy(info->driver, DRV_NAME, sizeof(info->driver));
- strlcpy(info->version, DRV_VERSION, sizeof(info->version));
- snprintf(info->bus_info, sizeof(info->bus_info), "ISA 0x%lx",
- dev->base_addr);
-}
-
-static u32 netdev_get_msglevel(struct net_device *dev)
-{
- return debug;
-}
-
-static void netdev_set_msglevel(struct net_device *dev, u32 level)
-{
- debug = level;
-}
-
-static const struct ethtool_ops netdev_ethtool_ops = {
- .get_drvinfo = netdev_get_drvinfo,
- .get_msglevel = netdev_get_msglevel,
- .set_msglevel = netdev_set_msglevel,
-};
-
-#ifdef MODULE
-
-static struct net_device *dev_3c501;
-
-module_param(io, int, 0);
-module_param(irq, int, 0);
-MODULE_PARM_DESC(io, "EtherLink I/O base address");
-MODULE_PARM_DESC(irq, "EtherLink IRQ number");
-
-/**
- * init_module:
- *
- * When the driver is loaded as a module this function is called. We fake up
- * a device structure with the base I/O and interrupt set as if it were being
- * called from Space.c. This minimises the extra code that would otherwise
- * be required.
- *
- * Returns 0 for success or -EIO if a card is not found. Returning an error
- * here also causes the module to be unloaded
- */
-
-int __init init_module(void)
-{
- dev_3c501 = el1_probe(-1);
- if (IS_ERR(dev_3c501))
- return PTR_ERR(dev_3c501);
- return 0;
-}
-
-/**
- * cleanup_module:
- *
- * The module is being unloaded. We unhook our network device from the system
- * and then free up the resources we took when the card was found.
- */
-
-void __exit cleanup_module(void)
-{
- struct net_device *dev = dev_3c501;
- unregister_netdev(dev);
- release_region(dev->base_addr, EL1_IO_EXTENT);
- free_netdev(dev);
-}
-
-#endif /* MODULE */
-
-MODULE_AUTHOR("Donald Becker, Alan Cox");
-MODULE_DESCRIPTION("Support for the ancient 3Com 3c501 ethernet card");
-MODULE_LICENSE("GPL");
-
diff --git a/drivers/net/ethernet/3com/3c501.h b/drivers/net/ethernet/3com/3c501.h
deleted file mode 100644
index 183fd55f03c..00000000000
--- a/drivers/net/ethernet/3com/3c501.h
+++ /dev/null
@@ -1,91 +0,0 @@
-
-/*
- * Index to functions.
- */
-
-static int el1_probe1(struct net_device *dev, int ioaddr);
-static int el_open(struct net_device *dev);
-static void el_timeout(struct net_device *dev);
-static netdev_tx_t el_start_xmit(struct sk_buff *skb, struct net_device *dev);
-static irqreturn_t el_interrupt(int irq, void *dev_id);
-static void el_receive(struct net_device *dev);
-static void el_reset(struct net_device *dev);
-static int el1_close(struct net_device *dev);
-static void set_multicast_list(struct net_device *dev);
-static const struct ethtool_ops netdev_ethtool_ops;
-
-#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;
-
-/*
- * Board-specific info in netdev_priv(dev).
- */
-
-struct net_local
-{
- int tx_pkt_start; /* The length of the current Tx packet. */
- int collisions; /* Tx collisions this packet */
- int loading; /* Spot buffer load collisions */
- int txing; /* True if card is in TX mode */
- spinlock_t lock; /* Serializing lock */
-};
-
-
-#define RX_STATUS (ioaddr + 0x06)
-#define RX_CMD RX_STATUS
-#define TX_STATUS (ioaddr + 0x07)
-#define TX_CMD TX_STATUS
-#define GP_LOW (ioaddr + 0x08)
-#define GP_HIGH (ioaddr + 0x09)
-#define RX_BUF_CLR (ioaddr + 0x0A)
-#define RX_LOW (ioaddr + 0x0A)
-#define RX_HIGH (ioaddr + 0x0B)
-#define SAPROM (ioaddr + 0x0C)
-#define AX_STATUS (ioaddr + 0x0E)
-#define AX_CMD AX_STATUS
-#define DATAPORT (ioaddr + 0x0F)
-#define TX_RDY 0x08 /* In TX_STATUS */
-
-#define EL1_DATAPTR 0x08
-#define EL1_RXPTR 0x0A
-#define EL1_SAPROM 0x0C
-#define EL1_DATAPORT 0x0f
-
-/*
- * Writes to the ax command register.
- */
-
-#define AX_OFF 0x00 /* Irq off, buffer access on */
-#define AX_SYS 0x40 /* Load the buffer */
-#define AX_XMIT 0x44 /* Transmit a packet */
-#define AX_RX 0x48 /* Receive a packet */
-#define AX_LOOP 0x0C /* Loopback mode */
-#define AX_RESET 0x80
-
-/*
- * Normal receive mode written to RX_STATUS. We must intr on short packets
- * to avoid bogus rx lockups.
- */
-
-#define RX_NORM 0xA8 /* 0x68 == all addrs, 0xA8 only to me. */
-#define RX_PROM 0x68 /* Senior Prom, uhmm promiscuous mode. */
-#define RX_MULT 0xE8 /* Accept multicast packets. */
-#define TX_NORM 0x0A /* Interrupt on everything that might hang the chip */
-
-/*
- * TX_STATUS register.
- */
-
-#define TX_COLLISION 0x02
-#define TX_16COLLISIONS 0x04
-#define TX_READY 0x08
-
-#define RX_RUNT 0x08
-#define RX_MISSED 0x01 /* Missed a packet due to 3c501 braindamage. */
-#define RX_GOOD 0x30 /* Good packet 0x20, or simple overflow 0x10. */
-
diff --git a/drivers/net/ethernet/3com/Kconfig b/drivers/net/ethernet/3com/Kconfig
index 8c417ed339b..1c71c763f68 100644
--- a/drivers/net/ethernet/3com/Kconfig
+++ b/drivers/net/ethernet/3com/Kconfig
@@ -18,20 +18,6 @@ config NET_VENDOR_3COM
if NET_VENDOR_3COM
-config EL1
- tristate "3c501 \"EtherLink\" support"
- depends on ISA
- ---help---
- If you have a network (Ethernet) card of this type, say Y and read
- the Ethernet-HOWTO, available from
- <http://www.tldp.org/docs.html#howto>. Also, consider buying a
- new card, since the 3c501 is slow, broken, and obsolete: you will
- have problems. Some people suggest to ping ("man ping") a nearby
- machine every minute ("man cron") when using this card.
-
- To compile this driver as a module, choose M here. The module
- will be called 3c501.
-
config EL3
tristate "3c509/3c579 \"EtherLink III\" support"
depends on (ISA || EISA)
diff --git a/drivers/net/ethernet/3com/Makefile b/drivers/net/ethernet/3com/Makefile
index 1e5382a30ea..74046afab99 100644
--- a/drivers/net/ethernet/3com/Makefile
+++ b/drivers/net/ethernet/3com/Makefile
@@ -2,7 +2,6 @@
# Makefile for the 3Com Ethernet device drivers
#
-obj-$(CONFIG_EL1) += 3c501.o
obj-$(CONFIG_EL3) += 3c509.o
obj-$(CONFIG_3C515) += 3c515.o
obj-$(CONFIG_PCMCIA_3C589) += 3c589_cs.o
diff --git a/drivers/net/ethernet/8390/3c503.c b/drivers/net/ethernet/8390/3c503.c
deleted file mode 100644
index 0e9afe7b61a..00000000000
--- a/drivers/net/ethernet/8390/3c503.c
+++ /dev/null
@@ -1,778 +0,0 @@
-/* 3c503.c: A shared-memory NS8390 ethernet driver for linux. */
-/*
- Written 1992-94 by Donald Becker.
-
- Copyright 1993 United States Government as represented by the
- Director, National Security Agency. This software may be used and
- distributed according to the terms of the GNU General Public License,
- incorporated herein by reference.
-
- The author may be reached as becker@scyld.com, or C/O
- Scyld Computing Corporation
- 410 Severn Ave., Suite 210
- Annapolis MD 21403
-
-
- This driver should work with the 3c503 and 3c503/16. It should be used
- in shared memory mode for best performance, although it may also work
- in programmed-I/O mode.
-
- Sources:
- EtherLink II Technical Reference Manual,
- EtherLink II/16 Technical Reference Manual Supplement,
- 3Com Corporation, 5400 Bayfront Plaza, Santa Clara CA 95052-8145
-
- The Crynwr 3c503 packet driver.
-
- Changelog:
-
- 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[] =
- DRV_NAME ".c:v" DRV_VERSION " " DRV_RELDATE " Donald Becker (becker@scyld.com)\n";
-
-#include <linux/module.h>
-#include <linux/kernel.h>
-#include <linux/errno.h>
-#include <linux/string.h>
-#include <linux/delay.h>
-#include <linux/netdevice.h>
-#include <linux/etherdevice.h>
-#include <linux/init.h>
-#include <linux/interrupt.h>
-#include <linux/ethtool.h>
-
-#include <asm/uaccess.h>
-#include <asm/io.h>
-#include <asm/byteorder.h>
-
-#include "8390.h"
-#include "3c503.h"
-#define WRD_COUNT 4
-
-static int el2_pio_probe(struct net_device *dev);
-static int el2_probe1(struct net_device *dev, int ioaddr);
-
-/* A zero-terminated list of I/O addresses to be probed in PIO mode. */
-static unsigned int netcard_portlist[] __initdata =
- { 0x300,0x310,0x330,0x350,0x250,0x280,0x2a0,0x2e0,0};
-
-#define EL2_IO_EXTENT 16
-
-static int el2_open(struct net_device *dev);
-static int el2_close(struct net_device *dev);
-static void el2_reset_8390(struct net_device *dev);
-static void el2_init_card(struct net_device *dev);
-static void el2_block_output(struct net_device *dev, int count,
- const unsigned char *buf, int start_page);
-static void el2_block_input(struct net_device *dev, int count, struct sk_buff *skb,
- int ring_offset);
-static void el2_get_8390_hdr(struct net_device *dev, struct e8390_pkt_hdr *hdr,
- int ring_page);
-static const struct ethtool_ops netdev_ethtool_ops;
-
-
-/* This routine probes for a memory-mapped 3c503 board by looking for
- the "location register" at the end of the jumpered boot PROM space.
- This works even if a PROM isn't there.
-
- If the ethercard isn't found there is an optional probe for
- ethercard jumpered to programmed-I/O mode.
- */
-static int __init do_el2_probe(struct net_device *dev)
-{
- int *addr, addrs[] = { 0xddffe, 0xd9ffe, 0xcdffe, 0xc9ffe, 0};
- int base_addr = dev->base_addr;
- int irq = dev->irq;
-
- if (base_addr > 0x1ff) /* Check a single specified location. */
- return el2_probe1(dev, base_addr);
- else if (base_addr != 0) /* Don't probe at all. */
- return -ENXIO;
-
- for (addr = addrs; *addr; addr++) {
- void __iomem *p = ioremap(*addr, 1);
- unsigned base_bits;
- int i;
-
- if (!p)
- continue;
- base_bits = readb(p);
- iounmap(p);
- i = ffs(base_bits) - 1;
- if (i == -1 || base_bits != (1 << i))
- continue;
- if (el2_probe1(dev, netcard_portlist[i]) == 0)
- return 0;
- dev->irq = irq;
- }
-#if ! defined(no_probe_nonshared_memory)
- return el2_pio_probe(dev);
-#else
- return -ENODEV;
-#endif
-}
-
-/* Try all of the locations that aren't obviously empty. This touches
- a lot of locations, and is much riskier than the code above. */
-static int __init
-el2_pio_probe(struct net_device *dev)
-{
- int i;
- int base_addr = dev->base_addr;
- int irq = dev->irq;
-
- if (base_addr > 0x1ff) /* Check a single specified location. */
- return el2_probe1(dev, base_addr);
- else if (base_addr != 0) /* Don't probe at all. */
- return -ENXIO;
-
- for (i = 0; netcard_portlist[i]; i++) {
- if (el2_probe1(dev, netcard_portlist[i]) == 0)
- return 0;
- dev->irq = irq;
- }
-
- return -ENODEV;
-}
-
-#ifndef MODULE
-struct net_device * __init el2_probe(int unit)
-{
- struct net_device *dev = alloc_eip_netdev();
- int err;
-
- if (!dev)
- return ERR_PTR(-ENOMEM);
-
- sprintf(dev->name, "eth%d", unit);
- netdev_boot_setup_check(dev);
-
- err = do_el2_probe(dev);
- if (err)
- goto out;
- return dev;
-out:
- free_netdev(dev);
- return ERR_PTR(err);
-}
-#endif
-
-static const struct net_device_ops el2_netdev_ops = {
- .ndo_open = el2_open,
- .ndo_stop = el2_close,
-
- .ndo_start_xmit = eip_start_xmit,
- .ndo_tx_timeout = eip_tx_timeout,
- .ndo_get_stats = eip_get_stats,
- .ndo_set_rx_mode = eip_set_multicast_list,
- .ndo_validate_addr = eth_validate_addr,
- .ndo_set_mac_address = eth_mac_addr,
- .ndo_change_mtu = eth_change_mtu,
-#ifdef CONFIG_NET_POLL_CONTROLLER
- .ndo_poll_controller = eip_poll,
-#endif
-};
-
-/* Probe for the Etherlink II card at I/O port base IOADDR,
- returning non-zero on success. If found, set the station
- address and memory parameters in DEVICE. */
-static int __init
-el2_probe1(struct net_device *dev, int ioaddr)
-{
- int i, iobase_reg, membase_reg, saved_406, wordlength, retval;
- static unsigned version_printed;
- unsigned long vendor_id;
-
- if (!request_region(ioaddr, EL2_IO_EXTENT, DRV_NAME))
- return -EBUSY;
-
- if (!request_region(ioaddr + 0x400, 8, DRV_NAME)) {
- retval = -EBUSY;
- goto out;
- }
-
- /* Reset and/or avoid any lurking NE2000 */
- if (inb(ioaddr + 0x408) == 0xff) {
- mdelay(1);
- retval = -ENODEV;
- goto out1;
- }
-
- /* We verify that it's a 3C503 board by checking the first three octets
- of its ethernet address. */
- iobase_reg = inb(ioaddr+0x403);
- membase_reg = inb(ioaddr+0x404);
- /* ASIC location registers should be 0 or have only a single bit set. */
- if ((iobase_reg & (iobase_reg - 1)) ||
- (membase_reg & (membase_reg - 1))) {
- retval = -ENODEV;
- goto out1;
- }
- saved_406 = inb_p(ioaddr + 0x406);
- outb_p(ECNTRL_RESET|ECNTRL_THIN, ioaddr + 0x406); /* Reset it... */
- outb_p(ECNTRL_THIN, ioaddr + 0x406);
- /* Map the station addr PROM into the lower I/O ports. We now check
- for both the old and new 3Com prefix */
- outb(ECNTRL_SAPROM|ECNTRL_THIN, ioaddr + 0x406);
- vendor_id = inb(ioaddr)*0x10000 + inb(ioaddr + 1)*0x100 + inb(ioaddr + 2);
- if ((vendor_id != OLD_3COM_ID) && (vendor_id != NEW_3COM_ID)) {
- /* Restore the register we frobbed. */
- outb(saved_406, ioaddr + 0x406);
- retval = -ENODEV;
- goto out1;
- }
-
- if (ei_debug && version_printed++ == 0)
- pr_debug("%s", version);
-
- dev->base_addr = ioaddr;
-
- pr_info("%s: 3c503 at i/o base %#3x, node ", dev->name, ioaddr);
-
- /* Retrieve and print the ethernet address. */
- for (i = 0; i < 6; i++)
- dev->dev_addr[i] = inb(ioaddr + i);
- pr_cont("%pM", dev->dev_addr);
-
- /* Map the 8390 back into the window. */
- outb(ECNTRL_THIN, ioaddr + 0x406);
-
- /* Check for EL2/16 as described in tech. man. */
- outb_p(E8390_PAGE0, ioaddr + E8390_CMD);
- outb_p(0, ioaddr + EN0_DCFG);
- outb_p(E8390_PAGE2, ioaddr + E8390_CMD);
- wordlength = inb_p(ioaddr + EN0_DCFG) & ENDCFG_WTS;
- outb_p(E8390_PAGE0, ioaddr + E8390_CMD);
-
- /* Probe for, turn on and clear the board's shared memory. */
- if (ei_debug > 2)
- pr_cont(" memory jumpers %2.2x ", membase_reg);
- outb(EGACFR_NORM, ioaddr + 0x405); /* Enable RAM */
-
- /* This should be probed for (or set via an ioctl()) at run-time.
- Right now we use a sleazy hack to pass in the interface number
- at boot-time via the low bits of the mem_end field. That value is
- unused, and the low bits would be discarded even if it was used. */
-#if defined(EI8390_THICK) || defined(EL2_AUI)
- ei_status.interface_num = 1;
-#else
- ei_status.interface_num = dev->mem_end & 0xf;
-#endif
- pr_cont(", using %sternal xcvr.\n", ei_status.interface_num == 0 ? "in" : "ex");
-
- if ((membase_reg & 0xf0) == 0) {
- dev->mem_start = 0;
- ei_status.name = "3c503-PIO";
- ei_status.mem = NULL;
- } else {
- dev->mem_start = ((membase_reg & 0xc0) ? 0xD8000 : 0xC8000) +
- ((membase_reg & 0xA0) ? 0x4000 : 0);
-#define EL2_MEMSIZE (EL2_MB1_STOP_PG - EL2_MB1_START_PG)*256
- ei_status.mem = ioremap(dev->mem_start, EL2_MEMSIZE);
-
-#ifdef EL2MEMTEST
- /* This has never found an error, but someone might care.
- Note that it only tests the 2nd 8kB on 16kB 3c503/16
- cards between card addr. 0x2000 and 0x3fff. */
- { /* Check the card's memory. */
- void __iomem *mem_base = ei_status.mem;
- unsigned int test_val = 0xbbadf00d;
- writel(0xba5eba5e, mem_base);
- for (i = sizeof(test_val); i < EL2_MEMSIZE; i+=sizeof(test_val)) {
- writel(test_val, mem_base + i);
- if (readl(mem_base) != 0xba5eba5e ||
- readl(mem_base + i) != test_val) {
- pr_warning("3c503: memory failure or memory address conflict.\n");
- dev->mem_start = 0;
- ei_status.name = "3c503-PIO";
- iounmap(mem_base);
- ei_status.mem = NULL;
- break;
- }
- test_val += 0x55555555;
- writel(0, mem_base + i);
- }
- }
-#endif /* EL2MEMTEST */
-
- if (dev->mem_start)
- dev->mem_end = dev->mem_start + EL2_MEMSIZE;
-
- if (wordlength) { /* No Tx pages to skip over to get to Rx */
- ei_status.priv = 0;
- ei_status.name = "3c503/16";
- } else {
- ei_status.priv = TX_PAGES * 256;
- ei_status.name = "3c503";
- }
- }
-
- /*
- Divide up the memory on the card. This is the same regardless of
- whether shared-mem or PIO is used. For 16 bit cards (16kB RAM),
- we use the entire 8k of bank1 for an Rx ring. We only use 3k
- of the bank0 for 2 full size Tx packet slots. For 8 bit cards,
- (8kB RAM) we use 3kB of bank1 for two Tx slots, and the remaining
- 5kB for an Rx ring. */
-
- if (wordlength) {
- ei_status.tx_start_page = EL2_MB0_START_PG;
- ei_status.rx_start_page = EL2_MB1_START_PG;
- } else {
- ei_status.tx_start_page = EL2_MB1_START_PG;
- ei_status.rx_start_page = EL2_MB1_START_PG + TX_PAGES;
- }
-
- /* Finish setting the board's parameters. */
- ei_status.stop_page = EL2_MB1_STOP_PG;
- ei_status.word16 = wordlength;
- ei_status.reset_8390 = el2_reset_8390;
- ei_status.get_8390_hdr = el2_get_8390_hdr;
- ei_status.block_input = el2_block_input;
- ei_status.block_output = el2_block_output;
-
- if (dev->irq == 2)
- dev->irq = 9;
- else if (dev->irq > 5 && dev->irq != 9) {
- pr_warning("3c503: configured interrupt %d invalid, will use autoIRQ.\n",
- dev->irq);
- dev->irq = 0;
- }
-
- ei_status.saved_irq = dev->irq;
-
- dev->netdev_ops = &el2_netdev_ops;
- dev->ethtool_ops = &netdev_ethtool_ops;
-
- retval = register_netdev(dev);
- if (retval)
- goto out1;
-
- if (dev->mem_start)
- pr_info("%s: %s - %dkB RAM, 8kB shared mem window at %#6lx-%#6lx.\n",
- dev->name, ei_status.name, (wordlength+1)<<3,
- dev->mem_start, dev->mem_end-1);
-
- else
- {
- ei_status.tx_start_page = EL2_MB1_START_PG;
- ei_status.rx_start_page = EL2_MB1_START_PG + TX_PAGES;
- pr_info("%s: %s, %dkB RAM, using programmed I/O (REJUMPER for SHARED MEMORY).\n",
- dev->name, ei_status.name, (wordlength+1)<<3);
- }
- release_region(ioaddr + 0x400, 8);
- return 0;
-out1:
- release_region(ioaddr + 0x400, 8);
-out:
- release_region(ioaddr, EL2_IO_EXTENT);
- return retval;
-}
-
-static irqreturn_t el2_probe_interrupt(int irq, void *seen)
-{
- *(bool *)seen = true;
- return IRQ_HANDLED;
-}
-
-static int
-el2_open(struct net_device *dev)
-{
- int retval;
-
- if (dev->irq < 2) {
- static const int irqlist[] = {5, 9, 3, 4, 0};
- const int *irqp = irqlist;
-
- outb(EGACFR_NORM, E33G_GACFR); /* Enable RAM and interrupts. */
- do {
- bool seen;
-
- retval = request_irq(*irqp, el2_probe_interrupt, 0,
- dev->name, &seen);
- if (retval == -EBUSY)
- continue;
- if (retval < 0)
- goto err_disable;
-
- /* Twinkle the interrupt, and check if it's seen. */
- seen = false;
- smp_wmb();
- outb_p(0x04 << ((*irqp == 9) ? 2 : *irqp), E33G_IDCFR);
- outb_p(0x00, E33G_IDCFR);
- msleep(1);
- free_irq(*irqp, &seen);
- if (!seen)
- continue;
-
- retval = request_irq(dev->irq = *irqp, eip_interrupt, 0,
- dev->name, dev);
- if (retval == -EBUSY)
- continue;
- if (retval < 0)
- goto err_disable;
- break;
- } while (*++irqp);
-
- if (*irqp == 0) {
- err_disable:
- outb(EGACFR_IRQOFF, E33G_GACFR); /* disable interrupts. */
- return -EAGAIN;
- }
- } else {
- if ((retval = request_irq(dev->irq, eip_interrupt, 0, dev->name, dev))) {
- return retval;
- }
- }
-
- el2_init_card(dev);
- eip_open(dev);
- return 0;
-}
-
-static int
-el2_close(struct net_device *dev)
-{
- free_irq(dev->irq, dev);
- dev->irq = ei_status.saved_irq;
- outb(EGACFR_IRQOFF, E33G_GACFR); /* disable interrupts. */
-
- eip_close(dev);
- return 0;
-}
-
-/* This is called whenever we have a unrecoverable failure:
- transmit timeout
- Bad ring buffer packet header
- */
-static void
-el2_reset_8390(struct net_device *dev)
-{
- if (ei_debug > 1) {
- pr_debug("%s: Resetting the 3c503 board...", dev->name);
- pr_cont(" %#lx=%#02x %#lx=%#02x %#lx=%#02x...", E33G_IDCFR, inb(E33G_IDCFR),
- E33G_CNTRL, inb(E33G_CNTRL), E33G_GACFR, inb(E33G_GACFR));
- }
- outb_p(ECNTRL_RESET|ECNTRL_THIN, E33G_CNTRL);
- ei_status.txing = 0;
- outb_p(ei_status.interface_num==0 ? ECNTRL_THIN : ECNTRL_AUI, E33G_CNTRL);
- el2_init_card(dev);
- if (ei_debug > 1)
- pr_cont("done\n");
-}
-
-/* Initialize the 3c503 GA registers after a reset. */
-static void
-el2_init_card(struct net_device *dev)
-{
- /* Unmap the station PROM and select the DIX or BNC connector. */
- outb_p(ei_status.interface_num==0 ? ECNTRL_THIN : ECNTRL_AUI, E33G_CNTRL);
-
- /* Set ASIC copy of rx's first and last+1 buffer pages */
- /* These must be the same as in the 8390. */
- outb(ei_status.rx_start_page, E33G_STARTPG);
- outb(ei_status.stop_page, E33G_STOPPG);
-
- /* Point the vector pointer registers somewhere ?harmless?. */
- outb(0xff, E33G_VP2); /* Point at the ROM restart location 0xffff0 */
- outb(0xff, E33G_VP1);
- outb(0x00, E33G_VP0);
- /* Turn off all interrupts until we're opened. */
- outb_p(0x00, dev->base_addr + EN0_IMR);
- /* Enable IRQs iff started. */
- outb(EGACFR_NORM, E33G_GACFR);
-
- /* Set the interrupt line. */
- outb_p((0x04 << (dev->irq == 9 ? 2 : dev->irq)), E33G_IDCFR);
- outb_p((WRD_COUNT << 1), E33G_DRQCNT); /* Set burst size to 8 */
- outb_p(0x20, E33G_DMAAH); /* Put a valid addr in the GA DMA */
- outb_p(0x00, E33G_DMAAL);
- return; /* We always succeed */
-}
-
-/*
- * Either use the shared memory (if enabled on the board) or put the packet
- * out through the ASIC FIFO.
- */
-static void
-el2_block_output(struct net_device *dev, int count,
- const unsigned char *buf, int start_page)
-{
- unsigned short int *wrd;
- int boguscount; /* timeout counter */
- unsigned short word; /* temporary for better machine code */
- void __iomem *base = ei_status.mem;
-
- if (ei_status.word16) /* Tx packets go into bank 0 on EL2/16 card */
- outb(EGACFR_RSEL|EGACFR_TCM, E33G_GACFR);
- else
- outb(EGACFR_NORM, E33G_GACFR);
-
- if (base) { /* Shared memory transfer */
- memcpy_toio(base + ((start_page - ei_status.tx_start_page) << 8),
- buf, count);
- outb(EGACFR_NORM, E33G_GACFR); /* Back to bank1 in case on bank0 */
- return;
- }
-
-/*
- * No shared memory, put the packet out the other way.
- * Set up then start the internal memory transfer to Tx Start Page
- */
-
- word = (unsigned short)start_page;
- outb(word&0xFF, E33G_DMAAH);
- outb(word>>8, E33G_DMAAL);
-
- outb_p((ei_status.interface_num ? ECNTRL_AUI : ECNTRL_THIN ) | ECNTRL_OUTPUT
- | ECNTRL_START, E33G_CNTRL);
-
-/*
- * Here I am going to write data to the FIFO as quickly as possible.
- * Note that E33G_FIFOH is defined incorrectly. It is really
- * E33G_FIFOL, the lowest port address for both the byte and
- * word write. Variable 'count' is NOT checked. Caller must supply a
- * valid count. Note that I may write a harmless extra byte to the
- * 8390 if the byte-count was not even.
- */
- wrd = (unsigned short int *) buf;
- count = (count + 1) >> 1;
- for(;;)
- {
- boguscount = 0x1000;
- while ((inb(E33G_STATUS) & ESTAT_DPRDY) == 0)
- {
- if(!boguscount--)
- {
- pr_notice("%s: FIFO blocked in el2_block_output.\n", dev->name);
- el2_reset_8390(dev);
- goto blocked;
- }
- }
- if(count > WRD_COUNT)
- {
- outsw(E33G_FIFOH, wrd, WRD_COUNT);
- wrd += WRD_COUNT;
- count -= WRD_COUNT;
- }
- else
- {
- outsw(E33G_FIFOH, wrd, count);
- break;
- }
- }
- blocked:;
- outb_p(ei_status.interface_num==0 ? ECNTRL_THIN : ECNTRL_AUI, E33G_CNTRL);
-}
-
-/* Read the 4 byte, page aligned 8390 specific header. */
-static void
-el2_get_8390_hdr(struct net_device *dev, struct e8390_pkt_hdr *hdr, int ring_page)
-{
- int boguscount;
- void __iomem *base = ei_status.mem;
- unsigned short word;
-
- if (base) { /* Use the shared memory. */
- void __iomem *hdr_start = base + ((ring_page - EL2_MB1_START_PG)<<8);
- memcpy_fromio(hdr, hdr_start, sizeof(struct e8390_pkt_hdr));
- hdr->count = le16_to_cpu(hdr->count);
- return;
- }
-
-/*
- * No shared memory, use programmed I/O.
- */
-
- word = (unsigned short)ring_page;
- outb(word&0xFF, E33G_DMAAH);
- outb(word>>8, E33G_DMAAL);
-
- outb_p((ei_status.interface_num == 0 ? ECNTRL_THIN : ECNTRL_AUI) | ECNTRL_INPUT
- | ECNTRL_START, E33G_CNTRL);
- boguscount = 0x1000;
- while ((inb(E33G_STATUS) & ESTAT_DPRDY) == 0)
- {
- if(!boguscount--)
- {
- pr_notice("%s: FIFO blocked in el2_get_8390_hdr.\n", dev->name);
- memset(hdr, 0x00, sizeof(struct e8390_pkt_hdr));
- el2_reset_8390(dev);
- goto blocked;
- }
- }
- insw(E33G_FIFOH, hdr, (sizeof(struct e8390_pkt_hdr))>> 1);
- blocked:;
- outb_p(ei_status.interface_num == 0 ? ECNTRL_THIN : ECNTRL_AUI, E33G_CNTRL);
-}
-
-
-static void
-el2_block_input(struct net_device *dev, int count, struct sk_buff *skb, int ring_offset)
-{
- int boguscount = 0;
- void __iomem *base = ei_status.mem;
- unsigned short int *buf;
- unsigned short word;
-
- /* Maybe enable shared memory just be to be safe... nahh.*/
- if (base) { /* Use the shared memory. */
- ring_offset -= (EL2_MB1_START_PG<<8);
- if (ring_offset + count > EL2_MEMSIZE) {
- /* We must wrap the input move. */
- int semi_count = EL2_MEMSIZE - ring_offset;
- memcpy_fromio(skb->data, base + ring_offset, semi_count);
- count -= semi_count;
- memcpy_fromio(skb->data + semi_count, base + ei_status.priv, count);
- } else {
- memcpy_fromio(skb->data, base + ring_offset, count);
- }
- return;
- }
-
-/*
- * No shared memory, use programmed I/O.
- */
- word = (unsigned short) ring_offset;
- outb(word>>8, E33G_DMAAH);
- outb(word&0xFF, E33G_DMAAL);
-
- outb_p((ei_status.interface_num == 0 ? ECNTRL_THIN : ECNTRL_AUI) | ECNTRL_INPUT
- | ECNTRL_START, E33G_CNTRL);
-
-/*
- * Here I also try to get data as fast as possible. I am betting that I
- * can read one extra byte without clobbering anything in the kernel because
- * this would only occur on an odd byte-count and allocation of skb->data
- * is word-aligned. Variable 'count' is NOT checked. Caller must check
- * for a valid count.
- * [This is currently quite safe.... but if one day the 3c503 explodes
- * you know where to come looking ;)]
- */
-
- buf = (unsigned short int *) skb->data;
- count = (count + 1) >> 1;
- for(;;)
- {
- boguscount = 0x1000;
- while ((inb(E33G_STATUS) & ESTAT_DPRDY) == 0)
- {
- if(!boguscount--)
- {
- pr_notice("%s: FIFO blocked in el2_block_input.\n", dev->name);
- el2_reset_8390(dev);
- goto blocked;
- }
- }
- if(count > WRD_COUNT)
- {
- insw(E33G_FIFOH, buf, WRD_COUNT);
- buf += WRD_COUNT;
- count -= WRD_COUNT;
- }
- else
- {
- insw(E33G_FIFOH, buf, count);
- break;
- }
- }
- blocked:;
- outb_p(ei_status.interface_num == 0 ? ECNTRL_THIN : ECNTRL_AUI, E33G_CNTRL);
-}
-
-
-static void netdev_get_drvinfo(struct net_device *dev,
- struct ethtool_drvinfo *info)
-{
- strlcpy(info->driver, DRV_NAME, sizeof(info->driver));
- strlcpy(info->version, DRV_VERSION, sizeof(info->version));
- snprintf(info->bus_info, sizeof(info->bus_info), "ISA 0x%lx",
- dev->base_addr);
-}
-
-static const struct ethtool_ops netdev_ethtool_ops = {
- .get_drvinfo = netdev_get_drvinfo,
-};
-
-#ifdef MODULE
-#define MAX_EL2_CARDS 4 /* Max number of EL2 cards per module */
-
-static struct net_device *dev_el2[MAX_EL2_CARDS];
-static int io[MAX_EL2_CARDS];
-static int irq[MAX_EL2_CARDS];
-static int xcvr[MAX_EL2_CARDS]; /* choose int. or ext. xcvr */
-module_param_array(io, int, NULL, 0);
-module_param_array(irq, int, NULL, 0);
-module_param_array(xcvr, int, NULL, 0);
-MODULE_PARM_DESC(io, "I/O base address(es)");
-MODULE_PARM_DESC(irq, "IRQ number(s) (assigned)");
-MODULE_PARM_DESC(xcvr, "transceiver(s) (0=internal, 1=external)");
-MODULE_DESCRIPTION("3Com ISA EtherLink II, II/16 (3c503, 3c503/16) driver");
-MODULE_LICENSE("GPL");
-
-/* This is set up so that only a single autoprobe takes place per call.
-ISA device autoprobes on a running machine are not recommended. */
-int __init
-init_module(void)
-{
- struct net_device *dev;
- int this_dev, found = 0;
-
- for (this_dev = 0; this_dev < MAX_EL2_CARDS; this_dev++) {
- if (io[this_dev] == 0) {
- if (this_dev != 0) break; /* only autoprobe 1st one */
- pr_notice("3c503.c: Presently autoprobing (not recommended) for a single card.\n");
- }
- dev = alloc_eip_netdev();
- if (!dev)
- break;
- dev->irq = irq[this_dev];
- dev->base_addr = io[this_dev];
- dev->mem_end = xcvr[this_dev]; /* low 4bits = xcvr sel. */
- if (do_el2_probe(dev) == 0) {
- dev_el2[found++] = dev;
- continue;
- }
- free_netdev(dev);
- pr_warning("3c503.c: No 3c503 card found (i/o = 0x%x).\n", io[this_dev]);
- break;
- }
- if (found)
- return 0;
- return -ENXIO;
-}
-
-static void cleanup_card(struct net_device *dev)
-{
- /* NB: el2_close() handles free_irq */
- release_region(dev->base_addr, EL2_IO_EXTENT);
- if (ei_status.mem)
- iounmap(ei_status.mem);
-}
-
-void __exit
-cleanup_module(void)
-{
- int this_dev;
-
- for (this_dev = 0; this_dev < MAX_EL2_CARDS; this_dev++) {
- struct net_device *dev = dev_el2[this_dev];
- if (dev) {
- unregister_netdev(dev);
- cleanup_card(dev);
- free_netdev(dev);
- }
- }
-}
-#endif /* MODULE */
diff --git a/drivers/net/ethernet/8390/3c503.h b/drivers/net/ethernet/8390/3c503.h
deleted file mode 100644
index e2367b82a2e..00000000000
--- a/drivers/net/ethernet/8390/3c503.h
+++ /dev/null
@@ -1,91 +0,0 @@
-/* Definitions for the 3Com 3c503 Etherlink 2. */
-/* This file is distributed under the GPL.
- Many of these names and comments are directly from the Crynwr packet
- drivers, which are released under the GPL. */
-
-#define EL2H (dev->base_addr + 0x400)
-#define EL2L (dev->base_addr)
-
-/* Vendor unique hardware addr. prefix. 3Com has 2 because they ran
- out of available addresses on the first one... */
-
-#define OLD_3COM_ID 0x02608c
-#define NEW_3COM_ID 0x0020af
-
-/* Shared memory management parameters. NB: The 8 bit cards have only
- one bank (MB1) which serves both Tx and Rx packet space. The 16bit
- cards have 2 banks, MB0 for Tx packets, and MB1 for Rx packets.
- You choose which bank appears in the sh. mem window with EGACFR_MBSn */
-
-#define EL2_MB0_START_PG (0x00) /* EL2/16 Tx packets go in bank 0 */
-#define EL2_MB1_START_PG (0x20) /* First page of bank 1 */
-#define EL2_MB1_STOP_PG (0x40) /* Last page +1 of bank 1 */
-
-/* 3Com 3c503 ASIC registers */
-#define E33G_STARTPG (EL2H+0) /* Start page, matching EN0_STARTPG */
-#define E33G_STOPPG (EL2H+1) /* Stop page, must match EN0_STOPPG */
-#define E33G_DRQCNT (EL2H+2) /* DMA burst count */
-#define E33G_IOBASE (EL2H+3) /* Read of I/O base jumpers. */
- /* (non-useful, but it also appears at the end of EPROM space) */
-#define E33G_ROMBASE (EL2H+4) /* Read of memory base jumpers. */
-#define E33G_GACFR (EL2H+5) /* Config/setup bits for the ASIC GA */
-#define E33G_CNTRL (EL2H+6) /* Board's main control register */
-#define E33G_STATUS (EL2H+7) /* Status on completions. */
-#define E33G_IDCFR (EL2H+8) /* Interrupt/DMA config register */
- /* (Which IRQ to assert, DMA chan to use) */
-#define E33G_DMAAH (EL2H+9) /* High byte of DMA address reg */
-#define E33G_DMAAL (EL2H+10) /* Low byte of DMA address reg */
-/* "Vector pointer" - if this address matches a read, the EPROM (rather than
- shared RAM) is mapped into memory space. */
-#define E33G_VP2 (EL2H+11)
-#define E33G_VP1 (EL2H+12)
-#define E33G_VP0 (EL2H+13)
-#define E33G_FIFOH (EL2H+14) /* FIFO for programmed I/O moves */
-#define E33G_FIFOL (EL2H+15) /* ... low byte of above. */
-
-/* Bits in E33G_CNTRL register: */
-
-#define ECNTRL_RESET (0x01) /* Software reset of the ASIC and 8390 */
-#define ECNTRL_THIN (0x02) /* Onboard xcvr enable, AUI disable */
-#define ECNTRL_AUI (0x00) /* Onboard xcvr disable, AUI enable */
-#define ECNTRL_SAPROM (0x04) /* Map the station address prom */
-#define ECNTRL_DBLBFR (0x20) /* FIFO configuration bit */
-#define ECNTRL_OUTPUT (0x40) /* PC-to-3C503 direction if 1 */
-#define ECNTRL_INPUT (0x00) /* 3C503-to-PC direction if 0 */
-#define ECNTRL_START (0x80) /* Start the DMA logic */
-
-/* Bits in E33G_STATUS register: */
-
-#define ESTAT_DPRDY (0x80) /* Data port (of FIFO) ready */
-#define ESTAT_UFLW (0x40) /* Tried to read FIFO when it was empty */
-#define ESTAT_OFLW (0x20) /* Tried to write FIFO when it was full */
-#define ESTAT_DTC (0x10) /* Terminal Count from PC bus DMA logic */
-#define ESTAT_DIP (0x08) /* DMA In Progress */
-
-/* Bits in E33G_GACFR register: */
-
-#define EGACFR_NIM (0x80) /* NIC interrupt mask */
-#define EGACFR_TCM (0x40) /* DMA term. count interrupt mask */
-#define EGACFR_RSEL (0x08) /* Map a bank of card mem into system mem */
-#define EGACFR_MBS2 (0x04) /* Memory bank select, bit 2. */
-#define EGACFR_MBS1 (0x02) /* Memory bank select, bit 1. */
-#define EGACFR_MBS0 (0x01) /* Memory bank select, bit 0. */
-
-#define EGACFR_NORM (0x49) /* TCM | RSEL | MBS0 */
-#define EGACFR_IRQOFF (0xc9) /* TCM | RSEL | MBS0 | NIM */
-
-/*
- MBS2 MBS1 MBS0 Sh. mem windows card mem at:
- ---- ---- ---- -----------------------------
- 0 0 0 0x0000 -- bank 0
- 0 0 1 0x2000 -- bank 1 (only choice for 8bit card)
- 0 1 0 0x4000 -- bank 2, not used
- 0 1 1 0x6000 -- bank 3, not used
-
-There was going to be a 32k card that used bank 2 and 3, but it
-never got produced.
-
-*/
-
-
-/* End of 3C503 parameter definitions */
diff --git a/drivers/net/ethernet/8390/Kconfig b/drivers/net/ethernet/8390/Kconfig
index e49a4422180..1b78ca7a978 100644
--- a/drivers/net/ethernet/8390/Kconfig
+++ b/drivers/net/ethernet/8390/Kconfig
@@ -21,18 +21,6 @@ config NET_VENDOR_8390
if NET_VENDOR_8390
-config EL2
- tristate "3c503 \"EtherLink II\" support"
- depends on ISA
- select CRC32
- ---help---
- If you have a network (Ethernet) card of this type, say Y and read
- the Ethernet-HOWTO, available from
- <http://www.tldp.org/docs.html#howto>.
-
- To compile this driver as a module, choose M here. The module
- will be called 3c503.
-
config PCMCIA_AXNET
tristate "Asix AX88190 PCMCIA support"
depends on PCMCIA
@@ -62,42 +50,6 @@ config AX88796_93CX6
---help---
Select this if your platform comes with an external 93CX6 eeprom.
-config E2100
- tristate "Cabletron E21xx support"
- depends on ISA
- select CRC32
- ---help---
- If you have a network (Ethernet) card of this type, say Y and read
- the Ethernet-HOWTO, available from
- <http://www.tldp.org/docs.html#howto>.
-
- To compile this driver as a module, choose M here. The module
- will be called e2100.
-
-config HPLAN_PLUS
- tristate "HP PCLAN+ (27247B and 27252A) support"
- depends on ISA
- select CRC32
- ---help---
- If you have a network (Ethernet) card of this type, say Y and read
- the Ethernet-HOWTO, available from
- <http://www.tldp.org/docs.html#howto>.
-
- To compile this driver as a module, choose M here. The module
- will be called hp-plus.
-
-config HPLAN
- tristate "HP PCLAN (27245 and other 27xxx series) support"
- depends on ISA
- select CRC32
- ---help---
- If you have a network (Ethernet) card of this type, say Y and read
- the Ethernet-HOWTO, available from
- <http://www.tldp.org/docs.html#howto>.
-
- To compile this driver as a module, choose M here. The module
- will be called hp.
-
config HYDRA
tristate "Hydra support"
depends on ZORRO
diff --git a/drivers/net/ethernet/8390/Makefile b/drivers/net/ethernet/8390/Makefile
index e8bb97cd355..588954a79b2 100644
--- a/drivers/net/ethernet/8390/Makefile
+++ b/drivers/net/ethernet/8390/Makefile
@@ -6,10 +6,6 @@ obj-$(CONFIG_MAC8390) += mac8390.o
obj-$(CONFIG_APNE) += apne.o 8390.o
obj-$(CONFIG_ARM_ETHERH) += etherh.o
obj-$(CONFIG_AX88796) += ax88796.o
-obj-$(CONFIG_E2100) += e2100.o 8390.o
-obj-$(CONFIG_EL2) += 3c503.o 8390p.o
-obj-$(CONFIG_HPLAN_PLUS) += hp-plus.o 8390p.o
-obj-$(CONFIG_HPLAN) += hp.o 8390p.o
obj-$(CONFIG_HYDRA) += hydra.o 8390.o
obj-$(CONFIG_MCF8390) += mcf8390.o 8390.o
obj-$(CONFIG_NE2000) += ne.o 8390p.o
diff --git a/drivers/net/ethernet/8390/e2100.c b/drivers/net/ethernet/8390/e2100.c
deleted file mode 100644
index ed55ce85ebb..00000000000
--- a/drivers/net/ethernet/8390/e2100.c
+++ /dev/null
@@ -1,489 +0,0 @@
-/* e2100.c: A Cabletron E2100 series ethernet driver for linux. */
-/*
- Written 1993-1994 by Donald Becker.
-
- Copyright 1994 by Donald Becker.
- Copyright 1993 United States Government as represented by the
- Director, National Security Agency. This software may be used and
- distributed according to the terms of the GNU General Public License,
- incorporated herein by reference.
-
- This is a driver for the Cabletron E2100 series ethercards.
-
- The Author may be reached as becker@scyld.com, or C/O
- Scyld Computing Corporation
- 410 Severn Ave., Suite 210
- Annapolis MD 21403
-
- The E2100 series ethercard is a fairly generic shared memory 8390
- implementation. The only unusual aspect is the way the shared memory
- registers are set: first you do an inb() in what is normally the
- station address region, and the low three bits of next outb() *address*
- is used as the write value for that register. Either someone wasn't
- too used to dem bit en bites, or they were trying to obfuscate the
- programming interface.
-
- There is an additional complication when setting the window on the packet
- buffer. You must first do a read into the packet buffer region with the
- low 8 address bits the address setting the page for the start of the packet
- buffer window, and then do the above operation. See mem_on() for details.
-
- One bug on the chip is that even a hard reset won't disable the memory
- window, usually resulting in a hung machine if mem_off() isn't called.
- If this happens, you must power down the machine for about 30 seconds.
-*/
-
-static const char version[] =
- "e2100.c:v1.01 7/21/94 Donald Becker (becker@cesdis.gsfc.nasa.gov)\n";
-
-#include <linux/module.h>
-#include <linux/kernel.h>
-#include <linux/errno.h>
-#include <linux/string.h>
-#include <linux/ioport.h>
-#include <linux/netdevice.h>
-#include <linux/etherdevice.h>
-#include <linux/init.h>
-#include <linux/interrupt.h>
-#include <linux/delay.h>
-
-#include <asm/io.h>
-
-#include "8390.h"
-
-#define DRV_NAME "e2100"
-
-static int e21_probe_list[] = {0x300, 0x280, 0x380, 0x220, 0};
-
-/* Offsets from the base_addr.
- Read from the ASIC register, and the low three bits of the next outb()
- address is used to set the corresponding register. */
-#define E21_NIC_OFFSET 0 /* Offset to the 8390 NIC. */
-#define E21_ASIC 0x10
-#define E21_MEM_ENABLE 0x10
-#define E21_MEM_ON 0x05 /* Enable memory in 16 bit mode. */
-#define E21_MEM_ON_8 0x07 /* Enable memory in 8 bit mode. */
-#define E21_MEM_BASE 0x11
-#define E21_IRQ_LOW 0x12 /* The low three bits of the IRQ number. */
-#define E21_IRQ_HIGH 0x14 /* The high IRQ bit and media select ... */
-#define E21_MEDIA 0x14 /* (alias). */
-#define E21_ALT_IFPORT 0x02 /* Set to use the other (BNC,AUI) port. */
-#define E21_BIG_MEM 0x04 /* Use a bigger (64K) buffer (we don't) */
-#define E21_SAPROM 0x10 /* Offset to station address data. */
-#define E21_IO_EXTENT 0x20
-
-static inline void mem_on(short port, volatile char __iomem *mem_base,
- unsigned char start_page )
-{
- /* This is a little weird: set the shared memory window by doing a
- read. The low address bits specify the starting page. */
- readb(mem_base+start_page);
- inb(port + E21_MEM_ENABLE);
- outb(E21_MEM_ON, port + E21_MEM_ENABLE + E21_MEM_ON);
-}
-
-static inline void mem_off(short port)
-{
- inb(port + E21_MEM_ENABLE);
- outb(0x00, port + E21_MEM_ENABLE);
-}
-
-/* In other drivers I put the TX pages first, but the E2100 window circuitry
- is designed to have a 4K Tx region last. The windowing circuitry wraps the
- window at 0x2fff->0x0000 so that the packets at e.g. 0x2f00 in the RX ring
- appear contiguously in the window. */
-#define E21_RX_START_PG 0x00 /* First page of RX buffer */
-#define E21_RX_STOP_PG 0x30 /* Last page +1 of RX ring */
-#define E21_BIG_RX_STOP_PG 0xF0 /* Last page +1 of RX ring */
-#define E21_TX_START_PG E21_RX_STOP_PG /* First page of TX buffer */
-
-static int e21_probe1(struct net_device *dev, int ioaddr);
-
-static int e21_open(struct net_device *dev);
-static void e21_reset_8390(struct net_device *dev);
-static void e21_block_input(struct net_device *dev, int count,
- struct sk_buff *skb, int ring_offset);
-static void e21_block_output(struct net_device *dev, int count,
- const unsigned char *buf, int start_page);
-static void e21_get_8390_hdr(struct net_device *dev, struct e8390_pkt_hdr *hdr,
- int ring_page);
-static int e21_open(struct net_device *dev);
-static int e21_close(struct net_device *dev);
-
-
-/* Probe for the E2100 series ethercards. These cards have an 8390 at the
- base address and the station address at both offset 0x10 and 0x18. I read
- the station address from offset 0x18 to avoid the dataport of NE2000
- ethercards, and look for Ctron's unique ID (first three octets of the
- station address).
- */
-
-static int __init do_e2100_probe(struct net_device *dev)
-{
- int *port;
- int base_addr = dev->base_addr;
- int irq = dev->irq;
-
- if (base_addr > 0x1ff) /* Check a single specified location. */
- return e21_probe1(dev, base_addr);
- else if (base_addr != 0) /* Don't probe at all. */
- return -ENXIO;
-
- for (port = e21_probe_list; *port; port++) {
- dev->irq = irq;
- if (e21_probe1(dev, *port) == 0)
- return 0;
- }
-
- return -ENODEV;
-}
-
-#ifndef MODULE
-struct net_device * __init e2100_probe(int unit)
-{
- struct net_device *dev = alloc_ei_netdev();
- int err;
-
- if (!dev)
- return ERR_PTR(-ENOMEM);
-
- sprintf(dev->name, "eth%d", unit);
- netdev_boot_setup_check(dev);
-
- err = do_e2100_probe(dev);
- if (err)
- goto out;
- return dev;
-out:
- free_netdev(dev);
- return ERR_PTR(err);
-}
-#endif
-
-static const struct net_device_ops e21_netdev_ops = {
- .ndo_open = e21_open,
- .ndo_stop = e21_close,
-
- .ndo_start_xmit = ei_start_xmit,
- .ndo_tx_timeout = ei_tx_timeout,
- .ndo_get_stats = ei_get_stats,
- .ndo_set_rx_mode = ei_set_multicast_list,
- .ndo_validate_addr = eth_validate_addr,
- .ndo_set_mac_address = eth_mac_addr,
- .ndo_change_mtu = eth_change_mtu,
-#ifdef CONFIG_NET_POLL_CONTROLLER
- .ndo_poll_controller = ei_poll,
-#endif
-};
-
-static int __init e21_probe1(struct net_device *dev, int ioaddr)
-{
- int i, status, retval;
- unsigned char *station_addr = dev->dev_addr;
- static unsigned version_printed;
-
- if (!request_region(ioaddr, E21_IO_EXTENT, DRV_NAME))
- return -EBUSY;
-
- /* First check the station address for the Ctron prefix. */
- if (inb(ioaddr + E21_SAPROM + 0) != 0x00 ||
- inb(ioaddr + E21_SAPROM + 1) != 0x00 ||
- inb(ioaddr + E21_SAPROM + 2) != 0x1d) {
- retval = -ENODEV;
- goto out;
- }
-
- /* Verify by making certain that there is a 8390 at there. */
- outb(E8390_NODMA + E8390_STOP, ioaddr);
- udelay(1); /* we want to delay one I/O cycle - which is 2MHz */
- status = inb(ioaddr);
- if (status != 0x21 && status != 0x23) {
- retval = -ENODEV;
- goto out;
- }
-
- /* Read the station address PROM. */
- for (i = 0; i < 6; i++)
- station_addr[i] = inb(ioaddr + E21_SAPROM + i);
-
- inb(ioaddr + E21_MEDIA); /* Point to media selection. */
- outb(0, ioaddr + E21_ASIC); /* and disable the secondary interface. */
-
- if (ei_debug && version_printed++ == 0)
- printk(version);
-
- for (i = 0; i < 6; i++)
- printk(" %02X", station_addr[i]);
-
- if (dev->irq < 2) {
- static const int irqlist[] = {15, 11, 10, 12, 5, 9, 3, 4};
- for (i = 0; i < ARRAY_SIZE(irqlist); i++)
- if (request_irq (irqlist[i], NULL, 0, "bogus", NULL) != -EBUSY) {
- dev->irq = irqlist[i];
- break;
- }
- if (i >= ARRAY_SIZE(irqlist)) {
- printk(" unable to get IRQ %d.\n", dev->irq);
- retval = -EAGAIN;
- goto out;
- }
- } else if (dev->irq == 2) /* Fixup luser bogosity: IRQ2 is really IRQ9 */
- dev->irq = 9;
-
- /* The 8390 is at the base address. */
- dev->base_addr = ioaddr;
-
- ei_status.name = "E2100";
- ei_status.word16 = 1;
- ei_status.tx_start_page = E21_TX_START_PG;
- ei_status.rx_start_page = E21_RX_START_PG;
- ei_status.stop_page = E21_RX_STOP_PG;
- ei_status.saved_irq = dev->irq;
-
- /* Check the media port used. The port can be passed in on the
- low mem_end bits. */
- if (dev->mem_end & 15)
- dev->if_port = dev->mem_end & 7;
- else {
- dev->if_port = 0;
- inb(ioaddr + E21_MEDIA); /* Turn automatic media detection on. */
- for(i = 0; i < 6; i++)
- if (station_addr[i] != inb(ioaddr + E21_SAPROM + 8 + i)) {
- dev->if_port = 1;
- break;
- }
- }
-
- /* Never map in the E21 shared memory unless you are actively using it.
- Also, the shared memory has effective only one setting -- spread all
- over the 128K region! */
- if (dev->mem_start == 0)
- dev->mem_start = 0xd0000;
-
- ei_status.mem = ioremap(dev->mem_start, 2*1024);
- if (!ei_status.mem) {
- printk("unable to remap memory\n");
- retval = -EAGAIN;
- goto out;
- }
-
-#ifdef notdef
- /* These values are unused. The E2100 has a 2K window into the packet
- buffer. The window can be set to start on any page boundary. */
- ei_status.rmem_start = dev->mem_start + TX_PAGES*256;
- dev->mem_end = ei_status.rmem_end = dev->mem_start + 2*1024;
-#endif
-
- printk(", IRQ %d, %s media, memory @ %#lx.\n", dev->irq,
- dev->if_port ? "secondary" : "primary", dev->mem_start);
-
- ei_status.reset_8390 = &e21_reset_8390;
- ei_status.block_input = &e21_block_input;
- ei_status.block_output = &e21_block_output;
- ei_status.get_8390_hdr = &e21_get_8390_hdr;
-
- dev->netdev_ops = &e21_netdev_ops;
- NS8390_init(dev, 0);
-
- retval = register_netdev(dev);
- if (retval)
- goto out;
- return 0;
-out:
- release_region(ioaddr, E21_IO_EXTENT);
- return retval;
-}
-
-static int
-e21_open(struct net_device *dev)
-{
- short ioaddr = dev->base_addr;
- int retval;
-
- if ((retval = request_irq(dev->irq, ei_interrupt, 0, dev->name, dev)))
- return retval;
-
- /* Set the interrupt line and memory base on the hardware. */
- inb(ioaddr + E21_IRQ_LOW);
- outb(0, ioaddr + E21_ASIC + (dev->irq & 7));
- inb(ioaddr + E21_IRQ_HIGH); /* High IRQ bit, and if_port. */
- outb(0, ioaddr + E21_ASIC + (dev->irq > 7 ? 1:0)
- + (dev->if_port ? E21_ALT_IFPORT : 0));
- inb(ioaddr + E21_MEM_BASE);
- outb(0, ioaddr + E21_ASIC + ((dev->mem_start >> 17) & 7));
-
- ei_open(dev);
- return 0;
-}
-
-static void
-e21_reset_8390(struct net_device *dev)
-{
- short ioaddr = dev->base_addr;
-
- outb(0x01, ioaddr);
- if (ei_debug > 1) printk("resetting the E2180x3 t=%ld...", jiffies);
- ei_status.txing = 0;
-
- /* Set up the ASIC registers, just in case something changed them. */
-
- if (ei_debug > 1) printk("reset done\n");
-}
-
-/* Grab the 8390 specific header. We put the 2k window so the header page
- appears at the start of the shared memory. */
-
-static void
-e21_get_8390_hdr(struct net_device *dev, struct e8390_pkt_hdr *hdr, int ring_page)
-{
-
- short ioaddr = dev->base_addr;
- char __iomem *shared_mem = ei_status.mem;
-
- mem_on(ioaddr, shared_mem, ring_page);
-
-#ifdef notdef
- /* Officially this is what we are doing, but the readl() is faster */
- memcpy_fromio(hdr, shared_mem, sizeof(struct e8390_pkt_hdr));
-#else
- ((unsigned int*)hdr)[0] = readl(shared_mem);
-#endif
-
- /* Turn off memory access: we would need to reprogram the window anyway. */
- mem_off(ioaddr);
-
-}
-
-/* Block input and output are easy on shared memory ethercards.
- The E21xx makes block_input() especially easy by wrapping the top
- ring buffer to the bottom automatically. */
-static void
-e21_block_input(struct net_device *dev, int count, struct sk_buff *skb, int ring_offset)
-{
- short ioaddr = dev->base_addr;
- char __iomem *shared_mem = ei_status.mem;
-
- mem_on(ioaddr, shared_mem, (ring_offset>>8));
-
- memcpy_fromio(skb->data, ei_status.mem + (ring_offset & 0xff), count);
-
- mem_off(ioaddr);
-}
-
-static void
-e21_block_output(struct net_device *dev, int count, const unsigned char *buf,
- int start_page)
-{
- short ioaddr = dev->base_addr;
- volatile char __iomem *shared_mem = ei_status.mem;
-
- /* Set the shared memory window start by doing a read, with the low address
- bits specifying the starting page. */
- readb(shared_mem + start_page);
- mem_on(ioaddr, shared_mem, start_page);
-
- memcpy_toio(shared_mem, buf, count);
- mem_off(ioaddr);
-}
-
-static int
-e21_close(struct net_device *dev)
-{
- short ioaddr = dev->base_addr;
-
- if (ei_debug > 1)
- printk("%s: Shutting down ethercard.\n", dev->name);
-
- free_irq(dev->irq, dev);
- dev->irq = ei_status.saved_irq;
-
- /* Shut off the interrupt line and secondary interface. */
- inb(ioaddr + E21_IRQ_LOW);
- outb(0, ioaddr + E21_ASIC);
- inb(ioaddr + E21_IRQ_HIGH); /* High IRQ bit, and if_port. */
- outb(0, ioaddr + E21_ASIC);
-
- ei_close(dev);
-
- /* Double-check that the memory has been turned off, because really
- really bad things happen if it isn't. */
- mem_off(ioaddr);
-
- return 0;
-}
-
-
-#ifdef MODULE
-#define MAX_E21_CARDS 4 /* Max number of E21 cards per module */
-static struct net_device *dev_e21[MAX_E21_CARDS];
-static int io[MAX_E21_CARDS];
-static int irq[MAX_E21_CARDS];
-static int mem[MAX_E21_CARDS];
-static int xcvr[MAX_E21_CARDS]; /* choose int. or ext. xcvr */
-
-module_param_array(io, int, NULL, 0);
-module_param_array(irq, int, NULL, 0);
-module_param_array(mem, int, NULL, 0);
-module_param_array(xcvr, int, NULL, 0);
-MODULE_PARM_DESC(io, "I/O base address(es)");
-MODULE_PARM_DESC(irq, "IRQ number(s)");
-MODULE_PARM_DESC(mem, " memory base address(es)");
-MODULE_PARM_DESC(xcvr, "transceiver(s) (0=internal, 1=external)");
-MODULE_DESCRIPTION("Cabletron E2100 ISA ethernet driver");
-MODULE_LICENSE("GPL");
-
-/* This is set up so that only a single autoprobe takes place per call.
-ISA device autoprobes on a running machine are not recommended. */
-
-int __init init_module(void)
-{
- struct net_device *dev;
- int this_dev, found = 0;
-
- for (this_dev = 0; this_dev < MAX_E21_CARDS; this_dev++) {
- if (io[this_dev] == 0) {
- if (this_dev != 0) break; /* only autoprobe 1st one */
- printk(KERN_NOTICE "e2100.c: Presently autoprobing (not recommended) for a single card.\n");
- }
- dev = alloc_ei_netdev();
- if (!dev)
- break;
- dev->irq = irq[this_dev];
- dev->base_addr = io[this_dev];
- dev->mem_start = mem[this_dev];
- dev->mem_end = xcvr[this_dev]; /* low 4bits = xcvr sel. */
- if (do_e2100_probe(dev) == 0) {
- dev_e21[found++] = dev;
- continue;
- }
- free_netdev(dev);
- printk(KERN_WARNING "e2100.c: No E2100 card found (i/o = 0x%x).\n", io[this_dev]);
- break;
- }
- if (found)
- return 0;
- return -ENXIO;
-}
-
-static void cleanup_card(struct net_device *dev)
-{
- /* NB: e21_close() handles free_irq */
- iounmap(ei_status.mem);
- release_region(dev->base_addr, E21_IO_EXTENT);
-}
-
-void __exit
-cleanup_module(void)
-{
- int this_dev;
-
- for (this_dev = 0; this_dev < MAX_E21_CARDS; this_dev++) {
- struct net_device *dev = dev_e21[this_dev];
- if (dev) {
- unregister_netdev(dev);
- cleanup_card(dev);
- free_netdev(dev);
- }
- }
-}
-#endif /* MODULE */
diff --git a/drivers/net/ethernet/8390/hp-plus.c b/drivers/net/ethernet/8390/hp-plus.c
deleted file mode 100644
index 52f70f999c0..00000000000
--- a/drivers/net/ethernet/8390/hp-plus.c
+++ /dev/null
@@ -1,505 +0,0 @@
-/* hp-plus.c: A HP PCLAN/plus ethernet driver for linux. */
-/*
- Written 1994 by Donald Becker.
-
- This driver is for the Hewlett Packard PC LAN (27***) plus ethercards.
- These cards are sold under several model numbers, usually 2724*.
-
- This software may be used and distributed according to the terms
- of the GNU General Public License, incorporated herein by reference.
-
- The author may be reached as becker@scyld.com, or C/O
- Scyld Computing Corporation
- 410 Severn Ave., Suite 210
- Annapolis MD 21403
-
- As is often the case, a great deal of credit is owed to Russ Nelson.
- The Crynwr packet driver was my primary source of HP-specific
- programming information.
-*/
-
-static const char version[] =
-"hp-plus.c:v1.10 9/24/94 Donald Becker (becker@cesdis.gsfc.nasa.gov)\n";
-
-#include <linux/module.h>
-
-#include <linux/string.h> /* Important -- this inlines word moves. */
-#include <linux/kernel.h>
-#include <linux/errno.h>
-#include <linux/ioport.h>
-#include <linux/netdevice.h>
-#include <linux/etherdevice.h>
-#include <linux/init.h>
-#include <linux/interrupt.h>
-#include <linux/delay.h>
-
-#include <asm/io.h>
-
-#include "8390.h"
-
-#define DRV_NAME "hp-plus"
-
-/* A zero-terminated list of I/O addresses to be probed. */
-static unsigned int hpplus_portlist[] __initdata =
-{0x200, 0x240, 0x280, 0x2C0, 0x300, 0x320, 0x340, 0};
-
-/*
- The HP EtherTwist chip implementation is a fairly routine DP8390
- implementation. It allows both shared memory and programmed-I/O buffer
- access, using a custom interface for both. The programmed-I/O mode is
- entirely implemented in the HP EtherTwist chip, bypassing the problem
- ridden built-in 8390 facilities used on NE2000 designs. The shared
- memory mode is likewise special, with an offset register used to make
- packets appear at the shared memory base. Both modes use a base and bounds
- page register to hide the Rx ring buffer wrap -- a packet that spans the
- end of physical buffer memory appears continuous to the driver. (c.f. the
- 3c503 and Cabletron E2100)
-
- A special note: the internal buffer of the board is only 8 bits wide.
- This lays several nasty traps for the unaware:
- - the 8390 must be programmed for byte-wide operations
- - all I/O and memory operations must work on whole words (the access
- latches are serially preloaded and have no byte-swapping ability).
-
- This board is laid out in I/O space much like the earlier HP boards:
- the first 16 locations are for the board registers, and the second 16 are
- for the 8390. The board is easy to identify, with both a dedicated 16 bit
- ID register and a constant 0x530* value in the upper bits of the paging
- register.
-*/
-
-#define HP_ID 0x00 /* ID register, always 0x4850. */
-#define HP_PAGING 0x02 /* Registers visible @ 8-f, see PageName. */
-#define HPP_OPTION 0x04 /* Bitmapped options, see HP_Option. */
-#define HPP_OUT_ADDR 0x08 /* I/O output location in Perf_Page. */
-#define HPP_IN_ADDR 0x0A /* I/O input location in Perf_Page. */
-#define HP_DATAPORT 0x0c /* I/O data transfer in Perf_Page. */
-#define NIC_OFFSET 0x10 /* Offset to the 8390 registers. */
-#define HP_IO_EXTENT 32
-
-#define HP_START_PG 0x00 /* First page of TX buffer */
-#define HP_STOP_PG 0x80 /* Last page +1 of RX ring */
-
-/* The register set selected in HP_PAGING. */
-enum PageName {
- Perf_Page = 0, /* Normal operation. */
- MAC_Page = 1, /* The ethernet address (+checksum). */
- HW_Page = 2, /* EEPROM-loaded hardware parameters. */
- LAN_Page = 4, /* Transceiver selection, testing, etc. */
- ID_Page = 6 };
-
-/* The bit definitions for the HPP_OPTION register. */
-enum HP_Option {
- NICReset = 1, ChipReset = 2, /* Active low, really UNreset. */
- EnableIRQ = 4, FakeIntr = 8, BootROMEnb = 0x10, IOEnb = 0x20,
- MemEnable = 0x40, ZeroWait = 0x80, MemDisable = 0x1000, };
-
-static int hpp_probe1(struct net_device *dev, int ioaddr);
-
-static void hpp_reset_8390(struct net_device *dev);
-static int hpp_open(struct net_device *dev);
-static int hpp_close(struct net_device *dev);
-static void hpp_mem_block_input(struct net_device *dev, int count,
- struct sk_buff *skb, int ring_offset);
-static void hpp_mem_block_output(struct net_device *dev, int count,
- const unsigned char *buf, int start_page);
-static void hpp_mem_get_8390_hdr(struct net_device *dev, struct e8390_pkt_hdr *hdr,
- int ring_page);
-static void hpp_io_block_input(struct net_device *dev, int count,
- struct sk_buff *skb, int ring_offset);
-static void hpp_io_block_output(struct net_device *dev, int count,
- const unsigned char *buf, int start_page);
-static void hpp_io_get_8390_hdr(struct net_device *dev, struct e8390_pkt_hdr *hdr,
- int ring_page);
-
-
-/* Probe a list of addresses for an HP LAN+ adaptor.
- This routine is almost boilerplate. */
-
-static int __init do_hpp_probe(struct net_device *dev)
-{
- int i;
- int base_addr = dev->base_addr;
- int irq = dev->irq;
-
- if (base_addr > 0x1ff) /* Check a single specified location. */
- return hpp_probe1(dev, base_addr);
- else if (base_addr != 0) /* Don't probe at all. */
- return -ENXIO;
-
- for (i = 0; hpplus_portlist[i]; i++) {
- if (hpp_probe1(dev, hpplus_portlist[i]) == 0)
- return 0;
- dev->irq = irq;
- }
-
- return -ENODEV;
-}
-
-#ifndef MODULE
-struct net_device * __init hp_plus_probe(int unit)
-{
- struct net_device *dev = alloc_eip_netdev();
- int err;
-
- if (!dev)
- return ERR_PTR(-ENOMEM);
-
- sprintf(dev->name, "eth%d", unit);
- netdev_boot_setup_check(dev);
-
- err = do_hpp_probe(dev);
- if (err)
- goto out;
- return dev;
-out:
- free_netdev(dev);
- return ERR_PTR(err);
-}
-#endif
-
-static const struct net_device_ops hpp_netdev_ops = {
- .ndo_open = hpp_open,
- .ndo_stop = hpp_close,
- .ndo_start_xmit = eip_start_xmit,
- .ndo_tx_timeout = eip_tx_timeout,
- .ndo_get_stats = eip_get_stats,
- .ndo_set_rx_mode = eip_set_multicast_list,
- .ndo_validate_addr = eth_validate_addr,
- .ndo_set_mac_address = eth_mac_addr,
- .ndo_change_mtu = eth_change_mtu,
-#ifdef CONFIG_NET_POLL_CONTROLLER
- .ndo_poll_controller = eip_poll,
-#endif
-};
-
-
-/* Do the interesting part of the probe at a single address. */
-static int __init hpp_probe1(struct net_device *dev, int ioaddr)
-{
- int i, retval;
- unsigned char checksum = 0;
- const char name[] = "HP-PC-LAN+";
- int mem_start;
- static unsigned version_printed;
-
- if (!request_region(ioaddr, HP_IO_EXTENT, DRV_NAME))
- return -EBUSY;
-
- /* Check for the HP+ signature, 50 48 0x 53. */
- if (inw(ioaddr + HP_ID) != 0x4850 ||
- (inw(ioaddr + HP_PAGING) & 0xfff0) != 0x5300) {
- retval = -ENODEV;
- goto out;
- }
-
- if (ei_debug && version_printed++ == 0)
- printk(version);
-
- printk("%s: %s at %#3x, ", dev->name, name, ioaddr);
-
- /* Retrieve and checksum the station address. */
- outw(MAC_Page, ioaddr + HP_PAGING);
-
- for(i = 0; i < ETH_ALEN; i++) {
- unsigned char inval = inb(ioaddr + 8 + i);
- dev->dev_addr[i] = inval;
- checksum += inval;
- }
- checksum += inb(ioaddr + 14);
-
- printk("%pM", dev->dev_addr);
-
- if (checksum != 0xff) {
- printk(" bad checksum %2.2x.\n", checksum);
- retval = -ENODEV;
- goto out;
- } else {
- /* Point at the Software Configuration Flags. */
- outw(ID_Page, ioaddr + HP_PAGING);
- printk(" ID %4.4x", inw(ioaddr + 12));
- }
-
- /* Read the IRQ line. */
- outw(HW_Page, ioaddr + HP_PAGING);
- {
- int irq = inb(ioaddr + 13) & 0x0f;
- int option = inw(ioaddr + HPP_OPTION);
-
- dev->irq = irq;
- if (option & MemEnable) {
- mem_start = inw(ioaddr + 9) << 8;
- printk(", IRQ %d, memory address %#x.\n", irq, mem_start);
- } else {
- mem_start = 0;
- printk(", IRQ %d, programmed-I/O mode.\n", irq);
- }
- }
-
- /* Set the wrap registers for string I/O reads. */
- outw((HP_START_PG + TX_PAGES/2) | ((HP_STOP_PG - 1) << 8), ioaddr + 14);
-
- /* Set the base address to point to the NIC, not the "real" base! */
- dev->base_addr = ioaddr + NIC_OFFSET;
-
- dev->netdev_ops = &hpp_netdev_ops;
-
- ei_status.name = name;
- ei_status.word16 = 0; /* Agggghhhhh! Debug time: 2 days! */
- ei_status.tx_start_page = HP_START_PG;
- ei_status.rx_start_page = HP_START_PG + TX_PAGES/2;
- ei_status.stop_page = HP_STOP_PG;
-
- ei_status.reset_8390 = &hpp_reset_8390;
- ei_status.block_input = &hpp_io_block_input;
- ei_status.block_output = &hpp_io_block_output;
- ei_status.get_8390_hdr = &hpp_io_get_8390_hdr;
-
- /* Check if the memory_enable flag is set in the option register. */
- if (mem_start) {
- ei_status.block_input = &hpp_mem_block_input;
- ei_status.block_output = &hpp_mem_block_output;
- ei_status.get_8390_hdr = &hpp_mem_get_8390_hdr;
- dev->mem_start = mem_start;
- ei_status.mem = ioremap(mem_start,
- (HP_STOP_PG - HP_START_PG)*256);
- if (!ei_status.mem) {
- retval = -ENOMEM;
- goto out;
- }
- ei_status.rmem_start = dev->mem_start + TX_PAGES/2*256;
- dev->mem_end = ei_status.rmem_end
- = dev->mem_start + (HP_STOP_PG - HP_START_PG)*256;
- }
-
- outw(Perf_Page, ioaddr + HP_PAGING);
- NS8390p_init(dev, 0);
- /* Leave the 8390 and HP chip reset. */
- outw(inw(ioaddr + HPP_OPTION) & ~EnableIRQ, ioaddr + HPP_OPTION);
-
- retval = register_netdev(dev);
- if (retval)
- goto out1;
- return 0;
-out1:
- iounmap(ei_status.mem);
-out:
- release_region(ioaddr, HP_IO_EXTENT);
- return retval;
-}
-
-static int
-hpp_open(struct net_device *dev)
-{
- int ioaddr = dev->base_addr - NIC_OFFSET;
- int option_reg;
- int retval;
-
- if ((retval = request_irq(dev->irq, eip_interrupt, 0, dev->name, dev))) {
- return retval;
- }
-
- /* Reset the 8390 and HP chip. */
- option_reg = inw(ioaddr + HPP_OPTION);
- outw(option_reg & ~(NICReset + ChipReset), ioaddr + HPP_OPTION);
- udelay(5);
- /* Unreset the board and enable interrupts. */
- outw(option_reg | (EnableIRQ + NICReset + ChipReset), ioaddr + HPP_OPTION);
-
- /* Set the wrap registers for programmed-I/O operation. */
- outw(HW_Page, ioaddr + HP_PAGING);
- outw((HP_START_PG + TX_PAGES/2) | ((HP_STOP_PG - 1) << 8), ioaddr + 14);
-
- /* Select the operational page. */
- outw(Perf_Page, ioaddr + HP_PAGING);
-
- return eip_open(dev);
-}
-
-static int
-hpp_close(struct net_device *dev)
-{
- int ioaddr = dev->base_addr - NIC_OFFSET;
- int option_reg = inw(ioaddr + HPP_OPTION);
-
- free_irq(dev->irq, dev);
- eip_close(dev);
- outw((option_reg & ~EnableIRQ) | MemDisable | NICReset | ChipReset,
- ioaddr + HPP_OPTION);
-
- return 0;
-}
-
-static void
-hpp_reset_8390(struct net_device *dev)
-{
- int ioaddr = dev->base_addr - NIC_OFFSET;
- int option_reg = inw(ioaddr + HPP_OPTION);
-
- if (ei_debug > 1) printk("resetting the 8390 time=%ld...", jiffies);
-
- outw(option_reg & ~(NICReset + ChipReset), ioaddr + HPP_OPTION);
- /* Pause a few cycles for the hardware reset to take place. */
- udelay(5);
- ei_status.txing = 0;
- outw(option_reg | (EnableIRQ + NICReset + ChipReset), ioaddr + HPP_OPTION);
-
- udelay(5);
-
-
- if ((inb_p(ioaddr+NIC_OFFSET+EN0_ISR) & ENISR_RESET) == 0)
- printk("%s: hp_reset_8390() did not complete.\n", dev->name);
-
- if (ei_debug > 1) printk("8390 reset done (%ld).", jiffies);
-}
-
-/* The programmed-I/O version of reading the 4 byte 8390 specific header.
- Note that transfer with the EtherTwist+ must be on word boundaries. */
-
-static void
-hpp_io_get_8390_hdr(struct net_device *dev, struct e8390_pkt_hdr *hdr, int ring_page)
-{
- int ioaddr = dev->base_addr - NIC_OFFSET;
-
- outw((ring_page<<8), ioaddr + HPP_IN_ADDR);
- insw(ioaddr + HP_DATAPORT, hdr, sizeof(struct e8390_pkt_hdr)>>1);
-}
-
-/* Block input and output, similar to the Crynwr packet driver. */
-
-static void
-hpp_io_block_input(struct net_device *dev, int count, struct sk_buff *skb, int ring_offset)
-{
- int ioaddr = dev->base_addr - NIC_OFFSET;
- char *buf = skb->data;
-
- outw(ring_offset, ioaddr + HPP_IN_ADDR);
- insw(ioaddr + HP_DATAPORT, buf, count>>1);
- if (count & 0x01)
- buf[count-1] = inw(ioaddr + HP_DATAPORT);
-}
-
-/* The corresponding shared memory versions of the above 2 functions. */
-
-static void
-hpp_mem_get_8390_hdr(struct net_device *dev, struct e8390_pkt_hdr *hdr, int ring_page)
-{
- int ioaddr = dev->base_addr - NIC_OFFSET;
- int option_reg = inw(ioaddr + HPP_OPTION);
-
- outw((ring_page<<8), ioaddr + HPP_IN_ADDR);
- outw(option_reg & ~(MemDisable + BootROMEnb), ioaddr + HPP_OPTION);
- memcpy_fromio(hdr, ei_status.mem, sizeof(struct e8390_pkt_hdr));
- outw(option_reg, ioaddr + HPP_OPTION);
- hdr->count = (le16_to_cpu(hdr->count) + 3) & ~3; /* Round up allocation. */
-}
-
-static void
-hpp_mem_block_input(struct net_device *dev, int count, struct sk_buff *skb, int ring_offset)
-{
- int ioaddr = dev->base_addr - NIC_OFFSET;
- int option_reg = inw(ioaddr + HPP_OPTION);
-
- outw(ring_offset, ioaddr + HPP_IN_ADDR);
-
- outw(option_reg & ~(MemDisable + BootROMEnb), ioaddr + HPP_OPTION);
-
- /* Caution: this relies on get_8390_hdr() rounding up count!
- Also note that we *can't* use eth_io_copy_and_sum() because
- it will not always copy "count" bytes (e.g. padded IP). */
-
- memcpy_fromio(skb->data, ei_status.mem, count);
- outw(option_reg, ioaddr + HPP_OPTION);
-}
-
-/* A special note: we *must* always transfer >=16 bit words.
- It's always safe to round up, so we do. */
-static void
-hpp_io_block_output(struct net_device *dev, int count,
- const unsigned char *buf, int start_page)
-{
- int ioaddr = dev->base_addr - NIC_OFFSET;
- outw(start_page << 8, ioaddr + HPP_OUT_ADDR);
- outsl(ioaddr + HP_DATAPORT, buf, (count+3)>>2);
-}
-
-static void
-hpp_mem_block_output(struct net_device *dev, int count,
- const unsigned char *buf, int start_page)
-{
- int ioaddr = dev->base_addr - NIC_OFFSET;
- int option_reg = inw(ioaddr + HPP_OPTION);
-
- outw(start_page << 8, ioaddr + HPP_OUT_ADDR);
- outw(option_reg & ~(MemDisable + BootROMEnb), ioaddr + HPP_OPTION);
- memcpy_toio(ei_status.mem, buf, (count + 3) & ~3);
- outw(option_reg, ioaddr + HPP_OPTION);
-}
-
-
-#ifdef MODULE
-#define MAX_HPP_CARDS 4 /* Max number of HPP cards per module */
-static struct net_device *dev_hpp[MAX_HPP_CARDS];
-static int io[MAX_HPP_CARDS];
-static int irq[MAX_HPP_CARDS];
-
-module_param_array(io, int, NULL, 0);
-module_param_array(irq, int, NULL, 0);
-MODULE_PARM_DESC(io, "I/O port address(es)");
-MODULE_PARM_DESC(irq, "IRQ number(s); ignored if properly detected");
-MODULE_DESCRIPTION("HP PC-LAN+ ISA ethernet driver");
-MODULE_LICENSE("GPL");
-
-/* This is set up so that only a single autoprobe takes place per call.
-ISA device autoprobes on a running machine are not recommended. */
-int __init
-init_module(void)
-{
- struct net_device *dev;
- int this_dev, found = 0;
-
- for (this_dev = 0; this_dev < MAX_HPP_CARDS; this_dev++) {
- if (io[this_dev] == 0) {
- if (this_dev != 0) break; /* only autoprobe 1st one */
- printk(KERN_NOTICE "hp-plus.c: Presently autoprobing (not recommended) for a single card.\n");
- }
- dev = alloc_eip_netdev();
- if (!dev)
- break;
- dev->irq = irq[this_dev];
- dev->base_addr = io[this_dev];
- if (do_hpp_probe(dev) == 0) {
- dev_hpp[found++] = dev;
- continue;
- }
- free_netdev(dev);
- printk(KERN_WARNING "hp-plus.c: No HP-Plus card found (i/o = 0x%x).\n", io[this_dev]);
- break;
- }
- if (found)
- return 0;
- return -ENXIO;
-}
-
-static void cleanup_card(struct net_device *dev)
-{
- /* NB: hpp_close() handles free_irq */
- iounmap(ei_status.mem);
- release_region(dev->base_addr - NIC_OFFSET, HP_IO_EXTENT);
-}
-
-void __exit
-cleanup_module(void)
-{
- int this_dev;
-
- for (this_dev = 0; this_dev < MAX_HPP_CARDS; this_dev++) {
- struct net_device *dev = dev_hpp[this_dev];
- if (dev) {
- unregister_netdev(dev);
- cleanup_card(dev);
- free_netdev(dev);
- }
- }
-}
-#endif /* MODULE */
diff --git a/drivers/net/ethernet/8390/hp.c b/drivers/net/ethernet/8390/hp.c
deleted file mode 100644
index 37fa89aa457..00000000000
--- a/drivers/net/ethernet/8390/hp.c
+++ /dev/null
@@ -1,438 +0,0 @@
-/* hp.c: A HP LAN ethernet driver for linux. */
-/*
- Written 1993-94 by Donald Becker.
-
- Copyright 1993 United States Government as represented by the
- Director, National Security Agency.
-
- This software may be used and distributed according to the terms
- of the GNU General Public License, incorporated herein by reference.
-
- The author may be reached as becker@scyld.com, or C/O
- Scyld Computing Corporation
- 410 Severn Ave., Suite 210
- Annapolis MD 21403
-
- This is a driver for the HP PC-LAN adaptors.
-
- Sources:
- The Crynwr packet driver.
-*/
-
-static const char version[] =
- "hp.c:v1.10 9/23/94 Donald Becker (becker@cesdis.gsfc.nasa.gov)\n";
-
-
-#include <linux/module.h>
-#include <linux/kernel.h>
-#include <linux/errno.h>
-#include <linux/ioport.h>
-#include <linux/netdevice.h>
-#include <linux/etherdevice.h>
-#include <linux/init.h>
-#include <linux/interrupt.h>
-#include <linux/delay.h>
-
-#include <asm/io.h>
-
-#include "8390.h"
-
-#define DRV_NAME "hp"
-
-/* A zero-terminated list of I/O addresses to be probed. */
-static unsigned int hppclan_portlist[] __initdata =
-{ 0x300, 0x320, 0x340, 0x280, 0x2C0, 0x200, 0x240, 0};
-
-#define HP_IO_EXTENT 32
-
-#define HP_DATAPORT 0x0c /* "Remote DMA" data port. */
-#define HP_ID 0x07
-#define HP_CONFIGURE 0x08 /* Configuration register. */
-#define HP_RUN 0x01 /* 1 == Run, 0 == reset. */
-#define HP_IRQ 0x0E /* Mask for software-configured IRQ line. */
-#define HP_DATAON 0x10 /* Turn on dataport */
-#define NIC_OFFSET 0x10 /* Offset the 8390 registers. */
-
-#define HP_START_PG 0x00 /* First page of TX buffer */
-#define HP_8BSTOP_PG 0x80 /* Last page +1 of RX ring */
-#define HP_16BSTOP_PG 0xFF /* Same, for 16 bit cards. */
-
-static int hp_probe1(struct net_device *dev, int ioaddr);
-
-static void hp_reset_8390(struct net_device *dev);
-static void hp_get_8390_hdr(struct net_device *dev, struct e8390_pkt_hdr *hdr,
- int ring_page);
-static void hp_block_input(struct net_device *dev, int count,
- struct sk_buff *skb , int ring_offset);
-static void hp_block_output(struct net_device *dev, int count,
- const unsigned char *buf, int start_page);
-
-static void hp_init_card(struct net_device *dev);
-
-/* The map from IRQ number to HP_CONFIGURE register setting. */
-/* My default is IRQ5 0 1 2 3 4 5 6 7 8 9 10 11 */
-static char irqmap[16] __initdata= { 0, 0, 4, 6, 8,10, 0,14, 0, 4, 2,12,0,0,0,0};
-
-
-/* Probe for an HP LAN adaptor.
- Also initialize the card and fill in STATION_ADDR with the station
- address. */
-
-static int __init do_hp_probe(struct net_device *dev)
-{
- int i;
- int base_addr = dev->base_addr;
- int irq = dev->irq;
-
- if (base_addr > 0x1ff) /* Check a single specified location. */
- return hp_probe1(dev, base_addr);
- else if (base_addr != 0) /* Don't probe at all. */
- return -ENXIO;
-
- for (i = 0; hppclan_portlist[i]; i++) {
- if (hp_probe1(dev, hppclan_portlist[i]) == 0)
- return 0;
- dev->irq = irq;
- }
-
- return -ENODEV;
-}
-
-#ifndef MODULE
-struct net_device * __init hp_probe(int unit)
-{
- struct net_device *dev = alloc_eip_netdev();
- int err;
-
- if (!dev)
- return ERR_PTR(-ENOMEM);
-
- sprintf(dev->name, "eth%d", unit);
- netdev_boot_setup_check(dev);
-
- err = do_hp_probe(dev);
- if (err)
- goto out;
- return dev;
-out:
- free_netdev(dev);
- return ERR_PTR(err);
-}
-#endif
-
-static int __init hp_probe1(struct net_device *dev, int ioaddr)
-{
- int i, retval, board_id, wordmode;
- const char *name;
- static unsigned version_printed;
-
- if (!request_region(ioaddr, HP_IO_EXTENT, DRV_NAME))
- return -EBUSY;
-
- /* Check for the HP physical address, 08 00 09 xx xx xx. */
- /* This really isn't good enough: we may pick up HP LANCE boards
- also! Avoid the lance 0x5757 signature. */
- if (inb(ioaddr) != 0x08
- || inb(ioaddr+1) != 0x00
- || inb(ioaddr+2) != 0x09
- || inb(ioaddr+14) == 0x57) {
- retval = -ENODEV;
- goto out;
- }
-
- /* Set up the parameters based on the board ID.
- If you have additional mappings, please mail them to me -djb. */
- if ((board_id = inb(ioaddr + HP_ID)) & 0x80) {
- name = "HP27247";
- wordmode = 1;
- } else {
- name = "HP27250";
- wordmode = 0;
- }
-
- if (ei_debug && version_printed++ == 0)
- printk(version);
-
- printk("%s: %s (ID %02x) at %#3x,", dev->name, name, board_id, ioaddr);
-
- for(i = 0; i < ETH_ALEN; i++)
- dev->dev_addr[i] = inb(ioaddr + i);
-
- printk(" %pM", dev->dev_addr);
-
- /* Snarf the interrupt now. Someday this could be moved to open(). */
- if (dev->irq < 2) {
- static const int irq_16list[] = { 11, 10, 5, 3, 4, 7, 9, 0};
- static const int irq_8list[] = { 7, 5, 3, 4, 9, 0};
- const int *irqp = wordmode ? irq_16list : irq_8list;
- do {
- int irq = *irqp;
- if (request_irq (irq, NULL, 0, "bogus", NULL) != -EBUSY) {
- unsigned long cookie = probe_irq_on();
- /* Twinkle the interrupt, and check if it's seen. */
- outb_p(irqmap[irq] | HP_RUN, ioaddr + HP_CONFIGURE);
- outb_p( 0x00 | HP_RUN, ioaddr + HP_CONFIGURE);
- if (irq == probe_irq_off(cookie) /* It's a good IRQ line! */
- && request_irq (irq, eip_interrupt, 0, DRV_NAME, dev) == 0) {
- printk(" selecting IRQ %d.\n", irq);
- dev->irq = *irqp;
- break;
- }
- }
- } while (*++irqp);
- if (*irqp == 0) {
- printk(" no free IRQ lines.\n");
- retval = -EBUSY;
- goto out;
- }
- } else {
- if (dev->irq == 2)
- dev->irq = 9;
- if ((retval = request_irq(dev->irq, eip_interrupt, 0, DRV_NAME, dev))) {
- printk (" unable to get IRQ %d.\n", dev->irq);
- goto out;
- }
- }
-
- /* Set the base address to point to the NIC, not the "real" base! */
- dev->base_addr = ioaddr + NIC_OFFSET;
- dev->netdev_ops = &eip_netdev_ops;
-
- ei_status.name = name;
- ei_status.word16 = wordmode;
- ei_status.tx_start_page = HP_START_PG;
- ei_status.rx_start_page = HP_START_PG + TX_PAGES;
- ei_status.stop_page = wordmode ? HP_16BSTOP_PG : HP_8BSTOP_PG;
-
- ei_status.reset_8390 = hp_reset_8390;
- ei_status.get_8390_hdr = hp_get_8390_hdr;
- ei_status.block_input = hp_block_input;
- ei_status.block_output = hp_block_output;
- hp_init_card(dev);
-
- retval = register_netdev(dev);
- if (retval)
- goto out1;
- return 0;
-out1:
- free_irq(dev->irq, dev);
-out:
- release_region(ioaddr, HP_IO_EXTENT);
- return retval;
-}
-
-static void
-hp_reset_8390(struct net_device *dev)
-{
- int hp_base = dev->base_addr - NIC_OFFSET;
- int saved_config = inb_p(hp_base + HP_CONFIGURE);
-
- if (ei_debug > 1) printk("resetting the 8390 time=%ld...", jiffies);
- outb_p(0x00, hp_base + HP_CONFIGURE);
- ei_status.txing = 0;
- /* Pause just a few cycles for the hardware reset to take place. */
- udelay(5);
-
- outb_p(saved_config, hp_base + HP_CONFIGURE);
- udelay(5);
-
- if ((inb_p(hp_base+NIC_OFFSET+EN0_ISR) & ENISR_RESET) == 0)
- printk("%s: hp_reset_8390() did not complete.\n", dev->name);
-
- if (ei_debug > 1) printk("8390 reset done (%ld).", jiffies);
-}
-
-static void
-hp_get_8390_hdr(struct net_device *dev, struct e8390_pkt_hdr *hdr, int ring_page)
-{
- int nic_base = dev->base_addr;
- int saved_config = inb_p(nic_base - NIC_OFFSET + HP_CONFIGURE);
-
- outb_p(saved_config | HP_DATAON, nic_base - NIC_OFFSET + HP_CONFIGURE);
- outb_p(E8390_NODMA+E8390_PAGE0+E8390_START, nic_base);
- outb_p(sizeof(struct e8390_pkt_hdr), nic_base + EN0_RCNTLO);
- outb_p(0, nic_base + EN0_RCNTHI);
- outb_p(0, nic_base + EN0_RSARLO); /* On page boundary */
- outb_p(ring_page, nic_base + EN0_RSARHI);
- outb_p(E8390_RREAD+E8390_START, nic_base);
-
- if (ei_status.word16)
- insw(nic_base - NIC_OFFSET + HP_DATAPORT, hdr, sizeof(struct e8390_pkt_hdr)>>1);
- else
- insb(nic_base - NIC_OFFSET + HP_DATAPORT, hdr, sizeof(struct e8390_pkt_hdr));
-
- outb_p(saved_config & (~HP_DATAON), nic_base - NIC_OFFSET + HP_CONFIGURE);
-}
-
-/* Block input and output, similar to the Crynwr packet driver. If you are
- porting to a new ethercard look at the packet driver source for hints.
- The HP LAN doesn't use shared memory -- we put the packet
- out through the "remote DMA" dataport. */
-
-static void
-hp_block_input(struct net_device *dev, int count, struct sk_buff *skb, int ring_offset)
-{
- int nic_base = dev->base_addr;
- int saved_config = inb_p(nic_base - NIC_OFFSET + HP_CONFIGURE);
- int xfer_count = count;
- char *buf = skb->data;
-
- outb_p(saved_config | HP_DATAON, nic_base - NIC_OFFSET + HP_CONFIGURE);
- outb_p(E8390_NODMA+E8390_PAGE0+E8390_START, nic_base);
- outb_p(count & 0xff, nic_base + EN0_RCNTLO);
- outb_p(count >> 8, nic_base + EN0_RCNTHI);
- outb_p(ring_offset & 0xff, nic_base + EN0_RSARLO);
- outb_p(ring_offset >> 8, nic_base + EN0_RSARHI);
- outb_p(E8390_RREAD+E8390_START, nic_base);
- if (ei_status.word16) {
- insw(nic_base - NIC_OFFSET + HP_DATAPORT,buf,count>>1);
- if (count & 0x01)
- buf[count-1] = inb(nic_base - NIC_OFFSET + HP_DATAPORT), xfer_count++;
- } else {
- insb(nic_base - NIC_OFFSET + HP_DATAPORT, buf, count);
- }
- /* This is for the ALPHA version only, remove for later releases. */
- if (ei_debug > 0) { /* DMA termination address check... */
- int high = inb_p(nic_base + EN0_RSARHI);
- int low = inb_p(nic_base + EN0_RSARLO);
- int addr = (high << 8) + low;
- /* Check only the lower 8 bits so we can ignore ring wrap. */
- if (((ring_offset + xfer_count) & 0xff) != (addr & 0xff))
- printk("%s: RX transfer address mismatch, %#4.4x vs. %#4.4x (actual).\n",
- dev->name, ring_offset + xfer_count, addr);
- }
- outb_p(saved_config & (~HP_DATAON), nic_base - NIC_OFFSET + HP_CONFIGURE);
-}
-
-static void
-hp_block_output(struct net_device *dev, int count,
- const unsigned char *buf, int start_page)
-{
- int nic_base = dev->base_addr;
- int saved_config = inb_p(nic_base - NIC_OFFSET + HP_CONFIGURE);
-
- outb_p(saved_config | HP_DATAON, nic_base - NIC_OFFSET + HP_CONFIGURE);
- /* Round the count up for word writes. Do we need to do this?
- What effect will an odd byte count have on the 8390?
- I should check someday. */
- if (ei_status.word16 && (count & 0x01))
- count++;
- /* We should already be in page 0, but to be safe... */
- outb_p(E8390_PAGE0+E8390_START+E8390_NODMA, nic_base);
-
-#ifdef NE8390_RW_BUGFIX
- /* Handle the read-before-write bug the same way as the
- Crynwr packet driver -- the NatSemi method doesn't work. */
- outb_p(0x42, nic_base + EN0_RCNTLO);
- outb_p(0, nic_base + EN0_RCNTHI);
- outb_p(0xff, nic_base + EN0_RSARLO);
- outb_p(0x00, nic_base + EN0_RSARHI);
-#define NE_CMD 0x00
- outb_p(E8390_RREAD+E8390_START, nic_base + NE_CMD);
- /* Make certain that the dummy read has occurred. */
- inb_p(0x61);
- inb_p(0x61);
-#endif
-
- outb_p(count & 0xff, nic_base + EN0_RCNTLO);
- outb_p(count >> 8, nic_base + EN0_RCNTHI);
- outb_p(0x00, nic_base + EN0_RSARLO);
- outb_p(start_page, nic_base + EN0_RSARHI);
-
- outb_p(E8390_RWRITE+E8390_START, nic_base);
- if (ei_status.word16) {
- /* Use the 'rep' sequence for 16 bit boards. */
- outsw(nic_base - NIC_OFFSET + HP_DATAPORT, buf, count>>1);
- } else {
- outsb(nic_base - NIC_OFFSET + HP_DATAPORT, buf, count);
- }
-
- /* DON'T check for 'inb_p(EN0_ISR) & ENISR_RDC' here -- it's broken! */
-
- /* This is for the ALPHA version only, remove for later releases. */
- if (ei_debug > 0) { /* DMA termination address check... */
- int high = inb_p(nic_base + EN0_RSARHI);
- int low = inb_p(nic_base + EN0_RSARLO);
- int addr = (high << 8) + low;
- if ((start_page << 8) + count != addr)
- printk("%s: TX Transfer address mismatch, %#4.4x vs. %#4.4x.\n",
- dev->name, (start_page << 8) + count, addr);
- }
- outb_p(saved_config & (~HP_DATAON), nic_base - NIC_OFFSET + HP_CONFIGURE);
-}
-
-/* This function resets the ethercard if something screws up. */
-static void __init
-hp_init_card(struct net_device *dev)
-{
- int irq = dev->irq;
- NS8390p_init(dev, 0);
- outb_p(irqmap[irq&0x0f] | HP_RUN,
- dev->base_addr - NIC_OFFSET + HP_CONFIGURE);
-}
-
-#ifdef MODULE
-#define MAX_HP_CARDS 4 /* Max number of HP cards per module */
-static struct net_device *dev_hp[MAX_HP_CARDS];
-static int io[MAX_HP_CARDS];
-static int irq[MAX_HP_CARDS];
-
-module_param_array(io, int, NULL, 0);
-module_param_array(irq, int, NULL, 0);
-MODULE_PARM_DESC(io, "I/O base address(es)");
-MODULE_PARM_DESC(irq, "IRQ number(s) (assigned)");
-MODULE_DESCRIPTION("HP PC-LAN ISA ethernet driver");
-MODULE_LICENSE("GPL");
-
-/* This is set up so that only a single autoprobe takes place per call.
-ISA device autoprobes on a running machine are not recommended. */
-int __init
-init_module(void)
-{
- struct net_device *dev;
- int this_dev, found = 0;
-
- for (this_dev = 0; this_dev < MAX_HP_CARDS; this_dev++) {
- if (io[this_dev] == 0) {
- if (this_dev != 0) break; /* only autoprobe 1st one */
- printk(KERN_NOTICE "hp.c: Presently autoprobing (not recommended) for a single card.\n");
- }
- dev = alloc_eip_netdev();
- if (!dev)
- break;
- dev->irq = irq[this_dev];
- dev->base_addr = io[this_dev];
- if (do_hp_probe(dev) == 0) {
- dev_hp[found++] = dev;
- continue;
- }
- free_netdev(dev);
- printk(KERN_WARNING "hp.c: No HP card found (i/o = 0x%x).\n", io[this_dev]);
- break;
- }
- if (found)
- return 0;
- return -ENXIO;
-}
-
-static void cleanup_card(struct net_device *dev)
-{
- free_irq(dev->irq, dev);
- release_region(dev->base_addr - NIC_OFFSET, HP_IO_EXTENT);
-}
-
-void __exit
-cleanup_module(void)
-{
- int this_dev;
-
- for (this_dev = 0; this_dev < MAX_HP_CARDS; this_dev++) {
- struct net_device *dev = dev_hp[this_dev];
- if (dev) {
- unregister_netdev(dev);
- cleanup_card(dev);
- free_netdev(dev);
- }
- }
-}
-#endif /* MODULE */
diff --git a/drivers/net/ethernet/Kconfig b/drivers/net/ethernet/Kconfig
index e4ff3894911..ed956e08d38 100644
--- a/drivers/net/ethernet/Kconfig
+++ b/drivers/net/ethernet/Kconfig
@@ -135,7 +135,6 @@ config ETHOC
source "drivers/net/ethernet/packetengines/Kconfig"
source "drivers/net/ethernet/pasemi/Kconfig"
source "drivers/net/ethernet/qlogic/Kconfig"
-source "drivers/net/ethernet/racal/Kconfig"
source "drivers/net/ethernet/realtek/Kconfig"
source "drivers/net/ethernet/renesas/Kconfig"
source "drivers/net/ethernet/rdc/Kconfig"
diff --git a/drivers/net/ethernet/Makefile b/drivers/net/ethernet/Makefile
index d4473072654..8268d85f944 100644
--- a/drivers/net/ethernet/Makefile
+++ b/drivers/net/ethernet/Makefile
@@ -53,7 +53,6 @@ obj-$(CONFIG_ETHOC) += ethoc.o
obj-$(CONFIG_NET_PACKET_ENGINE) += packetengines/
obj-$(CONFIG_NET_VENDOR_PASEMI) += pasemi/
obj-$(CONFIG_NET_VENDOR_QLOGIC) += qlogic/
-obj-$(CONFIG_NET_VENDOR_RACAL) += racal/
obj-$(CONFIG_NET_VENDOR_REALTEK) += realtek/
obj-$(CONFIG_SH_ETH) += renesas/
obj-$(CONFIG_NET_VENDOR_RDC) += rdc/
diff --git a/drivers/net/ethernet/amd/Kconfig b/drivers/net/ethernet/amd/Kconfig
index 304613302f0..13d74aa4033 100644
--- a/drivers/net/ethernet/amd/Kconfig
+++ b/drivers/net/ethernet/amd/Kconfig
@@ -105,19 +105,6 @@ config DECLANCE
DEC (now Compaq) based on the AMD LANCE chipset, including the
DEPCA series. (This chipset is better known via the NE2100 cards.)
-config DEPCA
- tristate "DEPCA, DE10x, DE200, DE201, DE202, DE422 support"
- depends on (ISA || EISA)
- select CRC32
- ---help---
- If you have a network (Ethernet) card of this type, say Y and read
- the Ethernet-HOWTO, available from
- <http://www.tldp.org/docs.html#howto> as well as
- <file:drivers/net/ethernet/amd/depca.c>.
-
- To compile this driver as a module, choose M here. The module
- will be called depca.
-
config HPLANCE
bool "HP on-board LANCE support"
depends on DIO
diff --git a/drivers/net/ethernet/amd/Makefile b/drivers/net/ethernet/amd/Makefile
index 175caa5328c..cdd4301a973 100644
--- a/drivers/net/ethernet/amd/Makefile
+++ b/drivers/net/ethernet/amd/Makefile
@@ -8,7 +8,6 @@ obj-$(CONFIG_ARM_AM79C961A) += am79c961a.o
obj-$(CONFIG_ARIADNE) += ariadne.o
obj-$(CONFIG_ATARILANCE) += atarilance.o
obj-$(CONFIG_DECLANCE) += declance.o
-obj-$(CONFIG_DEPCA) += depca.o
obj-$(CONFIG_HPLANCE) += hplance.o 7990.o
obj-$(CONFIG_LANCE) += lance.o
obj-$(CONFIG_MIPS_AU1X00_ENET) += au1000_eth.o
diff --git a/drivers/net/ethernet/amd/depca.c b/drivers/net/ethernet/amd/depca.c
deleted file mode 100644
index 34a485363d5..00000000000
--- a/drivers/net/ethernet/amd/depca.c
+++ /dev/null
@@ -1,1910 +0,0 @@
-/* depca.c: A DIGITAL DEPCA & EtherWORKS ethernet driver for linux.
-
- Written 1994, 1995 by David C. Davies.
-
-
- Copyright 1994 David C. Davies
- and
- United States Government
- (as represented by the Director, National Security Agency).
-
- Copyright 1995 Digital Equipment Corporation.
-
-
- This software may be used and distributed according to the terms of
- the GNU General Public License, incorporated herein by reference.
-
- This driver is written for the Digital Equipment Corporation series
- of DEPCA and EtherWORKS ethernet cards:
-
- DEPCA (the original)
- DE100
- DE101
- DE200 Turbo
- DE201 Turbo
- DE202 Turbo (TP BNC)
- DE210
- DE422 (EISA)
-
- The driver has been tested on DE100, DE200 and DE202 cards in a
- relatively busy network. The DE422 has been tested a little.
-
- This driver will NOT work for the DE203, DE204 and DE205 series of
- cards, since they have a new custom ASIC in place of the AMD LANCE
- chip. See the 'ewrk3.c' driver in the Linux source tree for running
- those cards.
-
- I have benchmarked the driver with a DE100 at 595kB/s to (542kB/s from)
- a DECstation 5000/200.
-
- The author may be reached at davies@maniac.ultranet.com
-
- =========================================================================
-
- The driver was originally based on the 'lance.c' driver from Donald
- Becker which is included with the standard driver distribution for
- linux. V0.4 is a complete re-write with only the kernel interface
- remaining from the original code.
-
- 1) Lance.c code in /linux/drivers/net/
- 2) "Ethernet/IEEE 802.3 Family. 1992 World Network Data Book/Handbook",
- AMD, 1992 [(800) 222-9323].
- 3) "Am79C90 CMOS Local Area Network Controller for Ethernet (C-LANCE)",
- AMD, Pub. #17881, May 1993.
- 4) "Am79C960 PCnet-ISA(tm), Single-Chip Ethernet Controller for ISA",
- AMD, Pub. #16907, May 1992
- 5) "DEC EtherWORKS LC Ethernet Controller Owners Manual",
- Digital Equipment corporation, 1990, Pub. #EK-DE100-OM.003
- 6) "DEC EtherWORKS Turbo Ethernet Controller Owners Manual",
- Digital Equipment corporation, 1990, Pub. #EK-DE200-OM.003
- 7) "DEPCA Hardware Reference Manual", Pub. #EK-DEPCA-PR
- Digital Equipment Corporation, 1989
- 8) "DEC EtherWORKS Turbo_(TP BNC) Ethernet Controller Owners Manual",
- Digital Equipment corporation, 1991, Pub. #EK-DE202-OM.001
-
-
- Peter Bauer's depca.c (V0.5) was referred to when debugging V0.1 of this
- driver.
-
- The original DEPCA card requires that the ethernet ROM address counter
- be enabled to count and has an 8 bit NICSR. The ROM counter enabling is
- only done when a 0x08 is read as the first address octet (to minimise
- the chances of writing over some other hardware's I/O register). The
- NICSR accesses have been changed to byte accesses for all the cards
- supported by this driver, since there is only one useful bit in the MSB
- (remote boot timeout) and it is not used. Also, there is a maximum of
- only 48kB network RAM for this card. My thanks to Torbjorn Lindh for
- help debugging all this (and holding my feet to the fire until I got it
- right).
-
- The DE200 series boards have on-board 64kB RAM for use as a shared
- memory network buffer. Only the DE100 cards make use of a 2kB buffer
- mode which has not been implemented in this driver (only the 32kB and
- 64kB modes are supported [16kB/48kB for the original DEPCA]).
-
- At the most only 2 DEPCA cards can be supported on the ISA bus because
- there is only provision for two I/O base addresses on each card (0x300
- and 0x200). The I/O address is detected by searching for a byte sequence
- in the Ethernet station address PROM at the expected I/O address for the
- Ethernet PROM. The shared memory base address is 'autoprobed' by
- looking for the self test PROM and detecting the card name. When a
- second DEPCA is detected, information is placed in the base_addr
- variable of the next device structure (which is created if necessary),
- thus enabling ethif_probe initialization for the device. More than 2
- EISA cards can be supported, but care will be needed assigning the
- shared memory to ensure that each slot has the correct IRQ, I/O address
- and shared memory address assigned.
-
- ************************************************************************
-
- NOTE: If you are using two ISA DEPCAs, it is important that you assign
- the base memory addresses correctly. The driver autoprobes I/O 0x300
- then 0x200. The base memory address for the first device must be less
- than that of the second so that the auto probe will correctly assign the
- I/O and memory addresses on the same card. I can't think of a way to do
- this unambiguously at the moment, since there is nothing on the cards to
- tie I/O and memory information together.
-
- I am unable to test 2 cards together for now, so this code is
- unchecked. All reports, good or bad, are welcome.
-
- ************************************************************************
-
- The board IRQ setting must be at an unused IRQ which is auto-probed
- using Donald Becker's autoprobe routines. DEPCA and DE100 board IRQs are
- {2,3,4,5,7}, whereas the DE200 is at {5,9,10,11,15}. Note that IRQ2 is
- really IRQ9 in machines with 16 IRQ lines.
-
- No 16MB memory limitation should exist with this driver as DMA is not
- used and the common memory area is in low memory on the network card (my
- current system has 20MB and I've not had problems yet).
-
- The ability to load this driver as a loadable module has been added. To
- utilise this ability, you have to do <8 things:
-
- 0) have a copy of the loadable modules code installed on your system.
- 1) copy depca.c from the /linux/drivers/net directory to your favourite
- temporary directory.
- 2) if you wish, edit the source code near line 1530 to reflect the I/O
- address and IRQ you're using (see also 5).
- 3) compile depca.c, but include -DMODULE in the command line to ensure
- that the correct bits are compiled (see end of source code).
- 4) if you are wanting to add a new card, goto 5. Otherwise, recompile a
- kernel with the depca configuration turned off and reboot.
- 5) insmod depca.o [irq=7] [io=0x200] [mem=0xd0000] [adapter_name=DE100]
- [Alan Cox: Changed the code to allow command line irq/io assignments]
- [Dave Davies: Changed the code to allow command line mem/name
- assignments]
- 6) run the net startup bits for your eth?? interface manually
- (usually /etc/rc.inet[12] at boot time).
- 7) enjoy!
-
- Note that autoprobing is not allowed in loadable modules - the system is
- already up and running and you're messing with interrupts.
-
- To unload a module, turn off the associated interface
- 'ifconfig eth?? down' then 'rmmod depca'.
-
- To assign a base memory address for the shared memory when running as a
- loadable module, see 5 above. To include the adapter name (if you have
- no PROM but know the card name) also see 5 above. Note that this last
- option will not work with kernel built-in depca's.
-
- The shared memory assignment for a loadable module makes sense to avoid
- the 'memory autoprobe' picking the wrong shared memory (for the case of
- 2 depca's in a PC).
-
- ************************************************************************
- Support for MCA EtherWORKS cards added 11-3-98. (MCA since deleted)
- Verified to work with up to 2 DE212 cards in a system (although not
- fully stress-tested).
-
- Revision History
- ----------------
-
- Version Date Description
-
- 0.1 25-jan-94 Initial writing.
- 0.2 27-jan-94 Added LANCE TX hardware buffer chaining.
- 0.3 1-feb-94 Added multiple DEPCA support.
- 0.31 4-feb-94 Added DE202 recognition.
- 0.32 19-feb-94 Tidy up. Improve multi-DEPCA support.
- 0.33 25-feb-94 Fix DEPCA ethernet ROM counter enable.
- Add jabber packet fix from murf@perftech.com
- and becker@super.org
- 0.34 7-mar-94 Fix DEPCA max network memory RAM & NICSR access.
- 0.35 8-mar-94 Added DE201 recognition. Tidied up.
- 0.351 30-apr-94 Added EISA support. Added DE422 recognition.
- 0.36 16-may-94 DE422 fix released.
- 0.37 22-jul-94 Added MODULE support
- 0.38 15-aug-94 Added DBR ROM switch in depca_close().
- Multi DEPCA bug fix.
- 0.38axp 15-sep-94 Special version for Alpha AXP Linux V1.0.
- 0.381 12-dec-94 Added DE101 recognition, fix multicast bug.
- 0.382 9-feb-95 Fix recognition bug reported by <bkm@star.rl.ac.uk>.
- 0.383 22-feb-95 Fix for conflict with VESA SCSI reported by
- <stromain@alf.dec.com>
- 0.384 17-mar-95 Fix a ring full bug reported by <bkm@star.rl.ac.uk>
- 0.385 3-apr-95 Fix a recognition bug reported by
- <ryan.niemi@lastfrontier.com>
- 0.386 21-apr-95 Fix the last fix...sorry, must be galloping senility
- 0.40 25-May-95 Rewrite for portability & updated.
- ALPHA support from <jestabro@amt.tay1.dec.com>
- 0.41 26-Jun-95 Added verify_area() calls in depca_ioctl() from
- suggestion by <heiko@colossus.escape.de>
- 0.42 27-Dec-95 Add 'mem' shared memory assignment for loadable
- modules.
- Add 'adapter_name' for loadable modules when no PROM.
- Both above from a suggestion by
- <pchen@woodruffs121.residence.gatech.edu>.
- Add new multicasting code.
- 0.421 22-Apr-96 Fix alloc_device() bug <jari@markkus2.fimr.fi>
- 0.422 29-Apr-96 Fix depca_hw_init() bug <jari@markkus2.fimr.fi>
- 0.423 7-Jun-96 Fix module load bug <kmg@barco.be>
- 0.43 16-Aug-96 Update alloc_device() to conform to de4x5.c
- 0.44 1-Sep-97 Fix *_probe() to test check_region() first - bug
- reported by <mmogilvi@elbert.uccs.edu>
- 0.45 3-Nov-98 Added support for MCA EtherWORKS (DE210/DE212) cards
- by <tymm@computer.org>
- 0.451 5-Nov-98 Fixed mca stuff cuz I'm a dummy. <tymm@computer.org>
- 0.5 14-Nov-98 Re-spin for 2.1.x kernels.
- 0.51 27-Jun-99 Correct received packet length for CRC from
- report by <worm@dkik.dk>
- 0.52 16-Oct-00 Fixes for 2.3 io memory accesses
- Fix show-stopper (ints left masked) in depca_interrupt
- by <peterd@pnd-pc.demon.co.uk>
- 0.53 12-Jan-01 Release resources on failure, bss tidbits
- by acme@conectiva.com.br
- 0.54 08-Nov-01 use library crc32 functions
- by Matt_Domsch@dell.com
- 0.55 01-Mar-03 Use EISA/sysfs framework <maz@wild-wind.fr.eu.org>
-
- =========================================================================
-*/
-
-#include <linux/module.h>
-#include <linux/kernel.h>
-#include <linux/sched.h>
-#include <linux/string.h>
-#include <linux/errno.h>
-#include <linux/ioport.h>
-#include <linux/slab.h>
-#include <linux/interrupt.h>
-#include <linux/delay.h>
-#include <linux/init.h>
-#include <linux/crc32.h>
-#include <linux/netdevice.h>
-#include <linux/etherdevice.h>
-#include <linux/skbuff.h>
-#include <linux/time.h>
-#include <linux/types.h>
-#include <linux/unistd.h>
-#include <linux/ctype.h>
-#include <linux/moduleparam.h>
-#include <linux/platform_device.h>
-#include <linux/bitops.h>
-
-#include <asm/uaccess.h>
-#include <asm/io.h>
-#include <asm/dma.h>
-
-#ifdef CONFIG_EISA
-#include <linux/eisa.h>
-#endif
-
-#include "depca.h"
-
-static char version[] __initdata = "depca.c:v0.53 2001/1/12 davies@maniac.ultranet.com\n";
-
-#ifdef DEPCA_DEBUG
-static int depca_debug = DEPCA_DEBUG;
-#else
-static int depca_debug = 1;
-#endif
-
-#define DEPCA_NDA 0xffe0 /* No Device Address */
-
-#define TX_TIMEOUT (1*HZ)
-
-/*
-** Ethernet PROM defines
-*/
-#define PROBE_LENGTH 32
-#define ETH_PROM_SIG 0xAA5500FFUL
-
-/*
-** Set the number of Tx and Rx buffers. Ensure that the memory requested
-** here is <= to the amount of shared memory set up by the board switches.
-** The number of descriptors MUST BE A POWER OF 2.
-**
-** total_memory = NUM_RX_DESC*(8+RX_BUFF_SZ) + NUM_TX_DESC*(8+TX_BUFF_SZ)
-*/
-#define NUM_RX_DESC 8 /* Number of RX descriptors */
-#define NUM_TX_DESC 8 /* Number of TX descriptors */
-#define RX_BUFF_SZ 1536 /* Buffer size for each Rx buffer */
-#define TX_BUFF_SZ 1536 /* Buffer size for each Tx buffer */
-
-/*
-** EISA bus defines
-*/
-#define DEPCA_EISA_IO_PORTS 0x0c00 /* I/O port base address, slot 0 */
-
-/*
-** ISA Bus defines
-*/
-#define DEPCA_RAM_BASE_ADDRESSES {0xc0000,0xd0000,0xe0000,0x00000}
-#define DEPCA_TOTAL_SIZE 0x10
-
-static struct {
- u_long iobase;
- struct platform_device *device;
-} depca_io_ports[] = {
- { 0x300, NULL },
- { 0x200, NULL },
- { 0 , NULL },
-};
-
-/*
-** Name <-> Adapter mapping
-*/
-#define DEPCA_SIGNATURE {"DEPCA",\
- "DE100","DE101",\
- "DE200","DE201","DE202",\
- "DE210","DE212",\
- "DE422",\
- ""}
-
-static char* __initdata depca_signature[] = DEPCA_SIGNATURE;
-
-enum depca_type {
- DEPCA, de100, de101, de200, de201, de202, de210, de212, de422, unknown
-};
-
-static char depca_string[] = "depca";
-
-static int depca_device_remove (struct device *device);
-
-#ifdef CONFIG_EISA
-static struct eisa_device_id depca_eisa_ids[] = {
- { "DEC4220", de422 },
- { "" }
-};
-MODULE_DEVICE_TABLE(eisa, depca_eisa_ids);
-
-static int depca_eisa_probe (struct device *device);
-
-static struct eisa_driver depca_eisa_driver = {
- .id_table = depca_eisa_ids,
- .driver = {
- .name = depca_string,
- .probe = depca_eisa_probe,
- .remove = depca_device_remove
- }
-};
-#endif
-
-static int depca_isa_probe (struct platform_device *);
-
-static int depca_isa_remove(struct platform_device *pdev)
-{
- return depca_device_remove(&pdev->dev);
-}
-
-static struct platform_driver depca_isa_driver = {
- .probe = depca_isa_probe,
- .remove = depca_isa_remove,
- .driver = {
- .name = depca_string,
- },
-};
-
-/*
-** Miscellaneous info...
-*/
-#define DEPCA_STRLEN 16
-
-/*
-** Memory Alignment. Each descriptor is 4 longwords long. To force a
-** particular alignment on the TX descriptor, adjust DESC_SKIP_LEN and
-** DESC_ALIGN. DEPCA_ALIGN aligns the start address of the private memory area
-** and hence the RX descriptor ring's first entry.
-*/
-#define DEPCA_ALIGN4 ((u_long)4 - 1) /* 1 longword align */
-#define DEPCA_ALIGN8 ((u_long)8 - 1) /* 2 longword (quadword) align */
-#define DEPCA_ALIGN DEPCA_ALIGN8 /* Keep the LANCE happy... */
-
-/*
-** The DEPCA Rx and Tx ring descriptors.
-*/
-struct depca_rx_desc {
- volatile s32 base;
- s16 buf_length; /* This length is negative 2's complement! */
- s16 msg_length; /* This length is "normal". */
-};
-
-struct depca_tx_desc {
- volatile s32 base;
- s16 length; /* This length is negative 2's complement! */
- s16 misc; /* Errors and TDR info */
-};
-
-#define LA_MASK 0x0000ffff /* LANCE address mask for mapping network RAM
- to LANCE memory address space */
-
-/*
-** The Lance initialization block, described in databook, in common memory.
-*/
-struct depca_init {
- u16 mode; /* Mode register */
- u8 phys_addr[ETH_ALEN]; /* Physical ethernet address */
- u8 mcast_table[8]; /* Multicast Hash Table. */
- u32 rx_ring; /* Rx ring base pointer & ring length */
- u32 tx_ring; /* Tx ring base pointer & ring length */
-};
-
-#define DEPCA_PKT_STAT_SZ 16
-#define DEPCA_PKT_BIN_SZ 128 /* Should be >=100 unless you
- increase DEPCA_PKT_STAT_SZ */
-struct depca_private {
- char adapter_name[DEPCA_STRLEN]; /* /proc/ioports string */
- enum depca_type adapter; /* Adapter type */
- enum {
- DEPCA_BUS_ISA = 1,
- DEPCA_BUS_EISA,
- } depca_bus; /* type of bus */
- struct depca_init init_block; /* Shadow Initialization block */
-/* CPU address space fields */
- struct depca_rx_desc __iomem *rx_ring; /* Pointer to start of RX descriptor ring */
- struct depca_tx_desc __iomem *tx_ring; /* Pointer to start of TX descriptor ring */
- void __iomem *rx_buff[NUM_RX_DESC]; /* CPU virt address of sh'd memory buffs */
- void __iomem *tx_buff[NUM_TX_DESC]; /* CPU virt address of sh'd memory buffs */
- void __iomem *sh_mem; /* CPU mapped virt address of device RAM */
- u_long mem_start; /* Bus address of device RAM (before remap) */
- u_long mem_len; /* device memory size */
-/* Device address space fields */
- u_long device_ram_start; /* Start of RAM in device addr space */
-/* Offsets used in both address spaces */
- u_long rx_ring_offset; /* Offset from start of RAM to rx_ring */
- u_long tx_ring_offset; /* Offset from start of RAM to tx_ring */
- u_long buffs_offset; /* LANCE Rx and Tx buffers start address. */
-/* Kernel-only (not device) fields */
- int rx_new, tx_new; /* The next free ring entry */
- int rx_old, tx_old; /* The ring entries to be free()ed. */
- spinlock_t lock;
- struct { /* Private stats counters */
- u32 bins[DEPCA_PKT_STAT_SZ];
- u32 unicast;
- u32 multicast;
- u32 broadcast;
- u32 excessive_collisions;
- u32 tx_underruns;
- u32 excessive_underruns;
- } pktStats;
- int txRingMask; /* TX ring mask */
- int rxRingMask; /* RX ring mask */
- s32 rx_rlen; /* log2(rxRingMask+1) for the descriptors */
- s32 tx_rlen; /* log2(txRingMask+1) for the descriptors */
-};
-
-/*
-** The transmit ring full condition is described by the tx_old and tx_new
-** pointers by:
-** tx_old = tx_new Empty ring
-** tx_old = tx_new+1 Full ring
-** tx_old+txRingMask = tx_new Full ring (wrapped condition)
-*/
-#define TX_BUFFS_AVAIL ((lp->tx_old<=lp->tx_new)?\
- lp->tx_old+lp->txRingMask-lp->tx_new:\
- lp->tx_old -lp->tx_new-1)
-
-/*
-** Public Functions
-*/
-static int depca_open(struct net_device *dev);
-static netdev_tx_t depca_start_xmit(struct sk_buff *skb,
- struct net_device *dev);
-static irqreturn_t depca_interrupt(int irq, void *dev_id);
-static int depca_close(struct net_device *dev);
-static int depca_ioctl(struct net_device *dev, struct ifreq *rq, int cmd);
-static void depca_tx_timeout(struct net_device *dev);
-static void set_multicast_list(struct net_device *dev);
-
-/*
-** Private functions
-*/
-static void depca_init_ring(struct net_device *dev);
-static int depca_rx(struct net_device *dev);
-static int depca_tx(struct net_device *dev);
-
-static void LoadCSRs(struct net_device *dev);
-static int InitRestartDepca(struct net_device *dev);
-static int DepcaSignature(char *name, u_long paddr);
-static int DevicePresent(u_long ioaddr);
-static int get_hw_addr(struct net_device *dev);
-static void SetMulticastFilter(struct net_device *dev);
-static int load_packet(struct net_device *dev, struct sk_buff *skb);
-static void depca_dbg_open(struct net_device *dev);
-
-static u_char de1xx_irq[] __initdata = { 2, 3, 4, 5, 7, 9, 0 };
-static u_char de2xx_irq[] __initdata = { 5, 9, 10, 11, 15, 0 };
-static u_char de422_irq[] __initdata = { 5, 9, 10, 11, 0 };
-static u_char *depca_irq;
-
-static int irq;
-static int io;
-static char *adapter_name;
-static int mem; /* For loadable module assignment
- use insmod mem=0x????? .... */
-module_param (irq, int, 0);
-module_param (io, int, 0);
-module_param (adapter_name, charp, 0);
-module_param (mem, int, 0);
-MODULE_PARM_DESC(irq, "DEPCA IRQ number");
-MODULE_PARM_DESC(io, "DEPCA I/O base address");
-MODULE_PARM_DESC(adapter_name, "DEPCA adapter name");
-MODULE_PARM_DESC(mem, "DEPCA shared memory address");
-MODULE_LICENSE("GPL");
-
-/*
-** Miscellaneous defines...
-*/
-#define STOP_DEPCA \
- outw(CSR0, DEPCA_ADDR);\
- outw(STOP, DEPCA_DATA)
-
-static const struct net_device_ops depca_netdev_ops = {
- .ndo_open = depca_open,
- .ndo_start_xmit = depca_start_xmit,
- .ndo_stop = depca_close,
- .ndo_set_rx_mode = set_multicast_list,
- .ndo_do_ioctl = depca_ioctl,
- .ndo_tx_timeout = depca_tx_timeout,
- .ndo_change_mtu = eth_change_mtu,
- .ndo_set_mac_address = eth_mac_addr,
- .ndo_validate_addr = eth_validate_addr,
-};
-
-static int __init depca_hw_init (struct net_device *dev, struct device *device)
-{
- struct depca_private *lp;
- int i, j, offset, netRAM, mem_len, status = 0;
- s16 nicsr;
- u_long ioaddr;
- u_long mem_start;
-
- /*
- * We are now supposed to enter this function with the
- * following fields filled with proper values :
- *
- * dev->base_addr
- * lp->mem_start
- * lp->depca_bus
- * lp->adapter
- *
- * dev->irq can be set if known from device configuration (on
- * MCA or EISA) or module option. Otherwise, it will be auto
- * detected.
- */
-
- ioaddr = dev->base_addr;
-
- STOP_DEPCA;
-
- nicsr = inb(DEPCA_NICSR);
- nicsr = ((nicsr & ~SHE & ~RBE & ~IEN) | IM);
- outb(nicsr, DEPCA_NICSR);
-
- if (inw(DEPCA_DATA) != STOP) {
- return -ENXIO;
- }
-
- lp = netdev_priv(dev);
- mem_start = lp->mem_start;
-
- if (!mem_start || lp->adapter < DEPCA || lp->adapter >=unknown)
- return -ENXIO;
-
- printk("%s: %s at 0x%04lx",
- dev_name(device), depca_signature[lp->adapter], ioaddr);
-
- switch (lp->depca_bus) {
-#ifdef CONFIG_EISA
- case DEPCA_BUS_EISA:
- printk(" (EISA slot %d)", to_eisa_device(device)->slot);
- break;
-#endif
-
- case DEPCA_BUS_ISA:
- break;
-
- default:
- printk("Unknown DEPCA bus %d\n", lp->depca_bus);
- return -ENXIO;
- }
-
- printk(", h/w address ");
- status = get_hw_addr(dev);
- printk("%pM", dev->dev_addr);
- if (status != 0) {
- printk(" which has an Ethernet PROM CRC error.\n");
- return -ENXIO;
- }
-
- /* Set up the maximum amount of network RAM(kB) */
- netRAM = ((lp->adapter != DEPCA) ? 64 : 48);
- if ((nicsr & _128KB) && (lp->adapter == de422))
- netRAM = 128;
-
- /* Shared Memory Base Address */
- if (nicsr & BUF) {
- nicsr &= ~BS; /* DEPCA RAM in top 32k */
- netRAM -= 32;
- mem_start += 0x8000;
- }
-
- if ((mem_len = (NUM_RX_DESC * (sizeof(struct depca_rx_desc) + RX_BUFF_SZ) + NUM_TX_DESC * (sizeof(struct depca_tx_desc) + TX_BUFF_SZ) + sizeof(struct depca_init)))
- > (netRAM << 10)) {
- printk(",\n requests %dkB RAM: only %dkB is available!\n", (mem_len >> 10), netRAM);
- return -ENXIO;
- }
-
- printk(",\n has %dkB RAM at 0x%.5lx", netRAM, mem_start);
-
- /* Enable the shadow RAM. */
- if (lp->adapter != DEPCA) {
- nicsr |= SHE;
- outb(nicsr, DEPCA_NICSR);
- }
-
- spin_lock_init(&lp->lock);
- sprintf(lp->adapter_name, "%s (%s)",
- depca_signature[lp->adapter], dev_name(device));
- status = -EBUSY;
-
- /* Initialisation Block */
- if (!request_mem_region (mem_start, mem_len, lp->adapter_name)) {
- printk(KERN_ERR "depca: cannot request ISA memory, aborting\n");
- goto out_priv;
- }
-
- status = -EIO;
- lp->sh_mem = ioremap(mem_start, mem_len);
- if (lp->sh_mem == NULL) {
- printk(KERN_ERR "depca: cannot remap ISA memory, aborting\n");
- goto out1;
- }
-
- lp->mem_start = mem_start;
- lp->mem_len = mem_len;
- lp->device_ram_start = mem_start & LA_MASK;
-
- offset = 0;
- offset += sizeof(struct depca_init);
-
- /* Tx & Rx descriptors (aligned to a quadword boundary) */
- offset = (offset + DEPCA_ALIGN) & ~DEPCA_ALIGN;
- lp->rx_ring = lp->sh_mem + offset;
- lp->rx_ring_offset = offset;
-
- offset += (sizeof(struct depca_rx_desc) * NUM_RX_DESC);
- lp->tx_ring = lp->sh_mem + offset;
- lp->tx_ring_offset = offset;
-
- offset += (sizeof(struct depca_tx_desc) * NUM_TX_DESC);
-
- lp->buffs_offset = offset;
-
- /* Finish initialising the ring information. */
- lp->rxRingMask = NUM_RX_DESC - 1;
- lp->txRingMask = NUM_TX_DESC - 1;
-
- /* Calculate Tx/Rx RLEN size for the descriptors. */
- for (i = 0, j = lp->rxRingMask; j > 0; i++) {
- j >>= 1;
- }
- lp->rx_rlen = (s32) (i << 29);
- for (i = 0, j = lp->txRingMask; j > 0; i++) {
- j >>= 1;
- }
- lp->tx_rlen = (s32) (i << 29);
-
- /* Load the initialisation block */
- depca_init_ring(dev);
-
- /* Initialise the control and status registers */
- LoadCSRs(dev);
-
- /* Enable DEPCA board interrupts for autoprobing */
- nicsr = ((nicsr & ~IM) | IEN);
- outb(nicsr, DEPCA_NICSR);
-
- /* To auto-IRQ we enable the initialization-done and DMA err,
- interrupts. For now we will always get a DMA error. */
- if (dev->irq < 2) {
- unsigned char irqnum;
- unsigned long irq_mask, delay;
-
- irq_mask = probe_irq_on();
-
- /* Assign the correct irq list */
- switch (lp->adapter) {
- case DEPCA:
- case de100:
- case de101:
- depca_irq = de1xx_irq;
- break;
- case de200:
- case de201:
- case de202:
- case de210:
- case de212:
- depca_irq = de2xx_irq;
- break;
- case de422:
- depca_irq = de422_irq;
- break;
-
- default:
- break; /* Not reached */
- }
-
- /* Trigger an initialization just for the interrupt. */
- outw(INEA | INIT, DEPCA_DATA);
-
- delay = jiffies + HZ/50;
- while (time_before(jiffies, delay))
- yield();
-
- irqnum = probe_irq_off(irq_mask);
-
- status = -ENXIO;
- if (!irqnum) {
- printk(" and failed to detect IRQ line.\n");
- goto out2;
- } else {
- for (dev->irq = 0, i = 0; (depca_irq[i]) && (!dev->irq); i++)
- if (irqnum == depca_irq[i]) {
- dev->irq = irqnum;
- printk(" and uses IRQ%d.\n", dev->irq);
- }
-
- if (!dev->irq) {
- printk(" but incorrect IRQ line detected.\n");
- goto out2;
- }
- }
- } else {
- printk(" and assigned IRQ%d.\n", dev->irq);
- }
-
- if (depca_debug > 1) {
- printk(version);
- }
-
- /* The DEPCA-specific entries in the device structure. */
- dev->netdev_ops = &depca_netdev_ops;
- dev->watchdog_timeo = TX_TIMEOUT;
-
- dev->mem_start = 0;
-
- dev_set_drvdata(device, dev);
- SET_NETDEV_DEV (dev, device);
-
- status = register_netdev(dev);
- if (status == 0)
- return 0;
-out2:
- iounmap(lp->sh_mem);
-out1:
- release_mem_region (mem_start, mem_len);
-out_priv:
- return status;
-}
-
-
-static int depca_open(struct net_device *dev)
-{
- struct depca_private *lp = netdev_priv(dev);
- u_long ioaddr = dev->base_addr;
- s16 nicsr;
- int status = 0;
-
- STOP_DEPCA;
- nicsr = inb(DEPCA_NICSR);
-
- /* Make sure the shadow RAM is enabled */
- if (lp->adapter != DEPCA) {
- nicsr |= SHE;
- outb(nicsr, DEPCA_NICSR);
- }
-
- /* Re-initialize the DEPCA... */
- depca_init_ring(dev);
- LoadCSRs(dev);
-
- depca_dbg_open(dev);
-
- if (request_irq(dev->irq, depca_interrupt, 0, lp->adapter_name, dev)) {
- printk("depca_open(): Requested IRQ%d is busy\n", dev->irq);
- status = -EAGAIN;
- } else {
-
- /* Enable DEPCA board interrupts and turn off LED */
- nicsr = ((nicsr & ~IM & ~LED) | IEN);
- outb(nicsr, DEPCA_NICSR);
- outw(CSR0, DEPCA_ADDR);
-
- netif_start_queue(dev);
-
- status = InitRestartDepca(dev);
-
- if (depca_debug > 1) {
- printk("CSR0: 0x%4.4x\n", inw(DEPCA_DATA));
- printk("nicsr: 0x%02x\n", inb(DEPCA_NICSR));
- }
- }
- return status;
-}
-
-/* Initialize the lance Rx and Tx descriptor rings. */
-static void depca_init_ring(struct net_device *dev)
-{
- struct depca_private *lp = netdev_priv(dev);
- u_int i;
- u_long offset;
-
- /* Lock out other processes whilst setting up the hardware */
- netif_stop_queue(dev);
-
- lp->rx_new = lp->tx_new = 0;
- lp->rx_old = lp->tx_old = 0;
-
- /* Initialize the base address and length of each buffer in the ring */
- for (i = 0; i <= lp->rxRingMask; i++) {
- offset = lp->buffs_offset + i * RX_BUFF_SZ;
- writel((lp->device_ram_start + offset) | R_OWN, &lp->rx_ring[i].base);
- writew(-RX_BUFF_SZ, &lp->rx_ring[i].buf_length);
- lp->rx_buff[i] = lp->sh_mem + offset;
- }
-
- for (i = 0; i <= lp->txRingMask; i++) {
- offset = lp->buffs_offset + (i + lp->rxRingMask + 1) * TX_BUFF_SZ;
- writel((lp->device_ram_start + offset) & 0x00ffffff, &lp->tx_ring[i].base);
- lp->tx_buff[i] = lp->sh_mem + offset;
- }
-
- /* Set up the initialization block */
- lp->init_block.rx_ring = (lp->device_ram_start + lp->rx_ring_offset) | lp->rx_rlen;
- lp->init_block.tx_ring = (lp->device_ram_start + lp->tx_ring_offset) | lp->tx_rlen;
-
- SetMulticastFilter(dev);
-
- for (i = 0; i < ETH_ALEN; i++) {
- lp->init_block.phys_addr[i] = dev->dev_addr[i];
- }
-
- lp->init_block.mode = 0x0000; /* Enable the Tx and Rx */
-}
-
-
-static void depca_tx_timeout(struct net_device *dev)
-{
- u_long ioaddr = dev->base_addr;
-
- printk("%s: transmit timed out, status %04x, resetting.\n", dev->name, inw(DEPCA_DATA));
-
- STOP_DEPCA;
- depca_init_ring(dev);
- LoadCSRs(dev);
- dev->trans_start = jiffies; /* prevent tx timeout */
- netif_wake_queue(dev);
- InitRestartDepca(dev);
-}
-
-
-/*
-** Writes a socket buffer to TX descriptor ring and starts transmission
-*/
-static netdev_tx_t depca_start_xmit(struct sk_buff *skb,
- struct net_device *dev)
-{
- struct depca_private *lp = netdev_priv(dev);
- u_long ioaddr = dev->base_addr;
- int status = 0;
-
- /* Transmitter timeout, serious problems. */
- if (skb->len < 1)
- goto out;
-
- if (skb_padto(skb, ETH_ZLEN))
- goto out;
-
- netif_stop_queue(dev);
-
- if (TX_BUFFS_AVAIL) { /* Fill in a Tx ring entry */
- status = load_packet(dev, skb);
-
- if (!status) {
- /* Trigger an immediate send demand. */
- outw(CSR0, DEPCA_ADDR);
- outw(INEA | TDMD, DEPCA_DATA);
-
- dev_kfree_skb(skb);
- }
- if (TX_BUFFS_AVAIL)
- netif_start_queue(dev);
- } else
- status = NETDEV_TX_LOCKED;
-
- out:
- return status;
-}
-
-/*
-** The DEPCA interrupt handler.
-*/
-static irqreturn_t depca_interrupt(int irq, void *dev_id)
-{
- struct net_device *dev = dev_id;
- struct depca_private *lp;
- s16 csr0, nicsr;
- u_long ioaddr;
-
- if (dev == NULL) {
- printk("depca_interrupt(): irq %d for unknown device.\n", irq);
- return IRQ_NONE;
- }
-
- lp = netdev_priv(dev);
- ioaddr = dev->base_addr;
-
- spin_lock(&lp->lock);
-
- /* mask the DEPCA board interrupts and turn on the LED */
- nicsr = inb(DEPCA_NICSR);
- nicsr |= (IM | LED);
- outb(nicsr, DEPCA_NICSR);
-
- outw(CSR0, DEPCA_ADDR);
- csr0 = inw(DEPCA_DATA);
-
- /* Acknowledge all of the current interrupt sources ASAP. */
- outw(csr0 & INTE, DEPCA_DATA);
-
- if (csr0 & RINT) /* Rx interrupt (packet arrived) */
- depca_rx(dev);
-
- if (csr0 & TINT) /* Tx interrupt (packet sent) */
- depca_tx(dev);
-
- /* Any resources available? */
- if ((TX_BUFFS_AVAIL >= 0) && netif_queue_stopped(dev)) {
- netif_wake_queue(dev);
- }
-
- /* Unmask the DEPCA board interrupts and turn off the LED */
- nicsr = (nicsr & ~IM & ~LED);
- outb(nicsr, DEPCA_NICSR);
-
- spin_unlock(&lp->lock);
- return IRQ_HANDLED;
-}
-
-/* Called with lp->lock held */
-static int depca_rx(struct net_device *dev)
-{
- struct depca_private *lp = netdev_priv(dev);
- int i, entry;
- s32 status;
-
- for (entry = lp->rx_new; !(readl(&lp->rx_ring[entry].base) & R_OWN); entry = lp->rx_new) {
- status = readl(&lp->rx_ring[entry].base) >> 16;
- if (status & R_STP) { /* Remember start of frame */
- lp->rx_old = entry;
- }
- if (status & R_ENP) { /* Valid frame status */
- if (status & R_ERR) { /* There was an error. */
- dev->stats.rx_errors++; /* Update the error stats. */
- if (status & R_FRAM)
- dev->stats.rx_frame_errors++;
- if (status & R_OFLO)
- dev->stats.rx_over_errors++;
- if (status & R_CRC)
- dev->stats.rx_crc_errors++;
- if (status & R_BUFF)
- dev->stats.rx_fifo_errors++;
- } else {
- short len, pkt_len = readw(&lp->rx_ring[entry].msg_length) - 4;
- struct sk_buff *skb;
-
- skb = netdev_alloc_skb(dev, pkt_len + 2);
- if (skb != NULL) {
- unsigned char *buf;
- skb_reserve(skb, 2); /* 16 byte align the IP header */
- buf = skb_put(skb, pkt_len);
- if (entry < lp->rx_old) { /* Wrapped buffer */
- len = (lp->rxRingMask - lp->rx_old + 1) * RX_BUFF_SZ;
- memcpy_fromio(buf, lp->rx_buff[lp->rx_old], len);
- memcpy_fromio(buf + len, lp->rx_buff[0], pkt_len - len);
- } else { /* Linear buffer */
- memcpy_fromio(buf, lp->rx_buff[lp->rx_old], pkt_len);
- }
-
- /*
- ** Notify the upper protocol layers that there is another
- ** packet to handle
- */
- skb->protocol = eth_type_trans(skb, dev);
- netif_rx(skb);
-
- /*
- ** Update stats
- */
- dev->stats.rx_packets++;
- dev->stats.rx_bytes += pkt_len;
- for (i = 1; i < DEPCA_PKT_STAT_SZ - 1; i++) {
- if (pkt_len < (i * DEPCA_PKT_BIN_SZ)) {
- lp->pktStats.bins[i]++;
- i = DEPCA_PKT_STAT_SZ;
- }
- }
- if (is_multicast_ether_addr(buf)) {
- if (is_broadcast_ether_addr(buf)) {
- lp->pktStats.broadcast++;
- } else {
- lp->pktStats.multicast++;
- }
- } else if (ether_addr_equal(buf,
- dev->dev_addr)) {
- lp->pktStats.unicast++;
- }
-
- lp->pktStats.bins[0]++; /* Duplicates stats.rx_packets */
- if (lp->pktStats.bins[0] == 0) { /* Reset counters */
- memset((char *) &lp->pktStats, 0, sizeof(lp->pktStats));
- }
- } else {
- printk("%s: Memory squeeze, deferring packet.\n", dev->name);
- dev->stats.rx_dropped++; /* Really, deferred. */
- break;
- }
- }
- /* Change buffer ownership for this last frame, back to the adapter */
- for (; lp->rx_old != entry; lp->rx_old = (lp->rx_old + 1) & lp->rxRingMask) {
- writel(readl(&lp->rx_ring[lp->rx_old].base) | R_OWN, &lp->rx_ring[lp->rx_old].base);
- }
- writel(readl(&lp->rx_ring[entry].base) | R_OWN, &lp->rx_ring[entry].base);
- }
-
- /*
- ** Update entry information
- */
- lp->rx_new = (lp->rx_new + 1) & lp->rxRingMask;
- }
-
- return 0;
-}
-
-/*
-** Buffer sent - check for buffer errors.
-** Called with lp->lock held
-*/
-static int depca_tx(struct net_device *dev)
-{
- struct depca_private *lp = netdev_priv(dev);
- int entry;
- s32 status;
- u_long ioaddr = dev->base_addr;
-
- for (entry = lp->tx_old; entry != lp->tx_new; entry = lp->tx_old) {
- status = readl(&lp->tx_ring[entry].base) >> 16;
-
- if (status < 0) { /* Packet not yet sent! */
- break;
- } else if (status & T_ERR) { /* An error occurred. */
- status = readl(&lp->tx_ring[entry].misc);
- dev->stats.tx_errors++;
- if (status & TMD3_RTRY)
- dev->stats.tx_aborted_errors++;
- if (status & TMD3_LCAR)
- dev->stats.tx_carrier_errors++;
- if (status & TMD3_LCOL)
- dev->stats.tx_window_errors++;
- if (status & TMD3_UFLO)
- dev->stats.tx_fifo_errors++;
- if (status & (TMD3_BUFF | TMD3_UFLO)) {
- /* Trigger an immediate send demand. */
- outw(CSR0, DEPCA_ADDR);
- outw(INEA | TDMD, DEPCA_DATA);
- }
- } else if (status & (T_MORE | T_ONE)) {
- dev->stats.collisions++;
- } else {
- dev->stats.tx_packets++;
- }
-
- /* Update all the pointers */
- lp->tx_old = (lp->tx_old + 1) & lp->txRingMask;
- }
-
- return 0;
-}
-
-static int depca_close(struct net_device *dev)
-{
- struct depca_private *lp = netdev_priv(dev);
- s16 nicsr;
- u_long ioaddr = dev->base_addr;
-
- netif_stop_queue(dev);
-
- outw(CSR0, DEPCA_ADDR);
-
- if (depca_debug > 1) {
- printk("%s: Shutting down ethercard, status was %2.2x.\n", dev->name, inw(DEPCA_DATA));
- }
-
- /*
- ** We stop the DEPCA here -- it occasionally polls
- ** memory if we don't.
- */
- outw(STOP, DEPCA_DATA);
-
- /*
- ** Give back the ROM in case the user wants to go to DOS
- */
- if (lp->adapter != DEPCA) {
- nicsr = inb(DEPCA_NICSR);
- nicsr &= ~SHE;
- outb(nicsr, DEPCA_NICSR);
- }
-
- /*
- ** Free the associated irq
- */
- free_irq(dev->irq, dev);
- return 0;
-}
-
-static void LoadCSRs(struct net_device *dev)
-{
- struct depca_private *lp = netdev_priv(dev);
- u_long ioaddr = dev->base_addr;
-
- outw(CSR1, DEPCA_ADDR); /* initialisation block address LSW */
- outw((u16) lp->device_ram_start, DEPCA_DATA);
- outw(CSR2, DEPCA_ADDR); /* initialisation block address MSW */
- outw((u16) (lp->device_ram_start >> 16), DEPCA_DATA);
- outw(CSR3, DEPCA_ADDR); /* ALE control */
- outw(ACON, DEPCA_DATA);
-
- outw(CSR0, DEPCA_ADDR); /* Point back to CSR0 */
-}
-
-static int InitRestartDepca(struct net_device *dev)
-{
- struct depca_private *lp = netdev_priv(dev);
- u_long ioaddr = dev->base_addr;
- int i, status = 0;
-
- /* Copy the shadow init_block to shared memory */
- memcpy_toio(lp->sh_mem, &lp->init_block, sizeof(struct depca_init));
-
- outw(CSR0, DEPCA_ADDR); /* point back to CSR0 */
- outw(INIT, DEPCA_DATA); /* initialize DEPCA */
-
- /* wait for lance to complete initialisation */
- for (i = 0; (i < 100) && !(inw(DEPCA_DATA) & IDON); i++);
-
- if (i != 100) {
- /* clear IDON by writing a "1", enable interrupts and start lance */
- outw(IDON | INEA | STRT, DEPCA_DATA);
- if (depca_debug > 2) {
- printk("%s: DEPCA open after %d ticks, init block 0x%08lx csr0 %4.4x.\n", dev->name, i, lp->mem_start, inw(DEPCA_DATA));
- }
- } else {
- printk("%s: DEPCA unopen after %d ticks, init block 0x%08lx csr0 %4.4x.\n", dev->name, i, lp->mem_start, inw(DEPCA_DATA));
- status = -1;
- }
-
- return status;
-}
-
-/*
-** Set or clear the multicast filter for this adaptor.
-*/
-static void set_multicast_list(struct net_device *dev)
-{
- struct depca_private *lp = netdev_priv(dev);
- u_long ioaddr = dev->base_addr;
-
- netif_stop_queue(dev);
- while (lp->tx_old != lp->tx_new); /* Wait for the ring to empty */
-
- STOP_DEPCA; /* Temporarily stop the depca. */
- depca_init_ring(dev); /* Initialize the descriptor rings */
-
- if (dev->flags & IFF_PROMISC) { /* Set promiscuous mode */
- lp->init_block.mode |= PROM;
- } else {
- SetMulticastFilter(dev);
- lp->init_block.mode &= ~PROM; /* Unset promiscuous mode */
- }
-
- LoadCSRs(dev); /* Reload CSR3 */
- InitRestartDepca(dev); /* Resume normal operation. */
- netif_start_queue(dev); /* Unlock the TX ring */
-}
-
-/*
-** Calculate the hash code and update the logical address filter
-** from a list of ethernet multicast addresses.
-** Big endian crc one liner is mine, all mine, ha ha ha ha!
-** LANCE calculates its hash codes big endian.
-*/
-static void SetMulticastFilter(struct net_device *dev)
-{
- struct depca_private *lp = netdev_priv(dev);
- struct netdev_hw_addr *ha;
- int i, j, bit, byte;
- u16 hashcode;
- u32 crc;
-
- if (dev->flags & IFF_ALLMULTI) { /* Set all multicast bits */
- for (i = 0; i < (HASH_TABLE_LEN >> 3); i++) {
- lp->init_block.mcast_table[i] = (char) 0xff;
- }
- } else {
- for (i = 0; i < (HASH_TABLE_LEN >> 3); i++) { /* Clear the multicast table */
- lp->init_block.mcast_table[i] = 0;
- }
- /* Add multicast addresses */
- netdev_for_each_mc_addr(ha, dev) {
- crc = ether_crc(ETH_ALEN, ha->addr);
- hashcode = (crc & 1); /* hashcode is 6 LSb of CRC ... */
- for (j = 0; j < 5; j++) { /* ... in reverse order. */
- hashcode = (hashcode << 1) | ((crc >>= 1) & 1);
- }
-
- byte = hashcode >> 3; /* bit[3-5] -> byte in filter */
- bit = 1 << (hashcode & 0x07); /* bit[0-2] -> bit in byte */
- lp->init_block.mcast_table[byte] |= bit;
- }
- }
-}
-
-static int __init depca_common_init (u_long ioaddr, struct net_device **devp)
-{
- int status = 0;
-
- if (!request_region (ioaddr, DEPCA_TOTAL_SIZE, depca_string)) {
- status = -EBUSY;
- goto out;
- }
-
- if (DevicePresent(ioaddr)) {
- status = -ENODEV;
- goto out_release;
- }
-
- if (!(*devp = alloc_etherdev (sizeof (struct depca_private)))) {
- status = -ENOMEM;
- goto out_release;
- }
-
- return 0;
-
- out_release:
- release_region (ioaddr, DEPCA_TOTAL_SIZE);
- out:
- return status;
-}
-
-/*
-** ISA bus I/O device probe
-*/
-
-static void __init depca_platform_probe (void)
-{
- int i;
- struct platform_device *pldev;
-
- for (i = 0; depca_io_ports[i].iobase; i++) {
- depca_io_ports[i].device = NULL;
-
- /* if an address has been specified on the command
- * line, use it (if valid) */
- if (io && io != depca_io_ports[i].iobase)
- continue;
-
- pldev = platform_device_alloc(depca_string, i);
- if (!pldev)
- continue;
-
- pldev->dev.platform_data = (void *) depca_io_ports[i].iobase;
- depca_io_ports[i].device = pldev;
-
- if (platform_device_add(pldev)) {
- depca_io_ports[i].device = NULL;
- pldev->dev.platform_data = NULL;
- platform_device_put(pldev);
- continue;
- }
-
- if (!pldev->dev.driver) {
- /* The driver was not bound to this device, there was
- * no hardware at this address. Unregister it, as the
- * release function will take care of freeing the
- * allocated structure */
-
- depca_io_ports[i].device = NULL;
- pldev->dev.platform_data = NULL;
- platform_device_unregister (pldev);
- }
- }
-}
-
-static enum depca_type __init depca_shmem_probe (ulong *mem_start)
-{
- u_long mem_base[] = DEPCA_RAM_BASE_ADDRESSES;
- enum depca_type adapter = unknown;
- int i;
-
- for (i = 0; mem_base[i]; i++) {
- *mem_start = mem ? mem : mem_base[i];
- adapter = DepcaSignature (adapter_name, *mem_start);
- if (adapter != unknown)
- break;
- }
-
- return adapter;
-}
-
-static int depca_isa_probe(struct platform_device *device)
-{
- struct net_device *dev;
- struct depca_private *lp;
- u_long ioaddr, mem_start = 0;
- enum depca_type adapter = unknown;
- int status = 0;
-
- ioaddr = (u_long) device->dev.platform_data;
-
- if ((status = depca_common_init (ioaddr, &dev)))
- goto out;
-
- adapter = depca_shmem_probe (&mem_start);
-
- if (adapter == unknown) {
- status = -ENODEV;
- goto out_free;
- }
-
- dev->base_addr = ioaddr;
- dev->irq = irq; /* Use whatever value the user gave
- * us, and 0 if he didn't. */
- lp = netdev_priv(dev);
- lp->depca_bus = DEPCA_BUS_ISA;
- lp->adapter = adapter;
- lp->mem_start = mem_start;
-
- if ((status = depca_hw_init(dev, &device->dev)))
- goto out_free;
-
- return 0;
-
- out_free:
- free_netdev (dev);
- release_region (ioaddr, DEPCA_TOTAL_SIZE);
- out:
- return status;
-}
-
-/*
-** EISA callbacks from sysfs.
-*/
-
-#ifdef CONFIG_EISA
-static int __init depca_eisa_probe (struct device *device)
-{
- enum depca_type adapter = unknown;
- struct eisa_device *edev;
- struct net_device *dev;
- struct depca_private *lp;
- u_long ioaddr, mem_start;
- int status = 0;
-
- edev = to_eisa_device (device);
- ioaddr = edev->base_addr + DEPCA_EISA_IO_PORTS;
-
- if ((status = depca_common_init (ioaddr, &dev)))
- goto out;
-
- /* It would have been nice to get card configuration from the
- * card. Unfortunately, this register is write-only (shares
- * it's address with the ethernet prom)... As we don't parse
- * the EISA configuration structures (yet... :-), just rely on
- * the ISA probing to sort it out... */
-
- adapter = depca_shmem_probe (&mem_start);
- if (adapter == unknown) {
- status = -ENODEV;
- goto out_free;
- }
-
- dev->base_addr = ioaddr;
- dev->irq = irq;
- lp = netdev_priv(dev);
- lp->depca_bus = DEPCA_BUS_EISA;
- lp->adapter = edev->id.driver_data;
- lp->mem_start = mem_start;
-
- if ((status = depca_hw_init(dev, device)))
- goto out_free;
-
- return 0;
-
- out_free:
- free_netdev (dev);
- release_region (ioaddr, DEPCA_TOTAL_SIZE);
- out:
- return status;
-}
-#endif
-
-static int depca_device_remove(struct device *device)
-{
- struct net_device *dev;
- struct depca_private *lp;
- int bus;
-
- dev = dev_get_drvdata(device);
- lp = netdev_priv(dev);
-
- unregister_netdev (dev);
- iounmap (lp->sh_mem);
- release_mem_region (lp->mem_start, lp->mem_len);
- release_region (dev->base_addr, DEPCA_TOTAL_SIZE);
- bus = lp->depca_bus;
- free_netdev (dev);
-
- return 0;
-}
-
-/*
-** Look for a particular board name in the on-board Remote Diagnostics
-** and Boot (readb) ROM. This will also give us a clue to the network RAM
-** base address.
-*/
-static int __init DepcaSignature(char *name, u_long base_addr)
-{
- u_int i, j, k;
- void __iomem *ptr;
- char tmpstr[16];
- u_long prom_addr = base_addr + 0xc000;
- u_long mem_addr = base_addr + 0x8000; /* 32KB */
-
- /* Can't reserve the prom region, it is already marked as
- * used, at least on x86. Instead, reserve a memory region a
- * board would certainly use. If it works, go ahead. If not,
- * run like hell... */
-
- if (!request_mem_region (mem_addr, 16, depca_string))
- return unknown;
-
- /* Copy the first 16 bytes of ROM */
-
- ptr = ioremap(prom_addr, 16);
- if (ptr == NULL) {
- printk(KERN_ERR "depca: I/O remap failed at %lx\n", prom_addr);
- return unknown;
- }
- for (i = 0; i < 16; i++) {
- tmpstr[i] = readb(ptr + i);
- }
- iounmap(ptr);
-
- release_mem_region (mem_addr, 16);
-
- /* Check if PROM contains a valid string */
- for (i = 0; *depca_signature[i] != '\0'; i++) {
- for (j = 0, k = 0; j < 16 && k < strlen(depca_signature[i]); j++) {
- if (depca_signature[i][k] == tmpstr[j]) { /* track signature */
- k++;
- } else { /* lost signature; begin search again */
- k = 0;
- }
- }
- if (k == strlen(depca_signature[i]))
- break;
- }
-
- /* Check if name string is valid, provided there's no PROM */
- if (name && *name && (i == unknown)) {
- for (i = 0; *depca_signature[i] != '\0'; i++) {
- if (strcmp(name, depca_signature[i]) == 0)
- break;
- }
- }
-
- return i;
-}
-
-/*
-** Look for a special sequence in the Ethernet station address PROM that
-** is common across all DEPCA products. Note that the original DEPCA needs
-** its ROM address counter to be initialized and enabled. Only enable
-** if the first address octet is a 0x08 - this minimises the chances of
-** messing around with some other hardware, but it assumes that this DEPCA
-** card initialized itself correctly.
-**
-** Search the Ethernet address ROM for the signature. Since the ROM address
-** counter can start at an arbitrary point, the search must include the entire
-** probe sequence length plus the (length_of_the_signature - 1).
-** Stop the search IMMEDIATELY after the signature is found so that the
-** PROM address counter is correctly positioned at the start of the
-** ethernet address for later read out.
-*/
-static int __init DevicePresent(u_long ioaddr)
-{
- union {
- struct {
- u32 a;
- u32 b;
- } llsig;
- char Sig[sizeof(u32) << 1];
- }
- dev;
- short sigLength = 0;
- s8 data;
- s16 nicsr;
- int i, j, status = 0;
-
- data = inb(DEPCA_PROM); /* clear counter on DEPCA */
- data = inb(DEPCA_PROM); /* read data */
-
- if (data == 0x08) { /* Enable counter on DEPCA */
- nicsr = inb(DEPCA_NICSR);
- nicsr |= AAC;
- outb(nicsr, DEPCA_NICSR);
- }
-
- dev.llsig.a = ETH_PROM_SIG;
- dev.llsig.b = ETH_PROM_SIG;
- sigLength = sizeof(u32) << 1;
-
- for (i = 0, j = 0; j < sigLength && i < PROBE_LENGTH + sigLength - 1; i++) {
- data = inb(DEPCA_PROM);
- if (dev.Sig[j] == data) { /* track signature */
- j++;
- } else { /* lost signature; begin search again */
- if (data == dev.Sig[0]) { /* rare case.... */
- j = 1;
- } else {
- j = 0;
- }
- }
- }
-
- if (j != sigLength) {
- status = -ENODEV; /* search failed */
- }
-
- return status;
-}
-
-/*
-** The DE100 and DE101 PROM accesses were made non-standard for some bizarre
-** reason: access the upper half of the PROM with x=0; access the lower half
-** with x=1.
-*/
-static int __init get_hw_addr(struct net_device *dev)
-{
- u_long ioaddr = dev->base_addr;
- struct depca_private *lp = netdev_priv(dev);
- int i, k, tmp, status = 0;
- u_short j, x, chksum;
-
- x = (((lp->adapter == de100) || (lp->adapter == de101)) ? 1 : 0);
-
- for (i = 0, k = 0, j = 0; j < 3; j++) {
- k <<= 1;
- if (k > 0xffff)
- k -= 0xffff;
-
- k += (u_char) (tmp = inb(DEPCA_PROM + x));
- dev->dev_addr[i++] = (u_char) tmp;
- k += (u_short) ((tmp = inb(DEPCA_PROM + x)) << 8);
- dev->dev_addr[i++] = (u_char) tmp;
-
- if (k > 0xffff)
- k -= 0xffff;
- }
- if (k == 0xffff)
- k = 0;
-
- chksum = (u_char) inb(DEPCA_PROM + x);
- chksum |= (u_short) (inb(DEPCA_PROM + x) << 8);
- if (k != chksum)
- status = -1;
-
- return status;
-}
-
-/*
-** Load a packet into the shared memory
-*/
-static int load_packet(struct net_device *dev, struct sk_buff *skb)
-{
- struct depca_private *lp = netdev_priv(dev);
- int i, entry, end, len, status = NETDEV_TX_OK;
-
- entry = lp->tx_new; /* Ring around buffer number. */
- end = (entry + (skb->len - 1) / TX_BUFF_SZ) & lp->txRingMask;
- if (!(readl(&lp->tx_ring[end].base) & T_OWN)) { /* Enough room? */
- /*
- ** Caution: the write order is important here... don't set up the
- ** ownership rights until all the other information is in place.
- */
- if (end < entry) { /* wrapped buffer */
- len = (lp->txRingMask - entry + 1) * TX_BUFF_SZ;
- memcpy_toio(lp->tx_buff[entry], skb->data, len);
- memcpy_toio(lp->tx_buff[0], skb->data + len, skb->len - len);
- } else { /* linear buffer */
- memcpy_toio(lp->tx_buff[entry], skb->data, skb->len);
- }
-
- /* set up the buffer descriptors */
- len = (skb->len < ETH_ZLEN) ? ETH_ZLEN : skb->len;
- for (i = entry; i != end; i = (i+1) & lp->txRingMask) {
- /* clean out flags */
- writel(readl(&lp->tx_ring[i].base) & ~T_FLAGS, &lp->tx_ring[i].base);
- writew(0x0000, &lp->tx_ring[i].misc); /* clears other error flags */
- writew(-TX_BUFF_SZ, &lp->tx_ring[i].length); /* packet length in buffer */
- len -= TX_BUFF_SZ;
- }
- /* clean out flags */
- writel(readl(&lp->tx_ring[end].base) & ~T_FLAGS, &lp->tx_ring[end].base);
- writew(0x0000, &lp->tx_ring[end].misc); /* clears other error flags */
- writew(-len, &lp->tx_ring[end].length); /* packet length in last buff */
-
- /* start of packet */
- writel(readl(&lp->tx_ring[entry].base) | T_STP, &lp->tx_ring[entry].base);
- /* end of packet */
- writel(readl(&lp->tx_ring[end].base) | T_ENP, &lp->tx_ring[end].base);
-
- for (i = end; i != entry; --i) {
- /* ownership of packet */
- writel(readl(&lp->tx_ring[i].base) | T_OWN, &lp->tx_ring[i].base);
- if (i == 0)
- i = lp->txRingMask + 1;
- }
- writel(readl(&lp->tx_ring[entry].base) | T_OWN, &lp->tx_ring[entry].base);
-
- lp->tx_new = (++end) & lp->txRingMask; /* update current pointers */
- } else {
- status = NETDEV_TX_LOCKED;
- }
-
- return status;
-}
-
-static void depca_dbg_open(struct net_device *dev)
-{
- struct depca_private *lp = netdev_priv(dev);
- u_long ioaddr = dev->base_addr;
- struct depca_init *p = &lp->init_block;
- int i;
-
- if (depca_debug > 1) {
- /* Do not copy the shadow init block into shared memory */
- /* Debugging should not affect normal operation! */
- /* The shadow init block will get copied across during InitRestartDepca */
- printk("%s: depca open with irq %d\n", dev->name, dev->irq);
- printk("Descriptor head addresses (CPU):\n");
- printk(" 0x%lx 0x%lx\n", (u_long) lp->rx_ring, (u_long) lp->tx_ring);
- printk("Descriptor addresses (CPU):\nRX: ");
- for (i = 0; i < lp->rxRingMask; i++) {
- if (i < 3) {
- printk("%p ", &lp->rx_ring[i].base);
- }
- }
- printk("...%p\n", &lp->rx_ring[i].base);
- printk("TX: ");
- for (i = 0; i < lp->txRingMask; i++) {
- if (i < 3) {
- printk("%p ", &lp->tx_ring[i].base);
- }
- }
- printk("...%p\n", &lp->tx_ring[i].base);
- printk("\nDescriptor buffers (Device):\nRX: ");
- for (i = 0; i < lp->rxRingMask; i++) {
- if (i < 3) {
- printk("0x%8.8x ", readl(&lp->rx_ring[i].base));
- }
- }
- printk("...0x%8.8x\n", readl(&lp->rx_ring[i].base));
- printk("TX: ");
- for (i = 0; i < lp->txRingMask; i++) {
- if (i < 3) {
- printk("0x%8.8x ", readl(&lp->tx_ring[i].base));
- }
- }
- printk("...0x%8.8x\n", readl(&lp->tx_ring[i].base));
- printk("Initialisation block at 0x%8.8lx(Phys)\n", lp->mem_start);
- printk(" mode: 0x%4.4x\n", p->mode);
- printk(" physical address: %pM\n", p->phys_addr);
- printk(" multicast hash table: ");
- for (i = 0; i < (HASH_TABLE_LEN >> 3) - 1; i++) {
- printk("%2.2x:", p->mcast_table[i]);
- }
- printk("%2.2x\n", p->mcast_table[i]);
- printk(" rx_ring at: 0x%8.8x\n", p->rx_ring);
- printk(" tx_ring at: 0x%8.8x\n", p->tx_ring);
- printk("buffers (Phys): 0x%8.8lx\n", lp->mem_start + lp->buffs_offset);
- printk("Ring size:\nRX: %d Log2(rxRingMask): 0x%8.8x\n", (int) lp->rxRingMask + 1, lp->rx_rlen);
- printk("TX: %d Log2(txRingMask): 0x%8.8x\n", (int) lp->txRingMask + 1, lp->tx_rlen);
- outw(CSR2, DEPCA_ADDR);
- printk("CSR2&1: 0x%4.4x", inw(DEPCA_DATA));
- outw(CSR1, DEPCA_ADDR);
- printk("%4.4x\n", inw(DEPCA_DATA));
- outw(CSR3, DEPCA_ADDR);
- printk("CSR3: 0x%4.4x\n", inw(DEPCA_DATA));
- }
-}
-
-/*
-** Perform IOCTL call functions here. Some are privileged operations and the
-** effective uid is checked in those cases.
-** All multicast IOCTLs will not work here and are for testing purposes only.
-*/
-static int depca_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
-{
- struct depca_private *lp = netdev_priv(dev);
- struct depca_ioctl *ioc = (struct depca_ioctl *) &rq->ifr_ifru;
- int i, status = 0;
- u_long ioaddr = dev->base_addr;
- union {
- u8 addr[(HASH_TABLE_LEN * ETH_ALEN)];
- u16 sval[(HASH_TABLE_LEN * ETH_ALEN) >> 1];
- u32 lval[(HASH_TABLE_LEN * ETH_ALEN) >> 2];
- } tmp;
- unsigned long flags;
- void *buf;
-
- switch (ioc->cmd) {
- case DEPCA_GET_HWADDR: /* Get the hardware address */
- for (i = 0; i < ETH_ALEN; i++) {
- tmp.addr[i] = dev->dev_addr[i];
- }
- ioc->len = ETH_ALEN;
- if (copy_to_user(ioc->data, tmp.addr, ioc->len))
- return -EFAULT;
- break;
-
- case DEPCA_SET_HWADDR: /* Set the hardware address */
- if (!capable(CAP_NET_ADMIN))
- return -EPERM;
- if (copy_from_user(tmp.addr, ioc->data, ETH_ALEN))
- return -EFAULT;
- for (i = 0; i < ETH_ALEN; i++) {
- dev->dev_addr[i] = tmp.addr[i];
- }
- netif_stop_queue(dev);
- while (lp->tx_old != lp->tx_new)
- cpu_relax(); /* Wait for the ring to empty */
-
- STOP_DEPCA; /* Temporarily stop the depca. */
- depca_init_ring(dev); /* Initialize the descriptor rings */
- LoadCSRs(dev); /* Reload CSR3 */
- InitRestartDepca(dev); /* Resume normal operation. */
- netif_start_queue(dev); /* Unlock the TX ring */
- break;
-
- case DEPCA_SET_PROM: /* Set Promiscuous Mode */
- if (!capable(CAP_NET_ADMIN))
- return -EPERM;
- netif_stop_queue(dev);
- while (lp->tx_old != lp->tx_new)
- cpu_relax(); /* Wait for the ring to empty */
-
- STOP_DEPCA; /* Temporarily stop the depca. */
- depca_init_ring(dev); /* Initialize the descriptor rings */
- lp->init_block.mode |= PROM; /* Set promiscuous mode */
-
- LoadCSRs(dev); /* Reload CSR3 */
- InitRestartDepca(dev); /* Resume normal operation. */
- netif_start_queue(dev); /* Unlock the TX ring */
- break;
-
- case DEPCA_CLR_PROM: /* Clear Promiscuous Mode */
- if (!capable(CAP_NET_ADMIN))
- return -EPERM;
- netif_stop_queue(dev);
- while (lp->tx_old != lp->tx_new)
- cpu_relax(); /* Wait for the ring to empty */
-
- STOP_DEPCA; /* Temporarily stop the depca. */
- depca_init_ring(dev); /* Initialize the descriptor rings */
- lp->init_block.mode &= ~PROM; /* Clear promiscuous mode */
-
- LoadCSRs(dev); /* Reload CSR3 */
- InitRestartDepca(dev); /* Resume normal operation. */
- netif_start_queue(dev); /* Unlock the TX ring */
- break;
-
- case DEPCA_SAY_BOO: /* Say "Boo!" to the kernel log file */
- if(!capable(CAP_NET_ADMIN))
- return -EPERM;
- printk("%s: Boo!\n", dev->name);
- break;
-
- case DEPCA_GET_MCA: /* Get the multicast address table */
- ioc->len = (HASH_TABLE_LEN >> 3);
- if (copy_to_user(ioc->data, lp->init_block.mcast_table, ioc->len))
- return -EFAULT;
- break;
-
- case DEPCA_SET_MCA: /* Set a multicast address */
- if (!capable(CAP_NET_ADMIN))
- return -EPERM;
- if (ioc->len >= HASH_TABLE_LEN)
- return -EINVAL;
- if (copy_from_user(tmp.addr, ioc->data, ETH_ALEN * ioc->len))
- return -EFAULT;
- set_multicast_list(dev);
- break;
-
- case DEPCA_CLR_MCA: /* Clear all multicast addresses */
- if (!capable(CAP_NET_ADMIN))
- return -EPERM;
- set_multicast_list(dev);
- break;
-
- case DEPCA_MCA_EN: /* Enable pass all multicast addressing */
- if (!capable(CAP_NET_ADMIN))
- return -EPERM;
- set_multicast_list(dev);
- break;
-
- case DEPCA_GET_STATS: /* Get the driver statistics */
- ioc->len = sizeof(lp->pktStats);
- buf = kmalloc(ioc->len, GFP_KERNEL);
- if(!buf)
- return -ENOMEM;
- spin_lock_irqsave(&lp->lock, flags);
- memcpy(buf, &lp->pktStats, ioc->len);
- spin_unlock_irqrestore(&lp->lock, flags);
- if (copy_to_user(ioc->data, buf, ioc->len))
- status = -EFAULT;
- kfree(buf);
- break;
-
- case DEPCA_CLR_STATS: /* Zero out the driver statistics */
- if (!capable(CAP_NET_ADMIN))
- return -EPERM;
- spin_lock_irqsave(&lp->lock, flags);
- memset(&lp->pktStats, 0, sizeof(lp->pktStats));
- spin_unlock_irqrestore(&lp->lock, flags);
- break;
-
- case DEPCA_GET_REG: /* Get the DEPCA Registers */
- i = 0;
- tmp.sval[i++] = inw(DEPCA_NICSR);
- outw(CSR0, DEPCA_ADDR); /* status register */
- tmp.sval[i++] = inw(DEPCA_DATA);
- memcpy(&tmp.sval[i], &lp->init_block, sizeof(struct depca_init));
- ioc->len = i + sizeof(struct depca_init);
- if (copy_to_user(ioc->data, tmp.addr, ioc->len))
- return -EFAULT;
- break;
-
- default:
- return -EOPNOTSUPP;
- }
-
- return status;
-}
-
-static int __init depca_module_init (void)
-{
- int err = 0;
-
-#ifdef CONFIG_EISA
- err = eisa_driver_register(&depca_eisa_driver);
- if (err)
- goto err_eisa;
-#endif
- err = platform_driver_register(&depca_isa_driver);
- if (err)
- goto err_eisa;
-
- depca_platform_probe();
- return 0;
-
-err_eisa:
-#ifdef CONFIG_EISA
- eisa_driver_unregister(&depca_eisa_driver);
-#endif
- return err;
-}
-
-static void __exit depca_module_exit (void)
-{
- int i;
-#ifdef CONFIG_EISA
- eisa_driver_unregister (&depca_eisa_driver);
-#endif
- platform_driver_unregister (&depca_isa_driver);
-
- for (i = 0; depca_io_ports[i].iobase; i++) {
- if (depca_io_ports[i].device) {
- depca_io_ports[i].device->dev.platform_data = NULL;
- platform_device_unregister (depca_io_ports[i].device);
- depca_io_ports[i].device = NULL;
- }
- }
-}
-
-module_init (depca_module_init);
-module_exit (depca_module_exit);
diff --git a/drivers/net/ethernet/amd/depca.h b/drivers/net/ethernet/amd/depca.h
deleted file mode 100644
index cdcfe4252c1..00000000000
--- a/drivers/net/ethernet/amd/depca.h
+++ /dev/null
@@ -1,183 +0,0 @@
-/*
- Written 1994 by David C. Davies.
-
- Copyright 1994 David C. Davies. This software may be used and distributed
- according to the terms of the GNU General Public License, incorporated herein by
- reference.
-*/
-
-/*
-** I/O addresses. Note that the 2k buffer option is not supported in
-** this driver.
-*/
-#define DEPCA_NICSR ioaddr+0x00 /* Network interface CSR */
-#define DEPCA_RBI ioaddr+0x02 /* RAM buffer index (2k buffer mode) */
-#define DEPCA_DATA ioaddr+0x04 /* LANCE registers' data port */
-#define DEPCA_ADDR ioaddr+0x06 /* LANCE registers' address port */
-#define DEPCA_HBASE ioaddr+0x08 /* EISA high memory base address reg. */
-#define DEPCA_PROM ioaddr+0x0c /* Ethernet address ROM data port */
-#define DEPCA_CNFG ioaddr+0x0c /* EISA Configuration port */
-#define DEPCA_RBSA ioaddr+0x0e /* RAM buffer starting address (2k buff.) */
-
-/*
-** These are LANCE registers addressable through DEPCA_ADDR
-*/
-#define CSR0 0
-#define CSR1 1
-#define CSR2 2
-#define CSR3 3
-
-/*
-** NETWORK INTERFACE CSR (NI_CSR) bit definitions
-*/
-
-#define TO 0x0100 /* Time Out for remote boot */
-#define SHE 0x0080 /* SHadow memory Enable */
-#define BS 0x0040 /* Bank Select */
-#define BUF 0x0020 /* BUFfer size (1->32k, 0->64k) */
-#define RBE 0x0010 /* Remote Boot Enable (1->net boot) */
-#define AAC 0x0008 /* Address ROM Address Counter (1->enable) */
-#define _128KB 0x0008 /* 128kB Network RAM (1->enable) */
-#define IM 0x0004 /* Interrupt Mask (1->mask) */
-#define IEN 0x0002 /* Interrupt tristate ENable (1->enable) */
-#define LED 0x0001 /* LED control */
-
-/*
-** Control and Status Register 0 (CSR0) bit definitions
-*/
-
-#define ERR 0x8000 /* Error summary */
-#define BABL 0x4000 /* Babble transmitter timeout error */
-#define CERR 0x2000 /* Collision Error */
-#define MISS 0x1000 /* Missed packet */
-#define MERR 0x0800 /* Memory Error */
-#define RINT 0x0400 /* Receiver Interrupt */
-#define TINT 0x0200 /* Transmit Interrupt */
-#define IDON 0x0100 /* Initialization Done */
-#define INTR 0x0080 /* Interrupt Flag */
-#define INEA 0x0040 /* Interrupt Enable */
-#define RXON 0x0020 /* Receiver on */
-#define TXON 0x0010 /* Transmitter on */
-#define TDMD 0x0008 /* Transmit Demand */
-#define STOP 0x0004 /* Stop */
-#define STRT 0x0002 /* Start */
-#define INIT 0x0001 /* Initialize */
-#define INTM 0xff00 /* Interrupt Mask */
-#define INTE 0xfff0 /* Interrupt Enable */
-
-/*
-** CONTROL AND STATUS REGISTER 3 (CSR3)
-*/
-
-#define BSWP 0x0004 /* Byte SWaP */
-#define ACON 0x0002 /* ALE control */
-#define BCON 0x0001 /* Byte CONtrol */
-
-/*
-** Initialization Block Mode Register
-*/
-
-#define PROM 0x8000 /* Promiscuous Mode */
-#define EMBA 0x0080 /* Enable Modified Back-off Algorithm */
-#define INTL 0x0040 /* Internal Loopback */
-#define DRTY 0x0020 /* Disable Retry */
-#define COLL 0x0010 /* Force Collision */
-#define DTCR 0x0008 /* Disable Transmit CRC */
-#define LOOP 0x0004 /* Loopback */
-#define DTX 0x0002 /* Disable the Transmitter */
-#define DRX 0x0001 /* Disable the Receiver */
-
-/*
-** Receive Message Descriptor 1 (RMD1) bit definitions.
-*/
-
-#define R_OWN 0x80000000 /* Owner bit 0 = host, 1 = lance */
-#define R_ERR 0x4000 /* Error Summary */
-#define R_FRAM 0x2000 /* Framing Error */
-#define R_OFLO 0x1000 /* Overflow Error */
-#define R_CRC 0x0800 /* CRC Error */
-#define R_BUFF 0x0400 /* Buffer Error */
-#define R_STP 0x0200 /* Start of Packet */
-#define R_ENP 0x0100 /* End of Packet */
-
-/*
-** Transmit Message Descriptor 1 (TMD1) bit definitions.
-*/
-
-#define T_OWN 0x80000000 /* Owner bit 0 = host, 1 = lance */
-#define T_ERR 0x4000 /* Error Summary */
-#define T_ADD_FCS 0x2000 /* More the 1 retry needed to Xmit */
-#define T_MORE 0x1000 /* >1 retry to transmit packet */
-#define T_ONE 0x0800 /* 1 try needed to transmit the packet */
-#define T_DEF 0x0400 /* Deferred */
-#define T_STP 0x02000000 /* Start of Packet */
-#define T_ENP 0x01000000 /* End of Packet */
-#define T_FLAGS 0xff000000 /* TX Flags Field */
-
-/*
-** Transmit Message Descriptor 3 (TMD3) bit definitions.
-*/
-
-#define TMD3_BUFF 0x8000 /* BUFFer error */
-#define TMD3_UFLO 0x4000 /* UnderFLOw error */
-#define TMD3_RES 0x2000 /* REServed */
-#define TMD3_LCOL 0x1000 /* Late COLlision */
-#define TMD3_LCAR 0x0800 /* Loss of CARrier */
-#define TMD3_RTRY 0x0400 /* ReTRY error */
-
-/*
-** EISA configuration Register (CNFG) bit definitions
-*/
-
-#define TIMEOUT 0x0100 /* 0:2.5 mins, 1: 30 secs */
-#define REMOTE 0x0080 /* Remote Boot Enable -> 1 */
-#define IRQ11 0x0040 /* Enable -> 1 */
-#define IRQ10 0x0020 /* Enable -> 1 */
-#define IRQ9 0x0010 /* Enable -> 1 */
-#define IRQ5 0x0008 /* Enable -> 1 */
-#define BUFF 0x0004 /* 0: 64kB or 128kB, 1: 32kB */
-#define PADR16 0x0002 /* RAM on 64kB boundary */
-#define PADR17 0x0001 /* RAM on 128kB boundary */
-
-/*
-** Miscellaneous
-*/
-#define HASH_TABLE_LEN 64 /* Bits */
-#define HASH_BITS 0x003f /* 6 LS bits */
-
-#define MASK_INTERRUPTS 1
-#define UNMASK_INTERRUPTS 0
-
-#define EISA_EN 0x0001 /* Enable EISA bus buffers */
-#define EISA_ID iobase+0x0080 /* ID long word for EISA card */
-#define EISA_CTRL iobase+0x0084 /* Control word for EISA card */
-
-/*
-** Include the IOCTL stuff
-*/
-#include <linux/sockios.h>
-
-struct depca_ioctl {
- unsigned short cmd; /* Command to run */
- unsigned short len; /* Length of the data buffer */
- unsigned char __user *data; /* Pointer to the data buffer */
-};
-
-/*
-** Recognised commands for the driver
-*/
-#define DEPCA_GET_HWADDR 0x01 /* Get the hardware address */
-#define DEPCA_SET_HWADDR 0x02 /* Get the hardware address */
-#define DEPCA_SET_PROM 0x03 /* Set Promiscuous Mode */
-#define DEPCA_CLR_PROM 0x04 /* Clear Promiscuous Mode */
-#define DEPCA_SAY_BOO 0x05 /* Say "Boo!" to the kernel log file */
-#define DEPCA_GET_MCA 0x06 /* Get a multicast address */
-#define DEPCA_SET_MCA 0x07 /* Set a multicast address */
-#define DEPCA_CLR_MCA 0x08 /* Clear a multicast address */
-#define DEPCA_MCA_EN 0x09 /* Enable a multicast address group */
-#define DEPCA_GET_STATS 0x0a /* Get the driver statistics */
-#define DEPCA_CLR_STATS 0x0b /* Zero out the driver statistics */
-#define DEPCA_GET_REG 0x0c /* Get the Register contents */
-#define DEPCA_SET_REG 0x0d /* Set the Register contents */
-#define DEPCA_DUMP 0x0f /* Dump the DEPCA Status */
-
diff --git a/drivers/net/ethernet/dec/Kconfig b/drivers/net/ethernet/dec/Kconfig
index 37940279ded..68262aa57d0 100644
--- a/drivers/net/ethernet/dec/Kconfig
+++ b/drivers/net/ethernet/dec/Kconfig
@@ -17,21 +17,5 @@ config NET_VENDOR_DEC
your specific card in the following questions.
if NET_VENDOR_DEC
-
-config EWRK3
- tristate "EtherWORKS 3 (DE203, DE204, DE205) support"
- depends on ISA
- select CRC32
- ---help---
- This driver supports the DE203, DE204 and DE205 network (Ethernet)
- cards. If this is for you, say Y and read
- <file:Documentation/networking/ewrk3.txt> in the kernel source as
- well as the Ethernet-HOWTO, available from
- <http://www.tldp.org/docs.html#howto>.
-
- To compile this driver as a module, choose M here. The module
- will be called ewrk3.
-
source "drivers/net/ethernet/dec/tulip/Kconfig"
-
endif # NET_VENDOR_DEC
diff --git a/drivers/net/ethernet/dec/Makefile b/drivers/net/ethernet/dec/Makefile
index 1b01ed8d42c..32993fccbbf 100644
--- a/drivers/net/ethernet/dec/Makefile
+++ b/drivers/net/ethernet/dec/Makefile
@@ -2,5 +2,4 @@
# Makefile for the Digital Equipment Inc. network device drivers.
#
-obj-$(CONFIG_EWRK3) += ewrk3.o
obj-$(CONFIG_NET_TULIP) += tulip/
diff --git a/drivers/net/ethernet/dec/ewrk3.c b/drivers/net/ethernet/dec/ewrk3.c
deleted file mode 100644
index 501517226f6..00000000000
--- a/drivers/net/ethernet/dec/ewrk3.c
+++ /dev/null
@@ -1,1961 +0,0 @@
-/* ewrk3.c: A DIGITAL EtherWORKS 3 ethernet driver for Linux.
-
- Written 1994 by David C. Davies.
-
- Copyright 1994 Digital Equipment Corporation.
-
- This software may be used and distributed according to the terms of
- the GNU General Public License, incorporated herein by reference.
-
- This driver is written for the Digital Equipment Corporation series
- of EtherWORKS ethernet cards:
-
- DE203 Turbo (BNC)
- DE204 Turbo (TP)
- DE205 Turbo (TP BNC)
-
- The driver has been tested on a relatively busy network using the DE205
- card and benchmarked with 'ttcp': it transferred 16M of data at 975kB/s
- (7.8Mb/s) to a DECstation 5000/200.
-
- The author may be reached at davies@maniac.ultranet.com.
-
- =========================================================================
- This driver has been written substantially from scratch, although its
- inheritance of style and stack interface from 'depca.c' and in turn from
- Donald Becker's 'lance.c' should be obvious.
-
- The DE203/4/5 boards all use a new proprietary chip in place of the
- LANCE chip used in prior cards (DEPCA, DE100, DE200/1/2, DE210, DE422).
- Use the depca.c driver in the standard distribution for the LANCE based
- cards from DIGITAL; this driver will not work with them.
-
- The DE203/4/5 cards have 2 main modes: shared memory and I/O only. I/O
- only makes all the card accesses through I/O transactions and no high
- (shared) memory is used. This mode provides a >48% performance penalty
- and is deprecated in this driver, although allowed to provide initial
- setup when hardstrapped.
-
- The shared memory mode comes in 3 flavours: 2kB, 32kB and 64kB. There is
- no point in using any mode other than the 2kB mode - their performances
- are virtually identical, although the driver has been tested in the 2kB
- and 32kB modes. I would suggest you uncomment the line:
-
- FORCE_2K_MODE;
-
- to allow the driver to configure the card as a 2kB card at your current
- base address, thus leaving more room to clutter your system box with
- other memory hungry boards.
-
- As many ISA and EISA cards can be supported under this driver as you
- wish, limited primarily by the available IRQ lines, rather than by the
- available I/O addresses (24 ISA, 16 EISA). I have checked different
- configurations of multiple depca cards and ewrk3 cards and have not
- found a problem yet (provided you have at least depca.c v0.38) ...
-
- The board IRQ setting must be at an unused IRQ which is auto-probed
- using Donald Becker's autoprobe routines. All these cards are at
- {5,10,11,15}.
-
- No 16MB memory limitation should exist with this driver as DMA is not
- used and the common memory area is in low memory on the network card (my
- current system has 20MB and I've not had problems yet).
-
- The ability to load this driver as a loadable module has been included
- and used extensively during the driver development (to save those long
- reboot sequences). To utilise this ability, you have to do 8 things:
-
- 0) have a copy of the loadable modules code installed on your system.
- 1) copy ewrk3.c from the /linux/drivers/net directory to your favourite
- temporary directory.
- 2) edit the source code near line 1898 to reflect the I/O address and
- IRQ you're using.
- 3) compile ewrk3.c, but include -DMODULE in the command line to ensure
- that the correct bits are compiled (see end of source code).
- 4) if you are wanting to add a new card, goto 5. Otherwise, recompile a
- kernel with the ewrk3 configuration turned off and reboot.
- 5) insmod ewrk3.o
- [Alan Cox: Changed this so you can insmod ewrk3.o irq=x io=y]
- [Adam Kropelin: now accepts irq=x1,x2 io=y1,y2 for multiple cards]
- 6) run the net startup bits for your new eth?? interface manually
- (usually /etc/rc.inet[12] at boot time).
- 7) enjoy!
-
- Note that autoprobing is not allowed in loadable modules - the system is
- already up and running and you're messing with interrupts.
-
- To unload a module, turn off the associated interface
- 'ifconfig eth?? down' then 'rmmod ewrk3'.
-
- Promiscuous mode has been turned off in this driver, but all the
- multicast address bits have been turned on. This improved the send
- performance on a busy network by about 13%.
-
- Ioctl's have now been provided (primarily because I wanted to grab some
- packet size statistics). They are patterned after 'plipconfig.c' from a
- suggestion by Alan Cox. Using these ioctls, you can enable promiscuous
- mode, add/delete multicast addresses, change the hardware address, get
- packet size distribution statistics and muck around with the control and
- status register. I'll add others if and when the need arises.
-
- TO DO:
- ------
-
-
- Revision History
- ----------------
-
- Version Date Description
-
- 0.1 26-aug-94 Initial writing. ALPHA code release.
- 0.11 31-aug-94 Fixed: 2k mode memory base calc.,
- LeMAC version calc.,
- IRQ vector assignments during autoprobe.
- 0.12 31-aug-94 Tested working on LeMAC2 (DE20[345]-AC) card.
- Fixed up MCA hash table algorithm.
- 0.20 4-sep-94 Added IOCTL functionality.
- 0.21 14-sep-94 Added I/O mode.
- 0.21axp 15-sep-94 Special version for ALPHA AXP Linux V1.0.
- 0.22 16-sep-94 Added more IOCTLs & tidied up.
- 0.23 21-sep-94 Added transmit cut through.
- 0.24 31-oct-94 Added uid checks in some ioctls.
- 0.30 1-nov-94 BETA code release.
- 0.31 5-dec-94 Added check/allocate region code.
- 0.32 16-jan-95 Broadcast packet fix.
- 0.33 10-Feb-95 Fix recognition bug reported by <bkm@star.rl.ac.uk>.
- 0.40 27-Dec-95 Rationalise MODULE and autoprobe code.
- Rewrite for portability & updated.
- ALPHA support from <jestabro@amt.tay1.dec.com>
- Added verify_area() calls in ewrk3_ioctl() from
- suggestion by <heiko@colossus.escape.de>.
- Add new multicasting code.
- 0.41 20-Jan-96 Fix IRQ set up problem reported by
- <kenneth@bbs.sas.ntu.ac.sg>.
- 0.42 22-Apr-96 Fix alloc_device() bug <jari@markkus2.fimr.fi>
- 0.43 16-Aug-96 Update alloc_device() to conform to de4x5.c
- 0.44 08-Nov-01 use library crc32 functions <Matt_Domsch@dell.com>
- 0.45 19-Jul-02 fix unaligned access on alpha <martin@bruli.net>
- 0.46 10-Oct-02 Multiple NIC support when module <akropel1@rochester.rr.com>
- 0.47 18-Oct-02 ethtool support <akropel1@rochester.rr.com>
- 0.48 18-Oct-02 cli/sti removal for 2.5 <vda@port.imtp.ilyichevsk.odessa.ua>
- ioctl locking, signature search cleanup <akropel1@rochester.rr.com>
-
- =========================================================================
- */
-
-#include <linux/module.h>
-#include <linux/kernel.h>
-#include <linux/sched.h>
-#include <linux/string.h>
-#include <linux/errno.h>
-#include <linux/ioport.h>
-#include <linux/slab.h>
-#include <linux/interrupt.h>
-#include <linux/delay.h>
-#include <linux/init.h>
-#include <linux/crc32.h>
-#include <linux/netdevice.h>
-#include <linux/etherdevice.h>
-#include <linux/skbuff.h>
-#include <linux/ethtool.h>
-#include <linux/time.h>
-#include <linux/types.h>
-#include <linux/unistd.h>
-#include <linux/ctype.h>
-#include <linux/bitops.h>
-
-#include <asm/io.h>
-#include <asm/dma.h>
-#include <asm/uaccess.h>
-
-#include "ewrk3.h"
-
-#define DRV_NAME "ewrk3"
-#define DRV_VERSION "0.48"
-
-static char version[] __initdata =
-DRV_NAME ":v" DRV_VERSION " 2002/10/18 davies@maniac.ultranet.com\n";
-
-#ifdef EWRK3_DEBUG
-static int ewrk3_debug = EWRK3_DEBUG;
-#else
-static int ewrk3_debug = 1;
-#endif
-
-#define EWRK3_NDA 0xffe0 /* No Device Address */
-
-#define PROBE_LENGTH 32
-#define ETH_PROM_SIG 0xAA5500FFUL
-
-#ifndef EWRK3_SIGNATURE
-#define EWRK3_SIGNATURE {"DE203","DE204","DE205",""}
-#define EWRK3_STRLEN 8
-#endif
-
-#ifndef EWRK3_RAM_BASE_ADDRESSES
-#define EWRK3_RAM_BASE_ADDRESSES {0xc0000,0xd0000,0x00000}
-#endif
-
-/*
- ** Sets up the I/O area for the autoprobe.
- */
-#define EWRK3_IO_BASE 0x100 /* Start address for probe search */
-#define EWRK3_IOP_INC 0x20 /* I/O address increment */
-#define EWRK3_TOTAL_SIZE 0x20 /* required I/O address length */
-
-#ifndef MAX_NUM_EWRK3S
-#define MAX_NUM_EWRK3S 21
-#endif
-
-#ifndef EWRK3_EISA_IO_PORTS
-#define EWRK3_EISA_IO_PORTS 0x0c00 /* I/O port base address, slot 0 */
-#endif
-
-#ifndef MAX_EISA_SLOTS
-#define MAX_EISA_SLOTS 16
-#define EISA_SLOT_INC 0x1000
-#endif
-
-#define QUEUE_PKT_TIMEOUT (1*HZ) /* Jiffies */
-
-/*
- ** EtherWORKS 3 shared memory window sizes
- */
-#define IO_ONLY 0x00
-#define SHMEM_2K 0x800
-#define SHMEM_32K 0x8000
-#define SHMEM_64K 0x10000
-
-/*
- ** EtherWORKS 3 IRQ ENABLE/DISABLE
- */
-#define ENABLE_IRQs { \
- icr |= lp->irq_mask;\
- outb(icr, EWRK3_ICR); /* Enable the IRQs */\
-}
-
-#define DISABLE_IRQs { \
- icr = inb(EWRK3_ICR);\
- icr &= ~lp->irq_mask;\
- outb(icr, EWRK3_ICR); /* Disable the IRQs */\
-}
-
-/*
- ** EtherWORKS 3 START/STOP
- */
-#define START_EWRK3 { \
- csr = inb(EWRK3_CSR);\
- csr &= ~(CSR_TXD|CSR_RXD);\
- outb(csr, EWRK3_CSR); /* Enable the TX and/or RX */\
-}
-
-#define STOP_EWRK3 { \
- csr = (CSR_TXD|CSR_RXD);\
- outb(csr, EWRK3_CSR); /* Disable the TX and/or RX */\
-}
-
-/*
- ** The EtherWORKS 3 private structure
- */
-#define EWRK3_PKT_STAT_SZ 16
-#define EWRK3_PKT_BIN_SZ 128 /* Should be >=100 unless you
- increase EWRK3_PKT_STAT_SZ */
-
-struct ewrk3_stats {
- u32 bins[EWRK3_PKT_STAT_SZ];
- u32 unicast;
- u32 multicast;
- u32 broadcast;
- u32 excessive_collisions;
- u32 tx_underruns;
- u32 excessive_underruns;
-};
-
-struct ewrk3_private {
- char adapter_name[80]; /* Name exported to /proc/ioports */
- u_long shmem_base; /* Shared memory start address */
- void __iomem *shmem;
- u_long shmem_length; /* Shared memory window length */
- struct ewrk3_stats pktStats; /* Private stats counters */
- u_char irq_mask; /* Adapter IRQ mask bits */
- u_char mPage; /* Maximum 2kB Page number */
- u_char lemac; /* Chip rev. level */
- u_char hard_strapped; /* Don't allow a full open */
- u_char txc; /* Transmit cut through */
- void __iomem *mctbl; /* Pointer to the multicast table */
- u_char led_mask; /* Used to reserve LED access for ethtool */
- spinlock_t hw_lock;
-};
-
-/*
- ** Force the EtherWORKS 3 card to be in 2kB MODE
- */
-#define FORCE_2K_MODE { \
- shmem_length = SHMEM_2K;\
- outb(((mem_start - 0x80000) >> 11), EWRK3_MBR);\
-}
-
-/*
- ** Public Functions
- */
-static int ewrk3_open(struct net_device *dev);
-static netdev_tx_t ewrk3_queue_pkt(struct sk_buff *skb, struct net_device *dev);
-static irqreturn_t ewrk3_interrupt(int irq, void *dev_id);
-static int ewrk3_close(struct net_device *dev);
-static void set_multicast_list(struct net_device *dev);
-static int ewrk3_ioctl(struct net_device *dev, struct ifreq *rq, int cmd);
-static const struct ethtool_ops ethtool_ops_203;
-static const struct ethtool_ops ethtool_ops;
-
-/*
- ** Private functions
- */
-static int ewrk3_hw_init(struct net_device *dev, u_long iobase);
-static void ewrk3_init(struct net_device *dev);
-static int ewrk3_rx(struct net_device *dev);
-static int ewrk3_tx(struct net_device *dev);
-static void ewrk3_timeout(struct net_device *dev);
-
-static void EthwrkSignature(char *name, char *eeprom_image);
-static int DevicePresent(u_long iobase);
-static void SetMulticastFilter(struct net_device *dev);
-static int EISA_signature(char *name, s32 eisa_id);
-
-static int Read_EEPROM(u_long iobase, u_char eaddr);
-static int Write_EEPROM(short data, u_long iobase, u_char eaddr);
-static u_char get_hw_addr(struct net_device *dev, u_char * eeprom_image, char chipType);
-
-static int ewrk3_probe1(struct net_device *dev, u_long iobase, int irq);
-static int isa_probe(struct net_device *dev, u_long iobase);
-static int eisa_probe(struct net_device *dev, u_long iobase);
-
-static u_char irq[MAX_NUM_EWRK3S+1] = {5, 0, 10, 3, 11, 9, 15, 12};
-
-static char name[EWRK3_STRLEN + 1];
-static int num_ewrks3s;
-
-/*
- ** Miscellaneous defines...
- */
-#define INIT_EWRK3 {\
- outb(EEPROM_INIT, EWRK3_IOPR);\
- mdelay(1);\
-}
-
-#ifndef MODULE
-struct net_device * __init ewrk3_probe(int unit)
-{
- struct net_device *dev = alloc_etherdev(sizeof(struct ewrk3_private));
- int err;
-
- if (!dev)
- return ERR_PTR(-ENOMEM);
-
- if (unit >= 0) {
- sprintf(dev->name, "eth%d", unit);
- netdev_boot_setup_check(dev);
- }
-
- err = ewrk3_probe1(dev, dev->base_addr, dev->irq);
- if (err)
- goto out;
- return dev;
-out:
- free_netdev(dev);
- return ERR_PTR(err);
-
-}
-#endif
-
-static int __init ewrk3_probe1(struct net_device *dev, u_long iobase, int irq)
-{
- int err;
-
- dev->base_addr = iobase;
- dev->irq = irq;
-
- /* Address PROM pattern */
- err = isa_probe(dev, iobase);
- if (err != 0)
- err = eisa_probe(dev, iobase);
-
- if (err)
- return err;
-
- err = register_netdev(dev);
- if (err)
- release_region(dev->base_addr, EWRK3_TOTAL_SIZE);
-
- return err;
-}
-
-static const struct net_device_ops ewrk3_netdev_ops = {
- .ndo_open = ewrk3_open,
- .ndo_start_xmit = ewrk3_queue_pkt,
- .ndo_stop = ewrk3_close,
- .ndo_set_rx_mode = set_multicast_list,
- .ndo_do_ioctl = ewrk3_ioctl,
- .ndo_tx_timeout = ewrk3_timeout,
- .ndo_change_mtu = eth_change_mtu,
- .ndo_set_mac_address = eth_mac_addr,
- .ndo_validate_addr = eth_validate_addr,
-};
-
-static int __init
-ewrk3_hw_init(struct net_device *dev, u_long iobase)
-{
- struct ewrk3_private *lp;
- int i, status = 0;
- u_long mem_start, shmem_length;
- u_char cr, cmr, icr, nicsr, lemac, hard_strapped = 0;
- u_char eeprom_image[EEPROM_MAX], chksum, eisa_cr = 0;
-
- /*
- ** Stop the EWRK3. Enable the DBR ROM. Disable interrupts and remote boot.
- ** This also disables the EISA_ENABLE bit in the EISA Control Register.
- */
- if (iobase > 0x400)
- eisa_cr = inb(EISA_CR);
- INIT_EWRK3;
-
- nicsr = inb(EWRK3_CSR);
-
- icr = inb(EWRK3_ICR);
- icr &= 0x70;
- outb(icr, EWRK3_ICR); /* Disable all the IRQs */
-
- if (nicsr != (CSR_TXD | CSR_RXD))
- return -ENXIO;
-
- /* Check that the EEPROM is alive and well and not living on Pluto... */
- for (chksum = 0, i = 0; i < EEPROM_MAX; i += 2) {
- union {
- short val;
- char c[2];
- } tmp;
-
- tmp.val = (short) Read_EEPROM(iobase, (i >> 1));
- eeprom_image[i] = tmp.c[0];
- eeprom_image[i + 1] = tmp.c[1];
- chksum += eeprom_image[i] + eeprom_image[i + 1];
- }
-
- if (chksum != 0) { /* Bad EEPROM Data! */
- printk("%s: Device has a bad on-board EEPROM.\n", dev->name);
- return -ENXIO;
- }
-
- EthwrkSignature(name, eeprom_image);
- if (*name == '\0')
- return -ENXIO;
-
- dev->base_addr = iobase;
-
- if (iobase > 0x400) {
- outb(eisa_cr, EISA_CR); /* Rewrite the EISA CR */
- }
- lemac = eeprom_image[EEPROM_CHIPVER];
- cmr = inb(EWRK3_CMR);
-
- if (((lemac == LeMAC) && ((cmr & CMR_NO_EEPROM) != CMR_NO_EEPROM)) ||
- ((lemac == LeMAC2) && !(cmr & CMR_HS))) {
- printk("%s: %s at %#4lx", dev->name, name, iobase);
- hard_strapped = 1;
- } else if ((iobase & 0x0fff) == EWRK3_EISA_IO_PORTS) {
- /* EISA slot address */
- printk("%s: %s at %#4lx (EISA slot %ld)",
- dev->name, name, iobase, ((iobase >> 12) & 0x0f));
- } else { /* ISA port address */
- printk("%s: %s at %#4lx", dev->name, name, iobase);
- }
-
- printk(", h/w address ");
- if (lemac != LeMAC2)
- DevicePresent(iobase); /* need after EWRK3_INIT */
- status = get_hw_addr(dev, eeprom_image, lemac);
- printk("%pM\n", dev->dev_addr);
-
- if (status) {
- printk(" which has an EEPROM CRC error.\n");
- return -ENXIO;
- }
-
- if (lemac == LeMAC2) { /* Special LeMAC2 CMR things */
- cmr &= ~(CMR_RA | CMR_WB | CMR_LINK | CMR_POLARITY | CMR_0WS);
- if (eeprom_image[EEPROM_MISC0] & READ_AHEAD)
- cmr |= CMR_RA;
- if (eeprom_image[EEPROM_MISC0] & WRITE_BEHIND)
- cmr |= CMR_WB;
- if (eeprom_image[EEPROM_NETMAN0] & NETMAN_POL)
- cmr |= CMR_POLARITY;
- if (eeprom_image[EEPROM_NETMAN0] & NETMAN_LINK)
- cmr |= CMR_LINK;
- if (eeprom_image[EEPROM_MISC0] & _0WS_ENA)
- cmr |= CMR_0WS;
- }
- if (eeprom_image[EEPROM_SETUP] & SETUP_DRAM)
- cmr |= CMR_DRAM;
- outb(cmr, EWRK3_CMR);
-
- cr = inb(EWRK3_CR); /* Set up the Control Register */
- cr |= eeprom_image[EEPROM_SETUP] & SETUP_APD;
- if (cr & SETUP_APD)
- cr |= eeprom_image[EEPROM_SETUP] & SETUP_PS;
- cr |= eeprom_image[EEPROM_MISC0] & FAST_BUS;
- cr |= eeprom_image[EEPROM_MISC0] & ENA_16;
- outb(cr, EWRK3_CR);
-
- /*
- ** Determine the base address and window length for the EWRK3
- ** RAM from the memory base register.
- */
- mem_start = inb(EWRK3_MBR);
- shmem_length = 0;
- if (mem_start != 0) {
- if ((mem_start >= 0x0a) && (mem_start <= 0x0f)) {
- mem_start *= SHMEM_64K;
- shmem_length = SHMEM_64K;
- } else if ((mem_start >= 0x14) && (mem_start <= 0x1f)) {
- mem_start *= SHMEM_32K;
- shmem_length = SHMEM_32K;
- } else if ((mem_start >= 0x40) && (mem_start <= 0xff)) {
- mem_start = mem_start * SHMEM_2K + 0x80000;
- shmem_length = SHMEM_2K;
- } else {
- return -ENXIO;
- }
- }
- /*
- ** See the top of this source code for comments about
- ** uncommenting this line.
- */
-/* FORCE_2K_MODE; */
-
- if (hard_strapped) {
- printk(" is hard strapped.\n");
- } else if (mem_start) {
- printk(" has a %dk RAM window", (int) (shmem_length >> 10));
- printk(" at 0x%.5lx", mem_start);
- } else {
- printk(" is in I/O only mode");
- }
-
- lp = netdev_priv(dev);
- lp->shmem_base = mem_start;
- lp->shmem = ioremap(mem_start, shmem_length);
- if (!lp->shmem)
- return -ENOMEM;
- lp->shmem_length = shmem_length;
- lp->lemac = lemac;
- lp->hard_strapped = hard_strapped;
- lp->led_mask = CR_LED;
- spin_lock_init(&lp->hw_lock);
-
- lp->mPage = 64;
- if (cmr & CMR_DRAM)
- lp->mPage <<= 1; /* 2 DRAMS on module */
-
- sprintf(lp->adapter_name, "%s (%s)", name, dev->name);
-
- lp->irq_mask = ICR_TNEM | ICR_TXDM | ICR_RNEM | ICR_RXDM;
-
- if (!hard_strapped) {
- /*
- ** Enable EWRK3 board interrupts for autoprobing
- */
- icr |= ICR_IE; /* Enable interrupts */
- outb(icr, EWRK3_ICR);
-
- /* The DMA channel may be passed in on this parameter. */
- dev->dma = 0;
-
- /* To auto-IRQ we enable the initialization-done and DMA err,
- interrupts. For now we will always get a DMA error. */
- if (dev->irq < 2) {
-#ifndef MODULE
- u_char irqnum;
- unsigned long irq_mask;
-
-
- irq_mask = probe_irq_on();
-
- /*
- ** Trigger a TNE interrupt.
- */
- icr |= ICR_TNEM;
- outb(1, EWRK3_TDQ); /* Write to the TX done queue */
- outb(icr, EWRK3_ICR); /* Unmask the TXD interrupt */
-
- irqnum = irq[((icr & IRQ_SEL) >> 4)];
-
- mdelay(20);
- dev->irq = probe_irq_off(irq_mask);
- if ((dev->irq) && (irqnum == dev->irq)) {
- printk(" and uses IRQ%d.\n", dev->irq);
- } else {
- if (!dev->irq) {
- printk(" and failed to detect IRQ line.\n");
- } else if ((irqnum == 1) && (lemac == LeMAC2)) {
- printk(" and an illegal IRQ line detected.\n");
- } else {
- printk(", but incorrect IRQ line detected.\n");
- }
- iounmap(lp->shmem);
- return -ENXIO;
- }
-
- DISABLE_IRQs; /* Mask all interrupts */
-
-#endif /* MODULE */
- } else {
- printk(" and requires IRQ%d.\n", dev->irq);
- }
- }
-
- if (ewrk3_debug > 1) {
- printk(version);
- }
- /* The EWRK3-specific entries in the device structure. */
- dev->netdev_ops = &ewrk3_netdev_ops;
- if (lp->adapter_name[4] == '3')
- SET_ETHTOOL_OPS(dev, &ethtool_ops_203);
- else
- SET_ETHTOOL_OPS(dev, &ethtool_ops);
- dev->watchdog_timeo = QUEUE_PKT_TIMEOUT;
-
- dev->mem_start = 0;
-
- return 0;
-}
-
-
-static int ewrk3_open(struct net_device *dev)
-{
- struct ewrk3_private *lp = netdev_priv(dev);
- u_long iobase = dev->base_addr;
- int status = 0;
- u_char icr, csr;
-
- /*
- ** Stop the TX and RX...
- */
- STOP_EWRK3;
-
- if (!lp->hard_strapped) {
- if (request_irq(dev->irq, (void *) ewrk3_interrupt, 0, "ewrk3", dev)) {
- printk("ewrk3_open(): Requested IRQ%d is busy\n", dev->irq);
- status = -EAGAIN;
- } else {
-
- /*
- ** Re-initialize the EWRK3...
- */
- ewrk3_init(dev);
-
- if (ewrk3_debug > 1) {
- printk("%s: ewrk3 open with irq %d\n", dev->name, dev->irq);
- printk(" physical address: %pM\n", dev->dev_addr);
- if (lp->shmem_length == 0) {
- printk(" no shared memory, I/O only mode\n");
- } else {
- printk(" start of shared memory: 0x%08lx\n", lp->shmem_base);
- printk(" window length: 0x%04lx\n", lp->shmem_length);
- }
- printk(" # of DRAMS: %d\n", ((inb(EWRK3_CMR) & 0x02) ? 2 : 1));
- printk(" csr: 0x%02x\n", inb(EWRK3_CSR));
- printk(" cr: 0x%02x\n", inb(EWRK3_CR));
- printk(" icr: 0x%02x\n", inb(EWRK3_ICR));
- printk(" cmr: 0x%02x\n", inb(EWRK3_CMR));
- printk(" fmqc: 0x%02x\n", inb(EWRK3_FMQC));
- }
- netif_start_queue(dev);
- /*
- ** Unmask EWRK3 board interrupts
- */
- icr = inb(EWRK3_ICR);
- ENABLE_IRQs;
-
- }
- } else {
- printk(KERN_ERR "%s: ewrk3 available for hard strapped set up only.\n", dev->name);
- printk(KERN_ERR " Run the 'ewrk3setup' utility or remove the hard straps.\n");
- return -EINVAL;
- }
-
- return status;
-}
-
-/*
- ** Initialize the EtherWORKS 3 operating conditions
- */
-static void ewrk3_init(struct net_device *dev)
-{
- struct ewrk3_private *lp = netdev_priv(dev);
- u_char csr, page;
- u_long iobase = dev->base_addr;
- int i;
-
- /*
- ** Enable any multicasts
- */
- set_multicast_list(dev);
-
- /*
- ** Set hardware MAC address. Address is initialized from the EEPROM
- ** during startup but may have since been changed by the user.
- */
- for (i=0; i<ETH_ALEN; i++)
- outb(dev->dev_addr[i], EWRK3_PAR0 + i);
-
- /*
- ** Clean out any remaining entries in all the queues here
- */
- while (inb(EWRK3_TQ));
- while (inb(EWRK3_TDQ));
- while (inb(EWRK3_RQ));
- while (inb(EWRK3_FMQ));
-
- /*
- ** Write a clean free memory queue
- */
- for (page = 1; page < lp->mPage; page++) { /* Write the free page numbers */
- outb(page, EWRK3_FMQ); /* to the Free Memory Queue */
- }
-
- START_EWRK3; /* Enable the TX and/or RX */
-}
-
-/*
- * Transmit timeout
- */
-
-static void ewrk3_timeout(struct net_device *dev)
-{
- struct ewrk3_private *lp = netdev_priv(dev);
- u_char icr, csr;
- u_long iobase = dev->base_addr;
-
- if (!lp->hard_strapped)
- {
- printk(KERN_WARNING"%s: transmit timed/locked out, status %04x, resetting.\n",
- dev->name, inb(EWRK3_CSR));
-
- /*
- ** Mask all board interrupts
- */
- DISABLE_IRQs;
-
- /*
- ** Stop the TX and RX...
- */
- STOP_EWRK3;
-
- ewrk3_init(dev);
-
- /*
- ** Unmask EWRK3 board interrupts
- */
- ENABLE_IRQs;
-
- dev->trans_start = jiffies; /* prevent tx timeout */
- netif_wake_queue(dev);
- }
-}
-
-/*
- ** Writes a socket buffer to the free page queue
- */
-static netdev_tx_t ewrk3_queue_pkt(struct sk_buff *skb, struct net_device *dev)
-{
- struct ewrk3_private *lp = netdev_priv(dev);
- u_long iobase = dev->base_addr;
- void __iomem *buf = NULL;
- u_char icr;
- u_char page;
-
- spin_lock_irq (&lp->hw_lock);
- DISABLE_IRQs;
-
- /* if no resources available, exit, request packet be queued */
- if (inb (EWRK3_FMQC) == 0) {
- printk (KERN_WARNING "%s: ewrk3_queue_pkt(): No free resources...\n",
- dev->name);
- printk (KERN_WARNING "%s: ewrk3_queue_pkt(): CSR: %02x ICR: %02x FMQC: %02x\n",
- dev->name, inb (EWRK3_CSR), inb (EWRK3_ICR),
- inb (EWRK3_FMQC));
- goto err_out;
- }
-
- /*
- ** Get a free page from the FMQ
- */
- if ((page = inb (EWRK3_FMQ)) >= lp->mPage) {
- printk ("ewrk3_queue_pkt(): Invalid free memory page (%d).\n",
- (u_char) page);
- goto err_out;
- }
-
-
- /*
- ** Set up shared memory window and pointer into the window
- */
- if (lp->shmem_length == IO_ONLY) {
- outb (page, EWRK3_IOPR);
- } else if (lp->shmem_length == SHMEM_2K) {
- buf = lp->shmem;
- outb (page, EWRK3_MPR);
- } else if (lp->shmem_length == SHMEM_32K) {
- buf = (((short) page << 11) & 0x7800) + lp->shmem;
- outb ((page >> 4), EWRK3_MPR);
- } else if (lp->shmem_length == SHMEM_64K) {
- buf = (((short) page << 11) & 0xf800) + lp->shmem;
- outb ((page >> 5), EWRK3_MPR);
- } else {
- printk (KERN_ERR "%s: Oops - your private data area is hosed!\n",
- dev->name);
- BUG ();
- }
-
- /*
- ** Set up the buffer control structures and copy the data from
- ** the socket buffer to the shared memory .
- */
- if (lp->shmem_length == IO_ONLY) {
- int i;
- u_char *p = skb->data;
- outb ((char) (TCR_QMODE | TCR_PAD | TCR_IFC), EWRK3_DATA);
- outb ((char) (skb->len & 0xff), EWRK3_DATA);
- outb ((char) ((skb->len >> 8) & 0xff), EWRK3_DATA);
- outb ((char) 0x04, EWRK3_DATA);
- for (i = 0; i < skb->len; i++) {
- outb (*p++, EWRK3_DATA);
- }
- outb (page, EWRK3_TQ); /* Start sending pkt */
- } else {
- writeb ((char) (TCR_QMODE | TCR_PAD | TCR_IFC), buf); /* ctrl byte */
- buf += 1;
- writeb ((char) (skb->len & 0xff), buf); /* length (16 bit xfer) */
- buf += 1;
- if (lp->txc) {
- writeb(((skb->len >> 8) & 0xff) | XCT, buf);
- buf += 1;
- writeb (0x04, buf); /* index byte */
- buf += 1;
- writeb (0x00, (buf + skb->len)); /* Write the XCT flag */
- memcpy_toio (buf, skb->data, PRELOAD); /* Write PRELOAD bytes */
- outb (page, EWRK3_TQ); /* Start sending pkt */
- memcpy_toio (buf + PRELOAD,
- skb->data + PRELOAD,
- skb->len - PRELOAD);
- writeb (0xff, (buf + skb->len)); /* Write the XCT flag */
- } else {
- writeb ((skb->len >> 8) & 0xff, buf);
- buf += 1;
- writeb (0x04, buf); /* index byte */
- buf += 1;
- memcpy_toio (buf, skb->data, skb->len); /* Write data bytes */
- outb (page, EWRK3_TQ); /* Start sending pkt */
- }
- }
-
- ENABLE_IRQs;
- spin_unlock_irq (&lp->hw_lock);
-
- dev->stats.tx_bytes += skb->len;
- dev_kfree_skb (skb);
-
- /* Check for free resources: stop Tx queue if there are none */
- if (inb (EWRK3_FMQC) == 0)
- netif_stop_queue (dev);
-
- return NETDEV_TX_OK;
-
-err_out:
- ENABLE_IRQs;
- spin_unlock_irq (&lp->hw_lock);
- return NETDEV_TX_BUSY;
-}
-
-/*
- ** The EWRK3 interrupt handler.
- */
-static irqreturn_t ewrk3_interrupt(int irq, void *dev_id)
-{
- struct net_device *dev = dev_id;
- struct ewrk3_private *lp;
- u_long iobase;
- u_char icr, cr, csr;
-
- lp = netdev_priv(dev);
- iobase = dev->base_addr;
-
- /* get the interrupt information */
- csr = inb(EWRK3_CSR);
-
- /*
- ** Mask the EWRK3 board interrupts and turn on the LED
- */
- spin_lock(&lp->hw_lock);
- DISABLE_IRQs;
-
- cr = inb(EWRK3_CR);
- cr |= lp->led_mask;
- outb(cr, EWRK3_CR);
-
- if (csr & CSR_RNE) /* Rx interrupt (packet[s] arrived) */
- ewrk3_rx(dev);
-
- if (csr & CSR_TNE) /* Tx interrupt (packet sent) */
- ewrk3_tx(dev);
-
- /*
- ** Now deal with the TX/RX disable flags. These are set when there
- ** are no more resources. If resources free up then enable these
- ** interrupts, otherwise mask them - failure to do this will result
- ** in the system hanging in an interrupt loop.
- */
- if (inb(EWRK3_FMQC)) { /* any resources available? */
- lp->irq_mask |= ICR_TXDM | ICR_RXDM; /* enable the interrupt source */
- csr &= ~(CSR_TXD | CSR_RXD); /* ensure restart of a stalled TX or RX */
- outb(csr, EWRK3_CSR);
- netif_wake_queue(dev);
- } else {
- lp->irq_mask &= ~(ICR_TXDM | ICR_RXDM); /* disable the interrupt source */
- }
-
- /* Unmask the EWRK3 board interrupts and turn off the LED */
- cr &= ~(lp->led_mask);
- outb(cr, EWRK3_CR);
- ENABLE_IRQs;
- spin_unlock(&lp->hw_lock);
- return IRQ_HANDLED;
-}
-
-/* Called with lp->hw_lock held */
-static int ewrk3_rx(struct net_device *dev)
-{
- struct ewrk3_private *lp = netdev_priv(dev);
- u_long iobase = dev->base_addr;
- int i, status = 0;
- u_char page;
- void __iomem *buf = NULL;
-
- while (inb(EWRK3_RQC) && !status) { /* Whilst there's incoming data */
- if ((page = inb(EWRK3_RQ)) < lp->mPage) { /* Get next entry's buffer page */
- /*
- ** Set up shared memory window and pointer into the window
- */
- if (lp->shmem_length == IO_ONLY) {
- outb(page, EWRK3_IOPR);
- } else if (lp->shmem_length == SHMEM_2K) {
- buf = lp->shmem;
- outb(page, EWRK3_MPR);
- } else if (lp->shmem_length == SHMEM_32K) {
- buf = (((short) page << 11) & 0x7800) + lp->shmem;
- outb((page >> 4), EWRK3_MPR);
- } else if (lp->shmem_length == SHMEM_64K) {
- buf = (((short) page << 11) & 0xf800) + lp->shmem;
- outb((page >> 5), EWRK3_MPR);
- } else {
- status = -1;
- printk("%s: Oops - your private data area is hosed!\n", dev->name);
- }
-
- if (!status) {
- char rx_status;
- int pkt_len;
-
- if (lp->shmem_length == IO_ONLY) {
- rx_status = inb(EWRK3_DATA);
- pkt_len = inb(EWRK3_DATA);
- pkt_len |= ((u_short) inb(EWRK3_DATA) << 8);
- } else {
- rx_status = readb(buf);
- buf += 1;
- pkt_len = readw(buf);
- buf += 3;
- }
-
- if (!(rx_status & R_ROK)) { /* There was an error. */
- dev->stats.rx_errors++; /* Update the error stats. */
- if (rx_status & R_DBE)
- dev->stats.rx_frame_errors++;
- if (rx_status & R_CRC)
- dev->stats.rx_crc_errors++;
- if (rx_status & R_PLL)
- dev->stats.rx_fifo_errors++;
- } else {
- struct sk_buff *skb;
- skb = netdev_alloc_skb(dev,
- pkt_len + 2);
-
- if (skb != NULL) {
- unsigned char *p;
- skb_reserve(skb, 2); /* Align to 16 bytes */
- p = skb_put(skb, pkt_len);
-
- if (lp->shmem_length == IO_ONLY) {
- *p = inb(EWRK3_DATA); /* dummy read */
- for (i = 0; i < pkt_len; i++) {
- *p++ = inb(EWRK3_DATA);
- }
- } else {
- memcpy_fromio(p, buf, pkt_len);
- }
-
- for (i = 1; i < EWRK3_PKT_STAT_SZ - 1; i++) {
- if (pkt_len < i * EWRK3_PKT_BIN_SZ) {
- lp->pktStats.bins[i]++;
- i = EWRK3_PKT_STAT_SZ;
- }
- }
- p = skb->data; /* Look at the dest addr */
- if (is_multicast_ether_addr(p)) {
- if (is_broadcast_ether_addr(p)) {
- lp->pktStats.broadcast++;
- } else {
- lp->pktStats.multicast++;
- }
- } else if (ether_addr_equal(p,
- dev->dev_addr)) {
- lp->pktStats.unicast++;
- }
- lp->pktStats.bins[0]++; /* Duplicates stats.rx_packets */
- if (lp->pktStats.bins[0] == 0) { /* Reset counters */
- memset(&lp->pktStats, 0, sizeof(lp->pktStats));
- }
- /*
- ** Notify the upper protocol layers that there is another
- ** packet to handle
- */
- skb->protocol = eth_type_trans(skb, dev);
- netif_rx(skb);
-
- /*
- ** Update stats
- */
- dev->stats.rx_packets++;
- dev->stats.rx_bytes += pkt_len;
- } else {
- printk("%s: Insufficient memory; nuking packet.\n", dev->name);
- dev->stats.rx_dropped++; /* Really, deferred. */
- break;
- }
- }
- }
- /*
- ** Return the received buffer to the free memory queue
- */
- outb(page, EWRK3_FMQ);
- } else {
- printk("ewrk3_rx(): Illegal page number, page %d\n", page);
- printk("ewrk3_rx(): CSR: %02x ICR: %02x FMQC: %02x\n", inb(EWRK3_CSR), inb(EWRK3_ICR), inb(EWRK3_FMQC));
- }
- }
- return status;
-}
-
-/*
-** Buffer sent - check for TX buffer errors.
-** Called with lp->hw_lock held
-*/
-static int ewrk3_tx(struct net_device *dev)
-{
- struct ewrk3_private *lp = netdev_priv(dev);
- u_long iobase = dev->base_addr;
- u_char tx_status;
-
- while ((tx_status = inb(EWRK3_TDQ)) > 0) { /* Whilst there's old buffers */
- if (tx_status & T_VSTS) { /* The status is valid */
- if (tx_status & T_TXE) {
- dev->stats.tx_errors++;
- if (tx_status & T_NCL)
- dev->stats.tx_carrier_errors++;
- if (tx_status & T_LCL)
- dev->stats.tx_window_errors++;
- if (tx_status & T_CTU) {
- if ((tx_status & T_COLL) ^ T_XUR) {
- lp->pktStats.tx_underruns++;
- } else {
- lp->pktStats.excessive_underruns++;
- }
- } else if (tx_status & T_COLL) {
- if ((tx_status & T_COLL) ^ T_XCOLL) {
- dev->stats.collisions++;
- } else {
- lp->pktStats.excessive_collisions++;
- }
- }
- } else {
- dev->stats.tx_packets++;
- }
- }
- }
-
- return 0;
-}
-
-static int ewrk3_close(struct net_device *dev)
-{
- struct ewrk3_private *lp = netdev_priv(dev);
- u_long iobase = dev->base_addr;
- u_char icr, csr;
-
- netif_stop_queue(dev);
-
- if (ewrk3_debug > 1) {
- printk("%s: Shutting down ethercard, status was %2.2x.\n",
- dev->name, inb(EWRK3_CSR));
- }
- /*
- ** We stop the EWRK3 here... mask interrupts and stop TX & RX
- */
- DISABLE_IRQs;
-
- STOP_EWRK3;
-
- /*
- ** Clean out the TX and RX queues here (note that one entry
- ** may get added to either the TXD or RX queues if the TX or RX
- ** just starts processing a packet before the STOP_EWRK3 command
- ** is received. This will be flushed in the ewrk3_open() call).
- */
- while (inb(EWRK3_TQ));
- while (inb(EWRK3_TDQ));
- while (inb(EWRK3_RQ));
-
- if (!lp->hard_strapped) {
- free_irq(dev->irq, dev);
- }
- return 0;
-}
-
-/*
- ** Set or clear the multicast filter for this adapter.
- */
-static void set_multicast_list(struct net_device *dev)
-{
- struct ewrk3_private *lp = netdev_priv(dev);
- u_long iobase = dev->base_addr;
- u_char csr;
-
- csr = inb(EWRK3_CSR);
-
- if (lp->shmem_length == IO_ONLY) {
- lp->mctbl = NULL;
- } else {
- lp->mctbl = lp->shmem + PAGE0_HTE;
- }
-
- csr &= ~(CSR_PME | CSR_MCE);
- if (dev->flags & IFF_PROMISC) { /* set promiscuous mode */
- csr |= CSR_PME;
- outb(csr, EWRK3_CSR);
- } else {
- SetMulticastFilter(dev);
- csr |= CSR_MCE;
- outb(csr, EWRK3_CSR);
- }
-}
-
-/*
- ** Calculate the hash code and update the logical address filter
- ** from a list of ethernet multicast addresses.
- ** Little endian crc one liner from Matt Thomas, DEC.
- **
- ** Note that when clearing the table, the broadcast bit must remain asserted
- ** to receive broadcast messages.
- */
-static void SetMulticastFilter(struct net_device *dev)
-{
- struct ewrk3_private *lp = netdev_priv(dev);
- struct netdev_hw_addr *ha;
- u_long iobase = dev->base_addr;
- int i;
- char bit, byte;
- short __iomem *p = lp->mctbl;
- u16 hashcode;
- u32 crc;
-
- spin_lock_irq(&lp->hw_lock);
-
- if (lp->shmem_length == IO_ONLY) {
- outb(0, EWRK3_IOPR);
- outw(PAGE0_HTE, EWRK3_PIR1);
- } else {
- outb(0, EWRK3_MPR);
- }
-
- if (dev->flags & IFF_ALLMULTI) {
- for (i = 0; i < (HASH_TABLE_LEN >> 3); i++) {
- if (lp->shmem_length == IO_ONLY) {
- outb(0xff, EWRK3_DATA);
- } else { /* memset didn't work here */
- writew(0xffff, p);
- p++;
- i++;
- }
- }
- } else {
- /* Clear table except for broadcast bit */
- if (lp->shmem_length == IO_ONLY) {
- for (i = 0; i < (HASH_TABLE_LEN >> 4) - 1; i++) {
- outb(0x00, EWRK3_DATA);
- }
- outb(0x80, EWRK3_DATA);
- i++; /* insert the broadcast bit */
- for (; i < (HASH_TABLE_LEN >> 3); i++) {
- outb(0x00, EWRK3_DATA);
- }
- } else {
- memset_io(lp->mctbl, 0, HASH_TABLE_LEN >> 3);
- writeb(0x80, lp->mctbl + (HASH_TABLE_LEN >> 4) - 1);
- }
-
- /* Update table */
- netdev_for_each_mc_addr(ha, dev) {
- crc = ether_crc_le(ETH_ALEN, ha->addr);
- hashcode = crc & ((1 << 9) - 1); /* hashcode is 9 LSb of CRC */
-
- byte = hashcode >> 3; /* bit[3-8] -> byte in filter */
- bit = 1 << (hashcode & 0x07); /* bit[0-2] -> bit in byte */
-
- if (lp->shmem_length == IO_ONLY) {
- u_char tmp;
-
- outw(PAGE0_HTE + byte, EWRK3_PIR1);
- tmp = inb(EWRK3_DATA);
- tmp |= bit;
- outw(PAGE0_HTE + byte, EWRK3_PIR1);
- outb(tmp, EWRK3_DATA);
- } else {
- writeb(readb(lp->mctbl + byte) | bit, lp->mctbl + byte);
- }
- }
- }
-
- spin_unlock_irq(&lp->hw_lock);
-}
-
-/*
- ** ISA bus I/O device probe
- */
-static int __init isa_probe(struct net_device *dev, u_long ioaddr)
-{
- int i = num_ewrks3s, maxSlots;
- int ret = -ENODEV;
-
- u_long iobase;
-
- if (ioaddr >= 0x400)
- goto out;
-
- if (ioaddr == 0) { /* Autoprobing */
- iobase = EWRK3_IO_BASE; /* Get the first slot address */
- maxSlots = 24;
- } else { /* Probe a specific location */
- iobase = ioaddr;
- maxSlots = i + 1;
- }
-
- for (; (i < maxSlots) && (dev != NULL);
- iobase += EWRK3_IOP_INC, i++)
- {
- if (request_region(iobase, EWRK3_TOTAL_SIZE, DRV_NAME)) {
- if (DevicePresent(iobase) == 0) {
- int irq = dev->irq;
- ret = ewrk3_hw_init(dev, iobase);
- if (!ret)
- break;
- dev->irq = irq;
- }
- release_region(iobase, EWRK3_TOTAL_SIZE);
- }
- }
- out:
-
- return ret;
-}
-
-/*
- ** EISA bus I/O device probe. Probe from slot 1 since slot 0 is usually
- ** the motherboard.
- */
-static int __init eisa_probe(struct net_device *dev, u_long ioaddr)
-{
- int i, maxSlots;
- u_long iobase;
- int ret = -ENODEV;
-
- if (ioaddr < 0x1000)
- goto out;
-
- iobase = ioaddr;
- i = (ioaddr >> 12);
- maxSlots = i + 1;
-
- for (i = 1; (i < maxSlots) && (dev != NULL); i++, iobase += EISA_SLOT_INC) {
- if (EISA_signature(name, EISA_ID) == 0) {
- if (request_region(iobase, EWRK3_TOTAL_SIZE, DRV_NAME) &&
- DevicePresent(iobase) == 0) {
- int irq = dev->irq;
- ret = ewrk3_hw_init(dev, iobase);
- if (!ret)
- break;
- dev->irq = irq;
- }
- release_region(iobase, EWRK3_TOTAL_SIZE);
- }
- }
-
- out:
- return ret;
-}
-
-
-/*
- ** Read the EWRK3 EEPROM using this routine
- */
-static int Read_EEPROM(u_long iobase, u_char eaddr)
-{
- int i;
-
- outb((eaddr & 0x3f), EWRK3_PIR1); /* set up 6 bits of address info */
- outb(EEPROM_RD, EWRK3_IOPR); /* issue read command */
- for (i = 0; i < 5000; i++)
- inb(EWRK3_CSR); /* wait 1msec */
-
- return inw(EWRK3_EPROM1); /* 16 bits data return */
-}
-
-/*
- ** Write the EWRK3 EEPROM using this routine
- */
-static int Write_EEPROM(short data, u_long iobase, u_char eaddr)
-{
- int i;
-
- outb(EEPROM_WR_EN, EWRK3_IOPR); /* issue write enable command */
- for (i = 0; i < 5000; i++)
- inb(EWRK3_CSR); /* wait 1msec */
- outw(data, EWRK3_EPROM1); /* write data to register */
- outb((eaddr & 0x3f), EWRK3_PIR1); /* set up 6 bits of address info */
- outb(EEPROM_WR, EWRK3_IOPR); /* issue write command */
- for (i = 0; i < 75000; i++)
- inb(EWRK3_CSR); /* wait 15msec */
- outb(EEPROM_WR_DIS, EWRK3_IOPR); /* issue write disable command */
- for (i = 0; i < 5000; i++)
- inb(EWRK3_CSR); /* wait 1msec */
-
- return 0;
-}
-
-/*
- ** Look for a particular board name in the on-board EEPROM.
- */
-static void __init EthwrkSignature(char *name, char *eeprom_image)
-{
- int i;
- char *signatures[] = EWRK3_SIGNATURE;
-
- for (i=0; *signatures[i] != '\0'; i++)
- if( !strncmp(eeprom_image+EEPROM_PNAME7, signatures[i], strlen(signatures[i])) )
- break;
-
- if (*signatures[i] != '\0') {
- memcpy(name, eeprom_image+EEPROM_PNAME7, EWRK3_STRLEN);
- name[EWRK3_STRLEN] = '\0';
- } else
- name[0] = '\0';
-}
-
-/*
- ** Look for a special sequence in the Ethernet station address PROM that
- ** is common across all EWRK3 products.
- **
- ** Search the Ethernet address ROM for the signature. Since the ROM address
- ** counter can start at an arbitrary point, the search must include the entire
- ** probe sequence length plus the (length_of_the_signature - 1).
- ** Stop the search IMMEDIATELY after the signature is found so that the
- ** PROM address counter is correctly positioned at the start of the
- ** ethernet address for later read out.
- */
-
-static int __init DevicePresent(u_long iobase)
-{
- union {
- struct {
- u32 a;
- u32 b;
- } llsig;
- char Sig[sizeof(u32) << 1];
- }
- dev;
- short sigLength;
- char data;
- int i, j, status = 0;
-
- dev.llsig.a = ETH_PROM_SIG;
- dev.llsig.b = ETH_PROM_SIG;
- sigLength = sizeof(u32) << 1;
-
- for (i = 0, j = 0; j < sigLength && i < PROBE_LENGTH + sigLength - 1; i++) {
- data = inb(EWRK3_APROM);
- if (dev.Sig[j] == data) { /* track signature */
- j++;
- } else { /* lost signature; begin search again */
- if (data == dev.Sig[0]) {
- j = 1;
- } else {
- j = 0;
- }
- }
- }
-
- if (j != sigLength) {
- status = -ENODEV; /* search failed */
- }
- return status;
-}
-
-static u_char __init get_hw_addr(struct net_device *dev, u_char * eeprom_image, char chipType)
-{
- int i, j, k;
- u_short chksum;
- u_char crc, lfsr, sd, status = 0;
- u_long iobase = dev->base_addr;
- u16 tmp;
-
- if (chipType == LeMAC2) {
- for (crc = 0x6a, j = 0; j < ETH_ALEN; j++) {
- sd = dev->dev_addr[j] = eeprom_image[EEPROM_PADDR0 + j];
- outb(dev->dev_addr[j], EWRK3_PAR0 + j);
- for (k = 0; k < 8; k++, sd >>= 1) {
- lfsr = ((((crc & 0x02) >> 1) ^ (crc & 0x01)) ^ (sd & 0x01)) << 7;
- crc = (crc >> 1) + lfsr;
- }
- }
- if (crc != eeprom_image[EEPROM_PA_CRC])
- status = -1;
- } else {
- for (i = 0, k = 0; i < ETH_ALEN;) {
- k <<= 1;
- if (k > 0xffff)
- k -= 0xffff;
-
- k += (u_char) (tmp = inb(EWRK3_APROM));
- dev->dev_addr[i] = (u_char) tmp;
- outb(dev->dev_addr[i], EWRK3_PAR0 + i);
- i++;
- k += (u_short) ((tmp = inb(EWRK3_APROM)) << 8);
- dev->dev_addr[i] = (u_char) tmp;
- outb(dev->dev_addr[i], EWRK3_PAR0 + i);
- i++;
-
- if (k > 0xffff)
- k -= 0xffff;
- }
- if (k == 0xffff)
- k = 0;
- chksum = inb(EWRK3_APROM);
- chksum |= (inb(EWRK3_APROM) << 8);
- if (k != chksum)
- status = -1;
- }
-
- return status;
-}
-
-/*
- ** Look for a particular board name in the EISA configuration space
- */
-static int __init EISA_signature(char *name, s32 eisa_id)
-{
- u_long i;
- char *signatures[] = EWRK3_SIGNATURE;
- char ManCode[EWRK3_STRLEN];
- union {
- s32 ID;
- char Id[4];
- } Eisa;
- int status = 0;
-
- *name = '\0';
- for (i = 0; i < 4; i++) {
- Eisa.Id[i] = inb(eisa_id + i);
- }
-
- ManCode[0] = (((Eisa.Id[0] >> 2) & 0x1f) + 0x40);
- ManCode[1] = (((Eisa.Id[1] & 0xe0) >> 5) + ((Eisa.Id[0] & 0x03) << 3) + 0x40);
- ManCode[2] = (((Eisa.Id[2] >> 4) & 0x0f) + 0x30);
- ManCode[3] = ((Eisa.Id[2] & 0x0f) + 0x30);
- ManCode[4] = (((Eisa.Id[3] >> 4) & 0x0f) + 0x30);
- ManCode[5] = '\0';
-
- for (i = 0; (*signatures[i] != '\0') && (*name == '\0'); i++) {
- if (strstr(ManCode, signatures[i]) != NULL) {
- strcpy(name, ManCode);
- status = 1;
- }
- }
-
- return status; /* return the device name string */
-}
-
-static void ewrk3_get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *info)
-{
- int fwrev = Read_EEPROM(dev->base_addr, EEPROM_REVLVL);
-
- strlcpy(info->driver, DRV_NAME, sizeof(info->driver));
- strlcpy(info->version, DRV_VERSION, sizeof(info->version));
- snprintf(info->fw_version, sizeof(info->fw_version), "%d", fwrev);
- strlcpy(info->bus_info, "N/A", sizeof(info->bus_info));
- info->eedump_len = EEPROM_MAX;
-}
-
-static int ewrk3_get_settings(struct net_device *dev, struct ethtool_cmd *ecmd)
-{
- struct ewrk3_private *lp = netdev_priv(dev);
- unsigned long iobase = dev->base_addr;
- u8 cr = inb(EWRK3_CR);
-
- switch (lp->adapter_name[4]) {
- case '3': /* DE203 */
- ecmd->supported = SUPPORTED_BNC;
- ecmd->port = PORT_BNC;
- break;
-
- case '4': /* DE204 */
- ecmd->supported = SUPPORTED_TP;
- ecmd->port = PORT_TP;
- break;
-
- case '5': /* DE205 */
- ecmd->supported = SUPPORTED_TP | SUPPORTED_BNC | SUPPORTED_AUI;
- ecmd->autoneg = !(cr & CR_APD);
- /*
- ** Port is only valid if autoneg is disabled
- ** and even then we don't know if AUI is jumpered.
- */
- if (!ecmd->autoneg)
- ecmd->port = (cr & CR_PSEL) ? PORT_BNC : PORT_TP;
- break;
- }
-
- ecmd->supported |= SUPPORTED_10baseT_Half;
- ethtool_cmd_speed_set(ecmd, SPEED_10);
- ecmd->duplex = DUPLEX_HALF;
- return 0;
-}
-
-static int ewrk3_set_settings(struct net_device *dev, struct ethtool_cmd *ecmd)
-{
- struct ewrk3_private *lp = netdev_priv(dev);
- unsigned long iobase = dev->base_addr;
- unsigned long flags;
- u8 cr;
-
- /* DE205 is the only card with anything to set */
- if (lp->adapter_name[4] != '5')
- return -EOPNOTSUPP;
-
- /* Sanity-check parameters */
- if (ecmd->speed != SPEED_10)
- return -EINVAL;
- if (ecmd->port != PORT_TP && ecmd->port != PORT_BNC)
- return -EINVAL; /* AUI is not software-selectable */
- if (ecmd->transceiver != XCVR_INTERNAL)
- return -EINVAL;
- if (ecmd->duplex != DUPLEX_HALF)
- return -EINVAL;
- if (ecmd->phy_address != 0)
- return -EINVAL;
-
- spin_lock_irqsave(&lp->hw_lock, flags);
- cr = inb(EWRK3_CR);
-
- /* If Autoneg is set, change to Auto Port mode */
- /* Otherwise, disable Auto Port and set port explicitly */
- if (ecmd->autoneg) {
- cr &= ~CR_APD;
- } else {
- cr |= CR_APD;
- if (ecmd->port == PORT_TP)
- cr &= ~CR_PSEL; /* Force TP */
- else
- cr |= CR_PSEL; /* Force BNC */
- }
-
- /* Commit the changes */
- outb(cr, EWRK3_CR);
- spin_unlock_irqrestore(&lp->hw_lock, flags);
- return 0;
-}
-
-static u32 ewrk3_get_link(struct net_device *dev)
-{
- unsigned long iobase = dev->base_addr;
- u8 cmr = inb(EWRK3_CMR);
- /* DE203 has BNC only and link status does not apply */
- /* On DE204 this is always valid since TP is the only port. */
- /* On DE205 this reflects TP status even if BNC or AUI is selected. */
- return !(cmr & CMR_LINK);
-}
-
-static int ewrk3_set_phys_id(struct net_device *dev,
- enum ethtool_phys_id_state state)
-{
- struct ewrk3_private *lp = netdev_priv(dev);
- unsigned long iobase = dev->base_addr;
- u8 cr;
-
- spin_lock_irq(&lp->hw_lock);
-
- switch (state) {
- case ETHTOOL_ID_ACTIVE:
- /* Prevent ISR from twiddling the LED */
- lp->led_mask = 0;
- spin_unlock_irq(&lp->hw_lock);
- return 2; /* cycle on/off twice per second */
-
- case ETHTOOL_ID_ON:
- cr = inb(EWRK3_CR);
- outb(cr | CR_LED, EWRK3_CR);
- break;
-
- case ETHTOOL_ID_OFF:
- cr = inb(EWRK3_CR);
- outb(cr & ~CR_LED, EWRK3_CR);
- break;
-
- case ETHTOOL_ID_INACTIVE:
- lp->led_mask = CR_LED;
- cr = inb(EWRK3_CR);
- outb(cr & ~CR_LED, EWRK3_CR);
- }
- spin_unlock_irq(&lp->hw_lock);
-
- return 0;
-}
-
-static const struct ethtool_ops ethtool_ops_203 = {
- .get_drvinfo = ewrk3_get_drvinfo,
- .get_settings = ewrk3_get_settings,
- .set_settings = ewrk3_set_settings,
- .set_phys_id = ewrk3_set_phys_id,
-};
-
-static const struct ethtool_ops ethtool_ops = {
- .get_drvinfo = ewrk3_get_drvinfo,
- .get_settings = ewrk3_get_settings,
- .set_settings = ewrk3_set_settings,
- .get_link = ewrk3_get_link,
- .set_phys_id = ewrk3_set_phys_id,
-};
-
-/*
- ** Perform IOCTL call functions here. Some are privileged operations and the
- ** effective uid is checked in those cases.
- */
-static int ewrk3_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
-{
- struct ewrk3_private *lp = netdev_priv(dev);
- struct ewrk3_ioctl *ioc = (struct ewrk3_ioctl *) &rq->ifr_ifru;
- u_long iobase = dev->base_addr;
- int i, j, status = 0;
- u_char csr;
- unsigned long flags;
- union ewrk3_addr {
- u_char addr[HASH_TABLE_LEN * ETH_ALEN];
- u_short val[(HASH_TABLE_LEN * ETH_ALEN) >> 1];
- };
-
- union ewrk3_addr *tmp;
-
- /* All we handle are private IOCTLs */
- if (cmd != EWRK3IOCTL)
- return -EOPNOTSUPP;
-
- tmp = kmalloc(sizeof(union ewrk3_addr), GFP_KERNEL);
- if(tmp==NULL)
- return -ENOMEM;
-
- switch (ioc->cmd) {
- case EWRK3_GET_HWADDR: /* Get the hardware address */
- for (i = 0; i < ETH_ALEN; i++) {
- tmp->addr[i] = dev->dev_addr[i];
- }
- ioc->len = ETH_ALEN;
- if (copy_to_user(ioc->data, tmp->addr, ioc->len))
- status = -EFAULT;
- break;
-
- case EWRK3_SET_HWADDR: /* Set the hardware address */
- if (capable(CAP_NET_ADMIN)) {
- spin_lock_irqsave(&lp->hw_lock, flags);
- csr = inb(EWRK3_CSR);
- csr |= (CSR_TXD | CSR_RXD);
- outb(csr, EWRK3_CSR); /* Disable the TX and RX */
- spin_unlock_irqrestore(&lp->hw_lock, flags);
-
- if (copy_from_user(tmp->addr, ioc->data, ETH_ALEN)) {
- status = -EFAULT;
- break;
- }
- spin_lock_irqsave(&lp->hw_lock, flags);
- for (i = 0; i < ETH_ALEN; i++) {
- dev->dev_addr[i] = tmp->addr[i];
- outb(tmp->addr[i], EWRK3_PAR0 + i);
- }
-
- csr = inb(EWRK3_CSR);
- csr &= ~(CSR_TXD | CSR_RXD); /* Enable the TX and RX */
- outb(csr, EWRK3_CSR);
- spin_unlock_irqrestore(&lp->hw_lock, flags);
- } else {
- status = -EPERM;
- }
-
- break;
- case EWRK3_SET_PROM: /* Set Promiscuous Mode */
- if (capable(CAP_NET_ADMIN)) {
- spin_lock_irqsave(&lp->hw_lock, flags);
- csr = inb(EWRK3_CSR);
- csr |= CSR_PME;
- csr &= ~CSR_MCE;
- outb(csr, EWRK3_CSR);
- spin_unlock_irqrestore(&lp->hw_lock, flags);
- } else {
- status = -EPERM;
- }
-
- break;
- case EWRK3_CLR_PROM: /* Clear Promiscuous Mode */
- if (capable(CAP_NET_ADMIN)) {
- spin_lock_irqsave(&lp->hw_lock, flags);
- csr = inb(EWRK3_CSR);
- csr &= ~CSR_PME;
- outb(csr, EWRK3_CSR);
- spin_unlock_irqrestore(&lp->hw_lock, flags);
- } else {
- status = -EPERM;
- }
-
- break;
- case EWRK3_GET_MCA: /* Get the multicast address table */
- spin_lock_irqsave(&lp->hw_lock, flags);
- if (lp->shmem_length == IO_ONLY) {
- outb(0, EWRK3_IOPR);
- outw(PAGE0_HTE, EWRK3_PIR1);
- for (i = 0; i < (HASH_TABLE_LEN >> 3); i++) {
- tmp->addr[i] = inb(EWRK3_DATA);
- }
- } else {
- outb(0, EWRK3_MPR);
- memcpy_fromio(tmp->addr, lp->shmem + PAGE0_HTE, (HASH_TABLE_LEN >> 3));
- }
- spin_unlock_irqrestore(&lp->hw_lock, flags);
-
- ioc->len = (HASH_TABLE_LEN >> 3);
- if (copy_to_user(ioc->data, tmp->addr, ioc->len))
- status = -EFAULT;
-
- break;
- case EWRK3_SET_MCA: /* Set a multicast address */
- if (capable(CAP_NET_ADMIN)) {
- if (ioc->len > HASH_TABLE_LEN) {
- status = -EINVAL;
- break;
- }
- if (copy_from_user(tmp->addr, ioc->data, ETH_ALEN * ioc->len)) {
- status = -EFAULT;
- break;
- }
- set_multicast_list(dev);
- } else {
- status = -EPERM;
- }
-
- break;
- case EWRK3_CLR_MCA: /* Clear all multicast addresses */
- if (capable(CAP_NET_ADMIN)) {
- set_multicast_list(dev);
- } else {
- status = -EPERM;
- }
-
- break;
- case EWRK3_MCA_EN: /* Enable multicast addressing */
- if (capable(CAP_NET_ADMIN)) {
- spin_lock_irqsave(&lp->hw_lock, flags);
- csr = inb(EWRK3_CSR);
- csr |= CSR_MCE;
- csr &= ~CSR_PME;
- outb(csr, EWRK3_CSR);
- spin_unlock_irqrestore(&lp->hw_lock, flags);
- } else {
- status = -EPERM;
- }
-
- break;
- case EWRK3_GET_STATS: { /* Get the driver statistics */
- struct ewrk3_stats *tmp_stats =
- kmalloc(sizeof(lp->pktStats), GFP_KERNEL);
- if (!tmp_stats) {
- status = -ENOMEM;
- break;
- }
-
- spin_lock_irqsave(&lp->hw_lock, flags);
- memcpy(tmp_stats, &lp->pktStats, sizeof(lp->pktStats));
- spin_unlock_irqrestore(&lp->hw_lock, flags);
-
- ioc->len = sizeof(lp->pktStats);
- if (copy_to_user(ioc->data, tmp_stats, sizeof(lp->pktStats)))
- status = -EFAULT;
- kfree(tmp_stats);
- break;
- }
- case EWRK3_CLR_STATS: /* Zero out the driver statistics */
- if (capable(CAP_NET_ADMIN)) {
- spin_lock_irqsave(&lp->hw_lock, flags);
- memset(&lp->pktStats, 0, sizeof(lp->pktStats));
- spin_unlock_irqrestore(&lp->hw_lock,flags);
- } else {
- status = -EPERM;
- }
-
- break;
- case EWRK3_GET_CSR: /* Get the CSR Register contents */
- tmp->addr[0] = inb(EWRK3_CSR);
- ioc->len = 1;
- if (copy_to_user(ioc->data, tmp->addr, ioc->len))
- status = -EFAULT;
- break;
- case EWRK3_SET_CSR: /* Set the CSR Register contents */
- if (capable(CAP_NET_ADMIN)) {
- if (copy_from_user(tmp->addr, ioc->data, 1)) {
- status = -EFAULT;
- break;
- }
- outb(tmp->addr[0], EWRK3_CSR);
- } else {
- status = -EPERM;
- }
-
- break;
- case EWRK3_GET_EEPROM: /* Get the EEPROM contents */
- if (capable(CAP_NET_ADMIN)) {
- for (i = 0; i < (EEPROM_MAX >> 1); i++) {
- tmp->val[i] = (short) Read_EEPROM(iobase, i);
- }
- i = EEPROM_MAX;
- tmp->addr[i++] = inb(EWRK3_CMR); /* Config/Management Reg. */
- for (j = 0; j < ETH_ALEN; j++) {
- tmp->addr[i++] = inb(EWRK3_PAR0 + j);
- }
- ioc->len = EEPROM_MAX + 1 + ETH_ALEN;
- if (copy_to_user(ioc->data, tmp->addr, ioc->len))
- status = -EFAULT;
- } else {
- status = -EPERM;
- }
-
- break;
- case EWRK3_SET_EEPROM: /* Set the EEPROM contents */
- if (capable(CAP_NET_ADMIN)) {
- if (copy_from_user(tmp->addr, ioc->data, EEPROM_MAX)) {
- status = -EFAULT;
- break;
- }
- for (i = 0; i < (EEPROM_MAX >> 1); i++) {
- Write_EEPROM(tmp->val[i], iobase, i);
- }
- } else {
- status = -EPERM;
- }
-
- break;
- case EWRK3_GET_CMR: /* Get the CMR Register contents */
- tmp->addr[0] = inb(EWRK3_CMR);
- ioc->len = 1;
- if (copy_to_user(ioc->data, tmp->addr, ioc->len))
- status = -EFAULT;
- break;
- case EWRK3_SET_TX_CUT_THRU: /* Set TX cut through mode */
- if (capable(CAP_NET_ADMIN)) {
- lp->txc = 1;
- } else {
- status = -EPERM;
- }
-
- break;
- case EWRK3_CLR_TX_CUT_THRU: /* Clear TX cut through mode */
- if (capable(CAP_NET_ADMIN)) {
- lp->txc = 0;
- } else {
- status = -EPERM;
- }
-
- break;
- default:
- status = -EOPNOTSUPP;
- }
- kfree(tmp);
- return status;
-}
-
-#ifdef MODULE
-static struct net_device *ewrk3_devs[MAX_NUM_EWRK3S];
-static int ndevs;
-static int io[MAX_NUM_EWRK3S+1] = { 0x300, 0, };
-
-module_param_array(io, int, NULL, 0);
-module_param_array(irq, byte, NULL, 0);
-MODULE_PARM_DESC(io, "EtherWORKS 3 I/O base address(es)");
-MODULE_PARM_DESC(irq, "EtherWORKS 3 IRQ number(s)");
-
-static __exit void ewrk3_exit_module(void)
-{
- int i;
-
- for( i=0; i<ndevs; i++ ) {
- struct net_device *dev = ewrk3_devs[i];
- struct ewrk3_private *lp = netdev_priv(dev);
- ewrk3_devs[i] = NULL;
- unregister_netdev(dev);
- release_region(dev->base_addr, EWRK3_TOTAL_SIZE);
- iounmap(lp->shmem);
- free_netdev(dev);
- }
-}
-
-static __init int ewrk3_init_module(void)
-{
- int i=0;
-
- while( io[i] && irq[i] ) {
- struct net_device *dev
- = alloc_etherdev(sizeof(struct ewrk3_private));
-
- if (!dev)
- break;
-
- if (ewrk3_probe1(dev, io[i], irq[i]) != 0) {
- free_netdev(dev);
- break;
- }
-
- ewrk3_devs[ndevs++] = dev;
- i++;
- }
-
- return ndevs ? 0 : -EIO;
-}
-
-
-/* Hack for breakage in new module stuff */
-module_exit(ewrk3_exit_module);
-module_init(ewrk3_init_module);
-#endif /* MODULE */
-MODULE_LICENSE("GPL");
diff --git a/drivers/net/ethernet/dec/ewrk3.h b/drivers/net/ethernet/dec/ewrk3.h
deleted file mode 100644
index 8e0ee906567..00000000000
--- a/drivers/net/ethernet/dec/ewrk3.h
+++ /dev/null
@@ -1,322 +0,0 @@
-/*
- Written 1994 by David C. Davies.
-
- Copyright 1994 Digital Equipment Corporation.
-
- This software may be used and distributed according to the terms of the
- GNU General Public License, incorporated herein by reference.
-
- The author may be reached as davies@wanton.lkg.dec.com or Digital
- Equipment Corporation, 550 King Street, Littleton MA 01460.
-
- =========================================================================
-*/
-
-/*
-** I/O Address Register Map
-*/
-#define EWRK3_CSR iobase+0x00 /* Control and Status Register */
-#define EWRK3_CR iobase+0x01 /* Control Register */
-#define EWRK3_ICR iobase+0x02 /* Interrupt Control Register */
-#define EWRK3_TSR iobase+0x03 /* Transmit Status Register */
-#define EWRK3_RSVD1 iobase+0x04 /* RESERVED */
-#define EWRK3_RSVD2 iobase+0x05 /* RESERVED */
-#define EWRK3_FMQ iobase+0x06 /* Free Memory Queue */
-#define EWRK3_FMQC iobase+0x07 /* Free Memory Queue Counter */
-#define EWRK3_RQ iobase+0x08 /* Receive Queue */
-#define EWRK3_RQC iobase+0x09 /* Receive Queue Counter */
-#define EWRK3_TQ iobase+0x0a /* Transmit Queue */
-#define EWRK3_TQC iobase+0x0b /* Transmit Queue Counter */
-#define EWRK3_TDQ iobase+0x0c /* Transmit Done Queue */
-#define EWRK3_TDQC iobase+0x0d /* Transmit Done Queue Counter */
-#define EWRK3_PIR1 iobase+0x0e /* Page Index Register 1 */
-#define EWRK3_PIR2 iobase+0x0f /* Page Index Register 2 */
-#define EWRK3_DATA iobase+0x10 /* Data Register */
-#define EWRK3_IOPR iobase+0x11 /* I/O Page Register */
-#define EWRK3_IOBR iobase+0x12 /* I/O Base Register */
-#define EWRK3_MPR iobase+0x13 /* Memory Page Register */
-#define EWRK3_MBR iobase+0x14 /* Memory Base Register */
-#define EWRK3_APROM iobase+0x15 /* Address PROM */
-#define EWRK3_EPROM1 iobase+0x16 /* EEPROM Data Register 1 */
-#define EWRK3_EPROM2 iobase+0x17 /* EEPROM Data Register 2 */
-#define EWRK3_PAR0 iobase+0x18 /* Physical Address Register 0 */
-#define EWRK3_PAR1 iobase+0x19 /* Physical Address Register 1 */
-#define EWRK3_PAR2 iobase+0x1a /* Physical Address Register 2 */
-#define EWRK3_PAR3 iobase+0x1b /* Physical Address Register 3 */
-#define EWRK3_PAR4 iobase+0x1c /* Physical Address Register 4 */
-#define EWRK3_PAR5 iobase+0x1d /* Physical Address Register 5 */
-#define EWRK3_CMR iobase+0x1e /* Configuration/Management Register */
-
-/*
-** Control Page Map
-*/
-#define PAGE0_FMQ 0x000 /* Free Memory Queue */
-#define PAGE0_RQ 0x080 /* Receive Queue */
-#define PAGE0_TQ 0x100 /* Transmit Queue */
-#define PAGE0_TDQ 0x180 /* Transmit Done Queue */
-#define PAGE0_HTE 0x200 /* Hash Table Entries */
-#define PAGE0_RSVD 0x240 /* RESERVED */
-#define PAGE0_USRD 0x600 /* User Data */
-
-/*
-** Control and Status Register bit definitions (EWRK3_CSR)
-*/
-#define CSR_RA 0x80 /* Runt Accept */
-#define CSR_PME 0x40 /* Promiscuous Mode Enable */
-#define CSR_MCE 0x20 /* Multicast Enable */
-#define CSR_TNE 0x08 /* TX Done Queue Not Empty */
-#define CSR_RNE 0x04 /* RX Queue Not Empty */
-#define CSR_TXD 0x02 /* TX Disable */
-#define CSR_RXD 0x01 /* RX Disable */
-
-/*
-** Control Register bit definitions (EWRK3_CR)
-*/
-#define CR_APD 0x80 /* Auto Port Disable */
-#define CR_PSEL 0x40 /* Port Select (0->TP port) */
-#define CR_LBCK 0x20 /* LoopBaCK enable */
-#define CR_FDUP 0x10 /* Full DUPlex enable */
-#define CR_FBUS 0x08 /* Fast BUS enable (ISA clk > 8.33MHz) */
-#define CR_EN_16 0x04 /* ENable 16 bit memory accesses */
-#define CR_LED 0x02 /* LED (1-> turn on) */
-
-/*
-** Interrupt Control Register bit definitions (EWRK3_ICR)
-*/
-#define ICR_IE 0x80 /* Interrupt Enable */
-#define ICR_IS 0x60 /* Interrupt Selected */
-#define ICR_TNEM 0x08 /* TNE Mask (0->mask) */
-#define ICR_RNEM 0x04 /* RNE Mask (0->mask) */
-#define ICR_TXDM 0x02 /* TXD Mask (0->mask) */
-#define ICR_RXDM 0x01 /* RXD Mask (0->mask) */
-
-/*
-** Transmit Status Register bit definitions (EWRK3_TSR)
-*/
-#define TSR_NCL 0x80 /* No Carrier Loopback */
-#define TSR_ID 0x40 /* Initially Deferred */
-#define TSR_LCL 0x20 /* Late CoLlision */
-#define TSR_ECL 0x10 /* Excessive CoLlisions */
-#define TSR_RCNTR 0x0f /* Retries CouNTeR */
-
-/*
-** I/O Page Register bit definitions (EWRK3_IOPR)
-*/
-#define EEPROM_INIT 0xc0 /* EEPROM INIT command */
-#define EEPROM_WR_EN 0xc8 /* EEPROM WRITE ENABLE command */
-#define EEPROM_WR 0xd0 /* EEPROM WRITE command */
-#define EEPROM_WR_DIS 0xd8 /* EEPROM WRITE DISABLE command */
-#define EEPROM_RD 0xe0 /* EEPROM READ command */
-
-/*
-** I/O Base Register bit definitions (EWRK3_IOBR)
-*/
-#define EISA_REGS_EN 0x20 /* Enable EISA ID and Control Registers */
-#define EISA_IOB 0x1f /* Compare bits for I/O Base Address */
-
-/*
-** I/O Configuration/Management Register bit definitions (EWRK3_CMR)
-*/
-#define CMR_RA 0x80 /* Read Ahead */
-#define CMR_WB 0x40 /* Write Behind */
-#define CMR_LINK 0x20 /* 0->TP */
-#define CMR_POLARITY 0x10 /* Informational */
-#define CMR_NO_EEPROM 0x0c /* NO_EEPROM<1:0> pin status */
-#define CMR_HS 0x08 /* Hard Strapped pin status (LeMAC2) */
-#define CMR_PNP 0x04 /* Plug 'n Play */
-#define CMR_DRAM 0x02 /* 0-> 1DRAM, 1-> 2 DRAM on board */
-#define CMR_0WS 0x01 /* Zero Wait State */
-
-/*
-** MAC Receive Status Register bit definitions
-*/
-
-#define R_ROK 0x80 /* Receive OK summary */
-#define R_IAM 0x10 /* Individual Address Match */
-#define R_MCM 0x08 /* MultiCast Match */
-#define R_DBE 0x04 /* Dribble Bit Error */
-#define R_CRC 0x02 /* CRC error */
-#define R_PLL 0x01 /* Phase Lock Lost */
-
-/*
-** MAC Transmit Control Register bit definitions
-*/
-
-#define TCR_SQEE 0x40 /* SQE Enable - look for heartbeat */
-#define TCR_SED 0x20 /* Stop when Error Detected */
-#define TCR_QMODE 0x10 /* Q_MODE */
-#define TCR_LAB 0x08 /* Less Aggressive Backoff */
-#define TCR_PAD 0x04 /* PAD Runt Packets */
-#define TCR_IFC 0x02 /* Insert Frame Check */
-#define TCR_ISA 0x01 /* Insert Source Address */
-
-/*
-** MAC Transmit Status Register bit definitions
-*/
-
-#define T_VSTS 0x80 /* Valid STatuS */
-#define T_CTU 0x40 /* Cut Through Used */
-#define T_SQE 0x20 /* Signal Quality Error */
-#define T_NCL 0x10 /* No Carrier Loopback */
-#define T_LCL 0x08 /* Late Collision */
-#define T_ID 0x04 /* Initially Deferred */
-#define T_COLL 0x03 /* COLLision status */
-#define T_XCOLL 0x03 /* Excessive Collisions */
-#define T_MCOLL 0x02 /* Multiple Collisions */
-#define T_OCOLL 0x01 /* One Collision */
-#define T_NOCOLL 0x00 /* No Collisions */
-#define T_XUR 0x03 /* Excessive Underruns */
-#define T_TXE 0x7f /* TX Errors */
-
-/*
-** EISA Configuration Register bit definitions
-*/
-
-#define EISA_ID iobase + 0x0c80 /* EISA ID Registers */
-#define EISA_ID0 iobase + 0x0c80 /* EISA ID Register 0 */
-#define EISA_ID1 iobase + 0x0c81 /* EISA ID Register 1 */
-#define EISA_ID2 iobase + 0x0c82 /* EISA ID Register 2 */
-#define EISA_ID3 iobase + 0x0c83 /* EISA ID Register 3 */
-#define EISA_CR iobase + 0x0c84 /* EISA Control Register */
-
-/*
-** EEPROM BYTES
-*/
-#define EEPROM_MEMB 0x00
-#define EEPROM_IOB 0x01
-#define EEPROM_EISA_ID0 0x02
-#define EEPROM_EISA_ID1 0x03
-#define EEPROM_EISA_ID2 0x04
-#define EEPROM_EISA_ID3 0x05
-#define EEPROM_MISC0 0x06
-#define EEPROM_MISC1 0x07
-#define EEPROM_PNAME7 0x08
-#define EEPROM_PNAME6 0x09
-#define EEPROM_PNAME5 0x0a
-#define EEPROM_PNAME4 0x0b
-#define EEPROM_PNAME3 0x0c
-#define EEPROM_PNAME2 0x0d
-#define EEPROM_PNAME1 0x0e
-#define EEPROM_PNAME0 0x0f
-#define EEPROM_SWFLAGS 0x10
-#define EEPROM_HWCAT 0x11
-#define EEPROM_NETMAN2 0x12
-#define EEPROM_REVLVL 0x13
-#define EEPROM_NETMAN0 0x14
-#define EEPROM_NETMAN1 0x15
-#define EEPROM_CHIPVER 0x16
-#define EEPROM_SETUP 0x17
-#define EEPROM_PADDR0 0x18
-#define EEPROM_PADDR1 0x19
-#define EEPROM_PADDR2 0x1a
-#define EEPROM_PADDR3 0x1b
-#define EEPROM_PADDR4 0x1c
-#define EEPROM_PADDR5 0x1d
-#define EEPROM_PA_CRC 0x1e
-#define EEPROM_CHKSUM 0x1f
-
-/*
-** EEPROM bytes for checksumming
-*/
-#define EEPROM_MAX 32 /* bytes */
-
-/*
-** EEPROM MISCELLANEOUS FLAGS
-*/
-#define RBE_SHADOW 0x0100 /* Remote Boot Enable Shadow */
-#define READ_AHEAD 0x0080 /* Read Ahead feature */
-#define IRQ_SEL2 0x0070 /* IRQ line selection (LeMAC2) */
-#define IRQ_SEL 0x0060 /* IRQ line selection */
-#define FAST_BUS 0x0008 /* ISA Bus speeds > 8.33MHz */
-#define ENA_16 0x0004 /* Enables 16 bit memory transfers */
-#define WRITE_BEHIND 0x0002 /* Write Behind feature */
-#define _0WS_ENA 0x0001 /* Zero Wait State Enable */
-
-/*
-** EEPROM NETWORK MANAGEMENT FLAGS
-*/
-#define NETMAN_POL 0x04 /* Polarity defeat */
-#define NETMAN_LINK 0x02 /* Link defeat */
-#define NETMAN_CCE 0x01 /* Custom Counters Enable */
-
-/*
-** EEPROM SW FLAGS
-*/
-#define SW_SQE 0x10 /* Signal Quality Error */
-#define SW_LAB 0x08 /* Less Aggressive Backoff */
-#define SW_INIT 0x04 /* Initialized */
-#define SW_TIMEOUT 0x02 /* 0:2.5 mins, 1: 30 secs */
-#define SW_REMOTE 0x01 /* Remote Boot Enable -> 1 */
-
-/*
-** EEPROM SETUP FLAGS
-*/
-#define SETUP_APD 0x80 /* AutoPort Disable */
-#define SETUP_PS 0x40 /* Port Select */
-#define SETUP_MP 0x20 /* MultiPort */
-#define SETUP_1TP 0x10 /* 1 port, TP */
-#define SETUP_1COAX 0x00 /* 1 port, Coax */
-#define SETUP_DRAM 0x02 /* Number of DRAMS on board */
-
-/*
-** EEPROM MANAGEMENT FLAGS
-*/
-#define MGMT_CCE 0x01 /* Custom Counters Enable */
-
-/*
-** EEPROM VERSIONS
-*/
-#define LeMAC 0x11
-#define LeMAC2 0x12
-
-/*
-** Miscellaneous
-*/
-
-#define EEPROM_WAIT_TIME 1000 /* Number of microseconds */
-#define EISA_EN 0x0001 /* Enable EISA bus buffers */
-
-#define HASH_TABLE_LEN 512 /* Bits */
-
-#define XCT 0x80 /* Transmit Cut Through */
-#define PRELOAD 16 /* 4 long words */
-
-#define MASK_INTERRUPTS 1
-#define UNMASK_INTERRUPTS 0
-
-#define EEPROM_OFFSET(a) ((u_short)((u_long)(a)))
-
-/*
-** Include the IOCTL stuff
-*/
-#include <linux/sockios.h>
-
-#define EWRK3IOCTL SIOCDEVPRIVATE
-
-struct ewrk3_ioctl {
- unsigned short cmd; /* Command to run */
- unsigned short len; /* Length of the data buffer */
- unsigned char __user *data; /* Pointer to the data buffer */
-};
-
-/*
-** Recognised commands for the driver
-*/
-#define EWRK3_GET_HWADDR 0x01 /* Get the hardware address */
-#define EWRK3_SET_HWADDR 0x02 /* Get the hardware address */
-#define EWRK3_SET_PROM 0x03 /* Set Promiscuous Mode */
-#define EWRK3_CLR_PROM 0x04 /* Clear Promiscuous Mode */
-#define EWRK3_SAY_BOO 0x05 /* Say "Boo!" to the kernel log file */
-#define EWRK3_GET_MCA 0x06 /* Get a multicast address */
-#define EWRK3_SET_MCA 0x07 /* Set a multicast address */
-#define EWRK3_CLR_MCA 0x08 /* Clear a multicast address */
-#define EWRK3_MCA_EN 0x09 /* Enable a multicast address group */
-#define EWRK3_GET_STATS 0x0a /* Get the driver statistics */
-#define EWRK3_CLR_STATS 0x0b /* Zero out the driver statistics */
-#define EWRK3_GET_CSR 0x0c /* Get the CSR Register contents */
-#define EWRK3_SET_CSR 0x0d /* Set the CSR Register contents */
-#define EWRK3_GET_EEPROM 0x0e /* Get the EEPROM contents */
-#define EWRK3_SET_EEPROM 0x0f /* Set the EEPROM contents */
-#define EWRK3_GET_CMR 0x10 /* Get the CMR Register contents */
-#define EWRK3_CLR_TX_CUT_THRU 0x11 /* Clear the TX cut through mode */
-#define EWRK3_SET_TX_CUT_THRU 0x12 /* Set the TX cut through mode */
diff --git a/drivers/net/ethernet/dlink/Kconfig b/drivers/net/ethernet/dlink/Kconfig
index b5afe218c31..ee26ce78e27 100644
--- a/drivers/net/ethernet/dlink/Kconfig
+++ b/drivers/net/ethernet/dlink/Kconfig
@@ -5,7 +5,7 @@
config NET_VENDOR_DLINK
bool "D-Link devices"
default y
- depends on PCI || PARPORT
+ depends on PCI
---help---
If you have a network (Ethernet) card belonging to this class, say Y
and read the Ethernet-HOWTO, available from
@@ -18,36 +18,6 @@ config NET_VENDOR_DLINK
if NET_VENDOR_DLINK
-config DE600
- tristate "D-Link DE600 pocket adapter support"
- depends on PARPORT
- ---help---
- This is a network (Ethernet) device which attaches to your parallel
- port. Read <file:Documentation/networking/DLINK.txt> as well as the
- Ethernet-HOWTO, available from
- <http://www.tldp.org/docs.html#howto>, if you want to use
- this. It is possible to have several devices share a single parallel
- port and it is safe to compile the corresponding drivers into the
- kernel.
-
- To compile this driver as a module, choose M here: the module
- will be called de600.
-
-config DE620
- tristate "D-Link DE620 pocket adapter support"
- depends on PARPORT
- ---help---
- This is a network (Ethernet) device which attaches to your parallel
- port. Read <file:Documentation/networking/DLINK.txt> as well as the
- Ethernet-HOWTO, available from
- <http://www.tldp.org/docs.html#howto>, if you want to use
- this. It is possible to have several devices share a single parallel
- port and it is safe to compile the corresponding drivers into the
- kernel.
-
- To compile this driver as a module, choose M here: the module
- will be called de620.
-
config DL2K
tristate "DL2000/TC902x-based Gigabit Ethernet support"
depends on PCI
diff --git a/drivers/net/ethernet/dlink/Makefile b/drivers/net/ethernet/dlink/Makefile
index c705eaa4f5b..40085f67157 100644
--- a/drivers/net/ethernet/dlink/Makefile
+++ b/drivers/net/ethernet/dlink/Makefile
@@ -2,7 +2,5 @@
# Makefile for the D-Link network device drivers.
#
-obj-$(CONFIG_DE600) += de600.o
-obj-$(CONFIG_DE620) += de620.o
obj-$(CONFIG_DL2K) += dl2k.o
obj-$(CONFIG_SUNDANCE) += sundance.o
diff --git a/drivers/net/ethernet/dlink/de600.c b/drivers/net/ethernet/dlink/de600.c
deleted file mode 100644
index 414f0eea104..00000000000
--- a/drivers/net/ethernet/dlink/de600.c
+++ /dev/null
@@ -1,529 +0,0 @@
-static const char version[] = "de600.c: $Revision: 1.41-2.5 $, Bjorn Ekwall (bj0rn@blox.se)\n";
-/*
- * de600.c
- *
- * Linux driver for the D-Link DE-600 Ethernet pocket adapter.
- *
- * Portions (C) Copyright 1993, 1994 by Bjorn Ekwall
- * The Author may be reached as bj0rn@blox.se
- *
- * Based on adapter information gathered from DE600.ASM by D-Link Inc.,
- * as included on disk C in the v.2.11 of PC/TCP from FTP Software.
- * For DE600.asm:
- * Portions (C) Copyright 1990 D-Link, Inc.
- * Copyright, 1988-1992, Russell Nelson, Crynwr Software
- *
- * Adapted to the sample network driver core for linux,
- * written by: Donald Becker <becker@super.org>
- * (Now at <becker@scyld.com>)
- *
- **************************************************************/
-/*
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2, or (at your option)
- * any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
- **************************************************************/
-
-/* Add more time here if your adapter won't work OK: */
-#define DE600_SLOW_DOWN udelay(delay_time)
-
-#include <linux/module.h>
-#include <linux/kernel.h>
-#include <linux/types.h>
-#include <linux/fcntl.h>
-#include <linux/string.h>
-#include <linux/interrupt.h>
-#include <linux/ioport.h>
-#include <linux/in.h>
-#include <linux/errno.h>
-#include <linux/init.h>
-#include <linux/delay.h>
-#include <linux/inet.h>
-#include <linux/netdevice.h>
-#include <linux/etherdevice.h>
-#include <linux/skbuff.h>
-
-#include <asm/io.h>
-
-#include "de600.h"
-
-static bool check_lost = true;
-module_param(check_lost, bool, 0);
-MODULE_PARM_DESC(check_lost, "If set then check for unplugged de600");
-
-static unsigned int delay_time = 10;
-module_param(delay_time, int, 0);
-MODULE_PARM_DESC(delay_time, "DE-600 deley on I/O in microseconds");
-
-
-/*
- * D-Link driver variables:
- */
-
-static volatile int rx_page;
-
-#define TX_PAGES 2
-static volatile int tx_fifo[TX_PAGES];
-static volatile int tx_fifo_in;
-static volatile int tx_fifo_out;
-static volatile int free_tx_pages = TX_PAGES;
-static int was_down;
-static DEFINE_SPINLOCK(de600_lock);
-
-static inline u8 de600_read_status(struct net_device *dev)
-{
- u8 status;
-
- outb_p(STATUS, DATA_PORT);
- status = inb(STATUS_PORT);
- outb_p(NULL_COMMAND | HI_NIBBLE, DATA_PORT);
-
- return status;
-}
-
-static inline u8 de600_read_byte(unsigned char type, struct net_device *dev)
-{
- /* dev used by macros */
- u8 lo;
- outb_p((type), DATA_PORT);
- lo = ((unsigned char)inb(STATUS_PORT)) >> 4;
- outb_p((type) | HI_NIBBLE, DATA_PORT);
- return ((unsigned char)inb(STATUS_PORT) & (unsigned char)0xf0) | lo;
-}
-
-/*
- * Open/initialize the board. This is called (in the current kernel)
- * after booting when 'ifconfig <dev->name> $IP_ADDR' is run (in rc.inet1).
- *
- * This routine should set everything up anew at each open, even
- * registers that "should" only need to be set once at boot, so that
- * there is a non-reboot way to recover if something goes wrong.
- */
-
-static int de600_open(struct net_device *dev)
-{
- unsigned long flags;
- int ret = request_irq(DE600_IRQ, de600_interrupt, 0, dev->name, dev);
- if (ret) {
- printk(KERN_ERR "%s: unable to get IRQ %d\n", dev->name, DE600_IRQ);
- return ret;
- }
- spin_lock_irqsave(&de600_lock, flags);
- ret = adapter_init(dev);
- spin_unlock_irqrestore(&de600_lock, flags);
- return ret;
-}
-
-/*
- * The inverse routine to de600_open().
- */
-
-static int de600_close(struct net_device *dev)
-{
- select_nic();
- rx_page = 0;
- de600_put_command(RESET);
- de600_put_command(STOP_RESET);
- de600_put_command(0);
- select_prn();
- free_irq(DE600_IRQ, dev);
- return 0;
-}
-
-static inline void trigger_interrupt(struct net_device *dev)
-{
- de600_put_command(FLIP_IRQ);
- select_prn();
- DE600_SLOW_DOWN;
- select_nic();
- de600_put_command(0);
-}
-
-/*
- * Copy a buffer to the adapter transmit page memory.
- * Start sending.
- */
-
-static int de600_start_xmit(struct sk_buff *skb, struct net_device *dev)
-{
- unsigned long flags;
- int transmit_from;
- int len;
- int tickssofar;
- u8 *buffer = skb->data;
- int i;
-
- if (free_tx_pages <= 0) { /* Do timeouts, to avoid hangs. */
- tickssofar = jiffies - dev_trans_start(dev);
- if (tickssofar < HZ/20)
- return NETDEV_TX_BUSY;
- /* else */
- printk(KERN_WARNING "%s: transmit timed out (%d), %s?\n", dev->name, tickssofar, "network cable problem");
- /* Restart the adapter. */
- spin_lock_irqsave(&de600_lock, flags);
- if (adapter_init(dev)) {
- spin_unlock_irqrestore(&de600_lock, flags);
- return NETDEV_TX_BUSY;
- }
- spin_unlock_irqrestore(&de600_lock, flags);
- }
-
- /* Start real output */
- pr_debug("de600_start_xmit:len=%d, page %d/%d\n", skb->len, tx_fifo_in, free_tx_pages);
-
- if ((len = skb->len) < RUNT)
- len = RUNT;
-
- spin_lock_irqsave(&de600_lock, flags);
- select_nic();
- tx_fifo[tx_fifo_in] = transmit_from = tx_page_adr(tx_fifo_in) - len;
- tx_fifo_in = (tx_fifo_in + 1) % TX_PAGES; /* Next free tx page */
-
- if(check_lost)
- {
- /* This costs about 40 instructions per packet... */
- de600_setup_address(NODE_ADDRESS, RW_ADDR);
- de600_read_byte(READ_DATA, dev);
- if (was_down || (de600_read_byte(READ_DATA, dev) != 0xde)) {
- if (adapter_init(dev)) {
- spin_unlock_irqrestore(&de600_lock, flags);
- return NETDEV_TX_BUSY;
- }
- }
- }
-
- de600_setup_address(transmit_from, RW_ADDR);
- for (i = 0; i < skb->len ; ++i, ++buffer)
- de600_put_byte(*buffer);
- for (; i < len; ++i)
- de600_put_byte(0);
-
- if (free_tx_pages-- == TX_PAGES) { /* No transmission going on */
- dev->trans_start = jiffies;
- netif_start_queue(dev); /* allow more packets into adapter */
- /* Send page and generate a faked interrupt */
- de600_setup_address(transmit_from, TX_ADDR);
- de600_put_command(TX_ENABLE);
- }
- else {
- if (free_tx_pages)
- netif_start_queue(dev);
- else
- netif_stop_queue(dev);
- select_prn();
- }
- spin_unlock_irqrestore(&de600_lock, flags);
- dev_kfree_skb(skb);
- return NETDEV_TX_OK;
-}
-
-/*
- * The typical workload of the driver:
- * Handle the network interface interrupts.
- */
-
-static irqreturn_t de600_interrupt(int irq, void *dev_id)
-{
- struct net_device *dev = dev_id;
- u8 irq_status;
- int retrig = 0;
- int boguscount = 0;
-
- spin_lock(&de600_lock);
-
- select_nic();
- irq_status = de600_read_status(dev);
-
- do {
- pr_debug("de600_interrupt (%02X)\n", irq_status);
-
- if (irq_status & RX_GOOD)
- de600_rx_intr(dev);
- else if (!(irq_status & RX_BUSY))
- de600_put_command(RX_ENABLE);
-
- /* Any transmission in progress? */
- if (free_tx_pages < TX_PAGES)
- retrig = de600_tx_intr(dev, irq_status);
- else
- retrig = 0;
-
- irq_status = de600_read_status(dev);
- } while ( (irq_status & RX_GOOD) || ((++boguscount < 100) && retrig) );
- /*
- * Yeah, it _looks_ like busy waiting, smells like busy waiting
- * and I know it's not PC, but please, it will only occur once
- * in a while and then only for a loop or so (< 1ms for sure!)
- */
-
- /* Enable adapter interrupts */
- select_prn();
- if (retrig)
- trigger_interrupt(dev);
- spin_unlock(&de600_lock);
- return IRQ_HANDLED;
-}
-
-static int de600_tx_intr(struct net_device *dev, int irq_status)
-{
- /*
- * Returns 1 if tx still not done
- */
-
- /* Check if current transmission is done yet */
- if (irq_status & TX_BUSY)
- return 1; /* tx not done, try again */
-
- /* else */
- /* If last transmission OK then bump fifo index */
- if (!(irq_status & TX_FAILED16)) {
- tx_fifo_out = (tx_fifo_out + 1) % TX_PAGES;
- ++free_tx_pages;
- dev->stats.tx_packets++;
- netif_wake_queue(dev);
- }
-
- /* More to send, or resend last packet? */
- if ((free_tx_pages < TX_PAGES) || (irq_status & TX_FAILED16)) {
- dev->trans_start = jiffies;
- de600_setup_address(tx_fifo[tx_fifo_out], TX_ADDR);
- de600_put_command(TX_ENABLE);
- return 1;
- }
- /* else */
-
- return 0;
-}
-
-/*
- * We have a good packet, get it out of the adapter.
- */
-static void de600_rx_intr(struct net_device *dev)
-{
- struct sk_buff *skb;
- int i;
- int read_from;
- int size;
- unsigned char *buffer;
-
- /* Get size of received packet */
- size = de600_read_byte(RX_LEN, dev); /* low byte */
- size += (de600_read_byte(RX_LEN, dev) << 8); /* high byte */
- size -= 4; /* Ignore trailing 4 CRC-bytes */
-
- /* Tell adapter where to store next incoming packet, enable receiver */
- read_from = rx_page_adr();
- next_rx_page();
- de600_put_command(RX_ENABLE);
-
- if ((size < 32) || (size > 1535)) {
- printk(KERN_WARNING "%s: Bogus packet size %d.\n", dev->name, size);
- if (size > 10000)
- adapter_init(dev);
- return;
- }
-
- skb = netdev_alloc_skb(dev, size + 2);
- if (skb == NULL) {
- printk("%s: Couldn't allocate a sk_buff of size %d.\n", dev->name, size);
- return;
- }
- /* else */
-
- skb_reserve(skb,2); /* Align */
-
- /* 'skb->data' points to the start of sk_buff data area. */
- buffer = skb_put(skb,size);
-
- /* copy the packet into the buffer */
- de600_setup_address(read_from, RW_ADDR);
- for (i = size; i > 0; --i, ++buffer)
- *buffer = de600_read_byte(READ_DATA, dev);
-
- skb->protocol=eth_type_trans(skb,dev);
-
- netif_rx(skb);
-
- /* update stats */
- dev->stats.rx_packets++; /* count all receives */
- dev->stats.rx_bytes += size; /* count all received bytes */
-
- /*
- * If any worth-while packets have been received, netif_rx()
- * will work on them when we get to the tasklets.
- */
-}
-
-static const struct net_device_ops de600_netdev_ops = {
- .ndo_open = de600_open,
- .ndo_stop = de600_close,
- .ndo_start_xmit = de600_start_xmit,
- .ndo_change_mtu = eth_change_mtu,
- .ndo_set_mac_address = eth_mac_addr,
- .ndo_validate_addr = eth_validate_addr,
-};
-
-
-static struct net_device * __init de600_probe(void)
-{
- int i;
- struct net_device *dev;
- int err;
-
- dev = alloc_etherdev(0);
- if (!dev)
- return ERR_PTR(-ENOMEM);
-
-
- if (!request_region(DE600_IO, 3, "de600")) {
- printk(KERN_WARNING "DE600: port 0x%x busy\n", DE600_IO);
- err = -EBUSY;
- goto out;
- }
-
- printk(KERN_INFO "%s: D-Link DE-600 pocket adapter", dev->name);
- /* Alpha testers must have the version number to report bugs. */
- pr_debug("%s", version);
-
- /* probe for adapter */
- err = -ENODEV;
- rx_page = 0;
- select_nic();
- (void)de600_read_status(dev);
- de600_put_command(RESET);
- de600_put_command(STOP_RESET);
- if (de600_read_status(dev) & 0xf0) {
- printk(": not at I/O %#3x.\n", DATA_PORT);
- goto out1;
- }
-
- /*
- * Maybe we found one,
- * have to check if it is a D-Link DE-600 adapter...
- */
-
- /* Get the adapter ethernet address from the ROM */
- de600_setup_address(NODE_ADDRESS, RW_ADDR);
- for (i = 0; i < ETH_ALEN; i++) {
- dev->dev_addr[i] = de600_read_byte(READ_DATA, dev);
- dev->broadcast[i] = 0xff;
- }
-
- /* Check magic code */
- if ((dev->dev_addr[1] == 0xde) && (dev->dev_addr[2] == 0x15)) {
- /* OK, install real address */
- dev->dev_addr[0] = 0x00;
- dev->dev_addr[1] = 0x80;
- dev->dev_addr[2] = 0xc8;
- dev->dev_addr[3] &= 0x0f;
- dev->dev_addr[3] |= 0x70;
- } else {
- printk(" not identified in the printer port\n");
- goto out1;
- }
-
- printk(", Ethernet Address: %pM\n", dev->dev_addr);
-
- dev->netdev_ops = &de600_netdev_ops;
-
- dev->flags&=~IFF_MULTICAST;
-
- select_prn();
-
- err = register_netdev(dev);
- if (err)
- goto out1;
-
- return dev;
-
-out1:
- release_region(DE600_IO, 3);
-out:
- free_netdev(dev);
- return ERR_PTR(err);
-}
-
-static int adapter_init(struct net_device *dev)
-{
- int i;
-
- select_nic();
- rx_page = 0; /* used by RESET */
- de600_put_command(RESET);
- de600_put_command(STOP_RESET);
-
- /* Check if it is still there... */
- /* Get the some bytes of the adapter ethernet address from the ROM */
- de600_setup_address(NODE_ADDRESS, RW_ADDR);
- de600_read_byte(READ_DATA, dev);
- if ((de600_read_byte(READ_DATA, dev) != 0xde) ||
- (de600_read_byte(READ_DATA, dev) != 0x15)) {
- /* was: if (de600_read_status(dev) & 0xf0) { */
- printk("Something has happened to the DE-600! Please check it and do a new ifconfig!\n");
- /* Goodbye, cruel world... */
- dev->flags &= ~IFF_UP;
- de600_close(dev);
- was_down = 1;
- netif_stop_queue(dev); /* Transmit busy... */
- return 1; /* failed */
- }
-
- if (was_down) {
- printk(KERN_INFO "%s: Thanks, I feel much better now!\n", dev->name);
- was_down = 0;
- }
-
- tx_fifo_in = 0;
- tx_fifo_out = 0;
- free_tx_pages = TX_PAGES;
-
-
- /* set the ether address. */
- de600_setup_address(NODE_ADDRESS, RW_ADDR);
- for (i = 0; i < ETH_ALEN; i++)
- de600_put_byte(dev->dev_addr[i]);
-
- /* where to start saving incoming packets */
- rx_page = RX_BP | RX_BASE_PAGE;
- de600_setup_address(MEM_4K, RW_ADDR);
- /* Enable receiver */
- de600_put_command(RX_ENABLE);
- select_prn();
-
- netif_start_queue(dev);
-
- return 0; /* OK */
-}
-
-static struct net_device *de600_dev;
-
-static int __init de600_init(void)
-{
- de600_dev = de600_probe();
- if (IS_ERR(de600_dev))
- return PTR_ERR(de600_dev);
- return 0;
-}
-
-static void __exit de600_exit(void)
-{
- unregister_netdev(de600_dev);
- release_region(DE600_IO, 3);
- free_netdev(de600_dev);
-}
-
-module_init(de600_init);
-module_exit(de600_exit);
-
-MODULE_LICENSE("GPL");
diff --git a/drivers/net/ethernet/dlink/de600.h b/drivers/net/ethernet/dlink/de600.h
deleted file mode 100644
index e80ecbabcf4..00000000000
--- a/drivers/net/ethernet/dlink/de600.h
+++ /dev/null
@@ -1,168 +0,0 @@
-/**************************************************
- * *
- * Definition of D-Link Ethernet Pocket adapter *
- * *
- **************************************************/
-/*
- * D-Link Ethernet pocket adapter ports
- */
-/*
- * OK, so I'm cheating, but there are an awful lot of
- * reads and writes in order to get anything in and out
- * of the DE-600 with 4 bits at a time in the parallel port,
- * so every saved instruction really helps :-)
- */
-
-#ifndef DE600_IO
-#define DE600_IO 0x378
-#endif
-
-#define DATA_PORT (DE600_IO)
-#define STATUS_PORT (DE600_IO + 1)
-#define COMMAND_PORT (DE600_IO + 2)
-
-#ifndef DE600_IRQ
-#define DE600_IRQ 7
-#endif
-/*
- * It really should look like this, and autoprobing as well...
- *
-#define DATA_PORT (dev->base_addr + 0)
-#define STATUS_PORT (dev->base_addr + 1)
-#define COMMAND_PORT (dev->base_addr + 2)
-#define DE600_IRQ dev->irq
- */
-
-/*
- * D-Link COMMAND_PORT commands
- */
-#define SELECT_NIC 0x04 /* select Network Interface Card */
-#define SELECT_PRN 0x1c /* select Printer */
-#define NML_PRN 0xec /* normal Printer situation */
-#define IRQEN 0x10 /* enable IRQ line */
-
-/*
- * D-Link STATUS_PORT
- */
-#define RX_BUSY 0x80
-#define RX_GOOD 0x40
-#define TX_FAILED16 0x10
-#define TX_BUSY 0x08
-
-/*
- * D-Link DATA_PORT commands
- * command in low 4 bits
- * data in high 4 bits
- * select current data nibble with HI_NIBBLE bit
- */
-#define WRITE_DATA 0x00 /* write memory */
-#define READ_DATA 0x01 /* read memory */
-#define STATUS 0x02 /* read status register */
-#define COMMAND 0x03 /* write command register (see COMMAND below) */
-#define NULL_COMMAND 0x04 /* null command */
-#define RX_LEN 0x05 /* read received packet length */
-#define TX_ADDR 0x06 /* set adapter transmit memory address */
-#define RW_ADDR 0x07 /* set adapter read/write memory address */
-#define HI_NIBBLE 0x08 /* read/write the high nibble of data,
- or-ed with rest of command */
-
-/*
- * command register, accessed through DATA_PORT with low bits = COMMAND
- */
-#define RX_ALL 0x01 /* PROMISCUOUS */
-#define RX_BP 0x02 /* default: BROADCAST & PHYSICAL ADDRESS */
-#define RX_MBP 0x03 /* MULTICAST, BROADCAST & PHYSICAL ADDRESS */
-
-#define TX_ENABLE 0x04 /* bit 2 */
-#define RX_ENABLE 0x08 /* bit 3 */
-
-#define RESET 0x80 /* set bit 7 high */
-#define STOP_RESET 0x00 /* set bit 7 low */
-
-/*
- * data to command register
- * (high 4 bits in write to DATA_PORT)
- */
-#define RX_PAGE2_SELECT 0x10 /* bit 4, only 2 pages to select */
-#define RX_BASE_PAGE 0x20 /* bit 5, always set when specifying RX_ADDR */
-#define FLIP_IRQ 0x40 /* bit 6 */
-
-/*
- * D-Link adapter internal memory:
- *
- * 0-2K 1:st transmit page (send from pointer up to 2K)
- * 2-4K 2:nd transmit page (send from pointer up to 4K)
- *
- * 4-6K 1:st receive page (data from 4K upwards)
- * 6-8K 2:nd receive page (data from 6K upwards)
- *
- * 8K+ Adapter ROM (contains magic code and last 3 bytes of Ethernet address)
- */
-#define MEM_2K 0x0800 /* 2048 */
-#define MEM_4K 0x1000 /* 4096 */
-#define MEM_6K 0x1800 /* 6144 */
-#define NODE_ADDRESS 0x2000 /* 8192 */
-
-#define RUNT 60 /* Too small Ethernet packet */
-
-/**************************************************
- * *
- * End of definition *
- * *
- **************************************************/
-
-/*
- * Index to functions, as function prototypes.
- */
-/* Routines used internally. (See "convenience macros") */
-static u8 de600_read_status(struct net_device *dev);
-static u8 de600_read_byte(unsigned char type, struct net_device *dev);
-
-/* Put in the device structure. */
-static int de600_open(struct net_device *dev);
-static int de600_close(struct net_device *dev);
-static int de600_start_xmit(struct sk_buff *skb, struct net_device *dev);
-
-/* Dispatch from interrupts. */
-static irqreturn_t de600_interrupt(int irq, void *dev_id);
-static int de600_tx_intr(struct net_device *dev, int irq_status);
-static void de600_rx_intr(struct net_device *dev);
-
-/* Initialization */
-static void trigger_interrupt(struct net_device *dev);
-static int adapter_init(struct net_device *dev);
-
-/*
- * Convenience macros/functions for D-Link adapter
- */
-
-#define select_prn() outb_p(SELECT_PRN, COMMAND_PORT); DE600_SLOW_DOWN
-#define select_nic() outb_p(SELECT_NIC, COMMAND_PORT); DE600_SLOW_DOWN
-
-/* Thanks for hints from Mark Burton <markb@ordern.demon.co.uk> */
-#define de600_put_byte(data) ( \
- outb_p(((data) << 4) | WRITE_DATA , DATA_PORT), \
- outb_p(((data) & 0xf0) | WRITE_DATA | HI_NIBBLE, DATA_PORT))
-
-/*
- * The first two outb_p()'s below could perhaps be deleted if there
- * would be more delay in the last two. Not certain about it yet...
- */
-#define de600_put_command(cmd) ( \
- outb_p(( rx_page << 4) | COMMAND , DATA_PORT), \
- outb_p(( rx_page & 0xf0) | COMMAND | HI_NIBBLE, DATA_PORT), \
- outb_p(((rx_page | cmd) << 4) | COMMAND , DATA_PORT), \
- outb_p(((rx_page | cmd) & 0xf0) | COMMAND | HI_NIBBLE, DATA_PORT))
-
-#define de600_setup_address(addr,type) ( \
- outb_p((((addr) << 4) & 0xf0) | type , DATA_PORT), \
- outb_p(( (addr) & 0xf0) | type | HI_NIBBLE, DATA_PORT), \
- outb_p((((addr) >> 4) & 0xf0) | type , DATA_PORT), \
- outb_p((((addr) >> 8) & 0xf0) | type | HI_NIBBLE, DATA_PORT))
-
-#define rx_page_adr() ((rx_page & RX_PAGE2_SELECT)?(MEM_6K):(MEM_4K))
-
-/* Flip bit, only 2 pages */
-#define next_rx_page() (rx_page ^= RX_PAGE2_SELECT)
-
-#define tx_page_adr(a) (((a) + 1) * MEM_2K)
diff --git a/drivers/net/ethernet/dlink/de620.c b/drivers/net/ethernet/dlink/de620.c
deleted file mode 100644
index 2e2bc60ee81..00000000000
--- a/drivers/net/ethernet/dlink/de620.c
+++ /dev/null
@@ -1,987 +0,0 @@
-/*
- * de620.c $Revision: 1.40 $ BETA
- *
- *
- * Linux driver for the D-Link DE-620 Ethernet pocket adapter.
- *
- * Portions (C) Copyright 1993, 1994 by Bjorn Ekwall <bj0rn@blox.se>
- *
- * Based on adapter information gathered from DOS packetdriver
- * sources from D-Link Inc: (Special thanks to Henry Ngai of D-Link.)
- * Portions (C) Copyright D-Link SYSTEM Inc. 1991, 1992
- * Copyright, 1988, Russell Nelson, Crynwr Software
- *
- * Adapted to the sample network driver core for linux,
- * written by: Donald Becker <becker@super.org>
- * (Now at <becker@scyld.com>)
- *
- * Valuable assistance from:
- * J. Joshua Kopper <kopper@rtsg.mot.com>
- * Olav Kvittem <Olav.Kvittem@uninett.no>
- * Germano Caronni <caronni@nessie.cs.id.ethz.ch>
- * Jeremy Fitzhardinge <jeremy@suite.sw.oz.au>
- *
- *****************************************************************************/
-/*
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2, or (at your option)
- * any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
- *****************************************************************************/
-static const char version[] =
- "de620.c: $Revision: 1.40 $, Bjorn Ekwall <bj0rn@blox.se>\n";
-
-/***********************************************************************
- *
- * "Tuning" section.
- *
- * Compile-time options: (see below for descriptions)
- * -DDE620_IO=0x378 (lpt1)
- * -DDE620_IRQ=7 (lpt1)
- * -DSHUTDOWN_WHEN_LOST
- * -DCOUNT_LOOPS
- * -DLOWSPEED
- * -DREAD_DELAY
- * -DWRITE_DELAY
- */
-
-/*
- * This driver assumes that the printer port is a "normal",
- * dumb, uni-directional port!
- * If your port is "fancy" in any way, please try to set it to "normal"
- * with your BIOS setup. I have no access to machines with bi-directional
- * ports, so I can't test such a driver :-(
- * (Yes, I _know_ it is possible to use DE620 with bidirectional ports...)
- *
- * There are some clones of DE620 out there, with different names.
- * If the current driver does not recognize a clone, try to change
- * the following #define to:
- *
- * #define DE620_CLONE 1
- */
-#define DE620_CLONE 0
-
-/*
- * If the adapter has problems with high speeds, enable this #define
- * otherwise full printerport speed will be attempted.
- *
- * You can tune the READ_DELAY/WRITE_DELAY below if you enable LOWSPEED
- *
-#define LOWSPEED
- */
-
-#ifndef READ_DELAY
-#define READ_DELAY 100 /* adapter internal read delay in 100ns units */
-#endif
-
-#ifndef WRITE_DELAY
-#define WRITE_DELAY 100 /* adapter internal write delay in 100ns units */
-#endif
-
-/*
- * Enable this #define if you want the adapter to do a "ifconfig down" on
- * itself when we have detected that something is possibly wrong with it.
- * The default behaviour is to retry with "adapter_init()" until success.
- * This should be used for debugging purposes only.
- *
-#define SHUTDOWN_WHEN_LOST
- */
-
-#ifdef LOWSPEED
-/*
- * Enable this #define if you want to see debugging output that show how long
- * we have to wait before the DE-620 is ready for the next read/write/command.
- *
-#define COUNT_LOOPS
- */
-#endif
-
-#include <linux/module.h>
-#include <linux/kernel.h>
-#include <linux/types.h>
-#include <linux/fcntl.h>
-#include <linux/string.h>
-#include <linux/interrupt.h>
-#include <linux/ioport.h>
-#include <linux/in.h>
-#include <linux/errno.h>
-#include <linux/init.h>
-#include <linux/inet.h>
-#include <linux/netdevice.h>
-#include <linux/etherdevice.h>
-#include <linux/skbuff.h>
-
-#include <asm/io.h>
-
-/* Constant definitions for the DE-620 registers, commands and bits */
-#include "de620.h"
-
-typedef unsigned char byte;
-
-/*******************************************************
- * *
- * Definition of D-Link DE-620 Ethernet Pocket adapter *
- * See also "de620.h" *
- * *
- *******************************************************/
-#ifndef DE620_IO /* Compile-time configurable */
-#define DE620_IO 0x378
-#endif
-
-#ifndef DE620_IRQ /* Compile-time configurable */
-#define DE620_IRQ 7
-#endif
-
-#define DATA_PORT (dev->base_addr)
-#define STATUS_PORT (dev->base_addr + 1)
-#define COMMAND_PORT (dev->base_addr + 2)
-
-#define RUNT 60 /* Too small Ethernet packet */
-#define GIANT 1514 /* largest legal size packet, no fcs */
-
-/*
- * Force media with insmod:
- * insmod de620.o bnc=1
- * or
- * insmod de620.o utp=1
- *
- * Force io and/or irq with insmod:
- * insmod de620.o io=0x378 irq=7
- *
- * Make a clone skip the Ethernet-address range check:
- * insmod de620.o clone=1
- */
-static int bnc;
-static int utp;
-static int io = DE620_IO;
-static int irq = DE620_IRQ;
-static int clone = DE620_CLONE;
-
-static spinlock_t de620_lock;
-
-module_param(bnc, int, 0);
-module_param(utp, int, 0);
-module_param(io, int, 0);
-module_param(irq, int, 0);
-module_param(clone, int, 0);
-MODULE_PARM_DESC(bnc, "DE-620 set BNC medium (0-1)");
-MODULE_PARM_DESC(utp, "DE-620 set UTP medium (0-1)");
-MODULE_PARM_DESC(io, "DE-620 I/O base address,required");
-MODULE_PARM_DESC(irq, "DE-620 IRQ number,required");
-MODULE_PARM_DESC(clone, "Check also for non-D-Link DE-620 clones (0-1)");
-
-/***********************************************
- * *
- * Index to functions, as function prototypes. *
- * *
- ***********************************************/
-
-/*
- * Routines used internally. (See also "convenience macros.. below")
- */
-
-/* Put in the device structure. */
-static int de620_open(struct net_device *);
-static int de620_close(struct net_device *);
-static void de620_set_multicast_list(struct net_device *);
-static int de620_start_xmit(struct sk_buff *, struct net_device *);
-
-/* Dispatch from interrupts. */
-static irqreturn_t de620_interrupt(int, void *);
-static int de620_rx_intr(struct net_device *);
-
-/* Initialization */
-static int adapter_init(struct net_device *);
-static int read_eeprom(struct net_device *);
-
-
-/*
- * D-Link driver variables:
- */
-#define SCR_DEF NIBBLEMODE |INTON | SLEEP | AUTOTX
-#define TCR_DEF RXPB /* not used: | TXSUCINT | T16INT */
-#define DE620_RX_START_PAGE 12 /* 12 pages (=3k) reserved for tx */
-#define DEF_NIC_CMD IRQEN | ICEN | DS1
-
-static volatile byte NIC_Cmd;
-static volatile byte next_rx_page;
-static byte first_rx_page;
-static byte last_rx_page;
-static byte EIPRegister;
-
-static struct nic {
- byte NodeID[6];
- byte RAM_Size;
- byte Model;
- byte Media;
- byte SCR;
-} nic_data;
-
-/**********************************************************
- * *
- * Convenience macros/functions for D-Link DE-620 adapter *
- * *
- **********************************************************/
-#define de620_tx_buffs(dd) (inb(STATUS_PORT) & (TXBF0 | TXBF1))
-#define de620_flip_ds(dd) NIC_Cmd ^= DS0 | DS1; outb(NIC_Cmd, COMMAND_PORT);
-
-/* Check for ready-status, and return a nibble (high 4 bits) for data input */
-#ifdef COUNT_LOOPS
-static int tot_cnt;
-#endif
-static inline byte
-de620_ready(struct net_device *dev)
-{
- byte value;
- register short int cnt = 0;
-
- while ((((value = inb(STATUS_PORT)) & READY) == 0) && (cnt <= 1000))
- ++cnt;
-
-#ifdef COUNT_LOOPS
- tot_cnt += cnt;
-#endif
- return value & 0xf0; /* nibble */
-}
-
-static inline void
-de620_send_command(struct net_device *dev, byte cmd)
-{
- de620_ready(dev);
- if (cmd == W_DUMMY)
- outb(NIC_Cmd, COMMAND_PORT);
-
- outb(cmd, DATA_PORT);
-
- outb(NIC_Cmd ^ CS0, COMMAND_PORT);
- de620_ready(dev);
- outb(NIC_Cmd, COMMAND_PORT);
-}
-
-static inline void
-de620_put_byte(struct net_device *dev, byte value)
-{
- /* The de620_ready() makes 7 loops, on the average, on a DX2/66 */
- de620_ready(dev);
- outb(value, DATA_PORT);
- de620_flip_ds(dev);
-}
-
-static inline byte
-de620_read_byte(struct net_device *dev)
-{
- byte value;
-
- /* The de620_ready() makes 7 loops, on the average, on a DX2/66 */
- value = de620_ready(dev); /* High nibble */
- de620_flip_ds(dev);
- value |= de620_ready(dev) >> 4; /* Low nibble */
- return value;
-}
-
-static inline void
-de620_write_block(struct net_device *dev, byte *buffer, int count, int pad)
-{
-#ifndef LOWSPEED
- byte uflip = NIC_Cmd ^ (DS0 | DS1);
- byte dflip = NIC_Cmd;
-#else /* LOWSPEED */
-#ifdef COUNT_LOOPS
- int bytes = count;
-#endif /* COUNT_LOOPS */
-#endif /* LOWSPEED */
-
-#ifdef LOWSPEED
-#ifdef COUNT_LOOPS
- tot_cnt = 0;
-#endif /* COUNT_LOOPS */
- /* No further optimization useful, the limit is in the adapter. */
- for ( ; count > 0; --count, ++buffer) {
- de620_put_byte(dev,*buffer);
- }
- for ( count = pad ; count > 0; --count, ++buffer) {
- de620_put_byte(dev, 0);
- }
- de620_send_command(dev,W_DUMMY);
-#ifdef COUNT_LOOPS
- /* trial debug output: loops per byte in de620_ready() */
- printk("WRITE(%d)\n", tot_cnt/((bytes?bytes:1)));
-#endif /* COUNT_LOOPS */
-#else /* not LOWSPEED */
- for ( ; count > 0; count -=2) {
- outb(*buffer++, DATA_PORT);
- outb(uflip, COMMAND_PORT);
- outb(*buffer++, DATA_PORT);
- outb(dflip, COMMAND_PORT);
- }
- de620_send_command(dev,W_DUMMY);
-#endif /* LOWSPEED */
-}
-
-static inline void
-de620_read_block(struct net_device *dev, byte *data, int count)
-{
-#ifndef LOWSPEED
- byte value;
- byte uflip = NIC_Cmd ^ (DS0 | DS1);
- byte dflip = NIC_Cmd;
-#else /* LOWSPEED */
-#ifdef COUNT_LOOPS
- int bytes = count;
-
- tot_cnt = 0;
-#endif /* COUNT_LOOPS */
-#endif /* LOWSPEED */
-
-#ifdef LOWSPEED
- /* No further optimization useful, the limit is in the adapter. */
- while (count-- > 0) {
- *data++ = de620_read_byte(dev);
- de620_flip_ds(dev);
- }
-#ifdef COUNT_LOOPS
- /* trial debug output: loops per byte in de620_ready() */
- printk("READ(%d)\n", tot_cnt/(2*(bytes?bytes:1)));
-#endif /* COUNT_LOOPS */
-#else /* not LOWSPEED */
- while (count-- > 0) {
- value = inb(STATUS_PORT) & 0xf0; /* High nibble */
- outb(uflip, COMMAND_PORT);
- *data++ = value | inb(STATUS_PORT) >> 4; /* Low nibble */
- outb(dflip , COMMAND_PORT);
- }
-#endif /* LOWSPEED */
-}
-
-static inline void
-de620_set_delay(struct net_device *dev)
-{
- de620_ready(dev);
- outb(W_DFR, DATA_PORT);
- outb(NIC_Cmd ^ CS0, COMMAND_PORT);
-
- de620_ready(dev);
-#ifdef LOWSPEED
- outb(WRITE_DELAY, DATA_PORT);
-#else
- outb(0, DATA_PORT);
-#endif
- de620_flip_ds(dev);
-
- de620_ready(dev);
-#ifdef LOWSPEED
- outb(READ_DELAY, DATA_PORT);
-#else
- outb(0, DATA_PORT);
-#endif
- de620_flip_ds(dev);
-}
-
-static inline void
-de620_set_register(struct net_device *dev, byte reg, byte value)
-{
- de620_ready(dev);
- outb(reg, DATA_PORT);
- outb(NIC_Cmd ^ CS0, COMMAND_PORT);
-
- de620_put_byte(dev, value);
-}
-
-static inline byte
-de620_get_register(struct net_device *dev, byte reg)
-{
- byte value;
-
- de620_send_command(dev,reg);
- value = de620_read_byte(dev);
- de620_send_command(dev,W_DUMMY);
-
- return value;
-}
-
-/*********************************************************************
- *
- * Open/initialize the board.
- *
- * This routine should set everything up anew at each open, even
- * registers that "should" only need to be set once at boot, so that
- * there is a non-reboot way to recover if something goes wrong.
- *
- */
-static int de620_open(struct net_device *dev)
-{
- int ret = request_irq(dev->irq, de620_interrupt, 0, dev->name, dev);
- if (ret) {
- printk (KERN_ERR "%s: unable to get IRQ %d\n", dev->name, dev->irq);
- return ret;
- }
-
- if (adapter_init(dev)) {
- ret = -EIO;
- goto out_free_irq;
- }
-
- netif_start_queue(dev);
- return 0;
-
-out_free_irq:
- free_irq(dev->irq, dev);
- return ret;
-}
-
-/************************************************
- *
- * The inverse routine to de620_open().
- *
- */
-
-static int de620_close(struct net_device *dev)
-{
- netif_stop_queue(dev);
- /* disable recv */
- de620_set_register(dev, W_TCR, RXOFF);
- free_irq(dev->irq, dev);
- return 0;
-}
-
-/*********************************************
- *
- * Set or clear the multicast filter for this adaptor.
- * (no real multicast implemented for the DE-620, but she can be promiscuous...)
- *
- */
-
-static void de620_set_multicast_list(struct net_device *dev)
-{
- if (!netdev_mc_empty(dev) || dev->flags&(IFF_ALLMULTI|IFF_PROMISC))
- { /* Enable promiscuous mode */
- de620_set_register(dev, W_TCR, (TCR_DEF & ~RXPBM) | RXALL);
- }
- else
- { /* Disable promiscuous mode, use normal mode */
- de620_set_register(dev, W_TCR, TCR_DEF);
- }
-}
-
-/*******************************************************
- *
- * Handle timeouts on transmit
- */
-
-static void de620_timeout(struct net_device *dev)
-{
- printk(KERN_WARNING "%s: transmit timed out, %s?\n", dev->name, "network cable problem");
- /* Restart the adapter. */
- if (!adapter_init(dev)) /* maybe close it */
- netif_wake_queue(dev);
-}
-
-/*******************************************************
- *
- * Copy a buffer to the adapter transmit page memory.
- * Start sending.
- */
-static int de620_start_xmit(struct sk_buff *skb, struct net_device *dev)
-{
- unsigned long flags;
- int len;
- byte *buffer = skb->data;
- byte using_txbuf;
-
- using_txbuf = de620_tx_buffs(dev); /* Peek at the adapter */
-
- netif_stop_queue(dev);
-
-
- if ((len = skb->len) < RUNT)
- len = RUNT;
- if (len & 1) /* send an even number of bytes */
- ++len;
-
- /* Start real output */
-
- spin_lock_irqsave(&de620_lock, flags);
- pr_debug("de620_start_xmit: len=%d, bufs 0x%02x\n",
- (int)skb->len, using_txbuf);
-
- /* select a free tx buffer. if there is one... */
- switch (using_txbuf) {
- default: /* both are free: use TXBF0 */
- case TXBF1: /* use TXBF0 */
- de620_send_command(dev,W_CR | RW0);
- using_txbuf |= TXBF0;
- break;
-
- case TXBF0: /* use TXBF1 */
- de620_send_command(dev,W_CR | RW1);
- using_txbuf |= TXBF1;
- break;
-
- case (TXBF0 | TXBF1): /* NONE!!! */
- printk(KERN_WARNING "%s: No tx-buffer available!\n", dev->name);
- spin_unlock_irqrestore(&de620_lock, flags);
- return NETDEV_TX_BUSY;
- }
- de620_write_block(dev, buffer, skb->len, len-skb->len);
-
- if(!(using_txbuf == (TXBF0 | TXBF1)))
- netif_wake_queue(dev);
-
- dev->stats.tx_packets++;
- spin_unlock_irqrestore(&de620_lock, flags);
- dev_kfree_skb (skb);
- return NETDEV_TX_OK;
-}
-
-/*****************************************************
- *
- * Handle the network interface interrupts.
- *
- */
-static irqreturn_t
-de620_interrupt(int irq_in, void *dev_id)
-{
- struct net_device *dev = dev_id;
- byte irq_status;
- int bogus_count = 0;
- int again = 0;
-
- spin_lock(&de620_lock);
-
- /* Read the status register (_not_ the status port) */
- irq_status = de620_get_register(dev, R_STS);
-
- pr_debug("de620_interrupt (%2.2X)\n", irq_status);
-
- if (irq_status & RXGOOD) {
- do {
- again = de620_rx_intr(dev);
- pr_debug("again=%d\n", again);
- }
- while (again && (++bogus_count < 100));
- }
-
- if(de620_tx_buffs(dev) != (TXBF0 | TXBF1))
- netif_wake_queue(dev);
-
- spin_unlock(&de620_lock);
- return IRQ_HANDLED;
-}
-
-/**************************************
- *
- * Get a packet from the adapter
- *
- * Send it "upstairs"
- *
- */
-static int de620_rx_intr(struct net_device *dev)
-{
- struct header_buf {
- byte status;
- byte Rx_NextPage;
- unsigned short Rx_ByteCount;
- } header_buf;
- struct sk_buff *skb;
- int size;
- byte *buffer;
- byte pagelink;
- byte curr_page;
-
- pr_debug("de620_rx_intr: next_rx_page = %d\n", next_rx_page);
-
- /* Tell the adapter that we are going to read data, and from where */
- de620_send_command(dev, W_CR | RRN);
- de620_set_register(dev, W_RSA1, next_rx_page);
- de620_set_register(dev, W_RSA0, 0);
-
- /* Deep breath, and away we goooooo */
- de620_read_block(dev, (byte *)&header_buf, sizeof(struct header_buf));
- pr_debug("page status=0x%02x, nextpage=%d, packetsize=%d\n",
- header_buf.status, header_buf.Rx_NextPage,
- header_buf.Rx_ByteCount);
-
- /* Plausible page header? */
- pagelink = header_buf.Rx_NextPage;
- if ((pagelink < first_rx_page) || (last_rx_page < pagelink)) {
- /* Ouch... Forget it! Skip all and start afresh... */
- printk(KERN_WARNING "%s: Ring overrun? Restoring...\n", dev->name);
- /* You win some, you lose some. And sometimes plenty... */
- adapter_init(dev);
- netif_wake_queue(dev);
- dev->stats.rx_over_errors++;
- return 0;
- }
-
- /* OK, this look good, so far. Let's see if it's consistent... */
- /* Let's compute the start of the next packet, based on where we are */
- pagelink = next_rx_page +
- ((header_buf.Rx_ByteCount + (4 - 1 + 0x100)) >> 8);
-
- /* Are we going to wrap around the page counter? */
- if (pagelink > last_rx_page)
- pagelink -= (last_rx_page - first_rx_page + 1);
-
- /* Is the _computed_ next page number equal to what the adapter says? */
- if (pagelink != header_buf.Rx_NextPage) {
- /* Naah, we'll skip this packet. Probably bogus data as well */
- printk(KERN_WARNING "%s: Page link out of sync! Restoring...\n", dev->name);
- next_rx_page = header_buf.Rx_NextPage; /* at least a try... */
- de620_send_command(dev, W_DUMMY);
- de620_set_register(dev, W_NPRF, next_rx_page);
- dev->stats.rx_over_errors++;
- return 0;
- }
- next_rx_page = pagelink;
-
- size = header_buf.Rx_ByteCount - 4;
- if ((size < RUNT) || (GIANT < size)) {
- printk(KERN_WARNING "%s: Illegal packet size: %d!\n", dev->name, size);
- }
- else { /* Good packet? */
- skb = netdev_alloc_skb(dev, size + 2);
- if (skb == NULL) { /* Yeah, but no place to put it... */
- printk(KERN_WARNING "%s: Couldn't allocate a sk_buff of size %d.\n", dev->name, size);
- dev->stats.rx_dropped++;
- }
- else { /* Yep! Go get it! */
- skb_reserve(skb,2); /* Align */
- /* skb->data points to the start of sk_buff data area */
- buffer = skb_put(skb,size);
- /* copy the packet into the buffer */
- de620_read_block(dev, buffer, size);
- pr_debug("Read %d bytes\n", size);
- skb->protocol=eth_type_trans(skb,dev);
- netif_rx(skb); /* deliver it "upstairs" */
- /* count all receives */
- dev->stats.rx_packets++;
- dev->stats.rx_bytes += size;
- }
- }
-
- /* Let's peek ahead to see if we have read the last current packet */
- /* NOTE! We're _not_ checking the 'EMPTY'-flag! This seems better... */
- curr_page = de620_get_register(dev, R_CPR);
- de620_set_register(dev, W_NPRF, next_rx_page);
- pr_debug("next_rx_page=%d CPR=%d\n", next_rx_page, curr_page);
-
- return next_rx_page != curr_page; /* That was slightly tricky... */
-}
-
-/*********************************************
- *
- * Reset the adapter to a known state
- *
- */
-static int adapter_init(struct net_device *dev)
-{
- int i;
- static int was_down;
-
- if ((nic_data.Model == 3) || (nic_data.Model == 0)) { /* CT */
- EIPRegister = NCTL0;
- if (nic_data.Media != 1)
- EIPRegister |= NIS0; /* not BNC */
- }
- else if (nic_data.Model == 2) { /* UTP */
- EIPRegister = NCTL0 | NIS0;
- }
-
- if (utp)
- EIPRegister = NCTL0 | NIS0;
- if (bnc)
- EIPRegister = NCTL0;
-
- de620_send_command(dev, W_CR | RNOP | CLEAR);
- de620_send_command(dev, W_CR | RNOP);
-
- de620_set_register(dev, W_SCR, SCR_DEF);
- /* disable recv to wait init */
- de620_set_register(dev, W_TCR, RXOFF);
-
- /* Set the node ID in the adapter */
- for (i = 0; i < 6; ++i) { /* W_PARn = 0xaa + n */
- de620_set_register(dev, W_PAR0 + i, dev->dev_addr[i]);
- }
-
- de620_set_register(dev, W_EIP, EIPRegister);
-
- next_rx_page = first_rx_page = DE620_RX_START_PAGE;
- if (nic_data.RAM_Size)
- last_rx_page = nic_data.RAM_Size - 1;
- else /* 64k RAM */
- last_rx_page = 255;
-
- de620_set_register(dev, W_SPR, first_rx_page); /* Start Page Register*/
- de620_set_register(dev, W_EPR, last_rx_page); /* End Page Register */
- de620_set_register(dev, W_CPR, first_rx_page);/*Current Page Register*/
- de620_send_command(dev, W_NPR | first_rx_page); /* Next Page Register*/
- de620_send_command(dev, W_DUMMY);
- de620_set_delay(dev);
-
- /* Final sanity check: Anybody out there? */
- /* Let's hope some bits from the statusregister make a good check */
-#define CHECK_MASK ( 0 | TXSUC | T16 | 0 | RXCRC | RXSHORT | 0 | 0 )
-#define CHECK_OK ( 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 )
- /* success: X 0 0 X 0 0 X X */
- /* ignore: EEDI RXGOOD COLS LNKS*/
-
- if (((i = de620_get_register(dev, R_STS)) & CHECK_MASK) != CHECK_OK) {
- printk(KERN_ERR "%s: Something has happened to the DE-620! Please check it"
-#ifdef SHUTDOWN_WHEN_LOST
- " and do a new ifconfig"
-#endif
- "! (%02x)\n", dev->name, i);
-#ifdef SHUTDOWN_WHEN_LOST
- /* Goodbye, cruel world... */
- dev->flags &= ~IFF_UP;
- de620_close(dev);
-#endif
- was_down = 1;
- return 1; /* failed */
- }
- if (was_down) {
- printk(KERN_WARNING "%s: Thanks, I feel much better now!\n", dev->name);
- was_down = 0;
- }
-
- /* All OK, go ahead... */
- de620_set_register(dev, W_TCR, TCR_DEF);
-
- return 0; /* all ok */
-}
-
-static const struct net_device_ops de620_netdev_ops = {
- .ndo_open = de620_open,
- .ndo_stop = de620_close,
- .ndo_start_xmit = de620_start_xmit,
- .ndo_tx_timeout = de620_timeout,
- .ndo_set_rx_mode = de620_set_multicast_list,
- .ndo_change_mtu = eth_change_mtu,
- .ndo_set_mac_address = eth_mac_addr,
- .ndo_validate_addr = eth_validate_addr,
-};
-
-/******************************************************************************
- *
- * Only start-up code below
- *
- */
-/****************************************
- *
- * Check if there is a DE-620 connected
- */
-struct net_device * __init de620_probe(int unit)
-{
- byte checkbyte = 0xa5;
- struct net_device *dev;
- int err = -ENOMEM;
- int i;
-
- dev = alloc_etherdev(0);
- if (!dev)
- goto out;
-
- spin_lock_init(&de620_lock);
-
- /*
- * This is where the base_addr and irq gets set.
- * Tunable at compile-time and insmod-time
- */
- dev->base_addr = io;
- dev->irq = irq;
-
- /* allow overriding parameters on command line */
- if (unit >= 0) {
- sprintf(dev->name, "eth%d", unit);
- netdev_boot_setup_check(dev);
- }
-
- pr_debug("%s", version);
-
- printk(KERN_INFO "D-Link DE-620 pocket adapter");
-
- if (!request_region(dev->base_addr, 3, "de620")) {
- printk(" io 0x%3lX, which is busy.\n", dev->base_addr);
- err = -EBUSY;
- goto out1;
- }
-
- /* Initially, configure basic nibble mode, so we can read the EEPROM */
- NIC_Cmd = DEF_NIC_CMD;
- de620_set_register(dev, W_EIP, EIPRegister);
-
- /* Anybody out there? */
- de620_set_register(dev, W_CPR, checkbyte);
- checkbyte = de620_get_register(dev, R_CPR);
-
- if ((checkbyte != 0xa5) || (read_eeprom(dev) != 0)) {
- printk(" not identified in the printer port\n");
- err = -ENODEV;
- goto out2;
- }
-
- /* else, got it! */
- dev->dev_addr[0] = nic_data.NodeID[0];
- for (i = 1; i < ETH_ALEN; i++) {
- dev->dev_addr[i] = nic_data.NodeID[i];
- dev->broadcast[i] = 0xff;
- }
-
- printk(", Ethernet Address: %pM", dev->dev_addr);
-
- printk(" (%dk RAM,",
- (nic_data.RAM_Size) ? (nic_data.RAM_Size >> 2) : 64);
-
- if (nic_data.Media == 1)
- printk(" BNC)\n");
- else
- printk(" UTP)\n");
-
- dev->netdev_ops = &de620_netdev_ops;
- dev->watchdog_timeo = HZ*2;
-
- /* base_addr and irq are already set, see above! */
-
- /* dump eeprom */
- pr_debug("\nEEPROM contents:\n"
- "RAM_Size = 0x%02X\n"
- "NodeID = %pM\n"
- "Model = %d\n"
- "Media = %d\n"
- "SCR = 0x%02x\n", nic_data.RAM_Size, nic_data.NodeID,
- nic_data.Model, nic_data.Media, nic_data.SCR);
-
- err = register_netdev(dev);
- if (err)
- goto out2;
- return dev;
-
-out2:
- release_region(dev->base_addr, 3);
-out1:
- free_netdev(dev);
-out:
- return ERR_PTR(err);
-}
-
-/**********************************
- *
- * Read info from on-board EEPROM
- *
- * Note: Bitwise serial I/O to/from the EEPROM vi the status _register_!
- */
-#define sendit(dev,data) de620_set_register(dev, W_EIP, data | EIPRegister);
-
-static unsigned short __init ReadAWord(struct net_device *dev, int from)
-{
- unsigned short data;
- int nbits;
-
- /* cs [__~~] SET SEND STATE */
- /* di [____] */
- /* sck [_~~_] */
- sendit(dev, 0); sendit(dev, 1); sendit(dev, 5); sendit(dev, 4);
-
- /* Send the 9-bit address from where we want to read the 16-bit word */
- for (nbits = 9; nbits > 0; --nbits, from <<= 1) {
- if (from & 0x0100) { /* bit set? */
- /* cs [~~~~] SEND 1 */
- /* di [~~~~] */
- /* sck [_~~_] */
- sendit(dev, 6); sendit(dev, 7); sendit(dev, 7); sendit(dev, 6);
- }
- else {
- /* cs [~~~~] SEND 0 */
- /* di [____] */
- /* sck [_~~_] */
- sendit(dev, 4); sendit(dev, 5); sendit(dev, 5); sendit(dev, 4);
- }
- }
-
- /* Shift in the 16-bit word. The bits appear serially in EEDI (=0x80) */
- for (data = 0, nbits = 16; nbits > 0; --nbits) {
- /* cs [~~~~] SEND 0 */
- /* di [____] */
- /* sck [_~~_] */
- sendit(dev, 4); sendit(dev, 5); sendit(dev, 5); sendit(dev, 4);
- data = (data << 1) | ((de620_get_register(dev, R_STS) & EEDI) >> 7);
- }
- /* cs [____] RESET SEND STATE */
- /* di [____] */
- /* sck [_~~_] */
- sendit(dev, 0); sendit(dev, 1); sendit(dev, 1); sendit(dev, 0);
-
- return data;
-}
-
-static int __init read_eeprom(struct net_device *dev)
-{
- unsigned short wrd;
-
- /* D-Link Ethernet addresses are in the series 00:80:c8:7X:XX:XX:XX */
- wrd = ReadAWord(dev, 0x1aa); /* bytes 0 + 1 of NodeID */
- if (!clone && (wrd != htons(0x0080))) /* Valid D-Link ether sequence? */
- return -1; /* Nope, not a DE-620 */
- nic_data.NodeID[0] = wrd & 0xff;
- nic_data.NodeID[1] = wrd >> 8;
-
- wrd = ReadAWord(dev, 0x1ab); /* bytes 2 + 3 of NodeID */
- if (!clone && ((wrd & 0xff) != 0xc8)) /* Valid D-Link ether sequence? */
- return -1; /* Nope, not a DE-620 */
- nic_data.NodeID[2] = wrd & 0xff;
- nic_data.NodeID[3] = wrd >> 8;
-
- wrd = ReadAWord(dev, 0x1ac); /* bytes 4 + 5 of NodeID */
- nic_data.NodeID[4] = wrd & 0xff;
- nic_data.NodeID[5] = wrd >> 8;
-
- wrd = ReadAWord(dev, 0x1ad); /* RAM size in pages (256 bytes). 0 = 64k */
- nic_data.RAM_Size = (wrd >> 8);
-
- wrd = ReadAWord(dev, 0x1ae); /* hardware model (CT = 3) */
- nic_data.Model = (wrd & 0xff);
-
- wrd = ReadAWord(dev, 0x1af); /* media (indicates BNC/UTP) */
- nic_data.Media = (wrd & 0xff);
-
- wrd = ReadAWord(dev, 0x1a8); /* System Configuration Register */
- nic_data.SCR = (wrd >> 8);
-
- return 0; /* no errors */
-}
-
-/******************************************************************************
- *
- * Loadable module skeleton
- *
- */
-#ifdef MODULE
-static struct net_device *de620_dev;
-
-int __init init_module(void)
-{
- de620_dev = de620_probe(-1);
- if (IS_ERR(de620_dev))
- return PTR_ERR(de620_dev);
- return 0;
-}
-
-void cleanup_module(void)
-{
- unregister_netdev(de620_dev);
- release_region(de620_dev->base_addr, 3);
- free_netdev(de620_dev);
-}
-#endif /* MODULE */
-MODULE_LICENSE("GPL");
diff --git a/drivers/net/ethernet/dlink/de620.h b/drivers/net/ethernet/dlink/de620.h
deleted file mode 100644
index e8d9a88f4cb..00000000000
--- a/drivers/net/ethernet/dlink/de620.h
+++ /dev/null
@@ -1,117 +0,0 @@
-/*********************************************************
- * *
- * Definition of D-Link DE-620 Ethernet Pocket adapter *
- * *
- *********************************************************/
-
-/* DE-620's CMD port Command */
-#define CS0 0x08 /* 1->0 command strobe */
-#define ICEN 0x04 /* 0=enable DL3520 host interface */
-#define DS0 0x02 /* 1->0 data strobe 0 */
-#define DS1 0x01 /* 1->0 data strobe 1 */
-
-#define WDIR 0x20 /* general 0=read 1=write */
-#define RDIR 0x00 /* (not 100% confirm ) */
-#define PS2WDIR 0x00 /* ps/2 mode 1=read, 0=write */
-#define PS2RDIR 0x20
-
-#define IRQEN 0x10 /* 1 = enable printer IRQ line */
-#define SELECTIN 0x08 /* 1 = select printer */
-#define INITP 0x04 /* 0 = initial printer */
-#define AUTOFEED 0x02 /* 1 = printer auto form feed */
-#define STROBE 0x01 /* 0->1 data strobe */
-
-#define RESET 0x08
-#define NIS0 0x20 /* 0 = BNC, 1 = UTP */
-#define NCTL0 0x10
-
-/* DE-620 DIC Command */
-#define W_DUMMY 0x00 /* DIC reserved command */
-#define W_CR 0x20 /* DIC write command register */
-#define W_NPR 0x40 /* DIC write Next Page Register */
-#define W_TBR 0x60 /* DIC write Tx Byte Count 1 reg */
-#define W_RSA 0x80 /* DIC write Remote Start Addr 1 */
-
-/* DE-620's STAT port bits 7-4 */
-#define EMPTY 0x80 /* 1 = receive buffer empty */
-#define INTLEVEL 0x40 /* 1 = interrupt level is high */
-#define TXBF1 0x20 /* 1 = transmit buffer 1 is in use */
-#define TXBF0 0x10 /* 1 = transmit buffer 0 is in use */
-#define READY 0x08 /* 1 = h/w ready to accept cmd/data */
-
-/* IDC 1 Command */
-#define W_RSA1 0xa0 /* write remote start address 1 */
-#define W_RSA0 0xa1 /* write remote start address 0 */
-#define W_NPRF 0xa2 /* write next page register NPR15-NPR8 */
-#define W_DFR 0xa3 /* write delay factor register */
-#define W_CPR 0xa4 /* write current page register */
-#define W_SPR 0xa5 /* write start page register */
-#define W_EPR 0xa6 /* write end page register */
-#define W_SCR 0xa7 /* write system configuration register */
-#define W_TCR 0xa8 /* write Transceiver Configuration reg */
-#define W_EIP 0xa9 /* write EEPM Interface port */
-#define W_PAR0 0xaa /* write physical address register 0 */
-#define W_PAR1 0xab /* write physical address register 1 */
-#define W_PAR2 0xac /* write physical address register 2 */
-#define W_PAR3 0xad /* write physical address register 3 */
-#define W_PAR4 0xae /* write physical address register 4 */
-#define W_PAR5 0xaf /* write physical address register 5 */
-
-/* IDC 2 Command */
-#define R_STS 0xc0 /* read status register */
-#define R_CPR 0xc1 /* read current page register */
-#define R_BPR 0xc2 /* read boundary page register */
-#define R_TDR 0xc3 /* read time domain reflectometry reg */
-
-/* STATUS Register */
-#define EEDI 0x80 /* EEPM DO pin */
-#define TXSUC 0x40 /* tx success */
-#define T16 0x20 /* tx fail 16 times */
-#define TS1 0x40 /* 0=Tx success, 1=T16 */
-#define TS0 0x20 /* 0=Tx success, 1=T16 */
-#define RXGOOD 0x10 /* rx a good packet */
-#define RXCRC 0x08 /* rx a CRC error packet */
-#define RXSHORT 0x04 /* rx a short packet */
-#define COLS 0x02 /* coaxial collision status */
-#define LNKS 0x01 /* UTP link status */
-
-/* Command Register */
-#define CLEAR 0x10 /* reset part of hardware */
-#define NOPER 0x08 /* No Operation */
-#define RNOP 0x08
-#define RRA 0x06 /* After RR then auto-advance NPR & BPR(=NPR-1) */
-#define RRN 0x04 /* Normal Remote Read mode */
-#define RW1 0x02 /* Remote Write tx buffer 1 ( page 6 - 11 ) */
-#define RW0 0x00 /* Remote Write tx buffer 0 ( page 0 - 5 ) */
-#define TXEN 0x01 /* 0->1 tx enable */
-
-/* System Configuration Register */
-#define TESTON 0x80 /* test host data transfer reliability */
-#define SLEEP 0x40 /* sleep mode */
-#if 0
-#define FASTMODE 0x04 /* fast mode for intel 82360SL fast mode */
-#define BYTEMODE 0x02 /* byte mode */
-#else
-#define FASTMODE 0x20 /* fast mode for intel 82360SL fast mode */
-#define BYTEMODE 0x10 /* byte mode */
-#endif
-#define NIBBLEMODE 0x00 /* nibble mode */
-#define IRQINV 0x08 /* turn off IRQ line inverter */
-#define IRQNML 0x00 /* turn on IRQ line inverter */
-#define INTON 0x04
-#define AUTOFFSET 0x02 /* auto shift address to TPR+12 */
-#define AUTOTX 0x01 /* auto tx when leave RW mode */
-
-/* Transceiver Configuration Register */
-#define JABBER 0x80 /* generate jabber condition */
-#define TXSUCINT 0x40 /* enable tx success interrupt */
-#define T16INT 0x20 /* enable T16 interrupt */
-#define RXERRPKT 0x10 /* accept CRC error or short packet */
-#define EXTERNALB2 0x0C /* external loopback 2 */
-#define EXTERNALB1 0x08 /* external loopback 1 */
-#define INTERNALB 0x04 /* internal loopback */
-#define NMLOPERATE 0x00 /* normal operation */
-#define RXPBM 0x03 /* rx physical, broadcast, multicast */
-#define RXPB 0x02 /* rx physical, broadcast */
-#define RXALL 0x01 /* rx all packet */
-#define RXOFF 0x00 /* rx disable */
diff --git a/drivers/net/ethernet/fujitsu/Kconfig b/drivers/net/ethernet/fujitsu/Kconfig
index aca156888fd..c6a87625898 100644
--- a/drivers/net/ethernet/fujitsu/Kconfig
+++ b/drivers/net/ethernet/fujitsu/Kconfig
@@ -17,18 +17,6 @@ config NET_VENDOR_FUJITSU
if NET_VENDOR_FUJITSU
-config AT1700
- tristate "AT1700/1720 support (EXPERIMENTAL)"
- depends on ISA && EXPERIMENTAL
- select CRC32
- ---help---
- If you have a network (Ethernet) card of this type, say Y and read
- the Ethernet-HOWTO, available from
- <http://www.tldp.org/docs.html#howto>.
-
- To compile this driver as a module, choose M here. The module
- will be called at1700.
-
config PCMCIA_FMVJ18X
tristate "Fujitsu FMV-J18x PCMCIA support"
depends on PCMCIA
@@ -40,15 +28,4 @@ config PCMCIA_FMVJ18X
To compile this driver as a module, choose M here: the module will be
called fmvj18x_cs. If unsure, say N.
-config ETH16I
- tristate "ICL EtherTeam 16i/32 support"
- depends on ISA
- ---help---
- If you have a network (Ethernet) card of this type, say Y and read
- the Ethernet-HOWTO, available from
- <http://www.tldp.org/docs.html#howto>.
-
- To compile this driver as a module, choose M here. The module
- will be called eth16i.
-
endif # NET_VENDOR_FUJITSU
diff --git a/drivers/net/ethernet/fujitsu/Makefile b/drivers/net/ethernet/fujitsu/Makefile
index 2730ae67d3a..21561fdcc69 100644
--- a/drivers/net/ethernet/fujitsu/Makefile
+++ b/drivers/net/ethernet/fujitsu/Makefile
@@ -2,6 +2,4 @@
# Makefile for the Fujitsu network device drivers.
#
-obj-$(CONFIG_AT1700) += at1700.o
-obj-$(CONFIG_ETH16I) += eth16i.o
obj-$(CONFIG_PCMCIA_FMVJ18X) += fmvj18x_cs.o
diff --git a/drivers/net/ethernet/fujitsu/at1700.c b/drivers/net/ethernet/fujitsu/at1700.c
deleted file mode 100644
index 4b80dc4531a..00000000000
--- a/drivers/net/ethernet/fujitsu/at1700.c
+++ /dev/null
@@ -1,791 +0,0 @@
-/* at1700.c: A network device driver for the Allied Telesis AT1700.
-
- Written 1993-98 by Donald Becker.
-
- Copyright 1993 United States Government as represented by the
- Director, National Security Agency.
-
- This software may be used and distributed according to the terms
- of the GNU General Public License, incorporated herein by reference.
-
- The author may be reached as becker@scyld.com, or C/O
- Scyld Computing Corporation
- 410 Severn Ave., Suite 210
- Annapolis MD 21403
-
- This is a device driver for the Allied Telesis AT1700, and
- Fujitsu FMV-181/182/181A/182A/183/184/183A/184A, which are
- straight-forward Fujitsu MB86965 implementations.
-
- Modification for Fujitsu FMV-18X cards is done by Yutaka Tamiya
- (tamy@flab.fujitsu.co.jp).
-
- Sources:
- The Fujitsu MB86965 datasheet.
-
- After the initial version of this driver was written Gerry Sawkins of
- ATI provided their EEPROM configuration code header file.
- Thanks to NIIBE Yutaka <gniibe@mri.co.jp> for bug fixes.
-
- MCA bus (AT1720) support (now deleted) by Rene Schmit <rene@bss.lu>
-
- Bugs:
- The MB86965 has a design flaw that makes all probes unreliable. Not
- only is it difficult to detect, it also moves around in I/O space in
- response to inb()s from other device probes!
-*/
-
-#include <linux/errno.h>
-#include <linux/netdevice.h>
-#include <linux/etherdevice.h>
-#include <linux/module.h>
-#include <linux/kernel.h>
-#include <linux/types.h>
-#include <linux/fcntl.h>
-#include <linux/interrupt.h>
-#include <linux/ioport.h>
-#include <linux/in.h>
-#include <linux/skbuff.h>
-#include <linux/string.h>
-#include <linux/init.h>
-#include <linux/crc32.h>
-#include <linux/bitops.h>
-
-#include <asm/io.h>
-#include <asm/dma.h>
-
-static char version[] __initdata =
- "at1700.c:v1.16 9/11/06 Donald Becker (becker@cesdis.gsfc.nasa.gov)\n";
-
-#define DRV_NAME "at1700"
-
-/* Tunable parameters. */
-
-/* When to switch from the 64-entry multicast filter to Rx-all-multicast. */
-#define MC_FILTERBREAK 64
-
-/* These unusual address orders are used to verify the CONFIG register. */
-
-static int fmv18x_probe_list[] __initdata = {
- 0x220, 0x240, 0x260, 0x280, 0x2a0, 0x2c0, 0x300, 0x340, 0
-};
-
-/*
- * ISA
- */
-
-static unsigned at1700_probe_list[] __initdata = {
- 0x260, 0x280, 0x2a0, 0x240, 0x340, 0x320, 0x380, 0x300, 0
-};
-
-/* use 0 for production, 1 for verification, >2 for debug */
-#ifndef NET_DEBUG
-#define NET_DEBUG 1
-#endif
-static unsigned int net_debug = NET_DEBUG;
-
-typedef unsigned char uchar;
-
-/* Information that need to be kept for each board. */
-struct net_local {
- spinlock_t lock;
- unsigned char mc_filter[8];
- uint jumpered:1; /* Set iff the board has jumper config. */
- uint tx_started:1; /* Packets are on the Tx queue. */
- uint tx_queue_ready:1; /* Tx queue is ready to be sent. */
- uint rx_started:1; /* Packets are Rxing. */
- uchar tx_queue; /* Number of packet on the Tx queue. */
- ushort tx_queue_len; /* Current length of the Tx queue. */
-};
-
-
-/* Offsets from the base address. */
-#define STATUS 0
-#define TX_STATUS 0
-#define RX_STATUS 1
-#define TX_INTR 2 /* Bit-mapped interrupt enable registers. */
-#define RX_INTR 3
-#define TX_MODE 4
-#define RX_MODE 5
-#define CONFIG_0 6 /* Misc. configuration settings. */
-#define CONFIG_1 7
-/* Run-time register bank 2 definitions. */
-#define DATAPORT 8 /* Word-wide DMA or programmed-I/O dataport. */
-#define TX_START 10
-#define COL16CNTL 11 /* Control Reg for 16 collisions */
-#define MODE13 13
-#define RX_CTRL 14
-/* Configuration registers only on the '865A/B chips. */
-#define EEPROM_Ctrl 16
-#define EEPROM_Data 17
-#define CARDSTATUS 16 /* FMV-18x Card Status */
-#define CARDSTATUS1 17 /* FMV-18x Card Status */
-#define IOCONFIG 18 /* Either read the jumper, or move the I/O. */
-#define IOCONFIG1 19
-#define SAPROM 20 /* The station address PROM, if no EEPROM. */
-#define MODE24 24
-#define RESET 31 /* Write to reset some parts of the chip. */
-#define AT1700_IO_EXTENT 32
-#define PORT_OFFSET(o) (o)
-
-
-#define TX_TIMEOUT (HZ/10)
-
-
-/* Index to functions, as function prototypes. */
-
-static int at1700_probe1(struct net_device *dev, int ioaddr);
-static int read_eeprom(long ioaddr, int location);
-static int net_open(struct net_device *dev);
-static netdev_tx_t net_send_packet(struct sk_buff *skb,
- struct net_device *dev);
-static irqreturn_t net_interrupt(int irq, void *dev_id);
-static void net_rx(struct net_device *dev);
-static int net_close(struct net_device *dev);
-static void set_rx_mode(struct net_device *dev);
-static void net_tx_timeout (struct net_device *dev);
-
-
-/* Check for a network adaptor of this type, and return '0' iff one exists.
- If dev->base_addr == 0, probe all likely locations.
- If dev->base_addr == 1, always return failure.
- If dev->base_addr == 2, allocate space for the device and return success
- (detachable devices only).
- */
-
-static int io = 0x260;
-
-static int irq;
-
-static void cleanup_card(struct net_device *dev)
-{
- free_irq(dev->irq, NULL);
- release_region(dev->base_addr, AT1700_IO_EXTENT);
-}
-
-struct net_device * __init at1700_probe(int unit)
-{
- struct net_device *dev = alloc_etherdev(sizeof(struct net_local));
- unsigned *port;
- int err = 0;
-
- if (!dev)
- return ERR_PTR(-ENODEV);
-
- if (unit >= 0) {
- sprintf(dev->name, "eth%d", unit);
- netdev_boot_setup_check(dev);
- io = dev->base_addr;
- irq = dev->irq;
- } else {
- dev->base_addr = io;
- dev->irq = irq;
- }
-
- if (io > 0x1ff) { /* Check a single specified location. */
- err = at1700_probe1(dev, io);
- } else if (io != 0) { /* Don't probe at all. */
- err = -ENXIO;
- } else {
- for (port = at1700_probe_list; *port; port++) {
- if (at1700_probe1(dev, *port) == 0)
- break;
- dev->irq = irq;
- }
- if (!*port)
- err = -ENODEV;
- }
- if (err)
- goto out;
- err = register_netdev(dev);
- if (err)
- goto out1;
- return dev;
-out1:
- cleanup_card(dev);
-out:
- free_netdev(dev);
- return ERR_PTR(err);
-}
-
-static const struct net_device_ops at1700_netdev_ops = {
- .ndo_open = net_open,
- .ndo_stop = net_close,
- .ndo_start_xmit = net_send_packet,
- .ndo_set_rx_mode = set_rx_mode,
- .ndo_tx_timeout = net_tx_timeout,
- .ndo_change_mtu = eth_change_mtu,
- .ndo_set_mac_address = eth_mac_addr,
- .ndo_validate_addr = eth_validate_addr,
-};
-
-/* The Fujitsu datasheet suggests that the NIC be probed for by checking its
- "signature", the default bit pattern after a reset. This *doesn't* work --
- there is no way to reset the bus interface without a complete power-cycle!
-
- It turns out that ATI came to the same conclusion I did: the only thing
- that can be done is checking a few bits and then diving right into an
- EEPROM read. */
-
-static int __init at1700_probe1(struct net_device *dev, int ioaddr)
-{
- static const char fmv_irqmap[4] = {3, 7, 10, 15};
- static const char fmv_irqmap_pnp[8] = {3, 4, 5, 7, 9, 10, 11, 15};
- static const char at1700_irqmap[8] = {3, 4, 5, 9, 10, 11, 14, 15};
- unsigned int i, irq, is_fmv18x = 0, is_at1700 = 0;
- int ret = -ENODEV;
- struct net_local *lp = netdev_priv(dev);
-
- if (!request_region(ioaddr, AT1700_IO_EXTENT, DRV_NAME))
- return -EBUSY;
-
- /* Resetting the chip doesn't reset the ISA interface, so don't bother.
- That means we have to be careful with the register values we probe
- for.
- */
-#ifdef notdef
- printk("at1700 probe at %#x, eeprom is %4.4x %4.4x %4.4x ctrl %4.4x.\n",
- ioaddr, read_eeprom(ioaddr, 4), read_eeprom(ioaddr, 5),
- read_eeprom(ioaddr, 6), inw(ioaddr + EEPROM_Ctrl));
-#endif
- /* We must check for the EEPROM-config boards first, else accessing
- IOCONFIG0 will move the board! */
- if (at1700_probe_list[inb(ioaddr + IOCONFIG1) & 0x07] == ioaddr &&
- read_eeprom(ioaddr, 4) == 0x0000 &&
- (read_eeprom(ioaddr, 5) & 0xff00) == 0xF400)
- is_at1700 = 1;
- else if (inb(ioaddr + SAPROM ) == 0x00 &&
- inb(ioaddr + SAPROM + 1) == 0x00 &&
- inb(ioaddr + SAPROM + 2) == 0x0e)
- is_fmv18x = 1;
- else {
- goto err_out;
- }
-
- /* Reset the internal state machines. */
- outb(0, ioaddr + RESET);
-
- if (is_at1700) {
- irq = at1700_irqmap[(read_eeprom(ioaddr, 12)&0x04)
- | (read_eeprom(ioaddr, 0)>>14)];
- } else {
- /* Check PnP mode for FMV-183/184/183A/184A. */
- /* This PnP routine is very poor. IO and IRQ should be known. */
- if (inb(ioaddr + CARDSTATUS1) & 0x20) {
- irq = dev->irq;
- for (i = 0; i < 8; i++) {
- if (irq == fmv_irqmap_pnp[i])
- break;
- }
- if (i == 8) {
- goto err_out;
- }
- } else {
- if (fmv18x_probe_list[inb(ioaddr + IOCONFIG) & 0x07] != ioaddr)
- goto err_out;
- irq = fmv_irqmap[(inb(ioaddr + IOCONFIG)>>6) & 0x03];
- }
- }
-
- printk("%s: %s found at %#3x, IRQ %d, address ", dev->name,
- is_at1700 ? "AT1700" : "FMV-18X", ioaddr, irq);
-
- dev->base_addr = ioaddr;
- dev->irq = irq;
-
- if (is_at1700) {
- for(i = 0; i < 3; i++) {
- unsigned short eeprom_val = read_eeprom(ioaddr, 4+i);
- ((unsigned short *)dev->dev_addr)[i] = ntohs(eeprom_val);
- }
- } else {
- for(i = 0; i < 6; i++) {
- unsigned char val = inb(ioaddr + SAPROM + i);
- dev->dev_addr[i] = val;
- }
- }
- printk("%pM", dev->dev_addr);
-
- /* The EEPROM word 12 bit 0x0400 means use regular 100 ohm 10baseT signals,
- rather than 150 ohm shielded twisted pair compensation.
- 0x0000 == auto-sense the interface
- 0x0800 == use TP interface
- 0x1800 == use coax interface
- */
- {
- const char *porttype[] = {"auto-sense", "10baseT", "auto-sense", "10base2"};
- if (is_at1700) {
- ushort setup_value = read_eeprom(ioaddr, 12);
- dev->if_port = setup_value >> 8;
- } else {
- ushort setup_value = inb(ioaddr + CARDSTATUS);
- switch (setup_value & 0x07) {
- case 0x01: /* 10base5 */
- case 0x02: /* 10base2 */
- dev->if_port = 0x18; break;
- case 0x04: /* 10baseT */
- dev->if_port = 0x08; break;
- default: /* auto-sense */
- dev->if_port = 0x00; break;
- }
- }
- printk(" %s interface.\n", porttype[(dev->if_port>>3) & 3]);
- }
-
- /* Set the configuration register 0 to 32K 100ns. byte-wide memory, 16 bit
- bus access, two 4K Tx queues, and disabled Tx and Rx. */
- outb(0xda, ioaddr + CONFIG_0);
-
- /* Set the station address in bank zero. */
- outb(0x00, ioaddr + CONFIG_1);
- for (i = 0; i < 6; i++)
- outb(dev->dev_addr[i], ioaddr + PORT_OFFSET(8 + i));
-
- /* Switch to bank 1 and set the multicast table to accept none. */
- outb(0x04, ioaddr + CONFIG_1);
- for (i = 0; i < 8; i++)
- outb(0x00, ioaddr + PORT_OFFSET(8 + i));
-
-
- /* Switch to bank 2 */
- /* Lock our I/O address, and set manual processing mode for 16 collisions. */
- outb(0x08, ioaddr + CONFIG_1);
- outb(dev->if_port, ioaddr + MODE13);
- outb(0x00, ioaddr + COL16CNTL);
-
- if (net_debug)
- printk(version);
-
- dev->netdev_ops = &at1700_netdev_ops;
- dev->watchdog_timeo = TX_TIMEOUT;
-
- spin_lock_init(&lp->lock);
-
- lp->jumpered = is_fmv18x;
- /* Snarf the interrupt vector now. */
- ret = request_irq(irq, net_interrupt, 0, DRV_NAME, dev);
- if (ret) {
- printk(KERN_ERR "AT1700 at %#3x is unusable due to a "
- "conflict on IRQ %d.\n",
- ioaddr, irq);
- goto err_out;
- }
-
- return 0;
-
-err_out:
- release_region(ioaddr, AT1700_IO_EXTENT);
- return ret;
-}
-
-
-/* EEPROM_Ctrl bits. */
-#define EE_SHIFT_CLK 0x40 /* EEPROM shift clock, in reg. 16. */
-#define EE_CS 0x20 /* EEPROM chip select, in reg. 16. */
-#define EE_DATA_WRITE 0x80 /* EEPROM chip data in, in reg. 17. */
-#define EE_DATA_READ 0x80 /* EEPROM chip data out, in reg. 17. */
-
-/* The EEPROM commands include the alway-set leading bit. */
-#define EE_WRITE_CMD (5 << 6)
-#define EE_READ_CMD (6 << 6)
-#define EE_ERASE_CMD (7 << 6)
-
-static int __init read_eeprom(long ioaddr, int location)
-{
- int i;
- unsigned short retval = 0;
- long ee_addr = ioaddr + EEPROM_Ctrl;
- long ee_daddr = ioaddr + EEPROM_Data;
- int read_cmd = location | EE_READ_CMD;
-
- /* Shift the read command bits out. */
- for (i = 9; i >= 0; i--) {
- short dataval = (read_cmd & (1 << i)) ? EE_DATA_WRITE : 0;
- outb(EE_CS, ee_addr);
- outb(dataval, ee_daddr);
- outb(EE_CS | EE_SHIFT_CLK, ee_addr); /* EEPROM clock tick. */
- }
- outb(EE_DATA_WRITE, ee_daddr);
- for (i = 16; i > 0; i--) {
- outb(EE_CS, ee_addr);
- outb(EE_CS | EE_SHIFT_CLK, ee_addr);
- retval = (retval << 1) | ((inb(ee_daddr) & EE_DATA_READ) ? 1 : 0);
- }
-
- /* Terminate the EEPROM access. */
- outb(EE_CS, ee_addr);
- outb(EE_SHIFT_CLK, ee_addr);
- outb(0, ee_addr);
- return retval;
-}
-
-
-
-static int net_open(struct net_device *dev)
-{
- struct net_local *lp = netdev_priv(dev);
- int ioaddr = dev->base_addr;
-
- /* Set the configuration register 0 to 32K 100ns. byte-wide memory, 16 bit
- bus access, and two 4K Tx queues. */
- outb(0x5a, ioaddr + CONFIG_0);
-
- /* Powerup, switch to register bank 2, and enable the Rx and Tx. */
- outb(0xe8, ioaddr + CONFIG_1);
-
- lp->tx_started = 0;
- lp->tx_queue_ready = 1;
- lp->rx_started = 0;
- lp->tx_queue = 0;
- lp->tx_queue_len = 0;
-
- /* Turn on hardware Tx and Rx interrupts. */
- outb(0x82, ioaddr + TX_INTR);
- outb(0x81, ioaddr + RX_INTR);
-
- /* Enable the IRQ on boards of fmv18x it is feasible. */
- if (lp->jumpered) {
- outb(0x80, ioaddr + IOCONFIG1);
- }
-
- netif_start_queue(dev);
- return 0;
-}
-
-static void net_tx_timeout (struct net_device *dev)
-{
- struct net_local *lp = netdev_priv(dev);
- int ioaddr = dev->base_addr;
-
- printk ("%s: transmit timed out with status %04x, %s?\n", dev->name,
- inw (ioaddr + STATUS), inb (ioaddr + TX_STATUS) & 0x80
- ? "IRQ conflict" : "network cable problem");
- printk ("%s: timeout registers: %04x %04x %04x %04x %04x %04x %04x %04x.\n",
- dev->name, inw(ioaddr + TX_STATUS), inw(ioaddr + TX_INTR), inw(ioaddr + TX_MODE),
- inw(ioaddr + CONFIG_0), inw(ioaddr + DATAPORT), inw(ioaddr + TX_START),
- inw(ioaddr + MODE13 - 1), inw(ioaddr + RX_CTRL));
- dev->stats.tx_errors++;
- /* ToDo: We should try to restart the adaptor... */
- outw(0xffff, ioaddr + MODE24);
- outw (0xffff, ioaddr + TX_STATUS);
- outb (0x5a, ioaddr + CONFIG_0);
- outb (0xe8, ioaddr + CONFIG_1);
- outw (0x8182, ioaddr + TX_INTR);
- outb (0x00, ioaddr + TX_START);
- outb (0x03, ioaddr + COL16CNTL);
-
- dev->trans_start = jiffies; /* prevent tx timeout */
-
- lp->tx_started = 0;
- lp->tx_queue_ready = 1;
- lp->rx_started = 0;
- lp->tx_queue = 0;
- lp->tx_queue_len = 0;
-
- netif_wake_queue(dev);
-}
-
-
-static netdev_tx_t net_send_packet (struct sk_buff *skb,
- struct net_device *dev)
-{
- struct net_local *lp = netdev_priv(dev);
- int ioaddr = dev->base_addr;
- short length = ETH_ZLEN < skb->len ? skb->len : ETH_ZLEN;
- short len = skb->len;
- unsigned char *buf = skb->data;
- static u8 pad[ETH_ZLEN];
-
- netif_stop_queue (dev);
-
- /* We may not start transmitting unless we finish transferring
- a packet into the Tx queue. During executing the following
- codes we possibly catch a Tx interrupt. Thus we flag off
- tx_queue_ready, so that we prevent the interrupt routine
- (net_interrupt) to start transmitting. */
- lp->tx_queue_ready = 0;
- {
- outw (length, ioaddr + DATAPORT);
- /* Packet data */
- outsw (ioaddr + DATAPORT, buf, len >> 1);
- /* Check for dribble byte */
- if (len & 1) {
- outw(skb->data[skb->len-1], ioaddr + DATAPORT);
- len++;
- }
- /* Check for packet padding */
- if (length != skb->len)
- outsw(ioaddr + DATAPORT, pad, (length - len + 1) >> 1);
-
- lp->tx_queue++;
- lp->tx_queue_len += length + 2;
- }
- lp->tx_queue_ready = 1;
-
- if (lp->tx_started == 0) {
- /* If the Tx is idle, always trigger a transmit. */
- outb (0x80 | lp->tx_queue, ioaddr + TX_START);
- lp->tx_queue = 0;
- lp->tx_queue_len = 0;
- lp->tx_started = 1;
- netif_start_queue (dev);
- } else if (lp->tx_queue_len < 4096 - 1502)
- /* Yes, there is room for one more packet. */
- netif_start_queue (dev);
- dev_kfree_skb (skb);
-
- return NETDEV_TX_OK;
-}
-
-/* The typical workload of the driver:
- Handle the network interface interrupts. */
-static irqreturn_t net_interrupt(int irq, void *dev_id)
-{
- struct net_device *dev = dev_id;
- struct net_local *lp;
- int ioaddr, status;
- int handled = 0;
-
- if (dev == NULL) {
- printk ("at1700_interrupt(): irq %d for unknown device.\n", irq);
- return IRQ_NONE;
- }
-
- ioaddr = dev->base_addr;
- lp = netdev_priv(dev);
-
- spin_lock (&lp->lock);
-
- status = inw(ioaddr + TX_STATUS);
- outw(status, ioaddr + TX_STATUS);
-
- if (net_debug > 4)
- printk("%s: Interrupt with status %04x.\n", dev->name, status);
- if (lp->rx_started == 0 &&
- (status & 0xff00 || (inb(ioaddr + RX_MODE) & 0x40) == 0)) {
- /* Got a packet(s).
- We cannot execute net_rx more than once at the same time for
- the same device. During executing net_rx, we possibly catch a
- Tx interrupt. Thus we flag on rx_started, so that we prevent
- the interrupt routine (net_interrupt) to dive into net_rx
- again. */
- handled = 1;
- lp->rx_started = 1;
- outb(0x00, ioaddr + RX_INTR); /* Disable RX intr. */
- net_rx(dev);
- outb(0x81, ioaddr + RX_INTR); /* Enable RX intr. */
- lp->rx_started = 0;
- }
- if (status & 0x00ff) {
- handled = 1;
- if (status & 0x02) {
- /* More than 16 collisions occurred */
- if (net_debug > 4)
- printk("%s: 16 Collision occur during Txing.\n", dev->name);
- /* Cancel sending a packet. */
- outb(0x03, ioaddr + COL16CNTL);
- dev->stats.collisions++;
- }
- if (status & 0x82) {
- dev->stats.tx_packets++;
- /* The Tx queue has any packets and is not being
- transferred a packet from the host, start
- transmitting. */
- if (lp->tx_queue && lp->tx_queue_ready) {
- outb(0x80 | lp->tx_queue, ioaddr + TX_START);
- lp->tx_queue = 0;
- lp->tx_queue_len = 0;
- dev->trans_start = jiffies;
- netif_wake_queue (dev);
- } else {
- lp->tx_started = 0;
- netif_wake_queue (dev);
- }
- }
- }
-
- spin_unlock (&lp->lock);
- return IRQ_RETVAL(handled);
-}
-
-/* We have a good packet(s), get it/them out of the buffers. */
-static void
-net_rx(struct net_device *dev)
-{
- int ioaddr = dev->base_addr;
- int boguscount = 5;
-
- while ((inb(ioaddr + RX_MODE) & 0x40) == 0) {
- ushort status = inw(ioaddr + DATAPORT);
- ushort pkt_len = inw(ioaddr + DATAPORT);
-
- if (net_debug > 4)
- printk("%s: Rxing packet mode %02x status %04x.\n",
- dev->name, inb(ioaddr + RX_MODE), status);
-#ifndef final_version
- if (status == 0) {
- outb(0x05, ioaddr + RX_CTRL);
- break;
- }
-#endif
-
- if ((status & 0xF0) != 0x20) { /* There was an error. */
- dev->stats.rx_errors++;
- if (status & 0x08) dev->stats.rx_length_errors++;
- if (status & 0x04) dev->stats.rx_frame_errors++;
- if (status & 0x02) dev->stats.rx_crc_errors++;
- if (status & 0x01) dev->stats.rx_over_errors++;
- } else {
- /* Malloc up new buffer. */
- struct sk_buff *skb;
-
- if (pkt_len > 1550) {
- printk("%s: The AT1700 claimed a very large packet, size %d.\n",
- dev->name, pkt_len);
- /* Prime the FIFO and then flush the packet. */
- inw(ioaddr + DATAPORT); inw(ioaddr + DATAPORT);
- outb(0x05, ioaddr + RX_CTRL);
- dev->stats.rx_errors++;
- break;
- }
- skb = netdev_alloc_skb(dev, pkt_len + 3);
- if (skb == NULL) {
- printk("%s: Memory squeeze, dropping packet (len %d).\n",
- dev->name, pkt_len);
- /* Prime the FIFO and then flush the packet. */
- inw(ioaddr + DATAPORT); inw(ioaddr + DATAPORT);
- outb(0x05, ioaddr + RX_CTRL);
- dev->stats.rx_dropped++;
- break;
- }
- skb_reserve(skb,2);
-
- insw(ioaddr + DATAPORT, skb_put(skb,pkt_len), (pkt_len + 1) >> 1);
- skb->protocol=eth_type_trans(skb, dev);
- netif_rx(skb);
- dev->stats.rx_packets++;
- dev->stats.rx_bytes += pkt_len;
- }
- if (--boguscount <= 0)
- break;
- }
-
- /* If any worth-while packets have been received, dev_rint()
- has done a mark_bh(NET_BH) for us and will work on them
- when we get to the bottom-half routine. */
- {
- int i;
- for (i = 0; i < 20; i++) {
- if ((inb(ioaddr + RX_MODE) & 0x40) == 0x40)
- break;
- inw(ioaddr + DATAPORT); /* dummy status read */
- outb(0x05, ioaddr + RX_CTRL);
- }
-
- if (net_debug > 5)
- printk("%s: Exint Rx packet with mode %02x after %d ticks.\n",
- dev->name, inb(ioaddr + RX_MODE), i);
- }
-}
-
-/* The inverse routine to net_open(). */
-static int net_close(struct net_device *dev)
-{
- struct net_local *lp = netdev_priv(dev);
- int ioaddr = dev->base_addr;
-
- netif_stop_queue(dev);
-
- /* Set configuration register 0 to disable Tx and Rx. */
- outb(0xda, ioaddr + CONFIG_0);
-
- /* No statistic counters on the chip to update. */
-
- /* Disable the IRQ on boards of fmv18x where it is feasible. */
- if (lp->jumpered)
- outb(0x00, ioaddr + IOCONFIG1);
-
- /* Power-down the chip. Green, green, green! */
- outb(0x00, ioaddr + CONFIG_1);
- return 0;
-}
-
-/*
- Set the multicast/promiscuous mode for this adaptor.
-*/
-
-static void
-set_rx_mode(struct net_device *dev)
-{
- int ioaddr = dev->base_addr;
- struct net_local *lp = netdev_priv(dev);
- unsigned char mc_filter[8]; /* Multicast hash filter */
- unsigned long flags;
-
- if (dev->flags & IFF_PROMISC) {
- memset(mc_filter, 0xff, sizeof(mc_filter));
- outb(3, ioaddr + RX_MODE); /* Enable promiscuous mode */
- } else if (netdev_mc_count(dev) > MC_FILTERBREAK ||
- (dev->flags & IFF_ALLMULTI)) {
- /* Too many to filter perfectly -- accept all multicasts. */
- memset(mc_filter, 0xff, sizeof(mc_filter));
- outb(2, ioaddr + RX_MODE); /* Use normal mode. */
- } else if (netdev_mc_empty(dev)) {
- memset(mc_filter, 0x00, sizeof(mc_filter));
- outb(1, ioaddr + RX_MODE); /* Ignore almost all multicasts. */
- } else {
- struct netdev_hw_addr *ha;
-
- memset(mc_filter, 0, sizeof(mc_filter));
- netdev_for_each_mc_addr(ha, dev) {
- unsigned int bit =
- ether_crc_le(ETH_ALEN, ha->addr) >> 26;
- mc_filter[bit >> 3] |= (1 << bit);
- }
- outb(0x02, ioaddr + RX_MODE); /* Use normal mode. */
- }
-
- spin_lock_irqsave (&lp->lock, flags);
- if (memcmp(mc_filter, lp->mc_filter, sizeof(mc_filter))) {
- int i;
- int saved_bank = inw(ioaddr + CONFIG_0);
- /* Switch to bank 1 and set the multicast table. */
- outw((saved_bank & ~0x0C00) | 0x0480, ioaddr + CONFIG_0);
- for (i = 0; i < 8; i++)
- outb(mc_filter[i], ioaddr + PORT_OFFSET(8 + i));
- memcpy(lp->mc_filter, mc_filter, sizeof(mc_filter));
- outw(saved_bank, ioaddr + CONFIG_0);
- }
- spin_unlock_irqrestore (&lp->lock, flags);
-}
-
-#ifdef MODULE
-static struct net_device *dev_at1700;
-
-module_param(io, int, 0);
-module_param(irq, int, 0);
-module_param(net_debug, int, 0);
-MODULE_PARM_DESC(io, "AT1700/FMV18X I/O base address");
-MODULE_PARM_DESC(irq, "AT1700/FMV18X IRQ number");
-MODULE_PARM_DESC(net_debug, "AT1700/FMV18X debug level (0-6)");
-
-static int __init at1700_module_init(void)
-{
- if (io == 0)
- printk("at1700: You should not use auto-probing with insmod!\n");
- dev_at1700 = at1700_probe(-1);
- if (IS_ERR(dev_at1700))
- return PTR_ERR(dev_at1700);
- return 0;
-}
-
-static void __exit at1700_module_exit(void)
-{
- unregister_netdev(dev_at1700);
- cleanup_card(dev_at1700);
- free_netdev(dev_at1700);
-}
-module_init(at1700_module_init);
-module_exit(at1700_module_exit);
-#endif /* MODULE */
-MODULE_LICENSE("GPL");
diff --git a/drivers/net/ethernet/fujitsu/eth16i.c b/drivers/net/ethernet/fujitsu/eth16i.c
deleted file mode 100644
index a992d1f7e0d..00000000000
--- a/drivers/net/ethernet/fujitsu/eth16i.c
+++ /dev/null
@@ -1,1483 +0,0 @@
-/* eth16i.c An ICL EtherTeam 16i and 32 EISA ethernet driver for Linux
-
- Written 1994-1999 by Mika Kuoppala
-
- Copyright (C) 1994-1999 by Mika Kuoppala
- Based on skeleton.c and heavily on at1700.c by Donald Becker
-
- This software may be used and distributed according to the terms
- of the GNU General Public License, incorporated herein by reference.
-
- The author may be reached as miku@iki.fi
-
- This driver supports following cards :
- - ICL EtherTeam 16i
- - ICL EtherTeam 32 EISA
- (Uses true 32 bit transfers rather than 16i compatibility mode)
-
- Example Module usage:
- insmod eth16i.o io=0x2a0 mediatype=bnc
-
- mediatype can be one of the following: bnc,tp,dix,auto,eprom
-
- 'auto' will try to autoprobe mediatype.
- 'eprom' will use whatever type defined in eprom.
-
- I have benchmarked driver with PII/300Mhz as a ftp client
- and 486/33Mhz as a ftp server. Top speed was 1128.37 kilobytes/sec.
-
- Sources:
- - skeleton.c a sample network driver core for linux,
- written by Donald Becker <becker@scyld.com>
- - at1700.c a driver for Allied Telesis AT1700, written
- by Donald Becker.
- - e16iSRV.asm a Netware 3.X Server Driver for ICL EtherTeam16i
- written by Markku Viima
- - The Fujitsu MB86965 databook.
-
- Author thanks following persons due to their valueble assistance:
- Markku Viima (ICL)
- Ari Valve (ICL)
- Donald Becker
- Kurt Huwig <kurt@huwig.de>
-
- Revision history:
-
- Version Date Description
-
- 0.01 15.12-94 Initial version (card detection)
- 0.02 23.01-95 Interrupt is now hooked correctly
- 0.03 01.02-95 Rewrote initialization part
- 0.04 07.02-95 Base skeleton done...
- Made a few changes to signature checking
- to make it a bit reliable.
- - fixed bug in tx_buf mapping
- - fixed bug in initialization (DLC_EN
- wasn't enabled when initialization
- was done.)
- 0.05 08.02-95 If there were more than one packet to send,
- transmit was jammed due to invalid
- register write...now fixed
- 0.06 19.02-95 Rewrote interrupt handling
- 0.07 13.04-95 Wrote EEPROM read routines
- Card configuration now set according to
- data read from EEPROM
- 0.08 23.06-95 Wrote part that tries to probe used interface
- port if AUTO is selected
-
- 0.09 01.09-95 Added module support
-
- 0.10 04.09-95 Fixed receive packet allocation to work
- with kernels > 1.3.x
-
- 0.20 20.09-95 Added support for EtherTeam32 EISA
-
- 0.21 17.10-95 Removed the unnecessary extern
- init_etherdev() declaration. Some
- other cleanups.
-
- 0.22 22.02-96 Receive buffer was not flushed
- correctly when faulty packet was
- received. Now fixed.
-
- 0.23 26.02-96 Made resetting the adapter
- more reliable.
-
- 0.24 27.02-96 Rewrote faulty packet handling in eth16i_rx
-
- 0.25 22.05-96 kfree() was missing from cleanup_module.
-
- 0.26 11.06-96 Sometimes card was not found by
- check_signature(). Now made more reliable.
-
- 0.27 23.06-96 Oops. 16 consecutive collisions halted
- adapter. Now will try to retransmit
- MAX_COL_16 times before finally giving up.
-
- 0.28 28.10-97 Added dev_id parameter (NULL) for free_irq
-
- 0.29 29.10-97 Multiple card support for module users
-
- 0.30 30.10-97 Fixed irq allocation bug.
- (request_irq moved from probe to open)
-
- 0.30a 21.08-98 Card detection made more relaxed. Driver
- had problems with some TCP/IP-PROM boots
- to find the card. Suggested by
- Kurt Huwig <kurt@huwig.de>
-
- 0.31 28.08-98 Media interface port can now be selected
- with module parameters or kernel
- boot parameters.
-
- 0.32 31.08-98 IRQ was never freed if open/close
- pair wasn't called. Now fixed.
-
- 0.33 10.09-98 When eth16i_open() was called after
- eth16i_close() chip never recovered.
- Now more shallow reset is made on
- close.
-
- 0.34 29.06-99 Fixed one bad #ifdef.
- Changed ioaddr -> io for consistency
-
- 0.35 01.07-99 transmit,-receive bytes were never
- updated in stats.
-
- Bugs:
- In some cases the media interface autoprobing code doesn't find
- the correct interface type. In this case you can
- manually choose the interface type in DOS with E16IC.EXE which is
- configuration software for EtherTeam16i and EtherTeam32 cards.
- This is also true for IRQ setting. You cannot use module
- parameter to configure IRQ of the card (yet).
-
- To do:
- - Real multicast support
- - Rewrite the media interface autoprobing code. Its _horrible_ !
- - Possibly merge all the MB86965 specific code to external
- module for use by eth16.c and Donald's at1700.c
- - IRQ configuration with module parameter. I will do
- this when i will get enough info about setting
- irq without configuration utility.
-*/
-
-static char *version =
- "eth16i.c: v0.35 01-Jul-1999 Mika Kuoppala (miku@iki.fi)\n";
-
-#include <linux/module.h>
-#include <linux/kernel.h>
-#include <linux/types.h>
-#include <linux/fcntl.h>
-#include <linux/interrupt.h>
-#include <linux/ioport.h>
-#include <linux/in.h>
-#include <linux/string.h>
-#include <linux/errno.h>
-#include <linux/init.h>
-#include <linux/spinlock.h>
-#include <linux/netdevice.h>
-#include <linux/etherdevice.h>
-#include <linux/skbuff.h>
-#include <linux/bitops.h>
-#include <linux/jiffies.h>
-#include <linux/io.h>
-
-#include <asm/dma.h>
-
-
-
-/* Few macros */
-#define BITSET(ioaddr, bnum) ((outb(((inb(ioaddr)) | (bnum)), ioaddr)))
-#define BITCLR(ioaddr, bnum) ((outb(((inb(ioaddr)) & (~(bnum))), ioaddr)))
-
-/* This is the I/O address space for Etherteam 16i adapter. */
-#define ETH16I_IO_EXTENT 32
-
-/* Ticks before deciding that transmit has timed out */
-#define TX_TIMEOUT (400*HZ/1000)
-
-/* Maximum loop count when receiving packets */
-#define MAX_RX_LOOP 20
-
-/* Some interrupt masks */
-#define ETH16I_INTR_ON 0xef8a /* Higher is receive mask */
-#define ETH16I_INTR_OFF 0x0000
-
-/* Buffers header status byte meanings */
-#define PKT_GOOD BIT(5)
-#define PKT_GOOD_RMT BIT(4)
-#define PKT_SHORT BIT(3)
-#define PKT_ALIGN_ERR BIT(2)
-#define PKT_CRC_ERR BIT(1)
-#define PKT_RX_BUF_OVERFLOW BIT(0)
-
-/* Transmit status register (DLCR0) */
-#define TX_STATUS_REG 0
-#define TX_DONE BIT(7)
-#define NET_BUSY BIT(6)
-#define TX_PKT_RCD BIT(5)
-#define CR_LOST BIT(4)
-#define TX_JABBER_ERR BIT(3)
-#define COLLISION BIT(2)
-#define COLLISIONS_16 BIT(1)
-
-/* Receive status register (DLCR1) */
-#define RX_STATUS_REG 1
-#define RX_PKT BIT(7) /* Packet received */
-#define BUS_RD_ERR BIT(6)
-#define SHORT_PKT_ERR BIT(3)
-#define ALIGN_ERR BIT(2)
-#define CRC_ERR BIT(1)
-#define RX_BUF_OVERFLOW BIT(0)
-
-/* Transmit Interrupt Enable Register (DLCR2) */
-#define TX_INTR_REG 2
-#define TX_INTR_DONE BIT(7)
-#define TX_INTR_COL BIT(2)
-#define TX_INTR_16_COL BIT(1)
-
-/* Receive Interrupt Enable Register (DLCR3) */
-#define RX_INTR_REG 3
-#define RX_INTR_RECEIVE BIT(7)
-#define RX_INTR_SHORT_PKT BIT(3)
-#define RX_INTR_CRC_ERR BIT(1)
-#define RX_INTR_BUF_OVERFLOW BIT(0)
-
-/* Transmit Mode Register (DLCR4) */
-#define TRANSMIT_MODE_REG 4
-#define LOOPBACK_CONTROL BIT(1)
-#define CONTROL_OUTPUT BIT(2)
-
-/* Receive Mode Register (DLCR5) */
-#define RECEIVE_MODE_REG 5
-#define RX_BUFFER_EMPTY BIT(6)
-#define ACCEPT_BAD_PACKETS BIT(5)
-#define RECEIVE_SHORT_ADDR BIT(4)
-#define ACCEPT_SHORT_PACKETS BIT(3)
-#define REMOTE_RESET BIT(2)
-
-#define ADDRESS_FILTER_MODE BIT(1) | BIT(0)
-#define REJECT_ALL 0
-#define ACCEPT_ALL 3
-#define MODE_1 1 /* NODE ID, BC, MC, 2-24th bit */
-#define MODE_2 2 /* NODE ID, BC, MC, Hash Table */
-
-/* Configuration Register 0 (DLCR6) */
-#define CONFIG_REG_0 6
-#define DLC_EN BIT(7)
-#define SRAM_CYCLE_TIME_100NS BIT(6)
-#define SYSTEM_BUS_WIDTH_8 BIT(5) /* 1 = 8bit, 0 = 16bit */
-#define BUFFER_WIDTH_8 BIT(4) /* 1 = 8bit, 0 = 16bit */
-#define TBS1 BIT(3)
-#define TBS0 BIT(2)
-#define SRAM_BS1 BIT(1) /* 00=8kb, 01=16kb */
-#define SRAM_BS0 BIT(0) /* 10=32kb, 11=64kb */
-
-#ifndef ETH16I_TX_BUF_SIZE /* 0 = 2kb, 1 = 4kb */
-#define ETH16I_TX_BUF_SIZE 3 /* 2 = 8kb, 3 = 16kb */
-#endif
-#define TX_BUF_1x2048 0
-#define TX_BUF_2x2048 1
-#define TX_BUF_2x4098 2
-#define TX_BUF_2x8192 3
-
-/* Configuration Register 1 (DLCR7) */
-#define CONFIG_REG_1 7
-#define POWERUP BIT(5)
-
-/* Transmit start register */
-#define TRANSMIT_START_REG 10
-#define TRANSMIT_START_RB 2
-#define TX_START BIT(7) /* Rest of register bit indicate*/
- /* number of packets in tx buffer*/
-/* Node ID registers (DLCR8-13) */
-#define NODE_ID_0 8
-#define NODE_ID_RB 0
-
-/* Hash Table registers (HT8-15) */
-#define HASH_TABLE_0 8
-#define HASH_TABLE_RB 1
-
-/* Buffer memory ports */
-#define BUFFER_MEM_PORT_LB 8
-#define DATAPORT BUFFER_MEM_PORT_LB
-#define BUFFER_MEM_PORT_HB 9
-
-/* 16 Collision control register (BMPR11) */
-#define COL_16_REG 11
-#define HALT_ON_16 0x00
-#define RETRANS_AND_HALT_ON_16 0x02
-
-/* Maximum number of attempts to send after 16 concecutive collisions */
-#define MAX_COL_16 10
-
-/* DMA Burst and Transceiver Mode Register (BMPR13) */
-#define TRANSCEIVER_MODE_REG 13
-#define TRANSCEIVER_MODE_RB 2
-#define IO_BASE_UNLOCK BIT(7)
-#define LOWER_SQUELCH_TRESH BIT(6)
-#define LINK_TEST_DISABLE BIT(5)
-#define AUI_SELECT BIT(4)
-#define DIS_AUTO_PORT_SEL BIT(3)
-
-/* Filter Self Receive Register (BMPR14) */
-#define FILTER_SELF_RX_REG 14
-#define SKIP_RX_PACKET BIT(2)
-#define FILTER_SELF_RECEIVE BIT(0)
-
-/* EEPROM Control Register (BMPR 16) */
-#define EEPROM_CTRL_REG 16
-
-/* EEPROM Data Register (BMPR 17) */
-#define EEPROM_DATA_REG 17
-
-/* NMC93CSx6 EEPROM Control Bits */
-#define CS_0 0x00
-#define CS_1 0x20
-#define SK_0 0x00
-#define SK_1 0x40
-#define DI_0 0x00
-#define DI_1 0x80
-
-/* NMC93CSx6 EEPROM Instructions */
-#define EEPROM_READ 0x80
-
-/* NMC93CSx6 EEPROM Addresses */
-#define E_NODEID_0 0x02
-#define E_NODEID_1 0x03
-#define E_NODEID_2 0x04
-#define E_PORT_SELECT 0x14
- #define E_PORT_BNC 0x00
- #define E_PORT_DIX 0x01
- #define E_PORT_TP 0x02
- #define E_PORT_AUTO 0x03
- #define E_PORT_FROM_EPROM 0x04
-#define E_PRODUCT_CFG 0x30
-
-
-/* Macro to slow down io between EEPROM clock transitions */
-#define eeprom_slow_io() do { int _i = 40; while(--_i > 0) { inb(0x80); }}while(0)
-
-/* Jumperless Configuration Register (BMPR19) */
-#define JUMPERLESS_CONFIG 19
-
-/* ID ROM registers, writing to them also resets some parts of chip */
-#define ID_ROM_0 24
-#define ID_ROM_7 31
-#define RESET ID_ROM_0
-
-/* This is the I/O address list to be probed when seeking the card */
-static unsigned int eth16i_portlist[] __initdata = {
- 0x260, 0x280, 0x2A0, 0x240, 0x340, 0x320, 0x380, 0x300, 0
-};
-
-static unsigned int eth32i_portlist[] __initdata = {
- 0x1000, 0x2000, 0x3000, 0x4000, 0x5000, 0x6000, 0x7000, 0x8000,
- 0x9000, 0xA000, 0xB000, 0xC000, 0xD000, 0xE000, 0xF000, 0
-};
-
-/* This is the Interrupt lookup table for Eth16i card */
-static unsigned int eth16i_irqmap[] __initdata = { 9, 10, 5, 15, 0 };
-#define NUM_OF_ISA_IRQS 4
-
-/* This is the Interrupt lookup table for Eth32i card */
-static unsigned int eth32i_irqmap[] __initdata = { 3, 5, 7, 9, 10, 11, 12, 15, 0 };
-#define EISA_IRQ_REG 0xc89
-#define NUM_OF_EISA_IRQS 8
-
-static unsigned int eth16i_tx_buf_map[] = { 2048, 2048, 4096, 8192 };
-
-/* Use 0 for production, 1 for verification, >2 for debug */
-#ifndef ETH16I_DEBUG
-#define ETH16I_DEBUG 0
-#endif
-static unsigned int eth16i_debug = ETH16I_DEBUG;
-
-/* Information for each board */
-
-struct eth16i_local {
- unsigned char tx_started;
- unsigned char tx_buf_busy;
- unsigned short tx_queue; /* Number of packets in transmit buffer */
- unsigned short tx_queue_len;
- unsigned int tx_buf_size;
- unsigned long open_time;
- unsigned long tx_buffered_packets;
- unsigned long tx_buffered_bytes;
- unsigned long col_16;
- spinlock_t lock;
-};
-
-/* Function prototypes */
-
-static int eth16i_probe1(struct net_device *dev, int ioaddr);
-static int eth16i_check_signature(int ioaddr);
-static int eth16i_probe_port(int ioaddr);
-static void eth16i_set_port(int ioaddr, int porttype);
-static int eth16i_send_probe_packet(int ioaddr, unsigned char *b, int l);
-static int eth16i_receive_probe_packet(int ioaddr);
-static int eth16i_get_irq(int ioaddr);
-static int eth16i_read_eeprom(int ioaddr, int offset);
-static int eth16i_read_eeprom_word(int ioaddr);
-static void eth16i_eeprom_cmd(int ioaddr, unsigned char command);
-static int eth16i_open(struct net_device *dev);
-static int eth16i_close(struct net_device *dev);
-static netdev_tx_t eth16i_tx(struct sk_buff *skb, struct net_device *dev);
-static void eth16i_rx(struct net_device *dev);
-static void eth16i_timeout(struct net_device *dev);
-static irqreturn_t eth16i_interrupt(int irq, void *dev_id);
-static void eth16i_reset(struct net_device *dev);
-static void eth16i_timeout(struct net_device *dev);
-static void eth16i_skip_packet(struct net_device *dev);
-static void eth16i_multicast(struct net_device *dev);
-static void eth16i_select_regbank(unsigned char regbank, int ioaddr);
-static void eth16i_initialize(struct net_device *dev, int boot);
-
-#if 0
-static int eth16i_set_irq(struct net_device *dev);
-#endif
-
-#ifdef MODULE
-static ushort eth16i_parse_mediatype(const char* s);
-#endif
-
-static char cardname[] __initdata = "ICL EtherTeam 16i/32";
-
-static int __init do_eth16i_probe(struct net_device *dev)
-{
- int i;
- int ioaddr;
- int base_addr = dev->base_addr;
-
- if(eth16i_debug > 4)
- printk(KERN_DEBUG "Probing started for %s\n", cardname);
-
- if(base_addr > 0x1ff) /* Check only single location */
- return eth16i_probe1(dev, base_addr);
- else if(base_addr != 0) /* Don't probe at all */
- return -ENXIO;
-
- /* Seek card from the ISA io address space */
- for(i = 0; (ioaddr = eth16i_portlist[i]) ; i++)
- if(eth16i_probe1(dev, ioaddr) == 0)
- return 0;
-
- /* Seek card from the EISA io address space */
- for(i = 0; (ioaddr = eth32i_portlist[i]) ; i++)
- if(eth16i_probe1(dev, ioaddr) == 0)
- return 0;
-
- return -ENODEV;
-}
-
-#ifndef MODULE
-struct net_device * __init eth16i_probe(int unit)
-{
- struct net_device *dev = alloc_etherdev(sizeof(struct eth16i_local));
- int err;
-
- if (!dev)
- return ERR_PTR(-ENOMEM);
-
- sprintf(dev->name, "eth%d", unit);
- netdev_boot_setup_check(dev);
-
- err = do_eth16i_probe(dev);
- if (err)
- goto out;
- return dev;
-out:
- free_netdev(dev);
- return ERR_PTR(err);
-}
-#endif
-
-static const struct net_device_ops eth16i_netdev_ops = {
- .ndo_open = eth16i_open,
- .ndo_stop = eth16i_close,
- .ndo_start_xmit = eth16i_tx,
- .ndo_set_rx_mode = eth16i_multicast,
- .ndo_tx_timeout = eth16i_timeout,
- .ndo_change_mtu = eth_change_mtu,
- .ndo_set_mac_address = eth_mac_addr,
- .ndo_validate_addr = eth_validate_addr,
-};
-
-static int __init eth16i_probe1(struct net_device *dev, int ioaddr)
-{
- struct eth16i_local *lp = netdev_priv(dev);
- static unsigned version_printed;
- int retval;
-
- /* Let's grab the region */
- if (!request_region(ioaddr, ETH16I_IO_EXTENT, cardname))
- return -EBUSY;
-
- /*
- The MB86985 chip has on register which holds information in which
- io address the chip lies. First read this register and compare
- it to our current io address and if match then this could
- be our chip.
- */
-
- if(ioaddr < 0x1000) {
- if(eth16i_portlist[(inb(ioaddr + JUMPERLESS_CONFIG) & 0x07)]
- != ioaddr) {
- retval = -ENODEV;
- goto out;
- }
- }
-
- /* Now we will go a bit deeper and try to find the chip's signature */
-
- if(eth16i_check_signature(ioaddr) != 0) {
- retval = -ENODEV;
- goto out;
- }
-
- /*
- Now it seems that we have found a ethernet chip in this particular
- ioaddr. The MB86985 chip has this feature, that when you read a
- certain register it will increase it's io base address to next
- configurable slot. Now when we have found the chip, first thing is
- to make sure that the chip's ioaddr will hold still here.
- */
-
- eth16i_select_regbank(TRANSCEIVER_MODE_RB, ioaddr);
- outb(0x00, ioaddr + TRANSCEIVER_MODE_REG);
-
- outb(0x00, ioaddr + RESET); /* Reset some parts of chip */
- BITSET(ioaddr + CONFIG_REG_0, BIT(7)); /* Disable the data link */
-
- if( (eth16i_debug & version_printed++) == 0)
- printk(KERN_INFO "%s", version);
-
- dev->base_addr = ioaddr;
- dev->irq = eth16i_get_irq(ioaddr);
-
- /* Try to obtain interrupt vector */
-
- if ((retval = request_irq(dev->irq, (void *)&eth16i_interrupt, 0, cardname, dev))) {
- printk(KERN_WARNING "%s at %#3x, but is unusable due to conflicting IRQ %d.\n",
- cardname, ioaddr, dev->irq);
- goto out;
- }
-
- printk(KERN_INFO "%s: %s at %#3x, IRQ %d, ",
- dev->name, cardname, ioaddr, dev->irq);
-
-
- /* Now we will have to lock the chip's io address */
- eth16i_select_regbank(TRANSCEIVER_MODE_RB, ioaddr);
- outb(0x38, ioaddr + TRANSCEIVER_MODE_REG);
-
- eth16i_initialize(dev, 1); /* Initialize rest of the chip's registers */
-
- /* Now let's same some energy by shutting down the chip ;) */
- BITCLR(ioaddr + CONFIG_REG_1, POWERUP);
-
- /* Initialize the device structure */
- dev->netdev_ops = &eth16i_netdev_ops;
- dev->watchdog_timeo = TX_TIMEOUT;
- spin_lock_init(&lp->lock);
-
- retval = register_netdev(dev);
- if (retval)
- goto out1;
- return 0;
-out1:
- free_irq(dev->irq, dev);
-out:
- release_region(ioaddr, ETH16I_IO_EXTENT);
- return retval;
-}
-
-
-static void eth16i_initialize(struct net_device *dev, int boot)
-{
- int ioaddr = dev->base_addr;
- int i, node_w = 0;
- unsigned char node_byte = 0;
-
- /* Setup station address */
- eth16i_select_regbank(NODE_ID_RB, ioaddr);
- for(i = 0 ; i < 3 ; i++) {
- unsigned short node_val = eth16i_read_eeprom(ioaddr, E_NODEID_0 + i);
- ((unsigned short *)dev->dev_addr)[i] = ntohs(node_val);
- }
-
- for(i = 0; i < 6; i++) {
- outb( ((unsigned char *)dev->dev_addr)[i], ioaddr + NODE_ID_0 + i);
- if(boot) {
- printk("%02x", inb(ioaddr + NODE_ID_0 + i));
- if(i != 5)
- printk(":");
- }
- }
-
- /* Now we will set multicast addresses to accept none */
- eth16i_select_regbank(HASH_TABLE_RB, ioaddr);
- for(i = 0; i < 8; i++)
- outb(0x00, ioaddr + HASH_TABLE_0 + i);
-
- /*
- Now let's disable the transmitter and receiver, set the buffer ram
- cycle time, bus width and buffer data path width. Also we shall
- set transmit buffer size and total buffer size.
- */
-
- eth16i_select_regbank(2, ioaddr);
-
- node_byte = 0;
- node_w = eth16i_read_eeprom(ioaddr, E_PRODUCT_CFG);
-
- if( (node_w & 0xFF00) == 0x0800)
- node_byte |= BUFFER_WIDTH_8;
-
- node_byte |= SRAM_BS1;
-
- if( (node_w & 0x00FF) == 64)
- node_byte |= SRAM_BS0;
-
- node_byte |= DLC_EN | SRAM_CYCLE_TIME_100NS | (ETH16I_TX_BUF_SIZE << 2);
-
- outb(node_byte, ioaddr + CONFIG_REG_0);
-
- /* We shall halt the transmitting, if 16 collisions are detected */
- outb(HALT_ON_16, ioaddr + COL_16_REG);
-
-#ifdef MODULE
- /* if_port already set by init_module() */
-#else
- dev->if_port = (dev->mem_start < E_PORT_FROM_EPROM) ?
- dev->mem_start : E_PORT_FROM_EPROM;
-#endif
-
- /* Set interface port type */
- if(boot) {
- static const char * const porttype[] = {
- "BNC", "DIX", "TP", "AUTO", "FROM_EPROM"
- };
-
- switch(dev->if_port)
- {
-
- case E_PORT_FROM_EPROM:
- dev->if_port = eth16i_read_eeprom(ioaddr, E_PORT_SELECT);
- break;
-
- case E_PORT_AUTO:
- dev->if_port = eth16i_probe_port(ioaddr);
- break;
-
- case E_PORT_BNC:
- case E_PORT_TP:
- case E_PORT_DIX:
- break;
- }
-
- printk(" %s interface.\n", porttype[dev->if_port]);
-
- eth16i_set_port(ioaddr, dev->if_port);
- }
-
- /* Set Receive Mode to normal operation */
- outb(MODE_2, ioaddr + RECEIVE_MODE_REG);
-}
-
-static int eth16i_probe_port(int ioaddr)
-{
- int i;
- int retcode;
- unsigned char dummy_packet[64];
-
- /* Powerup the chip */
- outb(0xc0 | POWERUP, ioaddr + CONFIG_REG_1);
-
- BITSET(ioaddr + CONFIG_REG_0, DLC_EN);
-
- eth16i_select_regbank(NODE_ID_RB, ioaddr);
-
- for(i = 0; i < 6; i++) {
- dummy_packet[i] = inb(ioaddr + NODE_ID_0 + i);
- dummy_packet[i+6] = inb(ioaddr + NODE_ID_0 + i);
- }
-
- dummy_packet[12] = 0x00;
- dummy_packet[13] = 0x04;
- memset(dummy_packet + 14, 0, sizeof(dummy_packet) - 14);
-
- eth16i_select_regbank(2, ioaddr);
-
- for(i = 0; i < 3; i++) {
- BITSET(ioaddr + CONFIG_REG_0, DLC_EN);
- BITCLR(ioaddr + CONFIG_REG_0, DLC_EN);
- eth16i_set_port(ioaddr, i);
-
- if(eth16i_debug > 1)
- printk(KERN_DEBUG "Set port number %d\n", i);
-
- retcode = eth16i_send_probe_packet(ioaddr, dummy_packet, 64);
- if(retcode == 0) {
- retcode = eth16i_receive_probe_packet(ioaddr);
- if(retcode != -1) {
- if(eth16i_debug > 1)
- printk(KERN_DEBUG "Eth16i interface port found at %d\n", i);
- return i;
- }
- }
- else {
- if(eth16i_debug > 1)
- printk(KERN_DEBUG "TRANSMIT_DONE timeout when probing interface port\n");
- }
- }
-
- if( eth16i_debug > 1)
- printk(KERN_DEBUG "Using default port\n");
-
- return E_PORT_BNC;
-}
-
-static void eth16i_set_port(int ioaddr, int porttype)
-{
- unsigned short temp = 0;
-
- eth16i_select_regbank(TRANSCEIVER_MODE_RB, ioaddr);
- outb(LOOPBACK_CONTROL, ioaddr + TRANSMIT_MODE_REG);
-
- temp |= DIS_AUTO_PORT_SEL;
-
- switch(porttype) {
-
- case E_PORT_BNC :
- temp |= AUI_SELECT;
- break;
-
- case E_PORT_TP :
- break;
-
- case E_PORT_DIX :
- temp |= AUI_SELECT;
- BITSET(ioaddr + TRANSMIT_MODE_REG, CONTROL_OUTPUT);
- break;
- }
-
- outb(temp, ioaddr + TRANSCEIVER_MODE_REG);
-
- if(eth16i_debug > 1) {
- printk(KERN_DEBUG "TRANSMIT_MODE_REG = %x\n", inb(ioaddr + TRANSMIT_MODE_REG));
- printk(KERN_DEBUG "TRANSCEIVER_MODE_REG = %x\n",
- inb(ioaddr+TRANSCEIVER_MODE_REG));
- }
-}
-
-static int eth16i_send_probe_packet(int ioaddr, unsigned char *b, int l)
-{
- unsigned long starttime;
-
- outb(0xff, ioaddr + TX_STATUS_REG);
-
- outw(l, ioaddr + DATAPORT);
- outsw(ioaddr + DATAPORT, (unsigned short *)b, (l + 1) >> 1);
-
- starttime = jiffies;
- outb(TX_START | 1, ioaddr + TRANSMIT_START_REG);
-
- while( (inb(ioaddr + TX_STATUS_REG) & 0x80) == 0) {
- if( time_after(jiffies, starttime + TX_TIMEOUT)) {
- return -1;
- }
- }
-
- return 0;
-}
-
-static int eth16i_receive_probe_packet(int ioaddr)
-{
- unsigned long starttime;
-
- starttime = jiffies;
-
- while((inb(ioaddr + TX_STATUS_REG) & 0x20) == 0) {
- if( time_after(jiffies, starttime + TX_TIMEOUT)) {
-
- if(eth16i_debug > 1)
- printk(KERN_DEBUG "Timeout occurred waiting transmit packet received\n");
- starttime = jiffies;
- while((inb(ioaddr + RX_STATUS_REG) & 0x80) == 0) {
- if( time_after(jiffies, starttime + TX_TIMEOUT)) {
- if(eth16i_debug > 1)
- printk(KERN_DEBUG "Timeout occurred waiting receive packet\n");
- return -1;
- }
- }
-
- if(eth16i_debug > 1)
- printk(KERN_DEBUG "RECEIVE_PACKET\n");
- return 0; /* Found receive packet */
- }
- }
-
- if(eth16i_debug > 1) {
- printk(KERN_DEBUG "TRANSMIT_PACKET_RECEIVED %x\n", inb(ioaddr + TX_STATUS_REG));
- printk(KERN_DEBUG "RX_STATUS_REG = %x\n", inb(ioaddr + RX_STATUS_REG));
- }
-
- return 0; /* Return success */
-}
-
-#if 0
-static int eth16i_set_irq(struct net_device* dev)
-{
- const int ioaddr = dev->base_addr;
- const int irq = dev->irq;
- int i = 0;
-
- if(ioaddr < 0x1000) {
- while(eth16i_irqmap[i] && eth16i_irqmap[i] != irq)
- i++;
-
- if(i < NUM_OF_ISA_IRQS) {
- u8 cbyte = inb(ioaddr + JUMPERLESS_CONFIG);
- cbyte = (cbyte & 0x3F) | (i << 6);
- outb(cbyte, ioaddr + JUMPERLESS_CONFIG);
- return 0;
- }
- }
- else {
- printk(KERN_NOTICE "%s: EISA Interrupt cannot be set. Use EISA Configuration utility.\n", dev->name);
- }
-
- return -1;
-
-}
-#endif
-
-static int __init eth16i_get_irq(int ioaddr)
-{
- unsigned char cbyte;
-
- if( ioaddr < 0x1000) {
- cbyte = inb(ioaddr + JUMPERLESS_CONFIG);
- return eth16i_irqmap[((cbyte & 0xC0) >> 6)];
- } else { /* Oh..the card is EISA so method getting IRQ different */
- unsigned short index = 0;
- cbyte = inb(ioaddr + EISA_IRQ_REG);
- while( (cbyte & 0x01) == 0) {
- cbyte = cbyte >> 1;
- index++;
- }
- return eth32i_irqmap[index];
- }
-}
-
-static int __init eth16i_check_signature(int ioaddr)
-{
- int i;
- unsigned char creg[4] = { 0 };
-
- for(i = 0; i < 4 ; i++) {
-
- creg[i] = inb(ioaddr + TRANSMIT_MODE_REG + i);
-
- if(eth16i_debug > 1)
- printk("eth16i: read signature byte %x at %x\n",
- creg[i],
- ioaddr + TRANSMIT_MODE_REG + i);
- }
-
- creg[0] &= 0x0F; /* Mask collision cnr */
- creg[2] &= 0x7F; /* Mask DCLEN bit */
-
-#if 0
- /*
- This was removed because the card was sometimes left to state
- from which it couldn't be find anymore. If there is need
- to more strict check still this have to be fixed.
- */
- if( ! ((creg[0] == 0x06) && (creg[1] == 0x41)) ) {
- if(creg[1] != 0x42)
- return -1;
- }
-#endif
-
- if( !((creg[2] == 0x36) && (creg[3] == 0xE0)) ) {
- creg[2] &= 0x40;
- creg[3] &= 0x03;
-
- if( !((creg[2] == 0x40) && (creg[3] == 0x00)) )
- return -1;
- }
-
- if(eth16i_read_eeprom(ioaddr, E_NODEID_0) != 0)
- return -1;
-
- if((eth16i_read_eeprom(ioaddr, E_NODEID_1) & 0xFF00) != 0x4B00)
- return -1;
-
- return 0;
-}
-
-static int eth16i_read_eeprom(int ioaddr, int offset)
-{
- int data = 0;
-
- eth16i_eeprom_cmd(ioaddr, EEPROM_READ | offset);
- outb(CS_1, ioaddr + EEPROM_CTRL_REG);
- data = eth16i_read_eeprom_word(ioaddr);
- outb(CS_0 | SK_0, ioaddr + EEPROM_CTRL_REG);
-
- return data;
-}
-
-static int eth16i_read_eeprom_word(int ioaddr)
-{
- int i;
- int data = 0;
-
- for(i = 16; i > 0; i--) {
- outb(CS_1 | SK_0, ioaddr + EEPROM_CTRL_REG);
- eeprom_slow_io();
- outb(CS_1 | SK_1, ioaddr + EEPROM_CTRL_REG);
- eeprom_slow_io();
- data = (data << 1) |
- ((inb(ioaddr + EEPROM_DATA_REG) & DI_1) ? 1 : 0);
-
- eeprom_slow_io();
- }
-
- return data;
-}
-
-static void eth16i_eeprom_cmd(int ioaddr, unsigned char command)
-{
- int i;
-
- outb(CS_0 | SK_0, ioaddr + EEPROM_CTRL_REG);
- outb(DI_0, ioaddr + EEPROM_DATA_REG);
- outb(CS_1 | SK_0, ioaddr + EEPROM_CTRL_REG);
- outb(DI_1, ioaddr + EEPROM_DATA_REG);
- outb(CS_1 | SK_1, ioaddr + EEPROM_CTRL_REG);
-
- for(i = 7; i >= 0; i--) {
- short cmd = ( (command & (1 << i)) ? DI_1 : DI_0 );
- outb(cmd, ioaddr + EEPROM_DATA_REG);
- outb(CS_1 | SK_0, ioaddr + EEPROM_CTRL_REG);
- eeprom_slow_io();
- outb(CS_1 | SK_1, ioaddr + EEPROM_CTRL_REG);
- eeprom_slow_io();
- }
-}
-
-static int eth16i_open(struct net_device *dev)
-{
- struct eth16i_local *lp = netdev_priv(dev);
- int ioaddr = dev->base_addr;
-
- /* Powerup the chip */
- outb(0xc0 | POWERUP, ioaddr + CONFIG_REG_1);
-
- /* Initialize the chip */
- eth16i_initialize(dev, 0);
-
- /* Set the transmit buffer size */
- lp->tx_buf_size = eth16i_tx_buf_map[ETH16I_TX_BUF_SIZE & 0x03];
-
- if(eth16i_debug > 0)
- printk(KERN_DEBUG "%s: transmit buffer size %d\n",
- dev->name, lp->tx_buf_size);
-
- /* Now enable Transmitter and Receiver sections */
- BITCLR(ioaddr + CONFIG_REG_0, DLC_EN);
-
- /* Now switch to register bank 2, for run time operation */
- eth16i_select_regbank(2, ioaddr);
-
- lp->open_time = jiffies;
- lp->tx_started = 0;
- lp->tx_queue = 0;
- lp->tx_queue_len = 0;
-
- /* Turn on interrupts*/
- outw(ETH16I_INTR_ON, ioaddr + TX_INTR_REG);
-
- netif_start_queue(dev);
- return 0;
-}
-
-static int eth16i_close(struct net_device *dev)
-{
- struct eth16i_local *lp = netdev_priv(dev);
- int ioaddr = dev->base_addr;
-
- eth16i_reset(dev);
-
- /* Turn off interrupts*/
- outw(ETH16I_INTR_OFF, ioaddr + TX_INTR_REG);
-
- netif_stop_queue(dev);
-
- lp->open_time = 0;
-
- /* Disable transmit and receive */
- BITSET(ioaddr + CONFIG_REG_0, DLC_EN);
-
- /* Reset the chip */
- /* outb(0xff, ioaddr + RESET); */
- /* outw(0xffff, ioaddr + TX_STATUS_REG); */
-
- outb(0x00, ioaddr + CONFIG_REG_1);
-
- return 0;
-}
-
-static void eth16i_timeout(struct net_device *dev)
-{
- struct eth16i_local *lp = netdev_priv(dev);
- int ioaddr = dev->base_addr;
- /*
- If we get here, some higher level has decided that
- we are broken. There should really be a "kick me"
- function call instead.
- */
-
- outw(ETH16I_INTR_OFF, ioaddr + TX_INTR_REG);
- printk(KERN_WARNING "%s: transmit timed out with status %04x, %s ?\n",
- dev->name,
- inw(ioaddr + TX_STATUS_REG), (inb(ioaddr + TX_STATUS_REG) & TX_DONE) ?
- "IRQ conflict" : "network cable problem");
-
- dev->trans_start = jiffies; /* prevent tx timeout */
-
- /* Let's dump all registers */
- if(eth16i_debug > 0) {
- printk(KERN_DEBUG "%s: timeout: %02x %02x %02x %02x %02x %02x %02x %02x.\n",
- dev->name, inb(ioaddr + 0),
- inb(ioaddr + 1), inb(ioaddr + 2),
- inb(ioaddr + 3), inb(ioaddr + 4),
- inb(ioaddr + 5),
- inb(ioaddr + 6), inb(ioaddr + 7));
-
- printk(KERN_DEBUG "%s: transmit start reg: %02x. collision reg %02x\n",
- dev->name, inb(ioaddr + TRANSMIT_START_REG),
- inb(ioaddr + COL_16_REG));
- printk(KERN_DEBUG "lp->tx_queue = %d\n", lp->tx_queue);
- printk(KERN_DEBUG "lp->tx_queue_len = %d\n", lp->tx_queue_len);
- printk(KERN_DEBUG "lp->tx_started = %d\n", lp->tx_started);
- }
- dev->stats.tx_errors++;
- eth16i_reset(dev);
- dev->trans_start = jiffies; /* prevent tx timeout */
- outw(ETH16I_INTR_ON, ioaddr + TX_INTR_REG);
- netif_wake_queue(dev);
-}
-
-static netdev_tx_t eth16i_tx(struct sk_buff *skb, struct net_device *dev)
-{
- struct eth16i_local *lp = netdev_priv(dev);
- int ioaddr = dev->base_addr;
- int status = 0;
- ushort length = skb->len;
- unsigned char *buf;
- unsigned long flags;
-
- if (length < ETH_ZLEN) {
- if (skb_padto(skb, ETH_ZLEN))
- return NETDEV_TX_OK;
- length = ETH_ZLEN;
- }
- buf = skb->data;
-
- netif_stop_queue(dev);
-
- /* Turn off TX interrupts */
- outw(ETH16I_INTR_OFF, ioaddr + TX_INTR_REG);
-
- /* We would be better doing the disable_irq tricks the 3c509 does,
- that would make this suck a lot less */
-
- spin_lock_irqsave(&lp->lock, flags);
-
- if( (length + 2) > (lp->tx_buf_size - lp->tx_queue_len)) {
- if(eth16i_debug > 0)
- printk(KERN_WARNING "%s: Transmit buffer full.\n", dev->name);
- }
- else {
- outw(length, ioaddr + DATAPORT);
-
- if( ioaddr < 0x1000 )
- outsw(ioaddr + DATAPORT, buf, (length + 1) >> 1);
- else {
- unsigned char frag = length % 4;
- outsl(ioaddr + DATAPORT, buf, length >> 2);
- if( frag != 0 ) {
- outsw(ioaddr + DATAPORT, (buf + (length & 0xFFFC)), 1);
- if( frag == 3 )
- outsw(ioaddr + DATAPORT,
- (buf + (length & 0xFFFC) + 2), 1);
- }
- }
- lp->tx_buffered_packets++;
- lp->tx_buffered_bytes = length;
- lp->tx_queue++;
- lp->tx_queue_len += length + 2;
- }
- lp->tx_buf_busy = 0;
-
- if(lp->tx_started == 0) {
- /* If the transmitter is idle..always trigger a transmit */
- outb(TX_START | lp->tx_queue, ioaddr + TRANSMIT_START_REG);
- lp->tx_queue = 0;
- lp->tx_queue_len = 0;
- lp->tx_started = 1;
- netif_wake_queue(dev);
- }
- else if(lp->tx_queue_len < lp->tx_buf_size - (ETH_FRAME_LEN + 2)) {
- /* There is still more room for one more packet in tx buffer */
- netif_wake_queue(dev);
- }
-
- spin_unlock_irqrestore(&lp->lock, flags);
-
- outw(ETH16I_INTR_ON, ioaddr + TX_INTR_REG);
- /* Turn TX interrupts back on */
- /* outb(TX_INTR_DONE | TX_INTR_16_COL, ioaddr + TX_INTR_REG); */
- status = 0;
- dev_kfree_skb(skb);
- return NETDEV_TX_OK;
-}
-
-static void eth16i_rx(struct net_device *dev)
-{
- int ioaddr = dev->base_addr;
- int boguscount = MAX_RX_LOOP;
-
- /* Loop until all packets have been read */
- while( (inb(ioaddr + RECEIVE_MODE_REG) & RX_BUFFER_EMPTY) == 0) {
-
- /* Read status byte from receive buffer */
- ushort status = inw(ioaddr + DATAPORT);
-
- /* Get the size of the packet from receive buffer */
- ushort pkt_len = inw(ioaddr + DATAPORT);
-
- if(eth16i_debug > 4)
- printk(KERN_DEBUG "%s: Receiving packet mode %02x status %04x.\n",
- dev->name,
- inb(ioaddr + RECEIVE_MODE_REG), status);
-
- if( !(status & PKT_GOOD) ) {
- dev->stats.rx_errors++;
-
- if( (pkt_len < ETH_ZLEN) || (pkt_len > ETH_FRAME_LEN) ) {
- dev->stats.rx_length_errors++;
- eth16i_reset(dev);
- return;
- }
- else {
- eth16i_skip_packet(dev);
- dev->stats.rx_dropped++;
- }
- }
- else { /* Ok so now we should have a good packet */
- struct sk_buff *skb;
-
- skb = netdev_alloc_skb(dev, pkt_len + 3);
- if( skb == NULL ) {
- printk(KERN_WARNING "%s: Could'n allocate memory for packet (len %d)\n",
- dev->name, pkt_len);
- eth16i_skip_packet(dev);
- dev->stats.rx_dropped++;
- break;
- }
-
- skb_reserve(skb,2);
-
- /*
- Now let's get the packet out of buffer.
- size is (pkt_len + 1) >> 1, cause we are now reading words
- and it have to be even aligned.
- */
-
- if(ioaddr < 0x1000)
- insw(ioaddr + DATAPORT, skb_put(skb, pkt_len),
- (pkt_len + 1) >> 1);
- else {
- unsigned char *buf = skb_put(skb, pkt_len);
- unsigned char frag = pkt_len % 4;
-
- insl(ioaddr + DATAPORT, buf, pkt_len >> 2);
-
- if(frag != 0) {
- unsigned short rest[2];
- rest[0] = inw( ioaddr + DATAPORT );
- if(frag == 3)
- rest[1] = inw( ioaddr + DATAPORT );
-
- memcpy(buf + (pkt_len & 0xfffc), (char *)rest, frag);
- }
- }
-
- skb->protocol=eth_type_trans(skb, dev);
-
- if( eth16i_debug > 5 ) {
- int i;
- printk(KERN_DEBUG "%s: Received packet of length %d.\n",
- dev->name, pkt_len);
- for(i = 0; i < 14; i++)
- printk(KERN_DEBUG " %02x", skb->data[i]);
- printk(KERN_DEBUG ".\n");
- }
- netif_rx(skb);
- dev->stats.rx_packets++;
- dev->stats.rx_bytes += pkt_len;
-
- } /* else */
-
- if(--boguscount <= 0)
- break;
-
- } /* while */
-}
-
-static irqreturn_t eth16i_interrupt(int irq, void *dev_id)
-{
- struct net_device *dev = dev_id;
- struct eth16i_local *lp;
- int ioaddr = 0, status;
- int handled = 0;
-
- ioaddr = dev->base_addr;
- lp = netdev_priv(dev);
-
- /* Turn off all interrupts from adapter */
- outw(ETH16I_INTR_OFF, ioaddr + TX_INTR_REG);
-
- /* eth16i_tx won't be called */
- spin_lock(&lp->lock);
-
- status = inw(ioaddr + TX_STATUS_REG); /* Get the status */
- outw(status, ioaddr + TX_STATUS_REG); /* Clear status bits */
-
- if (status)
- handled = 1;
-
- if(eth16i_debug > 3)
- printk(KERN_DEBUG "%s: Interrupt with status %04x.\n", dev->name, status);
-
- if( status & 0x7f00 ) {
-
- dev->stats.rx_errors++;
-
- if(status & (BUS_RD_ERR << 8) )
- printk(KERN_WARNING "%s: Bus read error.\n",dev->name);
- if(status & (SHORT_PKT_ERR << 8) ) dev->stats.rx_length_errors++;
- if(status & (ALIGN_ERR << 8) ) dev->stats.rx_frame_errors++;
- if(status & (CRC_ERR << 8) ) dev->stats.rx_crc_errors++;
- if(status & (RX_BUF_OVERFLOW << 8) ) dev->stats.rx_over_errors++;
- }
- if( status & 0x001a) {
-
- dev->stats.tx_errors++;
-
- if(status & CR_LOST) dev->stats.tx_carrier_errors++;
- if(status & TX_JABBER_ERR) dev->stats.tx_window_errors++;
-
-#if 0
- if(status & COLLISION) {
- dev->stats.collisions +=
- ((inb(ioaddr+TRANSMIT_MODE_REG) & 0xF0) >> 4);
- }
-#endif
- if(status & COLLISIONS_16) {
- if(lp->col_16 < MAX_COL_16) {
- lp->col_16++;
- dev->stats.collisions++;
- /* Resume transmitting, skip failed packet */
- outb(0x02, ioaddr + COL_16_REG);
- }
- else {
- printk(KERN_WARNING "%s: bailing out due to many consecutive 16-in-a-row collisions. Network cable problem?\n", dev->name);
- }
- }
- }
-
- if( status & 0x00ff ) { /* Let's check the transmit status reg */
-
- if(status & TX_DONE) { /* The transmit has been done */
- dev->stats.tx_packets = lp->tx_buffered_packets;
- dev->stats.tx_bytes += lp->tx_buffered_bytes;
- lp->col_16 = 0;
-
- if(lp->tx_queue) { /* Is there still packets ? */
- /* There was packet(s) so start transmitting and write also
- how many packets there is to be sended */
- outb(TX_START | lp->tx_queue, ioaddr + TRANSMIT_START_REG);
- lp->tx_queue = 0;
- lp->tx_queue_len = 0;
- lp->tx_started = 1;
- }
- else {
- lp->tx_started = 0;
- }
- netif_wake_queue(dev);
- }
- }
-
- if( ( status & 0x8000 ) ||
- ( (inb(ioaddr + RECEIVE_MODE_REG) & RX_BUFFER_EMPTY) == 0) ) {
- eth16i_rx(dev); /* We have packet in receive buffer */
- }
-
- /* Turn interrupts back on */
- outw(ETH16I_INTR_ON, ioaddr + TX_INTR_REG);
-
- if(lp->tx_queue_len < lp->tx_buf_size - (ETH_FRAME_LEN + 2)) {
- /* There is still more room for one more packet in tx buffer */
- netif_wake_queue(dev);
- }
-
- spin_unlock(&lp->lock);
-
- return IRQ_RETVAL(handled);
-}
-
-static void eth16i_skip_packet(struct net_device *dev)
-{
- int ioaddr = dev->base_addr;
-
- inw(ioaddr + DATAPORT);
- inw(ioaddr + DATAPORT);
- inw(ioaddr + DATAPORT);
-
- outb(SKIP_RX_PACKET, ioaddr + FILTER_SELF_RX_REG);
- while( inb( ioaddr + FILTER_SELF_RX_REG ) != 0);
-}
-
-static void eth16i_reset(struct net_device *dev)
-{
- struct eth16i_local *lp = netdev_priv(dev);
- int ioaddr = dev->base_addr;
-
- if(eth16i_debug > 1)
- printk(KERN_DEBUG "%s: Resetting device.\n", dev->name);
-
- BITSET(ioaddr + CONFIG_REG_0, DLC_EN);
- outw(0xffff, ioaddr + TX_STATUS_REG);
- eth16i_select_regbank(2, ioaddr);
-
- lp->tx_started = 0;
- lp->tx_buf_busy = 0;
- lp->tx_queue = 0;
- lp->tx_queue_len = 0;
- BITCLR(ioaddr + CONFIG_REG_0, DLC_EN);
-}
-
-static void eth16i_multicast(struct net_device *dev)
-{
- int ioaddr = dev->base_addr;
-
- if (!netdev_mc_empty(dev) || dev->flags&(IFF_ALLMULTI|IFF_PROMISC))
- {
- outb(3, ioaddr + RECEIVE_MODE_REG);
- } else {
- outb(2, ioaddr + RECEIVE_MODE_REG);
- }
-}
-
-static void eth16i_select_regbank(unsigned char banknbr, int ioaddr)
-{
- unsigned char data;
-
- data = inb(ioaddr + CONFIG_REG_1);
- outb( ((data & 0xF3) | ( (banknbr & 0x03) << 2)), ioaddr + CONFIG_REG_1);
-}
-
-#ifdef MODULE
-
-static ushort eth16i_parse_mediatype(const char* s)
-{
- if(!s)
- return E_PORT_FROM_EPROM;
-
- if (!strncmp(s, "bnc", 3))
- return E_PORT_BNC;
- else if (!strncmp(s, "tp", 2))
- return E_PORT_TP;
- else if (!strncmp(s, "dix", 3))
- return E_PORT_DIX;
- else if (!strncmp(s, "auto", 4))
- return E_PORT_AUTO;
- else
- return E_PORT_FROM_EPROM;
-}
-
-#define MAX_ETH16I_CARDS 4 /* Max number of Eth16i cards per module */
-
-static struct net_device *dev_eth16i[MAX_ETH16I_CARDS];
-static int io[MAX_ETH16I_CARDS];
-#if 0
-static int irq[MAX_ETH16I_CARDS];
-#endif
-static char* mediatype[MAX_ETH16I_CARDS];
-static int debug = -1;
-
-MODULE_AUTHOR("Mika Kuoppala <miku@iki.fi>");
-MODULE_DESCRIPTION("ICL EtherTeam 16i/32 driver");
-MODULE_LICENSE("GPL");
-
-
-module_param_array(io, int, NULL, 0);
-MODULE_PARM_DESC(io, "eth16i I/O base address(es)");
-
-#if 0
-module_param_array(irq, int, NULL, 0);
-MODULE_PARM_DESC(irq, "eth16i interrupt request number");
-#endif
-
-module_param_array(mediatype, charp, NULL, 0);
-MODULE_PARM_DESC(mediatype, "eth16i media type of interface(s) (bnc,tp,dix,auto,eprom)");
-
-module_param(debug, int, 0);
-MODULE_PARM_DESC(debug, "eth16i debug level (0-6)");
-
-int __init init_module(void)
-{
- int this_dev, found = 0;
- struct net_device *dev;
-
- for (this_dev = 0; this_dev < MAX_ETH16I_CARDS; this_dev++) {
- dev = alloc_etherdev(sizeof(struct eth16i_local));
- if (!dev)
- break;
-
- dev->base_addr = io[this_dev];
-
- if(debug != -1)
- eth16i_debug = debug;
-
- if(eth16i_debug > 1)
- printk(KERN_NOTICE "eth16i(%d): interface type %s\n", this_dev, mediatype[this_dev] ? mediatype[this_dev] : "none" );
-
- dev->if_port = eth16i_parse_mediatype(mediatype[this_dev]);
-
- if(io[this_dev] == 0) {
- if (this_dev != 0) { /* Only autoprobe 1st one */
- free_netdev(dev);
- break;
- }
-
- printk(KERN_NOTICE "eth16i.c: Presently autoprobing (not recommended) for a single card.\n");
- }
-
- if (do_eth16i_probe(dev) == 0) {
- dev_eth16i[found++] = dev;
- continue;
- }
- printk(KERN_WARNING "eth16i.c No Eth16i card found (i/o = 0x%x).\n",
- io[this_dev]);
- free_netdev(dev);
- break;
- }
- if (found)
- return 0;
- return -ENXIO;
-}
-
-void __exit cleanup_module(void)
-{
- int this_dev;
-
- for(this_dev = 0; this_dev < MAX_ETH16I_CARDS; this_dev++) {
- struct net_device *dev = dev_eth16i[this_dev];
-
- if (netdev_priv(dev)) {
- unregister_netdev(dev);
- free_irq(dev->irq, dev);
- release_region(dev->base_addr, ETH16I_IO_EXTENT);
- free_netdev(dev);
- }
- }
-}
-#endif /* MODULE */
diff --git a/drivers/net/ethernet/i825xx/3c505.c b/drivers/net/ethernet/i825xx/3c505.c
deleted file mode 100644
index 6d000d678a5..00000000000
--- a/drivers/net/ethernet/i825xx/3c505.c
+++ /dev/null
@@ -1,1672 +0,0 @@
-/*
- * Linux Ethernet device driver for the 3Com Etherlink Plus (3C505)
- * By Craig Southeren, Juha Laiho and Philip Blundell
- *
- * 3c505.c This module implements an interface to the 3Com
- * Etherlink Plus (3c505) Ethernet card. Linux device
- * driver interface reverse engineered from the Linux 3C509
- * device drivers. Some 3C505 information gleaned from
- * the Crynwr packet driver. Still this driver would not
- * be here without 3C505 technical reference provided by
- * 3Com.
- *
- * $Id: 3c505.c,v 1.10 1996/04/16 13:06:27 phil Exp $
- *
- * Authors: Linux 3c505 device driver by
- * Craig Southeren, <craigs@ineluki.apana.org.au>
- * Final debugging by
- * Andrew Tridgell, <tridge@nimbus.anu.edu.au>
- * Auto irq/address, tuning, cleanup and v1.1.4+ kernel mods by
- * Juha Laiho, <jlaiho@ichaos.nullnet.fi>
- * Linux 3C509 driver by
- * Donald Becker, <becker@super.org>
- * (Now at <becker@scyld.com>)
- * Crynwr packet driver by
- * Krishnan Gopalan and Gregg Stefancik,
- * Clemson University Engineering Computer Operations.
- * Portions of the code have been adapted from the 3c505
- * driver for NCSA Telnet by Bruce Orchard and later
- * modified by Warren Van Houten and krus@diku.dk.
- * 3C505 technical information provided by
- * Terry Murphy, of 3Com Network Adapter Division
- * Linux 1.3.0 changes by
- * Alan Cox <Alan.Cox@linux.org>
- * More debugging, DMA support, currently maintained by
- * Philip Blundell <philb@gnu.org>
- * 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
- * by means of Primary Command Blocks (PCBs); these are transferred using PIO
- * through the command register. The card has 256k of on-board RAM, which is
- * used to buffer received packets. It might seem at first that more buffers
- * are better, but in fact this isn't true. From my tests, it seems that
- * more than about 10 buffers are unnecessary, and there is a noticeable
- * performance hit in having more active on the card. So the majority of the
- * card's memory isn't, in fact, used. Sadly, the card only has one transmit
- * buffer and, short of loading our own firmware into it (which is what some
- * drivers resort to) there's nothing we can do about this.
- *
- * We keep up to 4 "receive packet" commands active on the board at a time.
- * When a packet comes in, so long as there is a receive command active, the
- * board will send us a "packet received" PCB and then add the data for that
- * packet to the DMA queue. If a DMA transfer is not already in progress, we
- * set one up to start uploading the data. We have to maintain a list of
- * backlogged receive packets, because the card may decide to tell us about
- * a newly-arrived packet at any time, and we may not be able to start a DMA
- * transfer immediately (ie one may already be going on). We can't NAK the
- * PCB, because then it would throw the packet away.
- *
- * Trying to send a PCB to the card at the wrong moment seems to have bad
- * effects. If we send it a transmit PCB while a receive DMA is happening,
- * it will just NAK the PCB and so we will have wasted our time. Worse, it
- * sometimes seems to interrupt the transfer. The majority of the low-level
- * code is protected by one huge semaphore -- "busy" -- which is set whenever
- * it probably isn't safe to do anything to the card. The receive routine
- * must gain a lock on "busy" before it can start a DMA transfer, and the
- * transmit routine must gain a lock before it sends the first PCB to the card.
- * The send_pcb() routine also has an internal semaphore to protect it against
- * being re-entered (which would be disastrous) -- this is needed because
- * several things can happen asynchronously (re-priming the receiver and
- * asking the card for statistics, for example). send_pcb() will also refuse
- * to talk to the card at all if a DMA upload is happening. The higher-level
- * networking code will reschedule a later retry if some part of the driver
- * is blocked. In practice, this doesn't seem to happen very often.
- */
-
-/* This driver may now work with revision 2.x hardware, since all the read
- * operations on the HCR have been removed (we now keep our own softcopy).
- * But I don't have an old card to test it on.
- *
- * This has had the bad effect that the autoprobe routine is now a bit
- * less friendly to other devices. However, it was never very good.
- * before, so I doubt it will hurt anybody.
- */
-
-/* The driver is a mess. I took Craig's and Juha's code, and hacked it firstly
- * to make it more reliable, and secondly to add DMA mode. Many things could
- * probably be done better; the concurrency protection is particularly awful.
- */
-
-#include <linux/module.h>
-#include <linux/kernel.h>
-#include <linux/string.h>
-#include <linux/interrupt.h>
-#include <linux/errno.h>
-#include <linux/in.h>
-#include <linux/ioport.h>
-#include <linux/spinlock.h>
-#include <linux/ethtool.h>
-#include <linux/delay.h>
-#include <linux/bitops.h>
-#include <linux/gfp.h>
-
-#include <asm/uaccess.h>
-#include <asm/io.h>
-#include <asm/dma.h>
-
-#include <linux/netdevice.h>
-#include <linux/etherdevice.h>
-#include <linux/skbuff.h>
-#include <linux/init.h>
-
-#include "3c505.h"
-
-/*********************************************************
- *
- * define debug messages here as common strings to reduce space
- *
- *********************************************************/
-
-#define timeout_msg "*** timeout at %s:%s (line %d) ***\n"
-#define TIMEOUT_MSG(lineno) \
- pr_notice(timeout_msg, __FILE__, __func__, (lineno))
-
-#define invalid_pcb_msg "*** invalid pcb length %d at %s:%s (line %d) ***\n"
-#define INVALID_PCB_MSG(len) \
- pr_notice(invalid_pcb_msg, (len), __FILE__, __func__, __LINE__)
-
-#define search_msg "%s: Looking for 3c505 adapter at address %#x..."
-
-#define stilllooking_msg "still looking..."
-
-#define found_msg "found.\n"
-
-#define notfound_msg "not found (reason = %d)\n"
-
-#define couldnot_msg "%s: 3c505 not found\n"
-
-/*********************************************************
- *
- * various other debug stuff
- *
- *********************************************************/
-
-#ifdef ELP_DEBUG
-static int elp_debug = ELP_DEBUG;
-#else
-static int elp_debug;
-#endif
-#define debug elp_debug
-
-/*
- * 0 = no messages (well, some)
- * 1 = messages when high level commands performed
- * 2 = messages when low level commands performed
- * 3 = messages when interrupts received
- */
-
-/*****************************************************************
- *
- * List of I/O-addresses we try to auto-sense
- * Last element MUST BE 0!
- *****************************************************************/
-
-static int addr_list[] __initdata = {0x300, 0x280, 0x310, 0};
-
-/* Dma Memory related stuff */
-
-static unsigned long dma_mem_alloc(int size)
-{
- int order = get_order(size);
- return __get_dma_pages(GFP_KERNEL, order);
-}
-
-
-/*****************************************************************
- *
- * Functions for I/O (note the inline !)
- *
- *****************************************************************/
-
-static inline unsigned char inb_status(unsigned int base_addr)
-{
- return inb(base_addr + PORT_STATUS);
-}
-
-static inline int inb_command(unsigned int base_addr)
-{
- return inb(base_addr + PORT_COMMAND);
-}
-
-static inline void outb_control(unsigned char val, struct net_device *dev)
-{
- outb(val, dev->base_addr + PORT_CONTROL);
- ((elp_device *)(netdev_priv(dev)))->hcr_val = val;
-}
-
-#define HCR_VAL(x) (((elp_device *)(netdev_priv(x)))->hcr_val)
-
-static inline void outb_command(unsigned char val, unsigned int base_addr)
-{
- outb(val, base_addr + PORT_COMMAND);
-}
-
-static inline unsigned int backlog_next(unsigned int n)
-{
- return (n + 1) % BACKLOG_SIZE;
-}
-
-/*****************************************************************
- *
- * useful functions for accessing the adapter
- *
- *****************************************************************/
-
-/*
- * use this routine when accessing the ASF bits as they are
- * changed asynchronously by the adapter
- */
-
-/* get adapter PCB status */
-#define GET_ASF(addr) \
- (get_status(addr)&ASF_PCB_MASK)
-
-static inline int get_status(unsigned int base_addr)
-{
- unsigned long timeout = jiffies + 10*HZ/100;
- register int stat1;
- do {
- stat1 = inb_status(base_addr);
- } while (stat1 != inb_status(base_addr) && time_before(jiffies, timeout));
- if (time_after_eq(jiffies, timeout))
- TIMEOUT_MSG(__LINE__);
- return stat1;
-}
-
-static inline void set_hsf(struct net_device *dev, int hsf)
-{
- elp_device *adapter = netdev_priv(dev);
- unsigned long flags;
-
- spin_lock_irqsave(&adapter->lock, flags);
- outb_control((HCR_VAL(dev) & ~HSF_PCB_MASK) | hsf, dev);
- spin_unlock_irqrestore(&adapter->lock, flags);
-}
-
-static bool start_receive(struct net_device *, pcb_struct *);
-
-static inline void adapter_reset(struct net_device *dev)
-{
- unsigned long timeout;
- elp_device *adapter = netdev_priv(dev);
- unsigned char orig_hcr = adapter->hcr_val;
-
- outb_control(0, dev);
-
- if (inb_status(dev->base_addr) & ACRF) {
- do {
- inb_command(dev->base_addr);
- timeout = jiffies + 2*HZ/100;
- while (time_before_eq(jiffies, timeout) && !(inb_status(dev->base_addr) & ACRF));
- } while (inb_status(dev->base_addr) & ACRF);
- set_hsf(dev, HSF_PCB_NAK);
- }
- outb_control(adapter->hcr_val | ATTN | DIR, dev);
- mdelay(10);
- outb_control(adapter->hcr_val & ~ATTN, dev);
- mdelay(10);
- outb_control(adapter->hcr_val | FLSH, dev);
- mdelay(10);
- outb_control(adapter->hcr_val & ~FLSH, dev);
- mdelay(10);
-
- outb_control(orig_hcr, dev);
- if (!start_receive(dev, &adapter->tx_pcb))
- pr_err("%s: start receive command failed\n", dev->name);
-}
-
-/* Check to make sure that a DMA transfer hasn't timed out. This should
- * never happen in theory, but seems to occur occasionally if the card gets
- * prodded at the wrong time.
- */
-static inline void check_3c505_dma(struct net_device *dev)
-{
- elp_device *adapter = netdev_priv(dev);
- if (adapter->dmaing && time_after(jiffies, adapter->current_dma.start_time + 10)) {
- unsigned long flags, f;
- pr_err("%s: DMA %s timed out, %d bytes left\n", dev->name,
- adapter->current_dma.direction ? "download" : "upload",
- get_dma_residue(dev->dma));
- spin_lock_irqsave(&adapter->lock, flags);
- adapter->dmaing = 0;
- adapter->busy = 0;
-
- f=claim_dma_lock();
- disable_dma(dev->dma);
- release_dma_lock(f);
-
- if (adapter->rx_active)
- adapter->rx_active--;
- outb_control(adapter->hcr_val & ~(DMAE | TCEN | DIR), dev);
- spin_unlock_irqrestore(&adapter->lock, flags);
- }
-}
-
-/* Primitive functions used by send_pcb() */
-static inline bool send_pcb_slow(unsigned int base_addr, unsigned char byte)
-{
- unsigned long timeout;
- outb_command(byte, base_addr);
- for (timeout = jiffies + 5*HZ/100; time_before(jiffies, timeout);) {
- if (inb_status(base_addr) & HCRE)
- return false;
- }
- pr_warning("3c505: send_pcb_slow timed out\n");
- return true;
-}
-
-static inline bool send_pcb_fast(unsigned int base_addr, unsigned char byte)
-{
- unsigned int timeout;
- outb_command(byte, base_addr);
- for (timeout = 0; timeout < 40000; timeout++) {
- if (inb_status(base_addr) & HCRE)
- return false;
- }
- pr_warning("3c505: send_pcb_fast timed out\n");
- return true;
-}
-
-/* Check to see if the receiver needs restarting, and kick it if so */
-static inline void prime_rx(struct net_device *dev)
-{
- elp_device *adapter = netdev_priv(dev);
- while (adapter->rx_active < ELP_RX_PCBS && netif_running(dev)) {
- if (!start_receive(dev, &adapter->itx_pcb))
- break;
- }
-}
-
-/*****************************************************************
- *
- * send_pcb
- * Send a PCB to the adapter.
- *
- * output byte to command reg --<--+
- * wait until HCRE is non zero |
- * loop until all bytes sent -->--+
- * set HSF1 and HSF2 to 1
- * output pcb length
- * wait until ASF give ACK or NAK
- * set HSF1 and HSF2 to 0
- *
- *****************************************************************/
-
-/* This can be quite slow -- the adapter is allowed to take up to 40ms
- * to respond to the initial interrupt.
- *
- * We run initially with interrupts turned on, but with a semaphore set
- * so that nobody tries to re-enter this code. Once the first byte has
- * gone through, we turn interrupts off and then send the others (the
- * timeout is reduced to 500us).
- */
-
-static bool send_pcb(struct net_device *dev, pcb_struct * pcb)
-{
- int i;
- unsigned long timeout;
- elp_device *adapter = netdev_priv(dev);
- unsigned long flags;
-
- check_3c505_dma(dev);
-
- if (adapter->dmaing && adapter->current_dma.direction == 0)
- return false;
-
- /* Avoid contention */
- if (test_and_set_bit(1, &adapter->send_pcb_semaphore)) {
- if (elp_debug >= 3) {
- pr_debug("%s: send_pcb entered while threaded\n", dev->name);
- }
- return false;
- }
- /*
- * load each byte into the command register and
- * wait for the HCRE bit to indicate the adapter
- * had read the byte
- */
- set_hsf(dev, 0);
-
- if (send_pcb_slow(dev->base_addr, pcb->command))
- goto abort;
-
- spin_lock_irqsave(&adapter->lock, flags);
-
- if (send_pcb_fast(dev->base_addr, pcb->length))
- goto sti_abort;
-
- for (i = 0; i < pcb->length; i++) {
- if (send_pcb_fast(dev->base_addr, pcb->data.raw[i]))
- goto sti_abort;
- }
-
- outb_control(adapter->hcr_val | 3, dev); /* signal end of PCB */
- outb_command(2 + pcb->length, dev->base_addr);
-
- /* now wait for the acknowledgement */
- spin_unlock_irqrestore(&adapter->lock, flags);
-
- for (timeout = jiffies + 5*HZ/100; time_before(jiffies, timeout);) {
- switch (GET_ASF(dev->base_addr)) {
- case ASF_PCB_ACK:
- adapter->send_pcb_semaphore = 0;
- return true;
-
- case ASF_PCB_NAK:
-#ifdef ELP_DEBUG
- pr_debug("%s: send_pcb got NAK\n", dev->name);
-#endif
- goto abort;
- }
- }
-
- if (elp_debug >= 1)
- pr_debug("%s: timeout waiting for PCB acknowledge (status %02x)\n",
- dev->name, inb_status(dev->base_addr));
- goto abort;
-
- sti_abort:
- spin_unlock_irqrestore(&adapter->lock, flags);
- abort:
- adapter->send_pcb_semaphore = 0;
- return false;
-}
-
-
-/*****************************************************************
- *
- * receive_pcb
- * Read a PCB from the adapter
- *
- * wait for ACRF to be non-zero ---<---+
- * input a byte |
- * if ASF1 and ASF2 were not both one |
- * before byte was read, loop --->---+
- * set HSF1 and HSF2 for ack
- *
- *****************************************************************/
-
-static bool receive_pcb(struct net_device *dev, pcb_struct * pcb)
-{
- int i, j;
- int total_length;
- int stat;
- unsigned long timeout;
- unsigned long flags;
-
- elp_device *adapter = netdev_priv(dev);
-
- set_hsf(dev, 0);
-
- /* get the command code */
- timeout = jiffies + 2*HZ/100;
- while (((stat = get_status(dev->base_addr)) & ACRF) == 0 && time_before(jiffies, timeout));
- if (time_after_eq(jiffies, timeout)) {
- TIMEOUT_MSG(__LINE__);
- return false;
- }
- pcb->command = inb_command(dev->base_addr);
-
- /* read the data length */
- timeout = jiffies + 3*HZ/100;
- while (((stat = get_status(dev->base_addr)) & ACRF) == 0 && time_before(jiffies, timeout));
- if (time_after_eq(jiffies, timeout)) {
- TIMEOUT_MSG(__LINE__);
- pr_info("%s: status %02x\n", dev->name, stat);
- return false;
- }
- pcb->length = inb_command(dev->base_addr);
-
- if (pcb->length > MAX_PCB_DATA) {
- INVALID_PCB_MSG(pcb->length);
- adapter_reset(dev);
- return false;
- }
- /* read the data */
- spin_lock_irqsave(&adapter->lock, flags);
- for (i = 0; i < MAX_PCB_DATA; i++) {
- for (j = 0; j < 20000; j++) {
- stat = get_status(dev->base_addr);
- if (stat & ACRF)
- break;
- }
- pcb->data.raw[i] = inb_command(dev->base_addr);
- if ((stat & ASF_PCB_MASK) == ASF_PCB_END || j >= 20000)
- break;
- }
- spin_unlock_irqrestore(&adapter->lock, flags);
- if (i >= MAX_PCB_DATA) {
- INVALID_PCB_MSG(i);
- return false;
- }
- if (j >= 20000) {
- TIMEOUT_MSG(__LINE__);
- return false;
- }
- /* the last "data" byte was really the length! */
- total_length = pcb->data.raw[i];
-
- /* safety check total length vs data length */
- if (total_length != (pcb->length + 2)) {
- if (elp_debug >= 2)
- pr_warning("%s: mangled PCB received\n", dev->name);
- set_hsf(dev, HSF_PCB_NAK);
- return false;
- }
-
- if (pcb->command == CMD_RECEIVE_PACKET_COMPLETE) {
- if (test_and_set_bit(0, (void *) &adapter->busy)) {
- if (backlog_next(adapter->rx_backlog.in) == adapter->rx_backlog.out) {
- set_hsf(dev, HSF_PCB_NAK);
- pr_warning("%s: PCB rejected, transfer in progress and backlog full\n", dev->name);
- pcb->command = 0;
- return true;
- } else {
- pcb->command = 0xff;
- }
- }
- }
- set_hsf(dev, HSF_PCB_ACK);
- return true;
-}
-
-/******************************************************
- *
- * queue a receive command on the adapter so we will get an
- * interrupt when a packet is received.
- *
- ******************************************************/
-
-static bool start_receive(struct net_device *dev, pcb_struct * tx_pcb)
-{
- bool status;
- elp_device *adapter = netdev_priv(dev);
-
- if (elp_debug >= 3)
- pr_debug("%s: restarting receiver\n", dev->name);
- tx_pcb->command = CMD_RECEIVE_PACKET;
- tx_pcb->length = sizeof(struct Rcv_pkt);
- tx_pcb->data.rcv_pkt.buf_seg
- = tx_pcb->data.rcv_pkt.buf_ofs = 0; /* Unused */
- tx_pcb->data.rcv_pkt.buf_len = 1600;
- tx_pcb->data.rcv_pkt.timeout = 0; /* set timeout to zero */
- status = send_pcb(dev, tx_pcb);
- if (status)
- adapter->rx_active++;
- return status;
-}
-
-/******************************************************
- *
- * extract a packet from the adapter
- * this routine is only called from within the interrupt
- * service routine, so no cli/sti calls are needed
- * note that the length is always assumed to be even
- *
- ******************************************************/
-
-static void receive_packet(struct net_device *dev, int len)
-{
- int rlen;
- elp_device *adapter = netdev_priv(dev);
- void *target;
- struct sk_buff *skb;
- unsigned long flags;
-
- rlen = (len + 1) & ~1;
- skb = netdev_alloc_skb(dev, rlen + 2);
-
- if (!skb) {
- pr_warning("%s: memory squeeze, dropping packet\n", dev->name);
- target = adapter->dma_buffer;
- adapter->current_dma.target = NULL;
- /* FIXME: stats */
- return;
- }
-
- skb_reserve(skb, 2);
- target = skb_put(skb, rlen);
- if ((unsigned long)(target + rlen) >= MAX_DMA_ADDRESS) {
- adapter->current_dma.target = target;
- target = adapter->dma_buffer;
- } else {
- adapter->current_dma.target = NULL;
- }
-
- /* if this happens, we die */
- if (test_and_set_bit(0, (void *) &adapter->dmaing))
- pr_err("%s: rx blocked, DMA in progress, dir %d\n",
- dev->name, adapter->current_dma.direction);
-
- adapter->current_dma.direction = 0;
- adapter->current_dma.length = rlen;
- adapter->current_dma.skb = skb;
- adapter->current_dma.start_time = jiffies;
-
- outb_control(adapter->hcr_val | DIR | TCEN | DMAE, dev);
-
- flags=claim_dma_lock();
- disable_dma(dev->dma);
- clear_dma_ff(dev->dma);
- set_dma_mode(dev->dma, 0x04); /* dma read */
- set_dma_addr(dev->dma, isa_virt_to_bus(target));
- set_dma_count(dev->dma, rlen);
- enable_dma(dev->dma);
- release_dma_lock(flags);
-
- if (elp_debug >= 3) {
- pr_debug("%s: rx DMA transfer started\n", dev->name);
- }
-
- if (adapter->rx_active)
- adapter->rx_active--;
-
- if (!adapter->busy)
- pr_warning("%s: receive_packet called, busy not set.\n", dev->name);
-}
-
-/******************************************************
- *
- * interrupt handler
- *
- ******************************************************/
-
-static irqreturn_t elp_interrupt(int irq, void *dev_id)
-{
- int len;
- int dlen;
- int icount = 0;
- struct net_device *dev = dev_id;
- elp_device *adapter = netdev_priv(dev);
- unsigned long timeout;
-
- spin_lock(&adapter->lock);
-
- do {
- /*
- * has a DMA transfer finished?
- */
- if (inb_status(dev->base_addr) & DONE) {
- if (!adapter->dmaing)
- pr_warning("%s: phantom DMA completed\n", dev->name);
-
- if (elp_debug >= 3)
- pr_debug("%s: %s DMA complete, status %02x\n", dev->name,
- adapter->current_dma.direction ? "tx" : "rx",
- inb_status(dev->base_addr));
-
- outb_control(adapter->hcr_val & ~(DMAE | TCEN | DIR), dev);
- if (adapter->current_dma.direction) {
- dev_kfree_skb_irq(adapter->current_dma.skb);
- } else {
- struct sk_buff *skb = adapter->current_dma.skb;
- if (skb) {
- if (adapter->current_dma.target) {
- /* have already done the skb_put() */
- memcpy(adapter->current_dma.target, adapter->dma_buffer, adapter->current_dma.length);
- }
- skb->protocol = eth_type_trans(skb,dev);
- dev->stats.rx_bytes += skb->len;
- netif_rx(skb);
- }
- }
- adapter->dmaing = 0;
- if (adapter->rx_backlog.in != adapter->rx_backlog.out) {
- int t = adapter->rx_backlog.length[adapter->rx_backlog.out];
- adapter->rx_backlog.out = backlog_next(adapter->rx_backlog.out);
- if (elp_debug >= 2)
- pr_debug("%s: receiving backlogged packet (%d)\n", dev->name, t);
- receive_packet(dev, t);
- } else {
- adapter->busy = 0;
- }
- } else {
- /* has one timed out? */
- check_3c505_dma(dev);
- }
-
- /*
- * receive a PCB from the adapter
- */
- timeout = jiffies + 3*HZ/100;
- while ((inb_status(dev->base_addr) & ACRF) != 0 && time_before(jiffies, timeout)) {
- if (receive_pcb(dev, &adapter->irx_pcb)) {
- switch (adapter->irx_pcb.command)
- {
- case 0:
- break;
- /*
- * received a packet - this must be handled fast
- */
- case 0xff:
- case CMD_RECEIVE_PACKET_COMPLETE:
- /* if the device isn't open, don't pass packets up the stack */
- if (!netif_running(dev))
- break;
- len = adapter->irx_pcb.data.rcv_resp.pkt_len;
- dlen = adapter->irx_pcb.data.rcv_resp.buf_len;
- if (adapter->irx_pcb.data.rcv_resp.timeout != 0) {
- pr_err("%s: interrupt - packet not received correctly\n", dev->name);
- } else {
- if (elp_debug >= 3) {
- pr_debug("%s: interrupt - packet received of length %i (%i)\n",
- dev->name, len, dlen);
- }
- if (adapter->irx_pcb.command == 0xff) {
- if (elp_debug >= 2)
- pr_debug("%s: adding packet to backlog (len = %d)\n",
- dev->name, dlen);
- adapter->rx_backlog.length[adapter->rx_backlog.in] = dlen;
- adapter->rx_backlog.in = backlog_next(adapter->rx_backlog.in);
- } else {
- receive_packet(dev, dlen);
- }
- if (elp_debug >= 3)
- pr_debug("%s: packet received\n", dev->name);
- }
- break;
-
- /*
- * 82586 configured correctly
- */
- case CMD_CONFIGURE_82586_RESPONSE:
- adapter->got[CMD_CONFIGURE_82586] = 1;
- if (elp_debug >= 3)
- pr_debug("%s: interrupt - configure response received\n", dev->name);
- break;
-
- /*
- * Adapter memory configuration
- */
- case CMD_CONFIGURE_ADAPTER_RESPONSE:
- adapter->got[CMD_CONFIGURE_ADAPTER_MEMORY] = 1;
- if (elp_debug >= 3)
- pr_debug("%s: Adapter memory configuration %s.\n", dev->name,
- adapter->irx_pcb.data.failed ? "failed" : "succeeded");
- break;
-
- /*
- * Multicast list loading
- */
- case CMD_LOAD_MULTICAST_RESPONSE:
- adapter->got[CMD_LOAD_MULTICAST_LIST] = 1;
- if (elp_debug >= 3)
- pr_debug("%s: Multicast address list loading %s.\n", dev->name,
- adapter->irx_pcb.data.failed ? "failed" : "succeeded");
- break;
-
- /*
- * Station address setting
- */
- case CMD_SET_ADDRESS_RESPONSE:
- adapter->got[CMD_SET_STATION_ADDRESS] = 1;
- if (elp_debug >= 3)
- pr_debug("%s: Ethernet address setting %s.\n", dev->name,
- adapter->irx_pcb.data.failed ? "failed" : "succeeded");
- break;
-
-
- /*
- * received board statistics
- */
- case CMD_NETWORK_STATISTICS_RESPONSE:
- dev->stats.rx_packets += adapter->irx_pcb.data.netstat.tot_recv;
- dev->stats.tx_packets += adapter->irx_pcb.data.netstat.tot_xmit;
- dev->stats.rx_crc_errors += adapter->irx_pcb.data.netstat.err_CRC;
- dev->stats.rx_frame_errors += adapter->irx_pcb.data.netstat.err_align;
- dev->stats.rx_fifo_errors += adapter->irx_pcb.data.netstat.err_ovrrun;
- dev->stats.rx_over_errors += adapter->irx_pcb.data.netstat.err_res;
- adapter->got[CMD_NETWORK_STATISTICS] = 1;
- if (elp_debug >= 3)
- pr_debug("%s: interrupt - statistics response received\n", dev->name);
- break;
-
- /*
- * sent a packet
- */
- case CMD_TRANSMIT_PACKET_COMPLETE:
- if (elp_debug >= 3)
- pr_debug("%s: interrupt - packet sent\n", dev->name);
- if (!netif_running(dev))
- break;
- switch (adapter->irx_pcb.data.xmit_resp.c_stat) {
- case 0xffff:
- dev->stats.tx_aborted_errors++;
- pr_info("%s: transmit timed out, network cable problem?\n", dev->name);
- break;
- case 0xfffe:
- dev->stats.tx_fifo_errors++;
- pr_info("%s: transmit timed out, FIFO underrun\n", dev->name);
- break;
- }
- netif_wake_queue(dev);
- break;
-
- /*
- * some unknown PCB
- */
- default:
- pr_debug("%s: unknown PCB received - %2.2x\n",
- dev->name, adapter->irx_pcb.command);
- break;
- }
- } else {
- pr_warning("%s: failed to read PCB on interrupt\n", dev->name);
- adapter_reset(dev);
- }
- }
-
- } while (icount++ < 5 && (inb_status(dev->base_addr) & (ACRF | DONE)));
-
- prime_rx(dev);
-
- /*
- * indicate no longer in interrupt routine
- */
- spin_unlock(&adapter->lock);
- return IRQ_HANDLED;
-}
-
-
-/******************************************************
- *
- * open the board
- *
- ******************************************************/
-
-static int elp_open(struct net_device *dev)
-{
- elp_device *adapter = netdev_priv(dev);
- int retval;
-
- if (elp_debug >= 3)
- pr_debug("%s: request to open device\n", dev->name);
-
- /*
- * make sure we actually found the device
- */
- if (adapter == NULL) {
- pr_err("%s: Opening a non-existent physical device\n", dev->name);
- return -EAGAIN;
- }
- /*
- * disable interrupts on the board
- */
- outb_control(0, dev);
-
- /*
- * clear any pending interrupts
- */
- inb_command(dev->base_addr);
- adapter_reset(dev);
-
- /*
- * no receive PCBs active
- */
- adapter->rx_active = 0;
-
- adapter->busy = 0;
- adapter->send_pcb_semaphore = 0;
- adapter->rx_backlog.in = 0;
- adapter->rx_backlog.out = 0;
-
- spin_lock_init(&adapter->lock);
-
- /*
- * install our interrupt service routine
- */
- if ((retval = request_irq(dev->irq, elp_interrupt, 0, dev->name, dev))) {
- pr_err("%s: could not allocate IRQ%d\n", dev->name, dev->irq);
- return retval;
- }
- if ((retval = request_dma(dev->dma, dev->name))) {
- free_irq(dev->irq, dev);
- pr_err("%s: could not allocate DMA%d channel\n", dev->name, dev->dma);
- return retval;
- }
- adapter->dma_buffer = (void *) dma_mem_alloc(DMA_BUFFER_SIZE);
- if (!adapter->dma_buffer) {
- pr_err("%s: could not allocate DMA buffer\n", dev->name);
- free_dma(dev->dma);
- free_irq(dev->irq, dev);
- return -ENOMEM;
- }
- adapter->dmaing = 0;
-
- /*
- * enable interrupts on the board
- */
- outb_control(CMDE, dev);
-
- /*
- * configure adapter memory: we need 10 multicast addresses, default==0
- */
- if (elp_debug >= 3)
- pr_debug("%s: sending 3c505 memory configuration command\n", dev->name);
- adapter->tx_pcb.command = CMD_CONFIGURE_ADAPTER_MEMORY;
- adapter->tx_pcb.data.memconf.cmd_q = 10;
- adapter->tx_pcb.data.memconf.rcv_q = 20;
- adapter->tx_pcb.data.memconf.mcast = 10;
- adapter->tx_pcb.data.memconf.frame = 20;
- adapter->tx_pcb.data.memconf.rcv_b = 20;
- adapter->tx_pcb.data.memconf.progs = 0;
- adapter->tx_pcb.length = sizeof(struct Memconf);
- adapter->got[CMD_CONFIGURE_ADAPTER_MEMORY] = 0;
- if (!send_pcb(dev, &adapter->tx_pcb))
- pr_err("%s: couldn't send memory configuration command\n", dev->name);
- else {
- unsigned long timeout = jiffies + TIMEOUT;
- while (adapter->got[CMD_CONFIGURE_ADAPTER_MEMORY] == 0 && time_before(jiffies, timeout));
- if (time_after_eq(jiffies, timeout))
- TIMEOUT_MSG(__LINE__);
- }
-
-
- /*
- * configure adapter to receive broadcast messages and wait for response
- */
- if (elp_debug >= 3)
- pr_debug("%s: sending 82586 configure command\n", dev->name);
- adapter->tx_pcb.command = CMD_CONFIGURE_82586;
- adapter->tx_pcb.data.configure = NO_LOOPBACK | RECV_BROAD;
- adapter->tx_pcb.length = 2;
- adapter->got[CMD_CONFIGURE_82586] = 0;
- if (!send_pcb(dev, &adapter->tx_pcb))
- pr_err("%s: couldn't send 82586 configure command\n", dev->name);
- else {
- unsigned long timeout = jiffies + TIMEOUT;
- while (adapter->got[CMD_CONFIGURE_82586] == 0 && time_before(jiffies, timeout));
- if (time_after_eq(jiffies, timeout))
- TIMEOUT_MSG(__LINE__);
- }
-
- /* enable burst-mode DMA */
- /* outb(0x1, dev->base_addr + PORT_AUXDMA); */
-
- /*
- * queue receive commands to provide buffering
- */
- prime_rx(dev);
- if (elp_debug >= 3)
- pr_debug("%s: %d receive PCBs active\n", dev->name, adapter->rx_active);
-
- /*
- * device is now officially open!
- */
-
- netif_start_queue(dev);
- return 0;
-}
-
-
-/******************************************************
- *
- * send a packet to the adapter
- *
- ******************************************************/
-
-static netdev_tx_t send_packet(struct net_device *dev, struct sk_buff *skb)
-{
- elp_device *adapter = netdev_priv(dev);
- unsigned long target;
- unsigned long flags;
-
- /*
- * make sure the length is even and no shorter than 60 bytes
- */
- unsigned int nlen = (((skb->len < 60) ? 60 : skb->len) + 1) & (~1);
-
- if (test_and_set_bit(0, (void *) &adapter->busy)) {
- if (elp_debug >= 2)
- pr_debug("%s: transmit blocked\n", dev->name);
- return false;
- }
-
- dev->stats.tx_bytes += nlen;
-
- /*
- * send the adapter a transmit packet command. Ignore segment and offset
- * and make sure the length is even
- */
- adapter->tx_pcb.command = CMD_TRANSMIT_PACKET;
- adapter->tx_pcb.length = sizeof(struct Xmit_pkt);
- adapter->tx_pcb.data.xmit_pkt.buf_ofs
- = adapter->tx_pcb.data.xmit_pkt.buf_seg = 0; /* Unused */
- adapter->tx_pcb.data.xmit_pkt.pkt_len = nlen;
-
- if (!send_pcb(dev, &adapter->tx_pcb)) {
- adapter->busy = 0;
- return false;
- }
- /* if this happens, we die */
- if (test_and_set_bit(0, (void *) &adapter->dmaing))
- pr_debug("%s: tx: DMA %d in progress\n", dev->name, adapter->current_dma.direction);
-
- adapter->current_dma.direction = 1;
- adapter->current_dma.start_time = jiffies;
-
- if ((unsigned long)(skb->data + nlen) >= MAX_DMA_ADDRESS || nlen != skb->len) {
- skb_copy_from_linear_data(skb, adapter->dma_buffer, nlen);
- memset(adapter->dma_buffer+skb->len, 0, nlen-skb->len);
- target = isa_virt_to_bus(adapter->dma_buffer);
- }
- else {
- target = isa_virt_to_bus(skb->data);
- }
- adapter->current_dma.skb = skb;
-
- flags=claim_dma_lock();
- disable_dma(dev->dma);
- clear_dma_ff(dev->dma);
- set_dma_mode(dev->dma, 0x48); /* dma memory -> io */
- set_dma_addr(dev->dma, target);
- set_dma_count(dev->dma, nlen);
- outb_control(adapter->hcr_val | DMAE | TCEN, dev);
- enable_dma(dev->dma);
- release_dma_lock(flags);
-
- if (elp_debug >= 3)
- pr_debug("%s: DMA transfer started\n", dev->name);
-
- return true;
-}
-
-/*
- * The upper layer thinks we timed out
- */
-
-static void elp_timeout(struct net_device *dev)
-{
- int stat;
-
- stat = inb_status(dev->base_addr);
- pr_warning("%s: transmit timed out, lost %s?\n", dev->name,
- (stat & ACRF) ? "interrupt" : "command");
- if (elp_debug >= 1)
- pr_debug("%s: status %#02x\n", dev->name, stat);
- dev->trans_start = jiffies; /* prevent tx timeout */
- dev->stats.tx_dropped++;
- netif_wake_queue(dev);
-}
-
-/******************************************************
- *
- * start the transmitter
- * return 0 if sent OK, else return 1
- *
- ******************************************************/
-
-static netdev_tx_t elp_start_xmit(struct sk_buff *skb, struct net_device *dev)
-{
- unsigned long flags;
- elp_device *adapter = netdev_priv(dev);
-
- spin_lock_irqsave(&adapter->lock, flags);
- check_3c505_dma(dev);
-
- if (elp_debug >= 3)
- pr_debug("%s: request to send packet of length %d\n", dev->name, (int) skb->len);
-
- netif_stop_queue(dev);
-
- /*
- * send the packet at skb->data for skb->len
- */
- if (!send_packet(dev, skb)) {
- if (elp_debug >= 2) {
- pr_debug("%s: failed to transmit packet\n", dev->name);
- }
- spin_unlock_irqrestore(&adapter->lock, flags);
- return NETDEV_TX_BUSY;
- }
- if (elp_debug >= 3)
- pr_debug("%s: packet of length %d sent\n", dev->name, (int) skb->len);
-
- prime_rx(dev);
- spin_unlock_irqrestore(&adapter->lock, flags);
- netif_start_queue(dev);
- return NETDEV_TX_OK;
-}
-
-/******************************************************
- *
- * return statistics on the board
- *
- ******************************************************/
-
-static struct net_device_stats *elp_get_stats(struct net_device *dev)
-{
- elp_device *adapter = netdev_priv(dev);
-
- if (elp_debug >= 3)
- pr_debug("%s: request for stats\n", dev->name);
-
- /* If the device is closed, just return the latest stats we have,
- - we cannot ask from the adapter without interrupts */
- if (!netif_running(dev))
- return &dev->stats;
-
- /* send a get statistics command to the board */
- adapter->tx_pcb.command = CMD_NETWORK_STATISTICS;
- adapter->tx_pcb.length = 0;
- adapter->got[CMD_NETWORK_STATISTICS] = 0;
- if (!send_pcb(dev, &adapter->tx_pcb))
- pr_err("%s: couldn't send get statistics command\n", dev->name);
- else {
- unsigned long timeout = jiffies + TIMEOUT;
- while (adapter->got[CMD_NETWORK_STATISTICS] == 0 && time_before(jiffies, timeout));
- if (time_after_eq(jiffies, timeout)) {
- TIMEOUT_MSG(__LINE__);
- return &dev->stats;
- }
- }
-
- /* statistics are now up to date */
- return &dev->stats;
-}
-
-
-static void netdev_get_drvinfo(struct net_device *dev,
- struct ethtool_drvinfo *info)
-{
- strlcpy(info->driver, DRV_NAME, sizeof(info->driver));
- strlcpy(info->version, DRV_VERSION, sizeof(info->version));
- snprintf(info->bus_info, sizeof(info->bus_info), "ISA 0x%lx",
- dev->base_addr);
-}
-
-static u32 netdev_get_msglevel(struct net_device *dev)
-{
- return debug;
-}
-
-static void netdev_set_msglevel(struct net_device *dev, u32 level)
-{
- debug = level;
-}
-
-static const struct ethtool_ops netdev_ethtool_ops = {
- .get_drvinfo = netdev_get_drvinfo,
- .get_msglevel = netdev_get_msglevel,
- .set_msglevel = netdev_set_msglevel,
-};
-
-/******************************************************
- *
- * close the board
- *
- ******************************************************/
-
-static int elp_close(struct net_device *dev)
-{
- elp_device *adapter = netdev_priv(dev);
-
- if (elp_debug >= 3)
- pr_debug("%s: request to close device\n", dev->name);
-
- netif_stop_queue(dev);
-
- /* Someone may request the device statistic information even when
- * the interface is closed. The following will update the statistics
- * structure in the driver, so we'll be able to give current statistics.
- */
- (void) elp_get_stats(dev);
-
- /*
- * disable interrupts on the board
- */
- outb_control(0, dev);
-
- /*
- * release the IRQ
- */
- free_irq(dev->irq, dev);
-
- free_dma(dev->dma);
- free_pages((unsigned long) adapter->dma_buffer, get_order(DMA_BUFFER_SIZE));
-
- return 0;
-}
-
-
-/************************************************************
- *
- * Set multicast list
- * num_addrs==0: clear mc_list
- * num_addrs==-1: set promiscuous mode
- * num_addrs>0: set mc_list
- *
- ************************************************************/
-
-static void elp_set_mc_list(struct net_device *dev)
-{
- elp_device *adapter = netdev_priv(dev);
- struct netdev_hw_addr *ha;
- int i;
- unsigned long flags;
-
- if (elp_debug >= 3)
- pr_debug("%s: request to set multicast list\n", dev->name);
-
- spin_lock_irqsave(&adapter->lock, flags);
-
- if (!(dev->flags & (IFF_PROMISC | IFF_ALLMULTI))) {
- /* send a "load multicast list" command to the board, max 10 addrs/cmd */
- /* if num_addrs==0 the list will be cleared */
- adapter->tx_pcb.command = CMD_LOAD_MULTICAST_LIST;
- adapter->tx_pcb.length = 6 * netdev_mc_count(dev);
- i = 0;
- netdev_for_each_mc_addr(ha, dev)
- memcpy(adapter->tx_pcb.data.multicast[i++],
- ha->addr, 6);
- adapter->got[CMD_LOAD_MULTICAST_LIST] = 0;
- if (!send_pcb(dev, &adapter->tx_pcb))
- pr_err("%s: couldn't send set_multicast command\n", dev->name);
- else {
- unsigned long timeout = jiffies + TIMEOUT;
- while (adapter->got[CMD_LOAD_MULTICAST_LIST] == 0 && time_before(jiffies, timeout));
- if (time_after_eq(jiffies, timeout)) {
- TIMEOUT_MSG(__LINE__);
- }
- }
- if (!netdev_mc_empty(dev))
- adapter->tx_pcb.data.configure = NO_LOOPBACK | RECV_BROAD | RECV_MULTI;
- else /* num_addrs == 0 */
- adapter->tx_pcb.data.configure = NO_LOOPBACK | RECV_BROAD;
- } else
- adapter->tx_pcb.data.configure = NO_LOOPBACK | RECV_PROMISC;
- /*
- * configure adapter to receive messages (as specified above)
- * and wait for response
- */
- if (elp_debug >= 3)
- pr_debug("%s: sending 82586 configure command\n", dev->name);
- adapter->tx_pcb.command = CMD_CONFIGURE_82586;
- adapter->tx_pcb.length = 2;
- adapter->got[CMD_CONFIGURE_82586] = 0;
- if (!send_pcb(dev, &adapter->tx_pcb))
- {
- spin_unlock_irqrestore(&adapter->lock, flags);
- pr_err("%s: couldn't send 82586 configure command\n", dev->name);
- }
- else {
- unsigned long timeout = jiffies + TIMEOUT;
- spin_unlock_irqrestore(&adapter->lock, flags);
- while (adapter->got[CMD_CONFIGURE_82586] == 0 && time_before(jiffies, timeout));
- if (time_after_eq(jiffies, timeout))
- TIMEOUT_MSG(__LINE__);
- }
-}
-
-/************************************************************
- *
- * A couple of tests to see if there's 3C505 or not
- * Called only by elp_autodetect
- ************************************************************/
-
-static int __init elp_sense(struct net_device *dev)
-{
- int addr = dev->base_addr;
- const char *name = dev->name;
- byte orig_HSR;
-
- if (!request_region(addr, ELP_IO_EXTENT, "3c505"))
- return -ENODEV;
-
- orig_HSR = inb_status(addr);
-
- if (elp_debug > 0)
- pr_debug(search_msg, name, addr);
-
- if (orig_HSR == 0xff) {
- if (elp_debug > 0)
- pr_cont(notfound_msg, 1);
- goto out;
- }
-
- /* Wait for a while; the adapter may still be booting up */
- if (elp_debug > 0)
- pr_cont(stilllooking_msg);
-
- if (orig_HSR & DIR) {
- /* If HCR.DIR is up, we pull it down. HSR.DIR should follow. */
- outb(0, dev->base_addr + PORT_CONTROL);
- msleep(300);
- if (inb_status(addr) & DIR) {
- if (elp_debug > 0)
- pr_cont(notfound_msg, 2);
- goto out;
- }
- } else {
- /* If HCR.DIR is down, we pull it up. HSR.DIR should follow. */
- outb(DIR, dev->base_addr + PORT_CONTROL);
- msleep(300);
- if (!(inb_status(addr) & DIR)) {
- if (elp_debug > 0)
- pr_cont(notfound_msg, 3);
- goto out;
- }
- }
- /*
- * It certainly looks like a 3c505.
- */
- if (elp_debug > 0)
- pr_cont(found_msg);
-
- return 0;
-out:
- release_region(addr, ELP_IO_EXTENT);
- return -ENODEV;
-}
-
-/*************************************************************
- *
- * Search through addr_list[] and try to find a 3C505
- * Called only by eplus_probe
- *************************************************************/
-
-static int __init elp_autodetect(struct net_device *dev)
-{
- int idx = 0;
-
- /* if base address set, then only check that address
- otherwise, run through the table */
- if (dev->base_addr != 0) { /* dev->base_addr == 0 ==> plain autodetect */
- if (elp_sense(dev) == 0)
- return dev->base_addr;
- } else
- while ((dev->base_addr = addr_list[idx++])) {
- if (elp_sense(dev) == 0)
- return dev->base_addr;
- }
-
- /* could not find an adapter */
- if (elp_debug > 0)
- pr_debug(couldnot_msg, dev->name);
-
- return 0; /* Because of this, the layer above will return -ENODEV */
-}
-
-static const struct net_device_ops elp_netdev_ops = {
- .ndo_open = elp_open,
- .ndo_stop = elp_close,
- .ndo_get_stats = elp_get_stats,
- .ndo_start_xmit = elp_start_xmit,
- .ndo_tx_timeout = elp_timeout,
- .ndo_set_rx_mode = elp_set_mc_list,
- .ndo_change_mtu = eth_change_mtu,
- .ndo_set_mac_address = eth_mac_addr,
- .ndo_validate_addr = eth_validate_addr,
-};
-
-/******************************************************
- *
- * probe for an Etherlink Plus board at the specified address
- *
- ******************************************************/
-
-/* There are three situations we need to be able to detect here:
-
- * a) the card is idle
- * b) the card is still booting up
- * c) the card is stuck in a strange state (some DOS drivers do this)
- *
- * In case (a), all is well. In case (b), we wait 10 seconds to see if the
- * card finishes booting, and carry on if so. In case (c), we do a hard reset,
- * loop round, and hope for the best.
- *
- * This is all very unpleasant, but hopefully avoids the problems with the old
- * probe code (which had a 15-second delay if the card was idle, and didn't
- * work at all if it was in a weird state).
- */
-
-static int __init elplus_setup(struct net_device *dev)
-{
- elp_device *adapter = netdev_priv(dev);
- int i, tries, tries1, okay;
- unsigned long timeout;
- unsigned long cookie = 0;
- int err = -ENODEV;
-
- /*
- * setup adapter structure
- */
-
- dev->base_addr = elp_autodetect(dev);
- if (!dev->base_addr)
- return -ENODEV;
-
- adapter->send_pcb_semaphore = 0;
-
- for (tries1 = 0; tries1 < 3; tries1++) {
- outb_control((adapter->hcr_val | CMDE) & ~DIR, dev);
- /* First try to write just one byte, to see if the card is
- * responding at all normally.
- */
- timeout = jiffies + 5*HZ/100;
- okay = 0;
- while (time_before(jiffies, timeout) && !(inb_status(dev->base_addr) & HCRE));
- if ((inb_status(dev->base_addr) & HCRE)) {
- outb_command(0, dev->base_addr); /* send a spurious byte */
- timeout = jiffies + 5*HZ/100;
- while (time_before(jiffies, timeout) && !(inb_status(dev->base_addr) & HCRE));
- if (inb_status(dev->base_addr) & HCRE)
- okay = 1;
- }
- if (!okay) {
- /* Nope, it's ignoring the command register. This means that
- * either it's still booting up, or it's died.
- */
- pr_err("%s: command register wouldn't drain, ", dev->name);
- if ((inb_status(dev->base_addr) & 7) == 3) {
- /* If the adapter status is 3, it *could* still be booting.
- * Give it the benefit of the doubt for 10 seconds.
- */
- pr_cont("assuming 3c505 still starting\n");
- timeout = jiffies + 10*HZ;
- while (time_before(jiffies, timeout) && (inb_status(dev->base_addr) & 7));
- if (inb_status(dev->base_addr) & 7) {
- pr_err("%s: 3c505 failed to start\n", dev->name);
- } else {
- okay = 1; /* It started */
- }
- } else {
- /* Otherwise, it must just be in a strange
- * state. We probably need to kick it.
- */
- pr_cont("3c505 is sulking\n");
- }
- }
- for (tries = 0; tries < 5 && okay; tries++) {
-
- /*
- * Try to set the Ethernet address, to make sure that the board
- * is working.
- */
- adapter->tx_pcb.command = CMD_STATION_ADDRESS;
- adapter->tx_pcb.length = 0;
- cookie = probe_irq_on();
- if (!send_pcb(dev, &adapter->tx_pcb)) {
- pr_err("%s: could not send first PCB\n", dev->name);
- probe_irq_off(cookie);
- continue;
- }
- if (!receive_pcb(dev, &adapter->rx_pcb)) {
- pr_err("%s: could not read first PCB\n", dev->name);
- probe_irq_off(cookie);
- continue;
- }
- if ((adapter->rx_pcb.command != CMD_ADDRESS_RESPONSE) ||
- (adapter->rx_pcb.length != 6)) {
- pr_err("%s: first PCB wrong (%d, %d)\n", dev->name,
- adapter->rx_pcb.command, adapter->rx_pcb.length);
- probe_irq_off(cookie);
- continue;
- }
- goto okay;
- }
- /* It's broken. Do a hard reset to re-initialise the board,
- * and try again.
- */
- pr_info("%s: resetting adapter\n", dev->name);
- outb_control(adapter->hcr_val | FLSH | ATTN, dev);
- outb_control(adapter->hcr_val & ~(FLSH | ATTN), dev);
- }
- pr_err("%s: failed to initialise 3c505\n", dev->name);
- goto out;
-
- okay:
- if (dev->irq) { /* Is there a preset IRQ? */
- int rpt = probe_irq_off(cookie);
- if (dev->irq != rpt) {
- pr_warning("%s: warning, irq %d configured but %d detected\n", dev->name, dev->irq, rpt);
- }
- /* if dev->irq == probe_irq_off(cookie), all is well */
- } else /* No preset IRQ; just use what we can detect */
- dev->irq = probe_irq_off(cookie);
- switch (dev->irq) { /* Legal, sane? */
- case 0:
- pr_err("%s: IRQ probe failed: check 3c505 jumpers.\n",
- dev->name);
- goto out;
- case 1:
- case 6:
- case 8:
- case 13:
- pr_err("%s: Impossible IRQ %d reported by probe_irq_off().\n",
- dev->name, dev->irq);
- goto out;
- }
- /*
- * Now we have the IRQ number so we can disable the interrupts from
- * the board until the board is opened.
- */
- outb_control(adapter->hcr_val & ~CMDE, dev);
-
- /*
- * copy Ethernet address into structure
- */
- for (i = 0; i < 6; i++)
- dev->dev_addr[i] = adapter->rx_pcb.data.eth_addr[i];
-
- /* find a DMA channel */
- if (!dev->dma) {
- if (dev->mem_start) {
- dev->dma = dev->mem_start & 7;
- }
- else {
- pr_warning("%s: warning, DMA channel not specified, using default\n", dev->name);
- dev->dma = ELP_DMA;
- }
- }
-
- /*
- * print remainder of startup message
- */
- pr_info("%s: 3c505 at %#lx, irq %d, dma %d, addr %pM, ",
- dev->name, dev->base_addr, dev->irq, dev->dma, dev->dev_addr);
- /*
- * read more information from the adapter
- */
-
- adapter->tx_pcb.command = CMD_ADAPTER_INFO;
- adapter->tx_pcb.length = 0;
- if (!send_pcb(dev, &adapter->tx_pcb) ||
- !receive_pcb(dev, &adapter->rx_pcb) ||
- (adapter->rx_pcb.command != CMD_ADAPTER_INFO_RESPONSE) ||
- (adapter->rx_pcb.length != 10)) {
- pr_cont("not responding to second PCB\n");
- }
- pr_cont("rev %d.%d, %dk\n", adapter->rx_pcb.data.info.major_vers,
- adapter->rx_pcb.data.info.minor_vers, adapter->rx_pcb.data.info.RAM_sz);
-
- /*
- * reconfigure the adapter memory to better suit our purposes
- */
- adapter->tx_pcb.command = CMD_CONFIGURE_ADAPTER_MEMORY;
- adapter->tx_pcb.length = 12;
- adapter->tx_pcb.data.memconf.cmd_q = 8;
- adapter->tx_pcb.data.memconf.rcv_q = 8;
- adapter->tx_pcb.data.memconf.mcast = 10;
- adapter->tx_pcb.data.memconf.frame = 10;
- adapter->tx_pcb.data.memconf.rcv_b = 10;
- adapter->tx_pcb.data.memconf.progs = 0;
- if (!send_pcb(dev, &adapter->tx_pcb) ||
- !receive_pcb(dev, &adapter->rx_pcb) ||
- (adapter->rx_pcb.command != CMD_CONFIGURE_ADAPTER_RESPONSE) ||
- (adapter->rx_pcb.length != 2)) {
- pr_err("%s: could not configure adapter memory\n", dev->name);
- }
- if (adapter->rx_pcb.data.configure) {
- pr_err("%s: adapter configuration failed\n", dev->name);
- }
-
- dev->netdev_ops = &elp_netdev_ops;
- dev->watchdog_timeo = 10*HZ;
- dev->ethtool_ops = &netdev_ethtool_ops; /* local */
-
- dev->mem_start = dev->mem_end = 0;
-
- err = register_netdev(dev);
- if (err)
- goto out;
-
- return 0;
-out:
- release_region(dev->base_addr, ELP_IO_EXTENT);
- return err;
-}
-
-#ifndef MODULE
-struct net_device * __init elplus_probe(int unit)
-{
- struct net_device *dev = alloc_etherdev(sizeof(elp_device));
- int err;
- if (!dev)
- return ERR_PTR(-ENOMEM);
-
- sprintf(dev->name, "eth%d", unit);
- netdev_boot_setup_check(dev);
-
- err = elplus_setup(dev);
- if (err) {
- free_netdev(dev);
- return ERR_PTR(err);
- }
- return dev;
-}
-
-#else
-static struct net_device *dev_3c505[ELP_MAX_CARDS];
-static int io[ELP_MAX_CARDS];
-static int irq[ELP_MAX_CARDS];
-static int dma[ELP_MAX_CARDS];
-module_param_array(io, int, NULL, 0);
-module_param_array(irq, int, NULL, 0);
-module_param_array(dma, int, NULL, 0);
-MODULE_PARM_DESC(io, "EtherLink Plus I/O base address(es)");
-MODULE_PARM_DESC(irq, "EtherLink Plus IRQ number(s) (assigned)");
-MODULE_PARM_DESC(dma, "EtherLink Plus DMA channel(s)");
-
-int __init init_module(void)
-{
- int this_dev, found = 0;
-
- for (this_dev = 0; this_dev < ELP_MAX_CARDS; this_dev++) {
- struct net_device *dev = alloc_etherdev(sizeof(elp_device));
- if (!dev)
- break;
-
- dev->irq = irq[this_dev];
- dev->base_addr = io[this_dev];
- if (dma[this_dev]) {
- dev->dma = dma[this_dev];
- } else {
- dev->dma = ELP_DMA;
- pr_warning("3c505.c: warning, using default DMA channel,\n");
- }
- if (io[this_dev] == 0) {
- if (this_dev) {
- free_netdev(dev);
- break;
- }
- pr_notice("3c505.c: module autoprobe not recommended, give io=xx.\n");
- }
- if (elplus_setup(dev) != 0) {
- pr_warning("3c505.c: Failed to register card at 0x%x.\n", io[this_dev]);
- free_netdev(dev);
- break;
- }
- dev_3c505[this_dev] = dev;
- found++;
- }
- if (!found)
- return -ENODEV;
- return 0;
-}
-
-void __exit cleanup_module(void)
-{
- int this_dev;
-
- for (this_dev = 0; this_dev < ELP_MAX_CARDS; this_dev++) {
- struct net_device *dev = dev_3c505[this_dev];
- if (dev) {
- unregister_netdev(dev);
- release_region(dev->base_addr, ELP_IO_EXTENT);
- free_netdev(dev);
- }
- }
-}
-
-#endif /* MODULE */
-MODULE_LICENSE("GPL");
diff --git a/drivers/net/ethernet/i825xx/3c505.h b/drivers/net/ethernet/i825xx/3c505.h
deleted file mode 100644
index 04df2a9002b..00000000000
--- a/drivers/net/ethernet/i825xx/3c505.h
+++ /dev/null
@@ -1,292 +0,0 @@
-/*****************************************************************
- *
- * defines for 3Com Etherlink Plus adapter
- *
- *****************************************************************/
-
-#define ELP_DMA 6
-#define ELP_RX_PCBS 4
-#define ELP_MAX_CARDS 4
-
-/*
- * I/O register offsets
- */
-#define PORT_COMMAND 0x00 /* read/write, 8-bit */
-#define PORT_STATUS 0x02 /* read only, 8-bit */
-#define PORT_AUXDMA 0x02 /* write only, 8-bit */
-#define PORT_DATA 0x04 /* read/write, 16-bit */
-#define PORT_CONTROL 0x06 /* read/write, 8-bit */
-
-#define ELP_IO_EXTENT 0x10 /* size of used IO registers */
-
-/*
- * host control registers bits
- */
-#define ATTN 0x80 /* attention */
-#define FLSH 0x40 /* flush data register */
-#define DMAE 0x20 /* DMA enable */
-#define DIR 0x10 /* direction */
-#define TCEN 0x08 /* terminal count interrupt enable */
-#define CMDE 0x04 /* command register interrupt enable */
-#define HSF2 0x02 /* host status flag 2 */
-#define HSF1 0x01 /* host status flag 1 */
-
-/*
- * combinations of HSF flags used for PCB transmission
- */
-#define HSF_PCB_ACK HSF1
-#define HSF_PCB_NAK HSF2
-#define HSF_PCB_END (HSF2|HSF1)
-#define HSF_PCB_MASK (HSF2|HSF1)
-
-/*
- * host status register bits
- */
-#define HRDY 0x80 /* data register ready */
-#define HCRE 0x40 /* command register empty */
-#define ACRF 0x20 /* adapter command register full */
-/* #define DIR 0x10 direction - same as in control register */
-#define DONE 0x08 /* DMA done */
-#define ASF3 0x04 /* adapter status flag 3 */
-#define ASF2 0x02 /* adapter status flag 2 */
-#define ASF1 0x01 /* adapter status flag 1 */
-
-/*
- * combinations of ASF flags used for PCB reception
- */
-#define ASF_PCB_ACK ASF1
-#define ASF_PCB_NAK ASF2
-#define ASF_PCB_END (ASF2|ASF1)
-#define ASF_PCB_MASK (ASF2|ASF1)
-
-/*
- * host aux DMA register bits
- */
-#define DMA_BRST 0x01 /* DMA burst */
-
-/*
- * maximum amount of data allowed in a PCB
- */
-#define MAX_PCB_DATA 62
-
-/*****************************************************************
- *
- * timeout value
- * this is a rough value used for loops to stop them from
- * locking up the whole machine in the case of failure or
- * error conditions
- *
- *****************************************************************/
-
-#define TIMEOUT 300
-
-/*****************************************************************
- *
- * PCB commands
- *
- *****************************************************************/
-
-enum {
- /*
- * host PCB commands
- */
- CMD_CONFIGURE_ADAPTER_MEMORY = 0x01,
- CMD_CONFIGURE_82586 = 0x02,
- CMD_STATION_ADDRESS = 0x03,
- CMD_DMA_DOWNLOAD = 0x04,
- CMD_DMA_UPLOAD = 0x05,
- CMD_PIO_DOWNLOAD = 0x06,
- CMD_PIO_UPLOAD = 0x07,
- CMD_RECEIVE_PACKET = 0x08,
- CMD_TRANSMIT_PACKET = 0x09,
- CMD_NETWORK_STATISTICS = 0x0a,
- CMD_LOAD_MULTICAST_LIST = 0x0b,
- CMD_CLEAR_PROGRAM = 0x0c,
- CMD_DOWNLOAD_PROGRAM = 0x0d,
- CMD_EXECUTE_PROGRAM = 0x0e,
- CMD_SELF_TEST = 0x0f,
- CMD_SET_STATION_ADDRESS = 0x10,
- CMD_ADAPTER_INFO = 0x11,
- NUM_TRANSMIT_CMDS,
-
- /*
- * adapter PCB commands
- */
- CMD_CONFIGURE_ADAPTER_RESPONSE = 0x31,
- CMD_CONFIGURE_82586_RESPONSE = 0x32,
- CMD_ADDRESS_RESPONSE = 0x33,
- CMD_DOWNLOAD_DATA_REQUEST = 0x34,
- CMD_UPLOAD_DATA_REQUEST = 0x35,
- CMD_RECEIVE_PACKET_COMPLETE = 0x38,
- CMD_TRANSMIT_PACKET_COMPLETE = 0x39,
- CMD_NETWORK_STATISTICS_RESPONSE = 0x3a,
- CMD_LOAD_MULTICAST_RESPONSE = 0x3b,
- CMD_CLEAR_PROGRAM_RESPONSE = 0x3c,
- CMD_DOWNLOAD_PROGRAM_RESPONSE = 0x3d,
- CMD_EXECUTE_RESPONSE = 0x3e,
- CMD_SELF_TEST_RESPONSE = 0x3f,
- CMD_SET_ADDRESS_RESPONSE = 0x40,
- CMD_ADAPTER_INFO_RESPONSE = 0x41
-};
-
-/* Definitions for the PCB data structure */
-
-/* Data units */
-typedef unsigned char byte;
-typedef unsigned short int word;
-typedef unsigned long int dword;
-
-/* Data structures */
-struct Memconf {
- word cmd_q,
- rcv_q,
- mcast,
- frame,
- rcv_b,
- progs;
-};
-
-struct Rcv_pkt {
- word buf_ofs,
- buf_seg,
- buf_len,
- timeout;
-};
-
-struct Xmit_pkt {
- word buf_ofs,
- buf_seg,
- pkt_len;
-};
-
-struct Rcv_resp {
- word buf_ofs,
- buf_seg,
- buf_len,
- pkt_len,
- timeout,
- status;
- dword timetag;
-};
-
-struct Xmit_resp {
- word buf_ofs,
- buf_seg,
- c_stat,
- status;
-};
-
-
-struct Netstat {
- dword tot_recv,
- tot_xmit;
- word err_CRC,
- err_align,
- err_res,
- err_ovrrun;
-};
-
-
-struct Selftest {
- word error;
- union {
- word ROM_cksum;
- struct {
- word ofs, seg;
- } RAM;
- word i82586;
- } failure;
-};
-
-struct Info {
- byte minor_vers,
- major_vers;
- word ROM_cksum,
- RAM_sz,
- free_ofs,
- free_seg;
-};
-
-struct Memdump {
- word size,
- off,
- seg;
-};
-
-/*
-Primary Command Block. The most important data structure. All communication
-between the host and the adapter is done with these. (Except for the actual
-Ethernet data, which has different packaging.)
-*/
-typedef struct {
- byte command;
- byte length;
- union {
- struct Memconf memconf;
- word configure;
- struct Rcv_pkt rcv_pkt;
- struct Xmit_pkt xmit_pkt;
- byte multicast[10][6];
- byte eth_addr[6];
- byte failed;
- struct Rcv_resp rcv_resp;
- struct Xmit_resp xmit_resp;
- struct Netstat netstat;
- struct Selftest selftest;
- struct Info info;
- struct Memdump memdump;
- byte raw[62];
- } data;
-} pcb_struct;
-
-/* These defines for 'configure' */
-#define RECV_STATION 0x00
-#define RECV_BROAD 0x01
-#define RECV_MULTI 0x02
-#define RECV_PROMISC 0x04
-#define NO_LOOPBACK 0x00
-#define INT_LOOPBACK 0x08
-#define EXT_LOOPBACK 0x10
-
-/*****************************************************************
- *
- * structure to hold context information for adapter
- *
- *****************************************************************/
-
-#define DMA_BUFFER_SIZE 1600
-#define BACKLOG_SIZE 4
-
-typedef struct {
- volatile short got[NUM_TRANSMIT_CMDS]; /* flags for
- command completion */
- pcb_struct tx_pcb; /* PCB for foreground sending */
- pcb_struct rx_pcb; /* PCB for foreground receiving */
- pcb_struct itx_pcb; /* PCB for background sending */
- pcb_struct irx_pcb; /* PCB for background receiving */
-
- void *dma_buffer;
-
- struct {
- unsigned int length[BACKLOG_SIZE];
- unsigned int in;
- unsigned int out;
- } rx_backlog;
-
- struct {
- unsigned int direction;
- unsigned int length;
- struct sk_buff *skb;
- void *target;
- unsigned long start_time;
- } current_dma;
-
- /* flags */
- unsigned long send_pcb_semaphore;
- unsigned long dmaing;
- unsigned long busy;
-
- unsigned int rx_active; /* number of receive PCBs */
- volatile unsigned char hcr_val; /* what we think the HCR contains */
- spinlock_t lock; /* Interrupt v tx lock */
-} elp_device;
diff --git a/drivers/net/ethernet/i825xx/3c507.c b/drivers/net/ethernet/i825xx/3c507.c
deleted file mode 100644
index 13983ee6bcf..00000000000
--- a/drivers/net/ethernet/i825xx/3c507.c
+++ /dev/null
@@ -1,939 +0,0 @@
-/* 3c507.c: An EtherLink16 device driver for Linux. */
-/*
- Written 1993,1994 by Donald Becker.
-
- Copyright 1993 United States Government as represented by the
- Director, National Security Agency.
-
- This software may be used and distributed according to the terms
- of the GNU General Public License, incorporated herein by reference.
-
- The author may be reached as becker@scyld.com, or C/O
- Scyld Computing Corporation
- 410 Severn Ave., Suite 210
- Annapolis MD 21403
-
-
- Thanks go to jennings@Montrouge.SMR.slb.com ( Patrick Jennings)
- and jrs@world.std.com (Rick Sladkey) for testing and bugfixes.
- Mark Salazar <leslie@access.digex.net> made the changes for cards with
- only 16K packet buffers.
-
- Things remaining to do:
- Verify that the tx and rx buffers don't have fencepost errors.
- Move the theory of operation and memory map documentation.
- 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[] =
- DRV_NAME ".c:v" DRV_VERSION " " DRV_RELDATE " Donald Becker (becker@scyld.com)\n";
-
-/*
- Sources:
- This driver wouldn't have been written with the availability of the
- Crynwr driver source code. It provided a known-working implementation
- that filled in the gaping holes of the Intel documentation. Three cheers
- for Russ Nelson.
-
- Intel Microcommunications Databook, Vol. 1, 1990. It provides just enough
- info that the casual reader might think that it documents the i82586 :-<.
-*/
-
-#include <linux/module.h>
-#include <linux/kernel.h>
-#include <linux/types.h>
-#include <linux/fcntl.h>
-#include <linux/interrupt.h>
-#include <linux/ioport.h>
-#include <linux/in.h>
-#include <linux/string.h>
-#include <linux/spinlock.h>
-#include <linux/ethtool.h>
-#include <linux/errno.h>
-#include <linux/netdevice.h>
-#include <linux/etherdevice.h>
-#include <linux/if_ether.h>
-#include <linux/skbuff.h>
-#include <linux/init.h>
-#include <linux/bitops.h>
-
-#include <asm/dma.h>
-#include <asm/io.h>
-#include <asm/uaccess.h>
-
-/* use 0 for production, 1 for verification, 2..7 for debug */
-#ifndef NET_DEBUG
-#define NET_DEBUG 1
-#endif
-static unsigned int net_debug = NET_DEBUG;
-#define debug net_debug
-
-
-/*
- Details of the i82586.
-
- You'll really need the databook to understand the details of this part,
- but the outline is that the i82586 has two separate processing units.
- Both are started from a list of three configuration tables, of which only
- the last, the System Control Block (SCB), is used after reset-time. The SCB
- has the following fields:
- Status word
- Command word
- Tx/Command block addr.
- Rx block addr.
- The command word accepts the following controls for the Tx and Rx units:
- */
-
-#define CUC_START 0x0100
-#define CUC_RESUME 0x0200
-#define CUC_SUSPEND 0x0300
-#define RX_START 0x0010
-#define RX_RESUME 0x0020
-#define RX_SUSPEND 0x0030
-
-/* The Rx unit uses a list of frame descriptors and a list of data buffer
- descriptors. We use full-sized (1518 byte) data buffers, so there is
- a one-to-one pairing of frame descriptors to buffer descriptors.
-
- The Tx ("command") unit executes a list of commands that look like:
- Status word Written by the 82586 when the command is done.
- Command word Command in lower 3 bits, post-command action in upper 3
- Link word The address of the next command.
- Parameters (as needed).
-
- Some definitions related to the Command Word are:
- */
-#define CMD_EOL 0x8000 /* The last command of the list, stop. */
-#define CMD_SUSP 0x4000 /* Suspend after doing cmd. */
-#define CMD_INTR 0x2000 /* Interrupt after doing cmd. */
-
-enum commands {
- CmdNOp = 0, CmdSASetup = 1, CmdConfigure = 2, CmdMulticastList = 3,
- CmdTx = 4, CmdTDR = 5, CmdDump = 6, CmdDiagnose = 7};
-
-/* Information that need to be kept for each board. */
-struct net_local {
- int last_restart;
- ushort rx_head;
- ushort rx_tail;
- ushort tx_head;
- ushort tx_cmd_link;
- ushort tx_reap;
- ushort tx_pkts_in_ring;
- spinlock_t lock;
- void __iomem *base;
-};
-
-/*
- Details of the EtherLink16 Implementation
- The 3c507 is a generic shared-memory i82586 implementation.
- The host can map 16K, 32K, 48K, or 64K of the 64K memory into
- 0x0[CD][08]0000, or all 64K into 0xF[02468]0000.
- */
-
-/* Offsets from the base I/O address. */
-#define SA_DATA 0 /* Station address data, or 3Com signature. */
-#define MISC_CTRL 6 /* Switch the SA_DATA banks, and bus config bits. */
-#define RESET_IRQ 10 /* Reset the latched IRQ line. */
-#define SIGNAL_CA 11 /* Frob the 82586 Channel Attention line. */
-#define ROM_CONFIG 13
-#define MEM_CONFIG 14
-#define IRQ_CONFIG 15
-#define EL16_IO_EXTENT 16
-
-/* The ID port is used at boot-time to locate the ethercard. */
-#define ID_PORT 0x100
-
-/* Offsets to registers in the mailbox (SCB). */
-#define iSCB_STATUS 0x8
-#define iSCB_CMD 0xA
-#define iSCB_CBL 0xC /* Command BLock offset. */
-#define iSCB_RFA 0xE /* Rx Frame Area offset. */
-
-/* Since the 3c507 maps the shared memory window so that the last byte is
- at 82586 address FFFF, the first byte is at 82586 address 0, 16K, 32K, or
- 48K corresponding to window sizes of 64K, 48K, 32K and 16K respectively.
- We can account for this be setting the 'SBC Base' entry in the ISCP table
- below for all the 16 bit offset addresses, and also adding the 'SCB Base'
- value to all 24 bit physical addresses (in the SCP table and the TX and RX
- Buffer Descriptors).
- -Mark
- */
-#define SCB_BASE ((unsigned)64*1024 - (dev->mem_end - dev->mem_start))
-
-/*
- What follows in 'init_words[]' is the "program" that is downloaded to the
- 82586 memory. It's mostly tables and command blocks, and starts at the
- reset address 0xfffff6. This is designed to be similar to the EtherExpress,
- thus the unusual location of the SCB at 0x0008.
-
- Even with the additional "don't care" values, doing it this way takes less
- program space than initializing the individual tables, and I feel it's much
- cleaner.
-
- The databook is particularly useless for the first two structures, I had
- to use the Crynwr driver as an example.
-
- The memory setup is as follows:
- */
-
-#define CONFIG_CMD 0x0018
-#define SET_SA_CMD 0x0024
-#define SA_OFFSET 0x002A
-#define IDLELOOP 0x30
-#define TDR_CMD 0x38
-#define TDR_TIME 0x3C
-#define DUMP_CMD 0x40
-#define DIAG_CMD 0x48
-#define SET_MC_CMD 0x4E
-#define DUMP_DATA 0x56 /* A 170 byte buffer for dump and Set-MC into. */
-
-#define TX_BUF_START 0x0100
-#define NUM_TX_BUFS 5
-#define TX_BUF_SIZE (1518+14+20+16) /* packet+header+TBD */
-
-#define RX_BUF_START 0x2000
-#define RX_BUF_SIZE (1518+14+18) /* packet+header+RBD */
-#define RX_BUF_END (dev->mem_end - dev->mem_start)
-
-#define TX_TIMEOUT (HZ/20)
-
-/*
- That's it: only 86 bytes to set up the beast, including every extra
- command available. The 170 byte buffer at DUMP_DATA is shared between the
- Dump command (called only by the diagnostic program) and the SetMulticastList
- command.
-
- To complete the memory setup you only have to write the station address at
- SA_OFFSET and create the Tx & Rx buffer lists.
-
- The Tx command chain and buffer list is setup as follows:
- A Tx command table, with the data buffer pointing to...
- A Tx data buffer descriptor. The packet is in a single buffer, rather than
- chaining together several smaller buffers.
- A NoOp command, which initially points to itself,
- And the packet data.
-
- A transmit is done by filling in the Tx command table and data buffer,
- re-writing the NoOp command, and finally changing the offset of the last
- command to point to the current Tx command. When the Tx command is finished,
- it jumps to the NoOp, when it loops until the next Tx command changes the
- "link offset" in the NoOp. This way the 82586 never has to go through the
- slow restart sequence.
-
- The Rx buffer list is set up in the obvious ring structure. We have enough
- memory (and low enough interrupt latency) that we can avoid the complicated
- Rx buffer linked lists by alway associating a full-size Rx data buffer with
- each Rx data frame.
-
- I current use four transmit buffers starting at TX_BUF_START (0x0100), and
- use the rest of memory, from RX_BUF_START to RX_BUF_END, for Rx buffers.
-
- */
-
-static unsigned short init_words[] = {
- /* System Configuration Pointer (SCP). */
- 0x0000, /* Set bus size to 16 bits. */
- 0,0, /* pad words. */
- 0x0000,0x0000, /* ISCP phys addr, set in init_82586_mem(). */
-
- /* Intermediate System Configuration Pointer (ISCP). */
- 0x0001, /* Status word that's cleared when init is done. */
- 0x0008,0,0, /* SCB offset, (skip, skip) */
-
- /* System Control Block (SCB). */
- 0,0xf000|RX_START|CUC_START, /* SCB status and cmd. */
- CONFIG_CMD, /* Command list pointer, points to Configure. */
- RX_BUF_START, /* Rx block list. */
- 0,0,0,0, /* Error count: CRC, align, buffer, overrun. */
-
- /* 0x0018: Configure command. Change to put MAC data with packet. */
- 0, CmdConfigure, /* Status, command. */
- SET_SA_CMD, /* Next command is Set Station Addr. */
- 0x0804, /* "4" bytes of config data, 8 byte FIFO. */
- 0x2e40, /* Magic values, including MAC data location. */
- 0, /* Unused pad word. */
-
- /* 0x0024: Setup station address command. */
- 0, CmdSASetup,
- SET_MC_CMD, /* Next command. */
- 0xaa00,0xb000,0x0bad, /* Station address (to be filled in) */
-
- /* 0x0030: NOP, looping back to itself. Point to first Tx buffer to Tx. */
- 0, CmdNOp, IDLELOOP, 0 /* pad */,
-
- /* 0x0038: A unused Time-Domain Reflectometer command. */
- 0, CmdTDR, IDLELOOP, 0,
-
- /* 0x0040: An unused Dump State command. */
- 0, CmdDump, IDLELOOP, DUMP_DATA,
-
- /* 0x0048: An unused Diagnose command. */
- 0, CmdDiagnose, IDLELOOP,
-
- /* 0x004E: An empty set-multicast-list command. */
- 0, CmdMulticastList, IDLELOOP, 0,
-};
-
-/* Index to functions, as function prototypes. */
-
-static int el16_probe1(struct net_device *dev, int ioaddr);
-static int el16_open(struct net_device *dev);
-static netdev_tx_t el16_send_packet(struct sk_buff *skb,
- struct net_device *dev);
-static irqreturn_t el16_interrupt(int irq, void *dev_id);
-static void el16_rx(struct net_device *dev);
-static int el16_close(struct net_device *dev);
-static void el16_tx_timeout (struct net_device *dev);
-
-static void hardware_send_packet(struct net_device *dev, void *buf, short length, short pad);
-static void init_82586_mem(struct net_device *dev);
-static const struct ethtool_ops netdev_ethtool_ops;
-static void init_rx_bufs(struct net_device *);
-
-static int io = 0x300;
-static int irq;
-static int mem_start;
-
-
-/* Check for a network adaptor of this type, and return '0' iff one exists.
- If dev->base_addr == 0, probe all likely locations.
- If dev->base_addr == 1, always return failure.
- If dev->base_addr == 2, (detachable devices only) allocate space for the
- device and return success.
- */
-
-struct net_device * __init el16_probe(int unit)
-{
- struct net_device *dev = alloc_etherdev(sizeof(struct net_local));
- static const unsigned ports[] = { 0x300, 0x320, 0x340, 0x280, 0};
- const unsigned *port;
- int err = -ENODEV;
-
- if (!dev)
- return ERR_PTR(-ENODEV);
-
- if (unit >= 0) {
- sprintf(dev->name, "eth%d", unit);
- netdev_boot_setup_check(dev);
- io = dev->base_addr;
- irq = dev->irq;
- mem_start = dev->mem_start & 15;
- }
-
- if (io > 0x1ff) /* Check a single specified location. */
- err = el16_probe1(dev, io);
- else if (io != 0)
- err = -ENXIO; /* Don't probe at all. */
- else {
- for (port = ports; *port; port++) {
- err = el16_probe1(dev, *port);
- if (!err)
- break;
- }
- }
-
- if (err)
- goto out;
- err = register_netdev(dev);
- if (err)
- goto out1;
- return dev;
-out1:
- free_irq(dev->irq, dev);
- iounmap(((struct net_local *)netdev_priv(dev))->base);
- release_region(dev->base_addr, EL16_IO_EXTENT);
-out:
- free_netdev(dev);
- return ERR_PTR(err);
-}
-
-static const struct net_device_ops netdev_ops = {
- .ndo_open = el16_open,
- .ndo_stop = el16_close,
- .ndo_start_xmit = el16_send_packet,
- .ndo_tx_timeout = el16_tx_timeout,
- .ndo_change_mtu = eth_change_mtu,
- .ndo_set_mac_address = eth_mac_addr,
- .ndo_validate_addr = eth_validate_addr,
-};
-
-static int __init el16_probe1(struct net_device *dev, int ioaddr)
-{
- static unsigned char init_ID_done;
- int i, irq, irqval, retval;
- struct net_local *lp;
-
- if (init_ID_done == 0) {
- ushort lrs_state = 0xff;
- /* Send the ID sequence to the ID_PORT to enable the board(s). */
- outb(0x00, ID_PORT);
- for(i = 0; i < 255; i++) {
- outb(lrs_state, ID_PORT);
- lrs_state <<= 1;
- if (lrs_state & 0x100)
- lrs_state ^= 0xe7;
- }
- outb(0x00, ID_PORT);
- init_ID_done = 1;
- }
-
- if (!request_region(ioaddr, EL16_IO_EXTENT, DRV_NAME))
- return -ENODEV;
-
- if ((inb(ioaddr) != '*') || (inb(ioaddr + 1) != '3') ||
- (inb(ioaddr + 2) != 'C') || (inb(ioaddr + 3) != 'O')) {
- retval = -ENODEV;
- goto out;
- }
-
- pr_info("%s: 3c507 at %#x,", dev->name, ioaddr);
-
- /* We should make a few more checks here, like the first three octets of
- the S.A. for the manufacturer's code. */
-
- irq = inb(ioaddr + IRQ_CONFIG) & 0x0f;
-
- irqval = request_irq(irq, el16_interrupt, 0, DRV_NAME, dev);
- if (irqval) {
- pr_cont("\n");
- pr_err("3c507: unable to get IRQ %d (irqval=%d).\n", irq, irqval);
- retval = -EAGAIN;
- goto out;
- }
-
- /* We've committed to using the board, and can start filling in *dev. */
- dev->base_addr = ioaddr;
-
- outb(0x01, ioaddr + MISC_CTRL);
- for (i = 0; i < 6; i++)
- dev->dev_addr[i] = inb(ioaddr + i);
- pr_cont(" %pM", dev->dev_addr);
-
- if (mem_start)
- net_debug = mem_start & 7;
-
-#ifdef MEM_BASE
- dev->mem_start = MEM_BASE;
- dev->mem_end = dev->mem_start + 0x10000;
-#else
- {
- int base;
- int size;
- char mem_config = inb(ioaddr + MEM_CONFIG);
- if (mem_config & 0x20) {
- size = 64*1024;
- base = 0xf00000 + (mem_config & 0x08 ? 0x080000
- : ((mem_config & 3) << 17));
- } else {
- size = ((mem_config & 3) + 1) << 14;
- base = 0x0c0000 + ( (mem_config & 0x18) << 12);
- }
- dev->mem_start = base;
- dev->mem_end = base + size;
- }
-#endif
-
- dev->if_port = (inb(ioaddr + ROM_CONFIG) & 0x80) ? 1 : 0;
- dev->irq = inb(ioaddr + IRQ_CONFIG) & 0x0f;
-
- pr_cont(", IRQ %d, %sternal xcvr, memory %#lx-%#lx.\n", dev->irq,
- dev->if_port ? "ex" : "in", dev->mem_start, dev->mem_end-1);
-
- if (net_debug)
- pr_debug("%s", version);
-
- lp = netdev_priv(dev);
- spin_lock_init(&lp->lock);
- lp->base = ioremap(dev->mem_start, RX_BUF_END);
- if (!lp->base) {
- pr_err("3c507: unable to remap memory\n");
- retval = -EAGAIN;
- goto out1;
- }
-
- dev->netdev_ops = &netdev_ops;
- dev->watchdog_timeo = TX_TIMEOUT;
- dev->ethtool_ops = &netdev_ethtool_ops;
- dev->flags &= ~IFF_MULTICAST; /* Multicast doesn't work */
- return 0;
-out1:
- free_irq(dev->irq, dev);
-out:
- release_region(ioaddr, EL16_IO_EXTENT);
- return retval;
-}
-
-static int el16_open(struct net_device *dev)
-{
- /* Initialize the 82586 memory and start it. */
- init_82586_mem(dev);
-
- netif_start_queue(dev);
- return 0;
-}
-
-
-static void el16_tx_timeout (struct net_device *dev)
-{
- struct net_local *lp = netdev_priv(dev);
- int ioaddr = dev->base_addr;
- void __iomem *shmem = lp->base;
-
- if (net_debug > 1)
- pr_debug("%s: transmit timed out, %s? ", dev->name,
- readw(shmem + iSCB_STATUS) & 0x8000 ? "IRQ conflict" :
- "network cable problem");
- /* Try to restart the adaptor. */
- if (lp->last_restart == dev->stats.tx_packets) {
- if (net_debug > 1)
- pr_cont("Resetting board.\n");
- /* Completely reset the adaptor. */
- init_82586_mem (dev);
- lp->tx_pkts_in_ring = 0;
- } else {
- /* Issue the channel attention signal and hope it "gets better". */
- if (net_debug > 1)
- pr_cont("Kicking board.\n");
- writew(0xf000 | CUC_START | RX_START, shmem + iSCB_CMD);
- outb (0, ioaddr + SIGNAL_CA); /* Issue channel-attn. */
- lp->last_restart = dev->stats.tx_packets;
- }
- dev->trans_start = jiffies; /* prevent tx timeout */
- netif_wake_queue (dev);
-}
-
-
-static netdev_tx_t el16_send_packet (struct sk_buff *skb,
- struct net_device *dev)
-{
- struct net_local *lp = netdev_priv(dev);
- int ioaddr = dev->base_addr;
- unsigned long flags;
- short length = ETH_ZLEN < skb->len ? skb->len : ETH_ZLEN;
- unsigned char *buf = skb->data;
-
- netif_stop_queue (dev);
-
- spin_lock_irqsave (&lp->lock, flags);
-
- dev->stats.tx_bytes += length;
- /* Disable the 82586's input to the interrupt line. */
- outb (0x80, ioaddr + MISC_CTRL);
-
- hardware_send_packet (dev, buf, skb->len, length - skb->len);
-
- /* Enable the 82586 interrupt input. */
- outb (0x84, ioaddr + MISC_CTRL);
-
- spin_unlock_irqrestore (&lp->lock, flags);
-
- dev_kfree_skb (skb);
-
- /* You might need to clean up and record Tx statistics here. */
-
- return NETDEV_TX_OK;
-}
-
-/* The typical workload of the driver:
- Handle the network interface interrupts. */
-static irqreturn_t el16_interrupt(int irq, void *dev_id)
-{
- struct net_device *dev = dev_id;
- struct net_local *lp;
- int ioaddr, status, boguscount = 0;
- ushort ack_cmd = 0;
- void __iomem *shmem;
-
- if (dev == NULL) {
- pr_err("net_interrupt(): irq %d for unknown device.\n", irq);
- return IRQ_NONE;
- }
-
- ioaddr = dev->base_addr;
- lp = netdev_priv(dev);
- shmem = lp->base;
-
- spin_lock(&lp->lock);
-
- status = readw(shmem+iSCB_STATUS);
-
- if (net_debug > 4) {
- pr_debug("%s: 3c507 interrupt, status %4.4x.\n", dev->name, status);
- }
-
- /* Disable the 82586's input to the interrupt line. */
- outb(0x80, ioaddr + MISC_CTRL);
-
- /* Reap the Tx packet buffers. */
- while (lp->tx_pkts_in_ring) {
- unsigned short tx_status = readw(shmem+lp->tx_reap);
- if (!(tx_status & 0x8000)) {
- if (net_debug > 5)
- pr_debug("Tx command incomplete (%#x).\n", lp->tx_reap);
- break;
- }
- /* Tx unsuccessful or some interesting status bit set. */
- if (!(tx_status & 0x2000) || (tx_status & 0x0f3f)) {
- dev->stats.tx_errors++;
- if (tx_status & 0x0600) dev->stats.tx_carrier_errors++;
- if (tx_status & 0x0100) dev->stats.tx_fifo_errors++;
- if (!(tx_status & 0x0040)) dev->stats.tx_heartbeat_errors++;
- if (tx_status & 0x0020) dev->stats.tx_aborted_errors++;
- dev->stats.collisions += tx_status & 0xf;
- }
- dev->stats.tx_packets++;
- if (net_debug > 5)
- pr_debug("Reaped %x, Tx status %04x.\n" , lp->tx_reap, tx_status);
- lp->tx_reap += TX_BUF_SIZE;
- if (lp->tx_reap > RX_BUF_START - TX_BUF_SIZE)
- lp->tx_reap = TX_BUF_START;
-
- lp->tx_pkts_in_ring--;
- /* There is always more space in the Tx ring buffer now. */
- netif_wake_queue(dev);
-
- if (++boguscount > 10)
- break;
- }
-
- if (status & 0x4000) { /* Packet received. */
- if (net_debug > 5)
- pr_debug("Received packet, rx_head %04x.\n", lp->rx_head);
- el16_rx(dev);
- }
-
- /* Acknowledge the interrupt sources. */
- ack_cmd = status & 0xf000;
-
- if ((status & 0x0700) != 0x0200 && netif_running(dev)) {
- if (net_debug)
- pr_debug("%s: Command unit stopped, status %04x, restarting.\n",
- dev->name, status);
- /* If this ever occurs we should really re-write the idle loop, reset
- the Tx list, and do a complete restart of the command unit.
- For now we rely on the Tx timeout if the resume doesn't work. */
- ack_cmd |= CUC_RESUME;
- }
-
- if ((status & 0x0070) != 0x0040 && netif_running(dev)) {
- /* The Rx unit is not ready, it must be hung. Restart the receiver by
- initializing the rx buffers, and issuing an Rx start command. */
- if (net_debug)
- pr_debug("%s: Rx unit stopped, status %04x, restarting.\n",
- dev->name, status);
- init_rx_bufs(dev);
- writew(RX_BUF_START,shmem+iSCB_RFA);
- ack_cmd |= RX_START;
- }
-
- writew(ack_cmd,shmem+iSCB_CMD);
- outb(0, ioaddr + SIGNAL_CA); /* Issue channel-attn. */
-
- /* Clear the latched interrupt. */
- outb(0, ioaddr + RESET_IRQ);
-
- /* Enable the 82586's interrupt input. */
- outb(0x84, ioaddr + MISC_CTRL);
- spin_unlock(&lp->lock);
- return IRQ_HANDLED;
-}
-
-static int el16_close(struct net_device *dev)
-{
- struct net_local *lp = netdev_priv(dev);
- int ioaddr = dev->base_addr;
- void __iomem *shmem = lp->base;
-
- netif_stop_queue(dev);
-
- /* Flush the Tx and disable Rx. */
- writew(RX_SUSPEND | CUC_SUSPEND,shmem+iSCB_CMD);
- outb(0, ioaddr + SIGNAL_CA);
-
- /* Disable the 82586's input to the interrupt line. */
- outb(0x80, ioaddr + MISC_CTRL);
-
- /* We always physically use the IRQ line, so we don't do free_irq(). */
-
- /* Update the statistics here. */
-
- return 0;
-}
-
-/* Initialize the Rx-block list. */
-static void init_rx_bufs(struct net_device *dev)
-{
- struct net_local *lp = netdev_priv(dev);
- void __iomem *write_ptr;
- unsigned short SCB_base = SCB_BASE;
-
- int cur_rxbuf = lp->rx_head = RX_BUF_START;
-
- /* Initialize each Rx frame + data buffer. */
- do { /* While there is room for one more. */
-
- write_ptr = lp->base + cur_rxbuf;
-
- writew(0x0000,write_ptr); /* Status */
- writew(0x0000,write_ptr+=2); /* Command */
- writew(cur_rxbuf + RX_BUF_SIZE,write_ptr+=2); /* Link */
- writew(cur_rxbuf + 22,write_ptr+=2); /* Buffer offset */
- writew(0x0000,write_ptr+=2); /* Pad for dest addr. */
- writew(0x0000,write_ptr+=2);
- writew(0x0000,write_ptr+=2);
- writew(0x0000,write_ptr+=2); /* Pad for source addr. */
- writew(0x0000,write_ptr+=2);
- writew(0x0000,write_ptr+=2);
- writew(0x0000,write_ptr+=2); /* Pad for protocol. */
-
- writew(0x0000,write_ptr+=2); /* Buffer: Actual count */
- writew(-1,write_ptr+=2); /* Buffer: Next (none). */
- writew(cur_rxbuf + 0x20 + SCB_base,write_ptr+=2);/* Buffer: Address low */
- writew(0x0000,write_ptr+=2);
- /* Finally, the number of bytes in the buffer. */
- writew(0x8000 + RX_BUF_SIZE-0x20,write_ptr+=2);
-
- lp->rx_tail = cur_rxbuf;
- cur_rxbuf += RX_BUF_SIZE;
- } while (cur_rxbuf <= RX_BUF_END - RX_BUF_SIZE);
-
- /* Terminate the list by setting the EOL bit, and wrap the pointer to make
- the list a ring. */
- write_ptr = lp->base + lp->rx_tail + 2;
- writew(0xC000,write_ptr); /* Command, mark as last. */
- writew(lp->rx_head,write_ptr+2); /* Link */
-}
-
-static void init_82586_mem(struct net_device *dev)
-{
- struct net_local *lp = netdev_priv(dev);
- short ioaddr = dev->base_addr;
- void __iomem *shmem = lp->base;
-
- /* Enable loopback to protect the wire while starting up,
- and hold the 586 in reset during the memory initialization. */
- outb(0x20, ioaddr + MISC_CTRL);
-
- /* Fix the ISCP address and base. */
- init_words[3] = SCB_BASE;
- init_words[7] = SCB_BASE;
-
- /* Write the words at 0xfff6 (address-aliased to 0xfffff6). */
- memcpy_toio(lp->base + RX_BUF_END - 10, init_words, 10);
-
- /* Write the words at 0x0000. */
- memcpy_toio(lp->base, init_words + 5, sizeof(init_words) - 10);
-
- /* Fill in the station address. */
- memcpy_toio(lp->base+SA_OFFSET, dev->dev_addr, ETH_ALEN);
-
- /* The Tx-block list is written as needed. We just set up the values. */
- lp->tx_cmd_link = IDLELOOP + 4;
- lp->tx_head = lp->tx_reap = TX_BUF_START;
-
- init_rx_bufs(dev);
-
- /* Start the 586 by releasing the reset line, but leave loopback. */
- outb(0xA0, ioaddr + MISC_CTRL);
-
- /* This was time consuming to track down: you need to give two channel
- attention signals to reliably start up the i82586. */
- outb(0, ioaddr + SIGNAL_CA);
-
- {
- int boguscnt = 50;
- while (readw(shmem+iSCB_STATUS) == 0)
- if (--boguscnt == 0) {
- pr_warning("%s: i82586 initialization timed out with status %04x, cmd %04x.\n",
- dev->name, readw(shmem+iSCB_STATUS), readw(shmem+iSCB_CMD));
- break;
- }
- /* Issue channel-attn -- the 82586 won't start. */
- outb(0, ioaddr + SIGNAL_CA);
- }
-
- /* Disable loopback and enable interrupts. */
- outb(0x84, ioaddr + MISC_CTRL);
- if (net_debug > 4)
- pr_debug("%s: Initialized 82586, status %04x.\n", dev->name,
- readw(shmem+iSCB_STATUS));
-}
-
-static void hardware_send_packet(struct net_device *dev, void *buf, short length, short pad)
-{
- struct net_local *lp = netdev_priv(dev);
- short ioaddr = dev->base_addr;
- ushort tx_block = lp->tx_head;
- void __iomem *write_ptr = lp->base + tx_block;
- static char padding[ETH_ZLEN];
-
- /* Set the write pointer to the Tx block, and put out the header. */
- writew(0x0000,write_ptr); /* Tx status */
- writew(CMD_INTR|CmdTx,write_ptr+=2); /* Tx command */
- writew(tx_block+16,write_ptr+=2); /* Next command is a NoOp. */
- writew(tx_block+8,write_ptr+=2); /* Data Buffer offset. */
-
- /* Output the data buffer descriptor. */
- writew((pad + length) | 0x8000,write_ptr+=2); /* Byte count parameter. */
- writew(-1,write_ptr+=2); /* No next data buffer. */
- writew(tx_block+22+SCB_BASE,write_ptr+=2); /* Buffer follows the NoOp command. */
- writew(0x0000,write_ptr+=2); /* Buffer address high bits (always zero). */
-
- /* Output the Loop-back NoOp command. */
- writew(0x0000,write_ptr+=2); /* Tx status */
- writew(CmdNOp,write_ptr+=2); /* Tx command */
- writew(tx_block+16,write_ptr+=2); /* Next is myself. */
-
- /* Output the packet at the write pointer. */
- memcpy_toio(write_ptr+2, buf, length);
- if (pad)
- memcpy_toio(write_ptr+length+2, padding, pad);
-
- /* Set the old command link pointing to this send packet. */
- writew(tx_block,lp->base + lp->tx_cmd_link);
- lp->tx_cmd_link = tx_block + 20;
-
- /* Set the next free tx region. */
- lp->tx_head = tx_block + TX_BUF_SIZE;
- if (lp->tx_head > RX_BUF_START - TX_BUF_SIZE)
- lp->tx_head = TX_BUF_START;
-
- if (net_debug > 4) {
- pr_debug("%s: 3c507 @%x send length = %d, tx_block %3x, next %3x.\n",
- dev->name, ioaddr, length, tx_block, lp->tx_head);
- }
-
- /* Grimly block further packets if there has been insufficient reaping. */
- if (++lp->tx_pkts_in_ring < NUM_TX_BUFS)
- netif_wake_queue(dev);
-}
-
-static void el16_rx(struct net_device *dev)
-{
- struct net_local *lp = netdev_priv(dev);
- void __iomem *shmem = lp->base;
- ushort rx_head = lp->rx_head;
- ushort rx_tail = lp->rx_tail;
- ushort boguscount = 10;
- short frame_status;
-
- while ((frame_status = readw(shmem+rx_head)) < 0) { /* Command complete */
- void __iomem *read_frame = lp->base + rx_head;
- ushort rfd_cmd = readw(read_frame+2);
- ushort next_rx_frame = readw(read_frame+4);
- ushort data_buffer_addr = readw(read_frame+6);
- void __iomem *data_frame = lp->base + data_buffer_addr;
- ushort pkt_len = readw(data_frame);
-
- if (rfd_cmd != 0 || data_buffer_addr != rx_head + 22 ||
- (pkt_len & 0xC000) != 0xC000) {
- pr_err("%s: Rx frame at %#x corrupted, "
- "status %04x cmd %04x next %04x "
- "data-buf @%04x %04x.\n",
- dev->name, rx_head, frame_status, rfd_cmd,
- next_rx_frame, data_buffer_addr, pkt_len);
- } else if ((frame_status & 0x2000) == 0) {
- /* Frame Rxed, but with error. */
- dev->stats.rx_errors++;
- if (frame_status & 0x0800) dev->stats.rx_crc_errors++;
- if (frame_status & 0x0400) dev->stats.rx_frame_errors++;
- if (frame_status & 0x0200) dev->stats.rx_fifo_errors++;
- if (frame_status & 0x0100) dev->stats.rx_over_errors++;
- if (frame_status & 0x0080) dev->stats.rx_length_errors++;
- } else {
- /* Malloc up new buffer. */
- struct sk_buff *skb;
-
- pkt_len &= 0x3fff;
- skb = netdev_alloc_skb(dev, pkt_len + 2);
- if (skb == NULL) {
- pr_err("%s: Memory squeeze, dropping packet.\n",
- dev->name);
- dev->stats.rx_dropped++;
- break;
- }
-
- skb_reserve(skb,2);
-
- /* 'skb->data' points to the start of sk_buff data area. */
- memcpy_fromio(skb_put(skb,pkt_len), data_frame + 10, pkt_len);
-
- skb->protocol=eth_type_trans(skb,dev);
- netif_rx(skb);
- dev->stats.rx_packets++;
- dev->stats.rx_bytes += pkt_len;
- }
-
- /* Clear the status word and set End-of-List on the rx frame. */
- writew(0,read_frame);
- writew(0xC000,read_frame+2);
- /* Clear the end-of-list on the prev. RFD. */
- writew(0x0000,lp->base + rx_tail + 2);
-
- rx_tail = rx_head;
- rx_head = next_rx_frame;
- if (--boguscount == 0)
- break;
- }
-
- lp->rx_head = rx_head;
- lp->rx_tail = rx_tail;
-}
-
-static void netdev_get_drvinfo(struct net_device *dev,
- struct ethtool_drvinfo *info)
-{
- strlcpy(info->driver, DRV_NAME, sizeof(info->driver));
- strlcpy(info->version, DRV_VERSION, sizeof(info->version));
- snprintf(info->bus_info, sizeof(info->bus_info), "ISA 0x%lx",
- dev->base_addr);
-}
-
-static u32 netdev_get_msglevel(struct net_device *dev)
-{
- return debug;
-}
-
-static void netdev_set_msglevel(struct net_device *dev, u32 level)
-{
- debug = level;
-}
-
-static const struct ethtool_ops netdev_ethtool_ops = {
- .get_drvinfo = netdev_get_drvinfo,
- .get_msglevel = netdev_get_msglevel,
- .set_msglevel = netdev_set_msglevel,
-};
-
-#ifdef MODULE
-static struct net_device *dev_3c507;
-module_param(io, int, 0);
-module_param(irq, int, 0);
-MODULE_PARM_DESC(io, "EtherLink16 I/O base address");
-MODULE_PARM_DESC(irq, "(ignored)");
-
-int __init init_module(void)
-{
- if (io == 0)
- pr_notice("3c507: You should not use auto-probing with insmod!\n");
- dev_3c507 = el16_probe(-1);
- return IS_ERR(dev_3c507) ? PTR_ERR(dev_3c507) : 0;
-}
-
-void __exit
-cleanup_module(void)
-{
- struct net_device *dev = dev_3c507;
- unregister_netdev(dev);
- free_irq(dev->irq, dev);
- iounmap(((struct net_local *)netdev_priv(dev))->base);
- release_region(dev->base_addr, EL16_IO_EXTENT);
- free_netdev(dev);
-}
-#endif /* MODULE */
-MODULE_LICENSE("GPL");
diff --git a/drivers/net/ethernet/i825xx/82596.c b/drivers/net/ethernet/i825xx/82596.c
index 6aa927af382..1c54e229e3c 100644
--- a/drivers/net/ethernet/i825xx/82596.c
+++ b/drivers/net/ethernet/i825xx/82596.c
@@ -95,9 +95,6 @@ static char version[] __initdata =
#if defined(CONFIG_BVME6000_NET) || defined(CONFIG_BVME6000_NET_MODULE)
#define ENABLE_BVME6000_NET
#endif
-#if defined(CONFIG_APRICOT) || defined(CONFIG_APRICOT_MODULE)
-#define ENABLE_APRICOT
-#endif
#ifdef ENABLE_MVME16x_NET
#include <asm/mvme16xhw.h>
@@ -120,8 +117,15 @@ static char version[] __initdata =
#define WSWAPtbd(x) ((struct i596_tbd *) (((u32)(x)<<16) | ((((u32)(x)))>>16)))
#define WSWAPchar(x) ((char *) (((u32)(x)<<16) | ((((u32)(x)))>>16)))
#define ISCP_BUSY 0x00010000
-#define MACH_IS_APRICOT 0
#else
+#error 82596.c: unknown architecture
+#endif
+
+/*
+ * These were the intel versions, left here for reference. There
+ * are currently no x86 users of this legacy i82596 chip.
+ */
+#if 0
#define WSWAPrfd(x) ((struct i596_rfd *)((long)x))
#define WSWAPrbd(x) ((struct i596_rbd *)((long)x))
#define WSWAPiscp(x) ((struct i596_iscp *)((long)x))
@@ -130,7 +134,6 @@ static char version[] __initdata =
#define WSWAPtbd(x) ((struct i596_tbd *)((long)x))
#define WSWAPchar(x) ((char *)((long)x))
#define ISCP_BUSY 0x0001
-#define MACH_IS_APRICOT 1
#endif
/*
@@ -383,11 +386,6 @@ static inline void CA(struct net_device *dev)
i = *(volatile u32 *) (dev->base_addr);
}
#endif
-#ifdef ENABLE_APRICOT
- if (MACH_IS_APRICOT) {
- outw(0, (short) (dev->base_addr) + 4);
- }
-#endif
}
@@ -617,9 +615,6 @@ static void rebuild_rx_bufs(struct net_device *dev)
static int init_i596_mem(struct net_device *dev)
{
struct i596_private *lp = dev->ml_priv;
-#if !defined(ENABLE_MVME16x_NET) && !defined(ENABLE_BVME6000_NET) || defined(ENABLE_APRICOT)
- short ioaddr = dev->base_addr;
-#endif
unsigned long flags;
MPU_PORT(dev, PORT_RESET, NULL);
@@ -653,18 +648,6 @@ static int init_i596_mem(struct net_device *dev)
MPU_PORT(dev, PORT_ALTSCP, (void *)virt_to_bus((void *)&lp->scp));
-#elif defined(ENABLE_APRICOT)
-
- {
- u32 scp = virt_to_bus(&lp->scp);
-
- /* change the scp address */
- outw(0, ioaddr);
- outw(0, ioaddr);
- outb(4, ioaddr + 0xf);
- outw(scp | 2, ioaddr);
- outw(scp >> 16, ioaddr);
- }
#endif
lp->last_cmd = jiffies;
@@ -677,10 +660,6 @@ static int init_i596_mem(struct net_device *dev)
if (MACH_IS_BVME6000)
lp->scp.sysbus = 0x0000004c;
#endif
-#ifdef ENABLE_APRICOT
- if (MACH_IS_APRICOT)
- lp->scp.sysbus = 0x00440000;
-#endif
lp->scp.iscp = WSWAPiscp(virt_to_bus((void *)&lp->iscp));
lp->iscp.scb = WSWAPscb(virt_to_bus((void *)&lp->scb));
@@ -698,10 +677,6 @@ static int init_i596_mem(struct net_device *dev)
DEB(DEB_INIT,printk(KERN_DEBUG "%s: starting i82596.\n", dev->name));
-#if defined(ENABLE_APRICOT)
- (void) inb(ioaddr + 0x10);
- outb(4, ioaddr + 0xf);
-#endif
CA(dev);
if (wait_istat(dev,lp,1000,"initialization timed out"))
@@ -1203,43 +1178,6 @@ struct net_device * __init i82596_probe(int unit)
goto found;
}
#endif
-#ifdef ENABLE_APRICOT
- {
- int checksum = 0;
- int ioaddr = 0x300;
-
- /* this is easy the ethernet interface can only be at 0x300 */
- /* first check nothing is already registered here */
-
- if (!request_region(ioaddr, I596_TOTAL_SIZE, DRV_NAME)) {
- printk(KERN_ERR "82596: IO address 0x%04x in use\n", ioaddr);
- err = -EBUSY;
- goto out;
- }
-
- dev->base_addr = ioaddr;
-
- for (i = 0; i < 8; i++) {
- eth_addr[i] = inb(ioaddr + 8 + i);
- checksum += eth_addr[i];
- }
-
- /* checksum is a multiple of 0x100, got this wrong first time
- some machines have 0x100, some 0x200. The DOS driver doesn't
- even bother with the checksum.
- Some other boards trip the checksum.. but then appear as
- ether address 0. Trap these - AC */
-
- if ((checksum % 0x100) ||
- (memcmp(eth_addr, "\x00\x00\x49", 3) != 0)) {
- err = -ENODEV;
- goto out1;
- }
-
- dev->irq = 10;
- goto found;
- }
-#endif
err = -ENODEV;
goto out;
@@ -1296,9 +1234,6 @@ out2:
#endif
free_page ((u32)(dev->mem_start));
out1:
-#ifdef ENABLE_APRICOT
- release_region(dev->base_addr, I596_TOTAL_SIZE);
-#endif
out:
free_netdev(dev);
return ERR_PTR(err);
@@ -1455,10 +1390,6 @@ static irqreturn_t i596_interrupt(int irq, void *dev_id)
*ethirq = 3;
}
#endif
-#ifdef ENABLE_APRICOT
- (void) inb(ioaddr + 0x10);
- outb(4, ioaddr + 0xf);
-#endif
CA(dev);
DEB(DEB_INTS,printk(KERN_DEBUG "%s: exiting interrupt.\n", dev->name));
@@ -1589,11 +1520,6 @@ static void set_multicast_list(struct net_device *dev)
#ifdef MODULE
static struct net_device *dev_82596;
-#ifdef ENABLE_APRICOT
-module_param(irq, int, 0);
-MODULE_PARM_DESC(irq, "Apricot IRQ number");
-#endif
-
static int debug = -1;
module_param(debug, int, 0);
MODULE_PARM_DESC(debug, "i82596 debug mask");
@@ -1620,10 +1546,6 @@ void __exit cleanup_module(void)
IOMAP_FULL_CACHING);
#endif
free_page ((u32)(dev_82596->mem_start));
-#ifdef ENABLE_APRICOT
- /* If we don't do this, we can't re-insmod it later. */
- release_region(dev_82596->base_addr, I596_TOTAL_SIZE);
-#endif
free_netdev(dev_82596);
}
diff --git a/drivers/net/ethernet/i825xx/Kconfig b/drivers/net/ethernet/i825xx/Kconfig
index 70f8c2d221b..955d929cd00 100644
--- a/drivers/net/ethernet/i825xx/Kconfig
+++ b/drivers/net/ethernet/i825xx/Kconfig
@@ -20,29 +20,6 @@ config NET_VENDOR_I825XX
if NET_VENDOR_I825XX
-config ELPLUS
- tristate "3c505 \"EtherLink Plus\" support"
- depends on ISA && ISA_DMA_API
- ---help---
- Information about this network (Ethernet) card can be found in
- <file:Documentation/networking/3c505.txt>. If you have a card of
- this type, say Y and read the Ethernet-HOWTO, available from
- <http://www.tldp.org/docs.html#howto>.
-
- To compile this driver as a module, choose M here. The module
- will be called 3c505.
-
-config EL16
- tristate "3c507 \"EtherLink 16\" support (EXPERIMENTAL)"
- depends on ISA && EXPERIMENTAL
- ---help---
- If you have a network (Ethernet) card of this type, say Y and read
- the Ethernet-HOWTO, available from
- <http://www.tldp.org/docs.html#howto>.
-
- To compile this driver as a module, choose M here. The module
- will be called 3c507.
-
config ARM_ETHER1
tristate "Acorn Ether1 support"
depends on ARM && ARCH_ACORN
@@ -50,17 +27,6 @@ config ARM_ETHER1
If you have an Acorn system with one of these (AKA25) network cards,
you should say Y to this option if you wish to use it with Linux.
-config APRICOT
- tristate "Apricot Xen-II on board Ethernet"
- depends on ISA
- ---help---
- If you have a network (Ethernet) controller of this type, say Y and
- read the Ethernet-HOWTO, available from
- <http://www.tldp.org/docs.html#howto>.
-
- To compile this driver as a module, choose M here. The module
- will be called apricot.
-
config BVME6000_NET
tristate "BVME6000 Ethernet support"
depends on BVME6000
@@ -70,33 +36,6 @@ config BVME6000_NET
in your kernel.
To compile this driver as a module, choose M here.
-config EEXPRESS
- tristate "EtherExpress 16 support"
- depends on ISA
- ---help---
- If you have an EtherExpress16 network (Ethernet) card, say Y and
- read the Ethernet-HOWTO, available from
- <http://www.tldp.org/docs.html#howto>. Note that the Intel
- EtherExpress16 card used to be regarded as a very poor choice
- because the driver was very unreliable. We now have a new driver
- that should do better.
-
- To compile this driver as a module, choose M here. The module
- will be called eexpress.
-
-config EEXPRESS_PRO
- tristate "EtherExpressPro support/EtherExpress 10 (i82595) support"
- depends on ISA
- ---help---
- If you have a network (Ethernet) card of this type, say Y. This
- driver supports Intel i82595{FX,TX} based boards. Note however
- that the EtherExpress PRO/100 Ethernet card has its own separate
- driver. Please read the Ethernet-HOWTO, available from
- <http://www.tldp.org/docs.html#howto>.
-
- To compile this driver as a module, choose M here. The module
- will be called eepro.
-
config LASI_82596
tristate "Lasi ethernet"
depends on GSC
@@ -104,14 +43,6 @@ config LASI_82596
Say Y here to support the builtin Intel 82596 ethernet controller
found in Hewlett-Packard PA-RISC machines with 10Mbit ethernet.
-config LP486E
- tristate "LP486E on board Ethernet"
- depends on ISA
- ---help---
- Say Y here to support the 82596-based on-board Ethernet controller
- for the Panther motherboard, which is one of the two shipped in the
- Intel Professional Workstation.
-
config MVME16x_NET
tristate "MVME16x Ethernet support"
depends on MVME16x
@@ -121,17 +52,6 @@ config MVME16x_NET
driver for this chip in your kernel.
To compile this driver as a module, choose M here.
-config NI52
- tristate "NI5210 support"
- depends on ISA
- ---help---
- If you have a network (Ethernet) card of this type, say Y and read
- the Ethernet-HOWTO, available from
- <http://www.tldp.org/docs.html#howto>.
-
- To compile this driver as a module, choose M here. The module
- will be called ni52.
-
config SNI_82596
tristate "SNI RM ethernet"
depends on SNI_RM
@@ -148,14 +68,4 @@ config SUN3_82586
that this driver does not support 82586-based adapters on additional
VME boards.
-config ZNET
- tristate "Zenith Z-Note support (EXPERIMENTAL)"
- depends on EXPERIMENTAL && ISA_DMA_API && X86
- ---help---
- The Zenith Z-Note notebook computer has a built-in network
- (Ethernet) card, and this is the Linux driver for it. Note that the
- IBM Thinkpad 300 is compatible with the Z-Note and is also supported
- by this driver. Read the Ethernet-HOWTO, available from
- <http://www.tldp.org/docs.html#howto>.
-
endif # NET_VENDOR_I825XX
diff --git a/drivers/net/ethernet/i825xx/Makefile b/drivers/net/ethernet/i825xx/Makefile
index 6adff85e8ec..8c8dcd29c40 100644
--- a/drivers/net/ethernet/i825xx/Makefile
+++ b/drivers/net/ethernet/i825xx/Makefile
@@ -3,15 +3,7 @@
#
obj-$(CONFIG_ARM_ETHER1) += ether1.o
-obj-$(CONFIG_EEXPRESS) += eexpress.o
-obj-$(CONFIG_EEXPRESS_PRO) += eepro.o
-obj-$(CONFIG_ELPLUS) += 3c505.o
-obj-$(CONFIG_EL16) += 3c507.o
-obj-$(CONFIG_LP486E) += lp486e.o
-obj-$(CONFIG_NI52) += ni52.o
obj-$(CONFIG_SUN3_82586) += sun3_82586.o
-obj-$(CONFIG_ZNET) += znet.o
-obj-$(CONFIG_APRICOT) += 82596.o
obj-$(CONFIG_LASI_82596) += lasi_82596.o
obj-$(CONFIG_SNI_82596) += sni_82596.o
obj-$(CONFIG_MVME16x_NET) += 82596.o
diff --git a/drivers/net/ethernet/i825xx/eepro.c b/drivers/net/ethernet/i825xx/eepro.c
deleted file mode 100644
index 7f49fd54c52..00000000000
--- a/drivers/net/ethernet/i825xx/eepro.c
+++ /dev/null
@@ -1,1822 +0,0 @@
-/* eepro.c: Intel EtherExpress Pro/10 device driver for Linux. */
-/*
- Written 1994, 1995,1996 by Bao C. Ha.
-
- Copyright (C) 1994, 1995,1996 by Bao C. Ha.
-
- This software may be used and distributed
- according to the terms of the GNU General Public License,
- incorporated herein by reference.
-
- The author may be reached at bao.ha@srs.gov
- or 418 Hastings Place, Martinez, GA 30907.
-
- Things remaining to do:
- Better record keeping of errors.
- Eliminate transmit interrupt to reduce overhead.
- Implement "concurrent processing". I won't be doing it!
-
- Bugs:
-
- If you have a problem of not detecting the 82595 during a
- reboot (warm reset), disable the FLASH memory should fix it.
- This is a compatibility hardware problem.
-
- Versions:
- 0.13b basic ethtool support (aris, 09/13/2004)
- 0.13a in memory shortage, drop packets also in board
- (Michael Westermann <mw@microdata-pos.de>, 07/30/2002)
- 0.13 irq sharing, rewrote probe function, fixed a nasty bug in
- hardware_send_packet and a major cleanup (aris, 11/08/2001)
- 0.12d fixing a problem with single card detected as eight eth devices
- fixing a problem with sudden drop in card performance
- (chris (asdn@go2.pl), 10/29/2001)
- 0.12c fixing some problems with old cards (aris, 01/08/2001)
- 0.12b misc fixes (aris, 06/26/2000)
- 0.12a port of version 0.12a of 2.2.x kernels to 2.3.x
- (aris (aris@conectiva.com.br), 05/19/2000)
- 0.11e some tweaks about multiple cards support (PdP, jul/aug 1999)
- 0.11d added __initdata, __init stuff; call spin_lock_init
- in eepro_probe1. Replaced "eepro" by dev->name. Augmented
- the code protected by spin_lock in interrupt routine
- (PdP, 12/12/1998)
- 0.11c minor cleanup (PdP, RMC, 09/12/1998)
- 0.11b Pascal Dupuis (dupuis@lei.ucl.ac.be): works as a module
- under 2.1.xx. Debug messages are flagged as KERN_DEBUG to
- avoid console flooding. Added locking at critical parts. Now
- the dawn thing is SMP safe.
- 0.11a Attempt to get 2.1.xx support up (RMC)
- 0.11 Brian Candler added support for multiple cards. Tested as
- a module, no idea if it works when compiled into kernel.
-
- 0.10e Rick Bressler notified me that ifconfig up;ifconfig down fails
- because the irq is lost somewhere. Fixed that by moving
- request_irq and free_irq to eepro_open and eepro_close respectively.
- 0.10d Ugh! Now Wakeup works. Was seriously broken in my first attempt.
- I'll need to find a way to specify an ioport other than
- the default one in the PnP case. PnP definitively sucks.
- And, yes, this is not the only reason.
- 0.10c PnP Wakeup Test for 595FX. uncomment #define PnPWakeup;
- to use.
- 0.10b Should work now with (some) Pro/10+. At least for
- me (and my two cards) it does. _No_ guarantee for
- function with non-Pro/10+ cards! (don't have any)
- (RMC, 9/11/96)
-
- 0.10 Added support for the Etherexpress Pro/10+. The
- IRQ map was changed significantly from the old
- pro/10. The new interrupt map was provided by
- Rainer M. Canavan (Canavan@Zeus.cs.bonn.edu).
- (BCH, 9/3/96)
-
- 0.09 Fixed a race condition in the transmit algorithm,
- which causes crashes under heavy load with fast
- pentium computers. The performance should also
- improve a bit. The size of RX buffer, and hence
- TX buffer, can also be changed via lilo or insmod.
- (BCH, 7/31/96)
-
- 0.08 Implement 32-bit I/O for the 82595TX and 82595FX
- based lan cards. Disable full-duplex mode if TPE
- is not used. (BCH, 4/8/96)
-
- 0.07a Fix a stat report which counts every packet as a
- heart-beat failure. (BCH, 6/3/95)
-
- 0.07 Modified to support all other 82595-based lan cards.
- The IRQ vector of the EtherExpress Pro will be set
- according to the value saved in the EEPROM. For other
- cards, I will do autoirq_request() to grab the next
- available interrupt vector. (BCH, 3/17/95)
-
- 0.06a,b Interim released. Minor changes in the comments and
- print out format. (BCH, 3/9/95 and 3/14/95)
-
- 0.06 First stable release that I am comfortable with. (BCH,
- 3/2/95)
-
- 0.05 Complete testing of multicast. (BCH, 2/23/95)
-
- 0.04 Adding multicast support. (BCH, 2/14/95)
-
- 0.03 First widely alpha release for public testing.
- (BCH, 2/14/95)
-
-*/
-
-static const char version[] =
- "eepro.c: v0.13b 09/13/2004 aris@cathedrallabs.org\n";
-
-#include <linux/module.h>
-
-/*
- Sources:
-
- This driver wouldn't have been written without the availability
- of the Crynwr's Lan595 driver source code. It helps me to
- familiarize with the 82595 chipset while waiting for the Intel
- documentation. I also learned how to detect the 82595 using
- the packet driver's technique.
-
- This driver is written by cutting and pasting the skeleton.c driver
- provided by Donald Becker. I also borrowed the EEPROM routine from
- Donald Becker's 82586 driver.
-
- Datasheet for the Intel 82595 (including the TX and FX version). It
- provides just enough info that the casual reader might think that it
- documents the i82595.
-
- The User Manual for the 82595. It provides a lot of the missing
- information.
-
-*/
-
-#include <linux/kernel.h>
-#include <linux/types.h>
-#include <linux/fcntl.h>
-#include <linux/interrupt.h>
-#include <linux/ioport.h>
-#include <linux/in.h>
-#include <linux/string.h>
-#include <linux/errno.h>
-#include <linux/netdevice.h>
-#include <linux/etherdevice.h>
-#include <linux/skbuff.h>
-#include <linux/spinlock.h>
-#include <linux/init.h>
-#include <linux/delay.h>
-#include <linux/bitops.h>
-#include <linux/ethtool.h>
-
-#include <asm/io.h>
-#include <asm/dma.h>
-
-#define DRV_NAME "eepro"
-#define DRV_VERSION "0.13c"
-
-#define compat_dev_kfree_skb( skb, mode ) dev_kfree_skb( (skb) )
-/* I had reports of looong delays with SLOW_DOWN defined as udelay(2) */
-#define SLOW_DOWN inb(0x80)
-/* udelay(2) */
-#define compat_init_data __initdata
-enum iftype { AUI=0, BNC=1, TPE=2 };
-
-/* First, a few definitions that the brave might change. */
-/* A zero-terminated list of I/O addresses to be probed. */
-static unsigned int eepro_portlist[] compat_init_data =
- { 0x300, 0x210, 0x240, 0x280, 0x2C0, 0x200, 0x320, 0x340, 0x360, 0};
-/* note: 0x300 is default, the 595FX supports ALL IO Ports
- from 0x000 to 0x3F0, some of which are reserved in PCs */
-
-/* To try the (not-really PnP Wakeup: */
-/*
-#define PnPWakeup
-*/
-
-/* use 0 for production, 1 for verification, >2 for debug */
-#ifndef NET_DEBUG
-#define NET_DEBUG 0
-#endif
-static unsigned int net_debug = NET_DEBUG;
-
-/* The number of low I/O ports used by the ethercard. */
-#define EEPRO_IO_EXTENT 16
-
-/* Different 82595 chips */
-#define LAN595 0
-#define LAN595TX 1
-#define LAN595FX 2
-#define LAN595FX_10ISA 3
-
-/* Information that need to be kept for each board. */
-struct eepro_local {
- unsigned rx_start;
- unsigned tx_start; /* start of the transmit chain */
- int tx_last; /* pointer to last packet in the transmit chain */
- unsigned tx_end; /* end of the transmit chain (plus 1) */
- int eepro; /* 1 for the EtherExpress Pro/10,
- 2 for the EtherExpress Pro/10+,
- 3 for the EtherExpress 10 (blue cards),
- 0 for other 82595-based lan cards. */
- int version; /* a flag to indicate if this is a TX or FX
- version of the 82595 chip. */
- int stepping;
-
- spinlock_t lock; /* Serializing lock */
-
- unsigned rcv_ram; /* pre-calculated space for rx */
- unsigned xmt_ram; /* pre-calculated space for tx */
- unsigned char xmt_bar;
- unsigned char xmt_lower_limit_reg;
- unsigned char xmt_upper_limit_reg;
- short xmt_lower_limit;
- short xmt_upper_limit;
- short rcv_lower_limit;
- short rcv_upper_limit;
- unsigned char eeprom_reg;
- unsigned short word[8];
-};
-
-/* The station (ethernet) address prefix, used for IDing the board. */
-#define SA_ADDR0 0x00 /* Etherexpress Pro/10 */
-#define SA_ADDR1 0xaa
-#define SA_ADDR2 0x00
-
-#define GetBit(x,y) ((x & (1<<y))>>y)
-
-/* EEPROM Word 0: */
-#define ee_PnP 0 /* Plug 'n Play enable bit */
-#define ee_Word1 1 /* Word 1? */
-#define ee_BusWidth 2 /* 8/16 bit */
-#define ee_FlashAddr 3 /* Flash Address */
-#define ee_FlashMask 0x7 /* Mask */
-#define ee_AutoIO 6 /* */
-#define ee_reserved0 7 /* =0! */
-#define ee_Flash 8 /* Flash there? */
-#define ee_AutoNeg 9 /* Auto Negotiation enabled? */
-#define ee_IO0 10 /* IO Address LSB */
-#define ee_IO0Mask 0x /*...*/
-#define ee_IO1 15 /* IO MSB */
-
-/* EEPROM Word 1: */
-#define ee_IntSel 0 /* Interrupt */
-#define ee_IntMask 0x7
-#define ee_LI 3 /* Link Integrity 0= enabled */
-#define ee_PC 4 /* Polarity Correction 0= enabled */
-#define ee_TPE_AUI 5 /* PortSelection 1=TPE */
-#define ee_Jabber 6 /* Jabber prevention 0= enabled */
-#define ee_AutoPort 7 /* Auto Port Selection 1= Disabled */
-#define ee_SMOUT 8 /* SMout Pin Control 0= Input */
-#define ee_PROM 9 /* Flash EPROM / PROM 0=Flash */
-#define ee_reserved1 10 /* .. 12 =0! */
-#define ee_AltReady 13 /* Alternate Ready, 0=normal */
-#define ee_reserved2 14 /* =0! */
-#define ee_Duplex 15
-
-/* Word2,3,4: */
-#define ee_IA5 0 /*bit start for individual Addr Byte 5 */
-#define ee_IA4 8 /*bit start for individual Addr Byte 5 */
-#define ee_IA3 0 /*bit start for individual Addr Byte 5 */
-#define ee_IA2 8 /*bit start for individual Addr Byte 5 */
-#define ee_IA1 0 /*bit start for individual Addr Byte 5 */
-#define ee_IA0 8 /*bit start for individual Addr Byte 5 */
-
-/* Word 5: */
-#define ee_BNC_TPE 0 /* 0=TPE */
-#define ee_BootType 1 /* 00=None, 01=IPX, 10=ODI, 11=NDIS */
-#define ee_BootTypeMask 0x3
-#define ee_NumConn 3 /* Number of Connections 0= One or Two */
-#define ee_FlashSock 4 /* Presence of Flash Socket 0= Present */
-#define ee_PortTPE 5
-#define ee_PortBNC 6
-#define ee_PortAUI 7
-#define ee_PowerMgt 10 /* 0= disabled */
-#define ee_CP 13 /* Concurrent Processing */
-#define ee_CPMask 0x7
-
-/* Word 6: */
-#define ee_Stepping 0 /* Stepping info */
-#define ee_StepMask 0x0F
-#define ee_BoardID 4 /* Manucaturer Board ID, reserved */
-#define ee_BoardMask 0x0FFF
-
-/* Word 7: */
-#define ee_INT_TO_IRQ 0 /* int to IRQ Mapping = 0x1EB8 for Pro/10+ */
-#define ee_FX_INT2IRQ 0x1EB8 /* the _only_ mapping allowed for FX chips */
-
-/*..*/
-#define ee_SIZE 0x40 /* total EEprom Size */
-#define ee_Checksum 0xBABA /* initial and final value for adding checksum */
-
-
-/* Card identification via EEprom: */
-#define ee_addr_vendor 0x10 /* Word offset for EISA Vendor ID */
-#define ee_addr_id 0x11 /* Word offset for Card ID */
-#define ee_addr_SN 0x12 /* Serial Number */
-#define ee_addr_CRC_8 0x14 /* CRC over last thee Bytes */
-
-
-#define ee_vendor_intel0 0x25 /* Vendor ID Intel */
-#define ee_vendor_intel1 0xD4
-#define ee_id_eepro10p0 0x10 /* ID for eepro/10+ */
-#define ee_id_eepro10p1 0x31
-
-#define TX_TIMEOUT ((4*HZ)/10)
-
-/* Index to functions, as function prototypes. */
-
-static int eepro_probe1(struct net_device *dev, int autoprobe);
-static int eepro_open(struct net_device *dev);
-static netdev_tx_t eepro_send_packet(struct sk_buff *skb,
- struct net_device *dev);
-static irqreturn_t eepro_interrupt(int irq, void *dev_id);
-static void eepro_rx(struct net_device *dev);
-static void eepro_transmit_interrupt(struct net_device *dev);
-static int eepro_close(struct net_device *dev);
-static void set_multicast_list(struct net_device *dev);
-static void eepro_tx_timeout (struct net_device *dev);
-
-static int read_eeprom(int ioaddr, int location, struct net_device *dev);
-static int hardware_send_packet(struct net_device *dev, void *buf, short length);
-static int eepro_grab_irq(struct net_device *dev);
-
-/*
- Details of the i82595.
-
-You will need either the datasheet or the user manual to understand what
-is going on here. The 82595 is very different from the 82586, 82593.
-
-The receive algorithm in eepro_rx() is just an implementation of the
-RCV ring structure that the Intel 82595 imposes at the hardware level.
-The receive buffer is set at 24K, and the transmit buffer is 8K. I
-am assuming that the total buffer memory is 32K, which is true for the
-Intel EtherExpress Pro/10. If it is less than that on a generic card,
-the driver will be broken.
-
-The transmit algorithm in the hardware_send_packet() is similar to the
-one in the eepro_rx(). The transmit buffer is a ring linked list.
-I just queue the next available packet to the end of the list. In my
-system, the 82595 is so fast that the list seems to always contain a
-single packet. In other systems with faster computers and more congested
-network traffics, the ring linked list should improve performance by
-allowing up to 8K worth of packets to be queued.
-
-The sizes of the receive and transmit buffers can now be changed via lilo
-or insmod. Lilo uses the appended line "ether=io,irq,debug,rx-buffer,eth0"
-where rx-buffer is in KB unit. Modules uses the parameter mem which is
-also in KB unit, for example "insmod io=io-address irq=0 mem=rx-buffer."
-The receive buffer has to be more than 3K or less than 29K. Otherwise,
-it is reset to the default of 24K, and, hence, 8K for the trasnmit
-buffer (transmit-buffer = 32K - receive-buffer).
-
-*/
-#define RAM_SIZE 0x8000
-
-#define RCV_HEADER 8
-#define RCV_DEFAULT_RAM 0x6000
-
-#define XMT_HEADER 8
-#define XMT_DEFAULT_RAM (RAM_SIZE - RCV_DEFAULT_RAM)
-
-#define XMT_START_PRO RCV_DEFAULT_RAM
-#define XMT_START_10 0x0000
-#define RCV_START_PRO 0x0000
-#define RCV_START_10 XMT_DEFAULT_RAM
-
-#define RCV_DONE 0x0008
-#define RX_OK 0x2000
-#define RX_ERROR 0x0d81
-
-#define TX_DONE_BIT 0x0080
-#define TX_OK 0x2000
-#define CHAIN_BIT 0x8000
-#define XMT_STATUS 0x02
-#define XMT_CHAIN 0x04
-#define XMT_COUNT 0x06
-
-#define BANK0_SELECT 0x00
-#define BANK1_SELECT 0x40
-#define BANK2_SELECT 0x80
-
-/* Bank 0 registers */
-#define COMMAND_REG 0x00 /* Register 0 */
-#define MC_SETUP 0x03
-#define XMT_CMD 0x04
-#define DIAGNOSE_CMD 0x07
-#define RCV_ENABLE_CMD 0x08
-#define RCV_DISABLE_CMD 0x0a
-#define STOP_RCV_CMD 0x0b
-#define RESET_CMD 0x0e
-#define POWER_DOWN_CMD 0x18
-#define RESUME_XMT_CMD 0x1c
-#define SEL_RESET_CMD 0x1e
-#define STATUS_REG 0x01 /* Register 1 */
-#define RX_INT 0x02
-#define TX_INT 0x04
-#define EXEC_STATUS 0x30
-#define ID_REG 0x02 /* Register 2 */
-#define R_ROBIN_BITS 0xc0 /* round robin counter */
-#define ID_REG_MASK 0x2c
-#define ID_REG_SIG 0x24
-#define AUTO_ENABLE 0x10
-#define INT_MASK_REG 0x03 /* Register 3 */
-#define RX_STOP_MASK 0x01
-#define RX_MASK 0x02
-#define TX_MASK 0x04
-#define EXEC_MASK 0x08
-#define ALL_MASK 0x0f
-#define IO_32_BIT 0x10
-#define RCV_BAR 0x04 /* The following are word (16-bit) registers */
-#define RCV_STOP 0x06
-
-#define XMT_BAR_PRO 0x0a
-#define XMT_BAR_10 0x0b
-
-#define HOST_ADDRESS_REG 0x0c
-#define IO_PORT 0x0e
-#define IO_PORT_32_BIT 0x0c
-
-/* Bank 1 registers */
-#define REG1 0x01
-#define WORD_WIDTH 0x02
-#define INT_ENABLE 0x80
-#define INT_NO_REG 0x02
-#define RCV_LOWER_LIMIT_REG 0x08
-#define RCV_UPPER_LIMIT_REG 0x09
-
-#define XMT_LOWER_LIMIT_REG_PRO 0x0a
-#define XMT_UPPER_LIMIT_REG_PRO 0x0b
-#define XMT_LOWER_LIMIT_REG_10 0x0b
-#define XMT_UPPER_LIMIT_REG_10 0x0a
-
-/* Bank 2 registers */
-#define XMT_Chain_Int 0x20 /* Interrupt at the end of the transmit chain */
-#define XMT_Chain_ErrStop 0x40 /* Interrupt at the end of the chain even if there are errors */
-#define RCV_Discard_BadFrame 0x80 /* Throw bad frames away, and continue to receive others */
-#define REG2 0x02
-#define PRMSC_Mode 0x01
-#define Multi_IA 0x20
-#define REG3 0x03
-#define TPE_BIT 0x04
-#define BNC_BIT 0x20
-#define REG13 0x0d
-#define FDX 0x00
-#define A_N_ENABLE 0x02
-
-#define I_ADD_REG0 0x04
-#define I_ADD_REG1 0x05
-#define I_ADD_REG2 0x06
-#define I_ADD_REG3 0x07
-#define I_ADD_REG4 0x08
-#define I_ADD_REG5 0x09
-
-#define EEPROM_REG_PRO 0x0a
-#define EEPROM_REG_10 0x0b
-
-#define EESK 0x01
-#define EECS 0x02
-#define EEDI 0x04
-#define EEDO 0x08
-
-/* do a full reset */
-#define eepro_reset(ioaddr) outb(RESET_CMD, ioaddr)
-
-/* do a nice reset */
-#define eepro_sel_reset(ioaddr) { \
- outb(SEL_RESET_CMD, ioaddr); \
- SLOW_DOWN; \
- SLOW_DOWN; \
- }
-
-/* disable all interrupts */
-#define eepro_dis_int(ioaddr) outb(ALL_MASK, ioaddr + INT_MASK_REG)
-
-/* clear all interrupts */
-#define eepro_clear_int(ioaddr) outb(ALL_MASK, ioaddr + STATUS_REG)
-
-/* enable tx/rx */
-#define eepro_en_int(ioaddr) outb(ALL_MASK & ~(RX_MASK | TX_MASK), \
- ioaddr + INT_MASK_REG)
-
-/* enable exec event interrupt */
-#define eepro_en_intexec(ioaddr) outb(ALL_MASK & ~(EXEC_MASK), ioaddr + INT_MASK_REG)
-
-/* enable rx */
-#define eepro_en_rx(ioaddr) outb(RCV_ENABLE_CMD, ioaddr)
-
-/* disable rx */
-#define eepro_dis_rx(ioaddr) outb(RCV_DISABLE_CMD, ioaddr)
-
-/* switch bank */
-#define eepro_sw2bank0(ioaddr) outb(BANK0_SELECT, ioaddr)
-#define eepro_sw2bank1(ioaddr) outb(BANK1_SELECT, ioaddr)
-#define eepro_sw2bank2(ioaddr) outb(BANK2_SELECT, ioaddr)
-
-/* enable interrupt line */
-#define eepro_en_intline(ioaddr) outb(inb(ioaddr + REG1) | INT_ENABLE,\
- ioaddr + REG1)
-
-/* disable interrupt line */
-#define eepro_dis_intline(ioaddr) outb(inb(ioaddr + REG1) & 0x7f, \
- ioaddr + REG1);
-
-/* set diagnose flag */
-#define eepro_diag(ioaddr) outb(DIAGNOSE_CMD, ioaddr)
-
-/* ack for rx int */
-#define eepro_ack_rx(ioaddr) outb (RX_INT, ioaddr + STATUS_REG)
-
-/* ack for tx int */
-#define eepro_ack_tx(ioaddr) outb (TX_INT, ioaddr + STATUS_REG)
-
-/* a complete sel reset */
-#define eepro_complete_selreset(ioaddr) { \
- dev->stats.tx_errors++;\
- eepro_sel_reset(ioaddr);\
- lp->tx_end = \
- lp->xmt_lower_limit;\
- lp->tx_start = lp->tx_end;\
- lp->tx_last = 0;\
- dev->trans_start = jiffies;\
- netif_wake_queue(dev);\
- eepro_en_rx(ioaddr);\
- }
-
-/* Check for a network adaptor of this type, and return '0' if one exists.
- If dev->base_addr == 0, probe all likely locations.
- If dev->base_addr == 1, always return failure.
- If dev->base_addr == 2, allocate space for the device and return success
- (detachable devices only).
- */
-static int __init do_eepro_probe(struct net_device *dev)
-{
- int i;
- int base_addr = dev->base_addr;
- int irq = dev->irq;
-
-#ifdef PnPWakeup
- /* XXXX for multiple cards should this only be run once? */
-
- /* Wakeup: */
- #define WakeupPort 0x279
- #define WakeupSeq {0x6A, 0xB5, 0xDA, 0xED, 0xF6, 0xFB, 0x7D, 0xBE,\
- 0xDF, 0x6F, 0x37, 0x1B, 0x0D, 0x86, 0xC3, 0x61,\
- 0xB0, 0x58, 0x2C, 0x16, 0x8B, 0x45, 0xA2, 0xD1,\
- 0xE8, 0x74, 0x3A, 0x9D, 0xCE, 0xE7, 0x73, 0x43}
-
- {
- unsigned short int WS[32]=WakeupSeq;
-
- if (request_region(WakeupPort, 2, "eepro wakeup")) {
- if (net_debug>5)
- printk(KERN_DEBUG "Waking UP\n");
-
- outb_p(0,WakeupPort);
- outb_p(0,WakeupPort);
- for (i=0; i<32; i++) {
- outb_p(WS[i],WakeupPort);
- if (net_debug>5) printk(KERN_DEBUG ": %#x ",WS[i]);
- }
-
- release_region(WakeupPort, 2);
- } else
- printk(KERN_WARNING "PnP wakeup region busy!\n");
- }
-#endif
-
- if (base_addr > 0x1ff) /* Check a single specified location. */
- return eepro_probe1(dev, 0);
-
- else if (base_addr != 0) /* Don't probe at all. */
- return -ENXIO;
-
- for (i = 0; eepro_portlist[i]; i++) {
- dev->base_addr = eepro_portlist[i];
- dev->irq = irq;
- if (eepro_probe1(dev, 1) == 0)
- return 0;
- }
-
- return -ENODEV;
-}
-
-#ifndef MODULE
-struct net_device * __init eepro_probe(int unit)
-{
- struct net_device *dev = alloc_etherdev(sizeof(struct eepro_local));
- int err;
-
- if (!dev)
- return ERR_PTR(-ENODEV);
-
- sprintf(dev->name, "eth%d", unit);
- netdev_boot_setup_check(dev);
-
- err = do_eepro_probe(dev);
- if (err)
- goto out;
- return dev;
-out:
- free_netdev(dev);
- return ERR_PTR(err);
-}
-#endif
-
-static void __init printEEPROMInfo(struct net_device *dev)
-{
- struct eepro_local *lp = netdev_priv(dev);
- int ioaddr = dev->base_addr;
- unsigned short Word;
- int i,j;
-
- j = ee_Checksum;
- for (i = 0; i < 8; i++)
- j += lp->word[i];
- for ( ; i < ee_SIZE; i++)
- j += read_eeprom(ioaddr, i, dev);
-
- printk(KERN_DEBUG "Checksum: %#x\n",j&0xffff);
-
- Word = lp->word[0];
- printk(KERN_DEBUG "Word0:\n");
- printk(KERN_DEBUG " Plug 'n Pray: %d\n",GetBit(Word,ee_PnP));
- printk(KERN_DEBUG " Buswidth: %d\n",(GetBit(Word,ee_BusWidth)+1)*8 );
- printk(KERN_DEBUG " AutoNegotiation: %d\n",GetBit(Word,ee_AutoNeg));
- printk(KERN_DEBUG " IO Address: %#x\n", (Word>>ee_IO0)<<4);
-
- if (net_debug>4) {
- Word = lp->word[1];
- printk(KERN_DEBUG "Word1:\n");
- printk(KERN_DEBUG " INT: %d\n", Word & ee_IntMask);
- printk(KERN_DEBUG " LI: %d\n", GetBit(Word,ee_LI));
- printk(KERN_DEBUG " PC: %d\n", GetBit(Word,ee_PC));
- printk(KERN_DEBUG " TPE/AUI: %d\n", GetBit(Word,ee_TPE_AUI));
- printk(KERN_DEBUG " Jabber: %d\n", GetBit(Word,ee_Jabber));
- printk(KERN_DEBUG " AutoPort: %d\n", !GetBit(Word,ee_AutoPort));
- printk(KERN_DEBUG " Duplex: %d\n", GetBit(Word,ee_Duplex));
- }
-
- Word = lp->word[5];
- printk(KERN_DEBUG "Word5:\n");
- printk(KERN_DEBUG " BNC: %d\n",GetBit(Word,ee_BNC_TPE));
- printk(KERN_DEBUG " NumConnectors: %d\n",GetBit(Word,ee_NumConn));
- printk(KERN_DEBUG " Has ");
- if (GetBit(Word,ee_PortTPE)) printk(KERN_DEBUG "TPE ");
- if (GetBit(Word,ee_PortBNC)) printk(KERN_DEBUG "BNC ");
- if (GetBit(Word,ee_PortAUI)) printk(KERN_DEBUG "AUI ");
- printk(KERN_DEBUG "port(s)\n");
-
- Word = lp->word[6];
- printk(KERN_DEBUG "Word6:\n");
- printk(KERN_DEBUG " Stepping: %d\n",Word & ee_StepMask);
- printk(KERN_DEBUG " BoardID: %d\n",Word>>ee_BoardID);
-
- Word = lp->word[7];
- printk(KERN_DEBUG "Word7:\n");
- printk(KERN_DEBUG " INT to IRQ:\n");
-
- for (i=0, j=0; i<15; i++)
- if (GetBit(Word,i)) printk(KERN_DEBUG " INT%d -> IRQ %d;",j++,i);
-
- printk(KERN_DEBUG "\n");
-}
-
-/* function to recalculate the limits of buffer based on rcv_ram */
-static void eepro_recalc (struct net_device *dev)
-{
- struct eepro_local * lp;
-
- lp = netdev_priv(dev);
- lp->xmt_ram = RAM_SIZE - lp->rcv_ram;
-
- if (lp->eepro == LAN595FX_10ISA) {
- lp->xmt_lower_limit = XMT_START_10;
- lp->xmt_upper_limit = (lp->xmt_ram - 2);
- lp->rcv_lower_limit = lp->xmt_ram;
- lp->rcv_upper_limit = (RAM_SIZE - 2);
- }
- else {
- lp->rcv_lower_limit = RCV_START_PRO;
- lp->rcv_upper_limit = (lp->rcv_ram - 2);
- lp->xmt_lower_limit = lp->rcv_ram;
- lp->xmt_upper_limit = (RAM_SIZE - 2);
- }
-}
-
-/* prints boot-time info */
-static void __init eepro_print_info (struct net_device *dev)
-{
- struct eepro_local * lp = netdev_priv(dev);
- int i;
- const char * ifmap[] = {"AUI", "10Base2", "10BaseT"};
-
- i = inb(dev->base_addr + ID_REG);
- printk(KERN_DEBUG " id: %#x ",i);
- printk(" io: %#x ", (unsigned)dev->base_addr);
-
- switch (lp->eepro) {
- case LAN595FX_10ISA:
- printk("%s: Intel EtherExpress 10 ISA\n at %#x,",
- dev->name, (unsigned)dev->base_addr);
- break;
- case LAN595FX:
- printk("%s: Intel EtherExpress Pro/10+ ISA\n at %#x,",
- dev->name, (unsigned)dev->base_addr);
- break;
- case LAN595TX:
- printk("%s: Intel EtherExpress Pro/10 ISA at %#x,",
- dev->name, (unsigned)dev->base_addr);
- break;
- case LAN595:
- printk("%s: Intel 82595-based lan card at %#x,",
- dev->name, (unsigned)dev->base_addr);
- break;
- }
-
- printk(" %pM", dev->dev_addr);
-
- if (net_debug > 3)
- printk(KERN_DEBUG ", %dK RCV buffer",
- (int)(lp->rcv_ram)/1024);
-
- if (dev->irq > 2)
- printk(", IRQ %d, %s.\n", dev->irq, ifmap[dev->if_port]);
- else
- printk(", %s.\n", ifmap[dev->if_port]);
-
- if (net_debug > 3) {
- i = lp->word[5];
- if (i & 0x2000) /* bit 13 of EEPROM word 5 */
- printk(KERN_DEBUG "%s: Concurrent Processing is "
- "enabled but not used!\n", dev->name);
- }
-
- /* Check the station address for the manufacturer's code */
- if (net_debug>3)
- printEEPROMInfo(dev);
-}
-
-static const struct ethtool_ops eepro_ethtool_ops;
-
-static const struct net_device_ops eepro_netdev_ops = {
- .ndo_open = eepro_open,
- .ndo_stop = eepro_close,
- .ndo_start_xmit = eepro_send_packet,
- .ndo_set_rx_mode = set_multicast_list,
- .ndo_tx_timeout = eepro_tx_timeout,
- .ndo_change_mtu = eth_change_mtu,
- .ndo_set_mac_address = eth_mac_addr,
- .ndo_validate_addr = eth_validate_addr,
-};
-
-/* This is the real probe routine. Linux has a history of friendly device
- probes on the ISA bus. A good device probe avoids doing writes, and
- verifies that the correct device exists and functions. */
-
-static int __init eepro_probe1(struct net_device *dev, int autoprobe)
-{
- unsigned short station_addr[3], id, counter;
- int i;
- struct eepro_local *lp;
- int ioaddr = dev->base_addr;
- int err;
-
- /* Grab the region so we can find another board if autoIRQ fails. */
- if (!request_region(ioaddr, EEPRO_IO_EXTENT, DRV_NAME)) {
- if (!autoprobe)
- printk(KERN_WARNING "EEPRO: io-port 0x%04x in use\n",
- ioaddr);
- return -EBUSY;
- }
-
- /* Now, we are going to check for the signature of the
- ID_REG (register 2 of bank 0) */
-
- id = inb(ioaddr + ID_REG);
-
- if ((id & ID_REG_MASK) != ID_REG_SIG)
- goto exit;
-
- /* We seem to have the 82595 signature, let's
- play with its counter (last 2 bits of
- register 2 of bank 0) to be sure. */
-
- counter = id & R_ROBIN_BITS;
-
- if ((inb(ioaddr + ID_REG) & R_ROBIN_BITS) != (counter + 0x40))
- goto exit;
-
- lp = netdev_priv(dev);
- memset(lp, 0, sizeof(struct eepro_local));
- lp->xmt_bar = XMT_BAR_PRO;
- lp->xmt_lower_limit_reg = XMT_LOWER_LIMIT_REG_PRO;
- lp->xmt_upper_limit_reg = XMT_UPPER_LIMIT_REG_PRO;
- lp->eeprom_reg = EEPROM_REG_PRO;
- spin_lock_init(&lp->lock);
-
- /* Now, get the ethernet hardware address from
- the EEPROM */
- station_addr[0] = read_eeprom(ioaddr, 2, dev);
-
- /* FIXME - find another way to know that we've found
- * an Etherexpress 10
- */
- if (station_addr[0] == 0x0000 || station_addr[0] == 0xffff) {
- lp->eepro = LAN595FX_10ISA;
- lp->eeprom_reg = EEPROM_REG_10;
- lp->xmt_lower_limit_reg = XMT_LOWER_LIMIT_REG_10;
- lp->xmt_upper_limit_reg = XMT_UPPER_LIMIT_REG_10;
- lp->xmt_bar = XMT_BAR_10;
- station_addr[0] = read_eeprom(ioaddr, 2, dev);
- }
-
- /* get all words at once. will be used here and for ethtool */
- for (i = 0; i < 8; i++) {
- lp->word[i] = read_eeprom(ioaddr, i, dev);
- }
- station_addr[1] = lp->word[3];
- station_addr[2] = lp->word[4];
-
- if (!lp->eepro) {
- if (lp->word[7] == ee_FX_INT2IRQ)
- lp->eepro = 2;
- else if (station_addr[2] == SA_ADDR1)
- lp->eepro = 1;
- }
-
- /* Fill in the 'dev' fields. */
- for (i=0; i < 6; i++)
- dev->dev_addr[i] = ((unsigned char *) station_addr)[5-i];
-
- /* RX buffer must be more than 3K and less than 29K */
- if (dev->mem_end < 3072 || dev->mem_end > 29696)
- lp->rcv_ram = RCV_DEFAULT_RAM;
-
- /* calculate {xmt,rcv}_{lower,upper}_limit */
- eepro_recalc(dev);
-
- if (GetBit(lp->word[5], ee_BNC_TPE))
- dev->if_port = BNC;
- else
- dev->if_port = TPE;
-
- if (dev->irq < 2 && lp->eepro != 0) {
- /* Mask off INT number */
- int count = lp->word[1] & 7;
- unsigned irqMask = lp->word[7];
-
- while (count--)
- irqMask &= irqMask - 1;
-
- count = ffs(irqMask);
-
- if (count)
- dev->irq = count - 1;
-
- if (dev->irq < 2) {
- printk(KERN_ERR " Duh! illegal interrupt vector stored in EEPROM.\n");
- goto exit;
- } else if (dev->irq == 2) {
- dev->irq = 9;
- }
- }
-
- dev->netdev_ops = &eepro_netdev_ops;
- dev->watchdog_timeo = TX_TIMEOUT;
- dev->ethtool_ops = &eepro_ethtool_ops;
-
- /* print boot time info */
- eepro_print_info(dev);
-
- /* reset 82595 */
- eepro_reset(ioaddr);
-
- err = register_netdev(dev);
- if (err)
- goto err;
- return 0;
-exit:
- err = -ENODEV;
-err:
- release_region(dev->base_addr, EEPRO_IO_EXTENT);
- return err;
-}
-
-/* Open/initialize the board. This is called (in the current kernel)
- sometime after booting when the 'ifconfig' program is run.
-
- This routine should set everything up anew at each open, even
- registers that "should" only need to be set once at boot, so that
- there is non-reboot way to recover if something goes wrong.
- */
-
-static const char irqrmap[] = {-1,-1,0,1,-1,2,-1,-1,-1,0,3,4,-1,-1,-1,-1};
-static const char irqrmap2[] = {-1,-1,4,0,1,2,-1,3,-1,4,5,6,7,-1,-1,-1};
-static int eepro_grab_irq(struct net_device *dev)
-{
- static const int irqlist[] = { 3, 4, 5, 7, 9, 10, 11, 12, 0 };
- const int *irqp = irqlist;
- int temp_reg, ioaddr = dev->base_addr;
-
- eepro_sw2bank1(ioaddr); /* be CAREFUL, BANK 1 now */
-
- /* Enable the interrupt line. */
- eepro_en_intline(ioaddr);
-
- /* be CAREFUL, BANK 0 now */
- eepro_sw2bank0(ioaddr);
-
- /* clear all interrupts */
- eepro_clear_int(ioaddr);
-
- /* Let EXEC event to interrupt */
- eepro_en_intexec(ioaddr);
-
- do {
- eepro_sw2bank1(ioaddr); /* be CAREFUL, BANK 1 now */
-
- temp_reg = inb(ioaddr + INT_NO_REG);
- outb((temp_reg & 0xf8) | irqrmap[*irqp], ioaddr + INT_NO_REG);
-
- eepro_sw2bank0(ioaddr); /* Switch back to Bank 0 */
-
- if (request_irq (*irqp, NULL, IRQF_SHARED, "bogus", dev) != EBUSY) {
- unsigned long irq_mask;
- /* Twinkle the interrupt, and check if it's seen */
- irq_mask = probe_irq_on();
-
- eepro_diag(ioaddr); /* RESET the 82595 */
- mdelay(20);
-
- if (*irqp == probe_irq_off(irq_mask)) /* It's a good IRQ line */
- break;
-
- /* clear all interrupts */
- eepro_clear_int(ioaddr);
- }
- } while (*++irqp);
-
- eepro_sw2bank1(ioaddr); /* Switch back to Bank 1 */
-
- /* Disable the physical interrupt line. */
- eepro_dis_intline(ioaddr);
-
- eepro_sw2bank0(ioaddr); /* Switch back to Bank 0 */
-
- /* Mask all the interrupts. */
- eepro_dis_int(ioaddr);
-
- /* clear all interrupts */
- eepro_clear_int(ioaddr);
-
- return dev->irq;
-}
-
-static int eepro_open(struct net_device *dev)
-{
- unsigned short temp_reg, old8, old9;
- int irqMask;
- int i, ioaddr = dev->base_addr;
- struct eepro_local *lp = netdev_priv(dev);
-
- if (net_debug > 3)
- printk(KERN_DEBUG "%s: entering eepro_open routine.\n", dev->name);
-
- irqMask = lp->word[7];
-
- if (lp->eepro == LAN595FX_10ISA) {
- if (net_debug > 3) printk(KERN_DEBUG "p->eepro = 3;\n");
- }
- else if (irqMask == ee_FX_INT2IRQ) /* INT to IRQ Mask */
- {
- lp->eepro = 2; /* Yes, an Intel EtherExpress Pro/10+ */
- if (net_debug > 3) printk(KERN_DEBUG "p->eepro = 2;\n");
- }
-
- else if ((dev->dev_addr[0] == SA_ADDR0 &&
- dev->dev_addr[1] == SA_ADDR1 &&
- dev->dev_addr[2] == SA_ADDR2))
- {
- lp->eepro = 1;
- if (net_debug > 3) printk(KERN_DEBUG "p->eepro = 1;\n");
- } /* Yes, an Intel EtherExpress Pro/10 */
-
- else lp->eepro = 0; /* No, it is a generic 82585 lan card */
-
- /* Get the interrupt vector for the 82595 */
- if (dev->irq < 2 && eepro_grab_irq(dev) == 0) {
- printk(KERN_ERR "%s: unable to get IRQ %d.\n", dev->name, dev->irq);
- return -EAGAIN;
- }
-
- if (request_irq(dev->irq , eepro_interrupt, 0, dev->name, dev)) {
- printk(KERN_ERR "%s: unable to get IRQ %d.\n", dev->name, dev->irq);
- return -EAGAIN;
- }
-
- /* Initialize the 82595. */
-
- eepro_sw2bank2(ioaddr); /* be CAREFUL, BANK 2 now */
- temp_reg = inb(ioaddr + lp->eeprom_reg);
-
- lp->stepping = temp_reg >> 5; /* Get the stepping number of the 595 */
-
- if (net_debug > 3)
- printk(KERN_DEBUG "The stepping of the 82595 is %d\n", lp->stepping);
-
- if (temp_reg & 0x10) /* Check the TurnOff Enable bit */
- outb(temp_reg & 0xef, ioaddr + lp->eeprom_reg);
- for (i=0; i < 6; i++)
- outb(dev->dev_addr[i] , ioaddr + I_ADD_REG0 + i);
-
- temp_reg = inb(ioaddr + REG1); /* Setup Transmit Chaining */
- outb(temp_reg | XMT_Chain_Int | XMT_Chain_ErrStop /* and discard bad RCV frames */
- | RCV_Discard_BadFrame, ioaddr + REG1);
-
- temp_reg = inb(ioaddr + REG2); /* Match broadcast */
- outb(temp_reg | 0x14, ioaddr + REG2);
-
- temp_reg = inb(ioaddr + REG3);
- outb(temp_reg & 0x3f, ioaddr + REG3); /* clear test mode */
-
- /* Set the receiving mode */
- eepro_sw2bank1(ioaddr); /* be CAREFUL, BANK 1 now */
-
- /* Set the interrupt vector */
- temp_reg = inb(ioaddr + INT_NO_REG);
- if (lp->eepro == LAN595FX || lp->eepro == LAN595FX_10ISA)
- outb((temp_reg & 0xf8) | irqrmap2[dev->irq], ioaddr + INT_NO_REG);
- else outb((temp_reg & 0xf8) | irqrmap[dev->irq], ioaddr + INT_NO_REG);
-
-
- temp_reg = inb(ioaddr + INT_NO_REG);
- if (lp->eepro == LAN595FX || lp->eepro == LAN595FX_10ISA)
- outb((temp_reg & 0xf0) | irqrmap2[dev->irq] | 0x08,ioaddr+INT_NO_REG);
- else outb((temp_reg & 0xf8) | irqrmap[dev->irq], ioaddr + INT_NO_REG);
-
- if (net_debug > 3)
- printk(KERN_DEBUG "eepro_open: content of INT Reg is %x\n", temp_reg);
-
-
- /* Initialize the RCV and XMT upper and lower limits */
- outb(lp->rcv_lower_limit >> 8, ioaddr + RCV_LOWER_LIMIT_REG);
- outb(lp->rcv_upper_limit >> 8, ioaddr + RCV_UPPER_LIMIT_REG);
- outb(lp->xmt_lower_limit >> 8, ioaddr + lp->xmt_lower_limit_reg);
- outb(lp->xmt_upper_limit >> 8, ioaddr + lp->xmt_upper_limit_reg);
-
- /* Enable the interrupt line. */
- eepro_en_intline(ioaddr);
-
- /* Switch back to Bank 0 */
- eepro_sw2bank0(ioaddr);
-
- /* Let RX and TX events to interrupt */
- eepro_en_int(ioaddr);
-
- /* clear all interrupts */
- eepro_clear_int(ioaddr);
-
- /* Initialize RCV */
- outw(lp->rcv_lower_limit, ioaddr + RCV_BAR);
- lp->rx_start = lp->rcv_lower_limit;
- outw(lp->rcv_upper_limit | 0xfe, ioaddr + RCV_STOP);
-
- /* Initialize XMT */
- outw(lp->xmt_lower_limit, ioaddr + lp->xmt_bar);
- lp->tx_start = lp->tx_end = lp->xmt_lower_limit;
- lp->tx_last = 0;
-
- /* Check for the i82595TX and i82595FX */
- old8 = inb(ioaddr + 8);
- outb(~old8, ioaddr + 8);
-
- if ((temp_reg = inb(ioaddr + 8)) == old8) {
- if (net_debug > 3)
- printk(KERN_DEBUG "i82595 detected!\n");
- lp->version = LAN595;
- }
- else {
- lp->version = LAN595TX;
- outb(old8, ioaddr + 8);
- old9 = inb(ioaddr + 9);
-
- if (irqMask==ee_FX_INT2IRQ) {
- if (net_debug > 3) {
- printk(KERN_DEBUG "IrqMask: %#x\n",irqMask);
- printk(KERN_DEBUG "i82595FX detected!\n");
- }
- lp->version = LAN595FX;
- outb(old9, ioaddr + 9);
- if (dev->if_port != TPE) { /* Hopefully, this will fix the
- problem of using Pentiums and
- pro/10 w/ BNC. */
- eepro_sw2bank2(ioaddr); /* be CAREFUL, BANK 2 now */
- temp_reg = inb(ioaddr + REG13);
- /* disable the full duplex mode since it is not
- applicable with the 10Base2 cable. */
- outb(temp_reg & ~(FDX | A_N_ENABLE), REG13);
- eepro_sw2bank0(ioaddr); /* be CAREFUL, BANK 0 now */
- }
- }
- else if (net_debug > 3) {
- printk(KERN_DEBUG "temp_reg: %#x ~old9: %#x\n",temp_reg,((~old9)&0xff));
- printk(KERN_DEBUG "i82595TX detected!\n");
- }
- }
-
- eepro_sel_reset(ioaddr);
-
- netif_start_queue(dev);
-
- if (net_debug > 3)
- printk(KERN_DEBUG "%s: exiting eepro_open routine.\n", dev->name);
-
- /* enabling rx */
- eepro_en_rx(ioaddr);
-
- return 0;
-}
-
-static void eepro_tx_timeout (struct net_device *dev)
-{
- struct eepro_local *lp = netdev_priv(dev);
- int ioaddr = dev->base_addr;
-
- /* if (net_debug > 1) */
- printk (KERN_ERR "%s: transmit timed out, %s?\n", dev->name,
- "network cable problem");
- /* This is not a duplicate. One message for the console,
- one for the log file */
- printk (KERN_DEBUG "%s: transmit timed out, %s?\n", dev->name,
- "network cable problem");
- eepro_complete_selreset(ioaddr);
-}
-
-
-static netdev_tx_t eepro_send_packet(struct sk_buff *skb,
- struct net_device *dev)
-{
- struct eepro_local *lp = netdev_priv(dev);
- unsigned long flags;
- int ioaddr = dev->base_addr;
- short length = skb->len;
-
- if (net_debug > 5)
- printk(KERN_DEBUG "%s: entering eepro_send_packet routine.\n", dev->name);
-
- if (length < ETH_ZLEN) {
- if (skb_padto(skb, ETH_ZLEN))
- return NETDEV_TX_OK;
- length = ETH_ZLEN;
- }
- netif_stop_queue (dev);
-
- eepro_dis_int(ioaddr);
- spin_lock_irqsave(&lp->lock, flags);
-
- {
- unsigned char *buf = skb->data;
-
- if (hardware_send_packet(dev, buf, length))
- /* we won't wake queue here because we're out of space */
- dev->stats.tx_dropped++;
- else {
- dev->stats.tx_bytes+=skb->len;
- netif_wake_queue(dev);
- }
-
- }
-
- dev_kfree_skb (skb);
-
- /* You might need to clean up and record Tx statistics here. */
- /* dev->stats.tx_aborted_errors++; */
-
- if (net_debug > 5)
- printk(KERN_DEBUG "%s: exiting eepro_send_packet routine.\n", dev->name);
-
- eepro_en_int(ioaddr);
- spin_unlock_irqrestore(&lp->lock, flags);
-
- return NETDEV_TX_OK;
-}
-
-
-/* The typical workload of the driver:
- Handle the network interface interrupts. */
-
-static irqreturn_t
-eepro_interrupt(int irq, void *dev_id)
-{
- struct net_device *dev = dev_id;
- struct eepro_local *lp;
- int ioaddr, status, boguscount = 20;
- int handled = 0;
-
- lp = netdev_priv(dev);
-
- spin_lock(&lp->lock);
-
- if (net_debug > 5)
- printk(KERN_DEBUG "%s: entering eepro_interrupt routine.\n", dev->name);
-
- ioaddr = dev->base_addr;
-
- while (((status = inb(ioaddr + STATUS_REG)) & (RX_INT|TX_INT)) && (boguscount--))
- {
- handled = 1;
- if (status & RX_INT) {
- if (net_debug > 4)
- printk(KERN_DEBUG "%s: packet received interrupt.\n", dev->name);
-
- eepro_dis_int(ioaddr);
-
- /* Get the received packets */
- eepro_ack_rx(ioaddr);
- eepro_rx(dev);
-
- eepro_en_int(ioaddr);
- }
- if (status & TX_INT) {
- if (net_debug > 4)
- printk(KERN_DEBUG "%s: packet transmit interrupt.\n", dev->name);
-
-
- eepro_dis_int(ioaddr);
-
- /* Process the status of transmitted packets */
- eepro_ack_tx(ioaddr);
- eepro_transmit_interrupt(dev);
-
- eepro_en_int(ioaddr);
- }
- }
-
- if (net_debug > 5)
- printk(KERN_DEBUG "%s: exiting eepro_interrupt routine.\n", dev->name);
-
- spin_unlock(&lp->lock);
- return IRQ_RETVAL(handled);
-}
-
-static int eepro_close(struct net_device *dev)
-{
- struct eepro_local *lp = netdev_priv(dev);
- int ioaddr = dev->base_addr;
- short temp_reg;
-
- netif_stop_queue(dev);
-
- eepro_sw2bank1(ioaddr); /* Switch back to Bank 1 */
-
- /* Disable the physical interrupt line. */
- temp_reg = inb(ioaddr + REG1);
- outb(temp_reg & 0x7f, ioaddr + REG1);
-
- eepro_sw2bank0(ioaddr); /* Switch back to Bank 0 */
-
- /* Flush the Tx and disable Rx. */
- outb(STOP_RCV_CMD, ioaddr);
- lp->tx_start = lp->tx_end = lp->xmt_lower_limit;
- lp->tx_last = 0;
-
- /* Mask all the interrupts. */
- eepro_dis_int(ioaddr);
-
- /* clear all interrupts */
- eepro_clear_int(ioaddr);
-
- /* Reset the 82595 */
- eepro_reset(ioaddr);
-
- /* release the interrupt */
- free_irq(dev->irq, dev);
-
- /* Update the statistics here. What statistics? */
-
- return 0;
-}
-
-/* Set or clear the multicast filter for this adaptor.
- */
-static void
-set_multicast_list(struct net_device *dev)
-{
- struct eepro_local *lp = netdev_priv(dev);
- short ioaddr = dev->base_addr;
- unsigned short mode;
- struct netdev_hw_addr *ha;
- int mc_count = netdev_mc_count(dev);
-
- if (dev->flags&(IFF_ALLMULTI|IFF_PROMISC) || mc_count > 63)
- {
- eepro_sw2bank2(ioaddr); /* be CAREFUL, BANK 2 now */
- mode = inb(ioaddr + REG2);
- outb(mode | PRMSC_Mode, ioaddr + REG2);
- mode = inb(ioaddr + REG3);
- outb(mode, ioaddr + REG3); /* writing reg. 3 to complete the update */
- eepro_sw2bank0(ioaddr); /* Return to BANK 0 now */
- }
-
- else if (mc_count == 0)
- {
- eepro_sw2bank2(ioaddr); /* be CAREFUL, BANK 2 now */
- mode = inb(ioaddr + REG2);
- outb(mode & 0xd6, ioaddr + REG2); /* Turn off Multi-IA and PRMSC_Mode bits */
- mode = inb(ioaddr + REG3);
- outb(mode, ioaddr + REG3); /* writing reg. 3 to complete the update */
- eepro_sw2bank0(ioaddr); /* Return to BANK 0 now */
- }
-
- else
- {
- unsigned short status, *eaddrs;
- int i, boguscount = 0;
-
- /* Disable RX and TX interrupts. Necessary to avoid
- corruption of the HOST_ADDRESS_REG by interrupt
- service routines. */
- eepro_dis_int(ioaddr);
-
- eepro_sw2bank2(ioaddr); /* be CAREFUL, BANK 2 now */
- mode = inb(ioaddr + REG2);
- outb(mode | Multi_IA, ioaddr + REG2);
- mode = inb(ioaddr + REG3);
- outb(mode, ioaddr + REG3); /* writing reg. 3 to complete the update */
- eepro_sw2bank0(ioaddr); /* Return to BANK 0 now */
- outw(lp->tx_end, ioaddr + HOST_ADDRESS_REG);
- outw(MC_SETUP, ioaddr + IO_PORT);
- outw(0, ioaddr + IO_PORT);
- outw(0, ioaddr + IO_PORT);
- outw(6 * (mc_count + 1), ioaddr + IO_PORT);
-
- netdev_for_each_mc_addr(ha, dev) {
- eaddrs = (unsigned short *) ha->addr;
- outw(*eaddrs++, ioaddr + IO_PORT);
- outw(*eaddrs++, ioaddr + IO_PORT);
- outw(*eaddrs++, ioaddr + IO_PORT);
- }
-
- eaddrs = (unsigned short *) dev->dev_addr;
- outw(eaddrs[0], ioaddr + IO_PORT);
- outw(eaddrs[1], ioaddr + IO_PORT);
- outw(eaddrs[2], ioaddr + IO_PORT);
- outw(lp->tx_end, ioaddr + lp->xmt_bar);
- outb(MC_SETUP, ioaddr);
-
- /* Update the transmit queue */
- i = lp->tx_end + XMT_HEADER + 6 * (mc_count + 1);
-
- if (lp->tx_start != lp->tx_end)
- {
- /* update the next address and the chain bit in the
- last packet */
- outw(lp->tx_last + XMT_CHAIN, ioaddr + HOST_ADDRESS_REG);
- outw(i, ioaddr + IO_PORT);
- outw(lp->tx_last + XMT_COUNT, ioaddr + HOST_ADDRESS_REG);
- status = inw(ioaddr + IO_PORT);
- outw(status | CHAIN_BIT, ioaddr + IO_PORT);
- lp->tx_end = i ;
- }
- else {
- lp->tx_start = lp->tx_end = i ;
- }
-
- /* Acknowledge that the MC setup is done */
- do { /* We should be doing this in the eepro_interrupt()! */
- SLOW_DOWN;
- SLOW_DOWN;
- if (inb(ioaddr + STATUS_REG) & 0x08)
- {
- i = inb(ioaddr);
- outb(0x08, ioaddr + STATUS_REG);
-
- if (i & 0x20) { /* command ABORTed */
- printk(KERN_NOTICE "%s: multicast setup failed.\n",
- dev->name);
- break;
- } else if ((i & 0x0f) == 0x03) { /* MC-Done */
- printk(KERN_DEBUG "%s: set Rx mode to %d address%s.\n",
- dev->name, mc_count,
- mc_count > 1 ? "es":"");
- break;
- }
- }
- } while (++boguscount < 100);
-
- /* Re-enable RX and TX interrupts */
- eepro_en_int(ioaddr);
- }
- if (lp->eepro == LAN595FX_10ISA) {
- eepro_complete_selreset(ioaddr);
- }
- else
- eepro_en_rx(ioaddr);
-}
-
-/* The horrible routine to read a word from the serial EEPROM. */
-/* IMPORTANT - the 82595 will be set to Bank 0 after the eeprom is read */
-
-/* The delay between EEPROM clock transitions. */
-#define eeprom_delay() { udelay(40); }
-#define EE_READ_CMD (6 << 6)
-
-static int
-read_eeprom(int ioaddr, int location, struct net_device *dev)
-{
- int i;
- unsigned short retval = 0;
- struct eepro_local *lp = netdev_priv(dev);
- short ee_addr = ioaddr + lp->eeprom_reg;
- int read_cmd = location | EE_READ_CMD;
- short ctrl_val = EECS ;
-
- /* XXXX - black magic */
- eepro_sw2bank1(ioaddr);
- outb(0x00, ioaddr + STATUS_REG);
- /* XXXX - black magic */
-
- eepro_sw2bank2(ioaddr);
- outb(ctrl_val, ee_addr);
-
- /* Shift the read command bits out. */
- for (i = 8; i >= 0; i--) {
- short outval = (read_cmd & (1 << i)) ? ctrl_val | EEDI
- : ctrl_val;
- outb(outval, ee_addr);
- outb(outval | EESK, ee_addr); /* EEPROM clock tick. */
- eeprom_delay();
- outb(outval, ee_addr); /* Finish EEPROM a clock tick. */
- eeprom_delay();
- }
- outb(ctrl_val, ee_addr);
-
- for (i = 16; i > 0; i--) {
- outb(ctrl_val | EESK, ee_addr); eeprom_delay();
- retval = (retval << 1) | ((inb(ee_addr) & EEDO) ? 1 : 0);
- outb(ctrl_val, ee_addr); eeprom_delay();
- }
-
- /* Terminate the EEPROM access. */
- ctrl_val &= ~EECS;
- outb(ctrl_val | EESK, ee_addr);
- eeprom_delay();
- outb(ctrl_val, ee_addr);
- eeprom_delay();
- eepro_sw2bank0(ioaddr);
- return retval;
-}
-
-static int
-hardware_send_packet(struct net_device *dev, void *buf, short length)
-{
- struct eepro_local *lp = netdev_priv(dev);
- short ioaddr = dev->base_addr;
- unsigned status, tx_available, last, end;
-
- if (net_debug > 5)
- printk(KERN_DEBUG "%s: entering hardware_send_packet routine.\n", dev->name);
-
- /* determine how much of the transmit buffer space is available */
- if (lp->tx_end > lp->tx_start)
- tx_available = lp->xmt_ram - (lp->tx_end - lp->tx_start);
- else if (lp->tx_end < lp->tx_start)
- tx_available = lp->tx_start - lp->tx_end;
- else tx_available = lp->xmt_ram;
-
- if (((((length + 3) >> 1) << 1) + 2*XMT_HEADER) >= tx_available) {
- /* No space available ??? */
- return 1;
- }
-
- last = lp->tx_end;
- end = last + (((length + 3) >> 1) << 1) + XMT_HEADER;
-
- if (end >= lp->xmt_upper_limit + 2) { /* the transmit buffer is wrapped around */
- if ((lp->xmt_upper_limit + 2 - last) <= XMT_HEADER) {
- /* Arrrr!!!, must keep the xmt header together,
- several days were lost to chase this one down. */
- last = lp->xmt_lower_limit;
- end = last + (((length + 3) >> 1) << 1) + XMT_HEADER;
- }
- else end = lp->xmt_lower_limit + (end -
- lp->xmt_upper_limit + 2);
- }
-
- outw(last, ioaddr + HOST_ADDRESS_REG);
- outw(XMT_CMD, ioaddr + IO_PORT);
- outw(0, ioaddr + IO_PORT);
- outw(end, ioaddr + IO_PORT);
- outw(length, ioaddr + IO_PORT);
-
- if (lp->version == LAN595)
- outsw(ioaddr + IO_PORT, buf, (length + 3) >> 1);
- else { /* LAN595TX or LAN595FX, capable of 32-bit I/O processing */
- unsigned short temp = inb(ioaddr + INT_MASK_REG);
- outb(temp | IO_32_BIT, ioaddr + INT_MASK_REG);
- outsl(ioaddr + IO_PORT_32_BIT, buf, (length + 3) >> 2);
- outb(temp & ~(IO_32_BIT), ioaddr + INT_MASK_REG);
- }
-
- /* A dummy read to flush the DRAM write pipeline */
- status = inw(ioaddr + IO_PORT);
-
- if (lp->tx_start == lp->tx_end) {
- outw(last, ioaddr + lp->xmt_bar);
- outb(XMT_CMD, ioaddr);
- lp->tx_start = last; /* I don't like to change tx_start here */
- }
- else {
- /* update the next address and the chain bit in the
- last packet */
-
- if (lp->tx_end != last) {
- outw(lp->tx_last + XMT_CHAIN, ioaddr + HOST_ADDRESS_REG);
- outw(last, ioaddr + IO_PORT);
- }
-
- outw(lp->tx_last + XMT_COUNT, ioaddr + HOST_ADDRESS_REG);
- status = inw(ioaddr + IO_PORT);
- outw(status | CHAIN_BIT, ioaddr + IO_PORT);
-
- /* Continue the transmit command */
- outb(RESUME_XMT_CMD, ioaddr);
- }
-
- lp->tx_last = last;
- lp->tx_end = end;
-
- if (net_debug > 5)
- printk(KERN_DEBUG "%s: exiting hardware_send_packet routine.\n", dev->name);
-
- return 0;
-}
-
-static void
-eepro_rx(struct net_device *dev)
-{
- struct eepro_local *lp = netdev_priv(dev);
- short ioaddr = dev->base_addr;
- short boguscount = 20;
- short rcv_car = lp->rx_start;
- unsigned rcv_event, rcv_status, rcv_next_frame, rcv_size;
-
- if (net_debug > 5)
- printk(KERN_DEBUG "%s: entering eepro_rx routine.\n", dev->name);
-
- /* Set the read pointer to the start of the RCV */
- outw(rcv_car, ioaddr + HOST_ADDRESS_REG);
-
- rcv_event = inw(ioaddr + IO_PORT);
-
- while (rcv_event == RCV_DONE) {
-
- rcv_status = inw(ioaddr + IO_PORT);
- rcv_next_frame = inw(ioaddr + IO_PORT);
- rcv_size = inw(ioaddr + IO_PORT);
-
- if ((rcv_status & (RX_OK | RX_ERROR)) == RX_OK) {
-
- /* Malloc up new buffer. */
- struct sk_buff *skb;
-
- dev->stats.rx_bytes+=rcv_size;
- rcv_size &= 0x3fff;
- skb = netdev_alloc_skb(dev, rcv_size + 5);
- if (skb == NULL) {
- printk(KERN_NOTICE "%s: Memory squeeze, dropping packet.\n", dev->name);
- dev->stats.rx_dropped++;
- rcv_car = lp->rx_start + RCV_HEADER + rcv_size;
- lp->rx_start = rcv_next_frame;
- outw(rcv_next_frame, ioaddr + HOST_ADDRESS_REG);
-
- break;
- }
- skb_reserve(skb,2);
-
- if (lp->version == LAN595)
- insw(ioaddr+IO_PORT, skb_put(skb,rcv_size), (rcv_size + 3) >> 1);
- else { /* LAN595TX or LAN595FX, capable of 32-bit I/O processing */
- unsigned short temp = inb(ioaddr + INT_MASK_REG);
- outb(temp | IO_32_BIT, ioaddr + INT_MASK_REG);
- insl(ioaddr+IO_PORT_32_BIT, skb_put(skb,rcv_size),
- (rcv_size + 3) >> 2);
- outb(temp & ~(IO_32_BIT), ioaddr + INT_MASK_REG);
- }
-
- skb->protocol = eth_type_trans(skb,dev);
- netif_rx(skb);
- dev->stats.rx_packets++;
- }
-
- else { /* Not sure will ever reach here,
- I set the 595 to discard bad received frames */
- dev->stats.rx_errors++;
-
- if (rcv_status & 0x0100)
- dev->stats.rx_over_errors++;
-
- else if (rcv_status & 0x0400)
- dev->stats.rx_frame_errors++;
-
- else if (rcv_status & 0x0800)
- dev->stats.rx_crc_errors++;
-
- printk(KERN_DEBUG "%s: event = %#x, status = %#x, next = %#x, size = %#x\n",
- dev->name, rcv_event, rcv_status, rcv_next_frame, rcv_size);
- }
-
- if (rcv_status & 0x1000)
- dev->stats.rx_length_errors++;
-
- rcv_car = lp->rx_start + RCV_HEADER + rcv_size;
- lp->rx_start = rcv_next_frame;
-
- if (--boguscount == 0)
- break;
-
- outw(rcv_next_frame, ioaddr + HOST_ADDRESS_REG);
- rcv_event = inw(ioaddr + IO_PORT);
-
- }
- if (rcv_car == 0)
- rcv_car = lp->rcv_upper_limit | 0xff;
-
- outw(rcv_car - 1, ioaddr + RCV_STOP);
-
- if (net_debug > 5)
- printk(KERN_DEBUG "%s: exiting eepro_rx routine.\n", dev->name);
-}
-
-static void
-eepro_transmit_interrupt(struct net_device *dev)
-{
- struct eepro_local *lp = netdev_priv(dev);
- short ioaddr = dev->base_addr;
- short boguscount = 25;
- short xmt_status;
-
- while ((lp->tx_start != lp->tx_end) && boguscount--) {
-
- outw(lp->tx_start, ioaddr + HOST_ADDRESS_REG);
- xmt_status = inw(ioaddr+IO_PORT);
-
- if (!(xmt_status & TX_DONE_BIT))
- break;
-
- xmt_status = inw(ioaddr+IO_PORT);
- lp->tx_start = inw(ioaddr+IO_PORT);
-
- netif_wake_queue (dev);
-
- if (xmt_status & TX_OK)
- dev->stats.tx_packets++;
- else {
- dev->stats.tx_errors++;
- if (xmt_status & 0x0400) {
- dev->stats.tx_carrier_errors++;
- printk(KERN_DEBUG "%s: carrier error\n",
- dev->name);
- printk(KERN_DEBUG "%s: XMT status = %#x\n",
- dev->name, xmt_status);
- }
- else {
- printk(KERN_DEBUG "%s: XMT status = %#x\n",
- dev->name, xmt_status);
- printk(KERN_DEBUG "%s: XMT status = %#x\n",
- dev->name, xmt_status);
- }
- }
- if (xmt_status & 0x000f) {
- dev->stats.collisions += (xmt_status & 0x000f);
- }
-
- if ((xmt_status & 0x0040) == 0x0) {
- dev->stats.tx_heartbeat_errors++;
- }
- }
-}
-
-static int eepro_ethtool_get_settings(struct net_device *dev,
- struct ethtool_cmd *cmd)
-{
- struct eepro_local *lp = netdev_priv(dev);
-
- cmd->supported = SUPPORTED_10baseT_Half |
- SUPPORTED_10baseT_Full |
- SUPPORTED_Autoneg;
- cmd->advertising = ADVERTISED_10baseT_Half |
- ADVERTISED_10baseT_Full |
- ADVERTISED_Autoneg;
-
- if (GetBit(lp->word[5], ee_PortTPE)) {
- cmd->supported |= SUPPORTED_TP;
- cmd->advertising |= ADVERTISED_TP;
- }
- if (GetBit(lp->word[5], ee_PortBNC)) {
- cmd->supported |= SUPPORTED_BNC;
- cmd->advertising |= ADVERTISED_BNC;
- }
- if (GetBit(lp->word[5], ee_PortAUI)) {
- cmd->supported |= SUPPORTED_AUI;
- cmd->advertising |= ADVERTISED_AUI;
- }
-
- ethtool_cmd_speed_set(cmd, SPEED_10);
-
- if (dev->if_port == TPE && lp->word[1] & ee_Duplex) {
- cmd->duplex = DUPLEX_FULL;
- }
- else {
- cmd->duplex = DUPLEX_HALF;
- }
-
- cmd->port = dev->if_port;
- cmd->phy_address = dev->base_addr;
- cmd->transceiver = XCVR_INTERNAL;
-
- if (lp->word[0] & ee_AutoNeg) {
- cmd->autoneg = 1;
- }
-
- return 0;
-}
-
-static void eepro_ethtool_get_drvinfo(struct net_device *dev,
- struct ethtool_drvinfo *drvinfo)
-{
- strlcpy(drvinfo->driver, DRV_NAME, sizeof(drvinfo->driver));
- strlcpy(drvinfo->version, DRV_VERSION, sizeof(drvinfo->version));
- snprintf(drvinfo->bus_info, sizeof(drvinfo->bus_info),
- "ISA 0x%lx", dev->base_addr);
-}
-
-static const struct ethtool_ops eepro_ethtool_ops = {
- .get_settings = eepro_ethtool_get_settings,
- .get_drvinfo = eepro_ethtool_get_drvinfo,
-};
-
-#ifdef MODULE
-
-#define MAX_EEPRO 8
-static struct net_device *dev_eepro[MAX_EEPRO];
-
-static int io[MAX_EEPRO] = {
- [0 ... MAX_EEPRO-1] = -1
-};
-static int irq[MAX_EEPRO];
-static int mem[MAX_EEPRO] = { /* Size of the rx buffer in KB */
- [0 ... MAX_EEPRO-1] = RCV_DEFAULT_RAM/1024
-};
-static int autodetect;
-
-static int n_eepro;
-/* For linux 2.1.xx */
-
-MODULE_AUTHOR("Pascal Dupuis and others");
-MODULE_DESCRIPTION("Intel i82595 ISA EtherExpressPro10/10+ driver");
-MODULE_LICENSE("GPL");
-
-module_param_array(io, int, NULL, 0);
-module_param_array(irq, int, NULL, 0);
-module_param_array(mem, int, NULL, 0);
-module_param(autodetect, int, 0);
-MODULE_PARM_DESC(io, "EtherExpress Pro/10 I/O base address(es)");
-MODULE_PARM_DESC(irq, "EtherExpress Pro/10 IRQ number(s)");
-MODULE_PARM_DESC(mem, "EtherExpress Pro/10 Rx buffer size(es) in kB (3-29)");
-MODULE_PARM_DESC(autodetect, "EtherExpress Pro/10 force board(s) detection (0-1)");
-
-int __init init_module(void)
-{
- struct net_device *dev;
- int i;
- if (io[0] == -1 && autodetect == 0) {
- printk(KERN_WARNING "eepro_init_module: Probe is very dangerous in ISA boards!\n");
- printk(KERN_WARNING "eepro_init_module: Please add \"autodetect=1\" to force probe\n");
- return -ENODEV;
- }
- else if (autodetect) {
- /* if autodetect is set then we must force detection */
- for (i = 0; i < MAX_EEPRO; i++) {
- io[i] = 0;
- }
-
- printk(KERN_INFO "eepro_init_module: Auto-detecting boards (May God protect us...)\n");
- }
-
- for (i = 0; i < MAX_EEPRO && io[i] != -1; i++) {
- dev = alloc_etherdev(sizeof(struct eepro_local));
- if (!dev)
- break;
-
- dev->mem_end = mem[i];
- dev->base_addr = io[i];
- dev->irq = irq[i];
-
- if (do_eepro_probe(dev) == 0) {
- dev_eepro[n_eepro++] = dev;
- continue;
- }
- free_netdev(dev);
- break;
- }
-
- if (n_eepro)
- printk(KERN_INFO "%s", version);
-
- return n_eepro ? 0 : -ENODEV;
-}
-
-void __exit
-cleanup_module(void)
-{
- int i;
-
- for (i=0; i<n_eepro; i++) {
- struct net_device *dev = dev_eepro[i];
- unregister_netdev(dev);
- release_region(dev->base_addr, EEPRO_IO_EXTENT);
- free_netdev(dev);
- }
-}
-#endif /* MODULE */
diff --git a/drivers/net/ethernet/i825xx/eexpress.c b/drivers/net/ethernet/i825xx/eexpress.c
deleted file mode 100644
index 7a6a2f04c5b..00000000000
--- a/drivers/net/ethernet/i825xx/eexpress.c
+++ /dev/null
@@ -1,1661 +0,0 @@
-/* Intel EtherExpress 16 device driver for Linux
- *
- * Written by John Sullivan, 1995
- * based on original code by Donald Becker, with changes by
- * Alan Cox and Pauline Middelink.
- *
- * Support for 8-bit mode by Zoltan Szilagyi <zoltans@cs.arizona.edu>
- *
- * Many modifications, and currently maintained, by
- * Philip Blundell <philb@gnu.org>
- * Added the Compaq LTE Alan Cox <alan@lxorguk.ukuu.org.uk>
- * Added MCA support Adam Fritzler (now deleted)
- *
- * Note - this driver is experimental still - it has problems on faster
- * machines. Someone needs to sit down and go through it line by line with
- * a databook...
- */
-
-/* The EtherExpress 16 is a fairly simple card, based on a shared-memory
- * design using the i82586 Ethernet coprocessor. It bears no relationship,
- * as far as I know, to the similarly-named "EtherExpress Pro" range.
- *
- * Historically, Linux support for these cards has been very bad. However,
- * things seem to be getting better slowly.
- */
-
-/* If your card is confused about what sort of interface it has (eg it
- * persistently reports "10baseT" when none is fitted), running 'SOFTSET /BART'
- * or 'SOFTSET /LISA' from DOS seems to help.
- */
-
-/* Here's the scoop on memory mapping.
- *
- * There are three ways to access EtherExpress card memory: either using the
- * shared-memory mapping, or using PIO through the dataport, or using PIO
- * through the "shadow memory" ports.
- *
- * The shadow memory system works by having the card map some of its memory
- * as follows:
- *
- * (the low five bits of the SMPTR are ignored)
- *
- * base+0x4000..400f memory at SMPTR+0..15
- * base+0x8000..800f memory at SMPTR+16..31
- * base+0xc000..c007 dubious stuff (memory at SMPTR+16..23 apparently)
- * base+0xc008..c00f memory at 0x0008..0x000f
- *
- * This last set (the one at c008) is particularly handy because the SCB
- * lives at 0x0008. So that set of ports gives us easy random access to data
- * in the SCB without having to mess around setting up pointers and the like.
- * We always use this method to access the SCB (via the scb_xx() functions).
- *
- * Dataport access works by aiming the appropriate (read or write) pointer
- * at the first address you're interested in, and then reading or writing from
- * the dataport. The pointers auto-increment after each transfer. We use
- * this for data transfer.
- *
- * We don't use the shared-memory system because it allegedly doesn't work on
- * all cards, and because it's a bit more prone to go wrong (it's one more
- * thing to configure...).
- */
-
-/* Known bugs:
- *
- * - The card seems to want to give us two interrupts every time something
- * happens, where just one would be better.
- */
-
-/*
- *
- * Note by Zoltan Szilagyi 10-12-96:
- *
- * I've succeeded in eliminating the "CU wedged" messages, and hence the
- * lockups, which were only occurring with cards running in 8-bit mode ("force
- * 8-bit operation" in Intel's SoftSet utility). This version of the driver
- * sets the 82586 and the ASIC to 8-bit mode at startup; it also stops the
- * CU before submitting a packet for transmission, and then restarts it as soon
- * as the process of handing the packet is complete. This is definitely an
- * unnecessary slowdown if the card is running in 16-bit mode; therefore one
- * should detect 16-bit vs 8-bit mode from the EEPROM settings and act
- * accordingly. In 8-bit mode with this bugfix I'm getting about 150 K/s for
- * ftp's, which is significantly better than I get in DOS, so the overhead of
- * stopping and restarting the CU with each transmit is not prohibitive in
- * practice.
- *
- * Update by David Woodhouse 11/5/99:
- *
- * I've seen "CU wedged" messages in 16-bit mode, on the Alpha architecture.
- * I assume that this is because 16-bit accesses are actually handled as two
- * 8-bit accesses.
- */
-
-#ifdef __alpha__
-#define LOCKUP16 1
-#endif
-#ifndef LOCKUP16
-#define LOCKUP16 0
-#endif
-
-#include <linux/module.h>
-#include <linux/kernel.h>
-#include <linux/types.h>
-#include <linux/fcntl.h>
-#include <linux/interrupt.h>
-#include <linux/ioport.h>
-#include <linux/string.h>
-#include <linux/in.h>
-#include <linux/delay.h>
-#include <linux/errno.h>
-#include <linux/init.h>
-#include <linux/netdevice.h>
-#include <linux/etherdevice.h>
-#include <linux/skbuff.h>
-#include <linux/spinlock.h>
-#include <linux/bitops.h>
-#include <linux/jiffies.h>
-
-#include <asm/io.h>
-#include <asm/irq.h>
-
-#ifndef NET_DEBUG
-#define NET_DEBUG 4
-#endif
-
-#include "eexpress.h"
-
-#define EEXP_IO_EXTENT 16
-
-/*
- * Private data declarations
- */
-
-struct net_local
-{
- unsigned long last_tx; /* jiffies when last transmit started */
- unsigned long init_time; /* jiffies when eexp_hw_init586 called */
- unsigned short rx_first; /* first rx buf, same as RX_BUF_START */
- unsigned short rx_last; /* last rx buf */
- unsigned short rx_ptr; /* first rx buf to look at */
- unsigned short tx_head; /* next free tx buf */
- unsigned short tx_reap; /* first in-use tx buf */
- unsigned short tx_tail; /* previous tx buf to tx_head */
- unsigned short tx_link; /* last known-executing tx buf */
- unsigned short last_tx_restart; /* set to tx_link when we
- restart the CU */
- unsigned char started;
- unsigned short rx_buf_start;
- unsigned short rx_buf_end;
- unsigned short num_tx_bufs;
- unsigned short num_rx_bufs;
- unsigned char width; /* 0 for 16bit, 1 for 8bit */
- unsigned char was_promisc;
- unsigned char old_mc_count;
- spinlock_t lock;
-};
-
-/* This is the code and data that is downloaded to the EtherExpress card's
- * memory at boot time.
- */
-
-static unsigned short start_code[] = {
-/* 0x0000 */
- 0x0001, /* ISCP: busy - cleared after reset */
- 0x0008,0x0000,0x0000, /* offset,address (lo,hi) of SCB */
-
- 0x0000,0x0000, /* SCB: status, commands */
- 0x0000,0x0000, /* links to first command block,
- first receive descriptor */
- 0x0000,0x0000, /* CRC error, alignment error counts */
- 0x0000,0x0000, /* out of resources, overrun error counts */
-
- 0x0000,0x0000, /* pad */
- 0x0000,0x0000,
-
-/* 0x20 -- start of 82586 CU program */
-#define CONF_LINK 0x20
- 0x0000,Cmd_Config,
- 0x0032, /* link to next command */
- 0x080c, /* 12 bytes follow : fifo threshold=8 */
- 0x2e40, /* don't rx bad frames
- * SRDY/ARDY => ext. sync. : preamble len=8
- * take addresses from data buffers
- * 6 bytes/address
- */
- 0x6000, /* default backoff method & priority
- * interframe spacing = 0x60 */
- 0xf200, /* slot time=0x200
- * max collision retry = 0xf */
-#define CONF_PROMISC 0x2e
- 0x0000, /* no HDLC : normal CRC : enable broadcast
- * disable promiscuous/multicast modes */
- 0x003c, /* minimum frame length = 60 octets) */
-
- 0x0000,Cmd_SetAddr,
- 0x003e, /* link to next command */
-#define CONF_HWADDR 0x38
- 0x0000,0x0000,0x0000, /* hardware address placed here */
-
- 0x0000,Cmd_MCast,
- 0x0076, /* link to next command */
-#define CONF_NR_MULTICAST 0x44
- 0x0000, /* number of bytes in multicast address(es) */
-#define CONF_MULTICAST 0x46
- 0x0000, 0x0000, 0x0000, /* some addresses */
- 0x0000, 0x0000, 0x0000,
- 0x0000, 0x0000, 0x0000,
- 0x0000, 0x0000, 0x0000,
- 0x0000, 0x0000, 0x0000,
- 0x0000, 0x0000, 0x0000,
- 0x0000, 0x0000, 0x0000,
- 0x0000, 0x0000, 0x0000,
-
-#define CONF_DIAG_RESULT 0x76
- 0x0000, Cmd_Diag,
- 0x007c, /* link to next command */
-
- 0x0000,Cmd_TDR|Cmd_INT,
- 0x0084,
-#define CONF_TDR_RESULT 0x82
- 0x0000,
-
- 0x0000,Cmd_END|Cmd_Nop, /* end of configure sequence */
- 0x0084 /* dummy link */
-};
-
-/* maps irq number to EtherExpress magic value */
-static char irqrmap[] = { 0,0,1,2,3,4,0,0,0,1,5,6,0,0,0,0 };
-
-/*
- * Prototypes for Linux interface
- */
-
-static int eexp_open(struct net_device *dev);
-static int eexp_close(struct net_device *dev);
-static void eexp_timeout(struct net_device *dev);
-static netdev_tx_t eexp_xmit(struct sk_buff *buf,
- struct net_device *dev);
-
-static irqreturn_t eexp_irq(int irq, void *dev_addr);
-static void eexp_set_multicast(struct net_device *dev);
-
-/*
- * Prototypes for hardware access functions
- */
-
-static void eexp_hw_rx_pio(struct net_device *dev);
-static void eexp_hw_tx_pio(struct net_device *dev, unsigned short *buf,
- unsigned short len);
-static int eexp_hw_probe(struct net_device *dev,unsigned short ioaddr);
-static unsigned short eexp_hw_readeeprom(unsigned short ioaddr,
- unsigned char location);
-
-static unsigned short eexp_hw_lasttxstat(struct net_device *dev);
-static void eexp_hw_txrestart(struct net_device *dev);
-
-static void eexp_hw_txinit (struct net_device *dev);
-static void eexp_hw_rxinit (struct net_device *dev);
-
-static void eexp_hw_init586 (struct net_device *dev);
-static void eexp_setup_filter (struct net_device *dev);
-
-static char *eexp_ifmap[]={"AUI", "BNC", "RJ45"};
-enum eexp_iftype {AUI=0, BNC=1, TPE=2};
-
-#define STARTED_RU 2
-#define STARTED_CU 1
-
-/*
- * Primitive hardware access functions.
- */
-
-static inline unsigned short scb_status(struct net_device *dev)
-{
- return inw(dev->base_addr + 0xc008);
-}
-
-static inline unsigned short scb_rdcmd(struct net_device *dev)
-{
- return inw(dev->base_addr + 0xc00a);
-}
-
-static inline void scb_command(struct net_device *dev, unsigned short cmd)
-{
- outw(cmd, dev->base_addr + 0xc00a);
-}
-
-static inline void scb_wrcbl(struct net_device *dev, unsigned short val)
-{
- outw(val, dev->base_addr + 0xc00c);
-}
-
-static inline void scb_wrrfa(struct net_device *dev, unsigned short val)
-{
- outw(val, dev->base_addr + 0xc00e);
-}
-
-static inline void set_loopback(struct net_device *dev)
-{
- outb(inb(dev->base_addr + Config) | 2, dev->base_addr + Config);
-}
-
-static inline void clear_loopback(struct net_device *dev)
-{
- outb(inb(dev->base_addr + Config) & ~2, dev->base_addr + Config);
-}
-
-static inline unsigned short int SHADOW(short int addr)
-{
- addr &= 0x1f;
- if (addr > 0xf) addr += 0x3ff0;
- return addr + 0x4000;
-}
-
-/*
- * Linux interface
- */
-
-/*
- * checks for presence of EtherExpress card
- */
-
-static int __init do_express_probe(struct net_device *dev)
-{
- unsigned short *port;
- static unsigned short ports[] = { 0x240,0x300,0x310,0x270,0x320,0x340,0 };
- unsigned short ioaddr = dev->base_addr;
- int dev_irq = dev->irq;
- int err;
-
- dev->if_port = 0xff; /* not set */
-
- if (ioaddr&0xfe00) {
- if (!request_region(ioaddr, EEXP_IO_EXTENT, "EtherExpress"))
- return -EBUSY;
- err = eexp_hw_probe(dev,ioaddr);
- release_region(ioaddr, EEXP_IO_EXTENT);
- return err;
- } else if (ioaddr)
- return -ENXIO;
-
- for (port=&ports[0] ; *port ; port++ )
- {
- unsigned short sum = 0;
- int i;
- if (!request_region(*port, EEXP_IO_EXTENT, "EtherExpress"))
- continue;
- for ( i=0 ; i<4 ; i++ )
- {
- unsigned short t;
- t = inb(*port + ID_PORT);
- sum |= (t>>4) << ((t & 0x03)<<2);
- }
- if (sum==0xbaba && !eexp_hw_probe(dev,*port)) {
- release_region(*port, EEXP_IO_EXTENT);
- return 0;
- }
- release_region(*port, EEXP_IO_EXTENT);
- dev->irq = dev_irq;
- }
- return -ENODEV;
-}
-
-#ifndef MODULE
-struct net_device * __init express_probe(int unit)
-{
- struct net_device *dev = alloc_etherdev(sizeof(struct net_local));
- int err;
-
- if (!dev)
- return ERR_PTR(-ENOMEM);
-
- sprintf(dev->name, "eth%d", unit);
- netdev_boot_setup_check(dev);
-
- err = do_express_probe(dev);
- if (!err)
- return dev;
- free_netdev(dev);
- return ERR_PTR(err);
-}
-#endif
-
-/*
- * open and initialize the adapter, ready for use
- */
-
-static int eexp_open(struct net_device *dev)
-{
- int ret;
- unsigned short ioaddr = dev->base_addr;
- struct net_local *lp = netdev_priv(dev);
-
-#if NET_DEBUG > 6
- printk(KERN_DEBUG "%s: eexp_open()\n", dev->name);
-#endif
-
- if (!dev->irq || !irqrmap[dev->irq])
- return -ENXIO;
-
- ret = request_irq(dev->irq, eexp_irq, 0, dev->name, dev);
- if (ret)
- return ret;
-
- if (!request_region(ioaddr, EEXP_IO_EXTENT, "EtherExpress")) {
- printk(KERN_WARNING "EtherExpress io port %x, is busy.\n"
- , ioaddr);
- goto err_out1;
- }
- if (!request_region(ioaddr+0x4000, EEXP_IO_EXTENT, "EtherExpress shadow")) {
- printk(KERN_WARNING "EtherExpress io port %x, is busy.\n"
- , ioaddr+0x4000);
- goto err_out2;
- }
- if (!request_region(ioaddr+0x8000, EEXP_IO_EXTENT, "EtherExpress shadow")) {
- printk(KERN_WARNING "EtherExpress io port %x, is busy.\n"
- , ioaddr+0x8000);
- goto err_out3;
- }
- if (!request_region(ioaddr+0xc000, EEXP_IO_EXTENT, "EtherExpress shadow")) {
- printk(KERN_WARNING "EtherExpress io port %x, is busy.\n"
- , ioaddr+0xc000);
- goto err_out4;
- }
-
- if (lp->width) {
- printk("%s: forcing ASIC to 8-bit mode\n", dev->name);
- outb(inb(dev->base_addr+Config)&~4, dev->base_addr+Config);
- }
-
- eexp_hw_init586(dev);
- netif_start_queue(dev);
-#if NET_DEBUG > 6
- printk(KERN_DEBUG "%s: leaving eexp_open()\n", dev->name);
-#endif
- return 0;
-
- err_out4:
- release_region(ioaddr+0x8000, EEXP_IO_EXTENT);
- err_out3:
- release_region(ioaddr+0x4000, EEXP_IO_EXTENT);
- err_out2:
- release_region(ioaddr, EEXP_IO_EXTENT);
- err_out1:
- free_irq(dev->irq, dev);
- return -EBUSY;
-}
-
-/*
- * close and disable the interface, leaving the 586 in reset.
- */
-
-static int eexp_close(struct net_device *dev)
-{
- unsigned short ioaddr = dev->base_addr;
- struct net_local *lp = netdev_priv(dev);
-
- int irq = dev->irq;
-
- netif_stop_queue(dev);
-
- outb(SIRQ_dis|irqrmap[irq],ioaddr+SET_IRQ);
- lp->started = 0;
- scb_command(dev, SCB_CUsuspend|SCB_RUsuspend);
- outb(0,ioaddr+SIGNAL_CA);
- free_irq(irq,dev);
- outb(i586_RST,ioaddr+EEPROM_Ctrl);
- release_region(ioaddr, EEXP_IO_EXTENT);
- release_region(ioaddr+0x4000, 16);
- release_region(ioaddr+0x8000, 16);
- release_region(ioaddr+0xc000, 16);
-
- return 0;
-}
-
-/*
- * This gets called when a higher level thinks we are broken. Check that
- * nothing has become jammed in the CU.
- */
-
-static void unstick_cu(struct net_device *dev)
-{
- struct net_local *lp = netdev_priv(dev);
- unsigned short ioaddr = dev->base_addr;
-
- if (lp->started)
- {
- if (time_after(jiffies, dev_trans_start(dev) + HZ/2))
- {
- if (lp->tx_link==lp->last_tx_restart)
- {
- unsigned short boguscount=200,rsst;
- printk(KERN_WARNING "%s: Retransmit timed out, status %04x, resetting...\n",
- dev->name, scb_status(dev));
- eexp_hw_txinit(dev);
- lp->last_tx_restart = 0;
- scb_wrcbl(dev, lp->tx_link);
- scb_command(dev, SCB_CUstart);
- outb(0,ioaddr+SIGNAL_CA);
- while (!SCB_complete(rsst=scb_status(dev)))
- {
- if (!--boguscount)
- {
- boguscount=200;
- printk(KERN_WARNING "%s: Reset timed out status %04x, retrying...\n",
- dev->name,rsst);
- scb_wrcbl(dev, lp->tx_link);
- scb_command(dev, SCB_CUstart);
- outb(0,ioaddr+SIGNAL_CA);
- }
- }
- netif_wake_queue(dev);
- }
- else
- {
- unsigned short status = scb_status(dev);
- if (SCB_CUdead(status))
- {
- unsigned short txstatus = eexp_hw_lasttxstat(dev);
- printk(KERN_WARNING "%s: Transmit timed out, CU not active status %04x %04x, restarting...\n",
- dev->name, status, txstatus);
- eexp_hw_txrestart(dev);
- }
- else
- {
- unsigned short txstatus = eexp_hw_lasttxstat(dev);
- if (netif_queue_stopped(dev) && !txstatus)
- {
- printk(KERN_WARNING "%s: CU wedged, status %04x %04x, resetting...\n",
- dev->name,status,txstatus);
- eexp_hw_init586(dev);
- netif_wake_queue(dev);
- }
- else
- {
- printk(KERN_WARNING "%s: transmit timed out\n", dev->name);
- }
- }
- }
- }
- }
- else
- {
- if (time_after(jiffies, lp->init_time + 10))
- {
- unsigned short status = scb_status(dev);
- printk(KERN_WARNING "%s: i82586 startup timed out, status %04x, resetting...\n",
- dev->name, status);
- eexp_hw_init586(dev);
- netif_wake_queue(dev);
- }
- }
-}
-
-static void eexp_timeout(struct net_device *dev)
-{
- struct net_local *lp = netdev_priv(dev);
-#ifdef CONFIG_SMP
- unsigned long flags;
-#endif
- int status;
-
- disable_irq(dev->irq);
-
- /*
- * Best would be to use synchronize_irq(); spin_lock() here
- * lets make it work first..
- */
-
-#ifdef CONFIG_SMP
- spin_lock_irqsave(&lp->lock, flags);
-#endif
-
- status = scb_status(dev);
- unstick_cu(dev);
- printk(KERN_INFO "%s: transmit timed out, %s?\n", dev->name,
- (SCB_complete(status)?"lost interrupt":
- "board on fire"));
- dev->stats.tx_errors++;
- lp->last_tx = jiffies;
- if (!SCB_complete(status)) {
- scb_command(dev, SCB_CUabort);
- outb(0,dev->base_addr+SIGNAL_CA);
- }
- netif_wake_queue(dev);
-#ifdef CONFIG_SMP
- spin_unlock_irqrestore(&lp->lock, flags);
-#endif
-}
-
-/*
- * Called to transmit a packet, or to allow us to right ourselves
- * if the kernel thinks we've died.
- */
-static netdev_tx_t eexp_xmit(struct sk_buff *buf, struct net_device *dev)
-{
- short length = buf->len;
-#ifdef CONFIG_SMP
- struct net_local *lp = netdev_priv(dev);
- unsigned long flags;
-#endif
-
-#if NET_DEBUG > 6
- printk(KERN_DEBUG "%s: eexp_xmit()\n", dev->name);
-#endif
-
- if (buf->len < ETH_ZLEN) {
- if (skb_padto(buf, ETH_ZLEN))
- return NETDEV_TX_OK;
- length = ETH_ZLEN;
- }
-
- disable_irq(dev->irq);
-
- /*
- * Best would be to use synchronize_irq(); spin_lock() here
- * lets make it work first..
- */
-
-#ifdef CONFIG_SMP
- spin_lock_irqsave(&lp->lock, flags);
-#endif
-
- {
- unsigned short *data = (unsigned short *)buf->data;
-
- dev->stats.tx_bytes += length;
-
- eexp_hw_tx_pio(dev,data,length);
- }
- dev_kfree_skb(buf);
-#ifdef CONFIG_SMP
- spin_unlock_irqrestore(&lp->lock, flags);
-#endif
- enable_irq(dev->irq);
- return NETDEV_TX_OK;
-}
-
-/*
- * Handle an EtherExpress interrupt
- * If we've finished initializing, start the RU and CU up.
- * If we've already started, reap tx buffers, handle any received packets,
- * check to make sure we've not become wedged.
- */
-
-static unsigned short eexp_start_irq(struct net_device *dev,
- unsigned short status)
-{
- unsigned short ack_cmd = SCB_ack(status);
- struct net_local *lp = netdev_priv(dev);
- unsigned short ioaddr = dev->base_addr;
- if ((dev->flags & IFF_UP) && !(lp->started & STARTED_CU)) {
- short diag_status, tdr_status;
- while (SCB_CUstat(status)==2)
- status = scb_status(dev);
-#if NET_DEBUG > 4
- printk("%s: CU went non-active (status %04x)\n",
- dev->name, status);
-#endif
-
- outw(CONF_DIAG_RESULT & ~31, ioaddr + SM_PTR);
- diag_status = inw(ioaddr + SHADOW(CONF_DIAG_RESULT));
- if (diag_status & 1<<11) {
- printk(KERN_WARNING "%s: 82586 failed self-test\n",
- dev->name);
- } else if (!(diag_status & 1<<13)) {
- printk(KERN_WARNING "%s: 82586 self-test failed to complete\n", dev->name);
- }
-
- outw(CONF_TDR_RESULT & ~31, ioaddr + SM_PTR);
- tdr_status = inw(ioaddr + SHADOW(CONF_TDR_RESULT));
- if (tdr_status & (TDR_SHORT|TDR_OPEN)) {
- printk(KERN_WARNING "%s: TDR reports cable %s at %d tick%s\n", dev->name, (tdr_status & TDR_SHORT)?"short":"broken", tdr_status & TDR_TIME, ((tdr_status & TDR_TIME) != 1) ? "s" : "");
- }
- else if (tdr_status & TDR_XCVRPROBLEM) {
- printk(KERN_WARNING "%s: TDR reports transceiver problem\n", dev->name);
- }
- else if (tdr_status & TDR_LINKOK) {
-#if NET_DEBUG > 4
- printk(KERN_DEBUG "%s: TDR reports link OK\n", dev->name);
-#endif
- } else {
- printk("%s: TDR is ga-ga (status %04x)\n", dev->name,
- tdr_status);
- }
-
- lp->started |= STARTED_CU;
- scb_wrcbl(dev, lp->tx_link);
- /* if the RU isn't running, start it now */
- if (!(lp->started & STARTED_RU)) {
- ack_cmd |= SCB_RUstart;
- scb_wrrfa(dev, lp->rx_buf_start);
- lp->rx_ptr = lp->rx_buf_start;
- lp->started |= STARTED_RU;
- }
- ack_cmd |= SCB_CUstart | 0x2000;
- }
-
- if ((dev->flags & IFF_UP) && !(lp->started & STARTED_RU) && SCB_RUstat(status)==4)
- lp->started|=STARTED_RU;
-
- return ack_cmd;
-}
-
-static void eexp_cmd_clear(struct net_device *dev)
-{
- unsigned long int oldtime = jiffies;
- while (scb_rdcmd(dev) && (time_before(jiffies, oldtime + 10)));
- if (scb_rdcmd(dev)) {
- printk("%s: command didn't clear\n", dev->name);
- }
-}
-
-static irqreturn_t eexp_irq(int dummy, void *dev_info)
-{
- struct net_device *dev = dev_info;
- struct net_local *lp;
- unsigned short ioaddr,status,ack_cmd;
- unsigned short old_read_ptr, old_write_ptr;
-
- lp = netdev_priv(dev);
- ioaddr = dev->base_addr;
-
- spin_lock(&lp->lock);
-
- old_read_ptr = inw(ioaddr+READ_PTR);
- old_write_ptr = inw(ioaddr+WRITE_PTR);
-
- outb(SIRQ_dis|irqrmap[dev->irq], ioaddr+SET_IRQ);
-
- status = scb_status(dev);
-
-#if NET_DEBUG > 4
- printk(KERN_DEBUG "%s: interrupt (status %x)\n", dev->name, status);
-#endif
-
- if (lp->started == (STARTED_CU | STARTED_RU)) {
-
- do {
- eexp_cmd_clear(dev);
-
- ack_cmd = SCB_ack(status);
- scb_command(dev, ack_cmd);
- outb(0,ioaddr+SIGNAL_CA);
-
- eexp_cmd_clear(dev);
-
- if (SCB_complete(status)) {
- if (!eexp_hw_lasttxstat(dev)) {
- printk("%s: tx interrupt but no status\n", dev->name);
- }
- }
-
- if (SCB_rxdframe(status))
- eexp_hw_rx_pio(dev);
-
- status = scb_status(dev);
- } while (status & 0xc000);
-
- if (SCB_RUdead(status))
- {
- printk(KERN_WARNING "%s: RU stopped: status %04x\n",
- dev->name,status);
-#if 0
- printk(KERN_WARNING "%s: cur_rfd=%04x, cur_rbd=%04x\n", dev->name, lp->cur_rfd, lp->cur_rbd);
- outw(lp->cur_rfd, ioaddr+READ_PTR);
- printk(KERN_WARNING "%s: [%04x]\n", dev->name, inw(ioaddr+DATAPORT));
- outw(lp->cur_rfd+6, ioaddr+READ_PTR);
- printk(KERN_WARNING "%s: rbd is %04x\n", dev->name, rbd= inw(ioaddr+DATAPORT));
- outw(rbd, ioaddr+READ_PTR);
- printk(KERN_WARNING "%s: [%04x %04x] ", dev->name, inw(ioaddr+DATAPORT), inw(ioaddr+DATAPORT));
- outw(rbd+8, ioaddr+READ_PTR);
- printk("[%04x]\n", inw(ioaddr+DATAPORT));
-#endif
- dev->stats.rx_errors++;
-#if 1
- eexp_hw_rxinit(dev);
-#else
- lp->cur_rfd = lp->first_rfd;
-#endif
- scb_wrrfa(dev, lp->rx_buf_start);
- scb_command(dev, SCB_RUstart);
- outb(0,ioaddr+SIGNAL_CA);
- }
- } else {
- if (status & 0x8000)
- ack_cmd = eexp_start_irq(dev, status);
- else
- ack_cmd = SCB_ack(status);
- scb_command(dev, ack_cmd);
- outb(0,ioaddr+SIGNAL_CA);
- }
-
- eexp_cmd_clear(dev);
-
- outb(SIRQ_en|irqrmap[dev->irq], ioaddr+SET_IRQ);
-
-#if NET_DEBUG > 6
- printk("%s: leaving eexp_irq()\n", dev->name);
-#endif
- outw(old_read_ptr, ioaddr+READ_PTR);
- outw(old_write_ptr, ioaddr+WRITE_PTR);
-
- spin_unlock(&lp->lock);
- return IRQ_HANDLED;
-}
-
-/*
- * Hardware access functions
- */
-
-/*
- * Set the cable type to use.
- */
-
-static void eexp_hw_set_interface(struct net_device *dev)
-{
- unsigned char oldval = inb(dev->base_addr + 0x300e);
- oldval &= ~0x82;
- switch (dev->if_port) {
- case TPE:
- oldval |= 0x2;
- case BNC:
- oldval |= 0x80;
- break;
- }
- outb(oldval, dev->base_addr+0x300e);
- mdelay(20);
-}
-
-/*
- * Check all the receive buffers, and hand any received packets
- * to the upper levels. Basic sanity check on each frame
- * descriptor, though we don't bother trying to fix broken ones.
- */
-
-static void eexp_hw_rx_pio(struct net_device *dev)
-{
- struct net_local *lp = netdev_priv(dev);
- unsigned short rx_block = lp->rx_ptr;
- unsigned short boguscount = lp->num_rx_bufs;
- unsigned short ioaddr = dev->base_addr;
- unsigned short status;
-
-#if NET_DEBUG > 6
- printk(KERN_DEBUG "%s: eexp_hw_rx()\n", dev->name);
-#endif
-
- do {
- unsigned short rfd_cmd, rx_next, pbuf, pkt_len;
-
- outw(rx_block, ioaddr + READ_PTR);
- status = inw(ioaddr + DATAPORT);
-
- if (FD_Done(status))
- {
- rfd_cmd = inw(ioaddr + DATAPORT);
- rx_next = inw(ioaddr + DATAPORT);
- pbuf = inw(ioaddr + DATAPORT);
-
- outw(pbuf, ioaddr + READ_PTR);
- pkt_len = inw(ioaddr + DATAPORT);
-
- if (rfd_cmd!=0x0000)
- {
- printk(KERN_WARNING "%s: rfd_cmd not zero:0x%04x\n",
- dev->name, rfd_cmd);
- continue;
- }
- else if (pbuf!=rx_block+0x16)
- {
- printk(KERN_WARNING "%s: rfd and rbd out of sync 0x%04x 0x%04x\n",
- dev->name, rx_block+0x16, pbuf);
- continue;
- }
- else if ((pkt_len & 0xc000)!=0xc000)
- {
- printk(KERN_WARNING "%s: EOF or F not set on received buffer (%04x)\n",
- dev->name, pkt_len & 0xc000);
- continue;
- }
- else if (!FD_OK(status))
- {
- dev->stats.rx_errors++;
- if (FD_CRC(status))
- dev->stats.rx_crc_errors++;
- if (FD_Align(status))
- dev->stats.rx_frame_errors++;
- if (FD_Resrc(status))
- dev->stats.rx_fifo_errors++;
- if (FD_DMA(status))
- dev->stats.rx_over_errors++;
- if (FD_Short(status))
- dev->stats.rx_length_errors++;
- }
- else
- {
- struct sk_buff *skb;
- pkt_len &= 0x3fff;
- skb = netdev_alloc_skb(dev, pkt_len + 16);
- if (skb == NULL)
- {
- printk(KERN_WARNING "%s: Memory squeeze, dropping packet\n",dev->name);
- dev->stats.rx_dropped++;
- break;
- }
- skb_reserve(skb, 2);
- outw(pbuf+10, ioaddr+READ_PTR);
- insw(ioaddr+DATAPORT, skb_put(skb,pkt_len),(pkt_len+1)>>1);
- skb->protocol = eth_type_trans(skb,dev);
- netif_rx(skb);
- dev->stats.rx_packets++;
- dev->stats.rx_bytes += pkt_len;
- }
- outw(rx_block, ioaddr+WRITE_PTR);
- outw(0, ioaddr+DATAPORT);
- outw(0, ioaddr+DATAPORT);
- rx_block = rx_next;
- }
- } while (FD_Done(status) && boguscount--);
- lp->rx_ptr = rx_block;
-}
-
-/*
- * Hand a packet to the card for transmission
- * If we get here, we MUST have already checked
- * to make sure there is room in the transmit
- * buffer region.
- */
-
-static void eexp_hw_tx_pio(struct net_device *dev, unsigned short *buf,
- unsigned short len)
-{
- struct net_local *lp = netdev_priv(dev);
- unsigned short ioaddr = dev->base_addr;
-
- if (LOCKUP16 || lp->width) {
- /* Stop the CU so that there is no chance that it
- jumps off to a bogus address while we are writing the
- pointer to the next transmit packet in 8-bit mode --
- this eliminates the "CU wedged" errors in 8-bit mode.
- (Zoltan Szilagyi 10-12-96) */
- scb_command(dev, SCB_CUsuspend);
- outw(0xFFFF, ioaddr+SIGNAL_CA);
- }
-
- outw(lp->tx_head, ioaddr + WRITE_PTR);
-
- outw(0x0000, ioaddr + DATAPORT);
- outw(Cmd_INT|Cmd_Xmit, ioaddr + DATAPORT);
- outw(lp->tx_head+0x08, ioaddr + DATAPORT);
- outw(lp->tx_head+0x0e, ioaddr + DATAPORT);
-
- outw(0x0000, ioaddr + DATAPORT);
- outw(0x0000, ioaddr + DATAPORT);
- outw(lp->tx_head+0x08, ioaddr + DATAPORT);
-
- outw(0x8000|len, ioaddr + DATAPORT);
- outw(-1, ioaddr + DATAPORT);
- outw(lp->tx_head+0x16, ioaddr + DATAPORT);
- outw(0, ioaddr + DATAPORT);
-
- outsw(ioaddr + DATAPORT, buf, (len+1)>>1);
-
- outw(lp->tx_tail+0xc, ioaddr + WRITE_PTR);
- outw(lp->tx_head, ioaddr + DATAPORT);
-
- dev->trans_start = jiffies;
- lp->tx_tail = lp->tx_head;
- if (lp->tx_head==TX_BUF_START+((lp->num_tx_bufs-1)*TX_BUF_SIZE))
- lp->tx_head = TX_BUF_START;
- else
- lp->tx_head += TX_BUF_SIZE;
- if (lp->tx_head != lp->tx_reap)
- netif_wake_queue(dev);
-
- if (LOCKUP16 || lp->width) {
- /* Restart the CU so that the packet can actually
- be transmitted. (Zoltan Szilagyi 10-12-96) */
- scb_command(dev, SCB_CUresume);
- outw(0xFFFF, ioaddr+SIGNAL_CA);
- }
-
- dev->stats.tx_packets++;
- lp->last_tx = jiffies;
-}
-
-static const struct net_device_ops eexp_netdev_ops = {
- .ndo_open = eexp_open,
- .ndo_stop = eexp_close,
- .ndo_start_xmit = eexp_xmit,
- .ndo_set_rx_mode = eexp_set_multicast,
- .ndo_tx_timeout = eexp_timeout,
- .ndo_change_mtu = eth_change_mtu,
- .ndo_set_mac_address = eth_mac_addr,
- .ndo_validate_addr = eth_validate_addr,
-};
-
-/*
- * Sanity check the suspected EtherExpress card
- * Read hardware address, reset card, size memory and initialize buffer
- * memory pointers. These are held in netdev_priv(), in case someone has more
- * than one card in a machine.
- */
-
-static int __init eexp_hw_probe(struct net_device *dev, unsigned short ioaddr)
-{
- unsigned short hw_addr[3];
- unsigned char buswidth;
- unsigned int memory_size;
- int i;
- unsigned short xsum = 0;
- struct net_local *lp = netdev_priv(dev);
-
- printk("%s: EtherExpress 16 at %#x ",dev->name,ioaddr);
-
- outb(ASIC_RST, ioaddr+EEPROM_Ctrl);
- outb(0, ioaddr+EEPROM_Ctrl);
- udelay(500);
- outb(i586_RST, ioaddr+EEPROM_Ctrl);
-
- hw_addr[0] = eexp_hw_readeeprom(ioaddr,2);
- hw_addr[1] = eexp_hw_readeeprom(ioaddr,3);
- hw_addr[2] = eexp_hw_readeeprom(ioaddr,4);
-
- /* Standard Address or Compaq LTE Address */
- if (!((hw_addr[2]==0x00aa && ((hw_addr[1] & 0xff00)==0x0000)) ||
- (hw_addr[2]==0x0080 && ((hw_addr[1] & 0xff00)==0x5F00))))
- {
- printk(" rejected: invalid address %04x%04x%04x\n",
- hw_addr[2],hw_addr[1],hw_addr[0]);
- return -ENODEV;
- }
-
- /* Calculate the EEPROM checksum. Carry on anyway if it's bad,
- * though.
- */
- for (i = 0; i < 64; i++)
- xsum += eexp_hw_readeeprom(ioaddr, i);
- if (xsum != 0xbaba)
- printk(" (bad EEPROM xsum 0x%02x)", xsum);
-
- dev->base_addr = ioaddr;
- for ( i=0 ; i<6 ; i++ )
- dev->dev_addr[i] = ((unsigned char *)hw_addr)[5-i];
-
- {
- static const char irqmap[] = { 0, 9, 3, 4, 5, 10, 11, 0 };
- unsigned short setupval = eexp_hw_readeeprom(ioaddr,0);
-
- /* Use the IRQ from EEPROM if none was given */
- if (!dev->irq)
- dev->irq = irqmap[setupval>>13];
-
- if (dev->if_port == 0xff) {
- dev->if_port = !(setupval & 0x1000) ? AUI :
- eexp_hw_readeeprom(ioaddr,5) & 0x1 ? TPE : BNC;
- }
-
- buswidth = !((setupval & 0x400) >> 10);
- }
-
- memset(lp, 0, sizeof(struct net_local));
- spin_lock_init(&lp->lock);
-
- printk("(IRQ %d, %s connector, %d-bit bus", dev->irq,
- eexp_ifmap[dev->if_port], buswidth?8:16);
-
- if (!request_region(dev->base_addr + 0x300e, 1, "EtherExpress"))
- return -EBUSY;
-
- eexp_hw_set_interface(dev);
-
- release_region(dev->base_addr + 0x300e, 1);
-
- /* Find out how much RAM we have on the card */
- outw(0, dev->base_addr + WRITE_PTR);
- for (i = 0; i < 32768; i++)
- outw(0, dev->base_addr + DATAPORT);
-
- for (memory_size = 0; memory_size < 64; memory_size++)
- {
- outw(memory_size<<10, dev->base_addr + READ_PTR);
- if (inw(dev->base_addr+DATAPORT))
- break;
- outw(memory_size<<10, dev->base_addr + WRITE_PTR);
- outw(memory_size | 0x5000, dev->base_addr+DATAPORT);
- outw(memory_size<<10, dev->base_addr + READ_PTR);
- if (inw(dev->base_addr+DATAPORT) != (memory_size | 0x5000))
- break;
- }
-
- /* Sort out the number of buffers. We may have 16, 32, 48 or 64k
- * of RAM to play with.
- */
- lp->num_tx_bufs = 4;
- lp->rx_buf_end = 0x3ff6;
- switch (memory_size)
- {
- case 64:
- lp->rx_buf_end += 0x4000;
- case 48:
- lp->num_tx_bufs += 4;
- lp->rx_buf_end += 0x4000;
- case 32:
- lp->rx_buf_end += 0x4000;
- case 16:
- printk(", %dk RAM)\n", memory_size);
- break;
- default:
- printk(") bad memory size (%dk).\n", memory_size);
- return -ENODEV;
- break;
- }
-
- lp->rx_buf_start = TX_BUF_START + (lp->num_tx_bufs*TX_BUF_SIZE);
- lp->width = buswidth;
-
- dev->netdev_ops = &eexp_netdev_ops;
- dev->watchdog_timeo = 2*HZ;
-
- return register_netdev(dev);
-}
-
-/*
- * Read a word from the EtherExpress on-board serial EEPROM.
- * The EEPROM contains 64 words of 16 bits.
- */
-static unsigned short __init eexp_hw_readeeprom(unsigned short ioaddr,
- unsigned char location)
-{
- unsigned short cmd = 0x180|(location&0x7f);
- unsigned short rval = 0,wval = EC_CS|i586_RST;
- int i;
-
- outb(EC_CS|i586_RST,ioaddr+EEPROM_Ctrl);
- for (i=0x100 ; i ; i>>=1 )
- {
- if (cmd&i)
- wval |= EC_Wr;
- else
- wval &= ~EC_Wr;
-
- outb(wval,ioaddr+EEPROM_Ctrl);
- outb(wval|EC_Clk,ioaddr+EEPROM_Ctrl);
- eeprom_delay();
- outb(wval,ioaddr+EEPROM_Ctrl);
- eeprom_delay();
- }
- wval &= ~EC_Wr;
- outb(wval,ioaddr+EEPROM_Ctrl);
- for (i=0x8000 ; i ; i>>=1 )
- {
- outb(wval|EC_Clk,ioaddr+EEPROM_Ctrl);
- eeprom_delay();
- if (inb(ioaddr+EEPROM_Ctrl)&EC_Rd)
- rval |= i;
- outb(wval,ioaddr+EEPROM_Ctrl);
- eeprom_delay();
- }
- wval &= ~EC_CS;
- outb(wval|EC_Clk,ioaddr+EEPROM_Ctrl);
- eeprom_delay();
- outb(wval,ioaddr+EEPROM_Ctrl);
- eeprom_delay();
- return rval;
-}
-
-/*
- * Reap tx buffers and return last transmit status.
- * if ==0 then either:
- * a) we're not transmitting anything, so why are we here?
- * b) we've died.
- * otherwise, Stat_Busy(return) means we've still got some packets
- * to transmit, Stat_Done(return) means our buffers should be empty
- * again
- */
-
-static unsigned short eexp_hw_lasttxstat(struct net_device *dev)
-{
- struct net_local *lp = netdev_priv(dev);
- unsigned short tx_block = lp->tx_reap;
- unsigned short status;
-
- if (!netif_queue_stopped(dev) && lp->tx_head==lp->tx_reap)
- return 0x0000;
-
- do
- {
- outw(tx_block & ~31, dev->base_addr + SM_PTR);
- status = inw(dev->base_addr + SHADOW(tx_block));
- if (!Stat_Done(status))
- {
- lp->tx_link = tx_block;
- return status;
- }
- else
- {
- lp->last_tx_restart = 0;
- dev->stats.collisions += Stat_NoColl(status);
- if (!Stat_OK(status))
- {
- char *whatsup = NULL;
- dev->stats.tx_errors++;
- if (Stat_Abort(status))
- dev->stats.tx_aborted_errors++;
- if (Stat_TNoCar(status)) {
- whatsup = "aborted, no carrier";
- dev->stats.tx_carrier_errors++;
- }
- if (Stat_TNoCTS(status)) {
- whatsup = "aborted, lost CTS";
- dev->stats.tx_carrier_errors++;
- }
- if (Stat_TNoDMA(status)) {
- whatsup = "FIFO underran";
- dev->stats.tx_fifo_errors++;
- }
- if (Stat_TXColl(status)) {
- whatsup = "aborted, too many collisions";
- dev->stats.tx_aborted_errors++;
- }
- if (whatsup)
- printk(KERN_INFO "%s: transmit %s\n",
- dev->name, whatsup);
- }
- else
- dev->stats.tx_packets++;
- }
- if (tx_block == TX_BUF_START+((lp->num_tx_bufs-1)*TX_BUF_SIZE))
- lp->tx_reap = tx_block = TX_BUF_START;
- else
- lp->tx_reap = tx_block += TX_BUF_SIZE;
- netif_wake_queue(dev);
- }
- while (lp->tx_reap != lp->tx_head);
-
- lp->tx_link = lp->tx_tail + 0x08;
-
- return status;
-}
-
-/*
- * This should never happen. It is called when some higher routine detects
- * that the CU has stopped, to try to restart it from the last packet we knew
- * we were working on, or the idle loop if we had finished for the time.
- */
-
-static void eexp_hw_txrestart(struct net_device *dev)
-{
- struct net_local *lp = netdev_priv(dev);
- unsigned short ioaddr = dev->base_addr;
-
- lp->last_tx_restart = lp->tx_link;
- scb_wrcbl(dev, lp->tx_link);
- scb_command(dev, SCB_CUstart);
- outb(0,ioaddr+SIGNAL_CA);
-
- {
- unsigned short boguscount=50,failcount=5;
- while (!scb_status(dev))
- {
- if (!--boguscount)
- {
- if (--failcount)
- {
- printk(KERN_WARNING "%s: CU start timed out, status %04x, cmd %04x\n", dev->name, scb_status(dev), scb_rdcmd(dev));
- scb_wrcbl(dev, lp->tx_link);
- scb_command(dev, SCB_CUstart);
- outb(0,ioaddr+SIGNAL_CA);
- boguscount = 100;
- }
- else
- {
- printk(KERN_WARNING "%s: Failed to restart CU, resetting board...\n",dev->name);
- eexp_hw_init586(dev);
- netif_wake_queue(dev);
- return;
- }
- }
- }
- }
-}
-
-/*
- * Writes down the list of transmit buffers into card memory. Each
- * entry consists of an 82586 transmit command, followed by a jump
- * pointing to itself. When we want to transmit a packet, we write
- * the data into the appropriate transmit buffer and then modify the
- * preceding jump to point at the new transmit command. This means that
- * the 586 command unit is continuously active.
- */
-
-static void eexp_hw_txinit(struct net_device *dev)
-{
- struct net_local *lp = netdev_priv(dev);
- unsigned short tx_block = TX_BUF_START;
- unsigned short curtbuf;
- unsigned short ioaddr = dev->base_addr;
-
- for ( curtbuf=0 ; curtbuf<lp->num_tx_bufs ; curtbuf++ )
- {
- outw(tx_block, ioaddr + WRITE_PTR);
-
- outw(0x0000, ioaddr + DATAPORT);
- outw(Cmd_INT|Cmd_Xmit, ioaddr + DATAPORT);
- outw(tx_block+0x08, ioaddr + DATAPORT);
- outw(tx_block+0x0e, ioaddr + DATAPORT);
-
- outw(0x0000, ioaddr + DATAPORT);
- outw(0x0000, ioaddr + DATAPORT);
- outw(tx_block+0x08, ioaddr + DATAPORT);
-
- outw(0x8000, ioaddr + DATAPORT);
- outw(-1, ioaddr + DATAPORT);
- outw(tx_block+0x16, ioaddr + DATAPORT);
- outw(0x0000, ioaddr + DATAPORT);
-
- tx_block += TX_BUF_SIZE;
- }
- lp->tx_head = TX_BUF_START;
- lp->tx_reap = TX_BUF_START;
- lp->tx_tail = tx_block - TX_BUF_SIZE;
- lp->tx_link = lp->tx_tail + 0x08;
- lp->rx_buf_start = tx_block;
-
-}
-
-/*
- * Write the circular list of receive buffer descriptors to card memory.
- * The end of the list isn't marked, which means that the 82586 receive
- * unit will loop until buffers become available (this avoids it giving us
- * "out of resources" messages).
- */
-
-static void eexp_hw_rxinit(struct net_device *dev)
-{
- struct net_local *lp = netdev_priv(dev);
- unsigned short rx_block = lp->rx_buf_start;
- unsigned short ioaddr = dev->base_addr;
-
- lp->num_rx_bufs = 0;
- lp->rx_first = lp->rx_ptr = rx_block;
- do
- {
- lp->num_rx_bufs++;
-
- outw(rx_block, ioaddr + WRITE_PTR);
-
- outw(0, ioaddr + DATAPORT); outw(0, ioaddr+DATAPORT);
- outw(rx_block + RX_BUF_SIZE, ioaddr+DATAPORT);
- outw(0xffff, ioaddr+DATAPORT);
-
- outw(0x0000, ioaddr+DATAPORT);
- outw(0xdead, ioaddr+DATAPORT);
- outw(0xdead, ioaddr+DATAPORT);
- outw(0xdead, ioaddr+DATAPORT);
- outw(0xdead, ioaddr+DATAPORT);
- outw(0xdead, ioaddr+DATAPORT);
- outw(0xdead, ioaddr+DATAPORT);
-
- outw(0x0000, ioaddr+DATAPORT);
- outw(rx_block + RX_BUF_SIZE + 0x16, ioaddr+DATAPORT);
- outw(rx_block + 0x20, ioaddr+DATAPORT);
- outw(0, ioaddr+DATAPORT);
- outw(RX_BUF_SIZE-0x20, ioaddr+DATAPORT);
-
- lp->rx_last = rx_block;
- rx_block += RX_BUF_SIZE;
- } while (rx_block <= lp->rx_buf_end-RX_BUF_SIZE);
-
-
- /* Make first Rx frame descriptor point to first Rx buffer
- descriptor */
- outw(lp->rx_first + 6, ioaddr+WRITE_PTR);
- outw(lp->rx_first + 0x16, ioaddr+DATAPORT);
-
- /* Close Rx frame descriptor ring */
- outw(lp->rx_last + 4, ioaddr+WRITE_PTR);
- outw(lp->rx_first, ioaddr+DATAPORT);
-
- /* Close Rx buffer descriptor ring */
- outw(lp->rx_last + 0x16 + 2, ioaddr+WRITE_PTR);
- outw(lp->rx_first + 0x16, ioaddr+DATAPORT);
-
-}
-
-/*
- * Un-reset the 586, and start the configuration sequence. We don't wait for
- * this to finish, but allow the interrupt handler to start the CU and RU for
- * us. We can't start the receive/transmission system up before we know that
- * the hardware is configured correctly.
- */
-
-static void eexp_hw_init586(struct net_device *dev)
-{
- struct net_local *lp = netdev_priv(dev);
- unsigned short ioaddr = dev->base_addr;
- int i;
-
-#if NET_DEBUG > 6
- printk("%s: eexp_hw_init586()\n", dev->name);
-#endif
-
- lp->started = 0;
-
- set_loopback(dev);
-
- outb(SIRQ_dis|irqrmap[dev->irq],ioaddr+SET_IRQ);
-
- /* Download the startup code */
- outw(lp->rx_buf_end & ~31, ioaddr + SM_PTR);
- outw(lp->width?0x0001:0x0000, ioaddr + 0x8006);
- outw(0x0000, ioaddr + 0x8008);
- outw(0x0000, ioaddr + 0x800a);
- outw(0x0000, ioaddr + 0x800c);
- outw(0x0000, ioaddr + 0x800e);
-
- for (i = 0; i < ARRAY_SIZE(start_code) * 2; i+=32) {
- int j;
- outw(i, ioaddr + SM_PTR);
- for (j = 0; j < 16 && (i+j)/2 < ARRAY_SIZE(start_code); j+=2)
- outw(start_code[(i+j)/2],
- ioaddr+0x4000+j);
- for (j = 0; j < 16 && (i+j+16)/2 < ARRAY_SIZE(start_code); j+=2)
- outw(start_code[(i+j+16)/2],
- ioaddr+0x8000+j);
- }
-
- /* Do we want promiscuous mode or multicast? */
- outw(CONF_PROMISC & ~31, ioaddr+SM_PTR);
- i = inw(ioaddr+SHADOW(CONF_PROMISC));
- outw((dev->flags & IFF_PROMISC)?(i|1):(i & ~1),
- ioaddr+SHADOW(CONF_PROMISC));
- lp->was_promisc = dev->flags & IFF_PROMISC;
-#if 0
- eexp_setup_filter(dev);
-#endif
-
- /* Write our hardware address */
- outw(CONF_HWADDR & ~31, ioaddr+SM_PTR);
- outw(((unsigned short *)dev->dev_addr)[0], ioaddr+SHADOW(CONF_HWADDR));
- outw(((unsigned short *)dev->dev_addr)[1],
- ioaddr+SHADOW(CONF_HWADDR+2));
- outw(((unsigned short *)dev->dev_addr)[2],
- ioaddr+SHADOW(CONF_HWADDR+4));
-
- eexp_hw_txinit(dev);
- eexp_hw_rxinit(dev);
-
- outb(0,ioaddr+EEPROM_Ctrl);
- mdelay(5);
-
- scb_command(dev, 0xf000);
- outb(0,ioaddr+SIGNAL_CA);
-
- outw(0, ioaddr+SM_PTR);
-
- {
- unsigned short rboguscount=50,rfailcount=5;
- while (inw(ioaddr+0x4000))
- {
- if (!--rboguscount)
- {
- printk(KERN_WARNING "%s: i82586 reset timed out, kicking...\n",
- dev->name);
- scb_command(dev, 0);
- outb(0,ioaddr+SIGNAL_CA);
- rboguscount = 100;
- if (!--rfailcount)
- {
- printk(KERN_WARNING "%s: i82586 not responding, giving up.\n",
- dev->name);
- return;
- }
- }
- }
- }
-
- scb_wrcbl(dev, CONF_LINK);
- scb_command(dev, 0xf000|SCB_CUstart);
- outb(0,ioaddr+SIGNAL_CA);
-
- {
- unsigned short iboguscount=50,ifailcount=5;
- while (!scb_status(dev))
- {
- if (!--iboguscount)
- {
- if (--ifailcount)
- {
- printk(KERN_WARNING "%s: i82586 initialization timed out, status %04x, cmd %04x\n",
- dev->name, scb_status(dev), scb_rdcmd(dev));
- scb_wrcbl(dev, CONF_LINK);
- scb_command(dev, 0xf000|SCB_CUstart);
- outb(0,ioaddr+SIGNAL_CA);
- iboguscount = 100;
- }
- else
- {
- printk(KERN_WARNING "%s: Failed to initialize i82586, giving up.\n",dev->name);
- return;
- }
- }
- }
- }
-
- clear_loopback(dev);
- outb(SIRQ_en|irqrmap[dev->irq],ioaddr+SET_IRQ);
-
- lp->init_time = jiffies;
-#if NET_DEBUG > 6
- printk("%s: leaving eexp_hw_init586()\n", dev->name);
-#endif
-}
-
-static void eexp_setup_filter(struct net_device *dev)
-{
- struct netdev_hw_addr *ha;
- unsigned short ioaddr = dev->base_addr;
- int count = netdev_mc_count(dev);
- int i;
- if (count > 8) {
- printk(KERN_INFO "%s: too many multicast addresses (%d)\n",
- dev->name, count);
- count = 8;
- }
-
- outw(CONF_NR_MULTICAST & ~31, ioaddr+SM_PTR);
- outw(6*count, ioaddr+SHADOW(CONF_NR_MULTICAST));
- i = 0;
- netdev_for_each_mc_addr(ha, dev) {
- unsigned short *data = (unsigned short *) ha->addr;
-
- if (i == count)
- break;
- outw((CONF_MULTICAST+(6*i)) & ~31, ioaddr+SM_PTR);
- outw(data[0], ioaddr+SHADOW(CONF_MULTICAST+(6*i)));
- outw((CONF_MULTICAST+(6*i)+2) & ~31, ioaddr+SM_PTR);
- outw(data[1], ioaddr+SHADOW(CONF_MULTICAST+(6*i)+2));
- outw((CONF_MULTICAST+(6*i)+4) & ~31, ioaddr+SM_PTR);
- outw(data[2], ioaddr+SHADOW(CONF_MULTICAST+(6*i)+4));
- i++;
- }
-}
-
-/*
- * Set or clear the multicast filter for this adaptor.
- */
-static void
-eexp_set_multicast(struct net_device *dev)
-{
- unsigned short ioaddr = dev->base_addr;
- struct net_local *lp = netdev_priv(dev);
- int kick = 0, i;
- if ((dev->flags & IFF_PROMISC) != lp->was_promisc) {
- outw(CONF_PROMISC & ~31, ioaddr+SM_PTR);
- i = inw(ioaddr+SHADOW(CONF_PROMISC));
- outw((dev->flags & IFF_PROMISC)?(i|1):(i & ~1),
- ioaddr+SHADOW(CONF_PROMISC));
- lp->was_promisc = dev->flags & IFF_PROMISC;
- kick = 1;
- }
- if (!(dev->flags & IFF_PROMISC)) {
- eexp_setup_filter(dev);
- if (lp->old_mc_count != netdev_mc_count(dev)) {
- kick = 1;
- lp->old_mc_count = netdev_mc_count(dev);
- }
- }
- if (kick) {
- unsigned long oj;
- scb_command(dev, SCB_CUsuspend);
- outb(0, ioaddr+SIGNAL_CA);
- outb(0, ioaddr+SIGNAL_CA);
-#if 0
- printk("%s: waiting for CU to go suspended\n", dev->name);
-#endif
- oj = jiffies;
- while ((SCB_CUstat(scb_status(dev)) == 2) &&
- (time_before(jiffies, oj + 2000)));
- if (SCB_CUstat(scb_status(dev)) == 2)
- printk("%s: warning, CU didn't stop\n", dev->name);
- lp->started &= ~(STARTED_CU);
- scb_wrcbl(dev, CONF_LINK);
- scb_command(dev, SCB_CUstart);
- outb(0, ioaddr+SIGNAL_CA);
- }
-}
-
-
-/*
- * MODULE stuff
- */
-
-#ifdef MODULE
-
-#define EEXP_MAX_CARDS 4 /* max number of cards to support */
-
-static struct net_device *dev_eexp[EEXP_MAX_CARDS];
-static int irq[EEXP_MAX_CARDS];
-static int io[EEXP_MAX_CARDS];
-
-module_param_array(io, int, NULL, 0);
-module_param_array(irq, int, NULL, 0);
-MODULE_PARM_DESC(io, "EtherExpress 16 I/O base address(es)");
-MODULE_PARM_DESC(irq, "EtherExpress 16 IRQ number(s)");
-MODULE_LICENSE("GPL");
-
-
-/* Ideally the user would give us io=, irq= for every card. If any parameters
- * are specified, we verify and then use them. If no parameters are given, we
- * autoprobe for one card only.
- */
-int __init init_module(void)
-{
- struct net_device *dev;
- int this_dev, found = 0;
-
- for (this_dev = 0; this_dev < EEXP_MAX_CARDS; this_dev++) {
- dev = alloc_etherdev(sizeof(struct net_local));
- dev->irq = irq[this_dev];
- dev->base_addr = io[this_dev];
- if (io[this_dev] == 0) {
- if (this_dev)
- break;
- printk(KERN_NOTICE "eexpress.c: Module autoprobe not recommended, give io=xx.\n");
- }
- if (do_express_probe(dev) == 0) {
- dev_eexp[this_dev] = dev;
- found++;
- continue;
- }
- printk(KERN_WARNING "eexpress.c: Failed to register card at 0x%x.\n", io[this_dev]);
- free_netdev(dev);
- break;
- }
- if (found)
- return 0;
- return -ENXIO;
-}
-
-void __exit cleanup_module(void)
-{
- int this_dev;
-
- for (this_dev = 0; this_dev < EEXP_MAX_CARDS; this_dev++) {
- struct net_device *dev = dev_eexp[this_dev];
- if (dev) {
- unregister_netdev(dev);
- free_netdev(dev);
- }
- }
-}
-#endif
-
-/*
- * Local Variables:
- * c-file-style: "linux"
- * tab-width: 8
- * End:
- */
diff --git a/drivers/net/ethernet/i825xx/eexpress.h b/drivers/net/ethernet/i825xx/eexpress.h
deleted file mode 100644
index dc9c6ea289e..00000000000
--- a/drivers/net/ethernet/i825xx/eexpress.h
+++ /dev/null
@@ -1,179 +0,0 @@
-/*
- * eexpress.h: Intel EtherExpress16 defines
- */
-
-/*
- * EtherExpress card register addresses
- * as offsets from the base IO region (dev->base_addr)
- */
-
-#define DATAPORT 0x0000
-#define WRITE_PTR 0x0002
-#define READ_PTR 0x0004
-#define SIGNAL_CA 0x0006
-#define SET_IRQ 0x0007
-#define SM_PTR 0x0008
-#define MEM_Dec 0x000a
-#define MEM_Ctrl 0x000b
-#define MEM_Page_Ctrl 0x000c
-#define Config 0x000d
-#define EEPROM_Ctrl 0x000e
-#define ID_PORT 0x000f
-#define MEM_ECtrl 0x000f
-
-/*
- * card register defines
- */
-
-/* SET_IRQ */
-#define SIRQ_en 0x08
-#define SIRQ_dis 0x00
-
-/* EEPROM_Ctrl */
-#define EC_Clk 0x01
-#define EC_CS 0x02
-#define EC_Wr 0x04
-#define EC_Rd 0x08
-#define ASIC_RST 0x40
-#define i586_RST 0x80
-
-#define eeprom_delay() { udelay(40); }
-
-/*
- * i82586 Memory Configuration
- */
-
-/* (System Configuration Pointer) System start up block, read after 586_RST */
-#define SCP_START 0xfff6
-
-/* Intermediate System Configuration Pointer */
-#define ISCP_START 0x0000
-
-/* System Command Block */
-#define SCB_START 0x0008
-
-/* Start of buffer region. Everything before this is used for control
- * structures and the CU configuration program. The memory layout is
- * determined in eexp_hw_probe(), once we know how much memory is
- * available on the card.
- */
-
-#define TX_BUF_START 0x0100
-
-#define TX_BUF_SIZE ((24+ETH_FRAME_LEN+31)&~0x1f)
-#define RX_BUF_SIZE ((32+ETH_FRAME_LEN+31)&~0x1f)
-
-/*
- * SCB defines
- */
-
-/* these functions take the SCB status word and test the relevant status bit */
-#define SCB_complete(s) (((s) & 0x8000) != 0)
-#define SCB_rxdframe(s) (((s) & 0x4000) != 0)
-#define SCB_CUdead(s) (((s) & 0x2000) != 0)
-#define SCB_RUdead(s) (((s) & 0x1000) != 0)
-#define SCB_ack(s) ((s) & 0xf000)
-
-/* Command unit status: 0=idle, 1=suspended, 2=active */
-#define SCB_CUstat(s) (((s)&0x0300)>>8)
-
-/* Receive unit status: 0=idle, 1=suspended, 2=out of resources, 4=ready */
-#define SCB_RUstat(s) (((s)&0x0070)>>4)
-
-/* SCB commands */
-#define SCB_CUnop 0x0000
-#define SCB_CUstart 0x0100
-#define SCB_CUresume 0x0200
-#define SCB_CUsuspend 0x0300
-#define SCB_CUabort 0x0400
-#define SCB_resetchip 0x0080
-
-#define SCB_RUnop 0x0000
-#define SCB_RUstart 0x0010
-#define SCB_RUresume 0x0020
-#define SCB_RUsuspend 0x0030
-#define SCB_RUabort 0x0040
-
-/*
- * Command block defines
- */
-
-#define Stat_Done(s) (((s) & 0x8000) != 0)
-#define Stat_Busy(s) (((s) & 0x4000) != 0)
-#define Stat_OK(s) (((s) & 0x2000) != 0)
-#define Stat_Abort(s) (((s) & 0x1000) != 0)
-#define Stat_STFail (((s) & 0x0800) != 0)
-#define Stat_TNoCar(s) (((s) & 0x0400) != 0)
-#define Stat_TNoCTS(s) (((s) & 0x0200) != 0)
-#define Stat_TNoDMA(s) (((s) & 0x0100) != 0)
-#define Stat_TDefer(s) (((s) & 0x0080) != 0)
-#define Stat_TColl(s) (((s) & 0x0040) != 0)
-#define Stat_TXColl(s) (((s) & 0x0020) != 0)
-#define Stat_NoColl(s) ((s) & 0x000f)
-
-/* Cmd_END will end AFTER the command if this is the first
- * command block after an SCB_CUstart, but BEFORE the command
- * for all subsequent commands. Best strategy is to place
- * Cmd_INT on the last command in the sequence, followed by a
- * dummy Cmd_Nop with Cmd_END after this.
- */
-
-#define Cmd_END 0x8000
-#define Cmd_SUS 0x4000
-#define Cmd_INT 0x2000
-
-#define Cmd_Nop 0x0000
-#define Cmd_SetAddr 0x0001
-#define Cmd_Config 0x0002
-#define Cmd_MCast 0x0003
-#define Cmd_Xmit 0x0004
-#define Cmd_TDR 0x0005
-#define Cmd_Dump 0x0006
-#define Cmd_Diag 0x0007
-
-
-/*
- * Frame Descriptor (Receive block) defines
- */
-
-#define FD_Done(s) (((s) & 0x8000) != 0)
-#define FD_Busy(s) (((s) & 0x4000) != 0)
-#define FD_OK(s) (((s) & 0x2000) != 0)
-
-#define FD_CRC(s) (((s) & 0x0800) != 0)
-#define FD_Align(s) (((s) & 0x0400) != 0)
-#define FD_Resrc(s) (((s) & 0x0200) != 0)
-#define FD_DMA(s) (((s) & 0x0100) != 0)
-#define FD_Short(s) (((s) & 0x0080) != 0)
-#define FD_NoEOF(s) (((s) & 0x0040) != 0)
-
-struct rfd_header {
- volatile unsigned long flags;
- volatile unsigned short link;
- volatile unsigned short rbd_offset;
- volatile unsigned short dstaddr1;
- volatile unsigned short dstaddr2;
- volatile unsigned short dstaddr3;
- volatile unsigned short srcaddr1;
- volatile unsigned short srcaddr2;
- volatile unsigned short srcaddr3;
- volatile unsigned short length;
-
- /* This is actually a Receive Buffer Descriptor. The way we
- * arrange memory means that an RBD always follows the RFD that
- * points to it, so they might as well be in the same structure.
- */
- volatile unsigned short actual_count;
- volatile unsigned short next_rbd;
- volatile unsigned short buf_addr1;
- volatile unsigned short buf_addr2;
- volatile unsigned short size;
-};
-
-/* Returned data from the Time Domain Reflectometer */
-
-#define TDR_LINKOK (1<<15)
-#define TDR_XCVRPROBLEM (1<<14)
-#define TDR_OPEN (1<<13)
-#define TDR_SHORT (1<<12)
-#define TDR_TIME 0x7ff
diff --git a/drivers/net/ethernet/i825xx/lp486e.c b/drivers/net/ethernet/i825xx/lp486e.c
deleted file mode 100644
index 3735bfa5360..00000000000
--- a/drivers/net/ethernet/i825xx/lp486e.c
+++ /dev/null
@@ -1,1337 +0,0 @@
-/* Intel Professional Workstation/panther ethernet driver */
-/* lp486e.c: A panther 82596 ethernet driver for linux. */
-/*
- History and copyrights:
-
- Driver skeleton
- Written 1993 by Donald Becker.
- Copyright 1993 United States Government as represented by the Director,
- National Security Agency. This software may only be used and
- distributed according to the terms of the GNU General Public License
- as modified by SRC, incorporated herein by reference.
-
- The author may be reached as becker@scyld.com, or C/O
- Scyld Computing Corporation
- 410 Severn Ave., Suite 210
- Annapolis MD 21403
-
- Apricot
- Written 1994 by Mark Evans.
- This driver is for the Apricot 82596 bus-master interface
-
- Modularised 12/94 Mark Evans
-
- Professional Workstation
- Derived from apricot.c by Ard van Breemen
- <ard@murphy.nl>|<ard@cstmel.hobby.nl>|<ard@cstmel.nl.eu.org>
-
- Credits:
- Thanks to Murphy Software BV for letting me write this in their time.
- Well, actually, I get paid doing this...
- (Also: see http://www.murphy.nl for murphy, and my homepage ~ard for
- more information on the Professional Workstation)
-
- Present version
- aeb@cwi.nl
-*/
-/*
- There are currently two motherboards that I know of in the
- professional workstation. The only one that I know is the
- intel panther motherboard. -- ard
-*/
-/*
-The pws is equipped with an intel 82596. This is a very intelligent controller
-which runs its own micro-code. Communication with the hostprocessor is done
-through linked lists of commands and buffers in the hostprocessors memory.
-A complete description of the 82596 is available from intel. Search for
-a file called "29021806.pdf". It is a complete description of the chip itself.
-To use it for the pws some additions are needed regarding generation of
-the PORT and CA signal, and the interrupt glue needed for a pc.
-I/O map:
-PORT SIZE ACTION MEANING
-0xCB0 2 WRITE Lower 16 bits for PORT command
-0xCB2 2 WRITE Upper 16 bits for PORT command, and issue of PORT command
-0xCB4 1 WRITE Generation of CA signal
-0xCB8 1 WRITE Clear interrupt glue
-All other communication is through memory!
-*/
-
-#include <linux/module.h>
-#include <linux/init.h>
-#include <linux/delay.h>
-#include <linux/kernel.h>
-#include <linux/string.h>
-#include <linux/errno.h>
-#include <linux/ioport.h>
-#include <linux/slab.h>
-#include <linux/interrupt.h>
-#include <linux/netdevice.h>
-#include <linux/etherdevice.h>
-#include <linux/skbuff.h>
-#include <linux/bitops.h>
-
-#include <asm/io.h>
-#include <asm/dma.h>
-
-#define DRV_NAME "lp486e"
-
-/* debug print flags */
-#define LOG_SRCDST 0x80000000
-#define LOG_STATINT 0x40000000
-#define LOG_STARTINT 0x20000000
-
-#define i596_debug debug
-
-static int i596_debug = 0;
-
-static const char * const medianame[] = {
- "10baseT", "AUI",
- "10baseT-FD", "AUI-FD",
-};
-
-#define LP486E_TOTAL_SIZE 16
-
-#define I596_NULL (0xffffffff)
-
-#define CMD_EOL 0x8000 /* The last command of the list, stop. */
-#define CMD_SUSP 0x4000 /* Suspend after doing cmd. */
-#define CMD_INTR 0x2000 /* Interrupt after doing cmd. */
-
-#define CMD_FLEX 0x0008 /* Enable flexible memory model */
-
-enum commands {
- CmdNOP = 0,
- CmdIASetup = 1,
- CmdConfigure = 2,
- CmdMulticastList = 3,
- CmdTx = 4,
- CmdTDR = 5,
- CmdDump = 6,
- CmdDiagnose = 7
-};
-
-#if 0
-static const char *CUcmdnames[8] = { "NOP", "IASetup", "Configure", "MulticastList",
- "Tx", "TDR", "Dump", "Diagnose" };
-#endif
-
-/* Status word bits */
-#define STAT_CX 0x8000 /* The CU finished executing a command
- with the Interrupt bit set */
-#define STAT_FR 0x4000 /* The RU finished receiving a frame */
-#define STAT_CNA 0x2000 /* The CU left the active state */
-#define STAT_RNR 0x1000 /* The RU left the active state */
-#define STAT_ACK (STAT_CX | STAT_FR | STAT_CNA | STAT_RNR)
-#define STAT_CUS 0x0700 /* Status of CU: 0: idle, 1: suspended,
- 2: active, 3-7: unused */
-#define STAT_RUS 0x00f0 /* Status of RU: 0: idle, 1: suspended,
- 2: no resources, 4: ready,
- 10: no resources due to no more RBDs,
- 12: no more RBDs, other: unused */
-#define STAT_T 0x0008 /* Bus throttle timers loaded */
-#define STAT_ZERO 0x0807 /* Always zero */
-
-#if 0
-static char *CUstates[8] = {
- "idle", "suspended", "active", 0, 0, 0, 0, 0
-};
-static char *RUstates[16] = {
- "idle", "suspended", "no resources", 0, "ready", 0, 0, 0,
- 0, 0, "no RBDs", 0, "out of RBDs", 0, 0, 0
-};
-
-static void
-i596_out_status(int status) {
- int bad = 0;
- char *s;
-
- printk("status %4.4x:", status);
- if (status == 0xffff)
- printk(" strange..\n");
- else {
- if (status & STAT_CX)
- printk(" CU done");
- if (status & STAT_CNA)
- printk(" CU stopped");
- if (status & STAT_FR)
- printk(" got a frame");
- if (status & STAT_RNR)
- printk(" RU stopped");
- if (status & STAT_T)
- printk(" throttled");
- if (status & STAT_ZERO)
- bad = 1;
- s = CUstates[(status & STAT_CUS) >> 8];
- if (!s)
- bad = 1;
- else
- printk(" CU(%s)", s);
- s = RUstates[(status & STAT_RUS) >> 4];
- if (!s)
- bad = 1;
- else
- printk(" RU(%s)", s);
- if (bad)
- printk(" bad status");
- printk("\n");
- }
-}
-#endif
-
-/* Command word bits */
-#define ACK_CX 0x8000
-#define ACK_FR 0x4000
-#define ACK_CNA 0x2000
-#define ACK_RNR 0x1000
-
-#define CUC_START 0x0100
-#define CUC_RESUME 0x0200
-#define CUC_SUSPEND 0x0300
-#define CUC_ABORT 0x0400
-
-#define RX_START 0x0010
-#define RX_RESUME 0x0020
-#define RX_SUSPEND 0x0030
-#define RX_ABORT 0x0040
-
-typedef u32 phys_addr;
-
-static inline phys_addr
-va_to_pa(void *x) {
- return x ? virt_to_bus(x) : I596_NULL;
-}
-
-static inline void *
-pa_to_va(phys_addr x) {
- return (x == I596_NULL) ? NULL : bus_to_virt(x);
-}
-
-/* status bits for cmd */
-#define CMD_STAT_C 0x8000 /* CU command complete */
-#define CMD_STAT_B 0x4000 /* CU command in progress */
-#define CMD_STAT_OK 0x2000 /* CU command completed without errors */
-#define CMD_STAT_A 0x1000 /* CU command abnormally terminated */
-
-struct i596_cmd { /* 8 bytes */
- unsigned short status;
- unsigned short command;
- phys_addr pa_next; /* va_to_pa(struct i596_cmd *next) */
-};
-
-#define EOF 0x8000
-#define SIZE_MASK 0x3fff
-
-struct i596_tbd {
- unsigned short size;
- unsigned short pad;
- phys_addr pa_next; /* va_to_pa(struct i596_tbd *next) */
- phys_addr pa_data; /* va_to_pa(char *data) */
- struct sk_buff *skb;
-};
-
-struct tx_cmd {
- struct i596_cmd cmd;
- phys_addr pa_tbd; /* va_to_pa(struct i596_tbd *tbd) */
- unsigned short size;
- unsigned short pad;
-};
-
-/* status bits for rfd */
-#define RFD_STAT_C 0x8000 /* Frame reception complete */
-#define RFD_STAT_B 0x4000 /* Frame reception in progress */
-#define RFD_STAT_OK 0x2000 /* Frame received without errors */
-#define RFD_STATUS 0x1fff
-#define RFD_LENGTH_ERR 0x1000
-#define RFD_CRC_ERR 0x0800
-#define RFD_ALIGN_ERR 0x0400
-#define RFD_NOBUFS_ERR 0x0200
-#define RFD_DMA_ERR 0x0100 /* DMA overrun failure to acquire system bus */
-#define RFD_SHORT_FRAME_ERR 0x0080
-#define RFD_NOEOP_ERR 0x0040
-#define RFD_TRUNC_ERR 0x0020
-#define RFD_MULTICAST 0x0002 /* 0: destination had our address
- 1: destination was broadcast/multicast */
-#define RFD_COLLISION 0x0001
-
-/* receive frame descriptor */
-struct i596_rfd {
- unsigned short stat;
- unsigned short cmd;
- phys_addr pa_next; /* va_to_pa(struct i596_rfd *next) */
- phys_addr pa_rbd; /* va_to_pa(struct i596_rbd *rbd) */
- unsigned short count;
- unsigned short size;
- char data[1532];
-};
-
-#define RBD_EL 0x8000
-#define RBD_P 0x4000
-#define RBD_SIZEMASK 0x3fff
-#define RBD_EOF 0x8000
-#define RBD_F 0x4000
-
-/* receive buffer descriptor */
-struct i596_rbd {
- unsigned short size;
- unsigned short pad;
- phys_addr pa_next; /* va_to_pa(struct i596_tbd *next) */
- phys_addr pa_data; /* va_to_pa(char *data) */
- phys_addr pa_prev; /* va_to_pa(struct i596_tbd *prev) */
-
- /* Driver private part */
- struct sk_buff *skb;
-};
-
-#define RX_RING_SIZE 64
-#define RX_SKBSIZE (ETH_FRAME_LEN+10)
-#define RX_RBD_SIZE 32
-
-/* System Control Block - 40 bytes */
-struct i596_scb {
- u16 status; /* 0 */
- u16 command; /* 2 */
- phys_addr pa_cmd; /* 4 - va_to_pa(struct i596_cmd *cmd) */
- phys_addr pa_rfd; /* 8 - va_to_pa(struct i596_rfd *rfd) */
- u32 crc_err; /* 12 */
- u32 align_err; /* 16 */
- u32 resource_err; /* 20 */
- u32 over_err; /* 24 */
- u32 rcvdt_err; /* 28 */
- u32 short_err; /* 32 */
- u16 t_on; /* 36 */
- u16 t_off; /* 38 */
-};
-
-/* Intermediate System Configuration Pointer - 8 bytes */
-struct i596_iscp {
- u32 busy; /* 0 */
- phys_addr pa_scb; /* 4 - va_to_pa(struct i596_scb *scb) */
-};
-
-/* System Configuration Pointer - 12 bytes */
-struct i596_scp {
- u32 sysbus; /* 0 */
- u32 pad; /* 4 */
- phys_addr pa_iscp; /* 8 - va_to_pa(struct i596_iscp *iscp) */
-};
-
-/* Selftest and dump results - needs 16-byte alignment */
-/*
- * The size of the dump area is 304 bytes. When the dump is executed
- * by the Port command an extra word will be appended to the dump area.
- * The extra word is a copy of the Dump status word (containing the
- * C, B, OK bits). [I find 0xa006, with a0 for C+OK and 6 for dump]
- */
-struct i596_dump {
- u16 dump[153]; /* (304 = 130h) + 2 bytes */
-};
-
-struct i596_private { /* aligned to a 16-byte boundary */
- struct i596_scp scp; /* 0 - needs 16-byte alignment */
- struct i596_iscp iscp; /* 12 */
- struct i596_scb scb; /* 20 */
- u32 dummy; /* 60 */
- struct i596_dump dump; /* 64 - needs 16-byte alignment */
-
- struct i596_cmd set_add;
- char eth_addr[8]; /* directly follows set_add */
-
- struct i596_cmd set_conf;
- char i596_config[16]; /* directly follows set_conf */
-
- struct i596_cmd tdr;
- unsigned long tdr_stat; /* directly follows tdr */
-
- int last_restart;
- struct i596_rbd *rbd_list;
- struct i596_rbd *rbd_tail;
- struct i596_rfd *rx_tail;
- struct i596_cmd *cmd_tail;
- struct i596_cmd *cmd_head;
- int cmd_backlog;
- unsigned long last_cmd;
- spinlock_t cmd_lock;
-};
-
-static char init_setup[14] = {
- 0x8E, /* length 14 bytes, prefetch on */
- 0xC8, /* default: fifo to 8, monitor off */
- 0x40, /* default: don't save bad frames (apricot.c had 0x80) */
- 0x2E, /* (default is 0x26)
- No source address insertion, 8 byte preamble */
- 0x00, /* default priority and backoff */
- 0x60, /* default interframe spacing */
- 0x00, /* default slot time LSB */
- 0xf2, /* default slot time and nr of retries */
- 0x00, /* default various bits
- (0: promiscuous mode, 1: broadcast disable,
- 2: encoding mode, 3: transmit on no CRS,
- 4: no CRC insertion, 5: CRC type,
- 6: bit stuffing, 7: padding) */
- 0x00, /* default carrier sense and collision detect */
- 0x40, /* default minimum frame length */
- 0xff, /* (default is 0xff, and that is what apricot.c has;
- elp486.c has 0xfb: Enable crc append in memory.) */
- 0x00, /* default: not full duplex */
- 0x7f /* (default is 0x3f) multi IA */
-};
-
-static int i596_open(struct net_device *dev);
-static netdev_tx_t i596_start_xmit(struct sk_buff *skb, struct net_device *dev);
-static irqreturn_t i596_interrupt(int irq, void *dev_id);
-static int i596_close(struct net_device *dev);
-static void i596_add_cmd(struct net_device *dev, struct i596_cmd *cmd);
-static void print_eth(char *);
-static void set_multicast_list(struct net_device *dev);
-static void i596_tx_timeout(struct net_device *dev);
-
-static int
-i596_timeout(struct net_device *dev, char *msg, int ct) {
- struct i596_private *lp;
- int boguscnt = ct;
-
- lp = netdev_priv(dev);
- while (lp->scb.command) {
- if (--boguscnt == 0) {
- printk("%s: %s timed out - stat %4.4x, cmd %4.4x\n",
- dev->name, msg,
- lp->scb.status, lp->scb.command);
- return 1;
- }
- udelay(5);
- barrier();
- }
- return 0;
-}
-
-static inline int
-init_rx_bufs(struct net_device *dev, int num) {
- struct i596_private *lp;
- struct i596_rfd *rfd;
- int i;
- // struct i596_rbd *rbd;
-
- lp = netdev_priv(dev);
- lp->scb.pa_rfd = I596_NULL;
-
- for (i = 0; i < num; i++) {
- rfd = kmalloc(sizeof(struct i596_rfd), GFP_KERNEL);
- if (rfd == NULL)
- break;
-
- rfd->stat = 0;
- rfd->pa_rbd = I596_NULL;
- rfd->count = 0;
- rfd->size = 1532;
- if (i == 0) {
- rfd->cmd = CMD_EOL;
- lp->rx_tail = rfd;
- } else {
- rfd->cmd = 0;
- }
- rfd->pa_next = lp->scb.pa_rfd;
- lp->scb.pa_rfd = va_to_pa(rfd);
- lp->rx_tail->pa_next = lp->scb.pa_rfd;
- }
-
-#if 0
- for (i = 0; i<RX_RBD_SIZE; i++) {
- rbd = kmalloc(sizeof(struct i596_rbd), GFP_KERNEL);
- if (rbd) {
- rbd->pad = 0;
- rbd->count = 0;
- rbd->skb = dev_alloc_skb(RX_SKBSIZE);
- if (!rbd->skb) {
- printk("dev_alloc_skb failed");
- }
- rbd->next = rfd->rbd;
- if (i) {
- rfd->rbd->prev = rbd;
- rbd->size = RX_SKBSIZE;
- } else {
- rbd->size = (RX_SKBSIZE | RBD_EL);
- lp->rbd_tail = rbd;
- }
-
- rfd->rbd = rbd;
- }
- }
- lp->rbd_tail->next = rfd->rbd;
-#endif
- return i;
-}
-
-static inline void
-remove_rx_bufs(struct net_device *dev) {
- struct i596_private *lp;
- struct i596_rfd *rfd;
-
- lp = netdev_priv(dev);
- lp->rx_tail->pa_next = I596_NULL;
-
- do {
- rfd = pa_to_va(lp->scb.pa_rfd);
- lp->scb.pa_rfd = rfd->pa_next;
- kfree(rfd);
- } while (rfd != lp->rx_tail);
-
- lp->rx_tail = NULL;
-
-#if 0
- for (lp->rbd_list) {
- }
-#endif
-}
-
-#define PORT_RESET 0x00 /* reset 82596 */
-#define PORT_SELFTEST 0x01 /* selftest */
-#define PORT_ALTSCP 0x02 /* alternate SCB address */
-#define PORT_DUMP 0x03 /* dump */
-
-#define IOADDR 0xcb0 /* real constant */
-#define IRQ 10 /* default IRQ - can be changed by ECU */
-
-/* The 82596 requires two 16-bit write cycles for a port command */
-static inline void
-PORT(phys_addr a, unsigned int cmd) {
- if (a & 0xf)
- printk("lp486e.c: PORT: address not aligned\n");
- outw(((a & 0xffff) | cmd), IOADDR);
- outw(((a>>16) & 0xffff), IOADDR+2);
-}
-
-static inline void
-CA(void) {
- outb(0, IOADDR+4);
- udelay(8);
-}
-
-static inline void
-CLEAR_INT(void) {
- outb(0, IOADDR+8);
-}
-
-#if 0
-/* selftest or dump */
-static void
-i596_port_do(struct net_device *dev, int portcmd, char *cmdname) {
- struct i596_private *lp = netdev_priv(dev);
- u16 *outp;
- int i, m;
-
- memset((void *)&(lp->dump), 0, sizeof(struct i596_dump));
- outp = &(lp->dump.dump[0]);
-
- PORT(va_to_pa(outp), portcmd);
- mdelay(30); /* random, unmotivated */
-
- printk("lp486e i82596 %s result:\n", cmdname);
- for (m = ARRAY_SIZE(lp->dump.dump); m && lp->dump.dump[m-1] == 0; m--)
- ;
- for (i = 0; i < m; i++) {
- printk(" %04x", lp->dump.dump[i]);
- if (i%8 == 7)
- printk("\n");
- }
- printk("\n");
-}
-#endif
-
-static int
-i596_scp_setup(struct net_device *dev) {
- struct i596_private *lp = netdev_priv(dev);
- int boguscnt;
-
- /* Setup SCP, ISCP, SCB */
- /*
- * sysbus bits:
- * only a single byte is significant - here 0x44
- * 0x80: big endian mode (details depend on stepping)
- * 0x40: 1
- * 0x20: interrupt pin is active low
- * 0x10: lock function disabled
- * 0x08: external triggering of bus throttle timers
- * 0x06: 00: 82586 compat mode, 01: segmented mode, 10: linear mode
- * 0x01: unused
- */
- lp->scp.sysbus = 0x00440000; /* linear mode */
- lp->scp.pad = 0; /* must be zero */
- lp->scp.pa_iscp = va_to_pa(&(lp->iscp));
-
- /*
- * The CPU sets the ISCP to 1 before it gives the first CA()
- */
- lp->iscp.busy = 0x0001;
- lp->iscp.pa_scb = va_to_pa(&(lp->scb));
-
- lp->scb.command = 0;
- lp->scb.status = 0;
- lp->scb.pa_cmd = I596_NULL;
- /* lp->scb.pa_rfd has been initialised already */
-
- lp->last_cmd = jiffies;
- lp->cmd_backlog = 0;
- lp->cmd_head = NULL;
-
- /*
- * Reset the 82596.
- * We need to wait 10 systemclock cycles, and
- * 5 serial clock cycles.
- */
- PORT(0, PORT_RESET); /* address part ignored */
- udelay(100);
-
- /*
- * Before the CA signal is asserted, the default SCP address
- * (0x00fffff4) can be changed to a 16-byte aligned value
- */
- PORT(va_to_pa(&lp->scp), PORT_ALTSCP); /* change the scp address */
-
- /*
- * The initialization procedure begins when a
- * Channel Attention signal is asserted after a reset.
- */
-
- CA();
-
- /*
- * The ISCP busy is cleared by the 82596 after the SCB address is read.
- */
- boguscnt = 100;
- while (lp->iscp.busy) {
- if (--boguscnt == 0) {
- /* No i82596 present? */
- printk("%s: i82596 initialization timed out\n",
- dev->name);
- return 1;
- }
- udelay(5);
- barrier();
- }
- /* I find here boguscnt==100, so no delay was required. */
-
- return 0;
-}
-
-static int
-init_i596(struct net_device *dev) {
- struct i596_private *lp;
-
- if (i596_scp_setup(dev))
- return 1;
-
- lp = netdev_priv(dev);
- lp->scb.command = 0;
-
- memcpy ((void *)lp->i596_config, init_setup, 14);
- lp->set_conf.command = CmdConfigure;
- i596_add_cmd(dev, (void *)&lp->set_conf);
-
- memcpy ((void *)lp->eth_addr, dev->dev_addr, 6);
- lp->set_add.command = CmdIASetup;
- i596_add_cmd(dev, &lp->set_add);
-
- lp->tdr.command = CmdTDR;
- i596_add_cmd(dev, &lp->tdr);
-
- if (lp->scb.command && i596_timeout(dev, "i82596 init", 200))
- return 1;
-
- lp->scb.command = RX_START;
- CA();
-
- barrier();
-
- if (lp->scb.command && i596_timeout(dev, "Receive Unit start", 100))
- return 1;
-
- return 0;
-}
-
-/* Receive a single frame */
-static inline int
-i596_rx_one(struct net_device *dev, struct i596_private *lp,
- struct i596_rfd *rfd, int *frames) {
-
- if (rfd->stat & RFD_STAT_OK) {
- /* a good frame */
- int pkt_len = (rfd->count & 0x3fff);
- struct sk_buff *skb = netdev_alloc_skb(dev, pkt_len);
-
- (*frames)++;
-
- if (rfd->cmd & CMD_EOL)
- printk("Received on EOL\n");
-
- if (skb == NULL) {
- printk ("%s: i596_rx Memory squeeze, "
- "dropping packet.\n", dev->name);
- dev->stats.rx_dropped++;
- return 1;
- }
-
- memcpy(skb_put(skb,pkt_len), rfd->data, pkt_len);
-
- skb->protocol = eth_type_trans(skb,dev);
- netif_rx(skb);
- dev->stats.rx_packets++;
- } else {
-#if 0
- printk("Frame reception error status %04x\n",
- rfd->stat);
-#endif
- dev->stats.rx_errors++;
- if (rfd->stat & RFD_COLLISION)
- dev->stats.collisions++;
- if (rfd->stat & RFD_SHORT_FRAME_ERR)
- dev->stats.rx_length_errors++;
- if (rfd->stat & RFD_DMA_ERR)
- dev->stats.rx_over_errors++;
- if (rfd->stat & RFD_NOBUFS_ERR)
- dev->stats.rx_fifo_errors++;
- if (rfd->stat & RFD_ALIGN_ERR)
- dev->stats.rx_frame_errors++;
- if (rfd->stat & RFD_CRC_ERR)
- dev->stats.rx_crc_errors++;
- if (rfd->stat & RFD_LENGTH_ERR)
- dev->stats.rx_length_errors++;
- }
- rfd->stat = rfd->count = 0;
- return 0;
-}
-
-static int
-i596_rx(struct net_device *dev) {
- struct i596_private *lp = netdev_priv(dev);
- struct i596_rfd *rfd;
- int frames = 0;
-
- while (1) {
- rfd = pa_to_va(lp->scb.pa_rfd);
- if (!rfd) {
- printk(KERN_ERR "i596_rx: NULL rfd?\n");
- return 0;
- }
-#if 1
- if (rfd->stat && !(rfd->stat & (RFD_STAT_C | RFD_STAT_B)))
- printk("SF:%p-%04x\n", rfd, rfd->stat);
-#endif
- if (!(rfd->stat & RFD_STAT_C))
- break; /* next one not ready */
- if (i596_rx_one(dev, lp, rfd, &frames))
- break; /* out of memory */
- rfd->cmd = CMD_EOL;
- lp->rx_tail->cmd = 0;
- lp->rx_tail = rfd;
- lp->scb.pa_rfd = rfd->pa_next;
- barrier();
- }
-
- return frames;
-}
-
-static void
-i596_cleanup_cmd(struct net_device *dev) {
- struct i596_private *lp;
- struct i596_cmd *cmd;
-
- lp = netdev_priv(dev);
- while (lp->cmd_head) {
- cmd = lp->cmd_head;
-
- lp->cmd_head = pa_to_va(lp->cmd_head->pa_next);
- lp->cmd_backlog--;
-
- switch ((cmd->command) & 0x7) {
- case CmdTx: {
- struct tx_cmd *tx_cmd = (struct tx_cmd *) cmd;
- struct i596_tbd * tx_cmd_tbd;
- tx_cmd_tbd = pa_to_va(tx_cmd->pa_tbd);
-
- dev_kfree_skb_any(tx_cmd_tbd->skb);
-
- dev->stats.tx_errors++;
- dev->stats.tx_aborted_errors++;
-
- cmd->pa_next = I596_NULL;
- kfree((unsigned char *)tx_cmd);
- netif_wake_queue(dev);
- break;
- }
- case CmdMulticastList: {
- // unsigned short count = *((unsigned short *) (ptr + 1));
-
- cmd->pa_next = I596_NULL;
- kfree((unsigned char *)cmd);
- break;
- }
- default: {
- cmd->pa_next = I596_NULL;
- break;
- }
- }
- barrier();
- }
-
- if (lp->scb.command && i596_timeout(dev, "i596_cleanup_cmd", 100))
- ;
-
- lp->scb.pa_cmd = va_to_pa(lp->cmd_head);
-}
-
-static void i596_reset(struct net_device *dev, struct i596_private *lp, int ioaddr) {
-
- if (lp->scb.command && i596_timeout(dev, "i596_reset", 100))
- ;
-
- netif_stop_queue(dev);
-
- lp->scb.command = CUC_ABORT | RX_ABORT;
- CA();
- barrier();
-
- /* wait for shutdown */
- if (lp->scb.command && i596_timeout(dev, "i596_reset(2)", 400))
- ;
-
- i596_cleanup_cmd(dev);
- i596_rx(dev);
-
- netif_start_queue(dev);
- /*dev_kfree_skb(skb, FREE_WRITE);*/
- init_i596(dev);
-}
-
-static void i596_add_cmd(struct net_device *dev, struct i596_cmd *cmd) {
- struct i596_private *lp = netdev_priv(dev);
- int ioaddr = dev->base_addr;
- unsigned long flags;
-
- cmd->status = 0;
- cmd->command |= (CMD_EOL | CMD_INTR);
- cmd->pa_next = I596_NULL;
-
- spin_lock_irqsave(&lp->cmd_lock, flags);
-
- if (lp->cmd_head) {
- lp->cmd_tail->pa_next = va_to_pa(cmd);
- } else {
- lp->cmd_head = cmd;
- if (lp->scb.command && i596_timeout(dev, "i596_add_cmd", 100))
- ;
- lp->scb.pa_cmd = va_to_pa(cmd);
- lp->scb.command = CUC_START;
- CA();
- }
- lp->cmd_tail = cmd;
- lp->cmd_backlog++;
-
- lp->cmd_head = pa_to_va(lp->scb.pa_cmd);
- spin_unlock_irqrestore(&lp->cmd_lock, flags);
-
- if (lp->cmd_backlog > 16) {
- int tickssofar = jiffies - lp->last_cmd;
- if (tickssofar < HZ/4)
- return;
-
- printk(KERN_WARNING "%s: command unit timed out, status resetting.\n", dev->name);
- i596_reset(dev, lp, ioaddr);
- }
-}
-
-static int i596_open(struct net_device *dev)
-{
- int i;
-
- i = request_irq(dev->irq, i596_interrupt, IRQF_SHARED, dev->name, dev);
- if (i) {
- printk(KERN_ERR "%s: IRQ %d not free\n", dev->name, dev->irq);
- return i;
- }
-
- if ((i = init_rx_bufs(dev, RX_RING_SIZE)) < RX_RING_SIZE)
- printk(KERN_ERR "%s: only able to allocate %d receive buffers\n", dev->name, i);
-
- if (i < 4) {
- free_irq(dev->irq, dev);
- return -EAGAIN;
- }
- netif_start_queue(dev);
- init_i596(dev);
- return 0; /* Always succeed */
-}
-
-static netdev_tx_t i596_start_xmit (struct sk_buff *skb, struct net_device *dev) {
- struct tx_cmd *tx_cmd;
- short length;
-
- length = skb->len;
-
- if (length < ETH_ZLEN) {
- if (skb_padto(skb, ETH_ZLEN))
- return NETDEV_TX_OK;
- length = ETH_ZLEN;
- }
-
- tx_cmd = kmalloc((sizeof (struct tx_cmd) + sizeof (struct i596_tbd)), GFP_ATOMIC);
- if (tx_cmd == NULL) {
- printk(KERN_WARNING "%s: i596_xmit Memory squeeze, dropping packet.\n", dev->name);
- dev->stats.tx_dropped++;
- dev_kfree_skb (skb);
- } else {
- struct i596_tbd *tx_cmd_tbd;
- tx_cmd_tbd = (struct i596_tbd *) (tx_cmd + 1);
- tx_cmd->pa_tbd = va_to_pa (tx_cmd_tbd);
- tx_cmd_tbd->pa_next = I596_NULL;
-
- tx_cmd->cmd.command = (CMD_FLEX | CmdTx);
-
- tx_cmd->pad = 0;
- tx_cmd->size = 0;
- tx_cmd_tbd->pad = 0;
- tx_cmd_tbd->size = (EOF | length);
-
- tx_cmd_tbd->pa_data = va_to_pa (skb->data);
- tx_cmd_tbd->skb = skb;
-
- if (i596_debug & LOG_SRCDST)
- print_eth (skb->data);
-
- i596_add_cmd (dev, (struct i596_cmd *) tx_cmd);
-
- dev->stats.tx_packets++;
- }
-
- return NETDEV_TX_OK;
-}
-
-static void
-i596_tx_timeout (struct net_device *dev) {
- struct i596_private *lp = netdev_priv(dev);
- int ioaddr = dev->base_addr;
-
- /* Transmitter timeout, serious problems. */
- printk(KERN_WARNING "%s: transmit timed out, status resetting.\n", dev->name);
- dev->stats.tx_errors++;
-
- /* Try to restart the adaptor */
- if (lp->last_restart == dev->stats.tx_packets) {
- printk ("Resetting board.\n");
-
- /* Shutdown and restart */
- i596_reset (dev, lp, ioaddr);
- } else {
- /* Issue a channel attention signal */
- printk ("Kicking board.\n");
- lp->scb.command = (CUC_START | RX_START);
- CA();
- lp->last_restart = dev->stats.tx_packets;
- }
- netif_wake_queue(dev);
-}
-
-static void print_eth(char *add)
-{
- int i;
-
- printk ("Dest ");
- for (i = 0; i < 6; i++)
- printk(" %2.2X", (unsigned char) add[i]);
- printk ("\n");
-
- printk ("Source");
- for (i = 0; i < 6; i++)
- printk(" %2.2X", (unsigned char) add[i+6]);
- printk ("\n");
-
- printk ("type %2.2X%2.2X\n",
- (unsigned char) add[12], (unsigned char) add[13]);
-}
-
-static const struct net_device_ops i596_netdev_ops = {
- .ndo_open = i596_open,
- .ndo_stop = i596_close,
- .ndo_start_xmit = i596_start_xmit,
- .ndo_set_rx_mode = set_multicast_list,
- .ndo_tx_timeout = i596_tx_timeout,
- .ndo_change_mtu = eth_change_mtu,
- .ndo_set_mac_address = eth_mac_addr,
- .ndo_validate_addr = eth_validate_addr,
-};
-
-static int __init lp486e_probe(struct net_device *dev) {
- struct i596_private *lp;
- unsigned char eth_addr[6] = { 0, 0xaa, 0, 0, 0, 0 };
- unsigned char *bios;
- int i, j;
- int ret = -ENOMEM;
- static int probed;
-
- if (probed)
- return -ENODEV;
- probed++;
-
- if (!request_region(IOADDR, LP486E_TOTAL_SIZE, DRV_NAME)) {
- printk(KERN_ERR "lp486e: IO address 0x%x in use\n", IOADDR);
- return -EBUSY;
- }
-
- lp = netdev_priv(dev);
- spin_lock_init(&lp->cmd_lock);
-
- /*
- * Do we really have this thing?
- */
- if (i596_scp_setup(dev)) {
- ret = -ENODEV;
- goto err_out_kfree;
- }
-
- dev->base_addr = IOADDR;
- dev->irq = IRQ;
-
-
- /*
- * How do we find the ethernet address? I don't know.
- * One possibility is to look at the EISA configuration area
- * [0xe8000-0xe9fff]. This contains the ethernet address
- * but not at a fixed address - things depend on setup options.
- *
- * If we find no address, or the wrong address, use
- * ifconfig eth0 hw ether a1:a2:a3:a4:a5:a6
- * with the value found in the BIOS setup.
- */
- bios = bus_to_virt(0xe8000);
- for (j = 0; j < 0x2000; j++) {
- if (bios[j] == 0 && bios[j+1] == 0xaa && bios[j+2] == 0) {
- printk("%s: maybe address at BIOS 0x%x:",
- dev->name, 0xe8000+j);
- for (i = 0; i < 6; i++) {
- eth_addr[i] = bios[i+j];
- printk(" %2.2X", eth_addr[i]);
- }
- printk("\n");
- }
- }
-
- printk("%s: lp486e 82596 at %#3lx, IRQ %d,",
- dev->name, dev->base_addr, dev->irq);
- for (i = 0; i < 6; i++)
- printk(" %2.2X", dev->dev_addr[i] = eth_addr[i]);
- printk("\n");
-
- /* The LP486E-specific entries in the device structure. */
- dev->netdev_ops = &i596_netdev_ops;
- dev->watchdog_timeo = 5*HZ;
-
-#if 0
- /* selftest reports 0x320925ae - don't know what that means */
- i596_port_do(dev, PORT_SELFTEST, "selftest");
- i596_port_do(dev, PORT_DUMP, "dump");
-#endif
- return 0;
-
-err_out_kfree:
- release_region(IOADDR, LP486E_TOTAL_SIZE);
- return ret;
-}
-
-static inline void
-i596_handle_CU_completion(struct net_device *dev,
- struct i596_private *lp,
- unsigned short status,
- unsigned short *ack_cmdp) {
- struct i596_cmd *cmd;
- int frames_out = 0;
- int commands_done = 0;
- int cmd_val;
- unsigned long flags;
-
- spin_lock_irqsave(&lp->cmd_lock, flags);
- cmd = lp->cmd_head;
-
- while (lp->cmd_head && (lp->cmd_head->status & CMD_STAT_C)) {
- cmd = lp->cmd_head;
-
- lp->cmd_head = pa_to_va(lp->cmd_head->pa_next);
- lp->cmd_backlog--;
-
- commands_done++;
- cmd_val = cmd->command & 0x7;
-#if 0
- printk("finished CU %s command (%d)\n",
- CUcmdnames[cmd_val], cmd_val);
-#endif
- switch (cmd_val) {
- case CmdTx:
- {
- struct tx_cmd *tx_cmd;
- struct i596_tbd *tx_cmd_tbd;
-
- tx_cmd = (struct tx_cmd *) cmd;
- tx_cmd_tbd = pa_to_va(tx_cmd->pa_tbd);
-
- frames_out++;
- if (cmd->status & CMD_STAT_OK) {
- if (i596_debug)
- print_eth(pa_to_va(tx_cmd_tbd->pa_data));
- } else {
- dev->stats.tx_errors++;
- if (i596_debug)
- printk("transmission failure:%04x\n",
- cmd->status);
- if (cmd->status & 0x0020)
- dev->stats.collisions++;
- if (!(cmd->status & 0x0040))
- dev->stats.tx_heartbeat_errors++;
- if (cmd->status & 0x0400)
- dev->stats.tx_carrier_errors++;
- if (cmd->status & 0x0800)
- dev->stats.collisions++;
- if (cmd->status & 0x1000)
- dev->stats.tx_aborted_errors++;
- }
- dev_kfree_skb_irq(tx_cmd_tbd->skb);
-
- cmd->pa_next = I596_NULL;
- kfree((unsigned char *)tx_cmd);
- netif_wake_queue(dev);
- break;
- }
-
- case CmdMulticastList:
- cmd->pa_next = I596_NULL;
- kfree((unsigned char *)cmd);
- break;
-
- case CmdTDR:
- {
- unsigned long status = *((unsigned long *) (cmd + 1));
- if (status & 0x8000) {
- if (i596_debug)
- printk("%s: link ok.\n", dev->name);
- } else {
- if (status & 0x4000)
- printk("%s: Transceiver problem.\n",
- dev->name);
- if (status & 0x2000)
- printk("%s: Termination problem.\n",
- dev->name);
- if (status & 0x1000)
- printk("%s: Short circuit.\n",
- dev->name);
- printk("%s: Time %ld.\n",
- dev->name, status & 0x07ff);
- }
- }
- default:
- cmd->pa_next = I596_NULL;
- lp->last_cmd = jiffies;
-
- }
- barrier();
- }
-
- cmd = lp->cmd_head;
- while (cmd && (cmd != lp->cmd_tail)) {
- cmd->command &= 0x1fff;
- cmd = pa_to_va(cmd->pa_next);
- barrier();
- }
-
- if (lp->cmd_head)
- *ack_cmdp |= CUC_START;
- lp->scb.pa_cmd = va_to_pa(lp->cmd_head);
- spin_unlock_irqrestore(&lp->cmd_lock, flags);
-}
-
-static irqreturn_t
-i596_interrupt(int irq, void *dev_instance)
-{
- struct net_device *dev = dev_instance;
- struct i596_private *lp = netdev_priv(dev);
- unsigned short status, ack_cmd = 0;
- int frames_in = 0;
-
- /*
- * The 82596 examines the command, performs the required action,
- * and then clears the SCB command word.
- */
- if (lp->scb.command && i596_timeout(dev, "interrupt", 40))
- ;
-
- /*
- * The status word indicates the status of the 82596.
- * It is modified only by the 82596.
- *
- * [So, we must not clear it. I find often status 0xffff,
- * which is not one of the values allowed by the docs.]
- */
- status = lp->scb.status;
-#if 0
- if (i596_debug) {
- printk("%s: i596 interrupt, ", dev->name);
- i596_out_status(status);
- }
-#endif
- /* Impossible, but it happens - perhaps when we get
- a receive interrupt but scb.pa_rfd is I596_NULL. */
- if (status == 0xffff) {
- printk("%s: i596_interrupt: got status 0xffff\n", dev->name);
- goto out;
- }
-
- ack_cmd = (status & STAT_ACK);
-
- if (status & (STAT_CX | STAT_CNA))
- i596_handle_CU_completion(dev, lp, status, &ack_cmd);
-
- if (status & (STAT_FR | STAT_RNR)) {
- /* Restart the receive unit when it got inactive somehow */
- if ((status & STAT_RNR) && netif_running(dev))
- ack_cmd |= RX_START;
-
- if (status & STAT_FR) {
- frames_in = i596_rx(dev);
- if (!frames_in)
- printk("receive frame reported, but no frames\n");
- }
- }
-
- /* acknowledge the interrupt */
- /*
- if ((lp->scb.pa_cmd != I596_NULL) && netif_running(dev))
- ack_cmd |= CUC_START;
- */
-
- if (lp->scb.command && i596_timeout(dev, "i596 interrupt", 100))
- ;
-
- lp->scb.command = ack_cmd;
-
- CLEAR_INT();
- CA();
-
- out:
- return IRQ_HANDLED;
-}
-
-static int i596_close(struct net_device *dev) {
- struct i596_private *lp = netdev_priv(dev);
-
- netif_stop_queue(dev);
-
- if (i596_debug)
- printk("%s: Shutting down ethercard, status was %4.4x.\n",
- dev->name, lp->scb.status);
-
- lp->scb.command = (CUC_ABORT | RX_ABORT);
- CA();
-
- i596_cleanup_cmd(dev);
-
- if (lp->scb.command && i596_timeout(dev, "i596_close", 200))
- ;
-
- free_irq(dev->irq, dev);
- remove_rx_bufs(dev);
-
- return 0;
-}
-
-/*
-* Set or clear the multicast filter for this adaptor.
-*/
-
-static void set_multicast_list(struct net_device *dev) {
- struct i596_private *lp = netdev_priv(dev);
- struct i596_cmd *cmd;
-
- if (i596_debug > 1)
- printk ("%s: set multicast list %d\n",
- dev->name, netdev_mc_count(dev));
-
- if (!netdev_mc_empty(dev)) {
- struct netdev_hw_addr *ha;
- char *cp;
- cmd = kmalloc(sizeof(struct i596_cmd) + 2 +
- netdev_mc_count(dev) * 6, GFP_ATOMIC);
- if (cmd == NULL) {
- printk (KERN_ERR "%s: set_multicast Memory squeeze.\n", dev->name);
- return;
- }
- cmd->command = CmdMulticastList;
- *((unsigned short *) (cmd + 1)) = netdev_mc_count(dev) * 6;
- cp = ((char *)(cmd + 1))+2;
- netdev_for_each_mc_addr(ha, dev) {
- memcpy(cp, ha->addr, 6);
- cp += 6;
- }
- if (i596_debug & LOG_SRCDST)
- print_eth (((char *)(cmd + 1)) + 2);
- i596_add_cmd(dev, cmd);
- } else {
- if (lp->set_conf.pa_next != I596_NULL) {
- return;
- }
- if (netdev_mc_empty(dev) &&
- !(dev->flags & (IFF_PROMISC | IFF_ALLMULTI))) {
- lp->i596_config[8] &= ~0x01;
- } else {
- lp->i596_config[8] |= 0x01;
- }
-
- i596_add_cmd(dev, &lp->set_conf);
- }
-}
-
-MODULE_AUTHOR("Ard van Breemen <ard@cstmel.nl.eu.org>");
-MODULE_DESCRIPTION("Intel Panther onboard i82596 driver");
-MODULE_LICENSE("GPL");
-
-static struct net_device *dev_lp486e;
-static int full_duplex;
-static int options;
-static int io = IOADDR;
-static int irq = IRQ;
-
-module_param(debug, int, 0);
-//module_param(max_interrupt_work, int, 0);
-//module_param(reverse_probe, int, 0);
-//module_param(rx_copybreak, int, 0);
-module_param(options, int, 0);
-module_param(full_duplex, int, 0);
-
-static int __init lp486e_init_module(void) {
- int err;
- struct net_device *dev = alloc_etherdev(sizeof(struct i596_private));
- if (!dev)
- return -ENOMEM;
-
- dev->irq = irq;
- dev->base_addr = io;
- err = lp486e_probe(dev);
- if (err) {
- free_netdev(dev);
- return err;
- }
- err = register_netdev(dev);
- if (err) {
- release_region(dev->base_addr, LP486E_TOTAL_SIZE);
- free_netdev(dev);
- return err;
- }
- dev_lp486e = dev;
- full_duplex = 0;
- options = 0;
- return 0;
-}
-
-static void __exit lp486e_cleanup_module(void) {
- unregister_netdev(dev_lp486e);
- release_region(dev_lp486e->base_addr, LP486E_TOTAL_SIZE);
- free_netdev(dev_lp486e);
-}
-
-module_init(lp486e_init_module);
-module_exit(lp486e_cleanup_module);
diff --git a/drivers/net/ethernet/i825xx/ni52.c b/drivers/net/ethernet/i825xx/ni52.c
deleted file mode 100644
index 272976e1bb0..00000000000
--- a/drivers/net/ethernet/i825xx/ni52.c
+++ /dev/null
@@ -1,1346 +0,0 @@
-/*
- * net-3-driver for the NI5210 card (i82586 Ethernet chip)
- *
- * This is an extension to the Linux operating system, and is covered by the
- * same GNU General Public License that covers that work.
- *
- * Alphacode 0.82 (96/09/29) for Linux 2.0.0 (or later)
- * Copyrights (c) 1994,1995,1996 by M.Hipp (hippm@informatik.uni-tuebingen.de)
- * [feel free to mail ....]
- *
- * when using as module: (no autoprobing!)
- * run with e.g:
- * insmod ni52.o io=0x360 irq=9 memstart=0xd0000 memend=0xd4000
- *
- * CAN YOU PLEASE REPORT ME YOUR PERFORMANCE EXPERIENCES !!.
- *
- * If you find a bug, please report me:
- * The kernel panic output and any kmsg from the ni52 driver
- * the ni5210-driver-version and the linux-kernel version
- * how many shared memory (memsize) on the netcard,
- * bootprom: yes/no, base_addr, mem_start
- * maybe the ni5210-card revision and the i82586 version
- *
- * autoprobe for: base_addr: 0x300,0x280,0x360,0x320,0x340
- * mem_start: 0xd0000,0xd2000,0xc8000,0xca000,0xd4000,0xd6000,
- * 0xd8000,0xcc000,0xce000,0xda000,0xdc000
- *
- * sources:
- * skeleton.c from Donald Becker
- *
- * I have also done a look in the following sources: (mail me if you need them)
- * crynwr-packet-driver by Russ Nelson
- * Garret A. Wollman's (fourth) i82586-driver for BSD
- * (before getting an i82596 (yes 596 not 586) manual, the existing drivers
- * helped me a lot to understand this tricky chip.)
- *
- * Known Problems:
- * The internal sysbus seems to be slow. So we often lose packets because of
- * overruns while receiving from a fast remote host.
- * This can slow down TCP connections. Maybe the newer ni5210 cards are
- * better. My experience is, that if a machine sends with more than about
- * 500-600K/s the fifo/sysbus overflows.
- *
- * IMPORTANT NOTE:
- * On fast networks, it's a (very) good idea to have 16K shared memory. With
- * 8K, we can store only 4 receive frames, so it can (easily) happen that a
- * remote machine 'overruns' our system.
- *
- * Known i82586/card problems (I'm sure, there are many more!):
- * Running the NOP-mode, the i82586 sometimes seems to forget to report
- * every xmit-interrupt until we restart the CU.
- * Another MAJOR bug is, that the RU sometimes seems to ignore the EL-Bit
- * in the RBD-Struct which indicates an end of the RBD queue.
- * Instead, the RU fetches another (randomly selected and
- * usually used) RBD and begins to fill it. (Maybe, this happens only if
- * the last buffer from the previous RFD fits exact into the queue and
- * the next RFD can't fetch an initial RBD. Anyone knows more? )
- *
- * results from ftp performance tests with Linux 1.2.5
- * send and receive about 350-400 KByte/s (peak up to 460 kbytes/s)
- * sending in NOP-mode: peak performance up to 530K/s (but better don't
- * run this mode)
- */
-
-/*
- * 29.Sept.96: virt_to_bus changes for new memory scheme
- * 19.Feb.96: more Mcast changes, module support (MH)
- *
- * 18.Nov.95: Mcast changes (AC).
- *
- * 23.April.95: fixed(?) receiving problems by configuring a RFD more
- * than the number of RBD's. Can maybe cause other problems.
- * 18.April.95: Added MODULE support (MH)
- * 17.April.95: MC related changes in init586() and set_multicast_list().
- * removed use of 'jiffies' in init586() (MH)
- *
- * 19.Sep.94: Added Multicast support (not tested yet) (MH)
- *
- * 18.Sep.94: Workaround for 'EL-Bug'. Removed flexible RBD-handling.
- * Now, every RFD has exact one RBD. (MH)
- *
- * 14.Sep.94: added promiscuous mode, a few cleanups (MH)
- *
- * 19.Aug.94: changed request_irq() parameter (MH)
- *
- * 20.July.94: removed cleanup bugs, removed a 16K-mem-probe-bug (MH)
- *
- * 19.July.94: lotsa cleanups .. (MH)
- *
- * 17.July.94: some patches ... verified to run with 1.1.29 (MH)
- *
- * 4.July.94: patches for Linux 1.1.24 (MH)
- *
- * 26.March.94: patches for Linux 1.0 and iomem-auto-probe (MH)
- *
- * 30.Sep.93: Added nop-chain .. driver now runs with only one Xmit-Buff,
- * too (MH)
- *
- * < 30.Sep.93: first versions
- */
-
-static int debuglevel; /* debug-printk 0: off 1: a few 2: more */
-static int automatic_resume; /* experimental .. better should be zero */
-static int rfdadd; /* rfdadd=1 may be better for 8K MEM cards */
-static int fifo = 0x8; /* don't change */
-
-#include <linux/module.h>
-#include <linux/kernel.h>
-#include <linux/string.h>
-#include <linux/errno.h>
-#include <linux/ioport.h>
-#include <linux/interrupt.h>
-#include <linux/delay.h>
-#include <linux/init.h>
-#include <linux/bitops.h>
-#include <asm/io.h>
-
-#include <linux/netdevice.h>
-#include <linux/etherdevice.h>
-#include <linux/skbuff.h>
-
-#include "ni52.h"
-
-#define DRV_NAME "ni52"
-
-#define DEBUG /* debug on */
-#define SYSBUSVAL 1 /* 8 Bit */
-
-#define ni_attn586() { outb(0, dev->base_addr + NI52_ATTENTION); }
-#define ni_reset586() { outb(0, dev->base_addr + NI52_RESET); }
-#define ni_disint() { outb(0, dev->base_addr + NI52_INTDIS); }
-#define ni_enaint() { outb(0, dev->base_addr + NI52_INTENA); }
-
-#define make32(ptr16) ((void __iomem *)(p->memtop + (short) (ptr16)))
-#define make24(ptr32) ((char __iomem *)(ptr32)) - p->base
-#define make16(ptr32) ((unsigned short) ((char __iomem *)(ptr32)\
- - p->memtop))
-
-/******************* how to calculate the buffers *****************************
-
- * IMPORTANT NOTE: if you configure only one NUM_XMIT_BUFFS, the driver works
- * --------------- in a different (more stable?) mode. Only in this mode it's
- * possible to configure the driver with 'NO_NOPCOMMANDS'
-
-sizeof(scp)=12; sizeof(scb)=16; sizeof(iscp)=8;
-sizeof(scp)+sizeof(iscp)+sizeof(scb) = 36 = INIT
-sizeof(rfd) = 24; sizeof(rbd) = 12;
-sizeof(tbd) = 8; sizeof(transmit_cmd) = 16;
-sizeof(nop_cmd) = 8;
-
- * if you don't know the driver, better do not change these values: */
-
-#define RECV_BUFF_SIZE 1524 /* slightly oversized */
-#define XMIT_BUFF_SIZE 1524 /* slightly oversized */
-#define NUM_XMIT_BUFFS 1 /* config for both, 8K and 16K shmem */
-#define NUM_RECV_BUFFS_8 4 /* config for 8K shared mem */
-#define NUM_RECV_BUFFS_16 9 /* config for 16K shared mem */
-#define NO_NOPCOMMANDS /* only possible with NUM_XMIT_BUFFS=1 */
-
-/**************************************************************************/
-
-
-#define NI52_TOTAL_SIZE 16
-#define NI52_ADDR0 0x02
-#define NI52_ADDR1 0x07
-#define NI52_ADDR2 0x01
-
-static int ni52_probe1(struct net_device *dev, int ioaddr);
-static irqreturn_t ni52_interrupt(int irq, void *dev_id);
-static int ni52_open(struct net_device *dev);
-static int ni52_close(struct net_device *dev);
-static netdev_tx_t ni52_send_packet(struct sk_buff *, struct net_device *);
-static struct net_device_stats *ni52_get_stats(struct net_device *dev);
-static void set_multicast_list(struct net_device *dev);
-static void ni52_timeout(struct net_device *dev);
-
-/* helper-functions */
-static int init586(struct net_device *dev);
-static int check586(struct net_device *dev, unsigned size);
-static void alloc586(struct net_device *dev);
-static void startrecv586(struct net_device *dev);
-static void __iomem *alloc_rfa(struct net_device *dev, void __iomem *ptr);
-static void ni52_rcv_int(struct net_device *dev);
-static void ni52_xmt_int(struct net_device *dev);
-static void ni52_rnr_int(struct net_device *dev);
-
-struct priv {
- char __iomem *base;
- char __iomem *mapped;
- char __iomem *memtop;
- spinlock_t spinlock;
- int reset;
- struct rfd_struct __iomem *rfd_last, *rfd_top, *rfd_first;
- struct scp_struct __iomem *scp;
- struct iscp_struct __iomem *iscp;
- struct scb_struct __iomem *scb;
- struct tbd_struct __iomem *xmit_buffs[NUM_XMIT_BUFFS];
-#if (NUM_XMIT_BUFFS == 1)
- struct transmit_cmd_struct __iomem *xmit_cmds[2];
- struct nop_cmd_struct __iomem *nop_cmds[2];
-#else
- struct transmit_cmd_struct __iomem *xmit_cmds[NUM_XMIT_BUFFS];
- struct nop_cmd_struct __iomem *nop_cmds[NUM_XMIT_BUFFS];
-#endif
- int nop_point, num_recv_buffs;
- char __iomem *xmit_cbuffs[NUM_XMIT_BUFFS];
- int xmit_count, xmit_last;
-};
-
-/* wait for command with timeout: */
-static void wait_for_scb_cmd(struct net_device *dev)
-{
- struct priv *p = netdev_priv(dev);
- int i;
- for (i = 0; i < 16384; i++) {
- if (readb(&p->scb->cmd_cuc) == 0)
- break;
- udelay(4);
- if (i == 16383) {
- printk(KERN_ERR "%s: scb_cmd timed out: %04x,%04x .. disabling i82586!!\n",
- dev->name, readb(&p->scb->cmd_cuc), readb(&p->scb->cus));
- if (!p->reset) {
- p->reset = 1;
- ni_reset586();
- }
- }
- }
-}
-
-static void wait_for_scb_cmd_ruc(struct net_device *dev)
-{
- struct priv *p = netdev_priv(dev);
- int i;
- for (i = 0; i < 16384; i++) {
- if (readb(&p->scb->cmd_ruc) == 0)
- break;
- udelay(4);
- if (i == 16383) {
- printk(KERN_ERR "%s: scb_cmd (ruc) timed out: %04x,%04x .. disabling i82586!!\n",
- dev->name, readb(&p->scb->cmd_ruc),
- readb(&p->scb->rus));
- if (!p->reset) {
- p->reset = 1;
- ni_reset586();
- }
- }
- }
-}
-
-static void wait_for_stat_compl(void __iomem *p)
-{
- struct nop_cmd_struct __iomem *addr = p;
- int i;
- for (i = 0; i < 32767; i++) {
- if (readw(&((addr)->cmd_status)) & STAT_COMPL)
- break;
- udelay(32);
- }
-}
-
-/**********************************************
- * close device
- */
-static int ni52_close(struct net_device *dev)
-{
- free_irq(dev->irq, dev);
- ni_reset586(); /* the hard way to stop the receiver */
- netif_stop_queue(dev);
- return 0;
-}
-
-/**********************************************
- * open device
- */
-static int ni52_open(struct net_device *dev)
-{
- int ret;
-
- ni_disint();
- alloc586(dev);
- init586(dev);
- startrecv586(dev);
- ni_enaint();
-
- ret = request_irq(dev->irq, ni52_interrupt, 0, dev->name, dev);
- if (ret) {
- ni_reset586();
- return ret;
- }
- netif_start_queue(dev);
- return 0; /* most done by init */
-}
-
-static int check_iscp(struct net_device *dev, void __iomem *addr)
-{
- struct iscp_struct __iomem *iscp = addr;
- struct priv *p = netdev_priv(dev);
- memset_io(iscp, 0, sizeof(struct iscp_struct));
-
- writel(make24(iscp), &p->scp->iscp);
- writeb(1, &iscp->busy);
-
- ni_reset586();
- ni_attn586();
- mdelay(32); /* wait a while... */
- /* i82586 clears 'busy' after successful init */
- if (readb(&iscp->busy))
- return 0;
- return 1;
-}
-
-/**********************************************
- * Check to see if there's an 82586 out there.
- */
-static int check586(struct net_device *dev, unsigned size)
-{
- struct priv *p = netdev_priv(dev);
- int i;
-
- p->mapped = ioremap(dev->mem_start, size);
- if (!p->mapped)
- return 0;
-
- p->base = p->mapped + size - 0x01000000;
- p->memtop = p->mapped + size;
- p->scp = (struct scp_struct __iomem *)(p->base + SCP_DEFAULT_ADDRESS);
- p->scb = (struct scb_struct __iomem *) p->mapped;
- p->iscp = (struct iscp_struct __iomem *)p->scp - 1;
- memset_io(p->scp, 0, sizeof(struct scp_struct));
- for (i = 0; i < sizeof(struct scp_struct); i++)
- /* memory was writeable? */
- if (readb((char __iomem *)p->scp + i))
- goto Enodev;
- writeb(SYSBUSVAL, &p->scp->sysbus); /* 1 = 8Bit-Bus, 0 = 16 Bit */
- if (readb(&p->scp->sysbus) != SYSBUSVAL)
- goto Enodev;
-
- if (!check_iscp(dev, p->mapped))
- goto Enodev;
- if (!check_iscp(dev, p->iscp))
- goto Enodev;
- return 1;
-Enodev:
- iounmap(p->mapped);
- return 0;
-}
-
-/******************************************************************
- * set iscp at the right place, called by ni52_probe1 and open586.
- */
-static void alloc586(struct net_device *dev)
-{
- struct priv *p = netdev_priv(dev);
-
- ni_reset586();
- mdelay(32);
-
- memset_io(p->iscp, 0, sizeof(struct iscp_struct));
- memset_io(p->scp , 0, sizeof(struct scp_struct));
-
- writel(make24(p->iscp), &p->scp->iscp);
- writeb(SYSBUSVAL, &p->scp->sysbus);
- writew(make16(p->scb), &p->iscp->scb_offset);
-
- writeb(1, &p->iscp->busy);
- ni_reset586();
- ni_attn586();
-
- mdelay(32);
-
- if (readb(&p->iscp->busy))
- printk(KERN_ERR "%s: Init-Problems (alloc).\n", dev->name);
-
- p->reset = 0;
-
- memset_io(p->scb, 0, sizeof(struct scb_struct));
-}
-
-/* set: io,irq,memstart,memend or set it when calling insmod */
-static int irq = 9;
-static int io = 0x300;
-static long memstart; /* e.g 0xd0000 */
-static long memend; /* e.g 0xd4000 */
-
-/**********************************************
- * probe the ni5210-card
- */
-struct net_device * __init ni52_probe(int unit)
-{
- struct net_device *dev = alloc_etherdev(sizeof(struct priv));
- static const int ports[] = {0x300, 0x280, 0x360, 0x320, 0x340, 0};
- const int *port;
- struct priv *p;
- int err = 0;
-
- if (!dev)
- return ERR_PTR(-ENOMEM);
-
- p = netdev_priv(dev);
-
- if (unit >= 0) {
- sprintf(dev->name, "eth%d", unit);
- netdev_boot_setup_check(dev);
- io = dev->base_addr;
- irq = dev->irq;
- memstart = dev->mem_start;
- memend = dev->mem_end;
- }
-
- if (io > 0x1ff) { /* Check a single specified location. */
- err = ni52_probe1(dev, io);
- } else if (io > 0) { /* Don't probe at all. */
- err = -ENXIO;
- } else {
- for (port = ports; *port && ni52_probe1(dev, *port) ; port++)
- ;
- if (*port)
- goto got_it;
-#ifdef FULL_IO_PROBE
- for (io = 0x200; io < 0x400 && ni52_probe1(dev, io); io += 8)
- ;
- if (io < 0x400)
- goto got_it;
-#endif
- err = -ENODEV;
- }
- if (err)
- goto out;
-got_it:
- err = register_netdev(dev);
- if (err)
- goto out1;
- return dev;
-out1:
- iounmap(p->mapped);
- release_region(dev->base_addr, NI52_TOTAL_SIZE);
-out:
- free_netdev(dev);
- return ERR_PTR(err);
-}
-
-static const struct net_device_ops ni52_netdev_ops = {
- .ndo_open = ni52_open,
- .ndo_stop = ni52_close,
- .ndo_get_stats = ni52_get_stats,
- .ndo_tx_timeout = ni52_timeout,
- .ndo_start_xmit = ni52_send_packet,
- .ndo_set_rx_mode = set_multicast_list,
- .ndo_change_mtu = eth_change_mtu,
- .ndo_set_mac_address = eth_mac_addr,
- .ndo_validate_addr = eth_validate_addr,
-};
-
-static int __init ni52_probe1(struct net_device *dev, int ioaddr)
-{
- int i, size, retval;
- struct priv *priv = netdev_priv(dev);
-
- dev->base_addr = ioaddr;
- dev->irq = irq;
- dev->mem_start = memstart;
- dev->mem_end = memend;
-
- spin_lock_init(&priv->spinlock);
-
- if (!request_region(ioaddr, NI52_TOTAL_SIZE, DRV_NAME))
- return -EBUSY;
-
- if (!(inb(ioaddr+NI52_MAGIC1) == NI52_MAGICVAL1) ||
- !(inb(ioaddr+NI52_MAGIC2) == NI52_MAGICVAL2)) {
- retval = -ENODEV;
- goto out;
- }
-
- for (i = 0; i < ETH_ALEN; i++)
- dev->dev_addr[i] = inb(dev->base_addr+i);
-
- if (dev->dev_addr[0] != NI52_ADDR0 || dev->dev_addr[1] != NI52_ADDR1 ||
- dev->dev_addr[2] != NI52_ADDR2) {
- retval = -ENODEV;
- goto out;
- }
-
- printk(KERN_INFO "%s: NI5210 found at %#3lx, ",
- dev->name, dev->base_addr);
-
- /*
- * check (or search) IO-Memory, 8K and 16K
- */
-#ifdef MODULE
- size = dev->mem_end - dev->mem_start;
- if (size != 0x2000 && size != 0x4000) {
- printk("\n");
- printk(KERN_ERR "%s: Invalid memory size %d. Allowed is 0x2000 or 0x4000 bytes.\n", dev->name, size);
- retval = -ENODEV;
- goto out;
- }
- if (!check586(dev, size)) {
- printk(KERN_ERR "?memcheck, Can't find memory at 0x%lx with size %d!\n", dev->mem_start, size);
- retval = -ENODEV;
- goto out;
- }
-#else
- if (dev->mem_start != 0) {
- /* no auto-mem-probe */
- size = 0x4000; /* check for 16K mem */
- if (!check586(dev, size)) {
- size = 0x2000; /* check for 8K mem */
- if (!check586(dev, size)) {
- printk(KERN_ERR "?memprobe, Can't find memory at 0x%lx!\n", dev->mem_start);
- retval = -ENODEV;
- goto out;
- }
- }
- } else {
- static const unsigned long memaddrs[] = {
- 0xc8000, 0xca000, 0xcc000, 0xce000, 0xd0000, 0xd2000,
- 0xd4000, 0xd6000, 0xd8000, 0xda000, 0xdc000, 0
- };
- for (i = 0;; i++) {
- if (!memaddrs[i]) {
- printk(KERN_ERR "?memprobe, Can't find io-memory!\n");
- retval = -ENODEV;
- goto out;
- }
- dev->mem_start = memaddrs[i];
- size = 0x2000; /* check for 8K mem */
- if (check586(dev, size))
- /* 8K-check */
- break;
- size = 0x4000; /* check for 16K mem */
- if (check586(dev, size))
- /* 16K-check */
- break;
- }
- }
- /* set mem_end showed by 'ifconfig' */
- dev->mem_end = dev->mem_start + size;
-#endif
-
- alloc586(dev);
-
- /* set number of receive-buffs according to memsize */
- if (size == 0x2000)
- priv->num_recv_buffs = NUM_RECV_BUFFS_8;
- else
- priv->num_recv_buffs = NUM_RECV_BUFFS_16;
-
- printk(KERN_DEBUG "Memaddr: 0x%lx, Memsize: %d, ",
- dev->mem_start, size);
-
- if (dev->irq < 2) {
- unsigned long irq_mask;
-
- irq_mask = probe_irq_on();
- ni_reset586();
- ni_attn586();
-
- mdelay(20);
- dev->irq = probe_irq_off(irq_mask);
- if (!dev->irq) {
- printk("?autoirq, Failed to detect IRQ line!\n");
- retval = -EAGAIN;
- iounmap(priv->mapped);
- goto out;
- }
- printk("IRQ %d (autodetected).\n", dev->irq);
- } else {
- if (dev->irq == 2)
- dev->irq = 9;
- printk("IRQ %d (assigned and not checked!).\n", dev->irq);
- }
-
- dev->netdev_ops = &ni52_netdev_ops;
- dev->watchdog_timeo = HZ/20;
-
- return 0;
-out:
- release_region(ioaddr, NI52_TOTAL_SIZE);
- return retval;
-}
-
-/**********************************************
- * init the chip (ni52-interrupt should be disabled?!)
- * needs a correct 'allocated' memory
- */
-
-static int init586(struct net_device *dev)
-{
- void __iomem *ptr;
- int i, result = 0;
- struct priv *p = netdev_priv(dev);
- struct configure_cmd_struct __iomem *cfg_cmd;
- struct iasetup_cmd_struct __iomem *ias_cmd;
- struct tdr_cmd_struct __iomem *tdr_cmd;
- struct mcsetup_cmd_struct __iomem *mc_cmd;
- struct netdev_hw_addr *ha;
- int num_addrs = netdev_mc_count(dev);
-
- ptr = p->scb + 1;
-
- cfg_cmd = ptr; /* configure-command */
- writew(0, &cfg_cmd->cmd_status);
- writew(CMD_CONFIGURE | CMD_LAST, &cfg_cmd->cmd_cmd);
- writew(0xFFFF, &cfg_cmd->cmd_link);
-
- /* number of cfg bytes */
- writeb(0x0a, &cfg_cmd->byte_cnt);
- /* fifo-limit (8=tx:32/rx:64) */
- writeb(fifo, &cfg_cmd->fifo);
- /* hold or discard bad recv frames (bit 7) */
- writeb(0x40, &cfg_cmd->sav_bf);
- /* addr_len |!src_insert |pre-len |loopback */
- writeb(0x2e, &cfg_cmd->adr_len);
- writeb(0x00, &cfg_cmd->priority);
- writeb(0x60, &cfg_cmd->ifs);
- writeb(0x00, &cfg_cmd->time_low);
- writeb(0xf2, &cfg_cmd->time_high);
- writeb(0x00, &cfg_cmd->promisc);
- if (dev->flags & IFF_ALLMULTI) {
- int len = ((char __iomem *)p->iscp - (char __iomem *)ptr - 8) / 6;
- if (num_addrs > len) {
- printk(KERN_ERR "%s: switching to promisc. mode\n",
- dev->name);
- writeb(0x01, &cfg_cmd->promisc);
- }
- }
- if (dev->flags & IFF_PROMISC)
- writeb(0x01, &cfg_cmd->promisc);
- writeb(0x00, &cfg_cmd->carr_coll);
- writew(make16(cfg_cmd), &p->scb->cbl_offset);
- writeb(0, &p->scb->cmd_ruc);
-
- writeb(CUC_START, &p->scb->cmd_cuc); /* cmd.-unit start */
- ni_attn586();
-
- wait_for_stat_compl(cfg_cmd);
-
- if ((readw(&cfg_cmd->cmd_status) & (STAT_OK|STAT_COMPL)) !=
- (STAT_COMPL|STAT_OK)) {
- printk(KERN_ERR "%s: configure command failed: %x\n",
- dev->name, readw(&cfg_cmd->cmd_status));
- return 1;
- }
-
- /*
- * individual address setup
- */
-
- ias_cmd = ptr;
-
- writew(0, &ias_cmd->cmd_status);
- writew(CMD_IASETUP | CMD_LAST, &ias_cmd->cmd_cmd);
- writew(0xffff, &ias_cmd->cmd_link);
-
- memcpy_toio(&ias_cmd->iaddr, (char *)dev->dev_addr, ETH_ALEN);
-
- writew(make16(ias_cmd), &p->scb->cbl_offset);
-
- writeb(CUC_START, &p->scb->cmd_cuc); /* cmd.-unit start */
- ni_attn586();
-
- wait_for_stat_compl(ias_cmd);
-
- if ((readw(&ias_cmd->cmd_status) & (STAT_OK|STAT_COMPL)) !=
- (STAT_OK|STAT_COMPL)) {
- printk(KERN_ERR "%s (ni52): individual address setup command failed: %04x\n", dev->name, readw(&ias_cmd->cmd_status));
- return 1;
- }
-
- /*
- * TDR, wire check .. e.g. no resistor e.t.c
- */
-
- tdr_cmd = ptr;
-
- writew(0, &tdr_cmd->cmd_status);
- writew(CMD_TDR | CMD_LAST, &tdr_cmd->cmd_cmd);
- writew(0xffff, &tdr_cmd->cmd_link);
- writew(0, &tdr_cmd->status);
-
- writew(make16(tdr_cmd), &p->scb->cbl_offset);
- writeb(CUC_START, &p->scb->cmd_cuc); /* cmd.-unit start */
- ni_attn586();
-
- wait_for_stat_compl(tdr_cmd);
-
- if (!(readw(&tdr_cmd->cmd_status) & STAT_COMPL))
- printk(KERN_ERR "%s: Problems while running the TDR.\n",
- dev->name);
- else {
- udelay(16);
- result = readw(&tdr_cmd->status);
- writeb(readb(&p->scb->cus) & STAT_MASK, &p->scb->cmd_cuc);
- ni_attn586(); /* ack the interrupts */
-
- if (result & TDR_LNK_OK)
- ;
- else if (result & TDR_XCVR_PRB)
- printk(KERN_ERR "%s: TDR: Transceiver problem. Check the cable(s)!\n",
- dev->name);
- else if (result & TDR_ET_OPN)
- printk(KERN_ERR "%s: TDR: No correct termination %d clocks away.\n",
- dev->name, result & TDR_TIMEMASK);
- else if (result & TDR_ET_SRT) {
- /* time == 0 -> strange :-) */
- if (result & TDR_TIMEMASK)
- printk(KERN_ERR "%s: TDR: Detected a short circuit %d clocks away.\n",
- dev->name, result & TDR_TIMEMASK);
- } else
- printk(KERN_ERR "%s: TDR: Unknown status %04x\n",
- dev->name, result);
- }
-
- /*
- * Multicast setup
- */
- if (num_addrs && !(dev->flags & IFF_PROMISC)) {
- mc_cmd = ptr;
- writew(0, &mc_cmd->cmd_status);
- writew(CMD_MCSETUP | CMD_LAST, &mc_cmd->cmd_cmd);
- writew(0xffff, &mc_cmd->cmd_link);
- writew(num_addrs * 6, &mc_cmd->mc_cnt);
-
- i = 0;
- netdev_for_each_mc_addr(ha, dev)
- memcpy_toio(mc_cmd->mc_list[i++], ha->addr, 6);
-
- writew(make16(mc_cmd), &p->scb->cbl_offset);
- writeb(CUC_START, &p->scb->cmd_cuc);
- ni_attn586();
-
- wait_for_stat_compl(mc_cmd);
-
- if ((readw(&mc_cmd->cmd_status) & (STAT_COMPL|STAT_OK))
- != (STAT_COMPL|STAT_OK))
- printk(KERN_ERR "%s: Can't apply multicast-address-list.\n", dev->name);
- }
-
- /*
- * alloc nop/xmit-cmds
- */
-#if (NUM_XMIT_BUFFS == 1)
- for (i = 0; i < 2; i++) {
- p->nop_cmds[i] = ptr;
- writew(CMD_NOP, &p->nop_cmds[i]->cmd_cmd);
- writew(0, &p->nop_cmds[i]->cmd_status);
- writew(make16(p->nop_cmds[i]), &p->nop_cmds[i]->cmd_link);
- ptr = ptr + sizeof(struct nop_cmd_struct);
- }
-#else
- for (i = 0; i < NUM_XMIT_BUFFS; i++) {
- p->nop_cmds[i] = ptr;
- writew(CMD_NOP, &p->nop_cmds[i]->cmd_cmd);
- writew(0, &p->nop_cmds[i]->cmd_status);
- writew(make16(p->nop_cmds[i]), &p->nop_cmds[i]->cmd_link);
- ptr = ptr + sizeof(struct nop_cmd_struct);
- }
-#endif
-
- ptr = alloc_rfa(dev, ptr); /* init receive-frame-area */
-
- /*
- * alloc xmit-buffs / init xmit_cmds
- */
- for (i = 0; i < NUM_XMIT_BUFFS; i++) {
- /* Transmit cmd/buff 0 */
- p->xmit_cmds[i] = ptr;
- ptr = ptr + sizeof(struct transmit_cmd_struct);
- p->xmit_cbuffs[i] = ptr; /* char-buffs */
- ptr = ptr + XMIT_BUFF_SIZE;
- p->xmit_buffs[i] = ptr; /* TBD */
- ptr = ptr + sizeof(struct tbd_struct);
- if ((void __iomem *)ptr > (void __iomem *)p->iscp) {
- printk(KERN_ERR "%s: not enough shared-mem for your configuration!\n",
- dev->name);
- return 1;
- }
- memset_io(p->xmit_cmds[i], 0,
- sizeof(struct transmit_cmd_struct));
- memset_io(p->xmit_buffs[i], 0,
- sizeof(struct tbd_struct));
- writew(make16(p->nop_cmds[(i+1)%NUM_XMIT_BUFFS]),
- &p->xmit_cmds[i]->cmd_link);
- writew(STAT_COMPL, &p->xmit_cmds[i]->cmd_status);
- writew(CMD_XMIT|CMD_INT, &p->xmit_cmds[i]->cmd_cmd);
- writew(make16(p->xmit_buffs[i]), &p->xmit_cmds[i]->tbd_offset);
- writew(0xffff, &p->xmit_buffs[i]->next);
- writel(make24(p->xmit_cbuffs[i]), &p->xmit_buffs[i]->buffer);
- }
-
- p->xmit_count = 0;
- p->xmit_last = 0;
-#ifndef NO_NOPCOMMANDS
- p->nop_point = 0;
-#endif
-
- /*
- * 'start transmitter'
- */
-#ifndef NO_NOPCOMMANDS
- writew(make16(p->nop_cmds[0]), &p->scb->cbl_offset);
- writeb(CUC_START, &p->scb->cmd_cuc);
- ni_attn586();
- wait_for_scb_cmd(dev);
-#else
- writew(make16(p->xmit_cmds[0]), &p->xmit_cmds[0]->cmd_link);
- writew(CMD_XMIT | CMD_SUSPEND | CMD_INT, &p->xmit_cmds[0]->cmd_cmd);
-#endif
-
- /*
- * ack. interrupts
- */
- writeb(readb(&p->scb->cus) & STAT_MASK, &p->scb->cmd_cuc);
- ni_attn586();
- udelay(16);
-
- ni_enaint();
-
- return 0;
-}
-
-/******************************************************
- * This is a helper routine for ni52_rnr_int() and init586().
- * It sets up the Receive Frame Area (RFA).
- */
-
-static void __iomem *alloc_rfa(struct net_device *dev, void __iomem *ptr)
-{
- struct rfd_struct __iomem *rfd = ptr;
- struct rbd_struct __iomem *rbd;
- int i;
- struct priv *p = netdev_priv(dev);
-
- memset_io(rfd, 0,
- sizeof(struct rfd_struct) * (p->num_recv_buffs + rfdadd));
- p->rfd_first = rfd;
-
- for (i = 0; i < (p->num_recv_buffs + rfdadd); i++) {
- writew(make16(rfd + (i+1) % (p->num_recv_buffs+rfdadd)),
- &rfd[i].next);
- writew(0xffff, &rfd[i].rbd_offset);
- }
- /* RU suspend */
- writeb(RFD_SUSP, &rfd[p->num_recv_buffs-1+rfdadd].last);
-
- ptr = rfd + (p->num_recv_buffs + rfdadd);
-
- rbd = ptr;
- ptr = rbd + p->num_recv_buffs;
-
- /* clr descriptors */
- memset_io(rbd, 0, sizeof(struct rbd_struct) * (p->num_recv_buffs));
-
- for (i = 0; i < p->num_recv_buffs; i++) {
- writew(make16(rbd + (i+1) % p->num_recv_buffs), &rbd[i].next);
- writew(RECV_BUFF_SIZE, &rbd[i].size);
- writel(make24(ptr), &rbd[i].buffer);
- ptr = ptr + RECV_BUFF_SIZE;
- }
- p->rfd_top = p->rfd_first;
- p->rfd_last = p->rfd_first + (p->num_recv_buffs - 1 + rfdadd);
-
- writew(make16(p->rfd_first), &p->scb->rfa_offset);
- writew(make16(rbd), &p->rfd_first->rbd_offset);
-
- return ptr;
-}
-
-
-/**************************************************
- * Interrupt Handler ...
- */
-
-static irqreturn_t ni52_interrupt(int irq, void *dev_id)
-{
- struct net_device *dev = dev_id;
- unsigned int stat;
- int cnt = 0;
- struct priv *p;
-
- p = netdev_priv(dev);
-
- if (debuglevel > 1)
- printk("I");
-
- spin_lock(&p->spinlock);
-
- wait_for_scb_cmd(dev); /* wait for last command */
-
- while ((stat = readb(&p->scb->cus) & STAT_MASK)) {
- writeb(stat, &p->scb->cmd_cuc);
- ni_attn586();
-
- if (stat & STAT_FR) /* received a frame */
- ni52_rcv_int(dev);
-
- if (stat & STAT_RNR) { /* RU went 'not ready' */
- printk("(R)");
- if (readb(&p->scb->rus) & RU_SUSPEND) {
- /* special case: RU_SUSPEND */
- wait_for_scb_cmd(dev);
- writeb(RUC_RESUME, &p->scb->cmd_ruc);
- ni_attn586();
- wait_for_scb_cmd_ruc(dev);
- } else {
- printk(KERN_ERR "%s: Receiver-Unit went 'NOT READY': %04x/%02x.\n",
- dev->name, stat, readb(&p->scb->rus));
- ni52_rnr_int(dev);
- }
- }
-
- /* Command with I-bit set complete */
- if (stat & STAT_CX)
- ni52_xmt_int(dev);
-
-#ifndef NO_NOPCOMMANDS
- if (stat & STAT_CNA) { /* CU went 'not ready' */
- if (netif_running(dev))
- printk(KERN_ERR "%s: oops! CU has left active state. stat: %04x/%02x.\n",
- dev->name, stat, readb(&p->scb->cus));
- }
-#endif
-
- if (debuglevel > 1)
- printk("%d", cnt++);
-
- /* Wait for ack. (ni52_xmt_int can be faster than ack!!) */
- wait_for_scb_cmd(dev);
- if (readb(&p->scb->cmd_cuc)) { /* timed out? */
- printk(KERN_ERR "%s: Acknowledge timed out.\n",
- dev->name);
- ni_disint();
- break;
- }
- }
- spin_unlock(&p->spinlock);
-
- if (debuglevel > 1)
- printk("i");
- return IRQ_HANDLED;
-}
-
-/*******************************************************
- * receive-interrupt
- */
-
-static void ni52_rcv_int(struct net_device *dev)
-{
- int status, cnt = 0;
- unsigned short totlen;
- struct sk_buff *skb;
- struct rbd_struct __iomem *rbd;
- struct priv *p = netdev_priv(dev);
-
- if (debuglevel > 0)
- printk("R");
-
- for (; (status = readb(&p->rfd_top->stat_high)) & RFD_COMPL;) {
- rbd = make32(readw(&p->rfd_top->rbd_offset));
- if (status & RFD_OK) { /* frame received without error? */
- totlen = readw(&rbd->status);
- if (totlen & RBD_LAST) {
- /* the first and the last buffer? */
- totlen &= RBD_MASK; /* length of this frame */
- writew(0x00, &rbd->status);
- skb = netdev_alloc_skb(dev, totlen + 2);
- if (skb != NULL) {
- skb_reserve(skb, 2);
- skb_put(skb, totlen);
- memcpy_fromio(skb->data, p->base + readl(&rbd->buffer), totlen);
- skb->protocol = eth_type_trans(skb, dev);
- netif_rx(skb);
- dev->stats.rx_packets++;
- dev->stats.rx_bytes += totlen;
- } else
- dev->stats.rx_dropped++;
- } else {
- int rstat;
- /* free all RBD's until RBD_LAST is set */
- totlen = 0;
- while (!((rstat = readw(&rbd->status)) & RBD_LAST)) {
- totlen += rstat & RBD_MASK;
- if (!rstat) {
- printk(KERN_ERR "%s: Whoops .. no end mark in RBD list\n", dev->name);
- break;
- }
- writew(0, &rbd->status);
- rbd = make32(readw(&rbd->next));
- }
- totlen += rstat & RBD_MASK;
- writew(0, &rbd->status);
- printk(KERN_ERR "%s: received oversized frame! length: %d\n",
- dev->name, totlen);
- dev->stats.rx_dropped++;
- }
- } else {/* frame !(ok), only with 'save-bad-frames' */
- printk(KERN_ERR "%s: oops! rfd-error-status: %04x\n",
- dev->name, status);
- dev->stats.rx_errors++;
- }
- writeb(0, &p->rfd_top->stat_high);
- writeb(RFD_SUSP, &p->rfd_top->last); /* maybe exchange by RFD_LAST */
- writew(0xffff, &p->rfd_top->rbd_offset);
- writeb(0, &p->rfd_last->last); /* delete RFD_SUSP */
- p->rfd_last = p->rfd_top;
- p->rfd_top = make32(readw(&p->rfd_top->next)); /* step to next RFD */
- writew(make16(p->rfd_top), &p->scb->rfa_offset);
-
- if (debuglevel > 0)
- printk("%d", cnt++);
- }
-
- if (automatic_resume) {
- wait_for_scb_cmd(dev);
- writeb(RUC_RESUME, &p->scb->cmd_ruc);
- ni_attn586();
- wait_for_scb_cmd_ruc(dev);
- }
-
-#ifdef WAIT_4_BUSY
- {
- int i;
- for (i = 0; i < 1024; i++) {
- if (p->rfd_top->status)
- break;
- udelay(16);
- if (i == 1023)
- printk(KERN_ERR "%s: RU hasn't fetched next RFD (not busy/complete)\n", dev->name);
- }
- }
-#endif
- if (debuglevel > 0)
- printk("r");
-}
-
-/**********************************************************
- * handle 'Receiver went not ready'.
- */
-
-static void ni52_rnr_int(struct net_device *dev)
-{
- struct priv *p = netdev_priv(dev);
-
- dev->stats.rx_errors++;
-
- wait_for_scb_cmd(dev); /* wait for the last cmd, WAIT_4_FULLSTAT?? */
- writeb(RUC_ABORT, &p->scb->cmd_ruc); /* usually the RU is in the 'no resource'-state .. abort it now. */
- ni_attn586();
- wait_for_scb_cmd_ruc(dev); /* wait for accept cmd. */
-
- alloc_rfa(dev, p->rfd_first);
- /* maybe add a check here, before restarting the RU */
- startrecv586(dev); /* restart RU */
-
- printk(KERN_ERR "%s: Receive-Unit restarted. Status: %04x\n",
- dev->name, readb(&p->scb->rus));
-
-}
-
-/**********************************************************
- * handle xmit - interrupt
- */
-
-static void ni52_xmt_int(struct net_device *dev)
-{
- int status;
- struct priv *p = netdev_priv(dev);
-
- if (debuglevel > 0)
- printk("X");
-
- status = readw(&p->xmit_cmds[p->xmit_last]->cmd_status);
- if (!(status & STAT_COMPL))
- printk(KERN_ERR "%s: strange .. xmit-int without a 'COMPLETE'\n", dev->name);
-
- if (status & STAT_OK) {
- dev->stats.tx_packets++;
- dev->stats.collisions += (status & TCMD_MAXCOLLMASK);
- } else {
- dev->stats.tx_errors++;
- if (status & TCMD_LATECOLL) {
- printk(KERN_ERR "%s: late collision detected.\n",
- dev->name);
- dev->stats.collisions++;
- } else if (status & TCMD_NOCARRIER) {
- dev->stats.tx_carrier_errors++;
- printk(KERN_ERR "%s: no carrier detected.\n",
- dev->name);
- } else if (status & TCMD_LOSTCTS)
- printk(KERN_ERR "%s: loss of CTS detected.\n",
- dev->name);
- else if (status & TCMD_UNDERRUN) {
- dev->stats.tx_fifo_errors++;
- printk(KERN_ERR "%s: DMA underrun detected.\n",
- dev->name);
- } else if (status & TCMD_MAXCOLL) {
- printk(KERN_ERR "%s: Max. collisions exceeded.\n",
- dev->name);
- dev->stats.collisions += 16;
- }
- }
-#if (NUM_XMIT_BUFFS > 1)
- if ((++p->xmit_last) == NUM_XMIT_BUFFS)
- p->xmit_last = 0;
-#endif
- netif_wake_queue(dev);
-}
-
-/***********************************************************
- * (re)start the receiver
- */
-
-static void startrecv586(struct net_device *dev)
-{
- struct priv *p = netdev_priv(dev);
-
- wait_for_scb_cmd(dev);
- wait_for_scb_cmd_ruc(dev);
- writew(make16(p->rfd_first), &p->scb->rfa_offset);
- writeb(RUC_START, &p->scb->cmd_ruc);
- ni_attn586(); /* start cmd. */
- wait_for_scb_cmd_ruc(dev);
- /* wait for accept cmd. (no timeout!!) */
-}
-
-static void ni52_timeout(struct net_device *dev)
-{
- struct priv *p = netdev_priv(dev);
-#ifndef NO_NOPCOMMANDS
- if (readb(&p->scb->cus) & CU_ACTIVE) { /* COMMAND-UNIT active? */
- netif_wake_queue(dev);
-#ifdef DEBUG
- printk(KERN_ERR "%s: strange ... timeout with CU active?!?\n",
- dev->name);
- printk(KERN_ERR "%s: X0: %04x N0: %04x N1: %04x %d\n",
- dev->name, (int)p->xmit_cmds[0]->cmd_status,
- readw(&p->nop_cmds[0]->cmd_status),
- readw(&p->nop_cmds[1]->cmd_status),
- p->nop_point);
-#endif
- writeb(CUC_ABORT, &p->scb->cmd_cuc);
- ni_attn586();
- wait_for_scb_cmd(dev);
- writew(make16(p->nop_cmds[p->nop_point]), &p->scb->cbl_offset);
- writeb(CUC_START, &p->scb->cmd_cuc);
- ni_attn586();
- wait_for_scb_cmd(dev);
- dev->trans_start = jiffies; /* prevent tx timeout */
- return 0;
- }
-#endif
- {
-#ifdef DEBUG
- printk(KERN_ERR "%s: xmitter timed out, try to restart! stat: %02x\n",
- dev->name, readb(&p->scb->cus));
- printk(KERN_ERR "%s: command-stats: %04x %04x\n",
- dev->name,
- readw(&p->xmit_cmds[0]->cmd_status),
- readw(&p->xmit_cmds[1]->cmd_status));
- printk(KERN_ERR "%s: check, whether you set the right interrupt number!\n",
- dev->name);
-#endif
- ni52_close(dev);
- ni52_open(dev);
- }
- dev->trans_start = jiffies; /* prevent tx timeout */
-}
-
-/******************************************************
- * send frame
- */
-
-static netdev_tx_t ni52_send_packet(struct sk_buff *skb,
- struct net_device *dev)
-{
- int len, i;
-#ifndef NO_NOPCOMMANDS
- int next_nop;
-#endif
- struct priv *p = netdev_priv(dev);
-
- if (skb->len > XMIT_BUFF_SIZE) {
- printk(KERN_ERR "%s: Sorry, max. framelength is %d bytes. The length of your frame is %d bytes.\n", dev->name, XMIT_BUFF_SIZE, skb->len);
- return NETDEV_TX_OK;
- }
-
- netif_stop_queue(dev);
-
- memcpy_toio(p->xmit_cbuffs[p->xmit_count], skb->data, skb->len);
- len = skb->len;
- if (len < ETH_ZLEN) {
- len = ETH_ZLEN;
- memset_io(p->xmit_cbuffs[p->xmit_count]+skb->len, 0,
- len - skb->len);
- }
-
-#if (NUM_XMIT_BUFFS == 1)
-# ifdef NO_NOPCOMMANDS
-
-#ifdef DEBUG
- if (readb(&p->scb->cus) & CU_ACTIVE) {
- printk(KERN_ERR "%s: Hmmm .. CU is still running and we wanna send a new packet.\n", dev->name);
- printk(KERN_ERR "%s: stat: %04x %04x\n",
- dev->name, readb(&p->scb->cus),
- readw(&p->xmit_cmds[0]->cmd_status));
- }
-#endif
- writew(TBD_LAST | len, &p->xmit_buffs[0]->size);
- for (i = 0; i < 16; i++) {
- writew(0, &p->xmit_cmds[0]->cmd_status);
- wait_for_scb_cmd(dev);
- if ((readb(&p->scb->cus) & CU_STATUS) == CU_SUSPEND)
- writeb(CUC_RESUME, &p->scb->cmd_cuc);
- else {
- writew(make16(p->xmit_cmds[0]), &p->scb->cbl_offset);
- writeb(CUC_START, &p->scb->cmd_cuc);
- }
- ni_attn586();
- if (!i)
- dev_kfree_skb(skb);
- wait_for_scb_cmd(dev);
- /* test it, because CU sometimes doesn't start immediately */
- if (readb(&p->scb->cus) & CU_ACTIVE)
- break;
- if (readw(&p->xmit_cmds[0]->cmd_status))
- break;
- if (i == 15)
- printk(KERN_WARNING "%s: Can't start transmit-command.\n", dev->name);
- }
-# else
- next_nop = (p->nop_point + 1) & 0x1;
- writew(TBD_LAST | len, &p->xmit_buffs[0]->size);
- writew(make16(p->nop_cmds[next_nop]), &p->xmit_cmds[0]->cmd_link);
- writew(make16(p->nop_cmds[next_nop]),
- &p->nop_cmds[next_nop]->cmd_link);
- writew(0, &p->xmit_cmds[0]->cmd_status);
- writew(0, &p->nop_cmds[next_nop]->cmd_status);
-
- writew(make16(p->xmit_cmds[0]), &p->nop_cmds[p->nop_point]->cmd_link);
- p->nop_point = next_nop;
- dev_kfree_skb(skb);
-# endif
-#else
- writew(TBD_LAST | len, &p->xmit_buffs[p->xmit_count]->size);
- next_nop = p->xmit_count + 1
- if (next_nop == NUM_XMIT_BUFFS)
- next_nop = 0;
- writew(0, &p->xmit_cmds[p->xmit_count]->cmd_status);
- /* linkpointer of xmit-command already points to next nop cmd */
- writew(make16(p->nop_cmds[next_nop]),
- &p->nop_cmds[next_nop]->cmd_link);
- writew(0, &p->nop_cmds[next_nop]->cmd_status);
- writew(make16(p->xmit_cmds[p->xmit_count]),
- &p->nop_cmds[p->xmit_count]->cmd_link);
- p->xmit_count = next_nop;
- {
- unsigned long flags;
- spin_lock_irqsave(&p->spinlock);
- if (p->xmit_count != p->xmit_last)
- netif_wake_queue(dev);
- spin_unlock_irqrestore(&p->spinlock);
- }
- dev_kfree_skb(skb);
-#endif
- return NETDEV_TX_OK;
-}
-
-/*******************************************
- * Someone wanna have the statistics
- */
-
-static struct net_device_stats *ni52_get_stats(struct net_device *dev)
-{
- struct priv *p = netdev_priv(dev);
- unsigned short crc, aln, rsc, ovrn;
-
- /* Get error-statistics from the ni82586 */
- crc = readw(&p->scb->crc_errs);
- writew(0, &p->scb->crc_errs);
- aln = readw(&p->scb->aln_errs);
- writew(0, &p->scb->aln_errs);
- rsc = readw(&p->scb->rsc_errs);
- writew(0, &p->scb->rsc_errs);
- ovrn = readw(&p->scb->ovrn_errs);
- writew(0, &p->scb->ovrn_errs);
-
- dev->stats.rx_crc_errors += crc;
- dev->stats.rx_fifo_errors += ovrn;
- dev->stats.rx_frame_errors += aln;
- dev->stats.rx_dropped += rsc;
-
- return &dev->stats;
-}
-
-/********************************************************
- * Set MC list ..
- */
-
-static void set_multicast_list(struct net_device *dev)
-{
- netif_stop_queue(dev);
- ni_disint();
- alloc586(dev);
- init586(dev);
- startrecv586(dev);
- ni_enaint();
- netif_wake_queue(dev);
-}
-
-#ifdef MODULE
-static struct net_device *dev_ni52;
-
-module_param(io, int, 0);
-module_param(irq, int, 0);
-module_param(memstart, long, 0);
-module_param(memend, long, 0);
-MODULE_PARM_DESC(io, "NI5210 I/O base address,required");
-MODULE_PARM_DESC(irq, "NI5210 IRQ number,required");
-MODULE_PARM_DESC(memstart, "NI5210 memory base address,required");
-MODULE_PARM_DESC(memend, "NI5210 memory end address,required");
-
-int __init init_module(void)
-{
- if (io <= 0x0 || !memend || !memstart || irq < 2) {
- printk(KERN_ERR "ni52: Autoprobing not allowed for modules.\n");
- printk(KERN_ERR "ni52: Set symbols 'io' 'irq' 'memstart' and 'memend'\n");
- return -ENODEV;
- }
- dev_ni52 = ni52_probe(-1);
- if (IS_ERR(dev_ni52))
- return PTR_ERR(dev_ni52);
- return 0;
-}
-
-void __exit cleanup_module(void)
-{
- struct priv *p = netdev_priv(dev_ni52);
- unregister_netdev(dev_ni52);
- iounmap(p->mapped);
- release_region(dev_ni52->base_addr, NI52_TOTAL_SIZE);
- free_netdev(dev_ni52);
-}
-#endif /* MODULE */
-
-MODULE_LICENSE("GPL");
diff --git a/drivers/net/ethernet/i825xx/ni52.h b/drivers/net/ethernet/i825xx/ni52.h
deleted file mode 100644
index 0a03b288332..00000000000
--- a/drivers/net/ethernet/i825xx/ni52.h
+++ /dev/null
@@ -1,310 +0,0 @@
-/*
- * Intel i82586 Ethernet definitions
- *
- * This is an extension to the Linux operating system, and is covered by the
- * same GNU General Public License that covers that work.
- *
- * copyrights (c) 1994 by Michael Hipp (hippm@informatik.uni-tuebingen.de)
- *
- * I have done a look in the following sources:
- * crynwr-packet-driver by Russ Nelson
- * Garret A. Wollman's i82586-driver for BSD
- */
-
-
-#define NI52_RESET 0 /* writing to this address, resets the i82586 */
-#define NI52_ATTENTION 1 /* channel attention, kick the 586 */
-#define NI52_TENA 3 /* 2-5 possibly wrong, Xmit enable */
-#define NI52_TDIS 2 /* Xmit disable */
-#define NI52_INTENA 5 /* Interrupt enable */
-#define NI52_INTDIS 4 /* Interrupt disable */
-#define NI52_MAGIC1 6 /* dunno exact function */
-#define NI52_MAGIC2 7 /* dunno exact function */
-
-#define NI52_MAGICVAL1 0x00 /* magic-values for ni5210 card */
-#define NI52_MAGICVAL2 0x55
-
-/*
- * where to find the System Configuration Pointer (SCP)
- */
-#define SCP_DEFAULT_ADDRESS 0xfffff4
-
-
-/*
- * System Configuration Pointer Struct
- */
-
-struct scp_struct
-{
- u16 zero_dum0; /* has to be zero */
- u8 sysbus; /* 0=16Bit,1=8Bit */
- u8 zero_dum1; /* has to be zero for 586 */
- u16 zero_dum2;
- u16 zero_dum3;
- u32 iscp; /* pointer to the iscp-block */
-};
-
-
-/*
- * Intermediate System Configuration Pointer (ISCP)
- */
-struct iscp_struct
-{
- u8 busy; /* 586 clears after successful init */
- u8 zero_dummy; /* has to be zero */
- u16 scb_offset; /* pointeroffset to the scb_base */
- u32 scb_base; /* base-address of all 16-bit offsets */
-};
-
-/*
- * System Control Block (SCB)
- */
-struct scb_struct
-{
- u8 rus;
- u8 cus;
- u8 cmd_ruc; /* command word: RU part */
- u8 cmd_cuc; /* command word: CU part & ACK */
- u16 cbl_offset; /* pointeroffset, command block list */
- u16 rfa_offset; /* pointeroffset, receive frame area */
- u16 crc_errs; /* CRC-Error counter */
- u16 aln_errs; /* alignmenterror counter */
- u16 rsc_errs; /* Resourceerror counter */
- u16 ovrn_errs; /* OVerrunerror counter */
-};
-
-/*
- * possible command values for the command word
- */
-#define RUC_MASK 0x0070 /* mask for RU commands */
-#define RUC_NOP 0x0000 /* NOP-command */
-#define RUC_START 0x0010 /* start RU */
-#define RUC_RESUME 0x0020 /* resume RU after suspend */
-#define RUC_SUSPEND 0x0030 /* suspend RU */
-#define RUC_ABORT 0x0040 /* abort receiver operation immediately */
-
-#define CUC_MASK 0x07 /* mask for CU command */
-#define CUC_NOP 0x00 /* NOP-command */
-#define CUC_START 0x01 /* start execution of 1. cmd on the CBL */
-#define CUC_RESUME 0x02 /* resume after suspend */
-#define CUC_SUSPEND 0x03 /* Suspend CU */
-#define CUC_ABORT 0x04 /* abort command operation immediately */
-
-#define ACK_MASK 0xf0 /* mask for ACK command */
-#define ACK_CX 0x80 /* acknowledges STAT_CX */
-#define ACK_FR 0x40 /* ack. STAT_FR */
-#define ACK_CNA 0x20 /* ack. STAT_CNA */
-#define ACK_RNR 0x10 /* ack. STAT_RNR */
-
-/*
- * possible status values for the status word
- */
-#define STAT_MASK 0xf0 /* mask for cause of interrupt */
-#define STAT_CX 0x80 /* CU finished cmd with its I bit set */
-#define STAT_FR 0x40 /* RU finished receiving a frame */
-#define STAT_CNA 0x20 /* CU left active state */
-#define STAT_RNR 0x10 /* RU left ready state */
-
-#define CU_STATUS 0x7 /* CU status, 0=idle */
-#define CU_SUSPEND 0x1 /* CU is suspended */
-#define CU_ACTIVE 0x2 /* CU is active */
-
-#define RU_STATUS 0x70 /* RU status, 0=idle */
-#define RU_SUSPEND 0x10 /* RU suspended */
-#define RU_NOSPACE 0x20 /* RU no resources */
-#define RU_READY 0x40 /* RU is ready */
-
-/*
- * Receive Frame Descriptor (RFD)
- */
-struct rfd_struct
-{
- u8 stat_low; /* status word */
- u8 stat_high; /* status word */
- u8 rfd_sf; /* 82596 mode only */
- u8 last; /* Bit15,Last Frame on List / Bit14,suspend */
- u16 next; /* linkoffset to next RFD */
- u16 rbd_offset; /* pointeroffset to RBD-buffer */
- u8 dest[6]; /* ethernet-address, destination */
- u8 source[6]; /* ethernet-address, source */
- u16 length; /* 802.3 frame-length */
- u16 zero_dummy; /* dummy */
-};
-
-#define RFD_LAST 0x80 /* last: last rfd in the list */
-#define RFD_SUSP 0x40 /* last: suspend RU after */
-#define RFD_COMPL 0x80
-#define RFD_OK 0x20
-#define RFD_BUSY 0x40
-#define RFD_ERR_LEN 0x10 /* Length error (if enabled length-checking */
-#define RFD_ERR_CRC 0x08 /* CRC error */
-#define RFD_ERR_ALGN 0x04 /* Alignment error */
-#define RFD_ERR_RNR 0x02 /* status: receiver out of resources */
-#define RFD_ERR_OVR 0x01 /* DMA Overrun! */
-
-#define RFD_ERR_FTS 0x0080 /* Frame to short */
-#define RFD_ERR_NEOP 0x0040 /* No EOP flag (for bitstuffing only) */
-#define RFD_ERR_TRUN 0x0020 /* (82596 only/SF mode) indicates truncated frame */
-#define RFD_MATCHADD 0x0002 /* status: Destinationaddress !matches IA (only 82596) */
-#define RFD_COLLDET 0x0001 /* Detected collision during reception */
-
-/*
- * Receive Buffer Descriptor (RBD)
- */
-struct rbd_struct
-{
- u16 status; /* status word,number of used bytes in buff */
- u16 next; /* pointeroffset to next RBD */
- u32 buffer; /* receive buffer address pointer */
- u16 size; /* size of this buffer */
- u16 zero_dummy; /* dummy */
-};
-
-#define RBD_LAST 0x8000 /* last buffer */
-#define RBD_USED 0x4000 /* this buffer has data */
-#define RBD_MASK 0x3fff /* size-mask for length */
-
-/*
- * Statusvalues for Commands/RFD
- */
-#define STAT_COMPL 0x8000 /* status: frame/command is complete */
-#define STAT_BUSY 0x4000 /* status: frame/command is busy */
-#define STAT_OK 0x2000 /* status: frame/command is ok */
-
-/*
- * Action-Commands
- */
-#define CMD_NOP 0x0000 /* NOP */
-#define CMD_IASETUP 0x0001 /* initial address setup command */
-#define CMD_CONFIGURE 0x0002 /* configure command */
-#define CMD_MCSETUP 0x0003 /* MC setup command */
-#define CMD_XMIT 0x0004 /* transmit command */
-#define CMD_TDR 0x0005 /* time domain reflectometer (TDR) command */
-#define CMD_DUMP 0x0006 /* dump command */
-#define CMD_DIAGNOSE 0x0007 /* diagnose command */
-
-/*
- * Action command bits
- */
-#define CMD_LAST 0x8000 /* indicates last command in the CBL */
-#define CMD_SUSPEND 0x4000 /* suspend CU after this CB */
-#define CMD_INT 0x2000 /* generate interrupt after execution */
-
-/*
- * NOP - command
- */
-struct nop_cmd_struct
-{
- u16 cmd_status; /* status of this command */
- u16 cmd_cmd; /* the command itself (+bits) */
- u16 cmd_link; /* offsetpointer to next command */
-};
-
-/*
- * IA Setup command
- */
-struct iasetup_cmd_struct
-{
- u16 cmd_status;
- u16 cmd_cmd;
- u16 cmd_link;
- u8 iaddr[6];
-};
-
-/*
- * Configure command
- */
-struct configure_cmd_struct
-{
- u16 cmd_status;
- u16 cmd_cmd;
- u16 cmd_link;
- u8 byte_cnt; /* size of the config-cmd */
- u8 fifo; /* fifo/recv monitor */
- u8 sav_bf; /* save bad frames (bit7=1)*/
- u8 adr_len; /* adr_len(0-2),al_loc(3),pream(4-5),loopbak(6-7)*/
- u8 priority; /* lin_prio(0-2),exp_prio(4-6),bof_metd(7) */
- u8 ifs; /* inter frame spacing */
- u8 time_low; /* slot time low */
- u8 time_high; /* slot time high(0-2) and max. retries(4-7) */
- u8 promisc; /* promisc-mode(0) , et al (1-7) */
- u8 carr_coll; /* carrier(0-3)/collision(4-7) stuff */
- u8 fram_len; /* minimal frame len */
- u8 dummy; /* dummy */
-};
-
-/*
- * Multicast Setup command
- */
-struct mcsetup_cmd_struct
-{
- u16 cmd_status;
- u16 cmd_cmd;
- u16 cmd_link;
- u16 mc_cnt; /* number of bytes in the MC-List */
- u8 mc_list[0][6]; /* pointer to 6 bytes entries */
-};
-
-/*
- * DUMP command
- */
-struct dump_cmd_struct
-{
- u16 cmd_status;
- u16 cmd_cmd;
- u16 cmd_link;
- u16 dump_offset; /* pointeroffset to DUMP space */
-};
-
-/*
- * transmit command
- */
-struct transmit_cmd_struct
-{
- u16 cmd_status;
- u16 cmd_cmd;
- u16 cmd_link;
- u16 tbd_offset; /* pointeroffset to TBD */
- u8 dest[6]; /* destination address of the frame */
- u16 length; /* user defined: 802.3 length / Ether type */
-};
-
-#define TCMD_ERRMASK 0x0fa0
-#define TCMD_MAXCOLLMASK 0x000f
-#define TCMD_MAXCOLL 0x0020
-#define TCMD_HEARTBEAT 0x0040
-#define TCMD_DEFERRED 0x0080
-#define TCMD_UNDERRUN 0x0100
-#define TCMD_LOSTCTS 0x0200
-#define TCMD_NOCARRIER 0x0400
-#define TCMD_LATECOLL 0x0800
-
-struct tdr_cmd_struct
-{
- u16 cmd_status;
- u16 cmd_cmd;
- u16 cmd_link;
- u16 status;
-};
-
-#define TDR_LNK_OK 0x8000 /* No link problem identified */
-#define TDR_XCVR_PRB 0x4000 /* indicates a transceiver problem */
-#define TDR_ET_OPN 0x2000 /* open, no correct termination */
-#define TDR_ET_SRT 0x1000 /* TDR detected a short circuit */
-#define TDR_TIMEMASK 0x07ff /* mask for the time field */
-
-/*
- * Transmit Buffer Descriptor (TBD)
- */
-struct tbd_struct
-{
- u16 size; /* size + EOF-Flag(15) */
- u16 next; /* pointeroffset to next TBD */
- u32 buffer; /* pointer to buffer */
-};
-
-#define TBD_LAST 0x8000 /* EOF-Flag, indicates last buffer in list */
-
-
-
-
diff --git a/drivers/net/ethernet/i825xx/znet.c b/drivers/net/ethernet/i825xx/znet.c
deleted file mode 100644
index c9479e081b8..00000000000
--- a/drivers/net/ethernet/i825xx/znet.c
+++ /dev/null
@@ -1,928 +0,0 @@
-/* znet.c: An Zenith Z-Note ethernet driver for linux. */
-
-/*
- Written by Donald Becker.
-
- The author may be reached as becker@scyld.com.
- This driver is based on the Linux skeleton driver. The copyright of the
- skeleton driver is held by the United States Government, as represented
- by DIRNSA, and it is released under the GPL.
-
- Thanks to Mike Hollick for alpha testing and suggestions.
-
- References:
- The Crynwr packet driver.
-
- "82593 CSMA/CD Core LAN Controller" Intel datasheet, 1992
- Intel Microcommunications Databook, Vol. 1, 1990.
- As usual with Intel, the documentation is incomplete and inaccurate.
- I had to read the Crynwr packet driver to figure out how to actually
- use the i82593, and guess at what register bits matched the loosely
- related i82586.
-
- Theory of Operation
-
- The i82593 used in the Zenith Z-Note series operates using two(!) slave
- DMA channels, one interrupt, and one 8-bit I/O port.
-
- While there several ways to configure '593 DMA system, I chose the one
- that seemed commensurate with the highest system performance in the face
- of moderate interrupt latency: Both DMA channels are configured as
- recirculating ring buffers, with one channel (#0) dedicated to Rx and
- the other channel (#1) to Tx and configuration. (Note that this is
- different than the Crynwr driver, where the Tx DMA channel is initialized
- before each operation. That approach simplifies operation and Tx error
- recovery, but requires additional I/O in normal operation and precludes
- transmit buffer chaining.)
-
- Both rings are set to 8192 bytes using {TX,RX}_RING_SIZE. This provides
- a reasonable ring size for Rx, while simplifying DMA buffer allocation --
- DMA buffers must not cross a 128K boundary. (In truth the size selection
- was influenced by my lack of '593 documentation. I thus was constrained
- to use the Crynwr '593 initialization table, which sets the Rx ring size
- to 8K.)
-
- Despite my usual low opinion about Intel-designed parts, I must admit
- that the bulk data handling of the i82593 is a good design for
- an integrated system, like a laptop, where using two slave DMA channels
- doesn't pose a problem. I still take issue with using only a single I/O
- port. In the same controlled environment there are essentially no
- limitations on I/O space, and using multiple locations would eliminate
- the need for multiple operations when looking at status registers,
- setting the Rx ring boundary, or switching to promiscuous mode.
-
- I also question Zenith's selection of the '593: one of the advertised
- advantages of earlier Intel parts was that if you figured out the magic
- initialization incantation you could use the same part on many different
- network types. Zenith's use of the "FriendlyNet" (sic) connector rather
- than an on-board transceiver leads me to believe that they were planning
- to take advantage of this. But, uhmmm, the '593 omits all but ethernet
- functionality from the serial subsystem.
- */
-
-/* 10/2002
-
- o Resurected for Linux 2.5+ by Marc Zyngier <maz@wild-wind.fr.eu.org> :
-
- - Removed strange DMA snooping in znet_sent_packet, which lead to
- TX buffer corruption on my laptop.
- - Use init_etherdev stuff.
- - Use kmalloc-ed DMA buffers.
- - Use as few global variables as possible.
- - Use proper resources management.
- - Use wireless/i82593.h as much as possible (structure, constants)
- - Compiles as module or build-in.
- - Now survives unplugging/replugging cable.
-
- Some code was taken from wavelan_cs.
-
- Tested on a vintage Zenith Z-Note 433Lnp+. Probably broken on
- anything else. Testers (and detailed bug reports) are welcome :-).
-
- o TODO :
-
- - Properly handle multicast
- - Understand why some traffic patterns add a 1s latency...
- */
-
-#include <linux/module.h>
-#include <linux/kernel.h>
-#include <linux/string.h>
-#include <linux/slab.h>
-#include <linux/errno.h>
-#include <linux/interrupt.h>
-#include <linux/ioport.h>
-#include <linux/init.h>
-#include <linux/delay.h>
-#include <linux/netdevice.h>
-#include <linux/etherdevice.h>
-#include <linux/skbuff.h>
-#include <linux/if_arp.h>
-#include <linux/bitops.h>
-
-#include <asm/io.h>
-#include <asm/dma.h>
-
-#include <linux/i82593.h>
-
-static char version[] __initdata = "znet.c:v1.02 9/23/94 becker@scyld.com\n";
-
-#ifndef ZNET_DEBUG
-#define ZNET_DEBUG 1
-#endif
-static unsigned int znet_debug = ZNET_DEBUG;
-module_param (znet_debug, int, 0);
-MODULE_PARM_DESC (znet_debug, "ZNet debug level");
-MODULE_LICENSE("GPL");
-
-/* The DMA modes we need aren't in <dma.h>. */
-#define DMA_RX_MODE 0x14 /* Auto init, I/O to mem, ++, demand. */
-#define DMA_TX_MODE 0x18 /* Auto init, Mem to I/O, ++, demand. */
-#define dma_page_eq(ptr1, ptr2) ((long)(ptr1)>>17 == (long)(ptr2)>>17)
-#define RX_BUF_SIZE 8192
-#define TX_BUF_SIZE 8192
-#define DMA_BUF_SIZE (RX_BUF_SIZE + 16) /* 8k + 16 bytes for trailers */
-
-#define TX_TIMEOUT (HZ/10)
-
-struct znet_private {
- int rx_dma, tx_dma;
- spinlock_t lock;
- short sia_base, sia_size, io_size;
- struct i82593_conf_block i593_init;
- /* The starting, current, and end pointers for the packet buffers. */
- ushort *rx_start, *rx_cur, *rx_end;
- ushort *tx_start, *tx_cur, *tx_end;
- ushort tx_buf_len; /* Tx buffer length, in words. */
-};
-
-/* Only one can be built-in;-> */
-static struct net_device *znet_dev;
-
-#define NETIDBLK_MAGIC "NETIDBLK"
-#define NETIDBLK_MAGIC_SIZE 8
-
-struct netidblk {
- char magic[NETIDBLK_MAGIC_SIZE]; /* The magic number (string) "NETIDBLK" */
- unsigned char netid[8]; /* The physical station address */
- char nettype, globalopt;
- char vendor[8]; /* The machine vendor and product name. */
- char product[8];
- char irq1, irq2; /* Interrupts, only one is currently used. */
- char dma1, dma2;
- short dma_mem_misc[8]; /* DMA buffer locations (unused in Linux). */
- short iobase1, iosize1;
- short iobase2, iosize2; /* Second iobase unused. */
- char driver_options; /* Misc. bits */
- char pad;
-};
-
-static int znet_open(struct net_device *dev);
-static netdev_tx_t znet_send_packet(struct sk_buff *skb,
- struct net_device *dev);
-static irqreturn_t znet_interrupt(int irq, void *dev_id);
-static void znet_rx(struct net_device *dev);
-static int znet_close(struct net_device *dev);
-static void hardware_init(struct net_device *dev);
-static void update_stop_hit(short ioaddr, unsigned short rx_stop_offset);
-static void znet_tx_timeout (struct net_device *dev);
-
-/* Request needed resources */
-static int znet_request_resources (struct net_device *dev)
-{
- struct znet_private *znet = netdev_priv(dev);
-
- if (request_irq (dev->irq, znet_interrupt, 0, "ZNet", dev))
- goto failed;
- if (request_dma (znet->rx_dma, "ZNet rx"))
- goto free_irq;
- if (request_dma (znet->tx_dma, "ZNet tx"))
- goto free_rx_dma;
- if (!request_region (znet->sia_base, znet->sia_size, "ZNet SIA"))
- goto free_tx_dma;
- if (!request_region (dev->base_addr, znet->io_size, "ZNet I/O"))
- goto free_sia;
-
- return 0; /* Happy ! */
-
- free_sia:
- release_region (znet->sia_base, znet->sia_size);
- free_tx_dma:
- free_dma (znet->tx_dma);
- free_rx_dma:
- free_dma (znet->rx_dma);
- free_irq:
- free_irq (dev->irq, dev);
- failed:
- return -1;
-}
-
-static void znet_release_resources (struct net_device *dev)
-{
- struct znet_private *znet = netdev_priv(dev);
-
- release_region (znet->sia_base, znet->sia_size);
- release_region (dev->base_addr, znet->io_size);
- free_dma (znet->tx_dma);
- free_dma (znet->rx_dma);
- free_irq (dev->irq, dev);
-}
-
-/* Keep the magical SIA stuff in a single function... */
-static void znet_transceiver_power (struct net_device *dev, int on)
-{
- struct znet_private *znet = netdev_priv(dev);
- unsigned char v;
-
- /* Turn on/off the 82501 SIA, using zenith-specific magic. */
- /* Select LAN control register */
- outb(0x10, znet->sia_base);
-
- if (on)
- v = inb(znet->sia_base + 1) | 0x84;
- else
- v = inb(znet->sia_base + 1) & ~0x84;
-
- outb(v, znet->sia_base+1); /* Turn on/off LAN power (bit 2). */
-}
-
-/* Init the i82593, with current promisc/mcast configuration.
- Also used from hardware_init. */
-static void znet_set_multicast_list (struct net_device *dev)
-{
- struct znet_private *znet = netdev_priv(dev);
- short ioaddr = dev->base_addr;
- struct i82593_conf_block *cfblk = &znet->i593_init;
-
- memset(cfblk, 0x00, sizeof(struct i82593_conf_block));
-
- /* The configuration block. What an undocumented nightmare.
- The first set of values are those suggested (without explanation)
- for ethernet in the Intel 82586 databook. The rest appear to be
- completely undocumented, except for cryptic notes in the Crynwr
- packet driver. This driver uses the Crynwr values verbatim. */
-
- /* maz : Rewritten to take advantage of the wanvelan includes.
- At least we have names, not just blind values */
-
- /* Byte 0 */
- cfblk->fifo_limit = 10; /* = 16 B rx and 80 B tx fifo thresholds */
- cfblk->forgnesi = 0; /* 0=82C501, 1=AMD7992B compatibility */
- cfblk->fifo_32 = 1;
- cfblk->d6mod = 0; /* Run in i82593 advanced mode */
- cfblk->throttle_enb = 1;
-
- /* Byte 1 */
- cfblk->throttle = 8; /* Continuous w/interrupts, 128-clock DMA. */
- cfblk->cntrxint = 0; /* enable continuous mode receive interrupts */
- cfblk->contin = 1; /* enable continuous mode */
-
- /* Byte 2 */
- cfblk->addr_len = ETH_ALEN;
- cfblk->acloc = 1; /* Disable source addr insertion by i82593 */
- cfblk->preamb_len = 2; /* 8 bytes preamble */
- cfblk->loopback = 0; /* Loopback off */
-
- /* Byte 3 */
- cfblk->lin_prio = 0; /* Default priorities & backoff methods. */
- cfblk->tbofstop = 0;
- cfblk->exp_prio = 0;
- cfblk->bof_met = 0;
-
- /* Byte 4 */
- cfblk->ifrm_spc = 6; /* 96 bit times interframe spacing */
-
- /* Byte 5 */
- cfblk->slottim_low = 0; /* 512 bit times slot time (low) */
-
- /* Byte 6 */
- cfblk->slottim_hi = 2; /* 512 bit times slot time (high) */
- cfblk->max_retr = 15; /* 15 collisions retries */
-
- /* Byte 7 */
- cfblk->prmisc = ((dev->flags & IFF_PROMISC) ? 1 : 0); /* Promiscuous mode */
- cfblk->bc_dis = 0; /* Enable broadcast reception */
- cfblk->crs_1 = 0; /* Don't transmit without carrier sense */
- cfblk->nocrc_ins = 0; /* i82593 generates CRC */
- cfblk->crc_1632 = 0; /* 32-bit Autodin-II CRC */
- cfblk->crs_cdt = 0; /* CD not to be interpreted as CS */
-
- /* Byte 8 */
- cfblk->cs_filter = 0; /* CS is recognized immediately */
- cfblk->crs_src = 0; /* External carrier sense */
- cfblk->cd_filter = 0; /* CD is recognized immediately */
-
- /* Byte 9 */
- cfblk->min_fr_len = ETH_ZLEN >> 2; /* Minimum frame length */
-
- /* Byte A */
- cfblk->lng_typ = 1; /* Type/length checks OFF */
- cfblk->lng_fld = 1; /* Disable 802.3 length field check */
- cfblk->rxcrc_xf = 1; /* Don't transfer CRC to memory */
- cfblk->artx = 1; /* Disable automatic retransmission */
- cfblk->sarec = 1; /* Disable source addr trig of CD */
- cfblk->tx_jabber = 0; /* Disable jabber jam sequence */
- cfblk->hash_1 = 1; /* Use bits 0-5 in mc address hash */
- cfblk->lbpkpol = 0; /* Loopback pin active high */
-
- /* Byte B */
- cfblk->fdx = 0; /* Disable full duplex operation */
-
- /* Byte C */
- cfblk->dummy_6 = 0x3f; /* all ones, Default multicast addresses & backoff. */
- cfblk->mult_ia = 0; /* No multiple individual addresses */
- cfblk->dis_bof = 0; /* Disable the backoff algorithm ?! */
-
- /* Byte D */
- cfblk->dummy_1 = 1; /* set to 1 */
- cfblk->tx_ifs_retrig = 3; /* Hmm... Disabled */
- cfblk->mc_all = (!netdev_mc_empty(dev) ||
- (dev->flags & IFF_ALLMULTI)); /* multicast all mode */
- cfblk->rcv_mon = 0; /* Monitor mode disabled */
- cfblk->frag_acpt = 0; /* Do not accept fragments */
- cfblk->tstrttrs = 0; /* No start transmission threshold */
-
- /* Byte E */
- cfblk->fretx = 1; /* FIFO automatic retransmission */
- cfblk->runt_eop = 0; /* drop "runt" packets */
- cfblk->hw_sw_pin = 0; /* ?? */
- cfblk->big_endn = 0; /* Big Endian ? no... */
- cfblk->syncrqs = 1; /* Synchronous DRQ deassertion... */
- cfblk->sttlen = 1; /* 6 byte status registers */
- cfblk->rx_eop = 0; /* Signal EOP on packet reception */
- cfblk->tx_eop = 0; /* Signal EOP on packet transmission */
-
- /* Byte F */
- cfblk->rbuf_size = RX_BUF_SIZE >> 12; /* Set receive buffer size */
- cfblk->rcvstop = 1; /* Enable Receive Stop Register */
-
- if (znet_debug > 2) {
- int i;
- unsigned char *c;
-
- for (i = 0, c = (char *) cfblk; i < sizeof (*cfblk); i++)
- printk ("%02X ", c[i]);
- printk ("\n");
- }
-
- *znet->tx_cur++ = sizeof(struct i82593_conf_block);
- memcpy(znet->tx_cur, cfblk, sizeof(struct i82593_conf_block));
- znet->tx_cur += sizeof(struct i82593_conf_block)/2;
- outb(OP0_CONFIGURE | CR0_CHNL, ioaddr);
-
- /* XXX FIXME maz : Add multicast addresses here, so having a
- * multicast address configured isn't equal to IFF_ALLMULTI */
-}
-
-static const struct net_device_ops znet_netdev_ops = {
- .ndo_open = znet_open,
- .ndo_stop = znet_close,
- .ndo_start_xmit = znet_send_packet,
- .ndo_set_rx_mode = znet_set_multicast_list,
- .ndo_tx_timeout = znet_tx_timeout,
- .ndo_change_mtu = eth_change_mtu,
- .ndo_set_mac_address = eth_mac_addr,
- .ndo_validate_addr = eth_validate_addr,
-};
-
-/* The Z-Note probe is pretty easy. The NETIDBLK exists in the safe-to-probe
- BIOS area. We just scan for the signature, and pull the vital parameters
- out of the structure. */
-
-static int __init znet_probe (void)
-{
- int i;
- struct netidblk *netinfo;
- struct znet_private *znet;
- struct net_device *dev;
- char *p;
- char *plast = phys_to_virt(0x100000 - NETIDBLK_MAGIC_SIZE);
- int err = -ENOMEM;
-
- /* This code scans the region 0xf0000 to 0xfffff for a "NETIDBLK". */
- for(p = (char *)phys_to_virt(0xf0000); p <= plast; p++)
- if (*p == 'N' &&
- strncmp(p, NETIDBLK_MAGIC, NETIDBLK_MAGIC_SIZE) == 0)
- break;
-
- if (p > plast) {
- if (znet_debug > 1)
- printk(KERN_INFO "No Z-Note ethernet adaptor found.\n");
- return -ENODEV;
- }
-
- dev = alloc_etherdev(sizeof(struct znet_private));
- if (!dev)
- return -ENOMEM;
-
- znet = netdev_priv(dev);
-
- netinfo = (struct netidblk *)p;
- dev->base_addr = netinfo->iobase1;
- dev->irq = netinfo->irq1;
-
- /* The station address is in the "netidblk" at 0x0f0000. */
- for (i = 0; i < 6; i++)
- dev->dev_addr[i] = netinfo->netid[i];
-
- printk(KERN_INFO "%s: ZNET at %#3lx, %pM"
- ", using IRQ %d DMA %d and %d.\n",
- dev->name, dev->base_addr, dev->dev_addr,
- dev->irq, netinfo->dma1, netinfo->dma2);
-
- if (znet_debug > 1) {
- printk(KERN_INFO "%s: vendor '%16.16s' IRQ1 %d IRQ2 %d DMA1 %d DMA2 %d.\n",
- dev->name, netinfo->vendor,
- netinfo->irq1, netinfo->irq2,
- netinfo->dma1, netinfo->dma2);
- printk(KERN_INFO "%s: iobase1 %#x size %d iobase2 %#x size %d net type %2.2x.\n",
- dev->name, netinfo->iobase1, netinfo->iosize1,
- netinfo->iobase2, netinfo->iosize2, netinfo->nettype);
- }
-
- if (znet_debug > 0)
- printk(KERN_INFO "%s", version);
-
- znet->rx_dma = netinfo->dma1;
- znet->tx_dma = netinfo->dma2;
- spin_lock_init(&znet->lock);
- znet->sia_base = 0xe6; /* Magic address for the 82501 SIA */
- znet->sia_size = 2;
- /* maz: Despite the '593 being advertised above as using a
- * single 8bits I/O port, this driver does many 16bits
- * access. So set io_size accordingly */
- znet->io_size = 2;
-
- if (!(znet->rx_start = kmalloc (DMA_BUF_SIZE, GFP_KERNEL | GFP_DMA)))
- goto free_dev;
- if (!(znet->tx_start = kmalloc (DMA_BUF_SIZE, GFP_KERNEL | GFP_DMA)))
- goto free_rx;
-
- if (!dma_page_eq (znet->rx_start, znet->rx_start + (RX_BUF_SIZE/2-1)) ||
- !dma_page_eq (znet->tx_start, znet->tx_start + (TX_BUF_SIZE/2-1))) {
- printk (KERN_WARNING "tx/rx crossing DMA frontiers, giving up\n");
- goto free_tx;
- }
-
- znet->rx_end = znet->rx_start + RX_BUF_SIZE/2;
- znet->tx_buf_len = TX_BUF_SIZE/2;
- znet->tx_end = znet->tx_start + znet->tx_buf_len;
-
- /* The ZNET-specific entries in the device structure. */
- dev->netdev_ops = &znet_netdev_ops;
- dev->watchdog_timeo = TX_TIMEOUT;
- err = register_netdev(dev);
- if (err)
- goto free_tx;
- znet_dev = dev;
- return 0;
-
- free_tx:
- kfree(znet->tx_start);
- free_rx:
- kfree(znet->rx_start);
- free_dev:
- free_netdev(dev);
- return err;
-}
-
-
-static int znet_open(struct net_device *dev)
-{
- int ioaddr = dev->base_addr;
-
- if (znet_debug > 2)
- printk(KERN_DEBUG "%s: znet_open() called.\n", dev->name);
-
- /* These should never fail. You can't add devices to a sealed box! */
- if (znet_request_resources (dev)) {
- printk(KERN_WARNING "%s: Not opened -- resource busy?!?\n", dev->name);
- return -EBUSY;
- }
-
- znet_transceiver_power (dev, 1);
-
- /* According to the Crynwr driver we should wait 50 msec. for the
- LAN clock to stabilize. My experiments indicates that the '593 can
- be initialized immediately. The delay is probably needed for the
- DC-to-DC converter to come up to full voltage, and for the oscillator
- to be spot-on at 20Mhz before transmitting.
- Until this proves to be a problem we rely on the higher layers for the
- delay and save allocating a timer entry. */
-
- /* maz : Well, I'm getting every time the following message
- * without the delay on a 486@33. This machine is much too
- * fast... :-) So maybe the Crynwr driver wasn't wrong after
- * all, even if the message is completly harmless on my
- * setup. */
- mdelay (50);
-
- /* This follows the packet driver's lead, and checks for success. */
- if (inb(ioaddr) != 0x10 && inb(ioaddr) != 0x00)
- printk(KERN_WARNING "%s: Problem turning on the transceiver power.\n",
- dev->name);
-
- hardware_init(dev);
- netif_start_queue (dev);
-
- return 0;
-}
-
-
-static void znet_tx_timeout (struct net_device *dev)
-{
- int ioaddr = dev->base_addr;
- ushort event, tx_status, rx_offset, state;
-
- outb (CR0_STATUS_0, ioaddr);
- event = inb (ioaddr);
- outb (CR0_STATUS_1, ioaddr);
- tx_status = inw (ioaddr);
- outb (CR0_STATUS_2, ioaddr);
- rx_offset = inw (ioaddr);
- outb (CR0_STATUS_3, ioaddr);
- state = inb (ioaddr);
- printk (KERN_WARNING "%s: transmit timed out, status %02x %04x %04x %02x,"
- " resetting.\n", dev->name, event, tx_status, rx_offset, state);
- if (tx_status == TX_LOST_CRS)
- printk (KERN_WARNING "%s: Tx carrier error, check transceiver cable.\n",
- dev->name);
- outb (OP0_RESET, ioaddr);
- hardware_init (dev);
- netif_wake_queue (dev);
-}
-
-static netdev_tx_t znet_send_packet(struct sk_buff *skb, struct net_device *dev)
-{
- int ioaddr = dev->base_addr;
- struct znet_private *znet = netdev_priv(dev);
- unsigned long flags;
- short length = skb->len;
-
- if (znet_debug > 4)
- printk(KERN_DEBUG "%s: ZNet_send_packet.\n", dev->name);
-
- if (length < ETH_ZLEN) {
- if (skb_padto(skb, ETH_ZLEN))
- return NETDEV_TX_OK;
- length = ETH_ZLEN;
- }
-
- netif_stop_queue (dev);
-
- /* Check that the part hasn't reset itself, probably from suspend. */
- outb(CR0_STATUS_0, ioaddr);
- if (inw(ioaddr) == 0x0010 &&
- inw(ioaddr) == 0x0000 &&
- inw(ioaddr) == 0x0010) {
- if (znet_debug > 1)
- printk (KERN_WARNING "%s : waking up\n", dev->name);
- hardware_init(dev);
- znet_transceiver_power (dev, 1);
- }
-
- if (1) {
- unsigned char *buf = (void *)skb->data;
- ushort *tx_link = znet->tx_cur - 1;
- ushort rnd_len = (length + 1)>>1;
-
- dev->stats.tx_bytes+=length;
-
- if (znet->tx_cur >= znet->tx_end)
- znet->tx_cur = znet->tx_start;
- *znet->tx_cur++ = length;
- if (znet->tx_cur + rnd_len + 1 > znet->tx_end) {
- int semi_cnt = (znet->tx_end - znet->tx_cur)<<1; /* Cvrt to byte cnt. */
- memcpy(znet->tx_cur, buf, semi_cnt);
- rnd_len -= semi_cnt>>1;
- memcpy(znet->tx_start, buf + semi_cnt, length - semi_cnt);
- znet->tx_cur = znet->tx_start + rnd_len;
- } else {
- memcpy(znet->tx_cur, buf, skb->len);
- znet->tx_cur += rnd_len;
- }
- *znet->tx_cur++ = 0;
-
- spin_lock_irqsave(&znet->lock, flags);
- {
- *tx_link = OP0_TRANSMIT | CR0_CHNL;
- /* Is this always safe to do? */
- outb(OP0_TRANSMIT | CR0_CHNL, ioaddr);
- }
- spin_unlock_irqrestore (&znet->lock, flags);
-
- netif_start_queue (dev);
-
- if (znet_debug > 4)
- printk(KERN_DEBUG "%s: Transmitter queued, length %d.\n", dev->name, length);
- }
- dev_kfree_skb(skb);
- return NETDEV_TX_OK;
-}
-
-/* The ZNET interrupt handler. */
-static irqreturn_t znet_interrupt(int irq, void *dev_id)
-{
- struct net_device *dev = dev_id;
- struct znet_private *znet = netdev_priv(dev);
- int ioaddr;
- int boguscnt = 20;
- int handled = 0;
-
- spin_lock (&znet->lock);
-
- ioaddr = dev->base_addr;
-
- outb(CR0_STATUS_0, ioaddr);
- do {
- ushort status = inb(ioaddr);
- if (znet_debug > 5) {
- ushort result, rx_ptr, running;
- outb(CR0_STATUS_1, ioaddr);
- result = inw(ioaddr);
- outb(CR0_STATUS_2, ioaddr);
- rx_ptr = inw(ioaddr);
- outb(CR0_STATUS_3, ioaddr);
- running = inb(ioaddr);
- printk(KERN_DEBUG "%s: interrupt, status %02x, %04x %04x %02x serial %d.\n",
- dev->name, status, result, rx_ptr, running, boguscnt);
- }
- if ((status & SR0_INTERRUPT) == 0)
- break;
-
- handled = 1;
-
- if ((status & SR0_EVENT_MASK) == SR0_TRANSMIT_DONE ||
- (status & SR0_EVENT_MASK) == SR0_RETRANSMIT_DONE ||
- (status & SR0_EVENT_MASK) == SR0_TRANSMIT_NO_CRC_DONE) {
- int tx_status;
- outb(CR0_STATUS_1, ioaddr);
- tx_status = inw(ioaddr);
- /* It's undocumented, but tx_status seems to match the i82586. */
- if (tx_status & TX_OK) {
- dev->stats.tx_packets++;
- dev->stats.collisions += tx_status & TX_NCOL_MASK;
- } else {
- if (tx_status & (TX_LOST_CTS | TX_LOST_CRS))
- dev->stats.tx_carrier_errors++;
- if (tx_status & TX_UND_RUN)
- dev->stats.tx_fifo_errors++;
- if (!(tx_status & TX_HRT_BEAT))
- dev->stats.tx_heartbeat_errors++;
- if (tx_status & TX_MAX_COL)
- dev->stats.tx_aborted_errors++;
- /* ...and the catch-all. */
- if ((tx_status | (TX_LOST_CRS | TX_LOST_CTS | TX_UND_RUN | TX_HRT_BEAT | TX_MAX_COL)) != (TX_LOST_CRS | TX_LOST_CTS | TX_UND_RUN | TX_HRT_BEAT | TX_MAX_COL))
- dev->stats.tx_errors++;
-
- /* Transceiver may be stuck if cable
- * was removed while emitting a
- * packet. Flip it off, then on to
- * reset it. This is very empirical,
- * but it seems to work. */
-
- znet_transceiver_power (dev, 0);
- znet_transceiver_power (dev, 1);
- }
- netif_wake_queue (dev);
- }
-
- if ((status & SR0_RECEPTION) ||
- (status & SR0_EVENT_MASK) == SR0_STOP_REG_HIT) {
- znet_rx(dev);
- }
- /* Clear the interrupts we've handled. */
- outb(CR0_INT_ACK, ioaddr);
- } while (boguscnt--);
-
- spin_unlock (&znet->lock);
-
- return IRQ_RETVAL(handled);
-}
-
-static void znet_rx(struct net_device *dev)
-{
- struct znet_private *znet = netdev_priv(dev);
- int ioaddr = dev->base_addr;
- int boguscount = 1;
- short next_frame_end_offset = 0; /* Offset of next frame start. */
- short *cur_frame_end;
- short cur_frame_end_offset;
-
- outb(CR0_STATUS_2, ioaddr);
- cur_frame_end_offset = inw(ioaddr);
-
- if (cur_frame_end_offset == znet->rx_cur - znet->rx_start) {
- printk(KERN_WARNING "%s: Interrupted, but nothing to receive, offset %03x.\n",
- dev->name, cur_frame_end_offset);
- return;
- }
-
- /* Use same method as the Crynwr driver: construct a forward list in
- the same area of the backwards links we now have. This allows us to
- pass packets to the upper layers in the order they were received --
- important for fast-path sequential operations. */
- while (znet->rx_start + cur_frame_end_offset != znet->rx_cur &&
- ++boguscount < 5) {
- unsigned short hi_cnt, lo_cnt, hi_status, lo_status;
- int count, status;
-
- if (cur_frame_end_offset < 4) {
- /* Oh no, we have a special case: the frame trailer wraps around
- the end of the ring buffer. We've saved space at the end of
- the ring buffer for just this problem. */
- memcpy(znet->rx_end, znet->rx_start, 8);
- cur_frame_end_offset += (RX_BUF_SIZE/2);
- }
- cur_frame_end = znet->rx_start + cur_frame_end_offset - 4;
-
- lo_status = *cur_frame_end++;
- hi_status = *cur_frame_end++;
- status = ((hi_status & 0xff) << 8) + (lo_status & 0xff);
- lo_cnt = *cur_frame_end++;
- hi_cnt = *cur_frame_end++;
- count = ((hi_cnt & 0xff) << 8) + (lo_cnt & 0xff);
-
- if (znet_debug > 5)
- printk(KERN_DEBUG "Constructing trailer at location %03x, %04x %04x %04x %04x"
- " count %#x status %04x.\n",
- cur_frame_end_offset<<1, lo_status, hi_status, lo_cnt, hi_cnt,
- count, status);
- cur_frame_end[-4] = status;
- cur_frame_end[-3] = next_frame_end_offset;
- cur_frame_end[-2] = count;
- next_frame_end_offset = cur_frame_end_offset;
- cur_frame_end_offset -= ((count + 1)>>1) + 3;
- if (cur_frame_end_offset < 0)
- cur_frame_end_offset += RX_BUF_SIZE/2;
- }
-
- /* Now step forward through the list. */
- do {
- ushort *this_rfp_ptr = znet->rx_start + next_frame_end_offset;
- int status = this_rfp_ptr[-4];
- int pkt_len = this_rfp_ptr[-2];
-
- if (znet_debug > 5)
- printk(KERN_DEBUG "Looking at trailer ending at %04x status %04x length %03x"
- " next %04x.\n", next_frame_end_offset<<1, status, pkt_len,
- this_rfp_ptr[-3]<<1);
- /* Once again we must assume that the i82586 docs apply. */
- if ( ! (status & RX_RCV_OK)) { /* There was an error. */
- dev->stats.rx_errors++;
- if (status & RX_CRC_ERR) dev->stats.rx_crc_errors++;
- if (status & RX_ALG_ERR) dev->stats.rx_frame_errors++;
-#if 0
- if (status & 0x0200) dev->stats.rx_over_errors++; /* Wrong. */
- if (status & 0x0100) dev->stats.rx_fifo_errors++;
-#else
- /* maz : Wild guess... */
- if (status & RX_OVRRUN) dev->stats.rx_over_errors++;
-#endif
- if (status & RX_SRT_FRM) dev->stats.rx_length_errors++;
- } else if (pkt_len > 1536) {
- dev->stats.rx_length_errors++;
- } else {
- /* Malloc up new buffer. */
- struct sk_buff *skb;
-
- skb = netdev_alloc_skb(dev, pkt_len);
- if (skb == NULL) {
- if (znet_debug)
- printk(KERN_WARNING "%s: Memory squeeze, dropping packet.\n", dev->name);
- dev->stats.rx_dropped++;
- break;
- }
-
- if (&znet->rx_cur[(pkt_len+1)>>1] > znet->rx_end) {
- int semi_cnt = (znet->rx_end - znet->rx_cur)<<1;
- memcpy(skb_put(skb,semi_cnt), znet->rx_cur, semi_cnt);
- memcpy(skb_put(skb,pkt_len-semi_cnt), znet->rx_start,
- pkt_len - semi_cnt);
- } else {
- memcpy(skb_put(skb,pkt_len), znet->rx_cur, pkt_len);
- if (znet_debug > 6) {
- unsigned int *packet = (unsigned int *) skb->data;
- printk(KERN_DEBUG "Packet data is %08x %08x %08x %08x.\n", packet[0],
- packet[1], packet[2], packet[3]);
- }
- }
- skb->protocol=eth_type_trans(skb,dev);
- netif_rx(skb);
- dev->stats.rx_packets++;
- dev->stats.rx_bytes += pkt_len;
- }
- znet->rx_cur = this_rfp_ptr;
- if (znet->rx_cur >= znet->rx_end)
- znet->rx_cur -= RX_BUF_SIZE/2;
- update_stop_hit(ioaddr, (znet->rx_cur - znet->rx_start)<<1);
- next_frame_end_offset = this_rfp_ptr[-3];
- if (next_frame_end_offset == 0) /* Read all the frames? */
- break; /* Done for now */
- this_rfp_ptr = znet->rx_start + next_frame_end_offset;
- } while (--boguscount);
-
- /* If any worth-while packets have been received, dev_rint()
- has done a mark_bh(INET_BH) for us and will work on them
- when we get to the bottom-half routine. */
-}
-
-/* The inverse routine to znet_open(). */
-static int znet_close(struct net_device *dev)
-{
- int ioaddr = dev->base_addr;
-
- netif_stop_queue (dev);
-
- outb(OP0_RESET, ioaddr); /* CMD0_RESET */
-
- if (znet_debug > 1)
- printk(KERN_DEBUG "%s: Shutting down ethercard.\n", dev->name);
- /* Turn off transceiver power. */
- znet_transceiver_power (dev, 0);
-
- znet_release_resources (dev);
-
- return 0;
-}
-
-static void show_dma(struct net_device *dev)
-{
- short ioaddr = dev->base_addr;
- unsigned char stat = inb (ioaddr);
- struct znet_private *znet = netdev_priv(dev);
- unsigned long flags;
- short dma_port = ((znet->tx_dma&3)<<2) + IO_DMA2_BASE;
- unsigned addr = inb(dma_port);
- short residue;
-
- addr |= inb(dma_port) << 8;
- residue = get_dma_residue(znet->tx_dma);
-
- if (znet_debug > 1) {
- flags=claim_dma_lock();
- printk(KERN_DEBUG "Stat:%02x Addr: %04x cnt:%3x\n",
- stat, addr<<1, residue);
- release_dma_lock(flags);
- }
-}
-
-/* Initialize the hardware. We have to do this when the board is open()ed
- or when we come out of suspend mode. */
-static void hardware_init(struct net_device *dev)
-{
- unsigned long flags;
- short ioaddr = dev->base_addr;
- struct znet_private *znet = netdev_priv(dev);
-
- znet->rx_cur = znet->rx_start;
- znet->tx_cur = znet->tx_start;
-
- /* Reset the chip, and start it up. */
- outb(OP0_RESET, ioaddr);
-
- flags=claim_dma_lock();
- disable_dma(znet->rx_dma); /* reset by an interrupting task. */
- clear_dma_ff(znet->rx_dma);
- set_dma_mode(znet->rx_dma, DMA_RX_MODE);
- set_dma_addr(znet->rx_dma, isa_virt_to_bus(znet->rx_start));
- set_dma_count(znet->rx_dma, RX_BUF_SIZE);
- enable_dma(znet->rx_dma);
- /* Now set up the Tx channel. */
- disable_dma(znet->tx_dma);
- clear_dma_ff(znet->tx_dma);
- set_dma_mode(znet->tx_dma, DMA_TX_MODE);
- set_dma_addr(znet->tx_dma, isa_virt_to_bus(znet->tx_start));
- set_dma_count(znet->tx_dma, znet->tx_buf_len<<1);
- enable_dma(znet->tx_dma);
- release_dma_lock(flags);
-
- if (znet_debug > 1)
- printk(KERN_DEBUG "%s: Initializing the i82593, rx buf %p tx buf %p\n",
- dev->name, znet->rx_start,znet->tx_start);
- /* Do an empty configure command, just like the Crynwr driver. This
- resets to chip to its default values. */
- *znet->tx_cur++ = 0;
- *znet->tx_cur++ = 0;
- show_dma(dev);
- outb(OP0_CONFIGURE | CR0_CHNL, ioaddr);
-
- znet_set_multicast_list (dev);
-
- *znet->tx_cur++ = 6;
- memcpy(znet->tx_cur, dev->dev_addr, 6);
- znet->tx_cur += 3;
- show_dma(dev);
- outb(OP0_IA_SETUP | CR0_CHNL, ioaddr);
- show_dma(dev);
-
- update_stop_hit(ioaddr, 8192);
- if (znet_debug > 1) printk(KERN_DEBUG "enabling Rx.\n");
- outb(OP0_RCV_ENABLE, ioaddr);
- netif_start_queue (dev);
-}
-
-static void update_stop_hit(short ioaddr, unsigned short rx_stop_offset)
-{
- outb(OP0_SWIT_TO_PORT_1 | CR0_CHNL, ioaddr);
- if (znet_debug > 5)
- printk(KERN_DEBUG "Updating stop hit with value %02x.\n",
- (rx_stop_offset >> 6) | CR1_STOP_REG_UPDATE);
- outb((rx_stop_offset >> 6) | CR1_STOP_REG_UPDATE, ioaddr);
- outb(OP1_SWIT_TO_PORT_0, ioaddr);
-}
-
-static __exit void znet_cleanup (void)
-{
- if (znet_dev) {
- struct znet_private *znet = netdev_priv(znet_dev);
-
- unregister_netdev (znet_dev);
- kfree (znet->rx_start);
- kfree (znet->tx_start);
- free_netdev (znet_dev);
- }
-}
-
-module_init (znet_probe);
-module_exit (znet_cleanup);
diff --git a/drivers/net/ethernet/racal/Kconfig b/drivers/net/ethernet/racal/Kconfig
deleted file mode 100644
index 01969e0a9c6..00000000000
--- a/drivers/net/ethernet/racal/Kconfig
+++ /dev/null
@@ -1,33 +0,0 @@
-#
-# Racal-Interlan device configuration
-#
-
-config NET_VENDOR_RACAL
- bool "Racal-Interlan (Micom) NI devices"
- default y
- depends on ISA
- ---help---
- If you have a network (Ethernet) card belonging to this class, such
- as the NI5010, NI5210 or NI6210, say Y and read the Ethernet-HOWTO,
- available from <http://www.tldp.org/docs.html#howto>.
-
- Note that the answer to this question doesn't directly affect the
- kernel: saying N will just cause the configurator to skip all
- the questions about NI cards. If you say Y, you will be asked for
- your specific card in the following questions.
-
-if NET_VENDOR_RACAL
-
-config NI5010
- tristate "NI5010 support (EXPERIMENTAL)"
- depends on ISA && EXPERIMENTAL && BROKEN_ON_SMP
- ---help---
- If you have a network (Ethernet) card of this type, say Y and read
- the Ethernet-HOWTO, available from
- <http://www.tldp.org/docs.html#howto>. Note that this is still
- experimental code.
-
- To compile this driver as a module, choose M here. The module
- will be called ni5010.
-
-endif # NET_VENDOR_RACAL
diff --git a/drivers/net/ethernet/racal/Makefile b/drivers/net/ethernet/racal/Makefile
deleted file mode 100644
index 1e210ca1d78..00000000000
--- a/drivers/net/ethernet/racal/Makefile
+++ /dev/null
@@ -1,5 +0,0 @@
-#
-# Makefile for the Racal-Interlan network device drivers.
-#
-
-obj-$(CONFIG_NI5010) += ni5010.o
diff --git a/drivers/net/ethernet/racal/ni5010.c b/drivers/net/ethernet/racal/ni5010.c
deleted file mode 100644
index 80798222005..00000000000
--- a/drivers/net/ethernet/racal/ni5010.c
+++ /dev/null
@@ -1,771 +0,0 @@
-/* ni5010.c: A network driver for the MiCom-Interlan NI5010 ethercard.
- *
- * Copyright 1996,1997,2006 Jan-Pascal van Best and Andreas Mohr.
- *
- * This software may be used and distributed according to the terms
- * of the GNU General Public License, incorporated herein by reference.
- *
- * The authors may be reached as:
- * janpascal@vanbest.org andi@lisas.de
- *
- * Sources:
- * Donald Becker's "skeleton.c"
- * Crynwr ni5010 packet driver
- *
- * Changes:
- * v0.0: First test version
- * v0.1: First working version
- * v0.2:
- * v0.3->v0.90: Now demand setting io and irq when loading as module
- * 970430 v0.91: modified for Linux 2.1.14
- * v0.92: Implemented Andreas' (better) NI5010 probe
- * 970503 v0.93: Fixed auto-irq failure on warm reboot (JB)
- * 970623 v1.00: First kernel version (AM)
- * 970814 v1.01: Added detection of onboard receive buffer size (AM)
- * 060611 v1.02: slight cleanup: email addresses, driver modernization.
- * Bugs:
- * - not SMP-safe (no locking of I/O accesses)
- * - Note that you have to patch ifconfig for the new /proc/net/dev
- * format. It gives incorrect stats otherwise.
- *
- * To do:
- * Fix all bugs :-)
- * Move some stuff to chipset_init()
- * Handle xmt errors other than collisions
- * Complete merge with Andreas' driver
- * Implement ring buffers (Is this useful? You can't squeeze
- * too many packet in a 2k buffer!)
- * Implement DMA (Again, is this useful? Some docs say DMA is
- * slower than programmed I/O)
- *
- * Compile with:
- * gcc -O2 -fomit-frame-pointer -m486 -D__KERNEL__ \
- * -DMODULE -c ni5010.c
- *
- * Insert with e.g.:
- * insmod ni5010.ko io=0x300 irq=5
- */
-
-#include <linux/module.h>
-#include <linux/kernel.h>
-#include <linux/string.h>
-#include <linux/errno.h>
-#include <linux/ioport.h>
-#include <linux/interrupt.h>
-#include <linux/delay.h>
-#include <linux/init.h>
-#include <linux/bitops.h>
-#include <asm/io.h>
-#include <asm/dma.h>
-
-#include <linux/netdevice.h>
-#include <linux/etherdevice.h>
-#include <linux/skbuff.h>
-
-#include "ni5010.h"
-
-static const char boardname[] = "NI5010";
-static char version[] __initdata =
- "ni5010.c: v1.02 20060611 Jan-Pascal van Best and Andreas Mohr\n";
-
-/* bufsize_rcv == 0 means autoprobing */
-static unsigned int bufsize_rcv;
-
-#define JUMPERED_INTERRUPTS /* IRQ line jumpered on board */
-#undef JUMPERED_DMA /* No DMA used */
-#undef FULL_IODETECT /* Only detect in portlist */
-
-#ifndef FULL_IODETECT
-/* A zero-terminated list of I/O addresses to be probed. */
-static unsigned int ports[] __initdata =
- { 0x300, 0x320, 0x340, 0x360, 0x380, 0x3a0, 0 };
-#endif
-
-/* Use 0 for production, 1 for verification, >2 for debug */
-#ifndef NI5010_DEBUG
-#define NI5010_DEBUG 0
-#endif
-
-/* Information that needs to be kept for each board. */
-struct ni5010_local {
- int o_pkt_size;
- spinlock_t lock;
-};
-
-/* Index to functions, as function prototypes. */
-
-static int ni5010_probe1(struct net_device *dev, int ioaddr);
-static int ni5010_open(struct net_device *dev);
-static int ni5010_send_packet(struct sk_buff *skb, struct net_device *dev);
-static irqreturn_t ni5010_interrupt(int irq, void *dev_id);
-static void ni5010_rx(struct net_device *dev);
-static void ni5010_timeout(struct net_device *dev);
-static int ni5010_close(struct net_device *dev);
-static void ni5010_set_multicast_list(struct net_device *dev);
-static void reset_receiver(struct net_device *dev);
-
-static int process_xmt_interrupt(struct net_device *dev);
-#define tx_done(dev) 1
-static void hardware_send_packet(struct net_device *dev, char *buf, int length, int pad);
-static void chipset_init(struct net_device *dev, int startp);
-static void dump_packet(void *buf, int len);
-static void ni5010_show_registers(struct net_device *dev);
-
-static int io;
-static int irq;
-
-struct net_device * __init ni5010_probe(int unit)
-{
- struct net_device *dev = alloc_etherdev(sizeof(struct ni5010_local));
- int *port;
- int err = 0;
-
- if (!dev)
- return ERR_PTR(-ENOMEM);
-
- if (unit >= 0) {
- sprintf(dev->name, "eth%d", unit);
- netdev_boot_setup_check(dev);
- io = dev->base_addr;
- irq = dev->irq;
- }
-
- PRINTK2((KERN_DEBUG "%s: Entering ni5010_probe\n", dev->name));
-
- if (io > 0x1ff) { /* Check a single specified location. */
- err = ni5010_probe1(dev, io);
- } else if (io != 0) { /* Don't probe at all. */
- err = -ENXIO;
- } else {
-#ifdef FULL_IODETECT
- for (io=0x200; io<0x400 && ni5010_probe1(dev, io) ; io+=0x20)
- ;
- if (io == 0x400)
- err = -ENODEV;
-
-#else
- for (port = ports; *port && ni5010_probe1(dev, *port); port++)
- ;
- if (!*port)
- err = -ENODEV;
-#endif /* FULL_IODETECT */
- }
- if (err)
- goto out;
- err = register_netdev(dev);
- if (err)
- goto out1;
- return dev;
-out1:
- release_region(dev->base_addr, NI5010_IO_EXTENT);
-out:
- free_netdev(dev);
- return ERR_PTR(err);
-}
-
-static inline int rd_port(int ioaddr)
-{
- inb(IE_RBUF);
- return inb(IE_SAPROM);
-}
-
-static void __init trigger_irq(int ioaddr)
-{
- outb(0x00, EDLC_RESET); /* Clear EDLC hold RESET state */
- outb(0x00, IE_RESET); /* Board reset */
- outb(0x00, EDLC_XMASK); /* Disable all Xmt interrupts */
- outb(0x00, EDLC_RMASK); /* Disable all Rcv interrupt */
- outb(0xff, EDLC_XCLR); /* Clear all pending Xmt interrupts */
- outb(0xff, EDLC_RCLR); /* Clear all pending Rcv interrupts */
- /*
- * Transmit packet mode: Ignore parity, Power xcvr,
- * Enable loopback
- */
- outb(XMD_IG_PAR | XMD_T_MODE | XMD_LBC, EDLC_XMODE);
- outb(RMD_BROADCAST, EDLC_RMODE); /* Receive normal&broadcast */
- outb(XM_ALL, EDLC_XMASK); /* Enable all Xmt interrupts */
- udelay(50); /* FIXME: Necessary? */
- outb(MM_EN_XMT|MM_MUX, IE_MMODE); /* Start transmission */
-}
-
-static const struct net_device_ops ni5010_netdev_ops = {
- .ndo_open = ni5010_open,
- .ndo_stop = ni5010_close,
- .ndo_start_xmit = ni5010_send_packet,
- .ndo_set_rx_mode = ni5010_set_multicast_list,
- .ndo_tx_timeout = ni5010_timeout,
- .ndo_validate_addr = eth_validate_addr,
- .ndo_set_mac_address = eth_mac_addr,
- .ndo_change_mtu = eth_change_mtu,
-};
-
-/*
- * This is the real probe routine. Linux has a history of friendly device
- * probes on the ISA bus. A good device probes avoids doing writes, and
- * verifies that the correct device exists and functions.
- */
-
-static int __init ni5010_probe1(struct net_device *dev, int ioaddr)
-{
- static unsigned version_printed;
- struct ni5010_local *lp;
- int i;
- unsigned int data = 0;
- int boguscount = 40;
- int err = -ENODEV;
-
- dev->base_addr = ioaddr;
- dev->irq = irq;
-
- if (!request_region(ioaddr, NI5010_IO_EXTENT, boardname))
- return -EBUSY;
-
- /*
- * This is no "official" probe method, I've rather tested which
- * probe works best with my seven NI5010 cards
- * (they have very different serial numbers)
- * Suggestions or failure reports are very, very welcome !
- * But I think it is a relatively good probe method
- * since it doesn't use any "outb"
- * It should be nearly 100% reliable !
- * well-known WARNING: this probe method (like many others)
- * will hang the system if a NE2000 card region is probed !
- *
- * - Andreas
- */
-
- PRINTK2((KERN_DEBUG "%s: entering ni5010_probe1(%#3x)\n",
- dev->name, ioaddr));
-
- if (inb(ioaddr+0) == 0xff)
- goto out;
-
- while ( (rd_port(ioaddr) & rd_port(ioaddr) & rd_port(ioaddr) &
- rd_port(ioaddr) & rd_port(ioaddr) & rd_port(ioaddr)) != 0xff)
- {
- if (boguscount-- == 0)
- goto out;
- }
-
- PRINTK2((KERN_DEBUG "%s: I/O #1 passed!\n", dev->name));
-
- for (i=0; i<32; i++)
- if ( (data = rd_port(ioaddr)) != 0xff) break;
- if (data==0xff)
- goto out;
-
- PRINTK2((KERN_DEBUG "%s: I/O #2 passed!\n", dev->name));
-
- if ((data != SA_ADDR0) || (rd_port(ioaddr) != SA_ADDR1) ||
- (rd_port(ioaddr) != SA_ADDR2))
- goto out;
-
- for (i=0; i<4; i++)
- rd_port(ioaddr);
-
- if ( (rd_port(ioaddr) != NI5010_MAGICVAL1) ||
- (rd_port(ioaddr) != NI5010_MAGICVAL2) )
- goto out;
-
- PRINTK2((KERN_DEBUG "%s: I/O #3 passed!\n", dev->name));
-
- if (NI5010_DEBUG && version_printed++ == 0)
- printk(KERN_INFO "%s", version);
-
- printk("NI5010 ethercard probe at 0x%x: ", ioaddr);
-
- dev->base_addr = ioaddr;
-
- for (i=0; i<6; i++) {
- outw(i, IE_GP);
- dev->dev_addr[i] = inb(IE_SAPROM);
- }
- printk("%pM ", dev->dev_addr);
-
- PRINTK2((KERN_DEBUG "%s: I/O #4 passed!\n", dev->name));
-
-#ifdef JUMPERED_INTERRUPTS
- if (dev->irq == 0xff)
- ;
- else if (dev->irq < 2) {
- unsigned long irq_mask;
-
- PRINTK2((KERN_DEBUG "%s: I/O #5 passed!\n", dev->name));
-
- irq_mask = probe_irq_on();
- trigger_irq(ioaddr);
- mdelay(20);
- dev->irq = probe_irq_off(irq_mask);
-
- PRINTK2((KERN_DEBUG "%s: I/O #6 passed!\n", dev->name));
-
- if (dev->irq == 0) {
- err = -EAGAIN;
- printk(KERN_WARNING "%s: no IRQ found!\n", dev->name);
- goto out;
- }
- PRINTK2((KERN_DEBUG "%s: I/O #7 passed!\n", dev->name));
- } else if (dev->irq == 2) {
- dev->irq = 9;
- }
-#endif /* JUMPERED_INTERRUPTS */
- PRINTK2((KERN_DEBUG "%s: I/O #9 passed!\n", dev->name));
-
- /* DMA is not supported (yet?), so no use detecting it */
- lp = netdev_priv(dev);
-
- spin_lock_init(&lp->lock);
-
- PRINTK2((KERN_DEBUG "%s: I/O #10 passed!\n", dev->name));
-
-/* get the size of the onboard receive buffer
- * higher addresses than bufsize are wrapped into real buffer
- * i.e. data for offs. 0x801 is written to 0x1 with a 2K onboard buffer
- */
- if (!bufsize_rcv) {
- outb(1, IE_MMODE); /* Put Rcv buffer on system bus */
- outw(0, IE_GP); /* Point GP at start of packet */
- outb(0, IE_RBUF); /* set buffer byte 0 to 0 */
- for (i = 1; i < 0xff; i++) {
- outw(i << 8, IE_GP); /* Point GP at packet size to be tested */
- outb(i, IE_RBUF);
- outw(0x0, IE_GP); /* Point GP at start of packet */
- data = inb(IE_RBUF);
- if (data == i) break;
- }
- bufsize_rcv = i << 8;
- outw(0, IE_GP); /* Point GP at start of packet */
- outb(0, IE_RBUF); /* set buffer byte 0 to 0 again */
- }
- printk("-> bufsize rcv/xmt=%d/%d\n", bufsize_rcv, NI5010_BUFSIZE);
-
- dev->netdev_ops = &ni5010_netdev_ops;
- dev->watchdog_timeo = HZ/20;
-
- dev->flags &= ~IFF_MULTICAST; /* Multicast doesn't work */
-
- /* Shut up the ni5010 */
- outb(0, EDLC_RMASK); /* Mask all receive interrupts */
- outb(0, EDLC_XMASK); /* Mask all xmit interrupts */
- outb(0xff, EDLC_RCLR); /* Kill all pending rcv interrupts */
- outb(0xff, EDLC_XCLR); /* Kill all pending xmt interrupts */
-
- printk(KERN_INFO "%s: NI5010 found at 0x%x, using IRQ %d", dev->name, ioaddr, dev->irq);
- if (dev->dma)
- printk(" & DMA %d", dev->dma);
- printk(".\n");
- return 0;
-out:
- release_region(dev->base_addr, NI5010_IO_EXTENT);
- return err;
-}
-
-/*
- * Open/initialize the board. This is called (in the current kernel)
- * sometime after booting when the 'ifconfig' program is run.
- *
- * This routine should set everything up anew at each open, even
- * registers that "should" only need to be set once at boot, so that
- * there is a non-reboot way to recover if something goes wrong.
- */
-
-static int ni5010_open(struct net_device *dev)
-{
- int ioaddr = dev->base_addr;
- int i;
-
- PRINTK2((KERN_DEBUG "%s: entering ni5010_open()\n", dev->name));
-
- if (request_irq(dev->irq, ni5010_interrupt, 0, boardname, dev)) {
- printk(KERN_WARNING "%s: Cannot get irq %#2x\n", dev->name, dev->irq);
- return -EAGAIN;
- }
- PRINTK3((KERN_DEBUG "%s: passed open() #1\n", dev->name));
- /*
- * Always allocate the DMA channel after the IRQ,
- * and clean up on failure.
- */
-#ifdef JUMPERED_DMA
- if (request_dma(dev->dma, cardname)) {
- printk(KERN_WARNING "%s: Cannot get dma %#2x\n", dev->name, dev->dma);
- free_irq(dev->irq, NULL);
- return -EAGAIN;
- }
-#endif /* JUMPERED_DMA */
-
- PRINTK3((KERN_DEBUG "%s: passed open() #2\n", dev->name));
- /* Reset the hardware here. Don't forget to set the station address. */
-
- outb(RS_RESET, EDLC_RESET); /* Hold up EDLC_RESET while configing board */
- outb(0, IE_RESET); /* Hardware reset of ni5010 board */
- outb(XMD_LBC, EDLC_XMODE); /* Only loopback xmits */
-
- PRINTK3((KERN_DEBUG "%s: passed open() #3\n", dev->name));
- /* Set the station address */
- for(i = 0;i < 6; i++) {
- outb(dev->dev_addr[i], EDLC_ADDR + i);
- }
-
- PRINTK3((KERN_DEBUG "%s: Initialising ni5010\n", dev->name));
- outb(0, EDLC_XMASK); /* No xmit interrupts for now */
- outb(XMD_IG_PAR | XMD_T_MODE | XMD_LBC, EDLC_XMODE);
- /* Normal packet xmit mode */
- outb(0xff, EDLC_XCLR); /* Clear all pending xmit interrupts */
- outb(RMD_BROADCAST, EDLC_RMODE);
- /* Receive broadcast and normal packets */
- reset_receiver(dev); /* Ready ni5010 for receiving packets */
-
- outb(0, EDLC_RESET); /* Un-reset the ni5010 */
-
- netif_start_queue(dev);
-
- if (NI5010_DEBUG) ni5010_show_registers(dev);
-
- PRINTK((KERN_DEBUG "%s: open successful\n", dev->name));
- return 0;
-}
-
-static void reset_receiver(struct net_device *dev)
-{
- int ioaddr = dev->base_addr;
-
- PRINTK3((KERN_DEBUG "%s: resetting receiver\n", dev->name));
- outw(0, IE_GP); /* Receive packet at start of buffer */
- outb(0xff, EDLC_RCLR); /* Clear all pending rcv interrupts */
- outb(0, IE_MMODE); /* Put EDLC to rcv buffer */
- outb(MM_EN_RCV, IE_MMODE); /* Enable rcv */
- outb(0xff, EDLC_RMASK); /* Enable all rcv interrupts */
-}
-
-static void ni5010_timeout(struct net_device *dev)
-{
- printk(KERN_WARNING "%s: transmit timed out, %s?\n", dev->name,
- tx_done(dev) ? "IRQ conflict" : "network cable problem");
- /* Try to restart the adaptor. */
- /* FIXME: Give it a real kick here */
- chipset_init(dev, 1);
- dev->trans_start = jiffies; /* prevent tx timeout */
- netif_wake_queue(dev);
-}
-
-static int ni5010_send_packet(struct sk_buff *skb, struct net_device *dev)
-{
- int length = ETH_ZLEN < skb->len ? skb->len : ETH_ZLEN;
-
- PRINTK2((KERN_DEBUG "%s: entering ni5010_send_packet\n", dev->name));
-
- /*
- * Block sending
- */
-
- netif_stop_queue(dev);
- hardware_send_packet(dev, (unsigned char *)skb->data, skb->len, length-skb->len);
- dev_kfree_skb (skb);
- return NETDEV_TX_OK;
-}
-
-/*
- * The typical workload of the driver:
- * Handle the network interface interrupts.
- */
-static irqreturn_t ni5010_interrupt(int irq, void *dev_id)
-{
- struct net_device *dev = dev_id;
- struct ni5010_local *lp;
- int ioaddr, status;
- int xmit_was_error = 0;
-
- PRINTK2((KERN_DEBUG "%s: entering ni5010_interrupt\n", dev->name));
-
- ioaddr = dev->base_addr;
- lp = netdev_priv(dev);
-
- spin_lock(&lp->lock);
- status = inb(IE_ISTAT);
- PRINTK3((KERN_DEBUG "%s: IE_ISTAT = %#02x\n", dev->name, status));
-
- if ((status & IS_R_INT) == 0) ni5010_rx(dev);
-
- if ((status & IS_X_INT) == 0) {
- xmit_was_error = process_xmt_interrupt(dev);
- }
-
- if ((status & IS_DMA_INT) == 0) {
- PRINTK((KERN_DEBUG "%s: DMA complete (?)\n", dev->name));
- outb(0, IE_DMA_RST); /* Reset DMA int */
- }
-
- if (!xmit_was_error)
- reset_receiver(dev);
- spin_unlock(&lp->lock);
- return IRQ_HANDLED;
-}
-
-
-static void dump_packet(void *buf, int len)
-{
- int i;
-
- printk(KERN_DEBUG "Packet length = %#4x\n", len);
- for (i = 0; i < len; i++){
- if (i % 16 == 0) printk(KERN_DEBUG "%#4.4x", i);
- if (i % 2 == 0) printk(" ");
- printk("%2.2x", ((unsigned char *)buf)[i]);
- if (i % 16 == 15) printk("\n");
- }
- printk("\n");
-}
-
-/* We have a good packet, get it out of the buffer. */
-static void ni5010_rx(struct net_device *dev)
-{
- int ioaddr = dev->base_addr;
- unsigned char rcv_stat;
- struct sk_buff *skb;
- int i_pkt_size;
-
- PRINTK2((KERN_DEBUG "%s: entering ni5010_rx()\n", dev->name));
-
- rcv_stat = inb(EDLC_RSTAT);
- PRINTK3((KERN_DEBUG "%s: EDLC_RSTAT = %#2x\n", dev->name, rcv_stat));
-
- if ( (rcv_stat & RS_VALID_BITS) != RS_PKT_OK) {
- PRINTK((KERN_INFO "%s: receive error.\n", dev->name));
- dev->stats.rx_errors++;
- if (rcv_stat & RS_RUNT) dev->stats.rx_length_errors++;
- if (rcv_stat & RS_ALIGN) dev->stats.rx_frame_errors++;
- if (rcv_stat & RS_CRC_ERR) dev->stats.rx_crc_errors++;
- if (rcv_stat & RS_OFLW) dev->stats.rx_fifo_errors++;
- outb(0xff, EDLC_RCLR); /* Clear the interrupt */
- return;
- }
-
- outb(0xff, EDLC_RCLR); /* Clear the interrupt */
-
- i_pkt_size = inw(IE_RCNT);
- if (i_pkt_size > ETH_FRAME_LEN || i_pkt_size < 10 ) {
- PRINTK((KERN_DEBUG "%s: Packet size error, packet size = %#4.4x\n",
- dev->name, i_pkt_size));
- dev->stats.rx_errors++;
- dev->stats.rx_length_errors++;
- return;
- }
-
- /* Malloc up new buffer. */
- skb = netdev_alloc_skb(dev, i_pkt_size + 3);
- if (skb == NULL) {
- printk(KERN_WARNING "%s: Memory squeeze, dropping packet.\n", dev->name);
- dev->stats.rx_dropped++;
- return;
- }
-
- skb_reserve(skb, 2);
-
- /* Read packet into buffer */
- outb(MM_MUX, IE_MMODE); /* Rcv buffer to system bus */
- outw(0, IE_GP); /* Seek to beginning of packet */
- insb(IE_RBUF, skb_put(skb, i_pkt_size), i_pkt_size);
-
- if (NI5010_DEBUG >= 4)
- dump_packet(skb->data, skb->len);
-
- skb->protocol = eth_type_trans(skb,dev);
- netif_rx(skb);
- dev->stats.rx_packets++;
- dev->stats.rx_bytes += i_pkt_size;
-
- PRINTK2((KERN_DEBUG "%s: Received packet, size=%#4.4x\n",
- dev->name, i_pkt_size));
-}
-
-static int process_xmt_interrupt(struct net_device *dev)
-{
- struct ni5010_local *lp = netdev_priv(dev);
- int ioaddr = dev->base_addr;
- int xmit_stat;
-
- PRINTK2((KERN_DEBUG "%s: entering process_xmt_interrupt\n", dev->name));
-
- xmit_stat = inb(EDLC_XSTAT);
- PRINTK3((KERN_DEBUG "%s: EDLC_XSTAT = %2.2x\n", dev->name, xmit_stat));
-
- outb(0, EDLC_XMASK); /* Disable xmit IRQ's */
- outb(0xff, EDLC_XCLR); /* Clear all pending xmit IRQ's */
-
- if (xmit_stat & XS_COLL){
- PRINTK((KERN_DEBUG "%s: collision detected, retransmitting\n",
- dev->name));
- outw(NI5010_BUFSIZE - lp->o_pkt_size, IE_GP);
- /* outb(0, IE_MMODE); */ /* xmt buf on sysbus FIXME: needed ? */
- outb(MM_EN_XMT | MM_MUX, IE_MMODE);
- outb(XM_ALL, EDLC_XMASK); /* Enable xmt IRQ's */
- dev->stats.collisions++;
- return 1;
- }
-
- /* FIXME: handle other xmt error conditions */
-
- dev->stats.tx_packets++;
- dev->stats.tx_bytes += lp->o_pkt_size;
- netif_wake_queue(dev);
-
- PRINTK2((KERN_DEBUG "%s: sent packet, size=%#4.4x\n",
- dev->name, lp->o_pkt_size));
-
- return 0;
-}
-
-/* The inverse routine to ni5010_open(). */
-static int ni5010_close(struct net_device *dev)
-{
- int ioaddr = dev->base_addr;
-
- PRINTK2((KERN_DEBUG "%s: entering ni5010_close\n", dev->name));
-#ifdef JUMPERED_INTERRUPTS
- free_irq(dev->irq, NULL);
-#endif
- /* Put card in held-RESET state */
- outb(0, IE_MMODE);
- outb(RS_RESET, EDLC_RESET);
-
- netif_stop_queue(dev);
-
- PRINTK((KERN_DEBUG "%s: %s closed down\n", dev->name, boardname));
- return 0;
-
-}
-
-/* Set or clear the multicast filter for this adaptor.
- num_addrs == -1 Promiscuous mode, receive all packets
- num_addrs == 0 Normal mode, clear multicast list
- num_addrs > 0 Multicast mode, receive normal and MC packets, and do
- best-effort filtering.
-*/
-static void ni5010_set_multicast_list(struct net_device *dev)
-{
- short ioaddr = dev->base_addr;
-
- PRINTK2((KERN_DEBUG "%s: entering set_multicast_list\n", dev->name));
-
- if (dev->flags & IFF_PROMISC || dev->flags & IFF_ALLMULTI ||
- !netdev_mc_empty(dev)) {
- outb(RMD_PROMISC, EDLC_RMODE); /* Enable promiscuous mode */
- PRINTK((KERN_DEBUG "%s: Entering promiscuous mode\n", dev->name));
- } else {
- PRINTK((KERN_DEBUG "%s: Entering broadcast mode\n", dev->name));
- outb(RMD_BROADCAST, EDLC_RMODE); /* Disable promiscuous mode, use normal mode */
- }
-}
-
-static void hardware_send_packet(struct net_device *dev, char *buf, int length, int pad)
-{
- struct ni5010_local *lp = netdev_priv(dev);
- int ioaddr = dev->base_addr;
- unsigned long flags;
- unsigned int buf_offs;
-
- PRINTK2((KERN_DEBUG "%s: entering hardware_send_packet\n", dev->name));
-
- if (length > ETH_FRAME_LEN) {
- PRINTK((KERN_WARNING "%s: packet too large, not possible\n",
- dev->name));
- return;
- }
-
- if (NI5010_DEBUG) ni5010_show_registers(dev);
-
- if (inb(IE_ISTAT) & IS_EN_XMT) {
- PRINTK((KERN_WARNING "%s: sending packet while already transmitting, not possible\n",
- dev->name));
- return;
- }
-
- if (NI5010_DEBUG > 3) dump_packet(buf, length);
-
- buf_offs = NI5010_BUFSIZE - length - pad;
-
- spin_lock_irqsave(&lp->lock, flags);
- lp->o_pkt_size = length + pad;
-
- outb(0, EDLC_RMASK); /* Mask all receive interrupts */
- outb(0, IE_MMODE); /* Put Xmit buffer on system bus */
- outb(0xff, EDLC_RCLR); /* Clear out pending rcv interrupts */
-
- outw(buf_offs, IE_GP); /* Point GP at start of packet */
- outsb(IE_XBUF, buf, length); /* Put data in buffer */
- while(pad--)
- outb(0, IE_XBUF);
-
- outw(buf_offs, IE_GP); /* Rewrite where packet starts */
-
- /* should work without that outb() (Crynwr used it) */
- /*outb(MM_MUX, IE_MMODE);*/ /* Xmt buffer to EDLC bus */
- outb(MM_EN_XMT | MM_MUX, IE_MMODE); /* Begin transmission */
- outb(XM_ALL, EDLC_XMASK); /* Cause interrupt after completion or fail */
-
- spin_unlock_irqrestore(&lp->lock, flags);
-
- netif_wake_queue(dev);
-
- if (NI5010_DEBUG) ni5010_show_registers(dev);
-}
-
-static void chipset_init(struct net_device *dev, int startp)
-{
- /* FIXME: Move some stuff here */
- PRINTK3((KERN_DEBUG "%s: doing NOTHING in chipset_init\n", dev->name));
-}
-
-static void ni5010_show_registers(struct net_device *dev)
-{
- int ioaddr = dev->base_addr;
-
- PRINTK3((KERN_DEBUG "%s: XSTAT %#2.2x\n", dev->name, inb(EDLC_XSTAT)));
- PRINTK3((KERN_DEBUG "%s: XMASK %#2.2x\n", dev->name, inb(EDLC_XMASK)));
- PRINTK3((KERN_DEBUG "%s: RSTAT %#2.2x\n", dev->name, inb(EDLC_RSTAT)));
- PRINTK3((KERN_DEBUG "%s: RMASK %#2.2x\n", dev->name, inb(EDLC_RMASK)));
- PRINTK3((KERN_DEBUG "%s: RMODE %#2.2x\n", dev->name, inb(EDLC_RMODE)));
- PRINTK3((KERN_DEBUG "%s: XMODE %#2.2x\n", dev->name, inb(EDLC_XMODE)));
- PRINTK3((KERN_DEBUG "%s: ISTAT %#2.2x\n", dev->name, inb(IE_ISTAT)));
-}
-
-#ifdef MODULE
-static struct net_device *dev_ni5010;
-
-module_param(io, int, 0);
-module_param(irq, int, 0);
-MODULE_PARM_DESC(io, "ni5010 I/O base address");
-MODULE_PARM_DESC(irq, "ni5010 IRQ number");
-
-static int __init ni5010_init_module(void)
-{
- PRINTK2((KERN_DEBUG "%s: entering init_module\n", boardname));
- /*
- if(io <= 0 || irq == 0){
- printk(KERN_WARNING "%s: Autoprobing not allowed for modules.\n", boardname);
- printk(KERN_WARNING "%s: Set symbols 'io' and 'irq'\n", boardname);
- return -EINVAL;
- }
- */
- if (io <= 0){
- printk(KERN_WARNING "%s: Autoprobing for modules is hazardous, trying anyway..\n", boardname);
- }
-
- PRINTK2((KERN_DEBUG "%s: init_module irq=%#2x, io=%#3x\n", boardname, irq, io));
- dev_ni5010 = ni5010_probe(-1);
- if (IS_ERR(dev_ni5010))
- return PTR_ERR(dev_ni5010);
- return 0;
-}
-
-static void __exit ni5010_cleanup_module(void)
-{
- PRINTK2((KERN_DEBUG "%s: entering cleanup_module\n", boardname));
- unregister_netdev(dev_ni5010);
- release_region(dev_ni5010->base_addr, NI5010_IO_EXTENT);
- free_netdev(dev_ni5010);
-}
-module_init(ni5010_init_module);
-module_exit(ni5010_cleanup_module);
-#endif /* MODULE */
-MODULE_LICENSE("GPL");
diff --git a/drivers/net/ethernet/racal/ni5010.h b/drivers/net/ethernet/racal/ni5010.h
deleted file mode 100644
index e10e717fcd7..00000000000
--- a/drivers/net/ethernet/racal/ni5010.h
+++ /dev/null
@@ -1,144 +0,0 @@
-/*
- * Racal-Interlan ni5010 Ethernet definitions
- *
- * This is an extension to the Linux operating system, and is covered by the
- * same GNU General Public License that covers that work.
- *
- * copyrights (c) 1996 by Jan-Pascal van Best (jvbest@wi.leidenuniv.nl)
- *
- * I have done a look in the following sources:
- * crynwr-packet-driver by Russ Nelson
- */
-
-#define NI5010_BUFSIZE 2048 /* number of bytes in a buffer */
-
-#define NI5010_MAGICVAL0 0x00 /* magic-values for ni5010 card */
-#define NI5010_MAGICVAL1 0x55
-#define NI5010_MAGICVAL2 0xAA
-
-#define SA_ADDR0 0x02
-#define SA_ADDR1 0x07
-#define SA_ADDR2 0x01
-
-/* The number of low I/O ports used by the ni5010 ethercard. */
-#define NI5010_IO_EXTENT 32
-
-#define PRINTK(x) if (NI5010_DEBUG) printk x
-#define PRINTK2(x) if (NI5010_DEBUG>=2) printk x
-#define PRINTK3(x) if (NI5010_DEBUG>=3) printk x
-
-/* The various IE command registers */
-#define EDLC_XSTAT (ioaddr + 0x00) /* EDLC transmit csr */
-#define EDLC_XCLR (ioaddr + 0x00) /* EDLC transmit "Clear IRQ" */
-#define EDLC_XMASK (ioaddr + 0x01) /* EDLC transmit "IRQ Masks" */
-#define EDLC_RSTAT (ioaddr + 0x02) /* EDLC receive csr */
-#define EDLC_RCLR (ioaddr + 0x02) /* EDLC receive "Clear IRQ" */
-#define EDLC_RMASK (ioaddr + 0x03) /* EDLC receive "IRQ Masks" */
-#define EDLC_XMODE (ioaddr + 0x04) /* EDLC transmit Mode */
-#define EDLC_RMODE (ioaddr + 0x05) /* EDLC receive Mode */
-#define EDLC_RESET (ioaddr + 0x06) /* EDLC RESET register */
-#define EDLC_TDR1 (ioaddr + 0x07) /* "Time Domain Reflectometry" reg1 */
-#define EDLC_ADDR (ioaddr + 0x08) /* EDLC station address, 6 bytes */
- /* 0x0E doesn't exist for r/w */
-#define EDLC_TDR2 (ioaddr + 0x0f) /* "Time Domain Reflectometry" reg2 */
-#define IE_GP (ioaddr + 0x10) /* GP pointer (word register) */
- /* 0x11 is 2nd byte of GP Pointer */
-#define IE_RCNT (ioaddr + 0x10) /* Count of bytes in rcv'd packet */
- /* 0x11 is 2nd byte of "Byte Count" */
-#define IE_MMODE (ioaddr + 0x12) /* Memory Mode register */
-#define IE_DMA_RST (ioaddr + 0x13) /* IE DMA Reset. write only */
-#define IE_ISTAT (ioaddr + 0x13) /* IE Interrupt Status. read only */
-#define IE_RBUF (ioaddr + 0x14) /* IE Receive Buffer port */
-#define IE_XBUF (ioaddr + 0x15) /* IE Transmit Buffer port */
-#define IE_SAPROM (ioaddr + 0x16) /* window on station addr prom */
-#define IE_RESET (ioaddr + 0x17) /* any write causes Board Reset */
-
-/* bits in EDLC_XSTAT, interrupt clear on write, status when read */
-#define XS_TPOK 0x80 /* transmit packet successful */
-#define XS_CS 0x40 /* carrier sense */
-#define XS_RCVD 0x20 /* transmitted packet received */
-#define XS_SHORT 0x10 /* transmission media is shorted */
-#define XS_UFLW 0x08 /* underflow. iff failed board */
-#define XS_COLL 0x04 /* collision occurred */
-#define XS_16COLL 0x02 /* 16th collision occurred */
-#define XS_PERR 0x01 /* parity error */
-
-#define XS_CLR_UFLW 0x08 /* clear underflow */
-#define XS_CLR_COLL 0x04 /* clear collision */
-#define XS_CLR_16COLL 0x02 /* clear 16th collision */
-#define XS_CLR_PERR 0x01 /* clear parity error */
-
-/* bits in EDLC_XMASK, mask/enable transmit interrupts. register is r/w */
-#define XM_TPOK 0x80 /* =1 to enable Xmt Pkt OK interrupts */
-#define XM_RCVD 0x20 /* =1 to enable Xmt Pkt Rcvd ints */
-#define XM_UFLW 0x08 /* =1 to enable Xmt Underflow ints */
-#define XM_COLL 0x04 /* =1 to enable Xmt Collision ints */
-#define XM_COLL16 0x02 /* =1 to enable Xmt 16th Coll ints */
-#define XM_PERR 0x01 /* =1 to enable Xmt Parity Error ints */
- /* note: always clear this bit */
-#define XM_ALL (XM_TPOK | XM_RCVD | XM_UFLW | XM_COLL | XM_COLL16)
-
-/* bits in EDLC_RSTAT, interrupt clear on write, status when read */
-#define RS_PKT_OK 0x80 /* received good packet */
-#define RS_RST_PKT 0x10 /* RESET packet received */
-#define RS_RUNT 0x08 /* Runt Pkt rcvd. Len < 64 Bytes */
-#define RS_ALIGN 0x04 /* Alignment error. not 8 bit aligned */
-#define RS_CRC_ERR 0x02 /* Bad CRC on rcvd pkt */
-#define RS_OFLW 0x01 /* overflow for rcv FIFO */
-#define RS_VALID_BITS ( RS_PKT_OK | RS_RST_PKT | RS_RUNT | RS_ALIGN | RS_CRC_ERR | RS_OFLW )
- /* all valid RSTAT bits */
-
-#define RS_CLR_PKT_OK 0x80 /* clear rcvd packet interrupt */
-#define RS_CLR_RST_PKT 0x10 /* clear RESET packet received */
-#define RS_CLR_RUNT 0x08 /* clear Runt Pckt received */
-#define RS_CLR_ALIGN 0x04 /* clear Alignment error */
-#define RS_CLR_CRC_ERR 0x02 /* clear CRC error */
-#define RS_CLR_OFLW 0x01 /* clear rcv FIFO Overflow */
-
-/* bits in EDLC_RMASK, mask/enable receive interrupts. register is r/w */
-#define RM_PKT_OK 0x80 /* =1 to enable rcvd good packet ints */
-#define RM_RST_PKT 0x10 /* =1 to enable RESET packet ints */
-#define RM_RUNT 0x08 /* =1 to enable Runt Pkt rcvd ints */
-#define RM_ALIGN 0x04 /* =1 to enable Alignment error ints */
-#define RM_CRC_ERR 0x02 /* =1 to enable Bad CRC error ints */
-#define RM_OFLW 0x01 /* =1 to enable overflow error ints */
-
-/* bits in EDLC_RMODE, set Receive Packet mode. register is r/w */
-#define RMD_TEST 0x80 /* =1 for Chip testing. normally 0 */
-#define RMD_ADD_SIZ 0x10 /* =1 5-byte addr match. normally 0 */
-#define RMD_EN_RUNT 0x08 /* =1 enable runt rcv. normally 0 */
-#define RMD_EN_RST 0x04 /* =1 to rcv RESET pkt. normally 0 */
-
-#define RMD_PROMISC 0x03 /* receive *all* packets. unusual */
-#define RMD_MULTICAST 0x02 /* receive multicasts too. unusual */
-#define RMD_BROADCAST 0x01 /* receive broadcasts & normal. usual */
-#define RMD_NO_PACKETS 0x00 /* don't receive any packets. unusual */
-
-/* bits in EDLC_XMODE, set Transmit Packet mode. register is r/w */
-#define XMD_COLL_CNT 0xf0 /* coll's since success. read-only */
-#define XMD_IG_PAR 0x08 /* =1 to ignore parity. ALWAYS set */
-#define XMD_T_MODE 0x04 /* =1 to power xcvr. ALWAYS set this */
-#define XMD_LBC 0x02 /* =1 for loopbakc. normally set */
-#define XMD_DIS_C 0x01 /* =1 disables contention. normally 0 */
-
-/* bits in EDLC_RESET, write only */
-#define RS_RESET 0x80 /* =1 to hold EDLC in reset state */
-
-/* bits in IE_MMODE, write only */
-#define MM_EN_DMA 0x80 /* =1 begin DMA xfer, Cplt clrs it */
-#define MM_EN_RCV 0x40 /* =1 allows Pkt rcv. clr'd by rcv */
-#define MM_EN_XMT 0x20 /* =1 begin Xmt pkt. Cplt clrs it */
-#define MM_BUS_PAGE 0x18 /* =00 ALWAYS. Used when MUX=1 */
-#define MM_NET_PAGE 0x06 /* =00 ALWAYS. Used when MUX=0 */
-#define MM_MUX 0x01 /* =1 means Rcv Buff on system bus */
- /* =0 means Xmt Buff on system bus */
-
-/* bits in IE_ISTAT, read only */
-#define IS_TDIAG 0x80 /* =1 if Diagnostic problem */
-#define IS_EN_RCV 0x20 /* =1 until frame is rcv'd cplt */
-#define IS_EN_XMT 0x10 /* =1 until frame is xmt'd cplt */
-#define IS_EN_DMA 0x08 /* =1 until DMA is cplt or aborted */
-#define IS_DMA_INT 0x04 /* =0 iff DMA done interrupt. */
-#define IS_R_INT 0x02 /* =0 iff unmasked Rcv interrupt */
-#define IS_X_INT 0x01 /* =0 iff unmasked Xmt interrupt */
-
diff --git a/drivers/net/ethernet/seeq/Kconfig b/drivers/net/ethernet/seeq/Kconfig
index 29f18533fdc..a71e1ec068e 100644
--- a/drivers/net/ethernet/seeq/Kconfig
+++ b/drivers/net/ethernet/seeq/Kconfig
@@ -26,17 +26,6 @@ config ARM_ETHER3
If you have an Acorn system with one of these network cards, you
should say Y to this option if you wish to use it with Linux.
-config SEEQ8005
- tristate "SEEQ8005 support (EXPERIMENTAL)"
- depends on EXPERIMENTAL
- ---help---
- This is a driver for the SEEQ 8005 network (Ethernet) card. If this
- is for you, read the Ethernet-HOWTO, available from
- <http://www.tldp.org/docs.html#howto>.
-
- To compile this driver as a module, choose M here. The module
- will be called seeq8005.
-
config SGISEEQ
tristate "SGI Seeq ethernet controller support"
depends on SGI_HAS_SEEQ
diff --git a/drivers/net/ethernet/seeq/Makefile b/drivers/net/ethernet/seeq/Makefile
index 3e258a580c0..0488e99b831 100644
--- a/drivers/net/ethernet/seeq/Makefile
+++ b/drivers/net/ethernet/seeq/Makefile
@@ -3,5 +3,4 @@
#
obj-$(CONFIG_ARM_ETHER3) += ether3.o
-obj-$(CONFIG_SEEQ8005) += seeq8005.o
obj-$(CONFIG_SGISEEQ) += sgiseeq.o
diff --git a/drivers/net/ethernet/seeq/seeq8005.c b/drivers/net/ethernet/seeq/seeq8005.c
deleted file mode 100644
index d6e50de7118..00000000000
--- a/drivers/net/ethernet/seeq/seeq8005.c
+++ /dev/null
@@ -1,749 +0,0 @@
-/* seeq8005.c: A network driver for linux. */
-/*
- Based on skeleton.c,
- Written 1993-94 by Donald Becker.
- See the skeleton.c file for further copyright information.
-
- This software may be used and distributed according to the terms
- of the GNU General Public License, incorporated herein by reference.
-
- The author may be reached as hamish@zot.apana.org.au
-
- This file is a network device driver for the SEEQ 8005 chipset and
- the Linux operating system.
-
-*/
-
-static const char version[] =
- "seeq8005.c:v1.00 8/07/95 Hamish Coleman (hamish@zot.apana.org.au)\n";
-
-/*
- Sources:
- SEEQ 8005 databook
-
- Version history:
- 1.00 Public release. cosmetic changes (no warnings now)
- 0.68 Turning per- packet,interrupt debug messages off - testing for release.
- 0.67 timing problems/bad buffer reads seem to be fixed now
- 0.63 *!@$ protocol=eth_type_trans -- now packets flow
- 0.56 Send working
- 0.48 Receive working
-*/
-
-#include <linux/module.h>
-#include <linux/kernel.h>
-#include <linux/types.h>
-#include <linux/fcntl.h>
-#include <linux/interrupt.h>
-#include <linux/ioport.h>
-#include <linux/in.h>
-#include <linux/string.h>
-#include <linux/init.h>
-#include <linux/delay.h>
-#include <linux/errno.h>
-#include <linux/netdevice.h>
-#include <linux/etherdevice.h>
-#include <linux/skbuff.h>
-#include <linux/bitops.h>
-#include <linux/jiffies.h>
-
-#include <asm/io.h>
-#include <asm/dma.h>
-
-#include "seeq8005.h"
-
-/* First, a few definitions that the brave might change. */
-/* A zero-terminated list of I/O addresses to be probed. */
-static unsigned int seeq8005_portlist[] __initdata =
- { 0x300, 0x320, 0x340, 0x360, 0};
-
-/* use 0 for production, 1 for verification, >2 for debug */
-#ifndef NET_DEBUG
-#define NET_DEBUG 1
-#endif
-static unsigned int net_debug = NET_DEBUG;
-
-/* Information that need to be kept for each board. */
-struct net_local {
- unsigned short receive_ptr; /* What address in packet memory do we expect a recv_pkt_header? */
- long open_time; /* Useless example local info. */
-};
-
-/* The station (ethernet) address prefix, used for IDing the board. */
-#define SA_ADDR0 0x00
-#define SA_ADDR1 0x80
-#define SA_ADDR2 0x4b
-
-/* Index to functions, as function prototypes. */
-
-static int seeq8005_probe1(struct net_device *dev, int ioaddr);
-static int seeq8005_open(struct net_device *dev);
-static void seeq8005_timeout(struct net_device *dev);
-static netdev_tx_t seeq8005_send_packet(struct sk_buff *skb,
- struct net_device *dev);
-static irqreturn_t seeq8005_interrupt(int irq, void *dev_id);
-static void seeq8005_rx(struct net_device *dev);
-static int seeq8005_close(struct net_device *dev);
-static void set_multicast_list(struct net_device *dev);
-
-/* Example routines you must write ;->. */
-#define tx_done(dev) (inw(SEEQ_STATUS) & SEEQSTAT_TX_ON)
-static void hardware_send_packet(struct net_device *dev, char *buf, int length);
-extern void seeq8005_init(struct net_device *dev, int startp);
-static inline void wait_for_buffer(struct net_device *dev);
-
-
-/* Check for a network adaptor of this type, and return '0' iff one exists.
- If dev->base_addr == 0, probe all likely locations.
- If dev->base_addr == 1, always return failure.
- */
-
-static int io = 0x320;
-static int irq = 10;
-
-struct net_device * __init seeq8005_probe(int unit)
-{
- struct net_device *dev = alloc_etherdev(sizeof(struct net_local));
- unsigned *port;
- int err = 0;
-
- if (!dev)
- return ERR_PTR(-ENODEV);
-
- if (unit >= 0) {
- sprintf(dev->name, "eth%d", unit);
- netdev_boot_setup_check(dev);
- io = dev->base_addr;
- irq = dev->irq;
- }
-
- if (io > 0x1ff) { /* Check a single specified location. */
- err = seeq8005_probe1(dev, io);
- } else if (io != 0) { /* Don't probe at all. */
- err = -ENXIO;
- } else {
- for (port = seeq8005_portlist; *port; port++) {
- if (seeq8005_probe1(dev, *port) == 0)
- break;
- }
- if (!*port)
- err = -ENODEV;
- }
- if (err)
- goto out;
- err = register_netdev(dev);
- if (err)
- goto out1;
- return dev;
-out1:
- release_region(dev->base_addr, SEEQ8005_IO_EXTENT);
-out:
- free_netdev(dev);
- return ERR_PTR(err);
-}
-
-static const struct net_device_ops seeq8005_netdev_ops = {
- .ndo_open = seeq8005_open,
- .ndo_stop = seeq8005_close,
- .ndo_start_xmit = seeq8005_send_packet,
- .ndo_tx_timeout = seeq8005_timeout,
- .ndo_set_rx_mode = set_multicast_list,
- .ndo_change_mtu = eth_change_mtu,
- .ndo_set_mac_address = eth_mac_addr,
- .ndo_validate_addr = eth_validate_addr,
-};
-
-/* This is the real probe routine. Linux has a history of friendly device
- probes on the ISA bus. A good device probes avoids doing writes, and
- verifies that the correct device exists and functions. */
-
-static int __init seeq8005_probe1(struct net_device *dev, int ioaddr)
-{
- static unsigned version_printed;
- int i,j;
- unsigned char SA_prom[32];
- int old_cfg1;
- int old_cfg2;
- int old_stat;
- int old_dmaar;
- int old_rear;
- int retval;
-
- if (!request_region(ioaddr, SEEQ8005_IO_EXTENT, "seeq8005"))
- return -ENODEV;
-
- if (net_debug>1)
- printk("seeq8005: probing at 0x%x\n",ioaddr);
-
- old_stat = inw(SEEQ_STATUS); /* read status register */
- if (old_stat == 0xffff) {
- retval = -ENODEV;
- goto out; /* assume that 0xffff == no device */
- }
- if ( (old_stat & 0x1800) != 0x1800 ) { /* assume that unused bits are 1, as my manual says */
- if (net_debug>1) {
- printk("seeq8005: reserved stat bits != 0x1800\n");
- printk(" == 0x%04x\n",old_stat);
- }
- retval = -ENODEV;
- goto out;
- }
-
- old_rear = inw(SEEQ_REA);
- if (old_rear == 0xffff) {
- outw(0,SEEQ_REA);
- if (inw(SEEQ_REA) == 0xffff) { /* assume that 0xffff == no device */
- retval = -ENODEV;
- goto out;
- }
- } else if ((old_rear & 0xff00) != 0xff00) { /* assume that unused bits are 1 */
- if (net_debug>1) {
- printk("seeq8005: unused rear bits != 0xff00\n");
- printk(" == 0x%04x\n",old_rear);
- }
- retval = -ENODEV;
- goto out;
- }
-
- old_cfg2 = inw(SEEQ_CFG2); /* read CFG2 register */
- old_cfg1 = inw(SEEQ_CFG1);
- old_dmaar = inw(SEEQ_DMAAR);
-
- if (net_debug>4) {
- printk("seeq8005: stat = 0x%04x\n",old_stat);
- printk("seeq8005: cfg1 = 0x%04x\n",old_cfg1);
- printk("seeq8005: cfg2 = 0x%04x\n",old_cfg2);
- printk("seeq8005: raer = 0x%04x\n",old_rear);
- printk("seeq8005: dmaar= 0x%04x\n",old_dmaar);
- }
-
- outw( SEEQCMD_FIFO_WRITE | SEEQCMD_SET_ALL_OFF, SEEQ_CMD); /* setup for reading PROM */
- outw( 0, SEEQ_DMAAR); /* set starting PROM address */
- outw( SEEQCFG1_BUFFER_PROM, SEEQ_CFG1); /* set buffer to look at PROM */
-
-
- j=0;
- for(i=0; i <32; i++) {
- j+= SA_prom[i] = inw(SEEQ_BUFFER) & 0xff;
- }
-
-#if 0
- /* untested because I only have the one card */
- if ( (j&0xff) != 0 ) { /* checksum appears to be 8bit = 0 */
- if (net_debug>1) { /* check this before deciding that we have a card */
- printk("seeq8005: prom sum error\n");
- }
- outw( old_stat, SEEQ_STATUS);
- outw( old_dmaar, SEEQ_DMAAR);
- outw( old_cfg1, SEEQ_CFG1);
- retval = -ENODEV;
- goto out;
- }
-#endif
-
- outw( SEEQCFG2_RESET, SEEQ_CFG2); /* reset the card */
- udelay(5);
- outw( SEEQCMD_SET_ALL_OFF, SEEQ_CMD);
-
- if (net_debug) {
- printk("seeq8005: prom sum = 0x%08x\n",j);
- for(j=0; j<32; j+=16) {
- printk("seeq8005: prom %02x: ",j);
- for(i=0;i<16;i++) {
- printk("%02x ",SA_prom[j|i]);
- }
- printk(" ");
- for(i=0;i<16;i++) {
- if ((SA_prom[j|i]>31)&&(SA_prom[j|i]<127)) {
- printk("%c", SA_prom[j|i]);
- } else {
- printk(" ");
- }
- }
- printk("\n");
- }
- }
-
-#if 0
- /*
- * testing the packet buffer memory doesn't work yet
- * but all other buffer accesses do
- * - fixing is not a priority
- */
- if (net_debug>1) { /* test packet buffer memory */
- printk("seeq8005: testing packet buffer ... ");
- outw( SEEQCFG1_BUFFER_BUFFER, SEEQ_CFG1);
- outw( SEEQCMD_FIFO_WRITE | SEEQCMD_SET_ALL_OFF, SEEQ_CMD);
- outw( 0 , SEEQ_DMAAR);
- for(i=0;i<32768;i++) {
- outw(0x5a5a, SEEQ_BUFFER);
- }
- j=jiffies+HZ;
- while ( ((inw(SEEQ_STATUS) & SEEQSTAT_FIFO_EMPTY) != SEEQSTAT_FIFO_EMPTY) && time_before(jiffies, j) )
- mb();
- outw( 0 , SEEQ_DMAAR);
- while ( ((inw(SEEQ_STATUS) & SEEQSTAT_WINDOW_INT) != SEEQSTAT_WINDOW_INT) && time_before(jiffies, j+HZ))
- mb();
- if ( (inw(SEEQ_STATUS) & SEEQSTAT_WINDOW_INT) == SEEQSTAT_WINDOW_INT)
- outw( SEEQCMD_WINDOW_INT_ACK | (inw(SEEQ_STATUS)& SEEQCMD_INT_MASK), SEEQ_CMD);
- outw( SEEQCMD_FIFO_READ | SEEQCMD_SET_ALL_OFF, SEEQ_CMD);
- j=0;
- for(i=0;i<32768;i++) {
- if (inw(SEEQ_BUFFER) != 0x5a5a)
- j++;
- }
- if (j) {
- printk("%i\n",j);
- } else {
- printk("ok.\n");
- }
- }
-#endif
-
- if (net_debug && version_printed++ == 0)
- printk(version);
-
- printk("%s: %s found at %#3x, ", dev->name, "seeq8005", ioaddr);
-
- /* Fill in the 'dev' fields. */
- dev->base_addr = ioaddr;
- dev->irq = irq;
-
- /* Retrieve and print the ethernet address. */
- for (i = 0; i < 6; i++)
- dev->dev_addr[i] = SA_prom[i+6];
- printk("%pM", dev->dev_addr);
-
- if (dev->irq == 0xff)
- ; /* Do nothing: a user-level program will set it. */
- else if (dev->irq < 2) { /* "Auto-IRQ" */
- unsigned long cookie = probe_irq_on();
-
- outw( SEEQCMD_RX_INT_EN | SEEQCMD_SET_RX_ON | SEEQCMD_SET_RX_OFF, SEEQ_CMD );
-
- dev->irq = probe_irq_off(cookie);
-
- if (net_debug >= 2)
- printk(" autoirq is %d\n", dev->irq);
- } else if (dev->irq == 2)
- /* Fixup for users that don't know that IRQ 2 is really IRQ 9,
- * or don't know which one to set.
- */
- dev->irq = 9;
-
-#if 0
- {
- int irqval = request_irq(dev->irq, seeq8005_interrupt, 0, "seeq8005", dev);
- if (irqval) {
- printk ("%s: unable to get IRQ %d (irqval=%d).\n", dev->name,
- dev->irq, irqval);
- retval = -EAGAIN;
- goto out;
- }
- }
-#endif
- dev->netdev_ops = &seeq8005_netdev_ops;
- dev->watchdog_timeo = HZ/20;
- dev->flags &= ~IFF_MULTICAST;
-
- return 0;
-out:
- release_region(ioaddr, SEEQ8005_IO_EXTENT);
- return retval;
-}
-
-
-/* Open/initialize the board. This is called (in the current kernel)
- sometime after booting when the 'ifconfig' program is run.
-
- This routine should set everything up anew at each open, even
- registers that "should" only need to be set once at boot, so that
- there is non-reboot way to recover if something goes wrong.
- */
-static int seeq8005_open(struct net_device *dev)
-{
- struct net_local *lp = netdev_priv(dev);
-
- {
- int irqval = request_irq(dev->irq, seeq8005_interrupt, 0, "seeq8005", dev);
- if (irqval) {
- printk ("%s: unable to get IRQ %d (irqval=%d).\n", dev->name,
- dev->irq, irqval);
- return -EAGAIN;
- }
- }
-
- /* Reset the hardware here. Don't forget to set the station address. */
- seeq8005_init(dev, 1);
-
- lp->open_time = jiffies;
-
- netif_start_queue(dev);
- return 0;
-}
-
-static void seeq8005_timeout(struct net_device *dev)
-{
- int ioaddr = dev->base_addr;
- printk(KERN_WARNING "%s: transmit timed out, %s?\n", dev->name,
- tx_done(dev) ? "IRQ conflict" : "network cable problem");
- /* Try to restart the adaptor. */
- seeq8005_init(dev, 1);
- dev->trans_start = jiffies; /* prevent tx timeout */
- netif_wake_queue(dev);
-}
-
-static netdev_tx_t seeq8005_send_packet(struct sk_buff *skb,
- struct net_device *dev)
-{
- short length = skb->len;
- unsigned char *buf;
-
- if (length < ETH_ZLEN) {
- if (skb_padto(skb, ETH_ZLEN))
- return NETDEV_TX_OK;
- length = ETH_ZLEN;
- }
- buf = skb->data;
-
- /* Block a timer-based transmit from overlapping */
- netif_stop_queue(dev);
-
- hardware_send_packet(dev, buf, length);
- dev->stats.tx_bytes += length;
- dev_kfree_skb (skb);
- /* You might need to clean up and record Tx statistics here. */
-
- return NETDEV_TX_OK;
-}
-
-/*
- * wait_for_buffer
- *
- * This routine waits for the SEEQ chip to assert that the FIFO is ready
- * by checking for a window interrupt, and then clearing it. This has to
- * occur in the interrupt handler!
- */
-inline void wait_for_buffer(struct net_device * dev)
-{
- int ioaddr = dev->base_addr;
- unsigned long tmp;
- int status;
-
- tmp = jiffies + HZ;
- while ( ( ((status=inw(SEEQ_STATUS)) & SEEQSTAT_WINDOW_INT) != SEEQSTAT_WINDOW_INT) && time_before(jiffies, tmp))
- cpu_relax();
-
- if ( (status & SEEQSTAT_WINDOW_INT) == SEEQSTAT_WINDOW_INT)
- outw( SEEQCMD_WINDOW_INT_ACK | (status & SEEQCMD_INT_MASK), SEEQ_CMD);
-}
-
-/* The typical workload of the driver:
- Handle the network interface interrupts. */
-static irqreturn_t seeq8005_interrupt(int irq, void *dev_id)
-{
- struct net_device *dev = dev_id;
- struct net_local *lp;
- int ioaddr, status, boguscount = 0;
- int handled = 0;
-
- ioaddr = dev->base_addr;
- lp = netdev_priv(dev);
-
- status = inw(SEEQ_STATUS);
- do {
- if (net_debug >2) {
- printk("%s: int, status=0x%04x\n",dev->name,status);
- }
-
- if (status & SEEQSTAT_WINDOW_INT) {
- handled = 1;
- outw( SEEQCMD_WINDOW_INT_ACK | (status & SEEQCMD_INT_MASK), SEEQ_CMD);
- if (net_debug) {
- printk("%s: window int!\n",dev->name);
- }
- }
- if (status & SEEQSTAT_TX_INT) {
- handled = 1;
- outw( SEEQCMD_TX_INT_ACK | (status & SEEQCMD_INT_MASK), SEEQ_CMD);
- dev->stats.tx_packets++;
- netif_wake_queue(dev); /* Inform upper layers. */
- }
- if (status & SEEQSTAT_RX_INT) {
- handled = 1;
- /* Got a packet(s). */
- seeq8005_rx(dev);
- }
- status = inw(SEEQ_STATUS);
- } while ( (++boguscount < 10) && (status & SEEQSTAT_ANY_INT)) ;
-
- if(net_debug>2) {
- printk("%s: eoi\n",dev->name);
- }
- return IRQ_RETVAL(handled);
-}
-
-/* We have a good packet(s), get it/them out of the buffers. */
-static void seeq8005_rx(struct net_device *dev)
-{
- struct net_local *lp = netdev_priv(dev);
- int boguscount = 10;
- int pkt_hdr;
- int ioaddr = dev->base_addr;
-
- do {
- int next_packet;
- int pkt_len;
- int i;
- int status;
-
- status = inw(SEEQ_STATUS);
- outw( lp->receive_ptr, SEEQ_DMAAR);
- outw(SEEQCMD_FIFO_READ | SEEQCMD_RX_INT_ACK | (status & SEEQCMD_INT_MASK), SEEQ_CMD);
- wait_for_buffer(dev);
- next_packet = ntohs(inw(SEEQ_BUFFER));
- pkt_hdr = inw(SEEQ_BUFFER);
-
- if (net_debug>2) {
- printk("%s: 0x%04x recv next=0x%04x, hdr=0x%04x\n",dev->name,lp->receive_ptr,next_packet,pkt_hdr);
- }
-
- if ((next_packet == 0) || ((pkt_hdr & SEEQPKTH_CHAIN)==0)) { /* Read all the frames? */
- return; /* Done for now */
- }
-
- if ((pkt_hdr & SEEQPKTS_DONE)==0)
- break;
-
- if (next_packet < lp->receive_ptr) {
- pkt_len = (next_packet + 0x10000 - ((DEFAULT_TEA+1)<<8)) - lp->receive_ptr - 4;
- } else {
- pkt_len = next_packet - lp->receive_ptr - 4;
- }
-
- if (next_packet < ((DEFAULT_TEA+1)<<8)) { /* is the next_packet address sane? */
- printk("%s: recv packet ring corrupt, resetting board\n",dev->name);
- seeq8005_init(dev,1);
- return;
- }
-
- lp->receive_ptr = next_packet;
-
- if (net_debug>2) {
- printk("%s: recv len=0x%04x\n",dev->name,pkt_len);
- }
-
- if (pkt_hdr & SEEQPKTS_ANY_ERROR) { /* There was an error. */
- dev->stats.rx_errors++;
- if (pkt_hdr & SEEQPKTS_SHORT) dev->stats.rx_frame_errors++;
- if (pkt_hdr & SEEQPKTS_DRIB) dev->stats.rx_frame_errors++;
- if (pkt_hdr & SEEQPKTS_OVERSIZE) dev->stats.rx_over_errors++;
- if (pkt_hdr & SEEQPKTS_CRC_ERR) dev->stats.rx_crc_errors++;
- /* skip over this packet */
- outw( SEEQCMD_FIFO_WRITE | SEEQCMD_DMA_INT_ACK | (status & SEEQCMD_INT_MASK), SEEQ_CMD);
- outw( (lp->receive_ptr & 0xff00)>>8, SEEQ_REA);
- } else {
- /* Malloc up new buffer. */
- struct sk_buff *skb;
- unsigned char *buf;
-
- skb = netdev_alloc_skb(dev, pkt_len);
- if (skb == NULL) {
- printk("%s: Memory squeeze, dropping packet.\n", dev->name);
- dev->stats.rx_dropped++;
- break;
- }
- skb_reserve(skb, 2); /* align data on 16 byte */
- buf = skb_put(skb,pkt_len);
-
- insw(SEEQ_BUFFER, buf, (pkt_len + 1) >> 1);
-
- if (net_debug>2) {
- char * p = buf;
- printk("%s: recv ",dev->name);
- for(i=0;i<14;i++) {
- printk("%02x ",*(p++)&0xff);
- }
- printk("\n");
- }
-
- skb->protocol=eth_type_trans(skb,dev);
- netif_rx(skb);
- dev->stats.rx_packets++;
- dev->stats.rx_bytes += pkt_len;
- }
- } while ((--boguscount) && (pkt_hdr & SEEQPKTH_CHAIN));
-
- /* If any worth-while packets have been received, netif_rx()
- has done a mark_bh(NET_BH) for us and will work on them
- when we get to the bottom-half routine. */
-}
-
-/* The inverse routine to net_open(). */
-static int seeq8005_close(struct net_device *dev)
-{
- struct net_local *lp = netdev_priv(dev);
- int ioaddr = dev->base_addr;
-
- lp->open_time = 0;
-
- netif_stop_queue(dev);
-
- /* Flush the Tx and disable Rx here. */
- outw( SEEQCMD_SET_ALL_OFF, SEEQ_CMD);
-
- free_irq(dev->irq, dev);
-
- /* Update the statistics here. */
-
- return 0;
-
-}
-
-/* Set or clear the multicast filter for this adaptor.
- num_addrs == -1 Promiscuous mode, receive all packets
- num_addrs == 0 Normal mode, clear multicast list
- num_addrs > 0 Multicast mode, receive normal and MC packets, and do
- best-effort filtering.
- */
-static void set_multicast_list(struct net_device *dev)
-{
-/*
- * I _could_ do up to 6 addresses here, but won't (yet?)
- */
-
-#if 0
- int ioaddr = dev->base_addr;
-/*
- * hmm, not even sure if my matching works _anyway_ - seem to be receiving
- * _everything_ . . .
- */
-
- if (num_addrs) { /* Enable promiscuous mode */
- outw( (inw(SEEQ_CFG1) & ~SEEQCFG1_MATCH_MASK)| SEEQCFG1_MATCH_ALL, SEEQ_CFG1);
- dev->flags|=IFF_PROMISC;
- } else { /* Disable promiscuous mode, use normal mode */
- outw( (inw(SEEQ_CFG1) & ~SEEQCFG1_MATCH_MASK)| SEEQCFG1_MATCH_BROAD, SEEQ_CFG1);
- }
-#endif
-}
-
-void seeq8005_init(struct net_device *dev, int startp)
-{
- struct net_local *lp = netdev_priv(dev);
- int ioaddr = dev->base_addr;
- int i;
-
- outw(SEEQCFG2_RESET, SEEQ_CFG2); /* reset device */
- udelay(5);
-
- outw( SEEQCMD_FIFO_WRITE | SEEQCMD_SET_ALL_OFF, SEEQ_CMD);
- outw( 0, SEEQ_DMAAR); /* load start address into both low and high byte */
-/* wait_for_buffer(dev); */ /* I think that you only need a wait for memory buffer */
- outw( SEEQCFG1_BUFFER_MAC0, SEEQ_CFG1);
-
- for(i=0;i<6;i++) { /* set Station address */
- outb(dev->dev_addr[i], SEEQ_BUFFER);
- udelay(2);
- }
-
- outw( SEEQCFG1_BUFFER_TEA, SEEQ_CFG1); /* set xmit end area pointer to 16K */
- outb( DEFAULT_TEA, SEEQ_BUFFER); /* this gives us 16K of send buffer and 48K of recv buffer */
-
- lp->receive_ptr = (DEFAULT_TEA+1)<<8; /* so we can find our packet_header */
- outw( lp->receive_ptr, SEEQ_RPR); /* Receive Pointer Register is set to recv buffer memory */
-
- outw( 0x00ff, SEEQ_REA); /* Receive Area End */
-
- if (net_debug>4) {
- printk("%s: SA0 = ",dev->name);
-
- outw( SEEQCMD_FIFO_READ | SEEQCMD_SET_ALL_OFF, SEEQ_CMD);
- outw( 0, SEEQ_DMAAR);
- outw( SEEQCFG1_BUFFER_MAC0, SEEQ_CFG1);
-
- for(i=0;i<6;i++) {
- printk("%02x ",inb(SEEQ_BUFFER));
- }
- printk("\n");
- }
-
- outw( SEEQCFG1_MAC0_EN | SEEQCFG1_MATCH_BROAD | SEEQCFG1_BUFFER_BUFFER, SEEQ_CFG1);
- outw( SEEQCFG2_AUTO_REA | SEEQCFG2_CTRLO, SEEQ_CFG2);
- outw( SEEQCMD_SET_RX_ON | SEEQCMD_TX_INT_EN | SEEQCMD_RX_INT_EN, SEEQ_CMD);
-
- if (net_debug>4) {
- int old_cfg1;
- old_cfg1 = inw(SEEQ_CFG1);
- printk("%s: stat = 0x%04x\n",dev->name,inw(SEEQ_STATUS));
- printk("%s: cfg1 = 0x%04x\n",dev->name,old_cfg1);
- printk("%s: cfg2 = 0x%04x\n",dev->name,inw(SEEQ_CFG2));
- printk("%s: raer = 0x%04x\n",dev->name,inw(SEEQ_REA));
- printk("%s: dmaar= 0x%04x\n",dev->name,inw(SEEQ_DMAAR));
-
- }
-}
-
-
-static void hardware_send_packet(struct net_device * dev, char *buf, int length)
-{
- int ioaddr = dev->base_addr;
- int status = inw(SEEQ_STATUS);
- int transmit_ptr = 0;
- unsigned long tmp;
-
- if (net_debug>4) {
- printk("%s: send 0x%04x\n",dev->name,length);
- }
-
- /* Set FIFO to writemode and set packet-buffer address */
- outw( SEEQCMD_FIFO_WRITE | (status & SEEQCMD_INT_MASK), SEEQ_CMD);
- outw( transmit_ptr, SEEQ_DMAAR);
-
- /* output SEEQ Packet header barfage */
- outw( htons(length + 4), SEEQ_BUFFER);
- outw( SEEQPKTH_XMIT | SEEQPKTH_DATA_FOLLOWS | SEEQPKTH_XMIT_INT_EN, SEEQ_BUFFER );
-
- /* blat the buffer */
- outsw( SEEQ_BUFFER, buf, (length +1) >> 1);
- /* paranoia !! */
- outw( 0, SEEQ_BUFFER);
- outw( 0, SEEQ_BUFFER);
-
- /* set address of start of transmit chain */
- outw( transmit_ptr, SEEQ_TPR);
-
- /* drain FIFO */
- tmp = jiffies;
- while ( (((status=inw(SEEQ_STATUS)) & SEEQSTAT_FIFO_EMPTY) == 0) && time_before(jiffies, tmp + HZ))
- mb();
-
- /* doit ! */
- outw( SEEQCMD_WINDOW_INT_ACK | SEEQCMD_SET_TX_ON | (status & SEEQCMD_INT_MASK), SEEQ_CMD);
-
-}
-
-
-#ifdef MODULE
-
-static struct net_device *dev_seeq;
-MODULE_LICENSE("GPL");
-module_param(io, int, 0);
-module_param(irq, int, 0);
-MODULE_PARM_DESC(io, "SEEQ 8005 I/O base address");
-MODULE_PARM_DESC(irq, "SEEQ 8005 IRQ number");
-
-int __init init_module(void)
-{
- dev_seeq = seeq8005_probe(-1);
- return PTR_RET(dev_seeq);
-}
-
-void __exit cleanup_module(void)
-{
- unregister_netdev(dev_seeq);
- release_region(dev_seeq->base_addr, SEEQ8005_IO_EXTENT);
- free_netdev(dev_seeq);
-}
-
-#endif /* MODULE */
diff --git a/drivers/net/ethernet/seeq/seeq8005.h b/drivers/net/ethernet/seeq/seeq8005.h
deleted file mode 100644
index 5dfb0098c6c..00000000000
--- a/drivers/net/ethernet/seeq/seeq8005.h
+++ /dev/null
@@ -1,156 +0,0 @@
-/*
- * defines, etc for the seeq8005
- */
-
-/*
- * This file is distributed under GPL.
- *
- * This style and layout of this file is also copied
- * from many of the other linux network device drivers.
- */
-
-/* The number of low I/O ports used by the ethercard. */
-#define SEEQ8005_IO_EXTENT 16
-
-#define SEEQ_B (ioaddr)
-
-#define SEEQ_CMD (SEEQ_B) /* Write only */
-#define SEEQ_STATUS (SEEQ_B) /* Read only */
-#define SEEQ_CFG1 (SEEQ_B + 2)
-#define SEEQ_CFG2 (SEEQ_B + 4)
-#define SEEQ_REA (SEEQ_B + 6) /* Receive End Area Register */
-#define SEEQ_RPR (SEEQ_B + 10) /* Receive Pointer Register */
-#define SEEQ_TPR (SEEQ_B + 12) /* Transmit Pointer Register */
-#define SEEQ_DMAAR (SEEQ_B + 14) /* DMA Address Register */
-#define SEEQ_BUFFER (SEEQ_B + 8) /* Buffer Window Register */
-
-#define DEFAULT_TEA (0x3f)
-
-#define SEEQCMD_DMA_INT_EN (0x0001) /* DMA Interrupt Enable */
-#define SEEQCMD_RX_INT_EN (0x0002) /* Receive Interrupt Enable */
-#define SEEQCMD_TX_INT_EN (0x0004) /* Transmit Interrupt Enable */
-#define SEEQCMD_WINDOW_INT_EN (0x0008) /* What the hell is this for?? */
-#define SEEQCMD_INT_MASK (0x000f)
-
-#define SEEQCMD_DMA_INT_ACK (0x0010) /* DMA ack */
-#define SEEQCMD_RX_INT_ACK (0x0020)
-#define SEEQCMD_TX_INT_ACK (0x0040)
-#define SEEQCMD_WINDOW_INT_ACK (0x0080)
-#define SEEQCMD_ACK_ALL (0x00f0)
-
-#define SEEQCMD_SET_DMA_ON (0x0100) /* Enables DMA Request logic */
-#define SEEQCMD_SET_RX_ON (0x0200) /* Enables Packet RX */
-#define SEEQCMD_SET_TX_ON (0x0400) /* Starts TX run */
-#define SEEQCMD_SET_DMA_OFF (0x0800)
-#define SEEQCMD_SET_RX_OFF (0x1000)
-#define SEEQCMD_SET_TX_OFF (0x2000)
-#define SEEQCMD_SET_ALL_OFF (0x3800) /* set all logic off */
-
-#define SEEQCMD_FIFO_READ (0x4000) /* Set FIFO to read mode (read from Buffer) */
-#define SEEQCMD_FIFO_WRITE (0x8000) /* Set FIFO to write mode */
-
-#define SEEQSTAT_DMA_INT_EN (0x0001) /* Status of interrupt enable */
-#define SEEQSTAT_RX_INT_EN (0x0002)
-#define SEEQSTAT_TX_INT_EN (0x0004)
-#define SEEQSTAT_WINDOW_INT_EN (0x0008)
-
-#define SEEQSTAT_DMA_INT (0x0010) /* Interrupt flagged */
-#define SEEQSTAT_RX_INT (0x0020)
-#define SEEQSTAT_TX_INT (0x0040)
-#define SEEQSTAT_WINDOW_INT (0x0080)
-#define SEEQSTAT_ANY_INT (0x00f0)
-
-#define SEEQSTAT_DMA_ON (0x0100) /* DMA logic on */
-#define SEEQSTAT_RX_ON (0x0200) /* Packet RX on */
-#define SEEQSTAT_TX_ON (0x0400) /* TX running */
-
-#define SEEQSTAT_FIFO_FULL (0x2000)
-#define SEEQSTAT_FIFO_EMPTY (0x4000)
-#define SEEQSTAT_FIFO_DIR (0x8000) /* 1=read, 0=write */
-
-#define SEEQCFG1_BUFFER_MASK (0x000f) /* define what maps into the BUFFER register */
-#define SEEQCFG1_BUFFER_MAC0 (0x0000) /* MAC station addresses 0-5 */
-#define SEEQCFG1_BUFFER_MAC1 (0x0001)
-#define SEEQCFG1_BUFFER_MAC2 (0x0002)
-#define SEEQCFG1_BUFFER_MAC3 (0x0003)
-#define SEEQCFG1_BUFFER_MAC4 (0x0004)
-#define SEEQCFG1_BUFFER_MAC5 (0x0005)
-#define SEEQCFG1_BUFFER_PROM (0x0006) /* The Address/CFG PROM */
-#define SEEQCFG1_BUFFER_TEA (0x0007) /* Transmit end area */
-#define SEEQCFG1_BUFFER_BUFFER (0x0008) /* Packet buffer memory */
-#define SEEQCFG1_BUFFER_INT_VEC (0x0009) /* Interrupt Vector */
-
-#define SEEQCFG1_DMA_INTVL_MASK (0x0030)
-#define SEEQCFG1_DMA_CONT (0x0000)
-#define SEEQCFG1_DMA_800ns (0x0010)
-#define SEEQCFG1_DMA_1600ns (0x0020)
-#define SEEQCFG1_DMA_3200ns (0x0030)
-
-#define SEEQCFG1_DMA_LEN_MASK (0x00c0)
-#define SEEQCFG1_DMA_LEN1 (0x0000)
-#define SEEQCFG1_DMA_LEN2 (0x0040)
-#define SEEQCFG1_DMA_LEN4 (0x0080)
-#define SEEQCFG1_DMA_LEN8 (0x00c0)
-
-#define SEEQCFG1_MAC_MASK (0x3f00) /* Dis/enable bits for MAC addresses */
-#define SEEQCFG1_MAC0_EN (0x0100)
-#define SEEQCFG1_MAC1_EN (0x0200)
-#define SEEQCFG1_MAC2_EN (0x0400)
-#define SEEQCFG1_MAC3_EN (0x0800)
-#define SEEQCFG1_MAC4_EN (0x1000)
-#define SEEQCFG1_MAC5_EN (0x2000)
-
-#define SEEQCFG1_MATCH_MASK (0xc000) /* Packet matching logic cfg bits */
-#define SEEQCFG1_MATCH_SPECIFIC (0x0000) /* only matching MAC addresses */
-#define SEEQCFG1_MATCH_BROAD (0x4000) /* matching and broadcast addresses */
-#define SEEQCFG1_MATCH_MULTI (0x8000) /* matching, broadcast and multicast */
-#define SEEQCFG1_MATCH_ALL (0xc000) /* Promiscuous mode */
-
-#define SEEQCFG1_DEFAULT (SEEQCFG1_BUFFER_BUFFER | SEEQCFG1_MAC0_EN | SEEQCFG1_MATCH_BROAD)
-
-#define SEEQCFG2_BYTE_SWAP (0x0001) /* 0=Intel byte-order */
-#define SEEQCFG2_AUTO_REA (0x0002) /* if set, Receive End Area will be updated when reading from Buffer */
-
-#define SEEQCFG2_CRC_ERR_EN (0x0008) /* enables receiving of packets with CRC errors */
-#define SEEQCFG2_DRIBBLE_EN (0x0010) /* enables receiving of non-aligned packets */
-#define SEEQCFG2_SHORT_EN (0x0020) /* enables receiving of short packets */
-
-#define SEEQCFG2_SLOTSEL (0x0040) /* 0= standard IEEE802.3, 1= smaller,faster, non-standard */
-#define SEEQCFG2_NO_PREAM (0x0080) /* 1= user supplies Xmit preamble bytes */
-#define SEEQCFG2_ADDR_LEN (0x0100) /* 1= 2byte addresses */
-#define SEEQCFG2_REC_CRC (0x0200) /* 0= received packets will have CRC stripped from them */
-#define SEEQCFG2_XMIT_NO_CRC (0x0400) /* don't xmit CRC with each packet (user supplies it) */
-#define SEEQCFG2_LOOPBACK (0x0800)
-#define SEEQCFG2_CTRLO (0x1000)
-#define SEEQCFG2_RESET (0x8000) /* software Hard-reset bit */
-
-struct seeq_pkt_hdr {
- unsigned short next; /* address of next packet header */
- unsigned char babble_int:1, /* enable int on >1514 byte packet */
- coll_int:1, /* enable int on collision */
- coll_16_int:1, /* enable int on >15 collision */
- xmit_int:1, /* enable int on success (or xmit with <15 collision) */
- unused:1,
- data_follows:1, /* if not set, process this as a header and pointer only */
- chain_cont:1, /* if set, more headers in chain only cmd bit valid in recv header */
- xmit_recv:1; /* if set, a xmit packet, else a receive packet.*/
- unsigned char status;
-};
-
-#define SEEQPKTH_BAB_INT_EN (0x01) /* xmit only */
-#define SEEQPKTH_COL_INT_EN (0x02) /* xmit only */
-#define SEEQPKTH_COL16_INT_EN (0x04) /* xmit only */
-#define SEEQPKTH_XMIT_INT_EN (0x08) /* xmit only */
-#define SEEQPKTH_DATA_FOLLOWS (0x20) /* supposedly in xmit only */
-#define SEEQPKTH_CHAIN (0x40) /* more headers follow */
-#define SEEQPKTH_XMIT (0x80)
-
-#define SEEQPKTS_BABBLE (0x0100) /* xmit only */
-#define SEEQPKTS_OVERSIZE (0x0100) /* recv only */
-#define SEEQPKTS_COLLISION (0x0200) /* xmit only */
-#define SEEQPKTS_CRC_ERR (0x0200) /* recv only */
-#define SEEQPKTS_COLL16 (0x0400) /* xmit only */
-#define SEEQPKTS_DRIB (0x0400) /* recv only */
-#define SEEQPKTS_SHORT (0x0800) /* recv only */
-#define SEEQPKTS_DONE (0x8000)
-#define SEEQPKTS_ANY_ERROR (0x0f00)