File: /usr/src/linux/drivers/net/daynaport.c
1 /* daynaport.c: A Macintosh 8390 based ethernet driver for linux. */
2 /*
3 Derived from code:
4
5 Written 1993-94 by Donald Becker.
6
7 Copyright 1993 United States Government as represented by the
8 Director, National Security Agency.
9
10 This software may be used and distributed according to the terms
11 of the GNU General Public License, incorporated herein by reference.
12
13 TODO:
14
15 The block output routines may be wrong for non Dayna
16 cards
17
18 Fix this driver so that it will attempt to use the info
19 (i.e. iobase, iosize) given to it by the new and improved
20 NuBus code.
21
22 Despite its misleading filename, this driver is not Dayna-specific
23 anymore. */
24 /* Cabletron E6100 card support added by Tony Mantler (eek@escape.ca) April 1999 */
25
26 static const char *version =
27 "daynaport.c: v0.02 1999-05-17 Alan Cox (Alan.Cox@linux.org) and others\n";
28 static int version_printed;
29
30 #include <linux/module.h>
31 #include <linux/init.h>
32 #include <linux/kernel.h>
33 #include <linux/sched.h>
34 #include <linux/errno.h>
35 #include <linux/string.h>
36 #include <linux/nubus.h>
37 #include <asm/io.h>
38 #include <asm/system.h>
39 #include <asm/hwtest.h>
40 #include <asm/macints.h>
41 #include <linux/delay.h>
42
43 #include <linux/netdevice.h>
44 #include <linux/etherdevice.h>
45 #include "8390.h"
46
47 static int ns8390_probe1(struct net_device *dev, int word16, char *name, int id,
48 int prom, struct nubus_dev *ndev);
49
50 static int ns8390_open(struct net_device *dev);
51 static void ns8390_no_reset(struct net_device *dev);
52 static int ns8390_close_card(struct net_device *dev);
53
54 /* Interlan */
55 static void interlan_reset(struct net_device *dev);
56
57 /* Dayna */
58 static void dayna_get_8390_hdr(struct net_device *dev, struct e8390_pkt_hdr *hdr,
59 int ring_page);
60 static void dayna_block_input(struct net_device *dev, int count,
61 struct sk_buff *skb, int ring_offset);
62 static void dayna_block_output(struct net_device *dev, int count,
63 const unsigned char *buf, const int start_page);
64
65 /* Sane (32-bit chunk memory read/write) */
66 static void sane_get_8390_hdr(struct net_device *dev, struct e8390_pkt_hdr *hdr,
67 int ring_page);
68 static void sane_block_input(struct net_device *dev, int count,
69 struct sk_buff *skb, int ring_offset);
70 static void sane_block_output(struct net_device *dev, int count,
71 const unsigned char *buf, const int start_page);
72
73 /* Slow Sane (16-bit chunk memory read/write) */
74 static void slow_sane_get_8390_hdr(struct net_device *dev, struct e8390_pkt_hdr *hdr,
75 int ring_page);
76 static void slow_sane_block_input(struct net_device *dev, int count,
77 struct sk_buff *skb, int ring_offset);
78 static void slow_sane_block_output(struct net_device *dev, int count,
79 const unsigned char *buf, const int start_page);
80
81
82 #define WD_START_PG 0x00 /* First page of TX buffer */
83 #define WD03_STOP_PG 0x20 /* Last page +1 of RX ring */
84 #define WD13_STOP_PG 0x40 /* Last page +1 of RX ring */
85
86 #define CABLETRON_RX_START_PG 0x00 /* First page of RX buffer */
87 #define CABLETRON_RX_STOP_PG 0x30 /* Last page +1 of RX ring */
88 #define CABLETRON_TX_START_PG CABLETRON_RX_STOP_PG /* First page of TX buffer */
89
90
91 #define DAYNA_MAC_BASE 0xf0007
92 #define DAYNA_8390_BASE 0x80000 /* 3 */
93 #define DAYNA_8390_MEM 0x00000
94 #define DAYNA_MEMSIZE 0x04000 /* First word of each long ! */
95
96 #define APPLE_8390_BASE 0xE0000
97 #define APPLE_8390_MEM 0xD0000
98 #define APPLE_MEMSIZE 8192 /* FIXME: need to dynamically check */
99
100 #define KINETICS_MAC_BASE 0xf0004 /* first byte of each long */
101 #define KINETICS_8390_BASE 0x80000
102 #define KINETICS_8390_MEM 0x00000 /* first word of each long */
103 #define KINETICS_MEMSIZE 8192 /* FIXME: need to dynamically check */
104 /*#define KINETICS_MEMSIZE (0x10000/2) * CSA: on the board I have, at least */
105
106 #define CABLETRON_8390_BASE 0x90000
107 #define CABLETRON_8390_MEM 0x00000
108
109 static int test_8390(volatile char *ptr, int scale)
110 {
111 int regd;
112 int v;
113
114 if(hwreg_present(&ptr[0x00])==0)
115 return -EIO;
116 if(hwreg_present(&ptr[0x0D<<scale])==0)
117 return -EIO;
118 if(hwreg_present(&ptr[0x0D<<scale])==0)
119 return -EIO;
120 ptr[0x00]=E8390_NODMA+E8390_PAGE1+E8390_STOP;
121 regd=ptr[0x0D<<scale];
122 ptr[0x0D<<scale]=0xFF;
123 ptr[0x00]=E8390_NODMA+E8390_PAGE0;
124 v=ptr[0x0D<<scale];
125 if(ptr[0x0D<<scale]!=0)
126 {
127 ptr[0x0D<<scale]=regd;
128 return -ENODEV;
129 }
130 /* printk("NS8390 found at %p scaled %d\n", ptr,scale);*/
131 return 0;
132 }
133 /*
134 * Identify the species of NS8390 card/driver we need
135 */
136
137 enum mac8390_type {
138 NS8390_DAYNA,
139 NS8390_INTERLAN,
140 NS8390_KINETICS,
141 NS8390_APPLE,
142 NS8390_FARALLON,
143 NS8390_ASANTE,
144 NS8390_CABLETRON
145 };
146
147 static int __init ns8390_ident(struct nubus_dev* ndev)
148 {
149 /* This really needs to be tested and tested hard. */
150
151 /* Summary of what we know so far --
152 * SW: 0x0104 -- asante, 16 bit, back4_offsets
153 * SW: 0x010b -- daynaport, 16 bit, fwrd4_offsets
154 * SW: 0x010c -- farallon, 16 bit, back4_offsets, no long word access
155 * SW: 0x011a -- focus, [no details yet]
156 * SW: ?????? -- interlan, 16 bit, back4_offsets, funny reset
157 * SW: ?????? -- kinetics, 8 bit, back4_offsets
158 * -- so i've this hypothesis going that says DrSW&1 says whether the
159 * map is forward or backwards -- and maybe DrSW&256 says what the
160 * register spacing is -- for all cards that report a DrSW in some
161 * range.
162 * This would allow the "apple compatible" driver to drive many
163 * seemingly different types of cards. More DrSW info is needed
164 * to investigate this properly. [CSA, 21-May-1999]
165 */
166 /* Dayna ex Kinetics board */
167 if(ndev->dr_sw == NUBUS_DRSW_DAYNA)
168 return NS8390_DAYNA;
169 if(ndev->dr_sw == NUBUS_DRSW_ASANTE)
170 return NS8390_ASANTE;
171 if(ndev->dr_sw == NUBUS_DRSW_FARALLON) /* farallon or sonic systems */
172 return NS8390_FARALLON;
173 if(ndev->dr_sw == NUBUS_DRSW_KINETICS)
174 return NS8390_KINETICS;
175 /* My ATI Engineering card with this combination crashes the */
176 /* driver trying to xmit packets. Best not touch it for now. */
177 /* - 1999-05-20 (funaho@jurai.org) */
178 if(ndev->dr_sw == NUBUS_DRSW_FOCUS)
179 return -1;
180
181 /* Check the HW on this one, because it shares the same DrSW as
182 the on-board SONIC chips */
183 if(ndev->dr_hw == NUBUS_DRHW_CABLETRON)
184 return NS8390_CABLETRON;
185 /* does anyone have one of these? */
186 if(ndev->dr_hw == NUBUS_DRHW_INTERLAN)
187 return NS8390_INTERLAN;
188
189 /* FIXME: what do genuine Apple boards look like? */
190 return -1;
191 }
192
193 /*
194 * Memory probe for 8390 cards
195 */
196
197 static int __init apple_8390_mem_probe(volatile unsigned short *p)
198 {
199 int i, j;
200 /*
201 * Algorithm.
202 * 1. Check each block size of memory doesn't fault
203 * 2. Write a value to it
204 * 3. Check all previous blocks are unaffected
205 */
206
207 for(i=0;i<2;i++)
208 {
209 volatile unsigned short *m=p+4096*i;
210 /* Unwriteable - we have a fully decoded card and the
211 RAM end located */
212
213 if(hwreg_present(m)==0)
214 return 8192*i;
215
216 *m=0xA5A0|i;
217
218 for(j=0;j<i;j++)
219 {
220 /* Partial decode and wrap ? */
221 if(p[4096*j]!=(0xA5A0|j))
222 {
223 /* This is the first misdecode, so it had
224 one less page than we tried */
225 return 8192*i;
226 }
227 j++;
228 }
229 /* Ok it still decodes.. move on 8K */
230 }
231 /*
232 * We don't look past 16K. That should cover most cards
233 * and above 16K there isnt really any gain.
234 */
235 return 16384;
236 }
237
238 /*
239 * Probe for 8390 cards.
240 * The ns8390_probe1() routine initializes the card and fills the
241 * station address field.
242 *
243 * The NuBus interface has changed! We now scan for these somewhat
244 * like how the PCI and Zorro drivers do. It's not clear whether
245 * this is actually better, but it makes things more consistent.
246 *
247 * dev->mem_start points
248 * at the memory ring, dev->mem_end gives the end of it.
249 */
250
251 int __init mac8390_probe(struct net_device *dev)
252 {
253 static int slots;
254 volatile unsigned short *i;
255 volatile unsigned char *p;
256 int plen;
257 int id;
258 static struct nubus_dev* ndev;
259
260 /* Find the first card that hasn't already been seen */
261 while ((ndev = nubus_find_type(NUBUS_CAT_NETWORK,
262 NUBUS_TYPE_ETHERNET, ndev)) != NULL) {
263 /* Have we seen it already? */
264 if (slots & (1<<ndev->board->slot))
265 continue;
266 slots |= 1<<ndev->board->slot;
267
268 /* Is it one of ours? */
269 if ((id = ns8390_ident(ndev)) != -1)
270 break;
271 }
272
273 /* Hm. No more cards, then */
274 if (ndev == NULL)
275 return -ENODEV;
276
277 dev = init_etherdev(dev, 0);
278 if (!dev)
279 return -ENOMEM;
280 SET_MODULE_OWNER(dev);
281
282 if (!version_printed) {
283 printk(KERN_INFO "%s", version);
284 version_printed = 1;
285 }
286
287 /*
288 * Dayna specific init
289 */
290 if(id==NS8390_DAYNA)
291 {
292 dev->base_addr = (int)(ndev->board->slot_addr+DAYNA_8390_BASE);
293 dev->mem_start = (int)(ndev->board->slot_addr+DAYNA_8390_MEM);
294 dev->mem_end = dev->mem_start+DAYNA_MEMSIZE; /* 8K it seems */
295
296 printk(KERN_INFO "%s: daynaport. testing board: ", dev->name);
297
298 printk("memory - ");
299
300 i = (void *)dev->mem_start;
301 memset((void *)i,0xAA, DAYNA_MEMSIZE);
302 while(i<(volatile unsigned short *)dev->mem_end)
303 {
304 if(*i!=0xAAAA)
305 goto membad;
306 *i=0x5678; /* make sure we catch byte smearing */
307 if(*i!=0x5678)
308 goto membad;
309 i+=2; /* Skip a word */
310 }
311
312 printk("controller - ");
313
314 p=(void *)dev->base_addr;
315 plen=0;
316
317 while(plen<0x3FF00)
318 {
319 if(test_8390(p,0)==0)
320 break;
321 if(test_8390(p,1)==0)
322 break;
323 if(test_8390(p,2)==0)
324 break;
325 if(test_8390(p,3)==0)
326 break;
327 plen++;
328 p++;
329 }
330 if(plen==0x3FF00)
331 goto membad;
332 printk("OK\n");
333 dev->irq = SLOT2IRQ(ndev->board->slot);
334 if(ns8390_probe1(dev, 0, "dayna", id, -1, ndev)==0)
335 return 0;
336 }
337 /* Cabletron */
338 if (id==NS8390_CABLETRON) {
339 int memsize = 16<<10; /* fix this */
340
341 dev->base_addr=(int)(ndev->board->slot_addr+CABLETRON_8390_BASE);
342 dev->mem_start=(int)(ndev->board->slot_addr+CABLETRON_8390_MEM);
343 dev->mem_end=dev->mem_start+memsize;
344 dev->irq = SLOT2IRQ(ndev->board->slot);
345
346 /* The base address is unreadable if 0x00 has been written to the command register */
347 /* Reset the chip by writing E8390_NODMA+E8390_PAGE0+E8390_STOP just to be sure */
348 i = (void *)dev->base_addr;
349 *i = 0x21;
350
351 printk(KERN_INFO "%s: cabletron: testing board: ", dev->name);
352 printk("%dK memory - ", memsize>>10);
353 i=(void *)dev->mem_start;
354 while(i<(volatile unsigned short *)(dev->mem_start+memsize))
355 {
356 *i=0xAAAA;
357 if(*i!=0xAAAA)
358 goto membad;
359 *i=0x5555;
360 if(*i!=0x5555)
361 goto membad;
362 i+=2; /* Skip a word */
363 }
364 printk("OK\n");
365
366 if(ns8390_probe1(dev, 1, "cabletron", id, -1, ndev)==0)
367 return 0;
368 }
369 /* Apple, Farallon, Asante */
370 if(id==NS8390_APPLE || id==NS8390_FARALLON || id==NS8390_ASANTE)
371 {
372 int memsize;
373
374 dev->base_addr=(int)(ndev->board->slot_addr+APPLE_8390_BASE);
375 dev->mem_start=(int)(ndev->board->slot_addr+APPLE_8390_MEM);
376
377 memsize = apple_8390_mem_probe((void *)dev->mem_start);
378
379 dev->mem_end=dev->mem_start+memsize;
380 dev->irq = SLOT2IRQ(ndev->board->slot);
381
382 switch(id)
383 {
384 case NS8390_FARALLON:
385 printk(KERN_INFO "%s: farallon: testing board: ", dev->name);
386 break;
387 case NS8390_ASANTE:
388 printk(KERN_INFO "%s: asante: testing board: ", dev->name);
389 break;
390 case NS8390_APPLE:
391 default:
392 printk(KERN_INFO "%s: apple/clone: testing board: ", dev->name);
393 break;
394 }
395
396 printk("%dK memory - ", memsize>>10);
397
398 i=(void *)dev->mem_start;
399 memset((void *)i,0xAA, memsize);
400 while(i<(volatile unsigned short *)dev->mem_end)
401 {
402 if(*i!=0xAAAA)
403 goto membad;
404 *i=0x5555;
405 if(*i!=0x5555)
406 goto membad;
407 i+=2; /* Skip a word */
408 }
409 printk("OK\n");
410
411 switch (id)
412 {
413 case NS8390_FARALLON:
414 if(ns8390_probe1(dev, 1, "farallon", id, -1, ndev)==0)
415 return 0;
416 break;
417 case NS8390_ASANTE:
418 if(ns8390_probe1(dev, 1, "asante", id, -1, ndev)==0)
419 return 0;
420 break;
421 case NS8390_APPLE:
422 default:
423 if(ns8390_probe1(dev, 1, "apple/clone", id, -1, ndev)==0)
424 return 0;
425 break;
426 }
427 }
428 /* Interlan */
429 if(id==NS8390_INTERLAN)
430 {
431 /* As apple and asante */
432 dev->base_addr=(int)(ndev->board->slot_addr+APPLE_8390_BASE);
433 dev->mem_start=(int)(ndev->board->slot_addr+APPLE_8390_MEM);
434 dev->mem_end=dev->mem_start+APPLE_MEMSIZE; /* 8K it seems */
435 dev->irq = SLOT2IRQ(ndev->board->slot);
436 if(ns8390_probe1(dev, 1, "interlan", id, -1, ndev)==0)
437 return 0;
438 }
439 /* Kinetics (Shiva Etherport) */
440 if(id==NS8390_KINETICS)
441 {
442 dev->base_addr=(int)(ndev->board->slot_addr+KINETICS_8390_BASE);
443 dev->mem_start=(int)(ndev->board->slot_addr+KINETICS_8390_MEM);
444 dev->mem_end=dev->mem_start+KINETICS_MEMSIZE; /* 8K it seems */
445 dev->irq = SLOT2IRQ(ndev->board->slot);
446 if(ns8390_probe1(dev, 0, "kinetics", id, -1, ndev)==0)
447 return 0;
448 }
449
450 /* We should hopefully not get here */
451 printk(KERN_ERR "Probe unsuccessful.\n");
452 return -ENODEV;
453
454 membad:
455 printk(KERN_ERR "failed at %p in %p - %p.\n", i,
456 (void *)dev->mem_start, (void *)dev->mem_end);
457 return -ENODEV;
458 }
459
460 static int __init mac8390_ethernet_addr(struct nubus_dev* ndev, unsigned char addr[6])
461 {
462 struct nubus_dir dir;
463 struct nubus_dirent ent;
464
465 /* Get the functional resource for this device */
466 if (nubus_get_func_dir(ndev, &dir) == -1)
467 return -1;
468 if (nubus_find_rsrc(&dir, NUBUS_RESID_MAC_ADDRESS, &ent) == -1)
469 return -1;
470
471 nubus_get_rsrc_mem(addr, &ent, 6);
472 return 0;
473 }
474
475 static int __init ns8390_probe1(struct net_device *dev, int word16, char *model_name,
476 int type, int promoff, struct nubus_dev *ndev)
477 {
478 static u32 fwrd4_offsets[16]={
479 0, 4, 8, 12,
480 16, 20, 24, 28,
481 32, 36, 40, 44,
482 48, 52, 56, 60
483 };
484 static u32 back4_offsets[16]={
485 60, 56, 52, 48,
486 44, 40, 36, 32,
487 28, 24, 20, 16,
488 12, 8, 4, 0
489 };
490 static u32 fwrd2_offsets[16]={
491 0, 2, 4, 6,
492 8, 10, 12, 14,
493 16, 18, 20, 22,
494 24, 26, 28, 30
495 };
496
497 unsigned char *prom = (unsigned char*) ndev->board->slot_addr + promoff;
498
499 /* Allocate dev->priv and fill in 8390 specific dev fields. */
500 if (ethdev_init(dev))
501 {
502 printk ("%s: unable to get memory for dev->priv.\n", dev->name);
503 return -ENOMEM;
504 }
505
506 /* OK, we are certain this is going to work. Setup the device. */
507
508 ei_status.name = model_name;
509 ei_status.word16 = word16;
510
511 if (type==NS8390_CABLETRON) {
512 /* Cabletron card puts the RX buffer before the TX buffer */
513 ei_status.tx_start_page = CABLETRON_TX_START_PG;
514 ei_status.rx_start_page = CABLETRON_RX_START_PG;
515 ei_status.stop_page = CABLETRON_RX_STOP_PG;
516 dev->rmem_start = dev->mem_start;
517 dev->rmem_end = dev->mem_start + CABLETRON_RX_STOP_PG*256;
518 } else {
519 ei_status.tx_start_page = WD_START_PG;
520 ei_status.rx_start_page = WD_START_PG + TX_PAGES;
521 ei_status.stop_page = (dev->mem_end - dev->mem_start)/256;
522 dev->rmem_start = dev->mem_start + TX_PAGES*256;
523 dev->rmem_end = dev->mem_end;
524 }
525
526 if(promoff==-1) /* Use nubus resources ? */
527 {
528 if(mac8390_ethernet_addr(ndev, dev->dev_addr))
529 {
530 printk("mac_ns8390: MAC address not in resources!\n");
531 return -ENODEV;
532 }
533 }
534 else /* Pull it off the card */
535 {
536 int i=0;
537 int x=1;
538 /* These should go in the end I hope */
539 if(type==NS8390_DAYNA)
540 x=2;
541 if(type==NS8390_INTERLAN || type==NS8390_KINETICS)
542 x=4;
543 while(i<6)
544 {
545 dev->dev_addr[i]=*prom;
546 prom+=x;
547 if(i)
548 printk(":");
549 printk("%02X",dev->dev_addr[i++]);
550 }
551 }
552
553 printk(KERN_INFO "%s: %s in slot %X (type %s)\n",
554 dev->name, ndev->board->name, ndev->board->slot, model_name);
555 printk(KERN_INFO "MAC ");
556 {
557 int i;
558 for (i = 0; i < 6; i++) {
559 printk("%2.2x", dev->dev_addr[i]);
560 if (i < 5)
561 printk(":");
562 }
563 }
564 printk(" IRQ %d, shared memory at %#lx-%#lx.\n",
565 dev->irq, dev->mem_start, dev->mem_end-1);
566
567 switch(type)
568 {
569 case NS8390_DAYNA: /* Dayna card */
570 case NS8390_KINETICS: /* Kinetics -- 8 bit config, but 16 bit mem */
571 /* 16 bit, 4 word offsets */
572 ei_status.reset_8390 = &ns8390_no_reset;
573 ei_status.block_input = &dayna_block_input;
574 ei_status.block_output = &dayna_block_output;
575 ei_status.get_8390_hdr = &dayna_get_8390_hdr;
576 ei_status.reg_offset = fwrd4_offsets;
577 break;
578 case NS8390_CABLETRON: /* Cabletron */
579 /* 16 bit card, register map is short forward */
580 ei_status.reset_8390 = &ns8390_no_reset;
581 /* Ctron card won't accept 32bit values read or written to it */
582 ei_status.block_input = &slow_sane_block_input;
583 ei_status.block_output = &slow_sane_block_output;
584 ei_status.get_8390_hdr = &slow_sane_get_8390_hdr;
585 ei_status.reg_offset = fwrd2_offsets;
586 break;
587 case NS8390_FARALLON:
588 case NS8390_APPLE: /* Apple/Asante/Farallon */
589 /* 16 bit card, register map is reversed */
590 ei_status.reset_8390 = &ns8390_no_reset;
591 ei_status.block_input = &slow_sane_block_input;
592 ei_status.block_output = &slow_sane_block_output;
593 ei_status.get_8390_hdr = &slow_sane_get_8390_hdr;
594 ei_status.reg_offset = back4_offsets;
595 break;
596 case NS8390_ASANTE:
597 /* 16 bit card, register map is reversed */
598 ei_status.reset_8390 = &ns8390_no_reset;
599 ei_status.block_input = &sane_block_input;
600 ei_status.block_output = &sane_block_output;
601 ei_status.get_8390_hdr = &sane_get_8390_hdr;
602 ei_status.reg_offset = back4_offsets;
603 break;
604 case NS8390_INTERLAN: /* Interlan */
605 /* 16 bit card, map is forward */
606 ei_status.reset_8390 = &interlan_reset;
607 ei_status.block_input = &sane_block_input;
608 ei_status.block_output = &sane_block_output;
609 ei_status.get_8390_hdr = &sane_get_8390_hdr;
610 ei_status.reg_offset = back4_offsets;
611 break;
612 #if 0 /* i think this suffered code rot. my kinetics card has much
613 * different settings. -- CSA [22-May-1999] */
614 case NS8390_KINETICS: /* Kinetics */
615 /* 8bit card, map is forward */
616 ei_status.reset_8390 = &ns8390_no_reset;
617 ei_status.block_input = &sane_block_input;
618 ei_status.block_output = &sane_block_output;
619 ei_status.get_8390_hdr = &sane_get_8390_hdr;
620 ei_status.reg_offset = back4_offsets;
621 break;
622 #endif
623 default:
624 panic("Detected a card I can't drive - whoops\n");
625 }
626 dev->open = &ns8390_open;
627 dev->stop = &ns8390_close_card;
628
629 NS8390_init(dev, 0);
630
631 return 0;
632 }
633
634 static int ns8390_open(struct net_device *dev)
635 {
636 int ret;
637
638 ei_open(dev);
639
640 /* At least on my card (a Focus Enhancements PDS card) I start */
641 /* getting interrupts right away, so the driver needs to be */
642 /* completely initialized before enabling the interrupt. */
643 /* - funaho@jurai.org (1999-05-17) */
644
645 /* Non-slow interrupt, works around issues with the SONIC driver */
646 ret = request_irq(dev->irq, ei_interrupt, 0, dev->name, dev);
647 if (ret) {
648 printk ("%s: unable to get IRQ %d.\n", dev->name, dev->irq);
649 return ret;
650 }
651 return 0;
652 }
653
654 static void ns8390_no_reset(struct net_device *dev)
655 {
656 if (ei_debug > 1)
657 printk("Need to reset the NS8390 t=%lu...", jiffies);
658 ei_status.txing = 0;
659 if (ei_debug > 1) printk("reset not supported\n");
660 }
661
662 static int ns8390_close_card(struct net_device *dev)
663 {
664 if (ei_debug > 1)
665 printk("%s: Shutting down ethercard.\n", dev->name);
666 free_irq(dev->irq, dev);
667 ei_close(dev);
668 return 0;
669 }
670
671 /*
672 * Interlan Specific Code Starts Here
673 */
674
675 static void interlan_reset(struct net_device *dev)
676 {
677 unsigned char *target=nubus_slot_addr(IRQ2SLOT(dev->irq));
678 if (ei_debug > 1)
679 printk("Need to reset the NS8390 t=%lu...", jiffies);
680 ei_status.txing = 0;
681 /* This write resets the card */
682 target[0xC0000]=0;
683 if (ei_debug > 1) printk("reset complete\n");
684 return;
685 }
686
687 /*
688 * Daynaport code (some is used by other drivers)
689 */
690
691
692 /* Grab the 8390 specific header. Similar to the block_input routine, but
693 we don't need to be concerned with ring wrap as the header will be at
694 the start of a page, so we optimize accordingly. */
695
696
697 /* Block input and output are easy on shared memory ethercards, and trivial
698 on the Daynaport card where there is no choice of how to do it.
699 The only complications are that the ring buffer wraps.
700 */
701
702 static void dayna_memcpy_fromcard(struct net_device *dev, void *to, int from, int count)
703 {
704 volatile unsigned short *ptr;
705 unsigned short *target=to;
706 from<<=1; /* word, skip overhead */
707 ptr=(unsigned short *)(dev->mem_start+from);
708 /*
709 * Leading byte?
710 */
711 if (from&2) {
712 *((char *)target)++ = *(((char *)ptr++)-1);
713 count--;
714 }
715 while(count>=2)
716 {
717 *target++=*ptr++; /* Copy and */
718 ptr++; /* skip cruft */
719 count-=2;
720 }
721 /*
722 * Trailing byte ?
723 */
724 if(count)
725 {
726 /* Big endian */
727 unsigned short v=*ptr;
728 *((char *)target)=v>>8;
729 }
730 }
731
732 static void dayna_memcpy_tocard(struct net_device *dev, int to, const void *from, int count)
733 {
734 volatile unsigned short *ptr;
735 const unsigned short *src=from;
736 to<<=1; /* word, skip overhead */
737 ptr=(unsigned short *)(dev->mem_start+to);
738 /*
739 * Leading byte?
740 */
741 if (to&2) { /* avoid a byte write (stomps on other data) */
742 ptr[-1] = (ptr[-1]&0xFF00)|*((unsigned char *)src)++;
743 ptr++;
744 count--;
745 }
746 while(count>=2)
747 {
748 *ptr++=*src++; /* Copy and */
749 ptr++; /* skip cruft */
750 count-=2;
751 }
752 /*
753 * Trailing byte ?
754 */
755 if(count)
756 {
757 /* Big endian */
758 unsigned short v=*src;
759 /* card doesn't like byte writes */
760 *ptr=(*ptr&0x00FF)|(v&0xFF00);
761 }
762 }
763
764 static void dayna_get_8390_hdr(struct net_device *dev, struct e8390_pkt_hdr *hdr, int ring_page)
765 {
766 unsigned long hdr_start = (ring_page - WD_START_PG)<<8;
767 dayna_memcpy_fromcard(dev, (void *)hdr, hdr_start, 4);
768 /* Register endianism - fix here rather than 8390.c */
769 hdr->count=(hdr->count&0xFF)<<8|(hdr->count>>8);
770 }
771
772 static void dayna_block_input(struct net_device *dev, int count, struct sk_buff *skb, int ring_offset)
773 {
774 unsigned long xfer_base = ring_offset - (WD_START_PG<<8);
775 unsigned long xfer_start = xfer_base+dev->mem_start;
776
777 /*
778 * Note the offset maths is done in card memory space which
779 * is word per long onto our space.
780 */
781
782 if (xfer_start + count > dev->rmem_end)
783 {
784 /* We must wrap the input move. */
785 int semi_count = dev->rmem_end - xfer_start;
786 dayna_memcpy_fromcard(dev, skb->data, xfer_base, semi_count);
787 count -= semi_count;
788 dayna_memcpy_fromcard(dev, skb->data + semi_count,
789 dev->rmem_start - dev->mem_start, count);
790 }
791 else
792 {
793 dayna_memcpy_fromcard(dev, skb->data, xfer_base, count);
794 }
795 }
796
797 static void dayna_block_output(struct net_device *dev, int count, const unsigned char *buf,
798 int start_page)
799 {
800 long shmem = (start_page - WD_START_PG)<<8;
801
802 dayna_memcpy_tocard(dev, shmem, buf, count);
803 }
804
805 /*
806 * Cards with full width memory
807 */
808
809
810 static void sane_get_8390_hdr(struct net_device *dev, struct e8390_pkt_hdr *hdr, int ring_page)
811 {
812 unsigned long hdr_start = (ring_page - WD_START_PG)<<8;
813 memcpy((void *)hdr, (char *)dev->mem_start+hdr_start, 4);
814 /* Register endianism - fix here rather than 8390.c */
815 hdr->count=(hdr->count&0xFF)<<8|(hdr->count>>8);
816 }
817
818 static void sane_block_input(struct net_device *dev, int count, struct sk_buff *skb, int ring_offset)
819 {
820 unsigned long xfer_base = ring_offset - (WD_START_PG<<8);
821 unsigned long xfer_start = xfer_base+dev->mem_start;
822
823 if (xfer_start + count > dev->rmem_end)
824 {
825 /* We must wrap the input move. */
826 int semi_count = dev->rmem_end - xfer_start;
827 memcpy(skb->data, (char *)dev->mem_start+xfer_base, semi_count);
828 count -= semi_count;
829 memcpy(skb->data + semi_count,
830 (char *)dev->rmem_start, count);
831 }
832 else
833 {
834 memcpy(skb->data, (char *)dev->mem_start+xfer_base, count);
835 }
836 }
837
838
839 static void sane_block_output(struct net_device *dev, int count, const unsigned char *buf,
840 int start_page)
841 {
842 long shmem = (start_page - WD_START_PG)<<8;
843
844 memcpy((char *)dev->mem_start+shmem, buf, count);
845 }
846
847 static void word_memcpy_tocard(void *tp, const void *fp, int count)
848 {
849 volatile unsigned short *to = tp;
850 const unsigned short *from = fp;
851
852 count++;
853 count/=2;
854
855 while(count--)
856 *to++=*from++;
857 }
858
859 static void word_memcpy_fromcard(void *tp, const void *fp, int count)
860 {
861 unsigned short *to = tp;
862 const volatile unsigned short *from = fp;
863
864 count++;
865 count/=2;
866
867 while(count--)
868 *to++=*from++;
869 }
870
871 static void slow_sane_get_8390_hdr(struct net_device *dev, struct e8390_pkt_hdr *hdr, int ring_page)
872 {
873 unsigned long hdr_start = (ring_page - WD_START_PG)<<8;
874 word_memcpy_fromcard((void *)hdr, (char *)dev->mem_start+hdr_start, 4);
875 /* Register endianism - fix here rather than 8390.c */
876 hdr->count=(hdr->count&0xFF)<<8|(hdr->count>>8);
877 }
878
879 static void slow_sane_block_input(struct net_device *dev, int count, struct sk_buff *skb, int ring_offset)
880 {
881 unsigned long xfer_base = ring_offset - (WD_START_PG<<8);
882 unsigned long xfer_start = xfer_base+dev->mem_start;
883
884 if (xfer_start + count > dev->rmem_end)
885 {
886 /* We must wrap the input move. */
887 int semi_count = dev->rmem_end - xfer_start;
888 word_memcpy_fromcard(skb->data, (char *)dev->mem_start+xfer_base, semi_count);
889 count -= semi_count;
890 word_memcpy_fromcard(skb->data + semi_count,
891 (char *)dev->rmem_start, count);
892 }
893 else
894 {
895 word_memcpy_fromcard(skb->data, (char *)dev->mem_start+xfer_base, count);
896 }
897 }
898
899 static void slow_sane_block_output(struct net_device *dev, int count, const unsigned char *buf,
900 int start_page)
901 {
902 long shmem = (start_page - WD_START_PG)<<8;
903
904 word_memcpy_tocard((char *)dev->mem_start+shmem, buf, count);
905 #if 0
906 long shmem = (start_page - WD_START_PG)<<8;
907 volatile unsigned short *to=(unsigned short *)(dev->mem_start+shmem);
908 volatile int p;
909 unsigned short *bp=(unsigned short *)buf;
910
911 count=(count+1)/2;
912
913 while(count--)
914 {
915 *to++=*bp++;
916 for(p=0;p<10;p++)
917 p++;
918 }
919 #endif
920 }
921
922 /*
923 * Local variables:
924 * compile-command: "gcc -D__KERNEL__ -I/usr/src/linux/net/inet -Wall -Wstrict-prototypes -O6 -m486 -c daynaport.c"
925 * version-control: t
926 * c-basic-offset: 4
927 * tab-width: 4
928 * kept-new-versions: 5
929 * End:
930 */
931