Commit | Line | Data |
---|---|---|
1da177e4 LT |
1 | /* |
2 | * Amiga Linux/m68k and Linux/PPC Zorro NS8390 Ethernet Driver | |
3 | * | |
4 | * (C) Copyright 1998-2000 by some Elitist 680x0 Users(TM) | |
5 | * | |
6 | * --------------------------------------------------------------------------- | |
7 | * | |
8 | * This program is based on all the other NE2000 drivers for Linux | |
9 | * | |
10 | * --------------------------------------------------------------------------- | |
11 | * | |
12 | * This file is subject to the terms and conditions of the GNU General Public | |
13 | * License. See the file COPYING in the main directory of the Linux | |
14 | * distribution for more details. | |
15 | * | |
16 | * --------------------------------------------------------------------------- | |
17 | * | |
18 | * The Ariadne II and X-Surf are Zorro-II boards containing Realtek RTL8019AS | |
19 | * Ethernet Controllers. | |
20 | */ | |
21 | ||
572404ea JP |
22 | #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt |
23 | ||
1da177e4 LT |
24 | #include <linux/module.h> |
25 | #include <linux/kernel.h> | |
26 | #include <linux/errno.h> | |
27 | #include <linux/init.h> | |
28 | #include <linux/delay.h> | |
29 | #include <linux/netdevice.h> | |
30 | #include <linux/etherdevice.h> | |
31 | #include <linux/zorro.h> | |
ff5688ae | 32 | #include <linux/jiffies.h> |
1da177e4 | 33 | |
1da177e4 LT |
34 | #include <asm/irq.h> |
35 | #include <asm/amigaints.h> | |
36 | #include <asm/amigahw.h> | |
37 | ||
572404ea JP |
38 | #define EI_SHIFT(x) (ei_local->reg_offset[x]) |
39 | #define ei_inb(port) in_8(port) | |
40 | #define ei_outb(val, port) out_8(port, val) | |
41 | #define ei_inb_p(port) in_8(port) | |
42 | #define ei_outb_p(val, port) out_8(port, val) | |
1da177e4 | 43 | |
8c6270f9 | 44 | static const char version[] = |
572404ea | 45 | "8390.c:v1.10cvs 9/23/94 Donald Becker (becker@cesdis.gsfc.nasa.gov)\n"; |
8c6270f9 | 46 | |
c45f812f MW |
47 | static u32 zorro8390_msg_enable; |
48 | ||
8c6270f9 | 49 | #include "lib8390.c" |
1da177e4 LT |
50 | |
51 | #define DRV_NAME "zorro8390" | |
52 | ||
53 | #define NE_BASE (dev->base_addr) | |
572404ea JP |
54 | #define NE_CMD (0x00 * 2) |
55 | #define NE_DATAPORT (0x10 * 2) /* NatSemi-defined port window offset */ | |
56 | #define NE_RESET (0x1f * 2) /* Issue a read to reset, | |
57 | * a write to clear. */ | |
58 | #define NE_IO_EXTENT (0x20 * 2) | |
59 | ||
60 | #define NE_EN0_ISR (0x07 * 2) | |
61 | #define NE_EN0_DCFG (0x0e * 2) | |
62 | ||
63 | #define NE_EN0_RSARLO (0x08 * 2) | |
64 | #define NE_EN0_RSARHI (0x09 * 2) | |
65 | #define NE_EN0_RCNTLO (0x0a * 2) | |
66 | #define NE_EN0_RXCR (0x0c * 2) | |
67 | #define NE_EN0_TXCR (0x0d * 2) | |
68 | #define NE_EN0_RCNTHI (0x0b * 2) | |
69 | #define NE_EN0_IMR (0x0f * 2) | |
1da177e4 LT |
70 | |
71 | #define NESM_START_PG 0x40 /* First page of TX buffer */ | |
72 | #define NESM_STOP_PG 0x80 /* Last page +1 of RX ring */ | |
73 | ||
572404ea | 74 | #define WORDSWAP(a) ((((a) >> 8) & 0xff) | ((a) << 8)) |
1da177e4 LT |
75 | |
76 | static struct card_info { | |
572404ea JP |
77 | zorro_id id; |
78 | const char *name; | |
79 | unsigned int offset; | |
4168ac0e | 80 | } cards[] = { |
572404ea JP |
81 | { ZORRO_PROD_VILLAGE_TRONIC_ARIADNE2, "Ariadne II", 0x0600 }, |
82 | { ZORRO_PROD_INDIVIDUAL_COMPUTERS_X_SURF, "X-Surf", 0x8600 }, | |
1da177e4 LT |
83 | }; |
84 | ||
572404ea JP |
85 | /* Hard reset the card. This used to pause for the same period that a |
86 | * 8390 reset command required, but that shouldn't be necessary. | |
87 | */ | |
88 | static void zorro8390_reset_8390(struct net_device *dev) | |
89 | { | |
90 | unsigned long reset_start_time = jiffies; | |
c45f812f | 91 | struct ei_device *ei_local = netdev_priv(dev); |
572404ea | 92 | |
c45f812f | 93 | netif_dbg(ei_local, hw, dev, "resetting - t=%ld...\n", jiffies); |
572404ea JP |
94 | |
95 | z_writeb(z_readb(NE_BASE + NE_RESET), NE_BASE + NE_RESET); | |
96 | ||
97 | ei_status.txing = 0; | |
98 | ei_status.dmaing = 0; | |
99 | ||
100 | /* This check _should_not_ be necessary, omit eventually. */ | |
101 | while ((z_readb(NE_BASE + NE_EN0_ISR) & ENISR_RESET) == 0) | |
102 | if (time_after(jiffies, reset_start_time + 2 * HZ / 100)) { | |
103 | netdev_warn(dev, "%s: did not complete\n", __func__); | |
104 | break; | |
105 | } | |
106 | z_writeb(ENISR_RESET, NE_BASE + NE_EN0_ISR); /* Ack intr */ | |
107 | } | |
108 | ||
109 | /* Grab the 8390 specific header. Similar to the block_input routine, but | |
110 | * we don't need to be concerned with ring wrap as the header will be at | |
111 | * the start of a page, so we optimize accordingly. | |
112 | */ | |
1da177e4 | 113 | static void zorro8390_get_8390_hdr(struct net_device *dev, |
572404ea JP |
114 | struct e8390_pkt_hdr *hdr, int ring_page) |
115 | { | |
116 | int nic_base = dev->base_addr; | |
117 | int cnt; | |
118 | short *ptrs; | |
119 | ||
120 | /* This *shouldn't* happen. | |
121 | * If it does, it's the last thing you'll see | |
122 | */ | |
123 | if (ei_status.dmaing) { | |
c45f812f MW |
124 | netdev_warn(dev, |
125 | "%s: DMAing conflict [DMAstat:%d][irqlock:%d]\n", | |
126 | __func__, ei_status.dmaing, ei_status.irqlock); | |
572404ea JP |
127 | return; |
128 | } | |
129 | ||
130 | ei_status.dmaing |= 0x01; | |
131 | z_writeb(E8390_NODMA + E8390_PAGE0 + E8390_START, nic_base + NE_CMD); | |
132 | z_writeb(ENISR_RDC, nic_base + NE_EN0_ISR); | |
133 | z_writeb(sizeof(struct e8390_pkt_hdr), nic_base + NE_EN0_RCNTLO); | |
134 | z_writeb(0, nic_base + NE_EN0_RCNTHI); | |
135 | z_writeb(0, nic_base + NE_EN0_RSARLO); /* On page boundary */ | |
136 | z_writeb(ring_page, nic_base + NE_EN0_RSARHI); | |
137 | z_writeb(E8390_RREAD+E8390_START, nic_base + NE_CMD); | |
138 | ||
139 | ptrs = (short *)hdr; | |
140 | for (cnt = 0; cnt < sizeof(struct e8390_pkt_hdr) >> 1; cnt++) | |
141 | *ptrs++ = z_readw(NE_BASE + NE_DATAPORT); | |
142 | ||
143 | z_writeb(ENISR_RDC, nic_base + NE_EN0_ISR); /* Ack intr */ | |
144 | ||
145 | hdr->count = WORDSWAP(hdr->count); | |
146 | ||
147 | ei_status.dmaing &= ~0x01; | |
148 | } | |
149 | ||
150 | /* Block input and output, similar to the Crynwr packet driver. | |
151 | * If you are porting to a new ethercard, look at the packet driver source | |
152 | * for hints. The NEx000 doesn't share the on-board packet memory -- | |
153 | * you have to put the packet out through the "remote DMA" dataport | |
154 | * using z_writeb. | |
155 | */ | |
1da177e4 | 156 | static void zorro8390_block_input(struct net_device *dev, int count, |
572404ea JP |
157 | struct sk_buff *skb, int ring_offset) |
158 | { | |
159 | int nic_base = dev->base_addr; | |
160 | char *buf = skb->data; | |
161 | short *ptrs; | |
162 | int cnt; | |
163 | ||
164 | /* This *shouldn't* happen. | |
165 | * If it does, it's the last thing you'll see | |
166 | */ | |
167 | if (ei_status.dmaing) { | |
168 | netdev_err(dev, "%s: DMAing conflict [DMAstat:%d][irqlock:%d]\n", | |
169 | __func__, ei_status.dmaing, ei_status.irqlock); | |
170 | return; | |
171 | } | |
172 | ei_status.dmaing |= 0x01; | |
173 | z_writeb(E8390_NODMA + E8390_PAGE0 + E8390_START, nic_base + NE_CMD); | |
174 | z_writeb(ENISR_RDC, nic_base + NE_EN0_ISR); | |
175 | z_writeb(count & 0xff, nic_base + NE_EN0_RCNTLO); | |
176 | z_writeb(count >> 8, nic_base + NE_EN0_RCNTHI); | |
177 | z_writeb(ring_offset & 0xff, nic_base + NE_EN0_RSARLO); | |
178 | z_writeb(ring_offset >> 8, nic_base + NE_EN0_RSARHI); | |
179 | z_writeb(E8390_RREAD+E8390_START, nic_base + NE_CMD); | |
180 | ptrs = (short *)buf; | |
181 | for (cnt = 0; cnt < count >> 1; cnt++) | |
182 | *ptrs++ = z_readw(NE_BASE + NE_DATAPORT); | |
183 | if (count & 0x01) | |
184 | buf[count - 1] = z_readb(NE_BASE + NE_DATAPORT); | |
185 | ||
186 | z_writeb(ENISR_RDC, nic_base + NE_EN0_ISR); /* Ack intr */ | |
187 | ei_status.dmaing &= ~0x01; | |
188 | } | |
189 | ||
190 | static void zorro8390_block_output(struct net_device *dev, int count, | |
1da177e4 | 191 | const unsigned char *buf, |
572404ea JP |
192 | const int start_page) |
193 | { | |
194 | int nic_base = NE_BASE; | |
195 | unsigned long dma_start; | |
196 | short *ptrs; | |
197 | int cnt; | |
198 | ||
199 | /* Round the count up for word writes. Do we need to do this? | |
200 | * What effect will an odd byte count have on the 8390? | |
201 | * I should check someday. | |
202 | */ | |
203 | if (count & 0x01) | |
204 | count++; | |
205 | ||
206 | /* This *shouldn't* happen. | |
207 | * If it does, it's the last thing you'll see | |
208 | */ | |
209 | if (ei_status.dmaing) { | |
210 | netdev_err(dev, "%s: DMAing conflict [DMAstat:%d][irqlock:%d]\n", | |
211 | __func__, ei_status.dmaing, ei_status.irqlock); | |
212 | return; | |
213 | } | |
214 | ei_status.dmaing |= 0x01; | |
215 | /* We should already be in page 0, but to be safe... */ | |
216 | z_writeb(E8390_PAGE0+E8390_START+E8390_NODMA, nic_base + NE_CMD); | |
217 | ||
218 | z_writeb(ENISR_RDC, nic_base + NE_EN0_ISR); | |
219 | ||
220 | /* Now the normal output. */ | |
221 | z_writeb(count & 0xff, nic_base + NE_EN0_RCNTLO); | |
222 | z_writeb(count >> 8, nic_base + NE_EN0_RCNTHI); | |
223 | z_writeb(0x00, nic_base + NE_EN0_RSARLO); | |
224 | z_writeb(start_page, nic_base + NE_EN0_RSARHI); | |
225 | ||
226 | z_writeb(E8390_RWRITE + E8390_START, nic_base + NE_CMD); | |
227 | ptrs = (short *)buf; | |
228 | for (cnt = 0; cnt < count >> 1; cnt++) | |
229 | z_writew(*ptrs++, NE_BASE + NE_DATAPORT); | |
230 | ||
231 | dma_start = jiffies; | |
232 | ||
233 | while ((z_readb(NE_BASE + NE_EN0_ISR) & ENISR_RDC) == 0) | |
234 | if (time_after(jiffies, dma_start + 2 * HZ / 100)) { | |
235 | /* 20ms */ | |
c45f812f | 236 | netdev_warn(dev, "timeout waiting for Tx RDC\n"); |
572404ea JP |
237 | zorro8390_reset_8390(dev); |
238 | __NS8390_init(dev, 1); | |
239 | break; | |
240 | } | |
241 | ||
242 | z_writeb(ENISR_RDC, nic_base + NE_EN0_ISR); /* Ack intr */ | |
243 | ei_status.dmaing &= ~0x01; | |
244 | } | |
1da177e4 | 245 | |
572404ea JP |
246 | static int zorro8390_open(struct net_device *dev) |
247 | { | |
248 | __ei_open(dev); | |
249 | return 0; | |
250 | } | |
1da177e4 | 251 | |
572404ea JP |
252 | static int zorro8390_close(struct net_device *dev) |
253 | { | |
c45f812f MW |
254 | struct ei_device *ei_local = netdev_priv(dev); |
255 | ||
256 | netif_dbg(ei_local, ifdown, dev, "Shutting down ethercard\n"); | |
572404ea JP |
257 | __ei_close(dev); |
258 | return 0; | |
259 | } | |
1da177e4 | 260 | |
4168ac0e | 261 | static void zorro8390_remove_one(struct zorro_dev *z) |
1da177e4 | 262 | { |
572404ea JP |
263 | struct net_device *dev = zorro_get_drvdata(z); |
264 | ||
265 | unregister_netdev(dev); | |
266 | free_irq(IRQ_AMIGA_PORTS, dev); | |
267 | release_mem_region(ZTWO_PADDR(dev->base_addr), NE_IO_EXTENT * 2); | |
1da177e4 | 268 | free_netdev(dev); |
1da177e4 LT |
269 | } |
270 | ||
4168ac0e | 271 | static struct zorro_device_id zorro8390_zorro_tbl[] = { |
572404ea JP |
272 | { ZORRO_PROD_VILLAGE_TRONIC_ARIADNE2, }, |
273 | { ZORRO_PROD_INDIVIDUAL_COMPUTERS_X_SURF, }, | |
274 | { 0 } | |
275 | }; | |
276 | MODULE_DEVICE_TABLE(zorro, zorro8390_zorro_tbl); | |
277 | ||
b6114794 SH |
278 | static const struct net_device_ops zorro8390_netdev_ops = { |
279 | .ndo_open = zorro8390_open, | |
280 | .ndo_stop = zorro8390_close, | |
cf7e032f GU |
281 | .ndo_start_xmit = __ei_start_xmit, |
282 | .ndo_tx_timeout = __ei_tx_timeout, | |
283 | .ndo_get_stats = __ei_get_stats, | |
afc4b13d | 284 | .ndo_set_rx_mode = __ei_set_multicast_list, |
b6114794 | 285 | .ndo_validate_addr = eth_validate_addr, |
572404ea | 286 | .ndo_set_mac_address = eth_mac_addr, |
b6114794 SH |
287 | .ndo_change_mtu = eth_change_mtu, |
288 | #ifdef CONFIG_NET_POLL_CONTROLLER | |
cf7e032f | 289 | .ndo_poll_controller = __ei_poll, |
b6114794 SH |
290 | #endif |
291 | }; | |
292 | ||
1dd06ae8 | 293 | static int zorro8390_init(struct net_device *dev, unsigned long board, |
6112ea08 | 294 | const char *name, void __iomem *ioaddr) |
1da177e4 | 295 | { |
572404ea JP |
296 | int i; |
297 | int err; | |
298 | unsigned char SA_prom[32]; | |
299 | int start_page, stop_page; | |
c45f812f | 300 | struct ei_device *ei_local = netdev_priv(dev); |
572404ea JP |
301 | static u32 zorro8390_offsets[16] = { |
302 | 0x00, 0x02, 0x04, 0x06, 0x08, 0x0a, 0x0c, 0x0e, | |
303 | 0x10, 0x12, 0x14, 0x16, 0x18, 0x1a, 0x1c, 0x1e, | |
1da177e4 | 304 | }; |
1da177e4 | 305 | |
572404ea JP |
306 | /* Reset card. Who knows what dain-bramaged state it was left in. */ |
307 | { | |
308 | unsigned long reset_start_time = jiffies; | |
1da177e4 | 309 | |
572404ea | 310 | z_writeb(z_readb(ioaddr + NE_RESET), ioaddr + NE_RESET); |
1da177e4 | 311 | |
572404ea JP |
312 | while ((z_readb(ioaddr + NE_EN0_ISR) & ENISR_RESET) == 0) |
313 | if (time_after(jiffies, | |
314 | reset_start_time + 2 * HZ / 100)) { | |
315 | netdev_warn(dev, "not found (no reset ack)\n"); | |
316 | return -ENODEV; | |
317 | } | |
1da177e4 | 318 | |
572404ea JP |
319 | z_writeb(0xff, ioaddr + NE_EN0_ISR); /* Ack all intr. */ |
320 | } | |
1da177e4 | 321 | |
572404ea JP |
322 | /* Read the 16 bytes of station address PROM. |
323 | * We must first initialize registers, | |
324 | * similar to NS8390_init(eifdev, 0). | |
325 | * We can't reliably read the SAPROM address without this. | |
326 | * (I learned the hard way!). | |
327 | */ | |
328 | { | |
329 | static const struct { | |
330 | u32 value; | |
331 | u32 offset; | |
332 | } program_seq[] = { | |
333 | {E8390_NODMA + E8390_PAGE0 + E8390_STOP, NE_CMD}, | |
334 | /* Select page 0 */ | |
335 | {0x48, NE_EN0_DCFG}, /* 0x48: Set byte-wide access */ | |
336 | {0x00, NE_EN0_RCNTLO}, /* Clear the count regs */ | |
337 | {0x00, NE_EN0_RCNTHI}, | |
338 | {0x00, NE_EN0_IMR}, /* Mask completion irq */ | |
339 | {0xFF, NE_EN0_ISR}, | |
340 | {E8390_RXOFF, NE_EN0_RXCR}, /* 0x20 Set to monitor */ | |
341 | {E8390_TXOFF, NE_EN0_TXCR}, /* 0x02 and loopback mode */ | |
342 | {32, NE_EN0_RCNTLO}, | |
343 | {0x00, NE_EN0_RCNTHI}, | |
344 | {0x00, NE_EN0_RSARLO}, /* DMA starting at 0x0000 */ | |
345 | {0x00, NE_EN0_RSARHI}, | |
346 | {E8390_RREAD + E8390_START, NE_CMD}, | |
347 | }; | |
348 | for (i = 0; i < ARRAY_SIZE(program_seq); i++) | |
349 | z_writeb(program_seq[i].value, | |
350 | ioaddr + program_seq[i].offset); | |
351 | } | |
352 | for (i = 0; i < 16; i++) { | |
353 | SA_prom[i] = z_readb(ioaddr + NE_DATAPORT); | |
354 | (void)z_readb(ioaddr + NE_DATAPORT); | |
355 | } | |
1da177e4 | 356 | |
572404ea JP |
357 | /* We must set the 8390 for word mode. */ |
358 | z_writeb(0x49, ioaddr + NE_EN0_DCFG); | |
359 | start_page = NESM_START_PG; | |
360 | stop_page = NESM_STOP_PG; | |
1da177e4 | 361 | |
6112ea08 | 362 | dev->base_addr = (unsigned long)ioaddr; |
572404ea | 363 | dev->irq = IRQ_AMIGA_PORTS; |
1da177e4 | 364 | |
572404ea JP |
365 | /* Install the Interrupt handler */ |
366 | i = request_irq(IRQ_AMIGA_PORTS, __ei_interrupt, | |
367 | IRQF_SHARED, DRV_NAME, dev); | |
368 | if (i) | |
369 | return i; | |
1da177e4 | 370 | |
104bf3fb | 371 | for (i = 0; i < ETH_ALEN; i++) |
572404ea | 372 | dev->dev_addr[i] = SA_prom[i]; |
1da177e4 | 373 | |
572404ea | 374 | pr_debug("Found ethernet address: %pM\n", dev->dev_addr); |
1da177e4 | 375 | |
572404ea JP |
376 | ei_status.name = name; |
377 | ei_status.tx_start_page = start_page; | |
378 | ei_status.stop_page = stop_page; | |
379 | ei_status.word16 = 1; | |
1da177e4 | 380 | |
572404ea | 381 | ei_status.rx_start_page = start_page + TX_PAGES; |
1da177e4 | 382 | |
572404ea JP |
383 | ei_status.reset_8390 = zorro8390_reset_8390; |
384 | ei_status.block_input = zorro8390_block_input; | |
385 | ei_status.block_output = zorro8390_block_output; | |
386 | ei_status.get_8390_hdr = zorro8390_get_8390_hdr; | |
387 | ei_status.reg_offset = zorro8390_offsets; | |
1da177e4 | 388 | |
572404ea JP |
389 | dev->netdev_ops = &zorro8390_netdev_ops; |
390 | __NS8390_init(dev, 0); | |
c45f812f MW |
391 | |
392 | ei_local->msg_enable = zorro8390_msg_enable; | |
393 | ||
572404ea JP |
394 | err = register_netdev(dev); |
395 | if (err) { | |
396 | free_irq(IRQ_AMIGA_PORTS, dev); | |
397 | return err; | |
1da177e4 | 398 | } |
1da177e4 | 399 | |
572404ea JP |
400 | netdev_info(dev, "%s at 0x%08lx, Ethernet Address %pM\n", |
401 | name, board, dev->dev_addr); | |
1da177e4 | 402 | |
572404ea | 403 | return 0; |
1da177e4 LT |
404 | } |
405 | ||
4168ac0e | 406 | static int zorro8390_init_one(struct zorro_dev *z, |
1dd06ae8 | 407 | const struct zorro_device_id *ent) |
1da177e4 | 408 | { |
572404ea JP |
409 | struct net_device *dev; |
410 | unsigned long board, ioaddr; | |
411 | int err, i; | |
412 | ||
413 | for (i = ARRAY_SIZE(cards) - 1; i >= 0; i--) | |
414 | if (z->id == cards[i].id) | |
415 | break; | |
416 | if (i < 0) | |
417 | return -ENODEV; | |
1da177e4 | 418 | |
572404ea JP |
419 | board = z->resource.start; |
420 | ioaddr = board + cards[i].offset; | |
421 | dev = ____alloc_ei_netdev(0); | |
422 | if (!dev) | |
423 | return -ENOMEM; | |
424 | if (!request_mem_region(ioaddr, NE_IO_EXTENT * 2, DRV_NAME)) { | |
425 | free_netdev(dev); | |
426 | return -EBUSY; | |
1da177e4 | 427 | } |
572404ea JP |
428 | err = zorro8390_init(dev, board, cards[i].name, ZTWO_VADDR(ioaddr)); |
429 | if (err) { | |
430 | release_mem_region(ioaddr, NE_IO_EXTENT * 2); | |
431 | free_netdev(dev); | |
432 | return err; | |
433 | } | |
434 | zorro_set_drvdata(z, dev); | |
435 | return 0; | |
1da177e4 LT |
436 | } |
437 | ||
572404ea JP |
438 | static struct zorro_driver zorro8390_driver = { |
439 | .name = "zorro8390", | |
440 | .id_table = zorro8390_zorro_tbl, | |
441 | .probe = zorro8390_init_one, | |
4168ac0e | 442 | .remove = zorro8390_remove_one, |
572404ea | 443 | }; |
1da177e4 LT |
444 | |
445 | static int __init zorro8390_init_module(void) | |
446 | { | |
572404ea | 447 | return zorro_register_driver(&zorro8390_driver); |
1da177e4 LT |
448 | } |
449 | ||
450 | static void __exit zorro8390_cleanup_module(void) | |
451 | { | |
572404ea | 452 | zorro_unregister_driver(&zorro8390_driver); |
1da177e4 LT |
453 | } |
454 | ||
455 | module_init(zorro8390_init_module); | |
456 | module_exit(zorro8390_cleanup_module); | |
457 | ||
458 | MODULE_LICENSE("GPL"); |