6 * Debugging Andreas Ehliar, Michael Schmitz
9 * (C) 1996 by Thomas Bogendoerfer (tsbogend@bigbug.franken.de)
11 * This driver is based on work from Andreas Busse, but most of
12 * the code is rewritten.
14 * (C) 1995 by Andreas Busse (andy@waldorf-gmbh.de)
16 * A driver for the Mac onboard Sonic ethernet chip.
18 * 98/12/21 MSch: judged from tests on Q800, it's basically working,
19 * but eating up both receive and transmit resources
20 * and duplicating packets. Needs more testing.
22 * 99/01/03 MSch: upgraded to version 0.92 of the core driver, fixed.
25 #include <linux/kernel.h>
26 #include <linux/sched.h>
27 #include <linux/types.h>
28 #include <linux/ctype.h>
29 #include <linux/fcntl.h>
30 #include <linux/interrupt.h>
31 #include <linux/ptrace.h>
32 #include <linux/init.h>
33 #include <linux/ioport.h>
35 #include <linux/malloc.h>
36 #include <linux/string.h>
37 #include <linux/delay.h>
38 #include <linux/nubus.h>
39 #include <asm/bootinfo.h>
40 #include <asm/system.h>
41 #include <asm/bitops.h>
42 #include <asm/pgtable.h>
43 #include <asm/segment.h>
46 #include <asm/macintosh.h>
48 #include <linux/errno.h>
50 #include <linux/netdevice.h>
51 #include <linux/etherdevice.h>
52 #include <linux/skbuff.h>
54 #include <config/macsonic.h>
56 #define SREGS_PAD(n) u16 n;
60 extern int mac_onboard_sonic_probe(void);
62 static int setup_debug
= -1;
63 static int setup_offset
= -1;
64 static int setup_shift
= -1;
67 * This seems to be the right default for the Q800
70 static int reg_offset
= 0;
71 static int reg_shift
= 0;
74 * Macros to access SONIC registers
77 #define MAC_SONIC_REGISTERS 0x50F0A000
78 #define MAC_SONIC_PROM_BASE 0x50f08000
79 #define MAC_SONIC_IRQ 9 /* Nubus 9 */
82 * FIXME: We may need to invert the byte ordering. These should
83 * be ok for other aspects as they are uncached spaces.
84 * The original macros from jazzsonic.c works for me
85 * on my LC 630, YMMV /Andreas Ehliar
89 #define SONIC_READ(reg) \
90 *((volatile unsigned int *)base_addr+((reg)<<2)+2)
92 #define SONIC_WRITE(reg,val) \
93 *((volatile unsigned int *)base_addr+((reg)<<2)+2) = val
95 #define SONIC_READ(reg) \
96 *((volatile unsigned int *)base_addr+reg)
98 #define SONIC_WRITE(reg,val) \
99 *((volatile unsigned int *)base_addr+reg) = val
102 #define SONIC_READ_PROM(addr) \
103 *((volatile unsigned char *)prom_addr+addr)
105 * Function : mac_sonic_setup(char *str, int *ints)
107 * Purpose : booter command line initialization of the overrides array,
109 * Inputs : str - unused, ints - array of integer parameters with ints[0]
110 * equal to the number of ints.
112 * Currently unused in the new driver; need to add settable parameters to the
117 void mac_sonic_setup(char *str
, int *ints
) {
118 /* Format of macsonic parameter is:
119 * macsonic=<debug>,<offset>,<shift>
120 * Negative values mean don't change.
123 /* Grmbl... the standard parameter parsing can't handle negative numbers
124 * :-( So let's do it ourselves!
127 int i
= ints
[0]+1, fact
;
129 while( str
&& (isdigit(*str
) || *str
== '-') && i
<= 10) {
134 ints
[i
++] = simple_strtoul( str
, NULL
, 0 ) * fact
;
135 if ((str
= strchr( str
, ',' )) != NULL
)
141 printk( "mac_sonic_setup: no arguments!\n" );
147 if (ints
[1] >= 0 && ints
[1] <= 8)
148 setup_debug
= ints
[1];
149 else if (ints
[1] > 16)
150 printk( "mac_sonic_setup: invalid debug level %d !\n", ints
[1] );
154 if (ints
[2] >= 0 && ints
[2] <= 16)
155 setup_offset
= ints
[2];
156 else if (ints
[2] > 16)
157 printk( "mac_sonic_setup: invalid offset %d !\n", ints
[2] );
161 if (ints
[3] >= 0 && ints
[3] <= 16)
162 setup_shift
= ints
[3];
163 else if (ints
[3] > 16)
164 printk( "mac_sonic_setup: invalid shift %d !\n", ints
[3] );
168 static int sonic_debug
= 0;
171 * For reversing the PROM address
174 static unsigned char nibbletab
[] = {0, 8, 4, 12, 2, 10, 6, 14,
175 1, 9, 5, 13, 3, 11, 7, 15};
177 int __init
mac_onboard_sonic_probe(void)
179 struct net_device
*dev
;
180 unsigned int silicon_revision
;
182 struct sonic_local
*lp
;
184 int base_addr
= MAC_SONIC_REGISTERS
;
185 int prom_addr
= MAC_SONIC_PROM_BASE
;
191 if(++one
!=1) /* Only one is allowed */
194 printk(KERN_INFO
"Checking for internal Macintosh ethernet (SONIC).. ");
196 if (macintosh_config
->ether_type
!= MAC_ETHER_SONIC
)
204 if (setup_debug
>= 0)
205 sonic_debug
= setup_debug
;
208 * This may depend on the actual Mac model ... works for me.
211 (setup_offset
>= 0) ? setup_offset
: 0;
213 (setup_shift
>= 0) ? setup_shift
: 0;
216 * get the Silicon Revision ID. If this is one of the known
217 * one assume that we found a SONIC ethernet controller at
218 * the expected location.
219 * (This is not implemented in the Macintosh driver yet; need
220 * to collect values from various sources. Mine is 0x4 ...)
223 silicon_revision
= SONIC_READ(SONIC_SR
);
225 printk("SONIC Silicon Revision = 0x%04x\n", silicon_revision
);
228 * We need to allocate sonic_local later on, making sure it's
229 * aligned on a 64k boundary. So, no space for dev->priv allocated
232 dev
= init_etherdev(0,0);
237 printk("%s: %s found at 0x%08x, ",
238 dev
->name
, "SONIC ethernet", base_addr
);
241 printk("using offset %d shift %d,", reg_offset
, reg_shift
);
243 /* Fill in the 'dev' fields. */
244 dev
->base_addr
= base_addr
;
245 dev
->irq
= MAC_SONIC_IRQ
;
248 * Put the sonic into software reset, then
249 * retrieve and print the ethernet address.
252 SONIC_WRITE(SONIC_CMD
, SONIC_CR_RST
);
255 * We can't trust MacOS to initialise things it seems.
259 printk("SONIC_DCR was %X\n",SONIC_READ(SONIC_DCR
));
261 SONIC_WRITE(SONIC_DCR
,
262 SONIC_DCR_RFT1
| SONIC_DCR_TFT0
| SONIC_DCR_EXBUS
| SONIC_DCR_DW
);
265 * We don't want floating spare IRQ's around, not on
266 * level triggered systems!
267 * Strange though - writing to the ISR only clears currently
268 * pending IRQs, but doesn't disable them... Does this make
269 * a difference?? Seems it does ...
272 SONIC_WRITE(SONIC_ISR
,0x7fff);
273 SONIC_WRITE(SONIC_IMR
,0);
275 SONIC_WRITE(SONIC_ISR
, SONIC_IMR_DEFAULT
);
278 /* This is how it is done in jazzsonic.c
279 * It doesn't seem to work here though.
281 if (sonic_debug
> 2) {
282 printk("Retreiving CAM entry 0. This should be the HW address.\n");
284 SONIC_WRITE(SONIC_CEP
, 0);
285 for (i
= 0; i
< 3; i
++)
287 val
= SONIC_READ(SONIC_CAP0
- i
);
288 dev
->dev_addr
[i
* 2] = val
;
289 dev
->dev_addr
[i
* 2 + 1] = val
>> 8;
292 printk("HW Address from CAM 0: ");
293 for (i
= 0; i
< 6; i
++)
295 printk("%2.2x", dev
->dev_addr
[i
]);
301 printk("Retreiving CAM entry 15. Another candidate...\n");
304 * MacOS seems to use CAM entry 15 ...
306 SONIC_WRITE(SONIC_CEP
, 15);
307 for (i
= 0; i
< 3; i
++)
309 val
= SONIC_READ(SONIC_CAP0
- i
);
310 dev
->dev_addr
[i
* 2] = val
;
311 dev
->dev_addr
[i
* 2 + 1] = val
>> 8;
314 printk("HW Address from CAM 15: ");
315 for (i
= 0; i
< 6; i
++)
317 printk("%2.2x", dev
->dev_addr
[i
]);
325 * if we can read the PROM, we're safe :-)
328 printk("Retreiving HW address from the PROM: ");
331 dev
->dev_addr
[i
]=SONIC_READ_PROM(i
);
333 if (sonic_debug
> 1) {
334 for (i
= 0; i
< 6; i
++)
336 printk("%2.2x", dev
->dev_addr
[i
]);
343 * If its not one of these we have
344 * screwed up on this Mac model
347 if (memcmp(dev
->dev_addr
, "\x08\x00\x07", 3) &&
348 memcmp(dev
->dev_addr
, "\x00\xA0\x40", 3) &&
349 memcmp(dev
->dev_addr
, "\x00\x05\x02", 3))
355 val
= SONIC_READ_PROM(i
);
356 dev
->dev_addr
[i
]=(nibbletab
[val
& 0xf] << 4) |
357 nibbletab
[(val
>> 4) &0xf];
359 if (sonic_debug
> 1) {
360 printk("Trying bit reversed: ");
361 for (i
= 0; i
< 6; i
++)
363 printk("%2.2x", dev
->dev_addr
[i
]);
369 if (memcmp(dev
->dev_addr
, "\x08\x00\x07", 3) &&
370 memcmp(dev
->dev_addr
, "\x00\xA0\x40", 3) &&
371 memcmp(dev
->dev_addr
, "\x00\x05\x02", 3))
374 * Still nonsense ... messed up someplace!
376 printk("ERROR (INVALID MAC)\n");
382 for (i
= 0; i
< 6; i
++)
384 printk("%2.2x", dev
->dev_addr
[i
]);
389 printk(" IRQ %d\n", MAC_SONIC_IRQ
);
391 /* Initialize the device structure. */
392 if (dev
->priv
== NULL
)
394 if (sonic_debug
> 2) {
395 printk("Allocating memory for dev->priv aka lp\n");
396 printk("Memory to allocate: %d\n",sizeof(*lp
));
399 * the memory be located in the same 64kb segment
405 lp
= (struct sonic_local
*) kmalloc(sizeof(*lp
), GFP_KERNEL
);
406 if ((unsigned long) lp
>> 16 != ((unsigned long) lp
+ sizeof(*lp
)) >> 16)
408 /* FIXME, free the memory later */
413 while (lp
== NULL
&& i
++ < 20);
417 printk("%s: couldn't allocate memory for descriptors\n",
422 if (sonic_debug
> 2) {
423 printk("Memory allocated after %d tries\n",i
);
426 /* XXX sonic_local has the TDA, RRA, RDA, don't cache */
427 kernel_set_cachemode((u32
)lp
, 8192, IOMAP_NOCACHE_SER
);
428 memset(lp
, 0, sizeof(struct sonic_local
));
430 lp
->cda_laddr
= (u32
)lp
;
431 if (sonic_debug
> 2) {
432 printk("memory allocated for sonic at 0x%x\n",lp
);
434 lp
->tda_laddr
= lp
->cda_laddr
+ sizeof(lp
->cda
);
435 lp
->rra_laddr
= lp
->tda_laddr
+ sizeof(lp
->tda
);
436 lp
->rda_laddr
= lp
->rra_laddr
+ sizeof(lp
->rra
);
438 /* allocate receive buffer area */
439 /* FIXME, maybe we should use skbs */
440 if ((lp
->rba
= (char *) kmalloc(SONIC_NUM_RRS
* SONIC_RBSIZE
, GFP_KERNEL
)) == NULL
)
442 printk("%s: couldn't allocate receive buffers\n", dev
->name
);
445 /* XXX RBA written by Sonic, not cached either */
446 kernel_set_cachemode((u32
)lp
->rba
, 6*8192, IOMAP_NOCACHE_SER
);
447 lp
->rba_laddr
= (u32
)lp
->rba
;
449 dev
->priv
= (struct sonic_local
*) lp
;
451 lp
= (struct sonic_local
*) dev
->priv
;
452 dev
->open
= sonic_open
;
453 dev
->stop
= sonic_close
;
454 dev
->hard_start_xmit
= sonic_send_packet
;
455 dev
->get_stats
= sonic_get_stats
;
456 dev
->set_multicast_list
= &sonic_multicast_list
;
458 /* Fill in the fields of the device structure with ethernet values. */
464 * SONIC uses a nubus IRQ
467 #define sonic_request_irq(irq, vec, flags, name, dev) \
468 nubus_request_irq(irq, dev, vec)
469 #define sonic_free_irq(irq,id) nubus_free_irq(irq)
472 * No funnies on memory mapping.
475 #define sonic_chiptomem(x) (x)
478 * No VDMA on a Macintosh. So we need request no such facility.
481 #define vdma_alloc(x,y) ((u32)(x))
483 #define PHYSADDR(x) (x)