1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31#include <linux/module.h>
32#include <linux/kernel.h>
33#include <linux/errno.h>
34#include <linux/pci.h>
35#include <linux/init.h>
36#include <linux/delay.h>
37#include <linux/netdevice.h>
38#include <linux/etherdevice.h>
39#include <linux/interrupt.h>
40#include <linux/jiffies.h>
41
42#include <asm/io.h>
43#include <asm/setup.h>
44#include <asm/amigaints.h>
45#include <asm/amigahw.h>
46#include <asm/amigayle.h>
47#include <asm/amipcmcia.h>
48
49#include "8390.h"
50
51
52
53#define DRV_NAME "apne"
54
55#define NE_BASE (dev->base_addr)
56#define NE_CMD 0x00
57#define NE_DATAPORT 0x10
58#define NE_RESET 0x1f
59#define NE_IO_EXTENT 0x20
60
61#define NE_EN0_ISR 0x07
62#define NE_EN0_DCFG 0x0e
63
64#define NE_EN0_RSARLO 0x08
65#define NE_EN0_RSARHI 0x09
66#define NE_EN0_RCNTLO 0x0a
67#define NE_EN0_RXCR 0x0c
68#define NE_EN0_TXCR 0x0d
69#define NE_EN0_RCNTHI 0x0b
70#define NE_EN0_IMR 0x0f
71
72#define NE1SM_START_PG 0x20
73#define NE1SM_STOP_PG 0x40
74#define NESM_START_PG 0x40
75#define NESM_STOP_PG 0x80
76
77
78struct net_device * __init apne_probe(int unit);
79static int apne_probe1(struct net_device *dev, int ioaddr);
80
81static void apne_reset_8390(struct net_device *dev);
82static void apne_get_8390_hdr(struct net_device *dev, struct e8390_pkt_hdr *hdr,
83 int ring_page);
84static void apne_block_input(struct net_device *dev, int count,
85 struct sk_buff *skb, int ring_offset);
86static void apne_block_output(struct net_device *dev, const int count,
87 const unsigned char *buf, const int start_page);
88static irqreturn_t apne_interrupt(int irq, void *dev_id);
89
90static int init_pcmcia(void);
91
92
93
94#define IOBASE 0x300
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114static const char version[] =
115 "apne.c:v1.1 7/10/98 Alain Malek (Alain.Malek@cryogen.ch)\n";
116
117static int apne_owned;
118
119static u32 apne_msg_enable;
120module_param_named(msg_enable, apne_msg_enable, uint, (S_IRUSR|S_IRGRP|S_IROTH));
121MODULE_PARM_DESC(msg_enable, "Debug message level (see linux/netdevice.h for bitmap)");
122
123struct net_device * __init apne_probe(int unit)
124{
125 struct net_device *dev;
126 struct ei_device *ei_local;
127
128#ifndef MANUAL_CONFIG
129 char tuple[8];
130#endif
131 int err;
132
133 if (!MACH_IS_AMIGA)
134 return ERR_PTR(-ENODEV);
135
136 if (apne_owned)
137 return ERR_PTR(-ENODEV);
138
139 if ( !(AMIGAHW_PRESENT(PCMCIA)) )
140 return ERR_PTR(-ENODEV);
141
142 pr_info("Looking for PCMCIA ethernet card : ");
143
144
145 if (!(PCMCIA_INSERTED)) {
146 pr_cont("NO PCMCIA card inserted\n");
147 return ERR_PTR(-ENODEV);
148 }
149
150 dev = alloc_ei_netdev();
151 if (!dev)
152 return ERR_PTR(-ENOMEM);
153 if (unit >= 0) {
154 sprintf(dev->name, "eth%d", unit);
155 netdev_boot_setup_check(dev);
156 }
157 ei_local = netdev_priv(dev);
158 ei_local->msg_enable = apne_msg_enable;
159
160
161 pcmcia_disable_irq();
162
163#ifndef MANUAL_CONFIG
164 if ((pcmcia_copy_tuple(CISTPL_FUNCID, tuple, 8) < 3) ||
165 (tuple[2] != CISTPL_FUNCID_NETWORK)) {
166 pr_cont("not an ethernet card\n");
167
168 free_netdev(dev);
169 return ERR_PTR(-ENODEV);
170 }
171#endif
172
173 pr_cont("ethernet PCMCIA card inserted\n");
174
175 if (!init_pcmcia()) {
176
177 free_netdev(dev);
178 return ERR_PTR(-ENODEV);
179 }
180
181 if (!request_region(IOBASE, 0x20, DRV_NAME)) {
182 free_netdev(dev);
183 return ERR_PTR(-EBUSY);
184 }
185
186 err = apne_probe1(dev, IOBASE);
187 if (err) {
188 release_region(IOBASE, 0x20);
189 free_netdev(dev);
190 return ERR_PTR(err);
191 }
192 err = register_netdev(dev);
193 if (!err)
194 return dev;
195
196 pcmcia_disable_irq();
197 free_irq(IRQ_AMIGA_PORTS, dev);
198 pcmcia_reset();
199 release_region(IOBASE, 0x20);
200 free_netdev(dev);
201 return ERR_PTR(err);
202}
203
204static int __init apne_probe1(struct net_device *dev, int ioaddr)
205{
206 int i;
207 unsigned char SA_prom[32];
208 int wordlength = 2;
209 const char *name = NULL;
210 int start_page, stop_page;
211#ifndef MANUAL_HWADDR0
212 int neX000, ctron;
213#endif
214 static unsigned version_printed;
215
216 if ((apne_msg_enable & NETIF_MSG_DRV) && (version_printed++ == 0))
217 netdev_info(dev, version);
218
219 netdev_info(dev, "PCMCIA NE*000 ethercard probe");
220
221
222 { unsigned long reset_start_time = jiffies;
223
224 outb(inb(ioaddr + NE_RESET), ioaddr + NE_RESET);
225
226 while ((inb(ioaddr + NE_EN0_ISR) & ENISR_RESET) == 0)
227 if (time_after(jiffies, reset_start_time + 2*HZ/100)) {
228 pr_cont(" not found (no reset ack).\n");
229 return -ENODEV;
230 }
231
232 outb(0xff, ioaddr + NE_EN0_ISR);
233 }
234
235#ifndef MANUAL_HWADDR0
236
237
238
239
240
241 {
242 struct {unsigned long value, offset; } program_seq[] = {
243 {E8390_NODMA+E8390_PAGE0+E8390_STOP, NE_CMD},
244 {0x48, NE_EN0_DCFG},
245 {0x00, NE_EN0_RCNTLO},
246 {0x00, NE_EN0_RCNTHI},
247 {0x00, NE_EN0_IMR},
248 {0xFF, NE_EN0_ISR},
249 {E8390_RXOFF, NE_EN0_RXCR},
250 {E8390_TXOFF, NE_EN0_TXCR},
251 {32, NE_EN0_RCNTLO},
252 {0x00, NE_EN0_RCNTHI},
253 {0x00, NE_EN0_RSARLO},
254 {0x00, NE_EN0_RSARHI},
255 {E8390_RREAD+E8390_START, NE_CMD},
256 };
257 for (i = 0; i < ARRAY_SIZE(program_seq); i++) {
258 outb(program_seq[i].value, ioaddr + program_seq[i].offset);
259 }
260
261 }
262 for(i = 0; i < 32 ; i+=2) {
263 SA_prom[i] = inb(ioaddr + NE_DATAPORT);
264 SA_prom[i+1] = inb(ioaddr + NE_DATAPORT);
265 if (SA_prom[i] != SA_prom[i+1])
266 wordlength = 1;
267 }
268
269
270
271
272
273
274 if (wordlength == 2)
275 for (i = 0; i < 16; i++)
276 SA_prom[i] = SA_prom[i+i];
277
278 if (wordlength == 2) {
279
280 outb(0x49, ioaddr + NE_EN0_DCFG);
281 start_page = NESM_START_PG;
282 stop_page = NESM_STOP_PG;
283 } else {
284 start_page = NE1SM_START_PG;
285 stop_page = NE1SM_STOP_PG;
286 }
287
288 neX000 = (SA_prom[14] == 0x57 && SA_prom[15] == 0x57);
289 ctron = (SA_prom[0] == 0x00 && SA_prom[1] == 0x00 && SA_prom[2] == 0x1d);
290
291
292 if (neX000) {
293 name = (wordlength == 2) ? "NE2000" : "NE1000";
294 } else if (ctron) {
295 name = (wordlength == 2) ? "Ctron-8" : "Ctron-16";
296 start_page = 0x01;
297 stop_page = (wordlength == 2) ? 0x40 : 0x20;
298 } else {
299 pr_cont(" not found.\n");
300 return -ENXIO;
301
302 }
303
304#else
305 wordlength = 2;
306
307 outb(0x49, ioaddr + NE_EN0_DCFG);
308 start_page = NESM_START_PG;
309 stop_page = NESM_STOP_PG;
310
311 SA_prom[0] = MANUAL_HWADDR0;
312 SA_prom[1] = MANUAL_HWADDR1;
313 SA_prom[2] = MANUAL_HWADDR2;
314 SA_prom[3] = MANUAL_HWADDR3;
315 SA_prom[4] = MANUAL_HWADDR4;
316 SA_prom[5] = MANUAL_HWADDR5;
317 name = "NE2000";
318#endif
319
320 dev->base_addr = ioaddr;
321 dev->irq = IRQ_AMIGA_PORTS;
322 dev->netdev_ops = &ei_netdev_ops;
323
324
325 i = request_irq(dev->irq, apne_interrupt, IRQF_SHARED, DRV_NAME, dev);
326 if (i) return i;
327
328 for (i = 0; i < ETH_ALEN; i++)
329 dev->dev_addr[i] = SA_prom[i];
330
331 pr_cont(" %pM\n", dev->dev_addr);
332
333 netdev_info(dev, "%s found.\n", name);
334
335 ei_status.name = name;
336 ei_status.tx_start_page = start_page;
337 ei_status.stop_page = stop_page;
338 ei_status.word16 = (wordlength == 2);
339
340 ei_status.rx_start_page = start_page + TX_PAGES;
341
342 ei_status.reset_8390 = &apne_reset_8390;
343 ei_status.block_input = &apne_block_input;
344 ei_status.block_output = &apne_block_output;
345 ei_status.get_8390_hdr = &apne_get_8390_hdr;
346
347 NS8390_init(dev, 0);
348
349 pcmcia_ack_int(pcmcia_get_intreq());
350 pcmcia_enable_irq();
351
352 apne_owned = 1;
353
354 return 0;
355}
356
357
358
359static void
360apne_reset_8390(struct net_device *dev)
361{
362 unsigned long reset_start_time = jiffies;
363 struct ei_device *ei_local = netdev_priv(dev);
364
365 init_pcmcia();
366
367 netif_dbg(ei_local, hw, dev, "resetting the 8390 t=%ld...\n", jiffies);
368
369 outb(inb(NE_BASE + NE_RESET), NE_BASE + NE_RESET);
370
371 ei_status.txing = 0;
372 ei_status.dmaing = 0;
373
374
375 while ((inb(NE_BASE+NE_EN0_ISR) & ENISR_RESET) == 0)
376 if (time_after(jiffies, reset_start_time + 2*HZ/100)) {
377 netdev_err(dev, "ne_reset_8390() did not complete.\n");
378 break;
379 }
380 outb(ENISR_RESET, NE_BASE + NE_EN0_ISR);
381}
382
383
384
385
386
387static void
388apne_get_8390_hdr(struct net_device *dev, struct e8390_pkt_hdr *hdr, int ring_page)
389{
390
391 int nic_base = dev->base_addr;
392 int cnt;
393 char *ptrc;
394 short *ptrs;
395
396
397 if (ei_status.dmaing) {
398 netdev_err(dev, "DMAing conflict in ne_get_8390_hdr "
399 "[DMAstat:%d][irqlock:%d][intr:%d].\n",
400 ei_status.dmaing, ei_status.irqlock, dev->irq);
401 return;
402 }
403
404 ei_status.dmaing |= 0x01;
405 outb(E8390_NODMA+E8390_PAGE0+E8390_START, nic_base+ NE_CMD);
406 outb(ENISR_RDC, nic_base + NE_EN0_ISR);
407 outb(sizeof(struct e8390_pkt_hdr), nic_base + NE_EN0_RCNTLO);
408 outb(0, nic_base + NE_EN0_RCNTHI);
409 outb(0, nic_base + NE_EN0_RSARLO);
410 outb(ring_page, nic_base + NE_EN0_RSARHI);
411 outb(E8390_RREAD+E8390_START, nic_base + NE_CMD);
412
413 if (ei_status.word16) {
414 ptrs = (short*)hdr;
415 for(cnt = 0; cnt < (sizeof(struct e8390_pkt_hdr)>>1); cnt++)
416 *ptrs++ = inw(NE_BASE + NE_DATAPORT);
417 } else {
418 ptrc = (char*)hdr;
419 for(cnt = 0; cnt < sizeof(struct e8390_pkt_hdr); cnt++)
420 *ptrc++ = inb(NE_BASE + NE_DATAPORT);
421 }
422
423 outb(ENISR_RDC, nic_base + NE_EN0_ISR);
424 ei_status.dmaing &= ~0x01;
425
426 le16_to_cpus(&hdr->count);
427}
428
429
430
431
432
433
434static void
435apne_block_input(struct net_device *dev, int count, struct sk_buff *skb, int ring_offset)
436{
437 int nic_base = dev->base_addr;
438 char *buf = skb->data;
439 char *ptrc;
440 short *ptrs;
441 int cnt;
442
443
444 if (ei_status.dmaing) {
445 netdev_err(dev, "DMAing conflict in ne_block_input "
446 "[DMAstat:%d][irqlock:%d][intr:%d].\n",
447 ei_status.dmaing, ei_status.irqlock, dev->irq);
448 return;
449 }
450 ei_status.dmaing |= 0x01;
451 outb(E8390_NODMA+E8390_PAGE0+E8390_START, nic_base+ NE_CMD);
452 outb(ENISR_RDC, nic_base + NE_EN0_ISR);
453 outb(count & 0xff, nic_base + NE_EN0_RCNTLO);
454 outb(count >> 8, nic_base + NE_EN0_RCNTHI);
455 outb(ring_offset & 0xff, nic_base + NE_EN0_RSARLO);
456 outb(ring_offset >> 8, nic_base + NE_EN0_RSARHI);
457 outb(E8390_RREAD+E8390_START, nic_base + NE_CMD);
458 if (ei_status.word16) {
459 ptrs = (short*)buf;
460 for (cnt = 0; cnt < (count>>1); cnt++)
461 *ptrs++ = inw(NE_BASE + NE_DATAPORT);
462 if (count & 0x01) {
463 buf[count-1] = inb(NE_BASE + NE_DATAPORT);
464 }
465 } else {
466 ptrc = buf;
467 for (cnt = 0; cnt < count; cnt++)
468 *ptrc++ = inb(NE_BASE + NE_DATAPORT);
469 }
470
471 outb(ENISR_RDC, nic_base + NE_EN0_ISR);
472 ei_status.dmaing &= ~0x01;
473}
474
475static void
476apne_block_output(struct net_device *dev, int count,
477 const unsigned char *buf, const int start_page)
478{
479 int nic_base = NE_BASE;
480 unsigned long dma_start;
481 char *ptrc;
482 short *ptrs;
483 int cnt;
484
485
486
487
488 if (ei_status.word16 && (count & 0x01))
489 count++;
490
491
492 if (ei_status.dmaing) {
493 netdev_err(dev, "DMAing conflict in ne_block_output."
494 "[DMAstat:%d][irqlock:%d][intr:%d]\n",
495 ei_status.dmaing, ei_status.irqlock, dev->irq);
496 return;
497 }
498 ei_status.dmaing |= 0x01;
499
500 outb(E8390_PAGE0+E8390_START+E8390_NODMA, nic_base + NE_CMD);
501
502 outb(ENISR_RDC, nic_base + NE_EN0_ISR);
503
504
505 outb(count & 0xff, nic_base + NE_EN0_RCNTLO);
506 outb(count >> 8, nic_base + NE_EN0_RCNTHI);
507 outb(0x00, nic_base + NE_EN0_RSARLO);
508 outb(start_page, nic_base + NE_EN0_RSARHI);
509
510 outb(E8390_RWRITE+E8390_START, nic_base + NE_CMD);
511 if (ei_status.word16) {
512 ptrs = (short*)buf;
513 for (cnt = 0; cnt < count>>1; cnt++)
514 outw(*ptrs++, NE_BASE+NE_DATAPORT);
515 } else {
516 ptrc = (char*)buf;
517 for (cnt = 0; cnt < count; cnt++)
518 outb(*ptrc++, NE_BASE + NE_DATAPORT);
519 }
520
521 dma_start = jiffies;
522
523 while ((inb(NE_BASE + NE_EN0_ISR) & ENISR_RDC) == 0)
524 if (time_after(jiffies, dma_start + 2*HZ/100)) {
525 netdev_warn(dev, "timeout waiting for Tx RDC.\n");
526 apne_reset_8390(dev);
527 NS8390_init(dev,1);
528 break;
529 }
530
531 outb(ENISR_RDC, nic_base + NE_EN0_ISR);
532 ei_status.dmaing &= ~0x01;
533}
534
535static irqreturn_t apne_interrupt(int irq, void *dev_id)
536{
537 unsigned char pcmcia_intreq;
538
539 if (!(gayle.inten & GAYLE_IRQ_IRQ))
540 return IRQ_NONE;
541
542 pcmcia_intreq = pcmcia_get_intreq();
543
544 if (!(pcmcia_intreq & GAYLE_IRQ_IRQ)) {
545 pcmcia_ack_int(pcmcia_intreq);
546 return IRQ_NONE;
547 }
548 if (apne_msg_enable & NETIF_MSG_INTR)
549 pr_debug("pcmcia intreq = %x\n", pcmcia_intreq);
550 pcmcia_disable_irq();
551 ei_interrupt(irq, dev_id);
552 pcmcia_ack_int(pcmcia_get_intreq());
553 pcmcia_enable_irq();
554 return IRQ_HANDLED;
555}
556
557#ifdef MODULE
558static struct net_device *apne_dev;
559
560static int __init apne_module_init(void)
561{
562 apne_dev = apne_probe(-1);
563 return PTR_ERR_OR_ZERO(apne_dev);
564}
565
566static void __exit apne_module_exit(void)
567{
568 unregister_netdev(apne_dev);
569
570 pcmcia_disable_irq();
571
572 free_irq(IRQ_AMIGA_PORTS, apne_dev);
573
574 pcmcia_reset();
575
576 release_region(IOBASE, 0x20);
577
578 free_netdev(apne_dev);
579}
580module_init(apne_module_init);
581module_exit(apne_module_exit);
582#endif
583
584static int init_pcmcia(void)
585{
586 u_char config;
587#ifndef MANUAL_CONFIG
588 u_char tuple[32];
589 int offset_len;
590#endif
591 u_long offset;
592
593 pcmcia_reset();
594 pcmcia_program_voltage(PCMCIA_0V);
595 pcmcia_access_speed(PCMCIA_SPEED_250NS);
596 pcmcia_write_enable();
597
598#ifdef MANUAL_CONFIG
599 config = MANUAL_CONFIG;
600#else
601
602
603 if (pcmcia_copy_tuple(CISTPL_CFTABLE_ENTRY, tuple, 32) < 3)
604 return 0;
605
606 config = tuple[2] & 0x3f;
607#endif
608#ifdef MANUAL_OFFSET
609 offset = MANUAL_OFFSET;
610#else
611 if (pcmcia_copy_tuple(CISTPL_CONFIG, tuple, 32) < 6)
612 return 0;
613
614 offset_len = (tuple[2] & 0x3) + 1;
615 offset = 0;
616 while(offset_len--) {
617 offset = (offset << 8) | tuple[4+offset_len];
618 }
619#endif
620
621 out_8(GAYLE_ATTRIBUTE+offset, config);
622
623 return 1;
624}
625
626MODULE_LICENSE("GPL");
627