diff options
-rw-r--r-- | drivers/net/ethernet/8390/Kconfig | 66 | ||||
-rw-r--r-- | drivers/net/ethernet/8390/Makefile | 5 | ||||
-rw-r--r-- | drivers/net/ethernet/8390/ac3200.c | 431 | ||||
-rw-r--r-- | drivers/net/ethernet/8390/es3210.c | 445 | ||||
-rw-r--r-- | drivers/net/ethernet/8390/lne390.c | 433 | ||||
-rw-r--r-- | drivers/net/ethernet/8390/ne3210.c | 346 | ||||
-rw-r--r-- | drivers/net/ethernet/8390/smc-ultra32.c | 463 |
7 files changed, 2 insertions, 2187 deletions
diff --git a/drivers/net/ethernet/8390/Kconfig b/drivers/net/ethernet/8390/Kconfig index 880121730cb0..e49a44221800 100644 --- a/drivers/net/ethernet/8390/Kconfig +++ b/drivers/net/ethernet/8390/Kconfig | |||
@@ -6,7 +6,7 @@ config NET_VENDOR_8390 | |||
6 | bool "National Semi-conductor 8390 devices" | 6 | bool "National Semi-conductor 8390 devices" |
7 | default y | 7 | default y |
8 | depends on NET_VENDOR_NATSEMI && (AMIGA_PCMCIA || PCI || SUPERH || \ | 8 | depends on NET_VENDOR_NATSEMI && (AMIGA_PCMCIA || PCI || SUPERH || \ |
9 | ISA || EISA || MAC || M32R || MACH_TX49XX || \ | 9 | ISA || MAC || M32R || MACH_TX49XX || \ |
10 | H8300 || ARM || MIPS || ZORRO || PCMCIA || \ | 10 | H8300 || ARM || MIPS || ZORRO || PCMCIA || \ |
11 | EXPERIMENTAL) | 11 | EXPERIMENTAL) |
12 | ---help--- | 12 | ---help--- |
@@ -33,18 +33,6 @@ config EL2 | |||
33 | To compile this driver as a module, choose M here. The module | 33 | To compile this driver as a module, choose M here. The module |
34 | will be called 3c503. | 34 | will be called 3c503. |
35 | 35 | ||
36 | config AC3200 | ||
37 | tristate "Ansel Communications EISA 3200 support (EXPERIMENTAL)" | ||
38 | depends on PCI && (ISA || EISA) && EXPERIMENTAL | ||
39 | select CRC32 | ||
40 | ---help--- | ||
41 | If you have a network (Ethernet) card of this type, say Y and read | ||
42 | the Ethernet-HOWTO, available from | ||
43 | <http://www.tldp.org/docs.html#howto>. | ||
44 | |||
45 | To compile this driver as a module, choose M here. The module | ||
46 | will be called ac3200. | ||
47 | |||
48 | config PCMCIA_AXNET | 36 | config PCMCIA_AXNET |
49 | tristate "Asix AX88190 PCMCIA support" | 37 | tristate "Asix AX88190 PCMCIA support" |
50 | depends on PCMCIA | 38 | depends on PCMCIA |
@@ -86,18 +74,6 @@ config E2100 | |||
86 | To compile this driver as a module, choose M here. The module | 74 | To compile this driver as a module, choose M here. The module |
87 | will be called e2100. | 75 | will be called e2100. |
88 | 76 | ||
89 | config ES3210 | ||
90 | tristate "Racal-Interlan EISA ES3210 support (EXPERIMENTAL)" | ||
91 | depends on PCI && EISA && EXPERIMENTAL | ||
92 | select CRC32 | ||
93 | ---help--- | ||
94 | If you have a network (Ethernet) card of this type, say Y and read | ||
95 | the Ethernet-HOWTO, available from | ||
96 | <http://www.tldp.org/docs.html#howto>. | ||
97 | |||
98 | To compile this driver as a module, choose M here. The module | ||
99 | will be called es3210. | ||
100 | |||
101 | config HPLAN_PLUS | 77 | config HPLAN_PLUS |
102 | tristate "HP PCLAN+ (27247B and 27252A) support" | 78 | tristate "HP PCLAN+ (27247B and 27252A) support" |
103 | depends on ISA | 79 | depends on ISA |
@@ -140,18 +116,6 @@ config ARM_ETHERH | |||
140 | If you have an Acorn system with one of these network cards, you | 116 | If you have an Acorn system with one of these network cards, you |
141 | should say Y to this option if you wish to use it with Linux. | 117 | should say Y to this option if you wish to use it with Linux. |
142 | 118 | ||
143 | config LNE390 | ||
144 | tristate "Mylex EISA LNE390A/B support (EXPERIMENTAL)" | ||
145 | depends on PCI && EISA && EXPERIMENTAL | ||
146 | select CRC32 | ||
147 | ---help--- | ||
148 | If you have a network (Ethernet) card of this type, say Y and read | ||
149 | the Ethernet-HOWTO, available from | ||
150 | <http://www.tldp.org/docs.html#howto>. | ||
151 | |||
152 | To compile this driver as a module, choose M here. The module | ||
153 | will be called lne390. | ||
154 | |||
155 | config MAC8390 | 119 | config MAC8390 |
156 | bool "Macintosh NS 8390 based ethernet cards" | 120 | bool "Macintosh NS 8390 based ethernet cards" |
157 | depends on MAC | 121 | depends on MAC |
@@ -187,8 +151,7 @@ config NE2000 | |||
187 | without a specific driver are compatible with NE2000. | 151 | without a specific driver are compatible with NE2000. |
188 | 152 | ||
189 | If you have a PCI NE2000 card however, say N here and Y to "PCI | 153 | If you have a PCI NE2000 card however, say N here and Y to "PCI |
190 | NE2000 and clone support" under "EISA, VLB, PCI and on board | 154 | NE2000 and clone support" below. |
191 | controllers" below. | ||
192 | 155 | ||
193 | To compile this driver as a module, choose M here. The module | 156 | To compile this driver as a module, choose M here. The module |
194 | will be called ne. | 157 | will be called ne. |
@@ -223,19 +186,6 @@ config APNE | |||
223 | To compile this driver as a module, choose M here: the module | 186 | To compile this driver as a module, choose M here: the module |
224 | will be called apne. | 187 | will be called apne. |
225 | 188 | ||
226 | config NE3210 | ||
227 | tristate "Novell/Eagle/Microdyne NE3210 EISA support (EXPERIMENTAL)" | ||
228 | depends on PCI && EISA && EXPERIMENTAL | ||
229 | select CRC32 | ||
230 | ---help--- | ||
231 | If you have a network (Ethernet) card of this type, say Y and read | ||
232 | the Ethernet-HOWTO, available from | ||
233 | <http://www.tldp.org/docs.html#howto>. Note that this driver | ||
234 | will NOT WORK for NE3200 cards as they are completely different. | ||
235 | |||
236 | To compile this driver as a module, choose M here. The module | ||
237 | will be called ne3210. | ||
238 | |||
239 | config PCMCIA_PCNET | 189 | config PCMCIA_PCNET |
240 | tristate "NE2000 compatible PCMCIA support" | 190 | tristate "NE2000 compatible PCMCIA support" |
241 | depends on PCMCIA | 191 | depends on PCMCIA |
@@ -285,18 +235,6 @@ config ULTRA | |||
285 | To compile this driver as a module, choose M here. The module | 235 | To compile this driver as a module, choose M here. The module |
286 | will be called smc-ultra. | 236 | will be called smc-ultra. |
287 | 237 | ||
288 | config ULTRA32 | ||
289 | tristate "SMC Ultra32 EISA support" | ||
290 | depends on EISA | ||
291 | select CRC32 | ||
292 | ---help--- | ||
293 | If you have a network (Ethernet) card of this type, say Y and read | ||
294 | the Ethernet-HOWTO, available from | ||
295 | <http://www.tldp.org/docs.html#howto>. | ||
296 | |||
297 | To compile this driver as a module, choose M here. The module | ||
298 | will be called smc-ultra32. | ||
299 | |||
300 | config WD80x3 | 238 | config WD80x3 |
301 | tristate "WD80*3 support" | 239 | tristate "WD80*3 support" |
302 | depends on ISA | 240 | depends on ISA |
diff --git a/drivers/net/ethernet/8390/Makefile b/drivers/net/ethernet/8390/Makefile index 8fb462cb9774..e8bb97cd355f 100644 --- a/drivers/net/ethernet/8390/Makefile +++ b/drivers/net/ethernet/8390/Makefile | |||
@@ -3,26 +3,21 @@ | |||
3 | # | 3 | # |
4 | 4 | ||
5 | obj-$(CONFIG_MAC8390) += mac8390.o | 5 | obj-$(CONFIG_MAC8390) += mac8390.o |
6 | obj-$(CONFIG_AC3200) += ac3200.o 8390.o | ||
7 | obj-$(CONFIG_APNE) += apne.o 8390.o | 6 | obj-$(CONFIG_APNE) += apne.o 8390.o |
8 | obj-$(CONFIG_ARM_ETHERH) += etherh.o | 7 | obj-$(CONFIG_ARM_ETHERH) += etherh.o |
9 | obj-$(CONFIG_AX88796) += ax88796.o | 8 | obj-$(CONFIG_AX88796) += ax88796.o |
10 | obj-$(CONFIG_E2100) += e2100.o 8390.o | 9 | obj-$(CONFIG_E2100) += e2100.o 8390.o |
11 | obj-$(CONFIG_EL2) += 3c503.o 8390p.o | 10 | obj-$(CONFIG_EL2) += 3c503.o 8390p.o |
12 | obj-$(CONFIG_ES3210) += es3210.o 8390.o | ||
13 | obj-$(CONFIG_HPLAN_PLUS) += hp-plus.o 8390p.o | 11 | obj-$(CONFIG_HPLAN_PLUS) += hp-plus.o 8390p.o |
14 | obj-$(CONFIG_HPLAN) += hp.o 8390p.o | 12 | obj-$(CONFIG_HPLAN) += hp.o 8390p.o |
15 | obj-$(CONFIG_HYDRA) += hydra.o 8390.o | 13 | obj-$(CONFIG_HYDRA) += hydra.o 8390.o |
16 | obj-$(CONFIG_LNE390) += lne390.o 8390.o | ||
17 | obj-$(CONFIG_MCF8390) += mcf8390.o 8390.o | 14 | obj-$(CONFIG_MCF8390) += mcf8390.o 8390.o |
18 | obj-$(CONFIG_NE2000) += ne.o 8390p.o | 15 | obj-$(CONFIG_NE2000) += ne.o 8390p.o |
19 | obj-$(CONFIG_NE2K_PCI) += ne2k-pci.o 8390.o | 16 | obj-$(CONFIG_NE2K_PCI) += ne2k-pci.o 8390.o |
20 | obj-$(CONFIG_NE3210) += ne3210.o 8390.o | ||
21 | obj-$(CONFIG_NE_H8300) += ne-h8300.o 8390.o | 17 | obj-$(CONFIG_NE_H8300) += ne-h8300.o 8390.o |
22 | obj-$(CONFIG_PCMCIA_AXNET) += axnet_cs.o 8390.o | 18 | obj-$(CONFIG_PCMCIA_AXNET) += axnet_cs.o 8390.o |
23 | obj-$(CONFIG_PCMCIA_PCNET) += pcnet_cs.o 8390.o | 19 | obj-$(CONFIG_PCMCIA_PCNET) += pcnet_cs.o 8390.o |
24 | obj-$(CONFIG_STNIC) += stnic.o 8390.o | 20 | obj-$(CONFIG_STNIC) += stnic.o 8390.o |
25 | obj-$(CONFIG_ULTRA) += smc-ultra.o 8390.o | 21 | obj-$(CONFIG_ULTRA) += smc-ultra.o 8390.o |
26 | obj-$(CONFIG_ULTRA32) += smc-ultra32.o 8390.o | ||
27 | obj-$(CONFIG_WD80x3) += wd.o 8390.o | 22 | obj-$(CONFIG_WD80x3) += wd.o 8390.o |
28 | obj-$(CONFIG_ZORRO8390) += zorro8390.o 8390.o | 23 | obj-$(CONFIG_ZORRO8390) += zorro8390.o 8390.o |
diff --git a/drivers/net/ethernet/8390/ac3200.c b/drivers/net/ethernet/8390/ac3200.c deleted file mode 100644 index ccf07942ff6e..000000000000 --- a/drivers/net/ethernet/8390/ac3200.c +++ /dev/null | |||
@@ -1,431 +0,0 @@ | |||
1 | /* ac3200.c: A driver for the Ansel Communications EISA ethernet adaptor. */ | ||
2 | /* | ||
3 | Written 1993, 1994 by Donald Becker. | ||
4 | Copyright 1993 United States Government as represented by the Director, | ||
5 | National Security Agency. This software may only be used and distributed | ||
6 | according to the terms of the GNU General Public License as modified by SRC, | ||
7 | incorporated herein by reference. | ||
8 | |||
9 | The author may be reached as becker@scyld.com, or C/O | ||
10 | Scyld Computing Corporation | ||
11 | 410 Severn Ave., Suite 210 | ||
12 | Annapolis MD 21403 | ||
13 | |||
14 | This is driver for the Ansel Communications Model 3200 EISA Ethernet LAN | ||
15 | Adapter. The programming information is from the users manual, as related | ||
16 | by glee@ardnassak.math.clemson.edu. | ||
17 | |||
18 | Changelog: | ||
19 | |||
20 | Paul Gortmaker 05/98 : add support for shared mem above 1MB. | ||
21 | |||
22 | */ | ||
23 | |||
24 | static const char version[] = | ||
25 | "ac3200.c:v1.01 7/1/94 Donald Becker (becker@cesdis.gsfc.nasa.gov)\n"; | ||
26 | |||
27 | #include <linux/module.h> | ||
28 | #include <linux/eisa.h> | ||
29 | #include <linux/kernel.h> | ||
30 | #include <linux/errno.h> | ||
31 | #include <linux/string.h> | ||
32 | #include <linux/netdevice.h> | ||
33 | #include <linux/etherdevice.h> | ||
34 | #include <linux/init.h> | ||
35 | #include <linux/interrupt.h> | ||
36 | |||
37 | #include <asm/io.h> | ||
38 | #include <asm/irq.h> | ||
39 | |||
40 | #include "8390.h" | ||
41 | |||
42 | #define DRV_NAME "ac3200" | ||
43 | |||
44 | /* Offsets from the base address. */ | ||
45 | #define AC_NIC_BASE 0x00 | ||
46 | #define AC_SA_PROM 0x16 /* The station address PROM. */ | ||
47 | #define AC_ADDR0 0x00 /* Prefix station address values. */ | ||
48 | #define AC_ADDR1 0x40 | ||
49 | #define AC_ADDR2 0x90 | ||
50 | #define AC_ID_PORT 0xC80 | ||
51 | #define AC_EISA_ID 0x0110d305 | ||
52 | #define AC_RESET_PORT 0xC84 | ||
53 | #define AC_RESET 0x00 | ||
54 | #define AC_ENABLE 0x01 | ||
55 | #define AC_CONFIG 0xC90 /* The configuration port. */ | ||
56 | |||
57 | #define AC_IO_EXTENT 0x20 | ||
58 | /* Actually accessed is: | ||
59 | * AC_NIC_BASE (0-15) | ||
60 | * AC_SA_PROM (0-5) | ||
61 | * AC_ID_PORT (0-3) | ||
62 | * AC_RESET_PORT | ||
63 | * AC_CONFIG | ||
64 | */ | ||
65 | |||
66 | /* Decoding of the configuration register. */ | ||
67 | static unsigned char config2irqmap[8] __initdata = {15, 12, 11, 10, 9, 7, 5, 3}; | ||
68 | static int addrmap[8] = | ||
69 | {0xFF0000, 0xFE0000, 0xFD0000, 0xFFF0000, 0xFFE0000, 0xFFC0000, 0xD0000, 0 }; | ||
70 | static const char *port_name[4] = { "10baseT", "invalid", "AUI", "10base2"}; | ||
71 | |||
72 | #define config2irq(configval) config2irqmap[((configval) >> 3) & 7] | ||
73 | #define config2mem(configval) addrmap[(configval) & 7] | ||
74 | #define config2name(configval) port_name[((configval) >> 6) & 3] | ||
75 | |||
76 | /* First and last 8390 pages. */ | ||
77 | #define AC_START_PG 0x00 /* First page of 8390 TX buffer */ | ||
78 | #define AC_STOP_PG 0x80 /* Last page +1 of the 8390 RX ring */ | ||
79 | |||
80 | static int ac_probe1(int ioaddr, struct net_device *dev); | ||
81 | |||
82 | static int ac_open(struct net_device *dev); | ||
83 | static void ac_reset_8390(struct net_device *dev); | ||
84 | static void ac_block_input(struct net_device *dev, int count, | ||
85 | struct sk_buff *skb, int ring_offset); | ||
86 | static void ac_block_output(struct net_device *dev, const int count, | ||
87 | const unsigned char *buf, const int start_page); | ||
88 | static void ac_get_8390_hdr(struct net_device *dev, struct e8390_pkt_hdr *hdr, | ||
89 | int ring_page); | ||
90 | |||
91 | static int ac_close_card(struct net_device *dev); | ||
92 | |||
93 | |||
94 | /* Probe for the AC3200. | ||
95 | |||
96 | The AC3200 can be identified by either the EISA configuration registers, | ||
97 | or the unique value in the station address PROM. | ||
98 | */ | ||
99 | |||
100 | static int __init do_ac3200_probe(struct net_device *dev) | ||
101 | { | ||
102 | unsigned short ioaddr = dev->base_addr; | ||
103 | int irq = dev->irq; | ||
104 | int mem_start = dev->mem_start; | ||
105 | |||
106 | if (ioaddr > 0x1ff) /* Check a single specified location. */ | ||
107 | return ac_probe1(ioaddr, dev); | ||
108 | else if (ioaddr > 0) /* Don't probe at all. */ | ||
109 | return -ENXIO; | ||
110 | |||
111 | if ( ! EISA_bus) | ||
112 | return -ENXIO; | ||
113 | |||
114 | for (ioaddr = 0x1000; ioaddr < 0x9000; ioaddr += 0x1000) { | ||
115 | if (ac_probe1(ioaddr, dev) == 0) | ||
116 | return 0; | ||
117 | dev->irq = irq; | ||
118 | dev->mem_start = mem_start; | ||
119 | } | ||
120 | |||
121 | return -ENODEV; | ||
122 | } | ||
123 | |||
124 | #ifndef MODULE | ||
125 | struct net_device * __init ac3200_probe(int unit) | ||
126 | { | ||
127 | struct net_device *dev = alloc_ei_netdev(); | ||
128 | int err; | ||
129 | |||
130 | if (!dev) | ||
131 | return ERR_PTR(-ENOMEM); | ||
132 | |||
133 | sprintf(dev->name, "eth%d", unit); | ||
134 | netdev_boot_setup_check(dev); | ||
135 | |||
136 | err = do_ac3200_probe(dev); | ||
137 | if (err) | ||
138 | goto out; | ||
139 | return dev; | ||
140 | out: | ||
141 | free_netdev(dev); | ||
142 | return ERR_PTR(err); | ||
143 | } | ||
144 | #endif | ||
145 | |||
146 | static const struct net_device_ops ac_netdev_ops = { | ||
147 | .ndo_open = ac_open, | ||
148 | .ndo_stop = ac_close_card, | ||
149 | |||
150 | .ndo_start_xmit = ei_start_xmit, | ||
151 | .ndo_tx_timeout = ei_tx_timeout, | ||
152 | .ndo_get_stats = ei_get_stats, | ||
153 | .ndo_set_rx_mode = ei_set_multicast_list, | ||
154 | .ndo_validate_addr = eth_validate_addr, | ||
155 | .ndo_set_mac_address = eth_mac_addr, | ||
156 | .ndo_change_mtu = eth_change_mtu, | ||
157 | #ifdef CONFIG_NET_POLL_CONTROLLER | ||
158 | .ndo_poll_controller = ei_poll, | ||
159 | #endif | ||
160 | }; | ||
161 | |||
162 | static int __init ac_probe1(int ioaddr, struct net_device *dev) | ||
163 | { | ||
164 | int i, retval; | ||
165 | |||
166 | if (!request_region(ioaddr, AC_IO_EXTENT, DRV_NAME)) | ||
167 | return -EBUSY; | ||
168 | |||
169 | if (inb_p(ioaddr + AC_ID_PORT) == 0xff) { | ||
170 | retval = -ENODEV; | ||
171 | goto out; | ||
172 | } | ||
173 | |||
174 | if (inl(ioaddr + AC_ID_PORT) != AC_EISA_ID) { | ||
175 | retval = -ENODEV; | ||
176 | goto out; | ||
177 | } | ||
178 | |||
179 | #ifndef final_version | ||
180 | printk(KERN_DEBUG "AC3200 ethercard configuration register is %#02x," | ||
181 | " EISA ID %02x %02x %02x %02x.\n", inb(ioaddr + AC_CONFIG), | ||
182 | inb(ioaddr + AC_ID_PORT + 0), inb(ioaddr + AC_ID_PORT + 1), | ||
183 | inb(ioaddr + AC_ID_PORT + 2), inb(ioaddr + AC_ID_PORT + 3)); | ||
184 | #endif | ||
185 | |||
186 | for (i = 0; i < 6; i++) | ||
187 | dev->dev_addr[i] = inb(ioaddr + AC_SA_PROM + i); | ||
188 | |||
189 | printk(KERN_DEBUG "AC3200 in EISA slot %d, node %pM", | ||
190 | ioaddr/0x1000, dev->dev_addr); | ||
191 | #if 0 | ||
192 | /* Check the vendor ID/prefix. Redundant after checking the EISA ID */ | ||
193 | if (inb(ioaddr + AC_SA_PROM + 0) != AC_ADDR0 | ||
194 | || inb(ioaddr + AC_SA_PROM + 1) != AC_ADDR1 | ||
195 | || inb(ioaddr + AC_SA_PROM + 2) != AC_ADDR2 ) { | ||
196 | printk(", not found (invalid prefix).\n"); | ||
197 | retval = -ENODEV; | ||
198 | goto out; | ||
199 | } | ||
200 | #endif | ||
201 | |||
202 | /* Assign and allocate the interrupt now. */ | ||
203 | if (dev->irq == 0) { | ||
204 | dev->irq = config2irq(inb(ioaddr + AC_CONFIG)); | ||
205 | printk(", using"); | ||
206 | } else { | ||
207 | dev->irq = irq_canonicalize(dev->irq); | ||
208 | printk(", assigning"); | ||
209 | } | ||
210 | |||
211 | retval = request_irq(dev->irq, ei_interrupt, 0, DRV_NAME, dev); | ||
212 | if (retval) { | ||
213 | printk (" nothing! Unable to get IRQ %d.\n", dev->irq); | ||
214 | goto out; | ||
215 | } | ||
216 | |||
217 | printk(" IRQ %d, %s port\n", dev->irq, port_name[dev->if_port]); | ||
218 | |||
219 | dev->base_addr = ioaddr; | ||
220 | |||
221 | #ifdef notyet | ||
222 | if (dev->mem_start) { /* Override the value from the board. */ | ||
223 | for (i = 0; i < 7; i++) | ||
224 | if (addrmap[i] == dev->mem_start) | ||
225 | break; | ||
226 | if (i >= 7) | ||
227 | i = 0; | ||
228 | outb((inb(ioaddr + AC_CONFIG) & ~7) | i, ioaddr + AC_CONFIG); | ||
229 | } | ||
230 | #endif | ||
231 | |||
232 | dev->if_port = inb(ioaddr + AC_CONFIG) >> 6; | ||
233 | dev->mem_start = config2mem(inb(ioaddr + AC_CONFIG)); | ||
234 | |||
235 | printk("%s: AC3200 at %#3x with %dkB memory at physical address %#lx.\n", | ||
236 | dev->name, ioaddr, AC_STOP_PG/4, dev->mem_start); | ||
237 | |||
238 | /* | ||
239 | * BEWARE!! Some dain-bramaged EISA SCUs will allow you to put | ||
240 | * the card mem within the region covered by `normal' RAM !!! | ||
241 | * | ||
242 | * ioremap() will fail in that case. | ||
243 | */ | ||
244 | ei_status.mem = ioremap(dev->mem_start, AC_STOP_PG*0x100); | ||
245 | if (!ei_status.mem) { | ||
246 | printk(KERN_ERR "ac3200.c: Unable to remap card memory above 1MB !!\n"); | ||
247 | printk(KERN_ERR "ac3200.c: Try using EISA SCU to set memory below 1MB.\n"); | ||
248 | printk(KERN_ERR "ac3200.c: Driver NOT installed.\n"); | ||
249 | retval = -EINVAL; | ||
250 | goto out1; | ||
251 | } | ||
252 | printk("ac3200.c: remapped %dkB card memory to virtual address %p\n", | ||
253 | AC_STOP_PG/4, ei_status.mem); | ||
254 | |||
255 | dev->mem_start = (unsigned long)ei_status.mem; | ||
256 | dev->mem_end = dev->mem_start + (AC_STOP_PG - AC_START_PG)*256; | ||
257 | |||
258 | ei_status.name = "AC3200"; | ||
259 | ei_status.tx_start_page = AC_START_PG; | ||
260 | ei_status.rx_start_page = AC_START_PG + TX_PAGES; | ||
261 | ei_status.stop_page = AC_STOP_PG; | ||
262 | ei_status.word16 = 1; | ||
263 | |||
264 | if (ei_debug > 0) | ||
265 | printk(version); | ||
266 | |||
267 | ei_status.reset_8390 = &ac_reset_8390; | ||
268 | ei_status.block_input = &ac_block_input; | ||
269 | ei_status.block_output = &ac_block_output; | ||
270 | ei_status.get_8390_hdr = &ac_get_8390_hdr; | ||
271 | |||
272 | dev->netdev_ops = &ac_netdev_ops; | ||
273 | NS8390_init(dev, 0); | ||
274 | |||
275 | retval = register_netdev(dev); | ||
276 | if (retval) | ||
277 | goto out2; | ||
278 | return 0; | ||
279 | out2: | ||
280 | if (ei_status.reg0) | ||
281 | iounmap(ei_status.mem); | ||
282 | out1: | ||
283 | free_irq(dev->irq, dev); | ||
284 | out: | ||
285 | release_region(ioaddr, AC_IO_EXTENT); | ||
286 | return retval; | ||
287 | } | ||
288 | |||
289 | static int ac_open(struct net_device *dev) | ||
290 | { | ||
291 | #ifdef notyet | ||
292 | /* Someday we may enable the IRQ and shared memory here. */ | ||
293 | int ioaddr = dev->base_addr; | ||
294 | #endif | ||
295 | |||
296 | ei_open(dev); | ||
297 | return 0; | ||
298 | } | ||
299 | |||
300 | static void ac_reset_8390(struct net_device *dev) | ||
301 | { | ||
302 | ushort ioaddr = dev->base_addr; | ||
303 | |||
304 | outb(AC_RESET, ioaddr + AC_RESET_PORT); | ||
305 | if (ei_debug > 1) printk("resetting AC3200, t=%ld...", jiffies); | ||
306 | |||
307 | ei_status.txing = 0; | ||
308 | outb(AC_ENABLE, ioaddr + AC_RESET_PORT); | ||
309 | if (ei_debug > 1) printk("reset done\n"); | ||
310 | } | ||
311 | |||
312 | /* Grab the 8390 specific header. Similar to the block_input routine, but | ||
313 | we don't need to be concerned with ring wrap as the header will be at | ||
314 | the start of a page, so we optimize accordingly. */ | ||
315 | |||
316 | static void | ||
317 | ac_get_8390_hdr(struct net_device *dev, struct e8390_pkt_hdr *hdr, int ring_page) | ||
318 | { | ||
319 | void __iomem *hdr_start = ei_status.mem + ((ring_page - AC_START_PG)<<8); | ||
320 | memcpy_fromio(hdr, hdr_start, sizeof(struct e8390_pkt_hdr)); | ||
321 | } | ||
322 | |||
323 | /* Block input and output are easy on shared memory ethercards, the only | ||
324 | complication is when the ring buffer wraps. */ | ||
325 | |||
326 | static void ac_block_input(struct net_device *dev, int count, struct sk_buff *skb, | ||
327 | int ring_offset) | ||
328 | { | ||
329 | void __iomem *start = ei_status.mem + ring_offset - AC_START_PG*256; | ||
330 | |||
331 | if (ring_offset + count > AC_STOP_PG*256) { | ||
332 | /* We must wrap the input move. */ | ||
333 | int semi_count = AC_STOP_PG*256 - ring_offset; | ||
334 | memcpy_fromio(skb->data, start, semi_count); | ||
335 | count -= semi_count; | ||
336 | memcpy_fromio(skb->data + semi_count, | ||
337 | ei_status.mem + TX_PAGES*256, count); | ||
338 | } else { | ||
339 | memcpy_fromio(skb->data, start, count); | ||
340 | } | ||
341 | } | ||
342 | |||
343 | static void ac_block_output(struct net_device *dev, int count, | ||
344 | const unsigned char *buf, int start_page) | ||
345 | { | ||
346 | void __iomem *shmem = ei_status.mem + ((start_page - AC_START_PG)<<8); | ||
347 | |||
348 | memcpy_toio(shmem, buf, count); | ||
349 | } | ||
350 | |||
351 | static int ac_close_card(struct net_device *dev) | ||
352 | { | ||
353 | if (ei_debug > 1) | ||
354 | printk("%s: Shutting down ethercard.\n", dev->name); | ||
355 | |||
356 | #ifdef notyet | ||
357 | /* We should someday disable shared memory and interrupts. */ | ||
358 | outb(0x00, ioaddr + 6); /* Disable interrupts. */ | ||
359 | free_irq(dev->irq, dev); | ||
360 | #endif | ||
361 | |||
362 | ei_close(dev); | ||
363 | return 0; | ||
364 | } | ||
365 | |||
366 | #ifdef MODULE | ||
367 | #define MAX_AC32_CARDS 4 /* Max number of AC32 cards per module */ | ||
368 | static struct net_device *dev_ac32[MAX_AC32_CARDS]; | ||
369 | static int io[MAX_AC32_CARDS]; | ||
370 | static int irq[MAX_AC32_CARDS]; | ||
371 | static int mem[MAX_AC32_CARDS]; | ||
372 | module_param_array(io, int, NULL, 0); | ||
373 | module_param_array(irq, int, NULL, 0); | ||
374 | module_param_array(mem, int, NULL, 0); | ||
375 | MODULE_PARM_DESC(io, "I/O base address(es)"); | ||
376 | MODULE_PARM_DESC(irq, "IRQ number(s)"); | ||
377 | MODULE_PARM_DESC(mem, "Memory base address(es)"); | ||
378 | MODULE_DESCRIPTION("Ansel AC3200 EISA ethernet driver"); | ||
379 | MODULE_LICENSE("GPL"); | ||
380 | |||
381 | static int __init ac3200_module_init(void) | ||
382 | { | ||
383 | struct net_device *dev; | ||
384 | int this_dev, found = 0; | ||
385 | |||
386 | for (this_dev = 0; this_dev < MAX_AC32_CARDS; this_dev++) { | ||
387 | if (io[this_dev] == 0 && this_dev != 0) | ||
388 | break; | ||
389 | dev = alloc_ei_netdev(); | ||
390 | if (!dev) | ||
391 | break; | ||
392 | dev->irq = irq[this_dev]; | ||
393 | dev->base_addr = io[this_dev]; | ||
394 | dev->mem_start = mem[this_dev]; /* Currently ignored by driver */ | ||
395 | if (do_ac3200_probe(dev) == 0) { | ||
396 | dev_ac32[found++] = dev; | ||
397 | continue; | ||
398 | } | ||
399 | free_netdev(dev); | ||
400 | printk(KERN_WARNING "ac3200.c: No ac3200 card found (i/o = 0x%x).\n", io[this_dev]); | ||
401 | break; | ||
402 | } | ||
403 | if (found) | ||
404 | return 0; | ||
405 | return -ENXIO; | ||
406 | } | ||
407 | |||
408 | static void cleanup_card(struct net_device *dev) | ||
409 | { | ||
410 | /* Someday free_irq may be in ac_close_card() */ | ||
411 | free_irq(dev->irq, dev); | ||
412 | release_region(dev->base_addr, AC_IO_EXTENT); | ||
413 | iounmap(ei_status.mem); | ||
414 | } | ||
415 | |||
416 | static void __exit ac3200_module_exit(void) | ||
417 | { | ||
418 | int this_dev; | ||
419 | |||
420 | for (this_dev = 0; this_dev < MAX_AC32_CARDS; this_dev++) { | ||
421 | struct net_device *dev = dev_ac32[this_dev]; | ||
422 | if (dev) { | ||
423 | unregister_netdev(dev); | ||
424 | cleanup_card(dev); | ||
425 | free_netdev(dev); | ||
426 | } | ||
427 | } | ||
428 | } | ||
429 | module_init(ac3200_module_init); | ||
430 | module_exit(ac3200_module_exit); | ||
431 | #endif /* MODULE */ | ||
diff --git a/drivers/net/ethernet/8390/es3210.c b/drivers/net/ethernet/8390/es3210.c deleted file mode 100644 index ba1b5c95531f..000000000000 --- a/drivers/net/ethernet/8390/es3210.c +++ /dev/null | |||
@@ -1,445 +0,0 @@ | |||
1 | /* | ||
2 | es3210.c | ||
3 | |||
4 | Linux driver for Racal-Interlan ES3210 EISA Network Adapter | ||
5 | |||
6 | Copyright (C) 1996, Paul Gortmaker. | ||
7 | |||
8 | This software may be used and distributed according to the terms | ||
9 | of the GNU General Public License, incorporated herein by reference. | ||
10 | |||
11 | Information and Code Sources: | ||
12 | |||
13 | 1) The existing myriad of Linux 8390 drivers written by Donald Becker. | ||
14 | |||
15 | 2) Once again Russ Nelson's asm packet driver provided additional info. | ||
16 | |||
17 | 3) Info for getting IRQ and sh-mem gleaned from the EISA cfg files. | ||
18 | Too bad it doesn't work -- see below. | ||
19 | |||
20 | The ES3210 is an EISA shared memory NS8390 implementation. Note | ||
21 | that all memory copies to/from the board must be 32bit transfers. | ||
22 | Which rules out using eth_io_copy_and_sum() in this driver. | ||
23 | |||
24 | Apparently there are two slightly different revisions of the | ||
25 | card, since there are two distinct EISA cfg files (!rii0101.cfg | ||
26 | and !rii0102.cfg) One has media select in the cfg file and the | ||
27 | other doesn't. Hopefully this will work with either. | ||
28 | |||
29 | That is about all I can tell you about it, having never actually | ||
30 | even seen one of these cards. :) Try http://www.interlan.com | ||
31 | if you want more info. | ||
32 | |||
33 | Thanks go to Mark Salazar for testing v0.02 of this driver. | ||
34 | |||
35 | Bugs, to-fix, etc: | ||
36 | |||
37 | 1) The EISA cfg ports that are *supposed* to have the IRQ and shared | ||
38 | mem values just read 0xff all the time. Hrrmpf. Apparently the | ||
39 | same happens with the packet driver as the code for reading | ||
40 | these registers is disabled there. In the meantime, boot with: | ||
41 | ether=<IRQ>,0,0x<shared_mem_addr>,eth0 to override the IRQ and | ||
42 | shared memory detection. (The i/o port detection is okay.) | ||
43 | |||
44 | 2) Module support currently untested. Probably works though. | ||
45 | |||
46 | */ | ||
47 | |||
48 | static const char version[] = | ||
49 | "es3210.c: Driver revision v0.03, 14/09/96\n"; | ||
50 | |||
51 | #include <linux/module.h> | ||
52 | #include <linux/eisa.h> | ||
53 | #include <linux/kernel.h> | ||
54 | #include <linux/errno.h> | ||
55 | #include <linux/string.h> | ||
56 | #include <linux/init.h> | ||
57 | #include <linux/interrupt.h> | ||
58 | #include <linux/netdevice.h> | ||
59 | #include <linux/etherdevice.h> | ||
60 | |||
61 | #include <asm/io.h> | ||
62 | |||
63 | #include "8390.h" | ||
64 | |||
65 | static int es_probe1(struct net_device *dev, int ioaddr); | ||
66 | |||
67 | static void es_reset_8390(struct net_device *dev); | ||
68 | |||
69 | static void es_get_8390_hdr(struct net_device *dev, struct e8390_pkt_hdr *hdr, int ring_page); | ||
70 | static void es_block_input(struct net_device *dev, int count, struct sk_buff *skb, int ring_offset); | ||
71 | static void es_block_output(struct net_device *dev, int count, const unsigned char *buf, int start_page); | ||
72 | |||
73 | #define ES_START_PG 0x00 /* First page of TX buffer */ | ||
74 | #define ES_STOP_PG 0x40 /* Last page +1 of RX ring */ | ||
75 | |||
76 | #define ES_IO_EXTENT 0x37 /* The cfg file says 0xc90 -> 0xcc7 */ | ||
77 | #define ES_ID_PORT 0xc80 /* Same for all EISA cards */ | ||
78 | #define ES_SA_PROM 0xc90 /* Start of e'net addr. */ | ||
79 | #define ES_RESET_PORT 0xc84 /* From the packet driver source */ | ||
80 | #define ES_NIC_OFFSET 0xca0 /* Hello, the 8390 is *here* */ | ||
81 | |||
82 | #define ES_ADDR0 0x02 /* 3 byte vendor prefix */ | ||
83 | #define ES_ADDR1 0x07 | ||
84 | #define ES_ADDR2 0x01 | ||
85 | |||
86 | /* | ||
87 | * Two card revisions. EISA ID's are always rev. minor, rev. major,, and | ||
88 | * then the three vendor letters stored in 5 bits each, with an "a" = 1. | ||
89 | * For eg: "rii" = 10010 01001 01001 = 0x4929, which is how the EISA | ||
90 | * config utility determines automagically what config file(s) to use. | ||
91 | */ | ||
92 | #define ES_EISA_ID1 0x01012949 /* !rii0101.cfg */ | ||
93 | #define ES_EISA_ID2 0x02012949 /* !rii0102.cfg */ | ||
94 | |||
95 | #define ES_CFG1 0xcc0 /* IOPORT(1) --> IOPORT(6) in cfg file */ | ||
96 | #define ES_CFG2 0xcc1 | ||
97 | #define ES_CFG3 0xcc2 | ||
98 | #define ES_CFG4 0xcc3 | ||
99 | #define ES_CFG5 0xcc4 | ||
100 | #define ES_CFG6 0xc84 /* NB: 0xc84 is also "reset" port. */ | ||
101 | |||
102 | /* | ||
103 | * You can OR any of the following bits together and assign it | ||
104 | * to ES_DEBUG to get verbose driver info during operation. | ||
105 | * Some of these don't do anything yet. | ||
106 | */ | ||
107 | |||
108 | #define ES_D_PROBE 0x01 | ||
109 | #define ES_D_RX_PKT 0x02 | ||
110 | #define ES_D_TX_PKT 0x04 | ||
111 | #define ED_D_IRQ 0x08 | ||
112 | |||
113 | #define ES_DEBUG 0 | ||
114 | |||
115 | static unsigned char lo_irq_map[] __initdata = {3, 4, 5, 6, 7, 9, 10}; | ||
116 | static unsigned char hi_irq_map[] __initdata = {11, 12, 0, 14, 0, 0, 0, 15}; | ||
117 | |||
118 | /* | ||
119 | * Probe for the card. The best way is to read the EISA ID if it | ||
120 | * is known. Then we check the prefix of the station address | ||
121 | * PROM for a match against the Racal-Interlan assigned value. | ||
122 | */ | ||
123 | |||
124 | static int __init do_es_probe(struct net_device *dev) | ||
125 | { | ||
126 | unsigned short ioaddr = dev->base_addr; | ||
127 | int irq = dev->irq; | ||
128 | int mem_start = dev->mem_start; | ||
129 | |||
130 | if (ioaddr > 0x1ff) /* Check a single specified location. */ | ||
131 | return es_probe1(dev, ioaddr); | ||
132 | else if (ioaddr > 0) /* Don't probe at all. */ | ||
133 | return -ENXIO; | ||
134 | |||
135 | if (!EISA_bus) { | ||
136 | #if ES_DEBUG & ES_D_PROBE | ||
137 | printk("es3210.c: Not EISA bus. Not probing high ports.\n"); | ||
138 | #endif | ||
139 | return -ENXIO; | ||
140 | } | ||
141 | |||
142 | /* EISA spec allows for up to 16 slots, but 8 is typical. */ | ||
143 | for (ioaddr = 0x1000; ioaddr < 0x9000; ioaddr += 0x1000) { | ||
144 | if (es_probe1(dev, ioaddr) == 0) | ||
145 | return 0; | ||
146 | dev->irq = irq; | ||
147 | dev->mem_start = mem_start; | ||
148 | } | ||
149 | |||
150 | return -ENODEV; | ||
151 | } | ||
152 | |||
153 | #ifndef MODULE | ||
154 | struct net_device * __init es_probe(int unit) | ||
155 | { | ||
156 | struct net_device *dev = alloc_ei_netdev(); | ||
157 | int err; | ||
158 | |||
159 | if (!dev) | ||
160 | return ERR_PTR(-ENOMEM); | ||
161 | |||
162 | sprintf(dev->name, "eth%d", unit); | ||
163 | netdev_boot_setup_check(dev); | ||
164 | |||
165 | err = do_es_probe(dev); | ||
166 | if (err) | ||
167 | goto out; | ||
168 | return dev; | ||
169 | out: | ||
170 | free_netdev(dev); | ||
171 | return ERR_PTR(err); | ||
172 | } | ||
173 | #endif | ||
174 | |||
175 | static int __init es_probe1(struct net_device *dev, int ioaddr) | ||
176 | { | ||
177 | int i, retval; | ||
178 | unsigned long eisa_id; | ||
179 | |||
180 | if (!request_region(ioaddr + ES_SA_PROM, ES_IO_EXTENT, "es3210")) | ||
181 | return -ENODEV; | ||
182 | |||
183 | #if ES_DEBUG & ES_D_PROBE | ||
184 | printk("es3210.c: probe at %#x, ID %#8x\n", ioaddr, inl(ioaddr + ES_ID_PORT)); | ||
185 | printk("es3210.c: config regs: %#x %#x %#x %#x %#x %#x\n", | ||
186 | inb(ioaddr + ES_CFG1), inb(ioaddr + ES_CFG2), inb(ioaddr + ES_CFG3), | ||
187 | inb(ioaddr + ES_CFG4), inb(ioaddr + ES_CFG5), inb(ioaddr + ES_CFG6)); | ||
188 | #endif | ||
189 | |||
190 | /* Check the EISA ID of the card. */ | ||
191 | eisa_id = inl(ioaddr + ES_ID_PORT); | ||
192 | if ((eisa_id != ES_EISA_ID1) && (eisa_id != ES_EISA_ID2)) { | ||
193 | retval = -ENODEV; | ||
194 | goto out; | ||
195 | } | ||
196 | |||
197 | for (i = 0; i < ETH_ALEN ; i++) | ||
198 | dev->dev_addr[i] = inb(ioaddr + ES_SA_PROM + i); | ||
199 | |||
200 | /* Check the Racal vendor ID as well. */ | ||
201 | if (dev->dev_addr[0] != ES_ADDR0 || | ||
202 | dev->dev_addr[1] != ES_ADDR1 || | ||
203 | dev->dev_addr[2] != ES_ADDR2) { | ||
204 | printk("es3210.c: card not found %pM (invalid_prefix).\n", | ||
205 | dev->dev_addr); | ||
206 | retval = -ENODEV; | ||
207 | goto out; | ||
208 | } | ||
209 | |||
210 | printk("es3210.c: ES3210 rev. %ld at %#x, node %pM", | ||
211 | eisa_id>>24, ioaddr, dev->dev_addr); | ||
212 | |||
213 | /* Snarf the interrupt now. */ | ||
214 | if (dev->irq == 0) { | ||
215 | unsigned char hi_irq = inb(ioaddr + ES_CFG2) & 0x07; | ||
216 | unsigned char lo_irq = inb(ioaddr + ES_CFG1) & 0xfe; | ||
217 | |||
218 | if (hi_irq != 0) { | ||
219 | dev->irq = hi_irq_map[hi_irq - 1]; | ||
220 | } else { | ||
221 | int i = 0; | ||
222 | while (lo_irq > (1<<i)) i++; | ||
223 | dev->irq = lo_irq_map[i]; | ||
224 | } | ||
225 | printk(" using IRQ %d", dev->irq); | ||
226 | #if ES_DEBUG & ES_D_PROBE | ||
227 | printk("es3210.c: hi_irq %#x, lo_irq %#x, dev->irq = %d\n", | ||
228 | hi_irq, lo_irq, dev->irq); | ||
229 | #endif | ||
230 | } else { | ||
231 | if (dev->irq == 2) | ||
232 | dev->irq = 9; /* Doh! */ | ||
233 | printk(" assigning IRQ %d", dev->irq); | ||
234 | } | ||
235 | |||
236 | if (request_irq(dev->irq, ei_interrupt, 0, "es3210", dev)) { | ||
237 | printk (" unable to get IRQ %d.\n", dev->irq); | ||
238 | retval = -EAGAIN; | ||
239 | goto out; | ||
240 | } | ||
241 | |||
242 | if (dev->mem_start == 0) { | ||
243 | unsigned char mem_enabled = inb(ioaddr + ES_CFG2) & 0xc0; | ||
244 | unsigned char mem_bits = inb(ioaddr + ES_CFG3) & 0x07; | ||
245 | |||
246 | if (mem_enabled != 0x80) { | ||
247 | printk(" shared mem disabled - giving up\n"); | ||
248 | retval = -ENXIO; | ||
249 | goto out1; | ||
250 | } | ||
251 | dev->mem_start = 0xC0000 + mem_bits*0x4000; | ||
252 | printk(" using "); | ||
253 | } else { | ||
254 | printk(" assigning "); | ||
255 | } | ||
256 | |||
257 | ei_status.mem = ioremap(dev->mem_start, (ES_STOP_PG - ES_START_PG)*256); | ||
258 | if (!ei_status.mem) { | ||
259 | printk("ioremap failed - giving up\n"); | ||
260 | retval = -ENXIO; | ||
261 | goto out1; | ||
262 | } | ||
263 | |||
264 | dev->mem_end = dev->mem_start + (ES_STOP_PG - ES_START_PG)*256; | ||
265 | |||
266 | printk("mem %#lx-%#lx\n", dev->mem_start, dev->mem_end-1); | ||
267 | |||
268 | #if ES_DEBUG & ES_D_PROBE | ||
269 | if (inb(ioaddr + ES_CFG5)) | ||
270 | printk("es3210: Warning - DMA channel enabled, but not used here.\n"); | ||
271 | #endif | ||
272 | /* Note, point at the 8390, and not the card... */ | ||
273 | dev->base_addr = ioaddr + ES_NIC_OFFSET; | ||
274 | |||
275 | ei_status.name = "ES3210"; | ||
276 | ei_status.tx_start_page = ES_START_PG; | ||
277 | ei_status.rx_start_page = ES_START_PG + TX_PAGES; | ||
278 | ei_status.stop_page = ES_STOP_PG; | ||
279 | ei_status.word16 = 1; | ||
280 | |||
281 | if (ei_debug > 0) | ||
282 | printk(version); | ||
283 | |||
284 | ei_status.reset_8390 = &es_reset_8390; | ||
285 | ei_status.block_input = &es_block_input; | ||
286 | ei_status.block_output = &es_block_output; | ||
287 | ei_status.get_8390_hdr = &es_get_8390_hdr; | ||
288 | |||
289 | dev->netdev_ops = &ei_netdev_ops; | ||
290 | NS8390_init(dev, 0); | ||
291 | |||
292 | retval = register_netdev(dev); | ||
293 | if (retval) | ||
294 | goto out1; | ||
295 | return 0; | ||
296 | out1: | ||
297 | free_irq(dev->irq, dev); | ||
298 | out: | ||
299 | release_region(ioaddr + ES_SA_PROM, ES_IO_EXTENT); | ||
300 | return retval; | ||
301 | } | ||
302 | |||
303 | /* | ||
304 | * Reset as per the packet driver method. Judging by the EISA cfg | ||
305 | * file, this just toggles the "Board Enable" bits (bit 2 and 0). | ||
306 | */ | ||
307 | |||
308 | static void es_reset_8390(struct net_device *dev) | ||
309 | { | ||
310 | unsigned short ioaddr = dev->base_addr; | ||
311 | unsigned long end; | ||
312 | |||
313 | outb(0x04, ioaddr + ES_RESET_PORT); | ||
314 | if (ei_debug > 1) printk("%s: resetting the ES3210...", dev->name); | ||
315 | |||
316 | end = jiffies + 2*HZ/100; | ||
317 | while ((signed)(end - jiffies) > 0) continue; | ||
318 | |||
319 | ei_status.txing = 0; | ||
320 | outb(0x01, ioaddr + ES_RESET_PORT); | ||
321 | if (ei_debug > 1) printk("reset done\n"); | ||
322 | } | ||
323 | |||
324 | /* | ||
325 | * Note: In the following three functions is the implicit assumption | ||
326 | * that the associated memcpy will only use "rep; movsl" as long as | ||
327 | * we keep the counts as some multiple of doublewords. This is a | ||
328 | * requirement of the hardware, and also prevents us from using | ||
329 | * eth_io_copy_and_sum() since we can't guarantee it will limit | ||
330 | * itself to doubleword access. | ||
331 | */ | ||
332 | |||
333 | /* | ||
334 | * Grab the 8390 specific header. Similar to the block_input routine, but | ||
335 | * we don't need to be concerned with ring wrap as the header will be at | ||
336 | * the start of a page, so we optimize accordingly. (A single doubleword.) | ||
337 | */ | ||
338 | |||
339 | static void | ||
340 | es_get_8390_hdr(struct net_device *dev, struct e8390_pkt_hdr *hdr, int ring_page) | ||
341 | { | ||
342 | void __iomem *hdr_start = ei_status.mem + ((ring_page - ES_START_PG)<<8); | ||
343 | memcpy_fromio(hdr, hdr_start, sizeof(struct e8390_pkt_hdr)); | ||
344 | hdr->count = (hdr->count + 3) & ~3; /* Round up allocation. */ | ||
345 | } | ||
346 | |||
347 | /* | ||
348 | * Block input and output are easy on shared memory ethercards, the only | ||
349 | * complication is when the ring buffer wraps. The count will already | ||
350 | * be rounded up to a doubleword value via es_get_8390_hdr() above. | ||
351 | */ | ||
352 | |||
353 | static void es_block_input(struct net_device *dev, int count, struct sk_buff *skb, | ||
354 | int ring_offset) | ||
355 | { | ||
356 | void __iomem *xfer_start = ei_status.mem + ring_offset - ES_START_PG*256; | ||
357 | |||
358 | if (ring_offset + count > ES_STOP_PG*256) { | ||
359 | /* Packet wraps over end of ring buffer. */ | ||
360 | int semi_count = ES_STOP_PG*256 - ring_offset; | ||
361 | memcpy_fromio(skb->data, xfer_start, semi_count); | ||
362 | count -= semi_count; | ||
363 | memcpy_fromio(skb->data + semi_count, ei_status.mem, count); | ||
364 | } else { | ||
365 | /* Packet is in one chunk. */ | ||
366 | memcpy_fromio(skb->data, xfer_start, count); | ||
367 | } | ||
368 | } | ||
369 | |||
370 | static void es_block_output(struct net_device *dev, int count, | ||
371 | const unsigned char *buf, int start_page) | ||
372 | { | ||
373 | void __iomem *shmem = ei_status.mem + ((start_page - ES_START_PG)<<8); | ||
374 | |||
375 | count = (count + 3) & ~3; /* Round up to doubleword */ | ||
376 | memcpy_toio(shmem, buf, count); | ||
377 | } | ||
378 | |||
379 | #ifdef MODULE | ||
380 | #define MAX_ES_CARDS 4 /* Max number of ES3210 cards per module */ | ||
381 | #define NAMELEN 8 /* # of chars for storing dev->name */ | ||
382 | static struct net_device *dev_es3210[MAX_ES_CARDS]; | ||
383 | static int io[MAX_ES_CARDS]; | ||
384 | static int irq[MAX_ES_CARDS]; | ||
385 | static int mem[MAX_ES_CARDS]; | ||
386 | |||
387 | module_param_array(io, int, NULL, 0); | ||
388 | module_param_array(irq, int, NULL, 0); | ||
389 | module_param_array(mem, int, NULL, 0); | ||
390 | MODULE_PARM_DESC(io, "I/O base address(es)"); | ||
391 | MODULE_PARM_DESC(irq, "IRQ number(s)"); | ||
392 | MODULE_PARM_DESC(mem, "memory base address(es)"); | ||
393 | MODULE_DESCRIPTION("Racal-Interlan ES3210 EISA ethernet driver"); | ||
394 | MODULE_LICENSE("GPL"); | ||
395 | |||
396 | int __init init_module(void) | ||
397 | { | ||
398 | struct net_device *dev; | ||
399 | int this_dev, found = 0; | ||
400 | |||
401 | for (this_dev = 0; this_dev < MAX_ES_CARDS; this_dev++) { | ||
402 | if (io[this_dev] == 0 && this_dev != 0) | ||
403 | break; | ||
404 | dev = alloc_ei_netdev(); | ||
405 | if (!dev) | ||
406 | break; | ||
407 | dev->irq = irq[this_dev]; | ||
408 | dev->base_addr = io[this_dev]; | ||
409 | dev->mem_start = mem[this_dev]; | ||
410 | if (do_es_probe(dev) == 0) { | ||
411 | dev_es3210[found++] = dev; | ||
412 | continue; | ||
413 | } | ||
414 | free_netdev(dev); | ||
415 | printk(KERN_WARNING "es3210.c: No es3210 card found (i/o = 0x%x).\n", io[this_dev]); | ||
416 | break; | ||
417 | } | ||
418 | if (found) | ||
419 | return 0; | ||
420 | return -ENXIO; | ||
421 | } | ||
422 | |||
423 | static void cleanup_card(struct net_device *dev) | ||
424 | { | ||
425 | free_irq(dev->irq, dev); | ||
426 | release_region(dev->base_addr, ES_IO_EXTENT); | ||
427 | iounmap(ei_status.mem); | ||
428 | } | ||
429 | |||
430 | void __exit | ||
431 | cleanup_module(void) | ||
432 | { | ||
433 | int this_dev; | ||
434 | |||
435 | for (this_dev = 0; this_dev < MAX_ES_CARDS; this_dev++) { | ||
436 | struct net_device *dev = dev_es3210[this_dev]; | ||
437 | if (dev) { | ||
438 | unregister_netdev(dev); | ||
439 | cleanup_card(dev); | ||
440 | free_netdev(dev); | ||
441 | } | ||
442 | } | ||
443 | } | ||
444 | #endif /* MODULE */ | ||
445 | |||
diff --git a/drivers/net/ethernet/8390/lne390.c b/drivers/net/ethernet/8390/lne390.c deleted file mode 100644 index 479409bf2e3c..000000000000 --- a/drivers/net/ethernet/8390/lne390.c +++ /dev/null | |||
@@ -1,433 +0,0 @@ | |||
1 | /* | ||
2 | lne390.c | ||
3 | |||
4 | Linux driver for Mylex LNE390 EISA Network Adapter | ||
5 | |||
6 | Copyright (C) 1996-1998, Paul Gortmaker. | ||
7 | |||
8 | This software may be used and distributed according to the terms | ||
9 | of the GNU General Public License, incorporated herein by reference. | ||
10 | |||
11 | Information and Code Sources: | ||
12 | |||
13 | 1) Based upon framework of es3210 driver. | ||
14 | 2) The existing myriad of other Linux 8390 drivers by Donald Becker. | ||
15 | 3) Russ Nelson's asm packet driver provided additional info. | ||
16 | 4) Info for getting IRQ and sh-mem gleaned from the EISA cfg files. | ||
17 | |||
18 | The LNE390 is an EISA shared memory NS8390 implementation. Note | ||
19 | that all memory copies to/from the board must be 32bit transfers. | ||
20 | There are two versions of the card: the lne390a and the lne390b. | ||
21 | Going by the EISA cfg files, the "a" has jumpers to select between | ||
22 | BNC/AUI, but the "b" also has RJ-45 and selection is via the SCU. | ||
23 | The shared memory address selection is also slightly different. | ||
24 | Note that shared memory address > 1MB are supported with this driver. | ||
25 | |||
26 | You can try <http://www.mylex.com> if you want more info, as I've | ||
27 | never even seen one of these cards. :) | ||
28 | |||
29 | Arnaldo Carvalho de Melo <acme@conectiva.com.br> - 2000/09/01 | ||
30 | - get rid of check_region | ||
31 | - no need to check if dev == NULL in lne390_probe1 | ||
32 | */ | ||
33 | |||
34 | static const char *version = | ||
35 | "lne390.c: Driver revision v0.99.1, 01/09/2000\n"; | ||
36 | |||
37 | #include <linux/module.h> | ||
38 | #include <linux/eisa.h> | ||
39 | #include <linux/kernel.h> | ||
40 | #include <linux/errno.h> | ||
41 | #include <linux/string.h> | ||
42 | #include <linux/delay.h> | ||
43 | #include <linux/init.h> | ||
44 | #include <linux/interrupt.h> | ||
45 | #include <linux/netdevice.h> | ||
46 | #include <linux/etherdevice.h> | ||
47 | |||
48 | #include <asm/io.h> | ||
49 | |||
50 | #include "8390.h" | ||
51 | |||
52 | #define DRV_NAME "lne390" | ||
53 | |||
54 | static int lne390_probe1(struct net_device *dev, int ioaddr); | ||
55 | |||
56 | static void lne390_reset_8390(struct net_device *dev); | ||
57 | |||
58 | static void lne390_get_8390_hdr(struct net_device *dev, struct e8390_pkt_hdr *hdr, int ring_page); | ||
59 | static void lne390_block_input(struct net_device *dev, int count, struct sk_buff *skb, int ring_offset); | ||
60 | static void lne390_block_output(struct net_device *dev, int count, const unsigned char *buf, const int start_page); | ||
61 | |||
62 | #define LNE390_START_PG 0x00 /* First page of TX buffer */ | ||
63 | #define LNE390_STOP_PG 0x80 /* Last page +1 of RX ring */ | ||
64 | |||
65 | #define LNE390_ID_PORT 0xc80 /* Same for all EISA cards */ | ||
66 | #define LNE390_IO_EXTENT 0x20 | ||
67 | #define LNE390_SA_PROM 0x16 /* Start of e'net addr. */ | ||
68 | #define LNE390_RESET_PORT 0xc84 /* From the pkt driver source */ | ||
69 | #define LNE390_NIC_OFFSET 0x00 /* Hello, the 8390 is *here* */ | ||
70 | |||
71 | #define LNE390_ADDR0 0x00 /* 3 byte vendor prefix */ | ||
72 | #define LNE390_ADDR1 0x80 | ||
73 | #define LNE390_ADDR2 0xe5 | ||
74 | |||
75 | #define LNE390_ID0 0x10009835 /* 0x3598 = 01101 01100 11000 = mlx */ | ||
76 | #define LNE390_ID1 0x11009835 /* above is the 390A, this is 390B */ | ||
77 | |||
78 | #define LNE390_CFG1 0xc84 /* NB: 0xc84 is also "reset" port. */ | ||
79 | #define LNE390_CFG2 0xc90 | ||
80 | |||
81 | /* | ||
82 | * You can OR any of the following bits together and assign it | ||
83 | * to LNE390_DEBUG to get verbose driver info during operation. | ||
84 | * Currently only the probe one is implemented. | ||
85 | */ | ||
86 | |||
87 | #define LNE390_D_PROBE 0x01 | ||
88 | #define LNE390_D_RX_PKT 0x02 | ||
89 | #define LNE390_D_TX_PKT 0x04 | ||
90 | #define LNE390_D_IRQ 0x08 | ||
91 | |||
92 | #define LNE390_DEBUG 0 | ||
93 | |||
94 | static unsigned char irq_map[] __initdata = {15, 12, 11, 10, 9, 7, 5, 3}; | ||
95 | static unsigned int shmem_mapA[] __initdata = {0xff, 0xfe, 0xfd, 0xfff, 0xffe, 0xffc, 0x0d, 0x0}; | ||
96 | static unsigned int shmem_mapB[] __initdata = {0xff, 0xfe, 0x0e, 0xfff, 0xffe, 0xffc, 0x0d, 0x0}; | ||
97 | |||
98 | /* | ||
99 | * Probe for the card. The best way is to read the EISA ID if it | ||
100 | * is known. Then we can check the prefix of the station address | ||
101 | * PROM for a match against the value assigned to Mylex. | ||
102 | */ | ||
103 | |||
104 | static int __init do_lne390_probe(struct net_device *dev) | ||
105 | { | ||
106 | unsigned short ioaddr = dev->base_addr; | ||
107 | int irq = dev->irq; | ||
108 | int mem_start = dev->mem_start; | ||
109 | int ret; | ||
110 | |||
111 | if (ioaddr > 0x1ff) { /* Check a single specified location. */ | ||
112 | if (!request_region(ioaddr, LNE390_IO_EXTENT, DRV_NAME)) | ||
113 | return -EBUSY; | ||
114 | ret = lne390_probe1(dev, ioaddr); | ||
115 | if (ret) | ||
116 | release_region(ioaddr, LNE390_IO_EXTENT); | ||
117 | return ret; | ||
118 | } | ||
119 | else if (ioaddr > 0) /* Don't probe at all. */ | ||
120 | return -ENXIO; | ||
121 | |||
122 | if (!EISA_bus) { | ||
123 | #if LNE390_DEBUG & LNE390_D_PROBE | ||
124 | printk("lne390-debug: Not an EISA bus. Not probing high ports.\n"); | ||
125 | #endif | ||
126 | return -ENXIO; | ||
127 | } | ||
128 | |||
129 | /* EISA spec allows for up to 16 slots, but 8 is typical. */ | ||
130 | for (ioaddr = 0x1000; ioaddr < 0x9000; ioaddr += 0x1000) { | ||
131 | if (!request_region(ioaddr, LNE390_IO_EXTENT, DRV_NAME)) | ||
132 | continue; | ||
133 | if (lne390_probe1(dev, ioaddr) == 0) | ||
134 | return 0; | ||
135 | release_region(ioaddr, LNE390_IO_EXTENT); | ||
136 | dev->irq = irq; | ||
137 | dev->mem_start = mem_start; | ||
138 | } | ||
139 | |||
140 | return -ENODEV; | ||
141 | } | ||
142 | |||
143 | #ifndef MODULE | ||
144 | struct net_device * __init lne390_probe(int unit) | ||
145 | { | ||
146 | struct net_device *dev = alloc_ei_netdev(); | ||
147 | int err; | ||
148 | |||
149 | if (!dev) | ||
150 | return ERR_PTR(-ENOMEM); | ||
151 | |||
152 | sprintf(dev->name, "eth%d", unit); | ||
153 | netdev_boot_setup_check(dev); | ||
154 | |||
155 | err = do_lne390_probe(dev); | ||
156 | if (err) | ||
157 | goto out; | ||
158 | return dev; | ||
159 | out: | ||
160 | free_netdev(dev); | ||
161 | return ERR_PTR(err); | ||
162 | } | ||
163 | #endif | ||
164 | |||
165 | static int __init lne390_probe1(struct net_device *dev, int ioaddr) | ||
166 | { | ||
167 | int i, revision, ret; | ||
168 | unsigned long eisa_id; | ||
169 | |||
170 | if (inb_p(ioaddr + LNE390_ID_PORT) == 0xff) return -ENODEV; | ||
171 | |||
172 | #if LNE390_DEBUG & LNE390_D_PROBE | ||
173 | printk("lne390-debug: probe at %#x, ID %#8x\n", ioaddr, inl(ioaddr + LNE390_ID_PORT)); | ||
174 | printk("lne390-debug: config regs: %#x %#x\n", | ||
175 | inb(ioaddr + LNE390_CFG1), inb(ioaddr + LNE390_CFG2)); | ||
176 | #endif | ||
177 | |||
178 | |||
179 | /* Check the EISA ID of the card. */ | ||
180 | eisa_id = inl(ioaddr + LNE390_ID_PORT); | ||
181 | if ((eisa_id != LNE390_ID0) && (eisa_id != LNE390_ID1)) { | ||
182 | return -ENODEV; | ||
183 | } | ||
184 | |||
185 | revision = (eisa_id >> 24) & 0x01; /* 0 = rev A, 1 rev B */ | ||
186 | |||
187 | #if 0 | ||
188 | /* Check the Mylex vendor ID as well. Not really required. */ | ||
189 | if (inb(ioaddr + LNE390_SA_PROM + 0) != LNE390_ADDR0 | ||
190 | || inb(ioaddr + LNE390_SA_PROM + 1) != LNE390_ADDR1 | ||
191 | || inb(ioaddr + LNE390_SA_PROM + 2) != LNE390_ADDR2 ) { | ||
192 | printk("lne390.c: card not found"); | ||
193 | for (i = 0; i < ETH_ALEN; i++) | ||
194 | printk(" %02x", inb(ioaddr + LNE390_SA_PROM + i)); | ||
195 | printk(" (invalid prefix).\n"); | ||
196 | return -ENODEV; | ||
197 | } | ||
198 | #endif | ||
199 | |||
200 | for (i = 0; i < ETH_ALEN; i++) | ||
201 | dev->dev_addr[i] = inb(ioaddr + LNE390_SA_PROM + i); | ||
202 | printk("lne390.c: LNE390%X in EISA slot %d, address %pM.\n", | ||
203 | 0xa+revision, ioaddr/0x1000, dev->dev_addr); | ||
204 | |||
205 | printk("lne390.c: "); | ||
206 | |||
207 | /* Snarf the interrupt now. CFG file has them all listed as `edge' with share=NO */ | ||
208 | if (dev->irq == 0) { | ||
209 | unsigned char irq_reg = inb(ioaddr + LNE390_CFG2) >> 3; | ||
210 | dev->irq = irq_map[irq_reg & 0x07]; | ||
211 | printk("using"); | ||
212 | } else { | ||
213 | /* This is useless unless we reprogram the card here too */ | ||
214 | if (dev->irq == 2) dev->irq = 9; /* Doh! */ | ||
215 | printk("assigning"); | ||
216 | } | ||
217 | printk(" IRQ %d,", dev->irq); | ||
218 | |||
219 | if ((ret = request_irq(dev->irq, ei_interrupt, 0, DRV_NAME, dev))) { | ||
220 | printk (" unable to get IRQ %d.\n", dev->irq); | ||
221 | return ret; | ||
222 | } | ||
223 | |||
224 | if (dev->mem_start == 0) { | ||
225 | unsigned char mem_reg = inb(ioaddr + LNE390_CFG2) & 0x07; | ||
226 | |||
227 | if (revision) /* LNE390B */ | ||
228 | dev->mem_start = shmem_mapB[mem_reg] * 0x10000; | ||
229 | else /* LNE390A */ | ||
230 | dev->mem_start = shmem_mapA[mem_reg] * 0x10000; | ||
231 | printk(" using "); | ||
232 | } else { | ||
233 | /* Should check for value in shmem_map and reprogram the card to use it */ | ||
234 | dev->mem_start &= 0xfff0000; | ||
235 | printk(" assigning "); | ||
236 | } | ||
237 | |||
238 | printk("%dkB memory at physical address %#lx\n", | ||
239 | LNE390_STOP_PG/4, dev->mem_start); | ||
240 | |||
241 | /* | ||
242 | BEWARE!! Some dain-bramaged EISA SCUs will allow you to put | ||
243 | the card mem within the region covered by `normal' RAM !!! | ||
244 | |||
245 | ioremap() will fail in that case. | ||
246 | */ | ||
247 | ei_status.mem = ioremap(dev->mem_start, LNE390_STOP_PG*0x100); | ||
248 | if (!ei_status.mem) { | ||
249 | printk(KERN_ERR "lne390.c: Unable to remap card memory above 1MB !!\n"); | ||
250 | printk(KERN_ERR "lne390.c: Try using EISA SCU to set memory below 1MB.\n"); | ||
251 | printk(KERN_ERR "lne390.c: Driver NOT installed.\n"); | ||
252 | ret = -EAGAIN; | ||
253 | goto cleanup; | ||
254 | } | ||
255 | printk("lne390.c: remapped %dkB card memory to virtual address %p\n", | ||
256 | LNE390_STOP_PG/4, ei_status.mem); | ||
257 | |||
258 | dev->mem_start = (unsigned long)ei_status.mem; | ||
259 | dev->mem_end = dev->mem_start + (LNE390_STOP_PG - LNE390_START_PG)*256; | ||
260 | |||
261 | /* The 8390 offset is zero for the LNE390 */ | ||
262 | dev->base_addr = ioaddr; | ||
263 | |||
264 | ei_status.name = "LNE390"; | ||
265 | ei_status.tx_start_page = LNE390_START_PG; | ||
266 | ei_status.rx_start_page = LNE390_START_PG + TX_PAGES; | ||
267 | ei_status.stop_page = LNE390_STOP_PG; | ||
268 | ei_status.word16 = 1; | ||
269 | |||
270 | if (ei_debug > 0) | ||
271 | printk(version); | ||
272 | |||
273 | ei_status.reset_8390 = &lne390_reset_8390; | ||
274 | ei_status.block_input = &lne390_block_input; | ||
275 | ei_status.block_output = &lne390_block_output; | ||
276 | ei_status.get_8390_hdr = &lne390_get_8390_hdr; | ||
277 | |||
278 | dev->netdev_ops = &ei_netdev_ops; | ||
279 | NS8390_init(dev, 0); | ||
280 | |||
281 | ret = register_netdev(dev); | ||
282 | if (ret) | ||
283 | goto unmap; | ||
284 | return 0; | ||
285 | unmap: | ||
286 | if (ei_status.reg0) | ||
287 | iounmap(ei_status.mem); | ||
288 | cleanup: | ||
289 | free_irq(dev->irq, dev); | ||
290 | return ret; | ||
291 | } | ||
292 | |||
293 | /* | ||
294 | * Reset as per the packet driver method. Judging by the EISA cfg | ||
295 | * file, this just toggles the "Board Enable" bits (bit 2 and 0). | ||
296 | */ | ||
297 | |||
298 | static void lne390_reset_8390(struct net_device *dev) | ||
299 | { | ||
300 | unsigned short ioaddr = dev->base_addr; | ||
301 | |||
302 | outb(0x04, ioaddr + LNE390_RESET_PORT); | ||
303 | if (ei_debug > 1) printk("%s: resetting the LNE390...", dev->name); | ||
304 | |||
305 | mdelay(2); | ||
306 | |||
307 | ei_status.txing = 0; | ||
308 | outb(0x01, ioaddr + LNE390_RESET_PORT); | ||
309 | if (ei_debug > 1) printk("reset done\n"); | ||
310 | } | ||
311 | |||
312 | /* | ||
313 | * Note: In the following three functions is the implicit assumption | ||
314 | * that the associated memcpy will only use "rep; movsl" as long as | ||
315 | * we keep the counts as some multiple of doublewords. This is a | ||
316 | * requirement of the hardware, and also prevents us from using | ||
317 | * eth_io_copy_and_sum() since we can't guarantee it will limit | ||
318 | * itself to doubleword access. | ||
319 | */ | ||
320 | |||
321 | /* | ||
322 | * Grab the 8390 specific header. Similar to the block_input routine, but | ||
323 | * we don't need to be concerned with ring wrap as the header will be at | ||
324 | * the start of a page, so we optimize accordingly. (A single doubleword.) | ||
325 | */ | ||
326 | |||
327 | static void | ||
328 | lne390_get_8390_hdr(struct net_device *dev, struct e8390_pkt_hdr *hdr, int ring_page) | ||
329 | { | ||
330 | void __iomem *hdr_start = ei_status.mem + ((ring_page - LNE390_START_PG)<<8); | ||
331 | memcpy_fromio(hdr, hdr_start, sizeof(struct e8390_pkt_hdr)); | ||
332 | hdr->count = (hdr->count + 3) & ~3; /* Round up allocation. */ | ||
333 | } | ||
334 | |||
335 | /* | ||
336 | * Block input and output are easy on shared memory ethercards, the only | ||
337 | * complication is when the ring buffer wraps. The count will already | ||
338 | * be rounded up to a doubleword value via lne390_get_8390_hdr() above. | ||
339 | */ | ||
340 | |||
341 | static void lne390_block_input(struct net_device *dev, int count, struct sk_buff *skb, | ||
342 | int ring_offset) | ||
343 | { | ||
344 | void __iomem *xfer_start = ei_status.mem + ring_offset - (LNE390_START_PG<<8); | ||
345 | |||
346 | if (ring_offset + count > (LNE390_STOP_PG<<8)) { | ||
347 | /* Packet wraps over end of ring buffer. */ | ||
348 | int semi_count = (LNE390_STOP_PG<<8) - ring_offset; | ||
349 | memcpy_fromio(skb->data, xfer_start, semi_count); | ||
350 | count -= semi_count; | ||
351 | memcpy_fromio(skb->data + semi_count, | ||
352 | ei_status.mem + (TX_PAGES<<8), count); | ||
353 | } else { | ||
354 | /* Packet is in one chunk. */ | ||
355 | memcpy_fromio(skb->data, xfer_start, count); | ||
356 | } | ||
357 | } | ||
358 | |||
359 | static void lne390_block_output(struct net_device *dev, int count, | ||
360 | const unsigned char *buf, int start_page) | ||
361 | { | ||
362 | void __iomem *shmem = ei_status.mem + ((start_page - LNE390_START_PG)<<8); | ||
363 | |||
364 | count = (count + 3) & ~3; /* Round up to doubleword */ | ||
365 | memcpy_toio(shmem, buf, count); | ||
366 | } | ||
367 | |||
368 | |||
369 | #ifdef MODULE | ||
370 | #define MAX_LNE_CARDS 4 /* Max number of LNE390 cards per module */ | ||
371 | static struct net_device *dev_lne[MAX_LNE_CARDS]; | ||
372 | static int io[MAX_LNE_CARDS]; | ||
373 | static int irq[MAX_LNE_CARDS]; | ||
374 | static int mem[MAX_LNE_CARDS]; | ||
375 | |||
376 | module_param_array(io, int, NULL, 0); | ||
377 | module_param_array(irq, int, NULL, 0); | ||
378 | module_param_array(mem, int, NULL, 0); | ||
379 | MODULE_PARM_DESC(io, "I/O base address(es)"); | ||
380 | MODULE_PARM_DESC(irq, "IRQ number(s)"); | ||
381 | MODULE_PARM_DESC(mem, "memory base address(es)"); | ||
382 | MODULE_DESCRIPTION("Mylex LNE390A/B EISA Ethernet driver"); | ||
383 | MODULE_LICENSE("GPL"); | ||
384 | |||
385 | int __init init_module(void) | ||
386 | { | ||
387 | struct net_device *dev; | ||
388 | int this_dev, found = 0; | ||
389 | |||
390 | for (this_dev = 0; this_dev < MAX_LNE_CARDS; this_dev++) { | ||
391 | if (io[this_dev] == 0 && this_dev != 0) | ||
392 | break; | ||
393 | dev = alloc_ei_netdev(); | ||
394 | if (!dev) | ||
395 | break; | ||
396 | dev->irq = irq[this_dev]; | ||
397 | dev->base_addr = io[this_dev]; | ||
398 | dev->mem_start = mem[this_dev]; | ||
399 | if (do_lne390_probe(dev) == 0) { | ||
400 | dev_lne[found++] = dev; | ||
401 | continue; | ||
402 | } | ||
403 | free_netdev(dev); | ||
404 | printk(KERN_WARNING "lne390.c: No LNE390 card found (i/o = 0x%x).\n", io[this_dev]); | ||
405 | break; | ||
406 | } | ||
407 | if (found) | ||
408 | return 0; | ||
409 | return -ENXIO; | ||
410 | } | ||
411 | |||
412 | static void cleanup_card(struct net_device *dev) | ||
413 | { | ||
414 | free_irq(dev->irq, dev); | ||
415 | release_region(dev->base_addr, LNE390_IO_EXTENT); | ||
416 | iounmap(ei_status.mem); | ||
417 | } | ||
418 | |||
419 | void __exit cleanup_module(void) | ||
420 | { | ||
421 | int this_dev; | ||
422 | |||
423 | for (this_dev = 0; this_dev < MAX_LNE_CARDS; this_dev++) { | ||
424 | struct net_device *dev = dev_lne[this_dev]; | ||
425 | if (dev) { | ||
426 | unregister_netdev(dev); | ||
427 | cleanup_card(dev); | ||
428 | free_netdev(dev); | ||
429 | } | ||
430 | } | ||
431 | } | ||
432 | #endif /* MODULE */ | ||
433 | |||
diff --git a/drivers/net/ethernet/8390/ne3210.c b/drivers/net/ethernet/8390/ne3210.c deleted file mode 100644 index ebcdb52ec739..000000000000 --- a/drivers/net/ethernet/8390/ne3210.c +++ /dev/null | |||
@@ -1,346 +0,0 @@ | |||
1 | /* | ||
2 | ne3210.c | ||
3 | |||
4 | Linux driver for Novell NE3210 EISA Network Adapter | ||
5 | |||
6 | Copyright (C) 1998, Paul Gortmaker. | ||
7 | |||
8 | This software may be used and distributed according to the terms | ||
9 | of the GNU General Public License, incorporated herein by reference. | ||
10 | |||
11 | Information and Code Sources: | ||
12 | |||
13 | 1) Based upon my other EISA 8390 drivers (lne390, es3210, smc-ultra32) | ||
14 | 2) The existing myriad of other Linux 8390 drivers by Donald Becker. | ||
15 | 3) Info for getting IRQ and sh-mem gleaned from the EISA cfg file | ||
16 | |||
17 | The NE3210 is an EISA shared memory NS8390 implementation. Shared | ||
18 | memory address > 1MB should work with this driver. | ||
19 | |||
20 | Note that the .cfg file (3/11/93, v1.0) has AUI and BNC switched | ||
21 | around (or perhaps there are some defective/backwards cards ???) | ||
22 | |||
23 | This driver WILL NOT WORK FOR THE NE3200 - it is completely different | ||
24 | and does not use an 8390 at all. | ||
25 | |||
26 | Updated to EISA probing API 5/2003 by Marc Zyngier. | ||
27 | */ | ||
28 | |||
29 | #include <linux/module.h> | ||
30 | #include <linux/eisa.h> | ||
31 | #include <linux/kernel.h> | ||
32 | #include <linux/errno.h> | ||
33 | #include <linux/string.h> | ||
34 | #include <linux/delay.h> | ||
35 | #include <linux/init.h> | ||
36 | #include <linux/interrupt.h> | ||
37 | #include <linux/netdevice.h> | ||
38 | #include <linux/etherdevice.h> | ||
39 | #include <linux/mm.h> | ||
40 | |||
41 | #include <asm/io.h> | ||
42 | |||
43 | #include "8390.h" | ||
44 | |||
45 | #define DRV_NAME "ne3210" | ||
46 | |||
47 | static void ne3210_reset_8390(struct net_device *dev); | ||
48 | |||
49 | static void ne3210_get_8390_hdr(struct net_device *dev, struct e8390_pkt_hdr *hdr, int ring_page); | ||
50 | static void ne3210_block_input(struct net_device *dev, int count, struct sk_buff *skb, int ring_offset); | ||
51 | static void ne3210_block_output(struct net_device *dev, int count, const unsigned char *buf, const int start_page); | ||
52 | |||
53 | #define NE3210_START_PG 0x00 /* First page of TX buffer */ | ||
54 | #define NE3210_STOP_PG 0x80 /* Last page +1 of RX ring */ | ||
55 | |||
56 | #define NE3210_IO_EXTENT 0x20 | ||
57 | #define NE3210_SA_PROM 0x16 /* Start of e'net addr. */ | ||
58 | #define NE3210_RESET_PORT 0xc84 | ||
59 | #define NE3210_NIC_OFFSET 0x00 /* Hello, the 8390 is *here* */ | ||
60 | |||
61 | #define NE3210_ADDR0 0x00 /* 3 byte vendor prefix */ | ||
62 | #define NE3210_ADDR1 0x00 | ||
63 | #define NE3210_ADDR2 0x1b | ||
64 | |||
65 | #define NE3210_CFG1 0xc84 /* NB: 0xc84 is also "reset" port. */ | ||
66 | #define NE3210_CFG2 0xc90 | ||
67 | #define NE3210_CFG_EXTENT (NE3210_CFG2 - NE3210_CFG1 + 1) | ||
68 | |||
69 | /* | ||
70 | * You can OR any of the following bits together and assign it | ||
71 | * to NE3210_DEBUG to get verbose driver info during operation. | ||
72 | * Currently only the probe one is implemented. | ||
73 | */ | ||
74 | |||
75 | #define NE3210_D_PROBE 0x01 | ||
76 | #define NE3210_D_RX_PKT 0x02 | ||
77 | #define NE3210_D_TX_PKT 0x04 | ||
78 | #define NE3210_D_IRQ 0x08 | ||
79 | |||
80 | #define NE3210_DEBUG 0x0 | ||
81 | |||
82 | static unsigned char irq_map[] __initdata = {15, 12, 11, 10, 9, 7, 5, 3}; | ||
83 | static unsigned int shmem_map[] __initdata = {0xff0, 0xfe0, 0xfff0, 0xd8, 0xffe0, 0xffc0, 0xd0, 0x0}; | ||
84 | static const char * const ifmap[] __initconst = {"UTP", "?", "BNC", "AUI"}; | ||
85 | static int ifmap_val[] __initdata = { | ||
86 | IF_PORT_10BASET, | ||
87 | IF_PORT_UNKNOWN, | ||
88 | IF_PORT_10BASE2, | ||
89 | IF_PORT_AUI, | ||
90 | }; | ||
91 | |||
92 | static int __init ne3210_eisa_probe (struct device *device) | ||
93 | { | ||
94 | unsigned long ioaddr, phys_mem; | ||
95 | int i, retval, port_index; | ||
96 | struct eisa_device *edev = to_eisa_device (device); | ||
97 | struct net_device *dev; | ||
98 | |||
99 | /* Allocate dev->priv and fill in 8390 specific dev fields. */ | ||
100 | if (!(dev = alloc_ei_netdev ())) { | ||
101 | printk ("ne3210.c: unable to allocate memory for dev!\n"); | ||
102 | return -ENOMEM; | ||
103 | } | ||
104 | |||
105 | SET_NETDEV_DEV(dev, device); | ||
106 | dev_set_drvdata(device, dev); | ||
107 | ioaddr = edev->base_addr; | ||
108 | |||
109 | if (!request_region(ioaddr, NE3210_IO_EXTENT, DRV_NAME)) { | ||
110 | retval = -EBUSY; | ||
111 | goto out; | ||
112 | } | ||
113 | |||
114 | if (!request_region(ioaddr + NE3210_CFG1, | ||
115 | NE3210_CFG_EXTENT, DRV_NAME)) { | ||
116 | retval = -EBUSY; | ||
117 | goto out1; | ||
118 | } | ||
119 | |||
120 | #if NE3210_DEBUG & NE3210_D_PROBE | ||
121 | printk("ne3210-debug: probe at %#x, ID %s\n", ioaddr, edev->id.sig); | ||
122 | printk("ne3210-debug: config regs: %#x %#x\n", | ||
123 | inb(ioaddr + NE3210_CFG1), inb(ioaddr + NE3210_CFG2)); | ||
124 | #endif | ||
125 | |||
126 | port_index = inb(ioaddr + NE3210_CFG2) >> 6; | ||
127 | for (i = 0; i < ETH_ALEN; i++) | ||
128 | dev->dev_addr[i] = inb(ioaddr + NE3210_SA_PROM + i); | ||
129 | printk("ne3210.c: NE3210 in EISA slot %d, media: %s, addr: %pM.\n", | ||
130 | edev->slot, ifmap[port_index], dev->dev_addr); | ||
131 | |||
132 | /* Snarf the interrupt now. CFG file has them all listed as `edge' with share=NO */ | ||
133 | dev->irq = irq_map[(inb(ioaddr + NE3210_CFG2) >> 3) & 0x07]; | ||
134 | printk("ne3210.c: using IRQ %d, ", dev->irq); | ||
135 | |||
136 | retval = request_irq(dev->irq, ei_interrupt, 0, DRV_NAME, dev); | ||
137 | if (retval) { | ||
138 | printk (" unable to get IRQ %d.\n", dev->irq); | ||
139 | goto out2; | ||
140 | } | ||
141 | |||
142 | phys_mem = shmem_map[inb(ioaddr + NE3210_CFG2) & 0x07] * 0x1000; | ||
143 | |||
144 | /* | ||
145 | BEWARE!! Some dain-bramaged EISA SCUs will allow you to put | ||
146 | the card mem within the region covered by `normal' RAM !!! | ||
147 | */ | ||
148 | if (phys_mem > 1024*1024) { /* phys addr > 1MB */ | ||
149 | if (phys_mem < virt_to_phys(high_memory)) { | ||
150 | printk(KERN_CRIT "ne3210.c: Card RAM overlaps with normal memory!!!\n"); | ||
151 | printk(KERN_CRIT "ne3210.c: Use EISA SCU to set card memory below 1MB,\n"); | ||
152 | printk(KERN_CRIT "ne3210.c: or to an address above 0x%llx.\n", | ||
153 | (u64)virt_to_phys(high_memory)); | ||
154 | printk(KERN_CRIT "ne3210.c: Driver NOT installed.\n"); | ||
155 | retval = -EINVAL; | ||
156 | goto out3; | ||
157 | } | ||
158 | } | ||
159 | |||
160 | if (!request_mem_region (phys_mem, NE3210_STOP_PG*0x100, DRV_NAME)) { | ||
161 | printk ("ne3210.c: Unable to request shared memory at physical address %#lx\n", | ||
162 | phys_mem); | ||
163 | goto out3; | ||
164 | } | ||
165 | |||
166 | printk("%dkB memory at physical address %#lx\n", | ||
167 | NE3210_STOP_PG/4, phys_mem); | ||
168 | |||
169 | ei_status.mem = ioremap(phys_mem, NE3210_STOP_PG*0x100); | ||
170 | if (!ei_status.mem) { | ||
171 | printk(KERN_ERR "ne3210.c: Unable to remap card memory !!\n"); | ||
172 | printk(KERN_ERR "ne3210.c: Driver NOT installed.\n"); | ||
173 | retval = -EAGAIN; | ||
174 | goto out4; | ||
175 | } | ||
176 | printk("ne3210.c: remapped %dkB card memory to virtual address %p\n", | ||
177 | NE3210_STOP_PG/4, ei_status.mem); | ||
178 | dev->mem_start = (unsigned long)ei_status.mem; | ||
179 | dev->mem_end = dev->mem_start + (NE3210_STOP_PG - NE3210_START_PG)*256; | ||
180 | |||
181 | /* The 8390 offset is zero for the NE3210 */ | ||
182 | dev->base_addr = ioaddr; | ||
183 | |||
184 | ei_status.name = "NE3210"; | ||
185 | ei_status.tx_start_page = NE3210_START_PG; | ||
186 | ei_status.rx_start_page = NE3210_START_PG + TX_PAGES; | ||
187 | ei_status.stop_page = NE3210_STOP_PG; | ||
188 | ei_status.word16 = 1; | ||
189 | ei_status.priv = phys_mem; | ||
190 | |||
191 | if (ei_debug > 0) | ||
192 | printk("ne3210 loaded.\n"); | ||
193 | |||
194 | ei_status.reset_8390 = &ne3210_reset_8390; | ||
195 | ei_status.block_input = &ne3210_block_input; | ||
196 | ei_status.block_output = &ne3210_block_output; | ||
197 | ei_status.get_8390_hdr = &ne3210_get_8390_hdr; | ||
198 | |||
199 | dev->netdev_ops = &ei_netdev_ops; | ||
200 | |||
201 | dev->if_port = ifmap_val[port_index]; | ||
202 | |||
203 | if ((retval = register_netdev (dev))) | ||
204 | goto out5; | ||
205 | |||
206 | NS8390_init(dev, 0); | ||
207 | return 0; | ||
208 | |||
209 | out5: | ||
210 | iounmap(ei_status.mem); | ||
211 | out4: | ||
212 | release_mem_region (phys_mem, NE3210_STOP_PG*0x100); | ||
213 | out3: | ||
214 | free_irq (dev->irq, dev); | ||
215 | out2: | ||
216 | release_region (ioaddr + NE3210_CFG1, NE3210_CFG_EXTENT); | ||
217 | out1: | ||
218 | release_region (ioaddr, NE3210_IO_EXTENT); | ||
219 | out: | ||
220 | free_netdev (dev); | ||
221 | |||
222 | return retval; | ||
223 | } | ||
224 | |||
225 | static int ne3210_eisa_remove(struct device *device) | ||
226 | { | ||
227 | struct net_device *dev = dev_get_drvdata(device); | ||
228 | unsigned long ioaddr = to_eisa_device (device)->base_addr; | ||
229 | |||
230 | unregister_netdev (dev); | ||
231 | iounmap(ei_status.mem); | ||
232 | release_mem_region (ei_status.priv, NE3210_STOP_PG*0x100); | ||
233 | free_irq (dev->irq, dev); | ||
234 | release_region (ioaddr + NE3210_CFG1, NE3210_CFG_EXTENT); | ||
235 | release_region (ioaddr, NE3210_IO_EXTENT); | ||
236 | free_netdev (dev); | ||
237 | |||
238 | return 0; | ||
239 | } | ||
240 | |||
241 | /* | ||
242 | * Reset by toggling the "Board Enable" bits (bit 2 and 0). | ||
243 | */ | ||
244 | |||
245 | static void ne3210_reset_8390(struct net_device *dev) | ||
246 | { | ||
247 | unsigned short ioaddr = dev->base_addr; | ||
248 | |||
249 | outb(0x04, ioaddr + NE3210_RESET_PORT); | ||
250 | if (ei_debug > 1) printk("%s: resetting the NE3210...", dev->name); | ||
251 | |||
252 | mdelay(2); | ||
253 | |||
254 | ei_status.txing = 0; | ||
255 | outb(0x01, ioaddr + NE3210_RESET_PORT); | ||
256 | if (ei_debug > 1) printk("reset done\n"); | ||
257 | } | ||
258 | |||
259 | /* | ||
260 | * Note: In the following three functions is the implicit assumption | ||
261 | * that the associated memcpy will only use "rep; movsl" as long as | ||
262 | * we keep the counts as some multiple of doublewords. This is a | ||
263 | * requirement of the hardware, and also prevents us from using | ||
264 | * eth_io_copy_and_sum() since we can't guarantee it will limit | ||
265 | * itself to doubleword access. | ||
266 | */ | ||
267 | |||
268 | /* | ||
269 | * Grab the 8390 specific header. Similar to the block_input routine, but | ||
270 | * we don't need to be concerned with ring wrap as the header will be at | ||
271 | * the start of a page, so we optimize accordingly. (A single doubleword.) | ||
272 | */ | ||
273 | |||
274 | static void | ||
275 | ne3210_get_8390_hdr(struct net_device *dev, struct e8390_pkt_hdr *hdr, int ring_page) | ||
276 | { | ||
277 | void __iomem *hdr_start = ei_status.mem + ((ring_page - NE3210_START_PG)<<8); | ||
278 | memcpy_fromio(hdr, hdr_start, sizeof(struct e8390_pkt_hdr)); | ||
279 | hdr->count = (hdr->count + 3) & ~3; /* Round up allocation. */ | ||
280 | } | ||
281 | |||
282 | /* | ||
283 | * Block input and output are easy on shared memory ethercards, the only | ||
284 | * complication is when the ring buffer wraps. The count will already | ||
285 | * be rounded up to a doubleword value via ne3210_get_8390_hdr() above. | ||
286 | */ | ||
287 | |||
288 | static void ne3210_block_input(struct net_device *dev, int count, struct sk_buff *skb, | ||
289 | int ring_offset) | ||
290 | { | ||
291 | void __iomem *start = ei_status.mem + ring_offset - NE3210_START_PG*256; | ||
292 | |||
293 | if (ring_offset + count > NE3210_STOP_PG*256) { | ||
294 | /* Packet wraps over end of ring buffer. */ | ||
295 | int semi_count = NE3210_STOP_PG*256 - ring_offset; | ||
296 | memcpy_fromio(skb->data, start, semi_count); | ||
297 | count -= semi_count; | ||
298 | memcpy_fromio(skb->data + semi_count, | ||
299 | ei_status.mem + TX_PAGES*256, count); | ||
300 | } else { | ||
301 | /* Packet is in one chunk. */ | ||
302 | memcpy_fromio(skb->data, start, count); | ||
303 | } | ||
304 | } | ||
305 | |||
306 | static void ne3210_block_output(struct net_device *dev, int count, | ||
307 | const unsigned char *buf, int start_page) | ||
308 | { | ||
309 | void __iomem *shmem = ei_status.mem + ((start_page - NE3210_START_PG)<<8); | ||
310 | |||
311 | count = (count + 3) & ~3; /* Round up to doubleword */ | ||
312 | memcpy_toio(shmem, buf, count); | ||
313 | } | ||
314 | |||
315 | static struct eisa_device_id ne3210_ids[] = { | ||
316 | { "EGL0101" }, | ||
317 | { "NVL1801" }, | ||
318 | { "" }, | ||
319 | }; | ||
320 | MODULE_DEVICE_TABLE(eisa, ne3210_ids); | ||
321 | |||
322 | static struct eisa_driver ne3210_eisa_driver = { | ||
323 | .id_table = ne3210_ids, | ||
324 | .driver = { | ||
325 | .name = "ne3210", | ||
326 | .probe = ne3210_eisa_probe, | ||
327 | .remove = ne3210_eisa_remove, | ||
328 | }, | ||
329 | }; | ||
330 | |||
331 | MODULE_DESCRIPTION("NE3210 EISA Ethernet driver"); | ||
332 | MODULE_LICENSE("GPL"); | ||
333 | MODULE_DEVICE_TABLE(eisa, ne3210_ids); | ||
334 | |||
335 | static int ne3210_init(void) | ||
336 | { | ||
337 | return eisa_driver_register (&ne3210_eisa_driver); | ||
338 | } | ||
339 | |||
340 | static void ne3210_cleanup(void) | ||
341 | { | ||
342 | eisa_driver_unregister (&ne3210_eisa_driver); | ||
343 | } | ||
344 | |||
345 | module_init (ne3210_init); | ||
346 | module_exit (ne3210_cleanup); | ||
diff --git a/drivers/net/ethernet/8390/smc-ultra32.c b/drivers/net/ethernet/8390/smc-ultra32.c deleted file mode 100644 index 923e42aedcfd..000000000000 --- a/drivers/net/ethernet/8390/smc-ultra32.c +++ /dev/null | |||
@@ -1,463 +0,0 @@ | |||
1 | /* smc-ultra32.c: An SMC Ultra32 EISA ethernet driver for linux. | ||
2 | |||
3 | Sources: | ||
4 | |||
5 | This driver is based on (cloned from) the ISA SMC Ultra driver | ||
6 | written by Donald Becker. Modifications to support the EISA | ||
7 | version of the card by Paul Gortmaker and Leonard N. Zubkoff. | ||
8 | |||
9 | This software may be used and distributed according to the terms | ||
10 | of the GNU General Public License, incorporated herein by reference. | ||
11 | |||
12 | Theory of Operation: | ||
13 | |||
14 | The SMC Ultra32C card uses the SMC 83c790 chip which is also | ||
15 | found on the ISA SMC Ultra cards. It has a shared memory mode of | ||
16 | operation that makes it similar to the ISA version of the card. | ||
17 | The main difference is that the EISA card has 32KB of RAM, but | ||
18 | only an 8KB window into that memory. The EISA card also can be | ||
19 | set for a bus-mastering mode of operation via the ECU, but that | ||
20 | is not (and probably will never be) supported by this driver. | ||
21 | The ECU should be run to enable shared memory and to disable the | ||
22 | bus-mastering feature for use with linux. | ||
23 | |||
24 | By programming the 8390 to use only 8KB RAM, the modifications | ||
25 | to the ISA driver can be limited to the probe and initialization | ||
26 | code. This allows easy integration of EISA support into the ISA | ||
27 | driver. However, the driver development kit from SMC provided the | ||
28 | register information for sliding the 8KB window, and hence the 8390 | ||
29 | is programmed to use the full 32KB RAM. | ||
30 | |||
31 | Unfortunately this required code changes outside the probe/init | ||
32 | routines, and thus we decided to separate the EISA driver from | ||
33 | the ISA one. In this way, ISA users don't end up with a larger | ||
34 | driver due to the EISA code, and EISA users don't end up with a | ||
35 | larger driver due to the ISA EtherEZ PIO code. The driver is | ||
36 | similar to the 3c503/16 driver, in that the window must be set | ||
37 | back to the 1st 8KB of space for access to the two 8390 Tx slots. | ||
38 | |||
39 | In testing, using only 8KB RAM (3 Tx / 5 Rx) didn't appear to | ||
40 | be a limiting factor, since the EISA bus could get packets off | ||
41 | the card fast enough, but having the use of lots of RAM as Rx | ||
42 | space is extra insurance if interrupt latencies become excessive. | ||
43 | |||
44 | */ | ||
45 | |||
46 | static const char *version = "smc-ultra32.c: 06/97 v1.00\n"; | ||
47 | |||
48 | |||
49 | #include <linux/module.h> | ||
50 | #include <linux/eisa.h> | ||
51 | #include <linux/kernel.h> | ||
52 | #include <linux/errno.h> | ||
53 | #include <linux/string.h> | ||
54 | #include <linux/init.h> | ||
55 | #include <linux/interrupt.h> | ||
56 | #include <linux/netdevice.h> | ||
57 | #include <linux/etherdevice.h> | ||
58 | |||
59 | #include <asm/io.h> | ||
60 | |||
61 | #include "8390.h" | ||
62 | |||
63 | #define DRV_NAME "smc-ultra32" | ||
64 | |||
65 | static int ultra32_probe1(struct net_device *dev, int ioaddr); | ||
66 | static int ultra32_open(struct net_device *dev); | ||
67 | static void ultra32_reset_8390(struct net_device *dev); | ||
68 | static void ultra32_get_8390_hdr(struct net_device *dev, struct e8390_pkt_hdr *hdr, | ||
69 | int ring_page); | ||
70 | static void ultra32_block_input(struct net_device *dev, int count, | ||
71 | struct sk_buff *skb, int ring_offset); | ||
72 | static void ultra32_block_output(struct net_device *dev, int count, | ||
73 | const unsigned char *buf, | ||
74 | const int start_page); | ||
75 | static int ultra32_close(struct net_device *dev); | ||
76 | |||
77 | #define ULTRA32_CMDREG 0 /* Offset to ASIC command register. */ | ||
78 | #define ULTRA32_RESET 0x80 /* Board reset, in ULTRA32_CMDREG. */ | ||
79 | #define ULTRA32_MEMENB 0x40 /* Enable the shared memory. */ | ||
80 | #define ULTRA32_NIC_OFFSET 16 /* NIC register offset from the base_addr. */ | ||
81 | #define ULTRA32_IO_EXTENT 32 | ||
82 | #define EN0_ERWCNT 0x08 /* Early receive warning count. */ | ||
83 | |||
84 | /* | ||
85 | * Defines that apply only to the Ultra32 EISA card. Note that | ||
86 | * "smc" = 10011 01101 00011 = 0x4da3, and hence !smc8010.cfg translates | ||
87 | * into an EISA ID of 0x1080A34D | ||
88 | */ | ||
89 | #define ULTRA32_BASE 0xca0 | ||
90 | #define ULTRA32_ID 0x1080a34d | ||
91 | #define ULTRA32_IDPORT (-0x20) /* 0xc80 */ | ||
92 | /* Config regs 1->7 from the EISA !SMC8010.CFG file. */ | ||
93 | #define ULTRA32_CFG1 0x04 /* 0xca4 */ | ||
94 | #define ULTRA32_CFG2 0x05 /* 0xca5 */ | ||
95 | #define ULTRA32_CFG3 (-0x18) /* 0xc88 */ | ||
96 | #define ULTRA32_CFG4 (-0x17) /* 0xc89 */ | ||
97 | #define ULTRA32_CFG5 (-0x16) /* 0xc8a */ | ||
98 | #define ULTRA32_CFG6 (-0x15) /* 0xc8b */ | ||
99 | #define ULTRA32_CFG7 0x0d /* 0xcad */ | ||
100 | |||
101 | static void cleanup_card(struct net_device *dev) | ||
102 | { | ||
103 | int ioaddr = dev->base_addr - ULTRA32_NIC_OFFSET; | ||
104 | /* NB: ultra32_close_card() does free_irq */ | ||
105 | release_region(ioaddr, ULTRA32_IO_EXTENT); | ||
106 | iounmap(ei_status.mem); | ||
107 | } | ||
108 | |||
109 | /* Probe for the Ultra32. This looks like a 8013 with the station | ||
110 | address PROM at I/O ports <base>+8 to <base>+13, with a checksum | ||
111 | following. | ||
112 | */ | ||
113 | |||
114 | struct net_device * __init ultra32_probe(int unit) | ||
115 | { | ||
116 | struct net_device *dev; | ||
117 | int base; | ||
118 | int irq; | ||
119 | int err = -ENODEV; | ||
120 | |||
121 | if (!EISA_bus) | ||
122 | return ERR_PTR(-ENODEV); | ||
123 | |||
124 | dev = alloc_ei_netdev(); | ||
125 | |||
126 | if (!dev) | ||
127 | return ERR_PTR(-ENOMEM); | ||
128 | |||
129 | if (unit >= 0) { | ||
130 | sprintf(dev->name, "eth%d", unit); | ||
131 | netdev_boot_setup_check(dev); | ||
132 | } | ||
133 | |||
134 | irq = dev->irq; | ||
135 | |||
136 | /* EISA spec allows for up to 16 slots, but 8 is typical. */ | ||
137 | for (base = 0x1000 + ULTRA32_BASE; base < 0x9000; base += 0x1000) { | ||
138 | if (ultra32_probe1(dev, base) == 0) | ||
139 | break; | ||
140 | dev->irq = irq; | ||
141 | } | ||
142 | if (base >= 0x9000) | ||
143 | goto out; | ||
144 | err = register_netdev(dev); | ||
145 | if (err) | ||
146 | goto out1; | ||
147 | return dev; | ||
148 | out1: | ||
149 | cleanup_card(dev); | ||
150 | out: | ||
151 | free_netdev(dev); | ||
152 | return ERR_PTR(err); | ||
153 | } | ||
154 | |||
155 | |||
156 | static const struct net_device_ops ultra32_netdev_ops = { | ||
157 | .ndo_open = ultra32_open, | ||
158 | .ndo_stop = ultra32_close, | ||
159 | .ndo_start_xmit = ei_start_xmit, | ||
160 | .ndo_tx_timeout = ei_tx_timeout, | ||
161 | .ndo_get_stats = ei_get_stats, | ||
162 | .ndo_set_rx_mode = ei_set_multicast_list, | ||
163 | .ndo_validate_addr = eth_validate_addr, | ||
164 | .ndo_set_mac_address = eth_mac_addr, | ||
165 | .ndo_change_mtu = eth_change_mtu, | ||
166 | #ifdef CONFIG_NET_POLL_CONTROLLER | ||
167 | .ndo_poll_controller = ei_poll, | ||
168 | #endif | ||
169 | }; | ||
170 | |||
171 | static int __init ultra32_probe1(struct net_device *dev, int ioaddr) | ||
172 | { | ||
173 | int i, edge, media, retval; | ||
174 | int checksum = 0; | ||
175 | const char *model_name; | ||
176 | static unsigned version_printed; | ||
177 | /* Values from various config regs. */ | ||
178 | unsigned char idreg; | ||
179 | unsigned char reg4; | ||
180 | const char *ifmap[] = {"UTP No Link", "", "UTP/AUI", "UTP/BNC"}; | ||
181 | |||
182 | if (!request_region(ioaddr, ULTRA32_IO_EXTENT, DRV_NAME)) | ||
183 | return -EBUSY; | ||
184 | |||
185 | if (inb(ioaddr + ULTRA32_IDPORT) == 0xff || | ||
186 | inl(ioaddr + ULTRA32_IDPORT) != ULTRA32_ID) { | ||
187 | retval = -ENODEV; | ||
188 | goto out; | ||
189 | } | ||
190 | |||
191 | media = inb(ioaddr + ULTRA32_CFG7) & 0x03; | ||
192 | edge = inb(ioaddr + ULTRA32_CFG5) & 0x08; | ||
193 | printk("SMC Ultra32 in EISA Slot %d, Media: %s, %s IRQs.\n", | ||
194 | ioaddr >> 12, ifmap[media], | ||
195 | (edge ? "Edge Triggered" : "Level Sensitive")); | ||
196 | |||
197 | idreg = inb(ioaddr + 7); | ||
198 | reg4 = inb(ioaddr + 4) & 0x7f; | ||
199 | |||
200 | /* Check the ID nibble. */ | ||
201 | if ((idreg & 0xf0) != 0x20) { /* SMC Ultra */ | ||
202 | retval = -ENODEV; | ||
203 | goto out; | ||
204 | } | ||
205 | |||
206 | /* Select the station address register set. */ | ||
207 | outb(reg4, ioaddr + 4); | ||
208 | |||
209 | for (i = 0; i < 8; i++) | ||
210 | checksum += inb(ioaddr + 8 + i); | ||
211 | if ((checksum & 0xff) != 0xff) { | ||
212 | retval = -ENODEV; | ||
213 | goto out; | ||
214 | } | ||
215 | |||
216 | if (ei_debug && version_printed++ == 0) | ||
217 | printk(version); | ||
218 | |||
219 | model_name = "SMC Ultra32"; | ||
220 | |||
221 | for (i = 0; i < 6; i++) | ||
222 | dev->dev_addr[i] = inb(ioaddr + 8 + i); | ||
223 | |||
224 | printk("%s: %s at 0x%X, %pM", | ||
225 | dev->name, model_name, ioaddr, dev->dev_addr); | ||
226 | |||
227 | /* Switch from the station address to the alternate register set and | ||
228 | read the useful registers there. */ | ||
229 | outb(0x80 | reg4, ioaddr + 4); | ||
230 | |||
231 | /* Enable FINE16 mode to avoid BIOS ROM width mismatches @ reboot. */ | ||
232 | outb(0x80 | inb(ioaddr + 0x0c), ioaddr + 0x0c); | ||
233 | |||
234 | /* Reset RAM addr. */ | ||
235 | outb(0x00, ioaddr + 0x0b); | ||
236 | |||
237 | /* Switch back to the station address register set so that the | ||
238 | MS-DOS driver can find the card after a warm boot. */ | ||
239 | outb(reg4, ioaddr + 4); | ||
240 | |||
241 | if ((inb(ioaddr + ULTRA32_CFG5) & 0x40) == 0) { | ||
242 | printk("\nsmc-ultra32: Card RAM is disabled! " | ||
243 | "Run EISA config utility.\n"); | ||
244 | retval = -ENODEV; | ||
245 | goto out; | ||
246 | } | ||
247 | if ((inb(ioaddr + ULTRA32_CFG2) & 0x04) == 0) | ||
248 | printk("\nsmc-ultra32: Ignoring Bus-Master enable bit. " | ||
249 | "Run EISA config utility.\n"); | ||
250 | |||
251 | if (dev->irq < 2) { | ||
252 | unsigned char irqmap[] = {0, 9, 3, 5, 7, 10, 11, 15}; | ||
253 | int irq = irqmap[inb(ioaddr + ULTRA32_CFG5) & 0x07]; | ||
254 | if (irq == 0) { | ||
255 | printk(", failed to detect IRQ line.\n"); | ||
256 | retval = -EAGAIN; | ||
257 | goto out; | ||
258 | } | ||
259 | dev->irq = irq; | ||
260 | } | ||
261 | |||
262 | /* The 8390 isn't at the base address, so fake the offset */ | ||
263 | dev->base_addr = ioaddr + ULTRA32_NIC_OFFSET; | ||
264 | |||
265 | /* Save RAM address in the unused reg0 to avoid excess inb's. */ | ||
266 | ei_status.reg0 = inb(ioaddr + ULTRA32_CFG3) & 0xfc; | ||
267 | |||
268 | dev->mem_start = 0xc0000 + ((ei_status.reg0 & 0x7c) << 11); | ||
269 | |||
270 | ei_status.name = model_name; | ||
271 | ei_status.word16 = 1; | ||
272 | ei_status.tx_start_page = 0; | ||
273 | ei_status.rx_start_page = TX_PAGES; | ||
274 | /* All Ultra32 cards have 32KB memory with an 8KB window. */ | ||
275 | ei_status.stop_page = 128; | ||
276 | |||
277 | ei_status.mem = ioremap(dev->mem_start, 0x2000); | ||
278 | if (!ei_status.mem) { | ||
279 | printk(", failed to ioremap.\n"); | ||
280 | retval = -ENOMEM; | ||
281 | goto out; | ||
282 | } | ||
283 | dev->mem_end = dev->mem_start + 0x1fff; | ||
284 | |||
285 | printk(", IRQ %d, 32KB memory, 8KB window at 0x%lx-0x%lx.\n", | ||
286 | dev->irq, dev->mem_start, dev->mem_end); | ||
287 | ei_status.block_input = &ultra32_block_input; | ||
288 | ei_status.block_output = &ultra32_block_output; | ||
289 | ei_status.get_8390_hdr = &ultra32_get_8390_hdr; | ||
290 | ei_status.reset_8390 = &ultra32_reset_8390; | ||
291 | |||
292 | dev->netdev_ops = &ultra32_netdev_ops; | ||
293 | NS8390_init(dev, 0); | ||
294 | |||
295 | return 0; | ||
296 | out: | ||
297 | release_region(ioaddr, ULTRA32_IO_EXTENT); | ||
298 | return retval; | ||
299 | } | ||
300 | |||
301 | static int ultra32_open(struct net_device *dev) | ||
302 | { | ||
303 | int ioaddr = dev->base_addr - ULTRA32_NIC_OFFSET; /* ASIC addr */ | ||
304 | int irq_flags = (inb(ioaddr + ULTRA32_CFG5) & 0x08) ? 0 : IRQF_SHARED; | ||
305 | int retval; | ||
306 | |||
307 | retval = request_irq(dev->irq, ei_interrupt, irq_flags, dev->name, dev); | ||
308 | if (retval) | ||
309 | return retval; | ||
310 | |||
311 | outb(ULTRA32_MEMENB, ioaddr); /* Enable Shared Memory. */ | ||
312 | outb(0x80, ioaddr + ULTRA32_CFG6); /* Enable Interrupts. */ | ||
313 | outb(0x84, ioaddr + 5); /* Enable MEM16 & Disable Bus Master. */ | ||
314 | outb(0x01, ioaddr + 6); /* Enable Interrupts. */ | ||
315 | /* Set the early receive warning level in window 0 high enough not | ||
316 | to receive ERW interrupts. */ | ||
317 | outb_p(E8390_NODMA+E8390_PAGE0, dev->base_addr); | ||
318 | outb(0xff, dev->base_addr + EN0_ERWCNT); | ||
319 | ei_open(dev); | ||
320 | return 0; | ||
321 | } | ||
322 | |||
323 | static int ultra32_close(struct net_device *dev) | ||
324 | { | ||
325 | int ioaddr = dev->base_addr - ULTRA32_NIC_OFFSET; /* CMDREG */ | ||
326 | |||
327 | netif_stop_queue(dev); | ||
328 | |||
329 | if (ei_debug > 1) | ||
330 | printk("%s: Shutting down ethercard.\n", dev->name); | ||
331 | |||
332 | outb(0x00, ioaddr + ULTRA32_CFG6); /* Disable Interrupts. */ | ||
333 | outb(0x00, ioaddr + 6); /* Disable interrupts. */ | ||
334 | free_irq(dev->irq, dev); | ||
335 | |||
336 | NS8390_init(dev, 0); | ||
337 | |||
338 | return 0; | ||
339 | } | ||
340 | |||
341 | static void ultra32_reset_8390(struct net_device *dev) | ||
342 | { | ||
343 | int ioaddr = dev->base_addr - ULTRA32_NIC_OFFSET; /* ASIC base addr */ | ||
344 | |||
345 | outb(ULTRA32_RESET, ioaddr); | ||
346 | if (ei_debug > 1) printk("resetting Ultra32, t=%ld...", jiffies); | ||
347 | ei_status.txing = 0; | ||
348 | |||
349 | outb(ULTRA32_MEMENB, ioaddr); /* Enable Shared Memory. */ | ||
350 | outb(0x80, ioaddr + ULTRA32_CFG6); /* Enable Interrupts. */ | ||
351 | outb(0x84, ioaddr + 5); /* Enable MEM16 & Disable Bus Master. */ | ||
352 | outb(0x01, ioaddr + 6); /* Enable Interrupts. */ | ||
353 | if (ei_debug > 1) printk("reset done\n"); | ||
354 | } | ||
355 | |||
356 | /* Grab the 8390 specific header. Similar to the block_input routine, but | ||
357 | we don't need to be concerned with ring wrap as the header will be at | ||
358 | the start of a page, so we optimize accordingly. */ | ||
359 | |||
360 | static void ultra32_get_8390_hdr(struct net_device *dev, | ||
361 | struct e8390_pkt_hdr *hdr, | ||
362 | int ring_page) | ||
363 | { | ||
364 | void __iomem *hdr_start = ei_status.mem + ((ring_page & 0x1f) << 8); | ||
365 | unsigned int RamReg = dev->base_addr - ULTRA32_NIC_OFFSET + ULTRA32_CFG3; | ||
366 | |||
367 | /* Select correct 8KB Window. */ | ||
368 | outb(ei_status.reg0 | ((ring_page & 0x60) >> 5), RamReg); | ||
369 | |||
370 | #ifdef __BIG_ENDIAN | ||
371 | /* Officially this is what we are doing, but the readl() is faster */ | ||
372 | /* unfortunately it isn't endian aware of the struct */ | ||
373 | memcpy_fromio(hdr, hdr_start, sizeof(struct e8390_pkt_hdr)); | ||
374 | hdr->count = le16_to_cpu(hdr->count); | ||
375 | #else | ||
376 | ((unsigned int*)hdr)[0] = readl(hdr_start); | ||
377 | #endif | ||
378 | } | ||
379 | |||
380 | /* Block input and output are easy on shared memory ethercards, the only | ||
381 | complication is when the ring buffer wraps, or in this case, when a | ||
382 | packet spans an 8KB boundary. Note that the current 8KB segment is | ||
383 | already set by the get_8390_hdr routine. */ | ||
384 | |||
385 | static void ultra32_block_input(struct net_device *dev, | ||
386 | int count, | ||
387 | struct sk_buff *skb, | ||
388 | int ring_offset) | ||
389 | { | ||
390 | void __iomem *xfer_start = ei_status.mem + (ring_offset & 0x1fff); | ||
391 | unsigned int RamReg = dev->base_addr - ULTRA32_NIC_OFFSET + ULTRA32_CFG3; | ||
392 | |||
393 | if ((ring_offset & ~0x1fff) != ((ring_offset + count - 1) & ~0x1fff)) { | ||
394 | int semi_count = 8192 - (ring_offset & 0x1FFF); | ||
395 | memcpy_fromio(skb->data, xfer_start, semi_count); | ||
396 | count -= semi_count; | ||
397 | if (ring_offset < 96*256) { | ||
398 | /* Select next 8KB Window. */ | ||
399 | ring_offset += semi_count; | ||
400 | outb(ei_status.reg0 | ((ring_offset & 0x6000) >> 13), RamReg); | ||
401 | memcpy_fromio(skb->data + semi_count, ei_status.mem, count); | ||
402 | } else { | ||
403 | /* Select first 8KB Window. */ | ||
404 | outb(ei_status.reg0, RamReg); | ||
405 | memcpy_fromio(skb->data + semi_count, ei_status.mem + TX_PAGES * 256, count); | ||
406 | } | ||
407 | } else { | ||
408 | memcpy_fromio(skb->data, xfer_start, count); | ||
409 | } | ||
410 | } | ||
411 | |||
412 | static void ultra32_block_output(struct net_device *dev, | ||
413 | int count, | ||
414 | const unsigned char *buf, | ||
415 | int start_page) | ||
416 | { | ||
417 | void __iomem *xfer_start = ei_status.mem + (start_page<<8); | ||
418 | unsigned int RamReg = dev->base_addr - ULTRA32_NIC_OFFSET + ULTRA32_CFG3; | ||
419 | |||
420 | /* Select first 8KB Window. */ | ||
421 | outb(ei_status.reg0, RamReg); | ||
422 | |||
423 | memcpy_toio(xfer_start, buf, count); | ||
424 | } | ||
425 | |||
426 | #ifdef MODULE | ||
427 | #define MAX_ULTRA32_CARDS 4 /* Max number of Ultra cards per module */ | ||
428 | static struct net_device *dev_ultra[MAX_ULTRA32_CARDS]; | ||
429 | |||
430 | MODULE_DESCRIPTION("SMC Ultra32 EISA ethernet driver"); | ||
431 | MODULE_LICENSE("GPL"); | ||
432 | |||
433 | int __init init_module(void) | ||
434 | { | ||
435 | int this_dev, found = 0; | ||
436 | |||
437 | for (this_dev = 0; this_dev < MAX_ULTRA32_CARDS; this_dev++) { | ||
438 | struct net_device *dev = ultra32_probe(-1); | ||
439 | if (IS_ERR(dev)) | ||
440 | break; | ||
441 | dev_ultra[found++] = dev; | ||
442 | } | ||
443 | if (found) | ||
444 | return 0; | ||
445 | printk(KERN_WARNING "smc-ultra32.c: No SMC Ultra32 found.\n"); | ||
446 | return -ENXIO; | ||
447 | } | ||
448 | |||
449 | void __exit cleanup_module(void) | ||
450 | { | ||
451 | int this_dev; | ||
452 | |||
453 | for (this_dev = 0; this_dev < MAX_ULTRA32_CARDS; this_dev++) { | ||
454 | struct net_device *dev = dev_ultra[this_dev]; | ||
455 | if (dev) { | ||
456 | unregister_netdev(dev); | ||
457 | cleanup_card(dev); | ||
458 | free_netdev(dev); | ||
459 | } | ||
460 | } | ||
461 | } | ||
462 | #endif /* MODULE */ | ||
463 | |||