2e64b0fc3e5f444e5b3295b2b4c2944cabc640cc
[openwrt/svn-archive/archive.git] / openwrt / target / linux / brcm-2.4 / patches / 001-bcm47xx.patch
1 diff -Nur linux-2.4.32/arch/mips/bcm947xx/cfe_env.c linux-2.4.32-brcm/arch/mips/bcm947xx/cfe_env.c
2 --- linux-2.4.32/arch/mips/bcm947xx/cfe_env.c 1970-01-01 01:00:00.000000000 +0100
3 +++ linux-2.4.32-brcm/arch/mips/bcm947xx/cfe_env.c 2005-12-19 01:56:35.104829500 +0100
4 @@ -0,0 +1,234 @@
5 +/*
6 + * NVRAM variable manipulation (Linux kernel half)
7 + *
8 + * Copyright 2001-2003, Broadcom Corporation
9 + * All Rights Reserved.
10 + *
11 + * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY
12 + * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM
13 + * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS
14 + * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE.
15 + *
16 + * $Id$
17 + */
18 +
19 +#include <linux/config.h>
20 +#include <linux/init.h>
21 +#include <linux/module.h>
22 +#include <linux/kernel.h>
23 +#include <linux/string.h>
24 +#include <asm/io.h>
25 +#include <asm/uaccess.h>
26 +
27 +#include <typedefs.h>
28 +#include <osl.h>
29 +#include <bcmendian.h>
30 +#include <bcmutils.h>
31 +
32 +#define NVRAM_SIZE (0x1ff0)
33 +static char _nvdata[NVRAM_SIZE] __initdata;
34 +static char _valuestr[256] __initdata;
35 +
36 +/*
37 + * TLV types. These codes are used in the "type-length-value"
38 + * encoding of the items stored in the NVRAM device (flash or EEPROM)
39 + *
40 + * The layout of the flash/nvram is as follows:
41 + *
42 + * <type> <length> <data ...> <type> <length> <data ...> <type_end>
43 + *
44 + * The type code of "ENV_TLV_TYPE_END" marks the end of the list.
45 + * The "length" field marks the length of the data section, not
46 + * including the type and length fields.
47 + *
48 + * Environment variables are stored as follows:
49 + *
50 + * <type_env> <length> <flags> <name> = <value>
51 + *
52 + * If bit 0 (low bit) is set, the length is an 8-bit value.
53 + * If bit 0 (low bit) is clear, the length is a 16-bit value
54 + *
55 + * Bit 7 set indicates "user" TLVs. In this case, bit 0 still
56 + * indicates the size of the length field.
57 + *
58 + * Flags are from the constants below:
59 + *
60 + */
61 +#define ENV_LENGTH_16BITS 0x00 /* for low bit */
62 +#define ENV_LENGTH_8BITS 0x01
63 +
64 +#define ENV_TYPE_USER 0x80
65 +
66 +#define ENV_CODE_SYS(n,l) (((n)<<1)|(l))
67 +#define ENV_CODE_USER(n,l) ((((n)<<1)|(l)) | ENV_TYPE_USER)
68 +
69 +/*
70 + * The actual TLV types we support
71 + */
72 +
73 +#define ENV_TLV_TYPE_END 0x00
74 +#define ENV_TLV_TYPE_ENV ENV_CODE_SYS(0,ENV_LENGTH_8BITS)
75 +
76 +/*
77 + * Environment variable flags
78 + */
79 +
80 +#define ENV_FLG_NORMAL 0x00 /* normal read/write */
81 +#define ENV_FLG_BUILTIN 0x01 /* builtin - not stored in flash */
82 +#define ENV_FLG_READONLY 0x02 /* read-only - cannot be changed */
83 +
84 +#define ENV_FLG_MASK 0xFF /* mask of attributes we keep */
85 +#define ENV_FLG_ADMIN 0x100 /* lets us internally override permissions */
86 +
87 +
88 +/* *********************************************************************
89 + * _nvram_read(buffer,offset,length)
90 + *
91 + * Read data from the NVRAM device
92 + *
93 + * Input parameters:
94 + * buffer - destination buffer
95 + * offset - offset of data to read
96 + * length - number of bytes to read
97 + *
98 + * Return value:
99 + * number of bytes read, or <0 if error occured
100 + ********************************************************************* */
101 +static int
102 +_nvram_read(unsigned char *nv_buf, unsigned char *buffer, int offset, int length)
103 +{
104 + int i;
105 + if (offset > NVRAM_SIZE)
106 + return -1;
107 +
108 + for ( i = 0; i < length; i++) {
109 + buffer[i] = ((volatile unsigned char*)nv_buf)[offset + i];
110 + }
111 + return length;
112 +}
113 +
114 +
115 +static char*
116 +_strnchr(const char *dest,int c,size_t cnt)
117 +{
118 + while (*dest && (cnt > 0)) {
119 + if (*dest == c) return (char *) dest;
120 + dest++;
121 + cnt--;
122 + }
123 + return NULL;
124 +}
125 +
126 +
127 +
128 +/*
129 + * Core support API: Externally visible.
130 + */
131 +
132 +/*
133 + * Get the value of an NVRAM variable
134 + * @param name name of variable to get
135 + * @return value of variable or NULL if undefined
136 + */
137 +
138 +char*
139 +cfe_env_get(unsigned char *nv_buf, char* name)
140 +{
141 + int size;
142 + unsigned char *buffer;
143 + unsigned char *ptr;
144 + unsigned char *envval;
145 + unsigned int reclen;
146 + unsigned int rectype;
147 + int offset;
148 + int flg;
149 +
150 + size = NVRAM_SIZE;
151 + buffer = &_nvdata[0];
152 +
153 + ptr = buffer;
154 + offset = 0;
155 +
156 + /* Read the record type and length */
157 + if (_nvram_read(nv_buf, ptr,offset,1) != 1) {
158 + goto error;
159 + }
160 +
161 + while ((*ptr != ENV_TLV_TYPE_END) && (size > 1)) {
162 +
163 + /* Adjust pointer for TLV type */
164 + rectype = *(ptr);
165 + offset++;
166 + size--;
167 +
168 + /*
169 + * Read the length. It can be either 1 or 2 bytes
170 + * depending on the code
171 + */
172 + if (rectype & ENV_LENGTH_8BITS) {
173 + /* Read the record type and length - 8 bits */
174 + if (_nvram_read(nv_buf, ptr,offset,1) != 1) {
175 + goto error;
176 + }
177 + reclen = *(ptr);
178 + size--;
179 + offset++;
180 + }
181 + else {
182 + /* Read the record type and length - 16 bits, MSB first */
183 + if (_nvram_read(nv_buf, ptr,offset,2) != 2) {
184 + goto error;
185 + }
186 + reclen = (((unsigned int) *(ptr)) << 8) + (unsigned int) *(ptr+1);
187 + size -= 2;
188 + offset += 2;
189 + }
190 +
191 + if (reclen > size)
192 + break; /* should not happen, bad NVRAM */
193 +
194 + switch (rectype) {
195 + case ENV_TLV_TYPE_ENV:
196 + /* Read the TLV data */
197 + if (_nvram_read(nv_buf, ptr,offset,reclen) != reclen)
198 + goto error;
199 + flg = *ptr++;
200 + envval = (unsigned char *) _strnchr(ptr,'=',(reclen-1));
201 + if (envval) {
202 + *envval++ = '\0';
203 + memcpy(_valuestr,envval,(reclen-1)-(envval-ptr));
204 + _valuestr[(reclen-1)-(envval-ptr)] = '\0';
205 +#if 0
206 + printk(KERN_INFO "NVRAM:%s=%s\n", ptr, _valuestr);
207 +#endif
208 + if(!strcmp(ptr, name)){
209 + return _valuestr;
210 + }
211 + if((strlen(ptr) > 1) && !strcmp(&ptr[1], name))
212 + return _valuestr;
213 + }
214 + break;
215 +
216 + default:
217 + /* Unknown TLV type, skip it. */
218 + break;
219 + }
220 +
221 + /*
222 + * Advance to next TLV
223 + */
224 +
225 + size -= (int)reclen;
226 + offset += reclen;
227 +
228 + /* Read the next record type */
229 + ptr = buffer;
230 + if (_nvram_read(nv_buf, ptr,offset,1) != 1)
231 + goto error;
232 + }
233 +
234 +error:
235 + return NULL;
236 +
237 +}
238 +
239 diff -Nur linux-2.4.32/arch/mips/bcm947xx/compressed/Makefile linux-2.4.32-brcm/arch/mips/bcm947xx/compressed/Makefile
240 --- linux-2.4.32/arch/mips/bcm947xx/compressed/Makefile 1970-01-01 01:00:00.000000000 +0100
241 +++ linux-2.4.32-brcm/arch/mips/bcm947xx/compressed/Makefile 2005-12-16 23:39:10.668819500 +0100
242 @@ -0,0 +1,33 @@
243 +#
244 +# Makefile for Broadcom BCM947XX boards
245 +#
246 +# Copyright 2001-2003, Broadcom Corporation
247 +# All Rights Reserved.
248 +#
249 +# THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY
250 +# KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM
251 +# SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS
252 +# FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE.
253 +#
254 +# $Id: Makefile,v 1.2 2005/04/02 12:12:57 wbx Exp $
255 +#
256 +
257 +OBJCOPY_ARGS = -O binary -R .reginfo -R .note -R .comment -R .mdebug -S
258 +SYSTEM ?= $(TOPDIR)/vmlinux
259 +
260 +all: vmlinuz
261 +
262 +# Don't build dependencies, this may die if $(CC) isn't gcc
263 +dep:
264 +
265 +# Create a gzipped version named vmlinuz for compatibility
266 +vmlinuz: piggy
267 + gzip -c9 $< > $@
268 +
269 +piggy: $(SYSTEM)
270 + $(OBJCOPY) $(OBJCOPY_ARGS) $< $@
271 +
272 +mrproper: clean
273 +
274 +clean:
275 + rm -f vmlinuz piggy
276 diff -Nur linux-2.4.32/arch/mips/bcm947xx/generic/int-handler.S linux-2.4.32-brcm/arch/mips/bcm947xx/generic/int-handler.S
277 --- linux-2.4.32/arch/mips/bcm947xx/generic/int-handler.S 1970-01-01 01:00:00.000000000 +0100
278 +++ linux-2.4.32-brcm/arch/mips/bcm947xx/generic/int-handler.S 2005-12-16 23:39:10.668819500 +0100
279 @@ -0,0 +1,51 @@
280 +/*
281 + * Generic interrupt handler for Broadcom MIPS boards
282 + *
283 + * Copyright 2004, Broadcom Corporation
284 + * All Rights Reserved.
285 + *
286 + * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY
287 + * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM
288 + * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS
289 + * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE.
290 + *
291 + * $Id: int-handler.S,v 1.1 2005/03/16 13:50:00 wbx Exp $
292 + */
293 +
294 +#include <linux/config.h>
295 +
296 +#include <asm/asm.h>
297 +#include <asm/mipsregs.h>
298 +#include <asm/regdef.h>
299 +#include <asm/stackframe.h>
300 +
301 +/*
302 + * MIPS IRQ Source
303 + * -------- ------
304 + * 0 Software (ignored)
305 + * 1 Software (ignored)
306 + * 2 Combined hardware interrupt (hw0)
307 + * 3 Hardware
308 + * 4 Hardware
309 + * 5 Hardware
310 + * 6 Hardware
311 + * 7 R4k timer
312 + */
313 +
314 + .text
315 + .set noreorder
316 + .set noat
317 + .align 5
318 + NESTED(brcmIRQ, PT_SIZE, sp)
319 + SAVE_ALL
320 + CLI
321 + .set at
322 + .set noreorder
323 +
324 + jal brcm_irq_dispatch
325 + move a0, sp
326 +
327 + j ret_from_irq
328 + nop
329 +
330 + END(brcmIRQ)
331 diff -Nur linux-2.4.32/arch/mips/bcm947xx/generic/irq.c linux-2.4.32-brcm/arch/mips/bcm947xx/generic/irq.c
332 --- linux-2.4.32/arch/mips/bcm947xx/generic/irq.c 1970-01-01 01:00:00.000000000 +0100
333 +++ linux-2.4.32-brcm/arch/mips/bcm947xx/generic/irq.c 2005-12-16 23:39:10.668819500 +0100
334 @@ -0,0 +1,130 @@
335 +/*
336 + * Generic interrupt control functions for Broadcom MIPS boards
337 + *
338 + * Copyright 2004, Broadcom Corporation
339 + * All Rights Reserved.
340 + *
341 + * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY
342 + * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM
343 + * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS
344 + * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE.
345 + *
346 + * $Id: irq.c,v 1.1 2005/03/16 13:50:00 wbx Exp $
347 + */
348 +
349 +#include <linux/config.h>
350 +#include <linux/init.h>
351 +#include <linux/kernel.h>
352 +#include <linux/types.h>
353 +#include <linux/interrupt.h>
354 +#include <linux/irq.h>
355 +
356 +#include <asm/irq.h>
357 +#include <asm/mipsregs.h>
358 +#include <asm/gdb-stub.h>
359 +
360 +#define ALLINTS (IE_IRQ0 | IE_IRQ1 | IE_IRQ2 | IE_IRQ3 | IE_IRQ4 | IE_IRQ5)
361 +
362 +extern asmlinkage void brcmIRQ(void);
363 +extern asmlinkage unsigned int do_IRQ(int irq, struct pt_regs *regs);
364 +
365 +void
366 +brcm_irq_dispatch(struct pt_regs *regs)
367 +{
368 + u32 cause;
369 +
370 + cause = read_c0_cause() &
371 + read_c0_status() &
372 + CAUSEF_IP;
373 +
374 +#ifdef CONFIG_KERNPROF
375 + change_c0_status(cause | 1, 1);
376 +#else
377 + clear_c0_status(cause);
378 +#endif
379 +
380 + if (cause & CAUSEF_IP7)
381 + do_IRQ(7, regs);
382 + if (cause & CAUSEF_IP2)
383 + do_IRQ(2, regs);
384 + if (cause & CAUSEF_IP3)
385 + do_IRQ(3, regs);
386 + if (cause & CAUSEF_IP4)
387 + do_IRQ(4, regs);
388 + if (cause & CAUSEF_IP5)
389 + do_IRQ(5, regs);
390 + if (cause & CAUSEF_IP6)
391 + do_IRQ(6, regs);
392 +}
393 +
394 +static void
395 +enable_brcm_irq(unsigned int irq)
396 +{
397 + if (irq < 8)
398 + set_c0_status(1 << (irq + 8));
399 + else
400 + set_c0_status(IE_IRQ0);
401 +}
402 +
403 +static void
404 +disable_brcm_irq(unsigned int irq)
405 +{
406 + if (irq < 8)
407 + clear_c0_status(1 << (irq + 8));
408 + else
409 + clear_c0_status(IE_IRQ0);
410 +}
411 +
412 +static void
413 +ack_brcm_irq(unsigned int irq)
414 +{
415 + /* Already done in brcm_irq_dispatch */
416 +}
417 +
418 +static unsigned int
419 +startup_brcm_irq(unsigned int irq)
420 +{
421 + enable_brcm_irq(irq);
422 +
423 + return 0; /* never anything pending */
424 +}
425 +
426 +static void
427 +end_brcm_irq(unsigned int irq)
428 +{
429 + if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS)))
430 + enable_brcm_irq(irq);
431 +}
432 +
433 +static struct hw_interrupt_type brcm_irq_type = {
434 + typename: "MIPS",
435 + startup: startup_brcm_irq,
436 + shutdown: disable_brcm_irq,
437 + enable: enable_brcm_irq,
438 + disable: disable_brcm_irq,
439 + ack: ack_brcm_irq,
440 + end: end_brcm_irq,
441 + NULL
442 +};
443 +
444 +void __init
445 +init_IRQ(void)
446 +{
447 + int i;
448 +
449 + for (i = 0; i < NR_IRQS; i++) {
450 + irq_desc[i].status = IRQ_DISABLED;
451 + irq_desc[i].action = 0;
452 + irq_desc[i].depth = 1;
453 + irq_desc[i].handler = &brcm_irq_type;
454 + }
455 +
456 + set_except_vector(0, brcmIRQ);
457 + change_c0_status(ST0_IM, ALLINTS);
458 +
459 +#ifdef CONFIG_REMOTE_DEBUG
460 + printk("Breaking into debugger...\n");
461 + set_debug_traps();
462 + breakpoint();
463 +#endif
464 +}
465 diff -Nur linux-2.4.32/arch/mips/bcm947xx/generic/Makefile linux-2.4.32-brcm/arch/mips/bcm947xx/generic/Makefile
466 --- linux-2.4.32/arch/mips/bcm947xx/generic/Makefile 1970-01-01 01:00:00.000000000 +0100
467 +++ linux-2.4.32-brcm/arch/mips/bcm947xx/generic/Makefile 2005-12-16 23:39:10.668819500 +0100
468 @@ -0,0 +1,15 @@
469 +#
470 +# Makefile for the BCM947xx specific kernel interface routines
471 +# under Linux.
472 +#
473 +
474 +.S.s:
475 + $(CPP) $(AFLAGS) $< -o $*.s
476 +.S.o:
477 + $(CC) $(AFLAGS) -c $< -o $*.o
478 +
479 +O_TARGET := brcm.o
480 +
481 +obj-y := int-handler.o irq.o
482 +
483 +include $(TOPDIR)/Rules.make
484 diff -Nur linux-2.4.32/arch/mips/bcm947xx/gpio.c linux-2.4.32-brcm/arch/mips/bcm947xx/gpio.c
485 --- linux-2.4.32/arch/mips/bcm947xx/gpio.c 1970-01-01 01:00:00.000000000 +0100
486 +++ linux-2.4.32-brcm/arch/mips/bcm947xx/gpio.c 2005-12-16 23:39:10.668819500 +0100
487 @@ -0,0 +1,158 @@
488 +/*
489 + * GPIO char driver
490 + *
491 + * Copyright 2005, Broadcom Corporation
492 + * All Rights Reserved.
493 + *
494 + * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY
495 + * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM
496 + * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS
497 + * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE.
498 + *
499 + * $Id$
500 + */
501 +
502 +#include <linux/module.h>
503 +#include <linux/init.h>
504 +#include <linux/fs.h>
505 +#include <linux/miscdevice.h>
506 +#include <asm/uaccess.h>
507 +
508 +#include <typedefs.h>
509 +#include <bcmutils.h>
510 +#include <sbutils.h>
511 +#include <bcmdevs.h>
512 +
513 +static sb_t *gpio_sbh;
514 +static int gpio_major;
515 +static devfs_handle_t gpio_dir;
516 +static struct {
517 + char *name;
518 + devfs_handle_t handle;
519 +} gpio_file[] = {
520 + { "in", NULL },
521 + { "out", NULL },
522 + { "outen", NULL },
523 + { "control", NULL }
524 +};
525 +
526 +static int
527 +gpio_open(struct inode *inode, struct file * file)
528 +{
529 + if (MINOR(inode->i_rdev) > ARRAYSIZE(gpio_file))
530 + return -ENODEV;
531 +
532 + MOD_INC_USE_COUNT;
533 + return 0;
534 +}
535 +
536 +static int
537 +gpio_release(struct inode *inode, struct file * file)
538 +{
539 + MOD_DEC_USE_COUNT;
540 + return 0;
541 +}
542 +
543 +static ssize_t
544 +gpio_read(struct file *file, char *buf, size_t count, loff_t *ppos)
545 +{
546 + u32 val;
547 +
548 + switch (MINOR(file->f_dentry->d_inode->i_rdev)) {
549 + case 0:
550 + val = sb_gpioin(gpio_sbh);
551 + break;
552 + case 1:
553 + val = sb_gpioout(gpio_sbh, 0, 0, GPIO_DRV_PRIORITY);
554 + break;
555 + case 2:
556 + val = sb_gpioouten(gpio_sbh, 0, 0, GPIO_DRV_PRIORITY);
557 + break;
558 + case 3:
559 + val = sb_gpiocontrol(gpio_sbh, 0, 0, GPIO_DRV_PRIORITY);
560 + break;
561 + default:
562 + return -ENODEV;
563 + }
564 +
565 + if (put_user(val, (u32 *) buf))
566 + return -EFAULT;
567 +
568 + return sizeof(val);
569 +}
570 +
571 +static ssize_t
572 +gpio_write(struct file *file, const char *buf, size_t count, loff_t *ppos)
573 +{
574 + u32 val;
575 +
576 + if (get_user(val, (u32 *) buf))
577 + return -EFAULT;
578 +
579 + switch (MINOR(file->f_dentry->d_inode->i_rdev)) {
580 + case 0:
581 + return -EACCES;
582 + case 1:
583 + sb_gpioout(gpio_sbh, ~0, val, GPIO_DRV_PRIORITY);
584 + break;
585 + case 2:
586 + sb_gpioouten(gpio_sbh, ~0, val, GPIO_DRV_PRIORITY);
587 + break;
588 + case 3:
589 + sb_gpiocontrol(gpio_sbh, ~0, val, GPIO_DRV_PRIORITY);
590 + break;
591 + default:
592 + return -ENODEV;
593 + }
594 +
595 + return sizeof(val);
596 +}
597 +
598 +static struct file_operations gpio_fops = {
599 + owner: THIS_MODULE,
600 + open: gpio_open,
601 + release: gpio_release,
602 + read: gpio_read,
603 + write: gpio_write,
604 +};
605 +
606 +static int __init
607 +gpio_init(void)
608 +{
609 + int i;
610 +
611 + if (!(gpio_sbh = sb_kattach()))
612 + return -ENODEV;
613 +
614 + sb_gpiosetcore(gpio_sbh);
615 +
616 + if ((gpio_major = devfs_register_chrdev(0, "gpio", &gpio_fops)) < 0)
617 + return gpio_major;
618 +
619 + gpio_dir = devfs_mk_dir(NULL, "gpio", NULL);
620 +
621 + for (i = 0; i < ARRAYSIZE(gpio_file); i++) {
622 + gpio_file[i].handle = devfs_register(gpio_dir,
623 + gpio_file[i].name,
624 + DEVFS_FL_DEFAULT, gpio_major, i,
625 + S_IFCHR | S_IRUGO | S_IWUGO,
626 + &gpio_fops, NULL);
627 + }
628 +
629 + return 0;
630 +}
631 +
632 +static void __exit
633 +gpio_exit(void)
634 +{
635 + int i;
636 +
637 + for (i = 0; i < ARRAYSIZE(gpio_file); i++)
638 + devfs_unregister(gpio_file[i].handle);
639 + devfs_unregister(gpio_dir);
640 + devfs_unregister_chrdev(gpio_major, "gpio");
641 + sb_detach(gpio_sbh);
642 +}
643 +
644 +module_init(gpio_init);
645 +module_exit(gpio_exit);
646 diff -Nur linux-2.4.32/arch/mips/bcm947xx/include/bcmdevs.h linux-2.4.32-brcm/arch/mips/bcm947xx/include/bcmdevs.h
647 --- linux-2.4.32/arch/mips/bcm947xx/include/bcmdevs.h 1970-01-01 01:00:00.000000000 +0100
648 +++ linux-2.4.32-brcm/arch/mips/bcm947xx/include/bcmdevs.h 2005-12-16 23:39:10.672819750 +0100
649 @@ -0,0 +1,391 @@
650 +/*
651 + * Broadcom device-specific manifest constants.
652 + *
653 + * Copyright 2005, Broadcom Corporation
654 + * All Rights Reserved.
655 + *
656 + * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY
657 + * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM
658 + * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS
659 + * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE.
660 + * $Id$
661 + */
662 +
663 +#ifndef _BCMDEVS_H
664 +#define _BCMDEVS_H
665 +
666 +
667 +/* Known PCI vendor Id's */
668 +#define VENDOR_EPIGRAM 0xfeda
669 +#define VENDOR_BROADCOM 0x14e4
670 +#define VENDOR_3COM 0x10b7
671 +#define VENDOR_NETGEAR 0x1385
672 +#define VENDOR_DIAMOND 0x1092
673 +#define VENDOR_DELL 0x1028
674 +#define VENDOR_HP 0x0e11
675 +#define VENDOR_APPLE 0x106b
676 +
677 +/* PCI Device Id's */
678 +#define BCM4210_DEVICE_ID 0x1072 /* never used */
679 +#define BCM4211_DEVICE_ID 0x4211
680 +#define BCM4230_DEVICE_ID 0x1086 /* never used */
681 +#define BCM4231_DEVICE_ID 0x4231
682 +
683 +#define BCM4410_DEVICE_ID 0x4410 /* bcm44xx family pci iline */
684 +#define BCM4430_DEVICE_ID 0x4430 /* bcm44xx family cardbus iline */
685 +#define BCM4412_DEVICE_ID 0x4412 /* bcm44xx family pci enet */
686 +#define BCM4432_DEVICE_ID 0x4432 /* bcm44xx family cardbus enet */
687 +
688 +#define BCM3352_DEVICE_ID 0x3352 /* bcm3352 device id */
689 +#define BCM3360_DEVICE_ID 0x3360 /* bcm3360 device id */
690 +
691 +#define EPI41210_DEVICE_ID 0xa0fa /* bcm4210 */
692 +#define EPI41230_DEVICE_ID 0xa10e /* bcm4230 */
693 +
694 +#define BCM47XX_ILINE_ID 0x4711 /* 47xx iline20 */
695 +#define BCM47XX_V90_ID 0x4712 /* 47xx v90 codec */
696 +#define BCM47XX_ENET_ID 0x4713 /* 47xx enet */
697 +#define BCM47XX_EXT_ID 0x4714 /* 47xx external i/f */
698 +#define BCM47XX_USB_ID 0x4715 /* 47xx usb */
699 +#define BCM47XX_USBH_ID 0x4716 /* 47xx usb host */
700 +#define BCM47XX_USBD_ID 0x4717 /* 47xx usb device */
701 +#define BCM47XX_IPSEC_ID 0x4718 /* 47xx ipsec */
702 +#define BCM47XX_ROBO_ID 0x4719 /* 47xx/53xx roboswitch core */
703 +#define BCM47XX_USB20H_ID 0x471a /* 47xx usb 2.0 host */
704 +#define BCM47XX_USB20D_ID 0x471b /* 47xx usb 2.0 device */
705 +
706 +#define BCM4710_DEVICE_ID 0x4710 /* 4710 primary function 0 */
707 +
708 +#define BCM4610_DEVICE_ID 0x4610 /* 4610 primary function 0 */
709 +#define BCM4610_ILINE_ID 0x4611 /* 4610 iline100 */
710 +#define BCM4610_V90_ID 0x4612 /* 4610 v90 codec */
711 +#define BCM4610_ENET_ID 0x4613 /* 4610 enet */
712 +#define BCM4610_EXT_ID 0x4614 /* 4610 external i/f */
713 +#define BCM4610_USB_ID 0x4615 /* 4610 usb */
714 +
715 +#define BCM4402_DEVICE_ID 0x4402 /* 4402 primary function 0 */
716 +#define BCM4402_ENET_ID 0x4402 /* 4402 enet */
717 +#define BCM4402_V90_ID 0x4403 /* 4402 v90 codec */
718 +#define BCM4401_ENET_ID 0x170c /* 4401b0 production enet cards */
719 +
720 +#define BCM4301_DEVICE_ID 0x4301 /* 4301 primary function 0 */
721 +#define BCM4301_D11B_ID 0x4301 /* 4301 802.11b */
722 +
723 +#define BCM4307_DEVICE_ID 0x4307 /* 4307 primary function 0 */
724 +#define BCM4307_V90_ID 0x4305 /* 4307 v90 codec */
725 +#define BCM4307_ENET_ID 0x4306 /* 4307 enet */
726 +#define BCM4307_D11B_ID 0x4307 /* 4307 802.11b */
727 +
728 +#define BCM4306_DEVICE_ID 0x4306 /* 4306 chipcommon chipid */
729 +#define BCM4306_D11G_ID 0x4320 /* 4306 802.11g */
730 +#define BCM4306_D11G_ID2 0x4325
731 +#define BCM4306_D11A_ID 0x4321 /* 4306 802.11a */
732 +#define BCM4306_UART_ID 0x4322 /* 4306 uart */
733 +#define BCM4306_V90_ID 0x4323 /* 4306 v90 codec */
734 +#define BCM4306_D11DUAL_ID 0x4324 /* 4306 dual A+B */
735 +
736 +#define BCM4309_PKG_ID 1 /* 4309 package id */
737 +
738 +#define BCM4303_D11B_ID 0x4303 /* 4303 802.11b */
739 +#define BCM4303_PKG_ID 2 /* 4303 package id */
740 +
741 +#define BCM4310_DEVICE_ID 0x4310 /* 4310 chipcommon chipid */
742 +#define BCM4310_D11B_ID 0x4311 /* 4310 802.11b */
743 +#define BCM4310_UART_ID 0x4312 /* 4310 uart */
744 +#define BCM4310_ENET_ID 0x4313 /* 4310 enet */
745 +#define BCM4310_USB_ID 0x4315 /* 4310 usb */
746 +
747 +#define BCMGPRS_UART_ID 0x4333 /* Uart id used by 4306/gprs card */
748 +#define BCMGPRS2_UART_ID 0x4344 /* Uart id used by 4306/gprs card */
749 +
750 +
751 +#define BCM4704_DEVICE_ID 0x4704 /* 4704 chipcommon chipid */
752 +#define BCM4704_ENET_ID 0x4706 /* 4704 enet (Use 47XX_ENET_ID instead!) */
753 +
754 +#define BCM4317_DEVICE_ID 0x4317 /* 4317 chip common chipid */
755 +
756 +#define BCM4318_DEVICE_ID 0x4318 /* 4318 chip common chipid */
757 +#define BCM4318_D11G_ID 0x4318 /* 4318 801.11b/g id */
758 +#define BCM4318_D11DUAL_ID 0x4319 /* 4318 801.11a/b/g id */
759 +#define BCM4318_JTAGM_ID 0x4331 /* 4318 jtagm device id */
760 +
761 +#define FPGA_JTAGM_ID 0x4330 /* ??? */
762 +
763 +/* Address map */
764 +#define BCM4710_SDRAM 0x00000000 /* Physical SDRAM */
765 +#define BCM4710_PCI_MEM 0x08000000 /* Host Mode PCI memory access space (64 MB) */
766 +#define BCM4710_PCI_CFG 0x0c000000 /* Host Mode PCI configuration space (64 MB) */
767 +#define BCM4710_PCI_DMA 0x40000000 /* Client Mode PCI memory access space (1 GB) */
768 +#define BCM4710_SDRAM_SWAPPED 0x10000000 /* Byteswapped Physical SDRAM */
769 +#define BCM4710_ENUM 0x18000000 /* Beginning of core enumeration space */
770 +
771 +/* Core register space */
772 +#define BCM4710_REG_SDRAM 0x18000000 /* SDRAM core registers */
773 +#define BCM4710_REG_ILINE20 0x18001000 /* InsideLine20 core registers */
774 +#define BCM4710_REG_EMAC0 0x18002000 /* Ethernet MAC 0 core registers */
775 +#define BCM4710_REG_CODEC 0x18003000 /* Codec core registers */
776 +#define BCM4710_REG_USB 0x18004000 /* USB core registers */
777 +#define BCM4710_REG_PCI 0x18005000 /* PCI core registers */
778 +#define BCM4710_REG_MIPS 0x18006000 /* MIPS core registers */
779 +#define BCM4710_REG_EXTIF 0x18007000 /* External Interface core registers */
780 +#define BCM4710_REG_EMAC1 0x18008000 /* Ethernet MAC 1 core registers */
781 +
782 +#define BCM4710_EXTIF 0x1f000000 /* External Interface base address */
783 +#define BCM4710_PCMCIA_MEM 0x1f000000 /* External Interface PCMCIA memory access */
784 +#define BCM4710_PCMCIA_IO 0x1f100000 /* PCMCIA I/O access */
785 +#define BCM4710_PCMCIA_CONF 0x1f200000 /* PCMCIA configuration */
786 +#define BCM4710_PROG 0x1f800000 /* Programable interface */
787 +#define BCM4710_FLASH 0x1fc00000 /* Flash */
788 +
789 +#define BCM4710_EJTAG 0xff200000 /* MIPS EJTAG space (2M) */
790 +
791 +#define BCM4710_UART (BCM4710_REG_EXTIF + 0x00000300)
792 +
793 +#define BCM4710_EUART (BCM4710_EXTIF + 0x00800000)
794 +#define BCM4710_LED (BCM4710_EXTIF + 0x00900000)
795 +
796 +#define BCM4712_DEVICE_ID 0x4712 /* 4712 chipcommon chipid */
797 +#define BCM4712_MIPS_ID 0x4720 /* 4712 base devid */
798 +#define BCM4712LARGE_PKG_ID 0 /* 340pin 4712 package id */
799 +#define BCM4712SMALL_PKG_ID 1 /* 200pin 4712 package id */
800 +#define BCM4712MID_PKG_ID 2 /* 225pin 4712 package id */
801 +
802 +#define SDIOH_FPGA_ID 0x4380 /* sdio host fpga */
803 +
804 +#define BCM5365_DEVICE_ID 0x5365 /* 5365 chipcommon chipid */
805 +#define BCM5350_DEVICE_ID 0x5350 /* bcm5350 chipcommon chipid */
806 +#define BCM5352_DEVICE_ID 0x5352 /* bcm5352 chipcommon chipid */
807 +
808 +#define BCM4320_DEVICE_ID 0x4320 /* bcm4320 chipcommon chipid */
809 +
810 +/* PCMCIA vendor Id's */
811 +
812 +#define VENDOR_BROADCOM_PCMCIA 0x02d0
813 +
814 +/* SDIO vendor Id's */
815 +#define VENDOR_BROADCOM_SDIO 0x00BF
816 +
817 +
818 +/* boardflags */
819 +#define BFL_BTCOEXIST 0x0001 /* This board implements Bluetooth coexistance */
820 +#define BFL_PACTRL 0x0002 /* This board has gpio 9 controlling the PA */
821 +#define BFL_AIRLINEMODE 0x0004 /* This board implements gpio13 radio disable indication */
822 +#define BFL_ENETROBO 0x0010 /* This board has robo switch or core */
823 +#define BFL_CCKHIPWR 0x0040 /* Can do high-power CCK transmission */
824 +#define BFL_ENETADM 0x0080 /* This board has ADMtek switch */
825 +#define BFL_ENETVLAN 0x0100 /* This board has vlan capability */
826 +#define BFL_AFTERBURNER 0x0200 /* This board supports Afterburner mode */
827 +#define BFL_NOPCI 0x0400 /* This board leaves PCI floating */
828 +#define BFL_FEM 0x0800 /* This board supports the Front End Module */
829 +#define BFL_EXTLNA 0x1000 /* This board has an external LNA */
830 +#define BFL_HGPA 0x2000 /* This board has a high gain PA */
831 +#define BFL_BTCMOD 0x4000 /* This board' BTCOEXIST is in the alternate gpios */
832 +#define BFL_ALTIQ 0x8000 /* Alternate I/Q settings */
833 +
834 +/* board specific GPIO assignment, gpio 0-3 are also customer-configurable led */
835 +#define BOARD_GPIO_HWRAD_B 0x010 /* bit 4 is HWRAD input on 4301 */
836 +#define BOARD_GPIO_BTCMOD_IN 0x010 /* bit 4 is the alternate BT Coexistance Input */
837 +#define BOARD_GPIO_BTCMOD_OUT 0x020 /* bit 5 is the alternate BT Coexistance Out */
838 +#define BOARD_GPIO_BTC_IN 0x080 /* bit 7 is BT Coexistance Input */
839 +#define BOARD_GPIO_BTC_OUT 0x100 /* bit 8 is BT Coexistance Out */
840 +#define BOARD_GPIO_PACTRL 0x200 /* bit 9 controls the PA on new 4306 boards */
841 +#define PCI_CFG_GPIO_SCS 0x10 /* PCI config space bit 4 for 4306c0 slow clock source */
842 +#define PCI_CFG_GPIO_HWRAD 0x20 /* PCI config space GPIO 13 for hw radio disable */
843 +#define PCI_CFG_GPIO_XTAL 0x40 /* PCI config space GPIO 14 for Xtal powerup */
844 +#define PCI_CFG_GPIO_PLL 0x80 /* PCI config space GPIO 15 for PLL powerdown */
845 +
846 +/* Bus types */
847 +#define SB_BUS 0 /* Silicon Backplane */
848 +#define PCI_BUS 1 /* PCI target */
849 +#define PCMCIA_BUS 2 /* PCMCIA target */
850 +#define SDIO_BUS 3 /* SDIO target */
851 +#define JTAG_BUS 4 /* JTAG */
852 +
853 +/* Allows optimization for single-bus support */
854 +#ifdef BCMBUSTYPE
855 +#define BUSTYPE(bus) (BCMBUSTYPE)
856 +#else
857 +#define BUSTYPE(bus) (bus)
858 +#endif
859 +
860 +/* power control defines */
861 +#define PLL_DELAY 150 /* us pll on delay */
862 +#define FREF_DELAY 200 /* us fref change delay */
863 +#define MIN_SLOW_CLK 32 /* us Slow clock period */
864 +#define XTAL_ON_DELAY 1000 /* us crystal power-on delay */
865 +
866 +/* Reference Board Types */
867 +
868 +#define BU4710_BOARD 0x0400
869 +#define VSIM4710_BOARD 0x0401
870 +#define QT4710_BOARD 0x0402
871 +
872 +#define BU4610_BOARD 0x0403
873 +#define VSIM4610_BOARD 0x0404
874 +
875 +#define BU4307_BOARD 0x0405
876 +#define BCM94301CB_BOARD 0x0406
877 +#define BCM94301PC_BOARD 0x0406 /* Pcmcia 5v card */
878 +#define BCM94301MP_BOARD 0x0407
879 +#define BCM94307MP_BOARD 0x0408
880 +#define BCMAP4307_BOARD 0x0409
881 +
882 +#define BU4309_BOARD 0x040a
883 +#define BCM94309CB_BOARD 0x040b
884 +#define BCM94309MP_BOARD 0x040c
885 +#define BCM4309AP_BOARD 0x040d
886 +
887 +#define BCM94302MP_BOARD 0x040e
888 +
889 +#define VSIM4310_BOARD 0x040f
890 +#define BU4711_BOARD 0x0410
891 +#define BCM94310U_BOARD 0x0411
892 +#define BCM94310AP_BOARD 0x0412
893 +#define BCM94310MP_BOARD 0x0414
894 +
895 +#define BU4306_BOARD 0x0416
896 +#define BCM94306CB_BOARD 0x0417
897 +#define BCM94306MP_BOARD 0x0418
898 +
899 +#define BCM94710D_BOARD 0x041a
900 +#define BCM94710R1_BOARD 0x041b
901 +#define BCM94710R4_BOARD 0x041c
902 +#define BCM94710AP_BOARD 0x041d
903 +
904 +
905 +#define BU2050_BOARD 0x041f
906 +
907 +
908 +#define BCM94309G_BOARD 0x0421
909 +
910 +#define BCM94301PC3_BOARD 0x0422 /* Pcmcia 3.3v card */
911 +
912 +#define BU4704_BOARD 0x0423
913 +#define BU4702_BOARD 0x0424
914 +
915 +#define BCM94306PC_BOARD 0x0425 /* pcmcia 3.3v 4306 card */
916 +
917 +#define BU4317_BOARD 0x0426
918 +
919 +
920 +#define BCM94702MN_BOARD 0x0428
921 +
922 +/* BCM4702 1U CompactPCI Board */
923 +#define BCM94702CPCI_BOARD 0x0429
924 +
925 +/* BCM4702 with BCM95380 VLAN Router */
926 +#define BCM95380RR_BOARD 0x042a
927 +
928 +/* cb4306 with SiGe PA */
929 +#define BCM94306CBSG_BOARD 0x042b
930 +
931 +/* mp4301 with 2050 radio */
932 +#define BCM94301MPL_BOARD 0x042c
933 +
934 +/* cb4306 with SiGe PA */
935 +#define PCSG94306_BOARD 0x042d
936 +
937 +/* bu4704 with sdram */
938 +#define BU4704SD_BOARD 0x042e
939 +
940 +/* Dual 11a/11g Router */
941 +#define BCM94704AGR_BOARD 0x042f
942 +
943 +/* 11a-only minipci */
944 +#define BCM94308MP_BOARD 0x0430
945 +
946 +
947 +
948 +/* BCM94317 boards */
949 +#define BCM94317CB_BOARD 0x0440
950 +#define BCM94317MP_BOARD 0x0441
951 +#define BCM94317PCMCIA_BOARD 0x0442
952 +#define BCM94317SDIO_BOARD 0x0443
953 +
954 +#define BU4712_BOARD 0x0444
955 +#define BU4712SD_BOARD 0x045d
956 +#define BU4712L_BOARD 0x045f
957 +
958 +/* BCM4712 boards */
959 +#define BCM94712AP_BOARD 0x0445
960 +#define BCM94712P_BOARD 0x0446
961 +
962 +/* BCM4318 boards */
963 +#define BU4318_BOARD 0x0447
964 +#define CB4318_BOARD 0x0448
965 +#define MPG4318_BOARD 0x0449
966 +#define MP4318_BOARD 0x044a
967 +#define SD4318_BOARD 0x044b
968 +
969 +/* BCM63XX boards */
970 +#define BCM96338_BOARD 0x6338
971 +#define BCM96345_BOARD 0x6345
972 +#define BCM96348_BOARD 0x6348
973 +
974 +/* Another mp4306 with SiGe */
975 +#define BCM94306P_BOARD 0x044c
976 +
977 +/* CF-like 4317 modules */
978 +#define BCM94317CF_BOARD 0x044d
979 +
980 +/* mp4303 */
981 +#define BCM94303MP_BOARD 0x044e
982 +
983 +/* mpsgh4306 */
984 +#define BCM94306MPSGH_BOARD 0x044f
985 +
986 +/* BRCM 4306 w/ Front End Modules */
987 +#define BCM94306MPM 0x0450
988 +#define BCM94306MPL 0x0453
989 +
990 +/* 4712agr */
991 +#define BCM94712AGR_BOARD 0x0451
992 +
993 +/* The real CF 4317 board */
994 +#define CFI4317_BOARD 0x0452
995 +
996 +/* pcmcia 4303 */
997 +#define PC4303_BOARD 0x0454
998 +
999 +/* 5350K */
1000 +#define BCM95350K_BOARD 0x0455
1001 +
1002 +/* 5350R */
1003 +#define BCM95350R_BOARD 0x0456
1004 +
1005 +/* 4306mplna */
1006 +#define BCM94306MPLNA_BOARD 0x0457
1007 +
1008 +/* 4320 boards */
1009 +#define BU4320_BOARD 0x0458
1010 +#define BU4320S_BOARD 0x0459
1011 +#define BCM94320PH_BOARD 0x045a
1012 +
1013 +/* 4306mph */
1014 +#define BCM94306MPH_BOARD 0x045b
1015 +
1016 +/* 4306pciv */
1017 +#define BCM94306PCIV_BOARD 0x045c
1018 +
1019 +#define BU4712SD_BOARD 0x045d
1020 +
1021 +#define BCM94320PFLSH_BOARD 0x045e
1022 +
1023 +#define BU4712L_BOARD 0x045f
1024 +#define BCM94712LGR_BOARD 0x0460
1025 +#define BCM94320R_BOARD 0x0461
1026 +
1027 +#define BU5352_BOARD 0x0462
1028 +
1029 +#define BCM94318MPGH_BOARD 0x0463
1030 +
1031 +
1032 +#define BCM95352GR_BOARD 0x0467
1033 +
1034 +/* bcm95351agr */
1035 +#define BCM95351AGR_BOARD 0x0470
1036 +
1037 +/* # of GPIO pins */
1038 +#define GPIO_NUMPINS 16
1039 +
1040 +#endif /* _BCMDEVS_H */
1041 diff -Nur linux-2.4.32/arch/mips/bcm947xx/include/bcmendian.h linux-2.4.32-brcm/arch/mips/bcm947xx/include/bcmendian.h
1042 --- linux-2.4.32/arch/mips/bcm947xx/include/bcmendian.h 1970-01-01 01:00:00.000000000 +0100
1043 +++ linux-2.4.32-brcm/arch/mips/bcm947xx/include/bcmendian.h 2005-12-16 23:39:10.672819750 +0100
1044 @@ -0,0 +1,152 @@
1045 +/*
1046 + * local version of endian.h - byte order defines
1047 + *
1048 + * Copyright 2005, Broadcom Corporation
1049 + * All Rights Reserved.
1050 + *
1051 + * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY
1052 + * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM
1053 + * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS
1054 + * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE.
1055 + *
1056 + * $Id$
1057 +*/
1058 +
1059 +#ifndef _BCMENDIAN_H_
1060 +#define _BCMENDIAN_H_
1061 +
1062 +#include <typedefs.h>
1063 +
1064 +/* Byte swap a 16 bit value */
1065 +#define BCMSWAP16(val) \
1066 + ((uint16)( \
1067 + (((uint16)(val) & (uint16)0x00ffU) << 8) | \
1068 + (((uint16)(val) & (uint16)0xff00U) >> 8) ))
1069 +
1070 +/* Byte swap a 32 bit value */
1071 +#define BCMSWAP32(val) \
1072 + ((uint32)( \
1073 + (((uint32)(val) & (uint32)0x000000ffUL) << 24) | \
1074 + (((uint32)(val) & (uint32)0x0000ff00UL) << 8) | \
1075 + (((uint32)(val) & (uint32)0x00ff0000UL) >> 8) | \
1076 + (((uint32)(val) & (uint32)0xff000000UL) >> 24) ))
1077 +
1078 +/* 2 Byte swap a 32 bit value */
1079 +#define BCMSWAP32BY16(val) \
1080 + ((uint32)( \
1081 + (((uint32)(val) & (uint32)0x0000ffffUL) << 16) | \
1082 + (((uint32)(val) & (uint32)0xffff0000UL) >> 16) ))
1083 +
1084 +
1085 +static INLINE uint16
1086 +bcmswap16(uint16 val)
1087 +{
1088 + return BCMSWAP16(val);
1089 +}
1090 +
1091 +static INLINE uint32
1092 +bcmswap32(uint32 val)
1093 +{
1094 + return BCMSWAP32(val);
1095 +}
1096 +
1097 +static INLINE uint32
1098 +bcmswap32by16(uint32 val)
1099 +{
1100 + return BCMSWAP32BY16(val);
1101 +}
1102 +
1103 +/* buf - start of buffer of shorts to swap */
1104 +/* len - byte length of buffer */
1105 +static INLINE void
1106 +bcmswap16_buf(uint16 *buf, uint len)
1107 +{
1108 + len = len/2;
1109 +
1110 + while(len--){
1111 + *buf = bcmswap16(*buf);
1112 + buf++;
1113 + }
1114 +}
1115 +
1116 +#ifndef hton16
1117 +#ifndef IL_BIGENDIAN
1118 +#define HTON16(i) BCMSWAP16(i)
1119 +#define hton16(i) bcmswap16(i)
1120 +#define hton32(i) bcmswap32(i)
1121 +#define ntoh16(i) bcmswap16(i)
1122 +#define ntoh32(i) bcmswap32(i)
1123 +#define ltoh16(i) (i)
1124 +#define ltoh32(i) (i)
1125 +#define htol16(i) (i)
1126 +#define htol32(i) (i)
1127 +#else
1128 +#define HTON16(i) (i)
1129 +#define hton16(i) (i)
1130 +#define hton32(i) (i)
1131 +#define ntoh16(i) (i)
1132 +#define ntoh32(i) (i)
1133 +#define ltoh16(i) bcmswap16(i)
1134 +#define ltoh32(i) bcmswap32(i)
1135 +#define htol16(i) bcmswap16(i)
1136 +#define htol32(i) bcmswap32(i)
1137 +#endif
1138 +#endif
1139 +
1140 +#ifndef IL_BIGENDIAN
1141 +#define ltoh16_buf(buf, i)
1142 +#define htol16_buf(buf, i)
1143 +#else
1144 +#define ltoh16_buf(buf, i) bcmswap16_buf((uint16*)buf, i)
1145 +#define htol16_buf(buf, i) bcmswap16_buf((uint16*)buf, i)
1146 +#endif
1147 +
1148 +/*
1149 +* load 16-bit value from unaligned little endian byte array.
1150 +*/
1151 +static INLINE uint16
1152 +ltoh16_ua(uint8 *bytes)
1153 +{
1154 + return (bytes[1]<<8)+bytes[0];
1155 +}
1156 +
1157 +/*
1158 +* load 32-bit value from unaligned little endian byte array.
1159 +*/
1160 +static INLINE uint32
1161 +ltoh32_ua(uint8 *bytes)
1162 +{
1163 + return (bytes[3]<<24)+(bytes[2]<<16)+(bytes[1]<<8)+bytes[0];
1164 +}
1165 +
1166 +/*
1167 +* load 16-bit value from unaligned big(network) endian byte array.
1168 +*/
1169 +static INLINE uint16
1170 +ntoh16_ua(uint8 *bytes)
1171 +{
1172 + return (bytes[0]<<8)+bytes[1];
1173 +}
1174 +
1175 +/*
1176 +* load 32-bit value from unaligned big(network) endian byte array.
1177 +*/
1178 +static INLINE uint32
1179 +ntoh32_ua(uint8 *bytes)
1180 +{
1181 + return (bytes[0]<<24)+(bytes[1]<<16)+(bytes[2]<<8)+bytes[3];
1182 +}
1183 +
1184 +#define ltoh_ua(ptr) ( \
1185 + sizeof(*(ptr)) == sizeof(uint8) ? *(uint8 *)ptr : \
1186 + sizeof(*(ptr)) == sizeof(uint16) ? (((uint8 *)ptr)[1]<<8)+((uint8 *)ptr)[0] : \
1187 + (((uint8 *)ptr)[3]<<24)+(((uint8 *)ptr)[2]<<16)+(((uint8 *)ptr)[1]<<8)+((uint8 *)ptr)[0] \
1188 +)
1189 +
1190 +#define ntoh_ua(ptr) ( \
1191 + sizeof(*(ptr)) == sizeof(uint8) ? *(uint8 *)ptr : \
1192 + sizeof(*(ptr)) == sizeof(uint16) ? (((uint8 *)ptr)[0]<<8)+((uint8 *)ptr)[1] : \
1193 + (((uint8 *)ptr)[0]<<24)+(((uint8 *)ptr)[1]<<16)+(((uint8 *)ptr)[2]<<8)+((uint8 *)ptr)[3] \
1194 +)
1195 +
1196 +#endif /* _BCMENDIAN_H_ */
1197 diff -Nur linux-2.4.32/arch/mips/bcm947xx/include/bcmnvram.h linux-2.4.32-brcm/arch/mips/bcm947xx/include/bcmnvram.h
1198 --- linux-2.4.32/arch/mips/bcm947xx/include/bcmnvram.h 1970-01-01 01:00:00.000000000 +0100
1199 +++ linux-2.4.32-brcm/arch/mips/bcm947xx/include/bcmnvram.h 2005-12-16 23:39:10.700821500 +0100
1200 @@ -0,0 +1,141 @@
1201 +/*
1202 + * NVRAM variable manipulation
1203 + *
1204 + * Copyright 2005, Broadcom Corporation
1205 + * All Rights Reserved.
1206 + *
1207 + * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY
1208 + * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM
1209 + * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS
1210 + * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE.
1211 + *
1212 + * $Id$
1213 + */
1214 +
1215 +#ifndef _bcmnvram_h_
1216 +#define _bcmnvram_h_
1217 +
1218 +#ifndef _LANGUAGE_ASSEMBLY
1219 +
1220 +#include <typedefs.h>
1221 +
1222 +struct nvram_header {
1223 + uint32 magic;
1224 + uint32 len;
1225 + uint32 crc_ver_init; /* 0:7 crc, 8:15 ver, 16:31 sdram_init */
1226 + uint32 config_refresh; /* 0:15 sdram_config, 16:31 sdram_refresh */
1227 + uint32 config_ncdl; /* ncdl values for memc */
1228 +};
1229 +
1230 +struct nvram_tuple {
1231 + char *name;
1232 + char *value;
1233 + struct nvram_tuple *next;
1234 +};
1235 +
1236 +/*
1237 + * Initialize NVRAM access. May be unnecessary or undefined on certain
1238 + * platforms.
1239 + */
1240 +extern int BCMINIT(nvram_init)(void *sbh);
1241 +
1242 +/*
1243 + * Disable NVRAM access. May be unnecessary or undefined on certain
1244 + * platforms.
1245 + */
1246 +extern void BCMINIT(nvram_exit)(void *sbh);
1247 +
1248 +/*
1249 + * Get the value of an NVRAM variable. The pointer returned may be
1250 + * invalid after a set.
1251 + * @param name name of variable to get
1252 + * @return value of variable or NULL if undefined
1253 + */
1254 +extern char * BCMINIT(nvram_get)(const char *name);
1255 +
1256 +/*
1257 + * Read the reset GPIO value from the nvram and set the GPIO
1258 + * as input
1259 + */
1260 +extern int BCMINITFN(nvram_resetgpio_init)(void *sbh);
1261 +
1262 +/*
1263 + * Get the value of an NVRAM variable.
1264 + * @param name name of variable to get
1265 + * @return value of variable or NUL if undefined
1266 + */
1267 +#define nvram_safe_get(name) (BCMINIT(nvram_get)(name) ? : "")
1268 +
1269 +/*
1270 + * Match an NVRAM variable.
1271 + * @param name name of variable to match
1272 + * @param match value to compare against value of variable
1273 + * @return TRUE if variable is defined and its value is string equal
1274 + * to match or FALSE otherwise
1275 + */
1276 +static INLINE int
1277 +nvram_match(char *name, char *match) {
1278 + const char *value = BCMINIT(nvram_get)(name);
1279 + return (value && !strcmp(value, match));
1280 +}
1281 +
1282 +/*
1283 + * Inversely match an NVRAM variable.
1284 + * @param name name of variable to match
1285 + * @param match value to compare against value of variable
1286 + * @return TRUE if variable is defined and its value is not string
1287 + * equal to invmatch or FALSE otherwise
1288 + */
1289 +static INLINE int
1290 +nvram_invmatch(char *name, char *invmatch) {
1291 + const char *value = BCMINIT(nvram_get)(name);
1292 + return (value && strcmp(value, invmatch));
1293 +}
1294 +
1295 +/*
1296 + * Set the value of an NVRAM variable. The name and value strings are
1297 + * copied into private storage. Pointers to previously set values
1298 + * may become invalid. The new value may be immediately
1299 + * retrieved but will not be permanently stored until a commit.
1300 + * @param name name of variable to set
1301 + * @param value value of variable
1302 + * @return 0 on success and errno on failure
1303 + */
1304 +extern int BCMINIT(nvram_set)(const char *name, const char *value);
1305 +
1306 +/*
1307 + * Unset an NVRAM variable. Pointers to previously set values
1308 + * remain valid until a set.
1309 + * @param name name of variable to unset
1310 + * @return 0 on success and errno on failure
1311 + * NOTE: use nvram_commit to commit this change to flash.
1312 + */
1313 +extern int BCMINIT(nvram_unset)(const char *name);
1314 +
1315 +/*
1316 + * Commit NVRAM variables to permanent storage. All pointers to values
1317 + * may be invalid after a commit.
1318 + * NVRAM values are undefined after a commit.
1319 + * @return 0 on success and errno on failure
1320 + */
1321 +extern int BCMINIT(nvram_commit)(void);
1322 +
1323 +/*
1324 + * Get all NVRAM variables (format name=value\0 ... \0\0).
1325 + * @param buf buffer to store variables
1326 + * @param count size of buffer in bytes
1327 + * @return 0 on success and errno on failure
1328 + */
1329 +extern int BCMINIT(nvram_getall)(char *buf, int count);
1330 +
1331 +#endif /* _LANGUAGE_ASSEMBLY */
1332 +
1333 +#define NVRAM_MAGIC 0x48534C46 /* 'FLSH' */
1334 +#define NVRAM_VERSION 1
1335 +#define NVRAM_HEADER_SIZE 20
1336 +#define NVRAM_SPACE 0x8000
1337 +
1338 +#define NVRAM_MAX_VALUE_LEN 255
1339 +#define NVRAM_MAX_PARAM_LEN 64
1340 +
1341 +#endif /* _bcmnvram_h_ */
1342 diff -Nur linux-2.4.32/arch/mips/bcm947xx/include/bcmsrom.h linux-2.4.32-brcm/arch/mips/bcm947xx/include/bcmsrom.h
1343 --- linux-2.4.32/arch/mips/bcm947xx/include/bcmsrom.h 1970-01-01 01:00:00.000000000 +0100
1344 +++ linux-2.4.32-brcm/arch/mips/bcm947xx/include/bcmsrom.h 2005-12-16 23:39:10.704821750 +0100
1345 @@ -0,0 +1,23 @@
1346 +/*
1347 + * Misc useful routines to access NIC local SROM/OTP .
1348 + *
1349 + * Copyright 2005, Broadcom Corporation
1350 + * All Rights Reserved.
1351 + *
1352 + * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY
1353 + * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM
1354 + * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS
1355 + * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE.
1356 + *
1357 + * $Id$
1358 + */
1359 +
1360 +#ifndef _bcmsrom_h_
1361 +#define _bcmsrom_h_
1362 +
1363 +extern int srom_var_init(void *sbh, uint bus, void *curmap, osl_t *osh, char **vars, int *count);
1364 +
1365 +extern int srom_read(uint bus, void *curmap, osl_t *osh, uint byteoff, uint nbytes, uint16 *buf);
1366 +extern int srom_write(uint bus, void *curmap, osl_t *osh, uint byteoff, uint nbytes, uint16 *buf);
1367 +
1368 +#endif /* _bcmsrom_h_ */
1369 diff -Nur linux-2.4.32/arch/mips/bcm947xx/include/bcmutils.h linux-2.4.32-brcm/arch/mips/bcm947xx/include/bcmutils.h
1370 --- linux-2.4.32/arch/mips/bcm947xx/include/bcmutils.h 1970-01-01 01:00:00.000000000 +0100
1371 +++ linux-2.4.32-brcm/arch/mips/bcm947xx/include/bcmutils.h 2005-12-16 23:39:10.704821750 +0100
1372 @@ -0,0 +1,313 @@
1373 +/*
1374 + * Misc useful os-independent macros and functions.
1375 + *
1376 + * Copyright 2005, Broadcom Corporation
1377 + * All Rights Reserved.
1378 + *
1379 + * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY
1380 + * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM
1381 + * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS
1382 + * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE.
1383 + * $Id$
1384 + */
1385 +
1386 +#ifndef _bcmutils_h_
1387 +#define _bcmutils_h_
1388 +
1389 +/*** driver-only section ***/
1390 +#ifdef BCMDRIVER
1391 +#include <osl.h>
1392 +
1393 +#define _BCM_U 0x01 /* upper */
1394 +#define _BCM_L 0x02 /* lower */
1395 +#define _BCM_D 0x04 /* digit */
1396 +#define _BCM_C 0x08 /* cntrl */
1397 +#define _BCM_P 0x10 /* punct */
1398 +#define _BCM_S 0x20 /* white space (space/lf/tab) */
1399 +#define _BCM_X 0x40 /* hex digit */
1400 +#define _BCM_SP 0x80 /* hard space (0x20) */
1401 +
1402 +#define GPIO_PIN_NOTDEFINED 0x20
1403 +
1404 +extern unsigned char bcm_ctype[];
1405 +#define bcm_ismask(x) (bcm_ctype[(int)(unsigned char)(x)])
1406 +
1407 +#define bcm_isalnum(c) ((bcm_ismask(c)&(_BCM_U|_BCM_L|_BCM_D)) != 0)
1408 +#define bcm_isalpha(c) ((bcm_ismask(c)&(_BCM_U|_BCM_L)) != 0)
1409 +#define bcm_iscntrl(c) ((bcm_ismask(c)&(_BCM_C)) != 0)
1410 +#define bcm_isdigit(c) ((bcm_ismask(c)&(_BCM_D)) != 0)
1411 +#define bcm_isgraph(c) ((bcm_ismask(c)&(_BCM_P|_BCM_U|_BCM_L|_BCM_D)) != 0)
1412 +#define bcm_islower(c) ((bcm_ismask(c)&(_BCM_L)) != 0)
1413 +#define bcm_isprint(c) ((bcm_ismask(c)&(_BCM_P|_BCM_U|_BCM_L|_BCM_D|_BCM_SP)) != 0)
1414 +#define bcm_ispunct(c) ((bcm_ismask(c)&(_BCM_P)) != 0)
1415 +#define bcm_isspace(c) ((bcm_ismask(c)&(_BCM_S)) != 0)
1416 +#define bcm_isupper(c) ((bcm_ismask(c)&(_BCM_U)) != 0)
1417 +#define bcm_isxdigit(c) ((bcm_ismask(c)&(_BCM_D|_BCM_X)) != 0)
1418 +
1419 +/*
1420 + * Spin at most 'us' microseconds while 'exp' is true.
1421 + * Caller should explicitly test 'exp' when this completes
1422 + * and take appropriate error action if 'exp' is still true.
1423 + */
1424 +#define SPINWAIT(exp, us) { \
1425 + uint countdown = (us) + 9; \
1426 + while ((exp) && (countdown >= 10)) {\
1427 + OSL_DELAY(10); \
1428 + countdown -= 10; \
1429 + } \
1430 +}
1431 +
1432 +/* generic osl packet queue */
1433 +struct pktq {
1434 + void *head; /* first packet to dequeue */
1435 + void *tail; /* last packet to dequeue */
1436 + uint len; /* number of queued packets */
1437 + uint maxlen; /* maximum number of queued packets */
1438 + bool priority; /* enqueue by packet priority */
1439 + uint8 prio_map[MAXPRIO+1]; /* user priority to packet enqueue policy map */
1440 +};
1441 +#define DEFAULT_QLEN 128
1442 +
1443 +#define pktq_len(q) ((q)->len)
1444 +#define pktq_avail(q) ((q)->maxlen - (q)->len)
1445 +#define pktq_head(q) ((q)->head)
1446 +#define pktq_full(q) ((q)->len >= (q)->maxlen)
1447 +#define _pktq_pri(q, pri) ((q)->prio_map[pri])
1448 +#define pktq_tailpri(q) ((q)->tail ? _pktq_pri(q, PKTPRIO((q)->tail)) : _pktq_pri(q, 0))
1449 +
1450 +/* externs */
1451 +/* packet */
1452 +extern uint pktcopy(osl_t *osh, void *p, uint offset, int len, uchar *buf);
1453 +extern uint pkttotlen(osl_t *osh, void *);
1454 +extern void pktq_init(struct pktq *q, uint maxlen, const uint8 prio_map[]);
1455 +extern void pktenq(struct pktq *q, void *p, bool lifo);
1456 +extern void *pktdeq(struct pktq *q);
1457 +extern void *pktdeqtail(struct pktq *q);
1458 +/* string */
1459 +extern uint bcm_atoi(char *s);
1460 +extern uchar bcm_toupper(uchar c);
1461 +extern ulong bcm_strtoul(char *cp, char **endp, uint base);
1462 +extern char *bcmstrstr(char *haystack, char *needle);
1463 +extern char *bcmstrcat(char *dest, const char *src);
1464 +extern ulong wchar2ascii(char *abuf, ushort *wbuf, ushort wbuflen, ulong abuflen);
1465 +/* ethernet address */
1466 +extern char *bcm_ether_ntoa(char *ea, char *buf);
1467 +extern int bcm_ether_atoe(char *p, char *ea);
1468 +/* delay */
1469 +extern void bcm_mdelay(uint ms);
1470 +/* variable access */
1471 +extern char *getvar(char *vars, char *name);
1472 +extern int getintvar(char *vars, char *name);
1473 +extern uint getgpiopin(char *vars, char *pin_name, uint def_pin);
1474 +#define bcmlog(fmt, a1, a2)
1475 +#define bcmdumplog(buf, size) *buf = '\0'
1476 +#define bcmdumplogent(buf, idx) -1
1477 +
1478 +#endif /* #ifdef BCMDRIVER */
1479 +
1480 +/*** driver/apps-shared section ***/
1481 +
1482 +#define BCME_STRLEN 64
1483 +#define VALID_BCMERROR(e) ((e <= 0) && (e >= BCME_LAST))
1484 +
1485 +
1486 +/*
1487 + * error codes could be added but the defined ones shouldn't be changed/deleted
1488 + * these error codes are exposed to the user code
1489 + * when ever a new error code is added to this list
1490 + * please update errorstring table with the related error string and
1491 + * update osl files with os specific errorcode map
1492 +*/
1493 +
1494 +#define BCME_ERROR -1 /* Error generic */
1495 +#define BCME_BADARG -2 /* Bad Argument */
1496 +#define BCME_BADOPTION -3 /* Bad option */
1497 +#define BCME_NOTUP -4 /* Not up */
1498 +#define BCME_NOTDOWN -5 /* Not down */
1499 +#define BCME_NOTAP -6 /* Not AP */
1500 +#define BCME_NOTSTA -7 /* Not STA */
1501 +#define BCME_BADKEYIDX -8 /* BAD Key Index */
1502 +#define BCME_RADIOOFF -9 /* Radio Off */
1503 +#define BCME_NOTBANDLOCKED -10 /* Not bandlocked */
1504 +#define BCME_NOCLK -11 /* No Clock*/
1505 +#define BCME_BADRATESET -12 /* BAD RateSet*/
1506 +#define BCME_BADBAND -13 /* BAD Band */
1507 +#define BCME_BUFTOOSHORT -14 /* Buffer too short */
1508 +#define BCME_BUFTOOLONG -15 /* Buffer too Long */
1509 +#define BCME_BUSY -16 /* Busy*/
1510 +#define BCME_NOTASSOCIATED -17 /* Not associated*/
1511 +#define BCME_BADSSIDLEN -18 /* BAD SSID Len */
1512 +#define BCME_OUTOFRANGECHAN -19 /* Out of Range Channel*/
1513 +#define BCME_BADCHAN -20 /* BAD Channel */
1514 +#define BCME_BADADDR -21 /* BAD Address*/
1515 +#define BCME_NORESOURCE -22 /* No resources*/
1516 +#define BCME_UNSUPPORTED -23 /* Unsupported*/
1517 +#define BCME_BADLEN -24 /* Bad Length*/
1518 +#define BCME_NOTREADY -25 /* Not ready Yet*/
1519 +#define BCME_EPERM -26 /* Not Permitted */
1520 +#define BCME_NOMEM -27 /* No Memory */
1521 +#define BCME_ASSOCIATED -28 /* Associated */
1522 +#define BCME_RANGE -29 /* Range Error*/
1523 +#define BCME_NOTFOUND -30 /* Not found */
1524 +#define BCME_LAST BCME_NOTFOUND
1525 +
1526 +#ifndef ABS
1527 +#define ABS(a) (((a)<0)?-(a):(a))
1528 +#endif
1529 +
1530 +#ifndef MIN
1531 +#define MIN(a, b) (((a)<(b))?(a):(b))
1532 +#endif
1533 +
1534 +#ifndef MAX
1535 +#define MAX(a, b) (((a)>(b))?(a):(b))
1536 +#endif
1537 +
1538 +#define CEIL(x, y) (((x) + ((y)-1)) / (y))
1539 +#define ROUNDUP(x, y) ((((x)+((y)-1))/(y))*(y))
1540 +#define ISALIGNED(a, x) (((a) & ((x)-1)) == 0)
1541 +#define ISPOWEROF2(x) ((((x)-1)&(x))==0)
1542 +#define VALID_MASK(mask) !((mask) & ((mask) + 1))
1543 +#define OFFSETOF(type, member) ((uint)(uintptr)&((type *)0)->member)
1544 +#define ARRAYSIZE(a) (sizeof(a)/sizeof(a[0]))
1545 +
1546 +/* bit map related macros */
1547 +#ifndef setbit
1548 +#define NBBY 8 /* 8 bits per byte */
1549 +#define setbit(a,i) (((uint8 *)a)[(i)/NBBY] |= 1<<((i)%NBBY))
1550 +#define clrbit(a,i) (((uint8 *)a)[(i)/NBBY] &= ~(1<<((i)%NBBY)))
1551 +#define isset(a,i) (((uint8 *)a)[(i)/NBBY] & (1<<((i)%NBBY)))
1552 +#define isclr(a,i) ((((uint8 *)a)[(i)/NBBY] & (1<<((i)%NBBY))) == 0)
1553 +#endif
1554 +
1555 +#define NBITS(type) (sizeof(type) * 8)
1556 +#define NBITVAL(bits) (1 << (bits))
1557 +#define MAXBITVAL(bits) ((1 << (bits)) - 1)
1558 +
1559 +/* crc defines */
1560 +#define CRC8_INIT_VALUE 0xff /* Initial CRC8 checksum value */
1561 +#define CRC8_GOOD_VALUE 0x9f /* Good final CRC8 checksum value */
1562 +#define CRC16_INIT_VALUE 0xffff /* Initial CRC16 checksum value */
1563 +#define CRC16_GOOD_VALUE 0xf0b8 /* Good final CRC16 checksum value */
1564 +#define CRC32_INIT_VALUE 0xffffffff /* Initial CRC32 checksum value */
1565 +#define CRC32_GOOD_VALUE 0xdebb20e3 /* Good final CRC32 checksum value */
1566 +
1567 +/* bcm_format_flags() bit description structure */
1568 +typedef struct bcm_bit_desc {
1569 + uint32 bit;
1570 + char* name;
1571 +} bcm_bit_desc_t;
1572 +
1573 +/* tag_ID/length/value_buffer tuple */
1574 +typedef struct bcm_tlv {
1575 + uint8 id;
1576 + uint8 len;
1577 + uint8 data[1];
1578 +} bcm_tlv_t;
1579 +
1580 +/* Check that bcm_tlv_t fits into the given buflen */
1581 +#define bcm_valid_tlv(elt, buflen) ((buflen) >= 2 && (int)(buflen) >= (int)(2 + (elt)->len))
1582 +
1583 +/* buffer length for ethernet address from bcm_ether_ntoa() */
1584 +#define ETHER_ADDR_STR_LEN 18
1585 +
1586 +/* unaligned load and store macros */
1587 +#ifdef IL_BIGENDIAN
1588 +static INLINE uint32
1589 +load32_ua(uint8 *a)
1590 +{
1591 + return ((a[0] << 24) | (a[1] << 16) | (a[2] << 8) | a[3]);
1592 +}
1593 +
1594 +static INLINE void
1595 +store32_ua(uint8 *a, uint32 v)
1596 +{
1597 + a[0] = (v >> 24) & 0xff;
1598 + a[1] = (v >> 16) & 0xff;
1599 + a[2] = (v >> 8) & 0xff;
1600 + a[3] = v & 0xff;
1601 +}
1602 +
1603 +static INLINE uint16
1604 +load16_ua(uint8 *a)
1605 +{
1606 + return ((a[0] << 8) | a[1]);
1607 +}
1608 +
1609 +static INLINE void
1610 +store16_ua(uint8 *a, uint16 v)
1611 +{
1612 + a[0] = (v >> 8) & 0xff;
1613 + a[1] = v & 0xff;
1614 +}
1615 +
1616 +#else
1617 +
1618 +static INLINE uint32
1619 +load32_ua(uint8 *a)
1620 +{
1621 + return ((a[3] << 24) | (a[2] << 16) | (a[1] << 8) | a[0]);
1622 +}
1623 +
1624 +static INLINE void
1625 +store32_ua(uint8 *a, uint32 v)
1626 +{
1627 + a[3] = (v >> 24) & 0xff;
1628 + a[2] = (v >> 16) & 0xff;
1629 + a[1] = (v >> 8) & 0xff;
1630 + a[0] = v & 0xff;
1631 +}
1632 +
1633 +static INLINE uint16
1634 +load16_ua(uint8 *a)
1635 +{
1636 + return ((a[1] << 8) | a[0]);
1637 +}
1638 +
1639 +static INLINE void
1640 +store16_ua(uint8 *a, uint16 v)
1641 +{
1642 + a[1] = (v >> 8) & 0xff;
1643 + a[0] = v & 0xff;
1644 +}
1645 +
1646 +#endif
1647 +
1648 +/* externs */
1649 +/* crc */
1650 +extern uint8 hndcrc8(uint8 *p, uint nbytes, uint8 crc);
1651 +extern uint16 hndcrc16(uint8 *p, uint nbytes, uint16 crc);
1652 +extern uint32 hndcrc32(uint8 *p, uint nbytes, uint32 crc);
1653 +/* format/print */
1654 +/* IE parsing */
1655 +extern bcm_tlv_t *bcm_next_tlv(bcm_tlv_t *elt, int *buflen);
1656 +extern bcm_tlv_t *bcm_parse_tlvs(void *buf, int buflen, uint key);
1657 +extern bcm_tlv_t *bcm_parse_ordered_tlvs(void *buf, int buflen, uint key);
1658 +
1659 +/* bcmerror*/
1660 +extern const char *bcmerrorstr(int bcmerror);
1661 +
1662 +/* multi-bool data type: set of bools, mbool is true if any is set */
1663 +typedef uint32 mbool;
1664 +#define mboolset(mb, bit) (mb |= bit) /* set one bool */
1665 +#define mboolclr(mb, bit) (mb &= ~bit) /* clear one bool */
1666 +#define mboolisset(mb, bit) ((mb & bit) != 0) /* TRUE if one bool is set */
1667 +#define mboolmaskset(mb, mask, val) ((mb) = (((mb) & ~(mask)) | (val)))
1668 +
1669 +/* power conversion */
1670 +extern uint16 bcm_qdbm_to_mw(uint8 qdbm);
1671 +extern uint8 bcm_mw_to_qdbm(uint16 mw);
1672 +
1673 +/* generic datastruct to help dump routines */
1674 +struct fielddesc {
1675 + char *nameandfmt;
1676 + uint32 offset;
1677 + uint32 len;
1678 +};
1679 +
1680 +typedef uint32 (*readreg_rtn)(void *arg0, void *arg1, uint32 offset);
1681 +extern uint bcmdumpfields(readreg_rtn func_ptr, void *arg0, void *arg1, struct fielddesc *str, char *buf, uint32 bufsize);
1682 +
1683 +extern uint bcm_mkiovar(char *name, char *data, uint datalen, char *buf, uint len);
1684 +
1685 +#endif /* _bcmutils_h_ */
1686 diff -Nur linux-2.4.32/arch/mips/bcm947xx/include/hnddma.h linux-2.4.32-brcm/arch/mips/bcm947xx/include/hnddma.h
1687 --- linux-2.4.32/arch/mips/bcm947xx/include/hnddma.h 1970-01-01 01:00:00.000000000 +0100
1688 +++ linux-2.4.32-brcm/arch/mips/bcm947xx/include/hnddma.h 2005-12-16 23:39:10.708822000 +0100
1689 @@ -0,0 +1,71 @@
1690 +/*
1691 + * Generic Broadcom Home Networking Division (HND) DMA engine SW interface
1692 + * This supports the following chips: BCM42xx, 44xx, 47xx .
1693 + *
1694 + * Copyright 2005, Broadcom Corporation
1695 + * All Rights Reserved.
1696 + *
1697 + * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY
1698 + * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM
1699 + * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS
1700 + * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE.
1701 + * $Id$
1702 + */
1703 +
1704 +#ifndef _hnddma_h_
1705 +#define _hnddma_h_
1706 +
1707 +/* export structure */
1708 +typedef volatile struct {
1709 + /* rx error counters */
1710 + uint rxgiants; /* rx giant frames */
1711 + uint rxnobuf; /* rx out of dma descriptors */
1712 + /* tx error counters */
1713 + uint txnobuf; /* tx out of dma descriptors */
1714 +} hnddma_t;
1715 +
1716 +#ifndef di_t
1717 +#define di_t void
1718 +#endif
1719 +
1720 +#ifndef osl_t
1721 +#define osl_t void
1722 +#endif
1723 +
1724 +/* externs */
1725 +extern void * dma_attach(osl_t *osh, char *name, sb_t *sbh, void *dmaregstx, void *dmaregsrx,
1726 + uint ntxd, uint nrxd, uint rxbufsize, uint nrxpost, uint rxoffset, uint *msg_level);
1727 +extern void dma_detach(di_t *di);
1728 +extern void dma_txreset(di_t *di);
1729 +extern void dma_rxreset(di_t *di);
1730 +extern void dma_txinit(di_t *di);
1731 +extern bool dma_txenabled(di_t *di);
1732 +extern void dma_rxinit(di_t *di);
1733 +extern void dma_rxenable(di_t *di);
1734 +extern bool dma_rxenabled(di_t *di);
1735 +extern void dma_txsuspend(di_t *di);
1736 +extern void dma_txresume(di_t *di);
1737 +extern bool dma_txsuspended(di_t *di);
1738 +extern bool dma_txsuspendedidle(di_t *di);
1739 +extern bool dma_txstopped(di_t *di);
1740 +extern bool dma_rxstopped(di_t *di);
1741 +extern int dma_txfast(di_t *di, void *p, uint32 coreflags);
1742 +extern void dma_fifoloopbackenable(di_t *di);
1743 +extern void *dma_rx(di_t *di);
1744 +extern void dma_rxfill(di_t *di);
1745 +extern void dma_txreclaim(di_t *di, bool forceall);
1746 +extern void dma_rxreclaim(di_t *di);
1747 +extern uintptr dma_getvar(di_t *di, char *name);
1748 +extern void *dma_getnexttxp(di_t *di, bool forceall);
1749 +extern void *dma_peeknexttxp(di_t *di);
1750 +extern void *dma_getnextrxp(di_t *di, bool forceall);
1751 +extern void dma_txblock(di_t *di);
1752 +extern void dma_txunblock(di_t *di);
1753 +extern uint dma_txactive(di_t *di);
1754 +extern void dma_txrotate(di_t *di);
1755 +
1756 +extern void dma_rxpiomode(dma32regs_t *);
1757 +extern void dma_txpioloopback(dma32regs_t *);
1758 +
1759 +
1760 +#endif /* _hnddma_h_ */
1761 diff -Nur linux-2.4.32/arch/mips/bcm947xx/include/hndmips.h linux-2.4.32-brcm/arch/mips/bcm947xx/include/hndmips.h
1762 --- linux-2.4.32/arch/mips/bcm947xx/include/hndmips.h 1970-01-01 01:00:00.000000000 +0100
1763 +++ linux-2.4.32-brcm/arch/mips/bcm947xx/include/hndmips.h 2005-12-16 23:39:10.708822000 +0100
1764 @@ -0,0 +1,16 @@
1765 +/*
1766 + * Alternate include file for HND sbmips.h since CFE also ships with
1767 + * a sbmips.h.
1768 + *
1769 + * Copyright 2005, Broadcom Corporation
1770 + * All Rights Reserved.
1771 + *
1772 + * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY
1773 + * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM
1774 + * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS
1775 + * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE.
1776 + *
1777 + * $Id$
1778 + */
1779 +
1780 +#include "sbmips.h"
1781 diff -Nur linux-2.4.32/arch/mips/bcm947xx/include/linux_osl.h linux-2.4.32-brcm/arch/mips/bcm947xx/include/linux_osl.h
1782 --- linux-2.4.32/arch/mips/bcm947xx/include/linux_osl.h 1970-01-01 01:00:00.000000000 +0100
1783 +++ linux-2.4.32-brcm/arch/mips/bcm947xx/include/linux_osl.h 2005-12-16 23:39:10.708822000 +0100
1784 @@ -0,0 +1,371 @@
1785 +/*
1786 + * Linux OS Independent Layer
1787 + *
1788 + * Copyright 2005, Broadcom Corporation
1789 + * All Rights Reserved.
1790 + *
1791 + * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY
1792 + * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM
1793 + * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS
1794 + * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE.
1795 + *
1796 + * $Id$
1797 + */
1798 +
1799 +#ifndef _linux_osl_h_
1800 +#define _linux_osl_h_
1801 +
1802 +#include <typedefs.h>
1803 +
1804 +/* use current 2.4.x calling conventions */
1805 +#include <linuxver.h>
1806 +
1807 +/* assert and panic */
1808 +#ifdef __GNUC__
1809 +#define GCC_VERSION (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__)
1810 +#if GCC_VERSION > 30100
1811 +#define ASSERT(exp) do {} while (0)
1812 +#else
1813 +/* ASSERT could causes segmentation fault on GCC3.1, use empty instead*/
1814 +#define ASSERT(exp)
1815 +#endif
1816 +#endif
1817 +
1818 +/* microsecond delay */
1819 +#define OSL_DELAY(usec) osl_delay(usec)
1820 +extern void osl_delay(uint usec);
1821 +
1822 +/* PCMCIA attribute space access macros */
1823 +#if defined(CONFIG_PCMCIA) || defined(CONFIG_PCMCIA_MODULE)
1824 +struct pcmcia_dev {
1825 + dev_link_t link; /* PCMCIA device pointer */
1826 + dev_node_t node; /* PCMCIA node structure */
1827 + void *base; /* Mapped attribute memory window */
1828 + size_t size; /* Size of window */
1829 + void *drv; /* Driver data */
1830 +};
1831 +#endif
1832 +#define OSL_PCMCIA_READ_ATTR(osh, offset, buf, size) \
1833 + osl_pcmcia_read_attr((osh), (offset), (buf), (size))
1834 +#define OSL_PCMCIA_WRITE_ATTR(osh, offset, buf, size) \
1835 + osl_pcmcia_write_attr((osh), (offset), (buf), (size))
1836 +extern void osl_pcmcia_read_attr(osl_t *osh, uint offset, void *buf, int size);
1837 +extern void osl_pcmcia_write_attr(osl_t *osh, uint offset, void *buf, int size);
1838 +
1839 +/* PCI configuration space access macros */
1840 +#define OSL_PCI_READ_CONFIG(osh, offset, size) \
1841 + osl_pci_read_config((osh), (offset), (size))
1842 +#define OSL_PCI_WRITE_CONFIG(osh, offset, size, val) \
1843 + osl_pci_write_config((osh), (offset), (size), (val))
1844 +extern uint32 osl_pci_read_config(osl_t *osh, uint size, uint offset);
1845 +extern void osl_pci_write_config(osl_t *osh, uint offset, uint size, uint val);
1846 +
1847 +/* PCI device bus # and slot # */
1848 +#define OSL_PCI_BUS(osh) osl_pci_bus(osh)
1849 +#define OSL_PCI_SLOT(osh) osl_pci_slot(osh)
1850 +extern uint osl_pci_bus(osl_t *osh);
1851 +extern uint osl_pci_slot(osl_t *osh);
1852 +
1853 +/* OSL initialization */
1854 +extern osl_t *osl_attach(void *pdev);
1855 +extern void osl_detach(osl_t *osh);
1856 +
1857 +/* host/bus architecture-specific byte swap */
1858 +#define BUS_SWAP32(v) (v)
1859 +
1860 +/* general purpose memory allocation */
1861 +
1862 +#if defined(BCMDBG_MEM)
1863 +
1864 +#define MALLOC(osh, size) osl_debug_malloc((osh), (size), __LINE__, __FILE__)
1865 +#define MFREE(osh, addr, size) osl_debug_mfree((osh), (addr), (size), __LINE__, __FILE__)
1866 +#define MALLOCED(osh) osl_malloced((osh))
1867 +#define MALLOC_DUMP(osh, buf, sz) osl_debug_memdump((osh), (buf), (sz))
1868 +extern void *osl_debug_malloc(osl_t *osh, uint size, int line, char* file);
1869 +extern void osl_debug_mfree(osl_t *osh, void *addr, uint size, int line, char* file);
1870 +extern char *osl_debug_memdump(osl_t *osh, char *buf, uint sz);
1871 +
1872 +#else
1873 +
1874 +#define MALLOC(osh, size) osl_malloc((osh), (size))
1875 +#define MFREE(osh, addr, size) osl_mfree((osh), (addr), (size))
1876 +#define MALLOCED(osh) osl_malloced((osh))
1877 +
1878 +#endif /* BCMDBG_MEM */
1879 +
1880 +#define MALLOC_FAILED(osh) osl_malloc_failed((osh))
1881 +
1882 +extern void *osl_malloc(osl_t *osh, uint size);
1883 +extern void osl_mfree(osl_t *osh, void *addr, uint size);
1884 +extern uint osl_malloced(osl_t *osh);
1885 +extern uint osl_malloc_failed(osl_t *osh);
1886 +
1887 +/* allocate/free shared (dma-able) consistent memory */
1888 +#define DMA_CONSISTENT_ALIGN PAGE_SIZE
1889 +#define DMA_ALLOC_CONSISTENT(osh, size, pap) \
1890 + osl_dma_alloc_consistent((osh), (size), (pap))
1891 +#define DMA_FREE_CONSISTENT(osh, va, size, pa) \
1892 + osl_dma_free_consistent((osh), (void*)(va), (size), (pa))
1893 +extern void *osl_dma_alloc_consistent(osl_t *osh, uint size, ulong *pap);
1894 +extern void osl_dma_free_consistent(osl_t *osh, void *va, uint size, ulong pa);
1895 +
1896 +/* map/unmap direction */
1897 +#define DMA_TX 1
1898 +#define DMA_RX 2
1899 +
1900 +/* map/unmap shared (dma-able) memory */
1901 +#define DMA_MAP(osh, va, size, direction, p) \
1902 + osl_dma_map((osh), (va), (size), (direction))
1903 +#define DMA_UNMAP(osh, pa, size, direction, p) \
1904 + osl_dma_unmap((osh), (pa), (size), (direction))
1905 +extern uint osl_dma_map(osl_t *osh, void *va, uint size, int direction);
1906 +extern void osl_dma_unmap(osl_t *osh, uint pa, uint size, int direction);
1907 +
1908 +/* register access macros */
1909 +#if defined(BCMJTAG)
1910 +#include <bcmjtag.h>
1911 +#define R_REG(r) bcmjtag_read(NULL, (uint32)(r), sizeof (*(r)))
1912 +#define W_REG(r, v) bcmjtag_write(NULL, (uint32)(r), (uint32)(v), sizeof (*(r)))
1913 +#endif
1914 +
1915 +/*
1916 + * BINOSL selects the slightly slower function-call-based binary compatible osl.
1917 + * Macros expand to calls to functions defined in linux_osl.c .
1918 + */
1919 +#ifndef BINOSL
1920 +
1921 +/* string library, kernel mode */
1922 +#define printf(fmt, args...) printk(fmt, ## args)
1923 +#include <linux/kernel.h>
1924 +#include <linux/string.h>
1925 +
1926 +/* register access macros */
1927 +#if !defined(BCMJTAG)
1928 +#ifndef IL_BIGENDIAN
1929 +#define R_REG(r) ( \
1930 + sizeof(*(r)) == sizeof(uint8) ? readb((volatile uint8*)(r)) : \
1931 + sizeof(*(r)) == sizeof(uint16) ? readw((volatile uint16*)(r)) : \
1932 + readl((volatile uint32*)(r)) \
1933 +)
1934 +#define W_REG(r, v) do { \
1935 + switch (sizeof(*(r))) { \
1936 + case sizeof(uint8): writeb((uint8)(v), (volatile uint8*)(r)); break; \
1937 + case sizeof(uint16): writew((uint16)(v), (volatile uint16*)(r)); break; \
1938 + case sizeof(uint32): writel((uint32)(v), (volatile uint32*)(r)); break; \
1939 + } \
1940 +} while (0)
1941 +#else /* IL_BIGENDIAN */
1942 +#define R_REG(r) ({ \
1943 + __typeof(*(r)) __osl_v; \
1944 + switch (sizeof(*(r))) { \
1945 + case sizeof(uint8): __osl_v = readb((volatile uint8*)((uint32)r^3)); break; \
1946 + case sizeof(uint16): __osl_v = readw((volatile uint16*)((uint32)r^2)); break; \
1947 + case sizeof(uint32): __osl_v = readl((volatile uint32*)(r)); break; \
1948 + } \
1949 + __osl_v; \
1950 +})
1951 +#define W_REG(r, v) do { \
1952 + switch (sizeof(*(r))) { \
1953 + case sizeof(uint8): writeb((uint8)(v), (volatile uint8*)((uint32)r^3)); break; \
1954 + case sizeof(uint16): writew((uint16)(v), (volatile uint16*)((uint32)r^2)); break; \
1955 + case sizeof(uint32): writel((uint32)(v), (volatile uint32*)(r)); break; \
1956 + } \
1957 +} while (0)
1958 +#endif
1959 +#endif
1960 +
1961 +#define AND_REG(r, v) W_REG((r), R_REG(r) & (v))
1962 +#define OR_REG(r, v) W_REG((r), R_REG(r) | (v))
1963 +
1964 +/* bcopy, bcmp, and bzero */
1965 +#define bcopy(src, dst, len) memcpy((dst), (src), (len))
1966 +#define bcmp(b1, b2, len) memcmp((b1), (b2), (len))
1967 +#define bzero(b, len) memset((b), '\0', (len))
1968 +
1969 +/* uncached virtual address */
1970 +#ifdef mips
1971 +#define OSL_UNCACHED(va) KSEG1ADDR((va))
1972 +#include <asm/addrspace.h>
1973 +#else
1974 +#define OSL_UNCACHED(va) (va)
1975 +#endif
1976 +
1977 +/* get processor cycle count */
1978 +#if defined(mips)
1979 +#define OSL_GETCYCLES(x) ((x) = read_c0_count() * 2)
1980 +#elif defined(__i386__)
1981 +#define OSL_GETCYCLES(x) rdtscl((x))
1982 +#else
1983 +#define OSL_GETCYCLES(x) ((x) = 0)
1984 +#endif
1985 +
1986 +/* dereference an address that may cause a bus exception */
1987 +#ifdef mips
1988 +#if defined(MODULE) && (LINUX_VERSION_CODE < KERNEL_VERSION(2,4,17))
1989 +#define BUSPROBE(val, addr) panic("get_dbe() will not fixup a bus exception when compiled into a module")
1990 +#else
1991 +#define BUSPROBE(val, addr) get_dbe((val), (addr))
1992 +#include <asm/paccess.h>
1993 +#endif
1994 +#else
1995 +#define BUSPROBE(val, addr) ({ (val) = R_REG((addr)); 0; })
1996 +#endif
1997 +
1998 +/* map/unmap physical to virtual I/O */
1999 +#define REG_MAP(pa, size) ioremap_nocache((unsigned long)(pa), (unsigned long)(size))
2000 +#define REG_UNMAP(va) iounmap((void *)(va))
2001 +
2002 +/* shared (dma-able) memory access macros */
2003 +#define R_SM(r) *(r)
2004 +#define W_SM(r, v) (*(r) = (v))
2005 +#define BZERO_SM(r, len) memset((r), '\0', (len))
2006 +
2007 +/* packet primitives */
2008 +#define PKTGET(osh, len, send) osl_pktget((osh), (len), (send))
2009 +#define PKTFREE(osh, skb, send) osl_pktfree((skb))
2010 +#define PKTDATA(osh, skb) (((struct sk_buff*)(skb))->data)
2011 +#define PKTLEN(osh, skb) (((struct sk_buff*)(skb))->len)
2012 +#define PKTHEADROOM(osh, skb) (PKTDATA(osh,skb)-(((struct sk_buff*)(skb))->head))
2013 +#define PKTTAILROOM(osh, skb) ((((struct sk_buff*)(skb))->end)-(((struct sk_buff*)(skb))->tail))
2014 +#define PKTNEXT(osh, skb) (((struct sk_buff*)(skb))->next)
2015 +#define PKTSETNEXT(skb, x) (((struct sk_buff*)(skb))->next = (struct sk_buff*)(x))
2016 +#define PKTSETLEN(osh, skb, len) __skb_trim((struct sk_buff*)(skb), (len))
2017 +#define PKTPUSH(osh, skb, bytes) skb_push((struct sk_buff*)(skb), (bytes))
2018 +#define PKTPULL(osh, skb, bytes) skb_pull((struct sk_buff*)(skb), (bytes))
2019 +#define PKTDUP(osh, skb) skb_clone((struct sk_buff*)(skb), GFP_ATOMIC)
2020 +#define PKTCOOKIE(skb) ((void*)((struct sk_buff*)(skb))->csum)
2021 +#define PKTSETCOOKIE(skb, x) (((struct sk_buff*)(skb))->csum = (uint)(x))
2022 +#define PKTLINK(skb) (((struct sk_buff*)(skb))->prev)
2023 +#define PKTSETLINK(skb, x) (((struct sk_buff*)(skb))->prev = (struct sk_buff*)(x))
2024 +#define PKTPRIO(skb) (((struct sk_buff*)(skb))->priority)
2025 +#define PKTSETPRIO(skb, x) (((struct sk_buff*)(skb))->priority = (x))
2026 +extern void *osl_pktget(osl_t *osh, uint len, bool send);
2027 +extern void osl_pktfree(void *skb);
2028 +
2029 +#else /* BINOSL */
2030 +
2031 +/* string library */
2032 +#ifndef LINUX_OSL
2033 +#undef printf
2034 +#define printf(fmt, args...) osl_printf((fmt), ## args)
2035 +#undef sprintf
2036 +#define sprintf(buf, fmt, args...) osl_sprintf((buf), (fmt), ## args)
2037 +#undef strcmp
2038 +#define strcmp(s1, s2) osl_strcmp((s1), (s2))
2039 +#undef strncmp
2040 +#define strncmp(s1, s2, n) osl_strncmp((s1), (s2), (n))
2041 +#undef strlen
2042 +#define strlen(s) osl_strlen((s))
2043 +#undef strcpy
2044 +#define strcpy(d, s) osl_strcpy((d), (s))
2045 +#undef strncpy
2046 +#define strncpy(d, s, n) osl_strncpy((d), (s), (n))
2047 +#endif
2048 +extern int osl_printf(const char *format, ...);
2049 +extern int osl_sprintf(char *buf, const char *format, ...);
2050 +extern int osl_strcmp(const char *s1, const char *s2);
2051 +extern int osl_strncmp(const char *s1, const char *s2, uint n);
2052 +extern int osl_strlen(const char *s);
2053 +extern char* osl_strcpy(char *d, const char *s);
2054 +extern char* osl_strncpy(char *d, const char *s, uint n);
2055 +
2056 +/* register access macros */
2057 +#if !defined(BCMJTAG)
2058 +#define R_REG(r) ( \
2059 + sizeof(*(r)) == sizeof(uint8) ? osl_readb((volatile uint8*)(r)) : \
2060 + sizeof(*(r)) == sizeof(uint16) ? osl_readw((volatile uint16*)(r)) : \
2061 + osl_readl((volatile uint32*)(r)) \
2062 +)
2063 +#define W_REG(r, v) do { \
2064 + switch (sizeof(*(r))) { \
2065 + case sizeof(uint8): osl_writeb((uint8)(v), (volatile uint8*)(r)); break; \
2066 + case sizeof(uint16): osl_writew((uint16)(v), (volatile uint16*)(r)); break; \
2067 + case sizeof(uint32): osl_writel((uint32)(v), (volatile uint32*)(r)); break; \
2068 + } \
2069 +} while (0)
2070 +#endif
2071 +
2072 +#define AND_REG(r, v) W_REG((r), R_REG(r) & (v))
2073 +#define OR_REG(r, v) W_REG((r), R_REG(r) | (v))
2074 +extern uint8 osl_readb(volatile uint8 *r);
2075 +extern uint16 osl_readw(volatile uint16 *r);
2076 +extern uint32 osl_readl(volatile uint32 *r);
2077 +extern void osl_writeb(uint8 v, volatile uint8 *r);
2078 +extern void osl_writew(uint16 v, volatile uint16 *r);
2079 +extern void osl_writel(uint32 v, volatile uint32 *r);
2080 +
2081 +/* bcopy, bcmp, and bzero */
2082 +extern void bcopy(const void *src, void *dst, int len);
2083 +extern int bcmp(const void *b1, const void *b2, int len);
2084 +extern void bzero(void *b, int len);
2085 +
2086 +/* uncached virtual address */
2087 +#define OSL_UNCACHED(va) osl_uncached((va))
2088 +extern void *osl_uncached(void *va);
2089 +
2090 +/* get processor cycle count */
2091 +#define OSL_GETCYCLES(x) ((x) = osl_getcycles())
2092 +extern uint osl_getcycles(void);
2093 +
2094 +/* dereference an address that may target abort */
2095 +#define BUSPROBE(val, addr) osl_busprobe(&(val), (addr))
2096 +extern int osl_busprobe(uint32 *val, uint32 addr);
2097 +
2098 +/* map/unmap physical to virtual */
2099 +#define REG_MAP(pa, size) osl_reg_map((pa), (size))
2100 +#define REG_UNMAP(va) osl_reg_unmap((va))
2101 +extern void *osl_reg_map(uint32 pa, uint size);
2102 +extern void osl_reg_unmap(void *va);
2103 +
2104 +/* shared (dma-able) memory access macros */
2105 +#define R_SM(r) *(r)
2106 +#define W_SM(r, v) (*(r) = (v))
2107 +#define BZERO_SM(r, len) bzero((r), (len))
2108 +
2109 +/* packet primitives */
2110 +#define PKTGET(osh, len, send) osl_pktget((osh), (len), (send))
2111 +#define PKTFREE(osh, skb, send) osl_pktfree((skb))
2112 +#define PKTDATA(osh, skb) osl_pktdata((osh), (skb))
2113 +#define PKTLEN(osh, skb) osl_pktlen((osh), (skb))
2114 +#define PKTHEADROOM(osh, skb) osl_pktheadroom((osh), (skb))
2115 +#define PKTTAILROOM(osh, skb) osl_pkttailroom((osh), (skb))
2116 +#define PKTNEXT(osh, skb) osl_pktnext((osh), (skb))
2117 +#define PKTSETNEXT(skb, x) osl_pktsetnext((skb), (x))
2118 +#define PKTSETLEN(osh, skb, len) osl_pktsetlen((osh), (skb), (len))
2119 +#define PKTPUSH(osh, skb, bytes) osl_pktpush((osh), (skb), (bytes))
2120 +#define PKTPULL(osh, skb, bytes) osl_pktpull((osh), (skb), (bytes))
2121 +#define PKTDUP(osh, skb) osl_pktdup((osh), (skb))
2122 +#define PKTCOOKIE(skb) osl_pktcookie((skb))
2123 +#define PKTSETCOOKIE(skb, x) osl_pktsetcookie((skb), (x))
2124 +#define PKTLINK(skb) osl_pktlink((skb))
2125 +#define PKTSETLINK(skb, x) osl_pktsetlink((skb), (x))
2126 +#define PKTPRIO(skb) osl_pktprio((skb))
2127 +#define PKTSETPRIO(skb, x) osl_pktsetprio((skb), (x))
2128 +extern void *osl_pktget(osl_t *osh, uint len, bool send);
2129 +extern void osl_pktfree(void *skb);
2130 +extern uchar *osl_pktdata(osl_t *osh, void *skb);
2131 +extern uint osl_pktlen(osl_t *osh, void *skb);
2132 +extern uint osl_pktheadroom(osl_t *osh, void *skb);
2133 +extern uint osl_pkttailroom(osl_t *osh, void *skb);
2134 +extern void *osl_pktnext(osl_t *osh, void *skb);
2135 +extern void osl_pktsetnext(void *skb, void *x);
2136 +extern void osl_pktsetlen(osl_t *osh, void *skb, uint len);
2137 +extern uchar *osl_pktpush(osl_t *osh, void *skb, int bytes);
2138 +extern uchar *osl_pktpull(osl_t *osh, void *skb, int bytes);
2139 +extern void *osl_pktdup(osl_t *osh, void *skb);
2140 +extern void *osl_pktcookie(void *skb);
2141 +extern void osl_pktsetcookie(void *skb, void *x);
2142 +extern void *osl_pktlink(void *skb);
2143 +extern void osl_pktsetlink(void *skb, void *x);
2144 +extern uint osl_pktprio(void *skb);
2145 +extern void osl_pktsetprio(void *skb, uint x);
2146 +
2147 +#endif /* BINOSL */
2148 +
2149 +#define OSL_ERROR(bcmerror) osl_error(bcmerror)
2150 +extern int osl_error(int bcmerror);
2151 +
2152 +/* the largest reasonable packet buffer driver uses for ethernet MTU in bytes */
2153 +#define PKTBUFSZ 2048
2154 +
2155 +#endif /* _linux_osl_h_ */
2156 diff -Nur linux-2.4.32/arch/mips/bcm947xx/include/linuxver.h linux-2.4.32-brcm/arch/mips/bcm947xx/include/linuxver.h
2157 --- linux-2.4.32/arch/mips/bcm947xx/include/linuxver.h 1970-01-01 01:00:00.000000000 +0100
2158 +++ linux-2.4.32-brcm/arch/mips/bcm947xx/include/linuxver.h 2005-12-16 23:39:10.748824500 +0100
2159 @@ -0,0 +1,411 @@
2160 +/*
2161 + * Linux-specific abstractions to gain some independence from linux kernel versions.
2162 + * Pave over some 2.2 versus 2.4 versus 2.6 kernel differences.
2163 + *
2164 + * Copyright 2005, Broadcom Corporation
2165 + * All Rights Reserved.
2166 + *
2167 + * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY
2168 + * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM
2169 + * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS
2170 + * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE.
2171 + *
2172 + * $Id$
2173 + */
2174 +
2175 +#ifndef _linuxver_h_
2176 +#define _linuxver_h_
2177 +
2178 +#include <linux/config.h>
2179 +#include <linux/version.h>
2180 +
2181 +#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,3,0))
2182 +/* __NO_VERSION__ must be defined for all linkables except one in 2.2 */
2183 +#ifdef __UNDEF_NO_VERSION__
2184 +#undef __NO_VERSION__
2185 +#else
2186 +#define __NO_VERSION__
2187 +#endif
2188 +#endif
2189 +
2190 +#if defined(MODULE) && defined(MODVERSIONS)
2191 +#include <linux/modversions.h>
2192 +#endif
2193 +
2194 +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
2195 +#include <linux/moduleparam.h>
2196 +#endif
2197 +
2198 +
2199 +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
2200 +#define module_param(_name_, _type_, _perm_) MODULE_PARM(_name_, "i")
2201 +#define module_param_string(_name_, _string_, _size_, _perm_) MODULE_PARM(_string_, "c" __MODULE_STRING(_size_))
2202 +#endif
2203 +
2204 +/* linux/malloc.h is deprecated, use linux/slab.h instead. */
2205 +#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,4,9))
2206 +#include <linux/malloc.h>
2207 +#else
2208 +#include <linux/slab.h>
2209 +#endif
2210 +
2211 +#include <linux/types.h>
2212 +#include <linux/init.h>
2213 +#include <linux/mm.h>
2214 +#include <linux/string.h>
2215 +#include <linux/pci.h>
2216 +#include <linux/interrupt.h>
2217 +#include <linux/netdevice.h>
2218 +#include <asm/io.h>
2219 +
2220 +#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,41))
2221 +#include <linux/workqueue.h>
2222 +#else
2223 +#include <linux/tqueue.h>
2224 +#ifndef work_struct
2225 +#define work_struct tq_struct
2226 +#endif
2227 +#ifndef INIT_WORK
2228 +#define INIT_WORK(_work, _func, _data) INIT_TQUEUE((_work), (_func), (_data))
2229 +#endif
2230 +#ifndef schedule_work
2231 +#define schedule_work(_work) schedule_task((_work))
2232 +#endif
2233 +#ifndef flush_scheduled_work
2234 +#define flush_scheduled_work() flush_scheduled_tasks()
2235 +#endif
2236 +#endif
2237 +
2238 +#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0))
2239 +/* Some distributions have their own 2.6.x compatibility layers */
2240 +#ifndef IRQ_NONE
2241 +typedef void irqreturn_t;
2242 +#define IRQ_NONE
2243 +#define IRQ_HANDLED
2244 +#define IRQ_RETVAL(x)
2245 +#endif
2246 +#else
2247 +typedef irqreturn_t (*FN_ISR) (int irq, void *dev_id, struct pt_regs *ptregs);
2248 +#endif
2249 +
2250 +#if defined(CONFIG_PCMCIA) || defined(CONFIG_PCMCIA_MODULE)
2251 +
2252 +#include <pcmcia/version.h>
2253 +#include <pcmcia/cs_types.h>
2254 +#include <pcmcia/cs.h>
2255 +#include <pcmcia/cistpl.h>
2256 +#include <pcmcia/cisreg.h>
2257 +#include <pcmcia/ds.h>
2258 +
2259 +#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,69))
2260 +/* In 2.5 (as of 2.5.69 at least) there is a cs_error exported which
2261 + * does this, but it's not in 2.4 so we do our own for now. */
2262 +static inline void
2263 +cs_error(client_handle_t handle, int func, int ret)
2264 +{
2265 + error_info_t err = { func, ret };
2266 + CardServices(ReportError, handle, &err);
2267 +}
2268 +#endif
2269 +
2270 +#endif /* CONFIG_PCMCIA */
2271 +
2272 +#ifndef __exit
2273 +#define __exit
2274 +#endif
2275 +#ifndef __devexit
2276 +#define __devexit
2277 +#endif
2278 +#ifndef __devinit
2279 +#define __devinit __init
2280 +#endif
2281 +#ifndef __devinitdata
2282 +#define __devinitdata
2283 +#endif
2284 +#ifndef __devexit_p
2285 +#define __devexit_p(x) x
2286 +#endif
2287 +
2288 +#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,4,0))
2289 +
2290 +#define pci_get_drvdata(dev) (dev)->sysdata
2291 +#define pci_set_drvdata(dev, value) (dev)->sysdata=(value)
2292 +
2293 +/*
2294 + * New-style (2.4.x) PCI/hot-pluggable PCI/CardBus registration
2295 + */
2296 +
2297 +struct pci_device_id {
2298 + unsigned int vendor, device; /* Vendor and device ID or PCI_ANY_ID */
2299 + unsigned int subvendor, subdevice; /* Subsystem ID's or PCI_ANY_ID */
2300 + unsigned int class, class_mask; /* (class,subclass,prog-if) triplet */
2301 + unsigned long driver_data; /* Data private to the driver */
2302 +};
2303 +
2304 +struct pci_driver {
2305 + struct list_head node;
2306 + char *name;
2307 + const struct pci_device_id *id_table; /* NULL if wants all devices */
2308 + int (*probe)(struct pci_dev *dev, const struct pci_device_id *id); /* New device inserted */
2309 + void (*remove)(struct pci_dev *dev); /* Device removed (NULL if not a hot-plug capable driver) */
2310 + void (*suspend)(struct pci_dev *dev); /* Device suspended */
2311 + void (*resume)(struct pci_dev *dev); /* Device woken up */
2312 +};
2313 +
2314 +#define MODULE_DEVICE_TABLE(type, name)
2315 +#define PCI_ANY_ID (~0)
2316 +
2317 +/* compatpci.c */
2318 +#define pci_module_init pci_register_driver
2319 +extern int pci_register_driver(struct pci_driver *drv);
2320 +extern void pci_unregister_driver(struct pci_driver *drv);
2321 +
2322 +#endif /* PCI registration */
2323 +
2324 +#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,2,18))
2325 +#ifdef MODULE
2326 +#define module_init(x) int init_module(void) { return x(); }
2327 +#define module_exit(x) void cleanup_module(void) { x(); }
2328 +#else
2329 +#define module_init(x) __initcall(x);
2330 +#define module_exit(x) __exitcall(x);
2331 +#endif
2332 +#endif
2333 +
2334 +#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,3,48))
2335 +#define list_for_each(pos, head) \
2336 + for (pos = (head)->next; pos != (head); pos = pos->next)
2337 +#endif
2338 +
2339 +#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,3,13))
2340 +#define pci_resource_start(dev, bar) ((dev)->base_address[(bar)])
2341 +#elif (LINUX_VERSION_CODE < KERNEL_VERSION(2,3,44))
2342 +#define pci_resource_start(dev, bar) ((dev)->resource[(bar)].start)
2343 +#endif
2344 +
2345 +#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,3,23))
2346 +#define pci_enable_device(dev) do { } while (0)
2347 +#endif
2348 +
2349 +#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,3,14))
2350 +#define net_device device
2351 +#endif
2352 +
2353 +#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,3,42))
2354 +
2355 +/*
2356 + * DMA mapping
2357 + *
2358 + * See linux/Documentation/DMA-mapping.txt
2359 + */
2360 +
2361 +#ifndef PCI_DMA_TODEVICE
2362 +#define PCI_DMA_TODEVICE 1
2363 +#define PCI_DMA_FROMDEVICE 2
2364 +#endif
2365 +
2366 +typedef u32 dma_addr_t;
2367 +
2368 +/* Pure 2^n version of get_order */
2369 +static inline int get_order(unsigned long size)
2370 +{
2371 + int order;
2372 +
2373 + size = (size-1) >> (PAGE_SHIFT-1);
2374 + order = -1;
2375 + do {
2376 + size >>= 1;
2377 + order++;
2378 + } while (size);
2379 + return order;
2380 +}
2381 +
2382 +static inline void *pci_alloc_consistent(struct pci_dev *hwdev, size_t size,
2383 + dma_addr_t *dma_handle)
2384 +{
2385 + void *ret;
2386 + int gfp = GFP_ATOMIC | GFP_DMA;
2387 +
2388 + ret = (void *)__get_free_pages(gfp, get_order(size));
2389 +
2390 + if (ret != NULL) {
2391 + memset(ret, 0, size);
2392 + *dma_handle = virt_to_bus(ret);
2393 + }
2394 + return ret;
2395 +}
2396 +static inline void pci_free_consistent(struct pci_dev *hwdev, size_t size,
2397 + void *vaddr, dma_addr_t dma_handle)
2398 +{
2399 + free_pages((unsigned long)vaddr, get_order(size));
2400 +}
2401 +#ifdef ILSIM
2402 +extern uint pci_map_single(void *dev, void *va, uint size, int direction);
2403 +extern void pci_unmap_single(void *dev, uint pa, uint size, int direction);
2404 +#else
2405 +#define pci_map_single(cookie, address, size, dir) virt_to_bus(address)
2406 +#define pci_unmap_single(cookie, address, size, dir)
2407 +#endif
2408 +
2409 +#endif /* DMA mapping */
2410 +
2411 +#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,3,43))
2412 +
2413 +#define dev_kfree_skb_any(a) dev_kfree_skb(a)
2414 +#define netif_down(dev) do { (dev)->start = 0; } while(0)
2415 +
2416 +/* pcmcia-cs provides its own netdevice compatibility layer */
2417 +#ifndef _COMPAT_NETDEVICE_H
2418 +
2419 +/*
2420 + * SoftNet
2421 + *
2422 + * For pre-softnet kernels we need to tell the upper layer not to
2423 + * re-enter start_xmit() while we are in there. However softnet
2424 + * guarantees not to enter while we are in there so there is no need
2425 + * to do the netif_stop_queue() dance unless the transmit queue really
2426 + * gets stuck. This should also improve performance according to tests
2427 + * done by Aman Singla.
2428 + */
2429 +
2430 +#define dev_kfree_skb_irq(a) dev_kfree_skb(a)
2431 +#define netif_wake_queue(dev) do { clear_bit(0, &(dev)->tbusy); mark_bh(NET_BH); } while(0)
2432 +#define netif_stop_queue(dev) set_bit(0, &(dev)->tbusy)
2433 +
2434 +static inline void netif_start_queue(struct net_device *dev)
2435 +{
2436 + dev->tbusy = 0;
2437 + dev->interrupt = 0;
2438 + dev->start = 1;
2439 +}
2440 +
2441 +#define netif_queue_stopped(dev) (dev)->tbusy
2442 +#define netif_running(dev) (dev)->start
2443 +
2444 +#endif /* _COMPAT_NETDEVICE_H */
2445 +
2446 +#define netif_device_attach(dev) netif_start_queue(dev)
2447 +#define netif_device_detach(dev) netif_stop_queue(dev)
2448 +
2449 +/* 2.4.x renamed bottom halves to tasklets */
2450 +#define tasklet_struct tq_struct
2451 +static inline void tasklet_schedule(struct tasklet_struct *tasklet)
2452 +{
2453 + queue_task(tasklet, &tq_immediate);
2454 + mark_bh(IMMEDIATE_BH);
2455 +}
2456 +
2457 +static inline void tasklet_init(struct tasklet_struct *tasklet,
2458 + void (*func)(unsigned long),
2459 + unsigned long data)
2460 +{
2461 + tasklet->next = NULL;
2462 + tasklet->sync = 0;
2463 + tasklet->routine = (void (*)(void *))func;
2464 + tasklet->data = (void *)data;
2465 +}
2466 +#define tasklet_kill(tasklet) {do{} while(0);}
2467 +
2468 +/* 2.4.x introduced del_timer_sync() */
2469 +#define del_timer_sync(timer) del_timer(timer)
2470 +
2471 +#else
2472 +
2473 +#define netif_down(dev)
2474 +
2475 +#endif /* SoftNet */
2476 +
2477 +#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,4,3))
2478 +
2479 +/*
2480 + * Emit code to initialise a tq_struct's routine and data pointers
2481 + */
2482 +#define PREPARE_TQUEUE(_tq, _routine, _data) \
2483 + do { \
2484 + (_tq)->routine = _routine; \
2485 + (_tq)->data = _data; \
2486 + } while (0)
2487 +
2488 +/*
2489 + * Emit code to initialise all of a tq_struct
2490 + */
2491 +#define INIT_TQUEUE(_tq, _routine, _data) \
2492 + do { \
2493 + INIT_LIST_HEAD(&(_tq)->list); \
2494 + (_tq)->sync = 0; \
2495 + PREPARE_TQUEUE((_tq), (_routine), (_data)); \
2496 + } while (0)
2497 +
2498 +#endif
2499 +
2500 +#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,4,6))
2501 +
2502 +/* Power management related routines */
2503 +
2504 +static inline int
2505 +pci_save_state(struct pci_dev *dev, u32 *buffer)
2506 +{
2507 + int i;
2508 + if (buffer) {
2509 + for (i = 0; i < 16; i++)
2510 + pci_read_config_dword(dev, i * 4,&buffer[i]);
2511 + }
2512 + return 0;
2513 +}
2514 +
2515 +static inline int
2516 +pci_restore_state(struct pci_dev *dev, u32 *buffer)
2517 +{
2518 + int i;
2519 +
2520 + if (buffer) {
2521 + for (i = 0; i < 16; i++)
2522 + pci_write_config_dword(dev,i * 4, buffer[i]);
2523 + }
2524 + /*
2525 + * otherwise, write the context information we know from bootup.
2526 + * This works around a problem where warm-booting from Windows
2527 + * combined with a D3(hot)->D0 transition causes PCI config
2528 + * header data to be forgotten.
2529 + */
2530 + else {
2531 + for (i = 0; i < 6; i ++)
2532 + pci_write_config_dword(dev,
2533 + PCI_BASE_ADDRESS_0 + (i * 4),
2534 + pci_resource_start(dev, i));
2535 + pci_write_config_byte(dev, PCI_INTERRUPT_LINE, dev->irq);
2536 + }
2537 + return 0;
2538 +}
2539 +
2540 +#endif /* PCI power management */
2541 +
2542 +/* Old cp0 access macros deprecated in 2.4.19 */
2543 +#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,4,19))
2544 +#define read_c0_count() read_32bit_cp0_register(CP0_COUNT)
2545 +#endif
2546 +
2547 +/* Module refcount handled internally in 2.6.x */
2548 +#ifndef SET_MODULE_OWNER
2549 +#define SET_MODULE_OWNER(dev) do {} while (0)
2550 +#define OLD_MOD_INC_USE_COUNT MOD_INC_USE_COUNT
2551 +#define OLD_MOD_DEC_USE_COUNT MOD_DEC_USE_COUNT
2552 +#else
2553 +#define OLD_MOD_INC_USE_COUNT do {} while (0)
2554 +#define OLD_MOD_DEC_USE_COUNT do {} while (0)
2555 +#endif
2556 +
2557 +#ifndef SET_NETDEV_DEV
2558 +#define SET_NETDEV_DEV(net, pdev) do {} while (0)
2559 +#endif
2560 +
2561 +#ifndef HAVE_FREE_NETDEV
2562 +#define free_netdev(dev) kfree(dev)
2563 +#endif
2564 +
2565 +#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0))
2566 +/* struct packet_type redefined in 2.6.x */
2567 +#define af_packet_priv data
2568 +#endif
2569 +
2570 +#endif /* _linuxver_h_ */
2571 diff -Nur linux-2.4.32/arch/mips/bcm947xx/include/mipsinc.h linux-2.4.32-brcm/arch/mips/bcm947xx/include/mipsinc.h
2572 --- linux-2.4.32/arch/mips/bcm947xx/include/mipsinc.h 1970-01-01 01:00:00.000000000 +0100
2573 +++ linux-2.4.32-brcm/arch/mips/bcm947xx/include/mipsinc.h 2005-12-16 23:39:10.748824500 +0100
2574 @@ -0,0 +1,552 @@
2575 +/*
2576 + * HND Run Time Environment for standalone MIPS programs.
2577 + *
2578 + * Copyright 2005, Broadcom Corporation
2579 + * All Rights Reserved.
2580 + *
2581 + * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY
2582 + * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM
2583 + * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS
2584 + * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE.
2585 + *
2586 + * $Id$
2587 + */
2588 +
2589 +#ifndef _MISPINC_H
2590 +#define _MISPINC_H
2591 +
2592 +
2593 +/* MIPS defines */
2594 +
2595 +#ifdef _LANGUAGE_ASSEMBLY
2596 +
2597 +/*
2598 + * Symbolic register names for 32 bit ABI
2599 + */
2600 +#define zero $0 /* wired zero */
2601 +#define AT $1 /* assembler temp - uppercase because of ".set at" */
2602 +#define v0 $2 /* return value */
2603 +#define v1 $3
2604 +#define a0 $4 /* argument registers */
2605 +#define a1 $5
2606 +#define a2 $6
2607 +#define a3 $7
2608 +#define t0 $8 /* caller saved */
2609 +#define t1 $9
2610 +#define t2 $10
2611 +#define t3 $11
2612 +#define t4 $12
2613 +#define t5 $13
2614 +#define t6 $14
2615 +#define t7 $15
2616 +#define s0 $16 /* callee saved */
2617 +#define s1 $17
2618 +#define s2 $18
2619 +#define s3 $19
2620 +#define s4 $20
2621 +#define s5 $21
2622 +#define s6 $22
2623 +#define s7 $23
2624 +#define t8 $24 /* caller saved */
2625 +#define t9 $25
2626 +#define jp $25 /* PIC jump register */
2627 +#define k0 $26 /* kernel scratch */
2628 +#define k1 $27
2629 +#define gp $28 /* global pointer */
2630 +#define sp $29 /* stack pointer */
2631 +#define fp $30 /* frame pointer */
2632 +#define s8 $30 /* same like fp! */
2633 +#define ra $31 /* return address */
2634 +
2635 +
2636 +/*
2637 + * CP0 Registers
2638 + */
2639 +
2640 +#define C0_INX $0
2641 +#define C0_RAND $1
2642 +#define C0_TLBLO0 $2
2643 +#define C0_TLBLO C0_TLBLO0
2644 +#define C0_TLBLO1 $3
2645 +#define C0_CTEXT $4
2646 +#define C0_PGMASK $5
2647 +#define C0_WIRED $6
2648 +#define C0_BADVADDR $8
2649 +#define C0_COUNT $9
2650 +#define C0_TLBHI $10
2651 +#define C0_COMPARE $11
2652 +#define C0_SR $12
2653 +#define C0_STATUS C0_SR
2654 +#define C0_CAUSE $13
2655 +#define C0_EPC $14
2656 +#define C0_PRID $15
2657 +#define C0_CONFIG $16
2658 +#define C0_LLADDR $17
2659 +#define C0_WATCHLO $18
2660 +#define C0_WATCHHI $19
2661 +#define C0_XCTEXT $20
2662 +#define C0_DIAGNOSTIC $22
2663 +#define C0_BROADCOM C0_DIAGNOSTIC
2664 +#define C0_PERFORMANCE $25
2665 +#define C0_ECC $26
2666 +#define C0_CACHEERR $27
2667 +#define C0_TAGLO $28
2668 +#define C0_TAGHI $29
2669 +#define C0_ERREPC $30
2670 +#define C0_DESAVE $31
2671 +
2672 +/*
2673 + * LEAF - declare leaf routine
2674 + */
2675 +#define LEAF(symbol) \
2676 + .globl symbol; \
2677 + .align 2; \
2678 + .type symbol,@function; \
2679 + .ent symbol,0; \
2680 +symbol: .frame sp,0,ra
2681 +
2682 +/*
2683 + * END - mark end of function
2684 + */
2685 +#define END(function) \
2686 + .end function; \
2687 + .size function,.-function
2688 +
2689 +#define _ULCAST_
2690 +
2691 +#else
2692 +
2693 +/*
2694 + * The following macros are especially useful for __asm__
2695 + * inline assembler.
2696 + */
2697 +#ifndef __STR
2698 +#define __STR(x) #x
2699 +#endif
2700 +#ifndef STR
2701 +#define STR(x) __STR(x)
2702 +#endif
2703 +
2704 +#define _ULCAST_ (unsigned long)
2705 +
2706 +
2707 +/*
2708 + * CP0 Registers
2709 + */
2710 +
2711 +#define C0_INX 0 /* CP0: TLB Index */
2712 +#define C0_RAND 1 /* CP0: TLB Random */
2713 +#define C0_TLBLO0 2 /* CP0: TLB EntryLo0 */
2714 +#define C0_TLBLO C0_TLBLO0 /* CP0: TLB EntryLo0 */
2715 +#define C0_TLBLO1 3 /* CP0: TLB EntryLo1 */
2716 +#define C0_CTEXT 4 /* CP0: Context */
2717 +#define C0_PGMASK 5 /* CP0: TLB PageMask */
2718 +#define C0_WIRED 6 /* CP0: TLB Wired */
2719 +#define C0_BADVADDR 8 /* CP0: Bad Virtual Address */
2720 +#define C0_COUNT 9 /* CP0: Count */
2721 +#define C0_TLBHI 10 /* CP0: TLB EntryHi */
2722 +#define C0_COMPARE 11 /* CP0: Compare */
2723 +#define C0_SR 12 /* CP0: Processor Status */
2724 +#define C0_STATUS C0_SR /* CP0: Processor Status */
2725 +#define C0_CAUSE 13 /* CP0: Exception Cause */
2726 +#define C0_EPC 14 /* CP0: Exception PC */
2727 +#define C0_PRID 15 /* CP0: Processor Revision Indentifier */
2728 +#define C0_CONFIG 16 /* CP0: Config */
2729 +#define C0_LLADDR 17 /* CP0: LLAddr */
2730 +#define C0_WATCHLO 18 /* CP0: WatchpointLo */
2731 +#define C0_WATCHHI 19 /* CP0: WatchpointHi */
2732 +#define C0_XCTEXT 20 /* CP0: XContext */
2733 +#define C0_DIAGNOSTIC 22 /* CP0: Diagnostic */
2734 +#define C0_BROADCOM C0_DIAGNOSTIC /* CP0: Broadcom Register */
2735 +#define C0_PERFORMANCE 25 /* CP0: Performance Counter/Control Registers */
2736 +#define C0_ECC 26 /* CP0: ECC */
2737 +#define C0_CACHEERR 27 /* CP0: CacheErr */
2738 +#define C0_TAGLO 28 /* CP0: TagLo */
2739 +#define C0_TAGHI 29 /* CP0: TagHi */
2740 +#define C0_ERREPC 30 /* CP0: ErrorEPC */
2741 +#define C0_DESAVE 31 /* CP0: DebugSave */
2742 +
2743 +#endif /* _LANGUAGE_ASSEMBLY */
2744 +
2745 +/*
2746 + * Memory segments (32bit kernel mode addresses)
2747 + */
2748 +#undef KUSEG
2749 +#undef KSEG0
2750 +#undef KSEG1
2751 +#undef KSEG2
2752 +#undef KSEG3
2753 +#define KUSEG 0x00000000
2754 +#define KSEG0 0x80000000
2755 +#define KSEG1 0xa0000000
2756 +#define KSEG2 0xc0000000
2757 +#define KSEG3 0xe0000000
2758 +#define PHYSADDR_MASK 0x1fffffff
2759 +
2760 +/*
2761 + * Map an address to a certain kernel segment
2762 + */
2763 +#undef PHYSADDR
2764 +#undef KSEG0ADDR
2765 +#undef KSEG1ADDR
2766 +#undef KSEG2ADDR
2767 +#undef KSEG3ADDR
2768 +
2769 +#define PHYSADDR(a) (_ULCAST_(a) & PHYSADDR_MASK)
2770 +#define KSEG0ADDR(a) ((_ULCAST_(a) & PHYSADDR_MASK) | KSEG0)
2771 +#define KSEG1ADDR(a) ((_ULCAST_(a) & PHYSADDR_MASK) | KSEG1)
2772 +#define KSEG2ADDR(a) ((_ULCAST_(a) & PHYSADDR_MASK) | KSEG2)
2773 +#define KSEG3ADDR(a) ((_ULCAST_(a) & PHYSADDR_MASK) | KSEG3)
2774 +
2775 +
2776 +#ifndef Index_Invalidate_I
2777 +/*
2778 + * Cache Operations
2779 + */
2780 +#define Index_Invalidate_I 0x00
2781 +#define Index_Writeback_Inv_D 0x01
2782 +#define Index_Invalidate_SI 0x02
2783 +#define Index_Writeback_Inv_SD 0x03
2784 +#define Index_Load_Tag_I 0x04
2785 +#define Index_Load_Tag_D 0x05
2786 +#define Index_Load_Tag_SI 0x06
2787 +#define Index_Load_Tag_SD 0x07
2788 +#define Index_Store_Tag_I 0x08
2789 +#define Index_Store_Tag_D 0x09
2790 +#define Index_Store_Tag_SI 0x0A
2791 +#define Index_Store_Tag_SD 0x0B
2792 +#define Create_Dirty_Excl_D 0x0d
2793 +#define Create_Dirty_Excl_SD 0x0f
2794 +#define Hit_Invalidate_I 0x10
2795 +#define Hit_Invalidate_D 0x11
2796 +#define Hit_Invalidate_SI 0x12
2797 +#define Hit_Invalidate_SD 0x13
2798 +#define Fill_I 0x14
2799 +#define Hit_Writeback_Inv_D 0x15
2800 + /* 0x16 is unused */
2801 +#define Hit_Writeback_Inv_SD 0x17
2802 +#define R5K_Page_Invalidate_S 0x17
2803 +#define Hit_Writeback_I 0x18
2804 +#define Hit_Writeback_D 0x19
2805 + /* 0x1a is unused */
2806 +#define Hit_Writeback_SD 0x1b
2807 + /* 0x1c is unused */
2808 + /* 0x1e is unused */
2809 +#define Hit_Set_Virtual_SI 0x1e
2810 +#define Hit_Set_Virtual_SD 0x1f
2811 +#endif
2812 +
2813 +
2814 +/*
2815 + * R4x00 interrupt enable / cause bits
2816 + */
2817 +#define IE_SW0 (_ULCAST_(1) << 8)
2818 +#define IE_SW1 (_ULCAST_(1) << 9)
2819 +#define IE_IRQ0 (_ULCAST_(1) << 10)
2820 +#define IE_IRQ1 (_ULCAST_(1) << 11)
2821 +#define IE_IRQ2 (_ULCAST_(1) << 12)
2822 +#define IE_IRQ3 (_ULCAST_(1) << 13)
2823 +#define IE_IRQ4 (_ULCAST_(1) << 14)
2824 +#define IE_IRQ5 (_ULCAST_(1) << 15)
2825 +
2826 +#ifndef ST0_UM
2827 +/*
2828 + * Bitfields in the mips32 cp0 status register
2829 + */
2830 +#define ST0_IE 0x00000001
2831 +#define ST0_EXL 0x00000002
2832 +#define ST0_ERL 0x00000004
2833 +#define ST0_UM 0x00000010
2834 +#define ST0_SWINT0 0x00000100
2835 +#define ST0_SWINT1 0x00000200
2836 +#define ST0_HWINT0 0x00000400
2837 +#define ST0_HWINT1 0x00000800
2838 +#define ST0_HWINT2 0x00001000
2839 +#define ST0_HWINT3 0x00002000
2840 +#define ST0_HWINT4 0x00004000
2841 +#define ST0_HWINT5 0x00008000
2842 +#define ST0_IM 0x0000ff00
2843 +#define ST0_NMI 0x00080000
2844 +#define ST0_SR 0x00100000
2845 +#define ST0_TS 0x00200000
2846 +#define ST0_BEV 0x00400000
2847 +#define ST0_RE 0x02000000
2848 +#define ST0_RP 0x08000000
2849 +#define ST0_CU 0xf0000000
2850 +#define ST0_CU0 0x10000000
2851 +#define ST0_CU1 0x20000000
2852 +#define ST0_CU2 0x40000000
2853 +#define ST0_CU3 0x80000000
2854 +#endif
2855 +
2856 +
2857 +/*
2858 + * Bitfields in the mips32 cp0 cause register
2859 + */
2860 +#define C_EXC 0x0000007c
2861 +#define C_EXC_SHIFT 2
2862 +#define C_INT 0x0000ff00
2863 +#define C_INT_SHIFT 8
2864 +#define C_SW0 (_ULCAST_(1) << 8)
2865 +#define C_SW1 (_ULCAST_(1) << 9)
2866 +#define C_IRQ0 (_ULCAST_(1) << 10)
2867 +#define C_IRQ1 (_ULCAST_(1) << 11)
2868 +#define C_IRQ2 (_ULCAST_(1) << 12)
2869 +#define C_IRQ3 (_ULCAST_(1) << 13)
2870 +#define C_IRQ4 (_ULCAST_(1) << 14)
2871 +#define C_IRQ5 (_ULCAST_(1) << 15)
2872 +#define C_WP 0x00400000
2873 +#define C_IV 0x00800000
2874 +#define C_CE 0x30000000
2875 +#define C_CE_SHIFT 28
2876 +#define C_BD 0x80000000
2877 +
2878 +/* Values in C_EXC */
2879 +#define EXC_INT 0
2880 +#define EXC_TLBM 1
2881 +#define EXC_TLBL 2
2882 +#define EXC_TLBS 3
2883 +#define EXC_AEL 4
2884 +#define EXC_AES 5
2885 +#define EXC_IBE 6
2886 +#define EXC_DBE 7
2887 +#define EXC_SYS 8
2888 +#define EXC_BPT 9
2889 +#define EXC_RI 10
2890 +#define EXC_CU 11
2891 +#define EXC_OV 12
2892 +#define EXC_TR 13
2893 +#define EXC_WATCH 23
2894 +#define EXC_MCHK 24
2895 +
2896 +
2897 +/*
2898 + * Bits in the cp0 config register.
2899 + */
2900 +#define CONF_CM_CACHABLE_NO_WA 0
2901 +#define CONF_CM_CACHABLE_WA 1
2902 +#define CONF_CM_UNCACHED 2
2903 +#define CONF_CM_CACHABLE_NONCOHERENT 3
2904 +#define CONF_CM_CACHABLE_CE 4
2905 +#define CONF_CM_CACHABLE_COW 5
2906 +#define CONF_CM_CACHABLE_CUW 6
2907 +#define CONF_CM_CACHABLE_ACCELERATED 7
2908 +#define CONF_CM_CMASK 7
2909 +#define CONF_CU (_ULCAST_(1) << 3)
2910 +#define CONF_DB (_ULCAST_(1) << 4)
2911 +#define CONF_IB (_ULCAST_(1) << 5)
2912 +#define CONF_SE (_ULCAST_(1) << 12)
2913 +#define CONF_SC (_ULCAST_(1) << 17)
2914 +#define CONF_AC (_ULCAST_(1) << 23)
2915 +#define CONF_HALT (_ULCAST_(1) << 25)
2916 +
2917 +
2918 +/*
2919 + * Bits in the cp0 config register select 1.
2920 + */
2921 +#define CONF1_FP 0x00000001 /* FPU present */
2922 +#define CONF1_EP 0x00000002 /* EJTAG present */
2923 +#define CONF1_CA 0x00000004 /* mips16 implemented */
2924 +#define CONF1_WR 0x00000008 /* Watch registers present */
2925 +#define CONF1_PC 0x00000010 /* Performance counters present */
2926 +#define CONF1_DA_SHIFT 7 /* D$ associativity */
2927 +#define CONF1_DA_MASK 0x00000380
2928 +#define CONF1_DA_BASE 1
2929 +#define CONF1_DL_SHIFT 10 /* D$ line size */
2930 +#define CONF1_DL_MASK 0x00001c00
2931 +#define CONF1_DL_BASE 2
2932 +#define CONF1_DS_SHIFT 13 /* D$ sets/way */
2933 +#define CONF1_DS_MASK 0x0000e000
2934 +#define CONF1_DS_BASE 64
2935 +#define CONF1_IA_SHIFT 16 /* I$ associativity */
2936 +#define CONF1_IA_MASK 0x00070000
2937 +#define CONF1_IA_BASE 1
2938 +#define CONF1_IL_SHIFT 19 /* I$ line size */
2939 +#define CONF1_IL_MASK 0x00380000
2940 +#define CONF1_IL_BASE 2
2941 +#define CONF1_IS_SHIFT 22 /* Instruction cache sets/way */
2942 +#define CONF1_IS_MASK 0x01c00000
2943 +#define CONF1_IS_BASE 64
2944 +#define CONF1_MS_MASK 0x7e000000 /* Number of tlb entries */
2945 +#define CONF1_MS_SHIFT 25
2946 +
2947 +/* PRID register */
2948 +#define PRID_COPT_MASK 0xff000000
2949 +#define PRID_COMP_MASK 0x00ff0000
2950 +#define PRID_IMP_MASK 0x0000ff00
2951 +#define PRID_REV_MASK 0x000000ff
2952 +
2953 +#define PRID_COMP_LEGACY 0x000000
2954 +#define PRID_COMP_MIPS 0x010000
2955 +#define PRID_COMP_BROADCOM 0x020000
2956 +#define PRID_COMP_ALCHEMY 0x030000
2957 +#define PRID_COMP_SIBYTE 0x040000
2958 +#define PRID_IMP_BCM4710 0x4000
2959 +#define PRID_IMP_BCM3302 0x9000
2960 +#define PRID_IMP_BCM3303 0x9100
2961 +
2962 +#define PRID_IMP_UNKNOWN 0xff00
2963 +
2964 +#define BCM330X(id) \
2965 + (((id & (PRID_COMP_MASK | PRID_IMP_MASK)) == (PRID_COMP_BROADCOM | PRID_IMP_BCM3302)) \
2966 + || ((id & (PRID_COMP_MASK | PRID_IMP_MASK)) == (PRID_COMP_BROADCOM | PRID_IMP_BCM3303)))
2967 +
2968 +/* Bits in C0_BROADCOM */
2969 +#define BRCM_PFC_AVAIL 0x20000000 /* PFC is available */
2970 +#define BRCM_DC_ENABLE 0x40000000 /* Enable Data $ */
2971 +#define BRCM_IC_ENABLE 0x80000000 /* Enable Instruction $ */
2972 +#define BRCM_PFC_ENABLE 0x00400000 /* Obsolete? Enable PFC (at least on 4310) */
2973 +
2974 +/* PreFetch Cache aka Read Ahead Cache */
2975 +
2976 +#define PFC_CR0 0xff400000 /* control reg 0 */
2977 +#define PFC_CR1 0xff400004 /* control reg 1 */
2978 +
2979 +/* PFC operations */
2980 +#define PFC_I 0x00000001 /* Enable PFC use for instructions */
2981 +#define PFC_D 0x00000002 /* Enable PFC use for data */
2982 +#define PFC_PFI 0x00000004 /* Enable seq. prefetch for instructions */
2983 +#define PFC_PFD 0x00000008 /* Enable seq. prefetch for data */
2984 +#define PFC_CINV 0x00000010 /* Enable selective (i/d) cacheop flushing */
2985 +#define PFC_NCH 0x00000020 /* Disable flushing based on cacheops */
2986 +#define PFC_DPF 0x00000040 /* Enable directional prefetching */
2987 +#define PFC_FLUSH 0x00000100 /* Flush the PFC */
2988 +#define PFC_BRR 0x40000000 /* Bus error indication */
2989 +#define PFC_PWR 0x80000000 /* Disable power saving (clock gating) */
2990 +
2991 +/* Handy defaults */
2992 +#define PFC_DISABLED 0
2993 +#define PFC_AUTO 0xffffffff /* auto select the default mode */
2994 +#define PFC_INST (PFC_I | PFC_PFI | PFC_CINV)
2995 +#define PFC_INST_NOPF (PFC_I | PFC_CINV)
2996 +#define PFC_DATA (PFC_D | PFC_PFD | PFC_CINV)
2997 +#define PFC_DATA_NOPF (PFC_D | PFC_CINV)
2998 +#define PFC_I_AND_D (PFC_INST | PFC_DATA)
2999 +#define PFC_I_AND_D_NOPF (PFC_INST_NOPF | PFC_DATA_NOPF)
3000 +
3001 +
3002 +/*
3003 + * These are the UART port assignments, expressed as offsets from the base
3004 + * register. These assignments should hold for any serial port based on
3005 + * a 8250, 16450, or 16550(A).
3006 + */
3007 +
3008 +#define UART_RX 0 /* In: Receive buffer (DLAB=0) */
3009 +#define UART_TX 0 /* Out: Transmit buffer (DLAB=0) */
3010 +#define UART_DLL 0 /* Out: Divisor Latch Low (DLAB=1) */
3011 +#define UART_DLM 1 /* Out: Divisor Latch High (DLAB=1) */
3012 +#define UART_LCR 3 /* Out: Line Control Register */
3013 +#define UART_MCR 4 /* Out: Modem Control Register */
3014 +#define UART_LSR 5 /* In: Line Status Register */
3015 +#define UART_MSR 6 /* In: Modem Status Register */
3016 +#define UART_SCR 7 /* I/O: Scratch Register */
3017 +#define UART_LCR_DLAB 0x80 /* Divisor latch access bit */
3018 +#define UART_LCR_WLEN8 0x03 /* Wordlength: 8 bits */
3019 +#define UART_MCR_LOOP 0x10 /* Enable loopback test mode */
3020 +#define UART_LSR_THRE 0x20 /* Transmit-hold-register empty */
3021 +#define UART_LSR_RXRDY 0x01 /* Receiver ready */
3022 +
3023 +
3024 +#ifndef _LANGUAGE_ASSEMBLY
3025 +
3026 +/*
3027 + * Macros to access the system control coprocessor
3028 + */
3029 +
3030 +#define MFC0(source, sel) \
3031 +({ \
3032 + int __res; \
3033 + __asm__ __volatile__( \
3034 + ".set\tnoreorder\n\t" \
3035 + ".set\tnoat\n\t" \
3036 + ".word\t"STR(0x40010000 | ((source)<<11) | (sel))"\n\t" \
3037 + "move\t%0,$1\n\t" \
3038 + ".set\tat\n\t" \
3039 + ".set\treorder" \
3040 + :"=r" (__res) \
3041 + : \
3042 + :"$1"); \
3043 + __res; \
3044 +})
3045 +
3046 +#define MTC0(source, sel, value) \
3047 +do { \
3048 + __asm__ __volatile__( \
3049 + ".set\tnoreorder\n\t" \
3050 + ".set\tnoat\n\t" \
3051 + "move\t$1,%z0\n\t" \
3052 + ".word\t"STR(0x40810000 | ((source)<<11) | (sel))"\n\t" \
3053 + ".set\tat\n\t" \
3054 + ".set\treorder" \
3055 + : \
3056 + :"jr" (value) \
3057 + :"$1"); \
3058 +} while (0)
3059 +
3060 +#define get_c0_count() \
3061 +({ \
3062 + int __res; \
3063 + __asm__ __volatile__( \
3064 + ".set\tnoreorder\n\t" \
3065 + ".set\tnoat\n\t" \
3066 + "mfc0\t%0,$9\n\t" \
3067 + ".set\tat\n\t" \
3068 + ".set\treorder" \
3069 + :"=r" (__res)); \
3070 + __res; \
3071 +})
3072 +
3073 +static INLINE void icache_probe(uint32 config1, uint *size, uint *lsize)
3074 +{
3075 + uint lsz, sets, ways;
3076 +
3077 + /* Instruction Cache Size = Associativity * Line Size * Sets Per Way */
3078 + if ((lsz = ((config1 & CONF1_IL_MASK) >> CONF1_IL_SHIFT)))
3079 + lsz = CONF1_IL_BASE << lsz;
3080 + sets = CONF1_IS_BASE << ((config1 & CONF1_IS_MASK) >> CONF1_IS_SHIFT);
3081 + ways = CONF1_IA_BASE + ((config1 & CONF1_IA_MASK) >> CONF1_IA_SHIFT);
3082 + *size = lsz * sets * ways;
3083 + *lsize = lsz;
3084 +}
3085 +
3086 +static INLINE void dcache_probe(uint32 config1, uint *size, uint *lsize)
3087 +{
3088 + uint lsz, sets, ways;
3089 +
3090 + /* Data Cache Size = Associativity * Line Size * Sets Per Way */
3091 + if ((lsz = ((config1 & CONF1_DL_MASK) >> CONF1_DL_SHIFT)))
3092 + lsz = CONF1_DL_BASE << lsz;
3093 + sets = CONF1_DS_BASE << ((config1 & CONF1_DS_MASK) >> CONF1_DS_SHIFT);
3094 + ways = CONF1_DA_BASE + ((config1 & CONF1_DA_MASK) >> CONF1_DA_SHIFT);
3095 + *size = lsz * sets * ways;
3096 + *lsize = lsz;
3097 +}
3098 +
3099 +#define cache_op(base, op) \
3100 + __asm__ __volatile__(" \
3101 + .set noreorder; \
3102 + .set mips3; \
3103 + cache %1, (%0); \
3104 + .set mips0; \
3105 + .set reorder" \
3106 + : \
3107 + : "r" (base), \
3108 + "i" (op));
3109 +
3110 +#define cache_unroll4(base, delta, op) \
3111 + __asm__ __volatile__(" \
3112 + .set noreorder; \
3113 + .set mips3; \
3114 + cache %1,0(%0); \
3115 + cache %1,delta(%0); \
3116 + cache %1,(2 * delta)(%0); \
3117 + cache %1,(3 * delta)(%0); \
3118 + .set mips0; \
3119 + .set reorder" \
3120 + : \
3121 + : "r" (base), \
3122 + "i" (op));
3123 +
3124 +#endif /* !_LANGUAGE_ASSEMBLY */
3125 +
3126 +#endif /* _MISPINC_H */
3127 diff -Nur linux-2.4.32/arch/mips/bcm947xx/include/osl.h linux-2.4.32-brcm/arch/mips/bcm947xx/include/osl.h
3128 --- linux-2.4.32/arch/mips/bcm947xx/include/osl.h 1970-01-01 01:00:00.000000000 +0100
3129 +++ linux-2.4.32-brcm/arch/mips/bcm947xx/include/osl.h 2005-12-16 23:39:10.748824500 +0100
3130 @@ -0,0 +1,42 @@
3131 +/*
3132 + * OS Abstraction Layer
3133 + *
3134 + * Copyright 2005, Broadcom Corporation
3135 + * All Rights Reserved.
3136 + *
3137 + * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY
3138 + * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM
3139 + * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS
3140 + * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE.
3141 + * $Id$
3142 + */
3143 +
3144 +#ifndef _osl_h_
3145 +#define _osl_h_
3146 +
3147 +/* osl handle type forward declaration */
3148 +typedef struct os_handle osl_t;
3149 +
3150 +#if defined(linux)
3151 +#include <linux_osl.h>
3152 +#elif defined(NDIS)
3153 +#include <ndis_osl.h>
3154 +#elif defined(_CFE_)
3155 +#include <cfe_osl.h>
3156 +#elif defined(_HNDRTE_)
3157 +#include <hndrte_osl.h>
3158 +#elif defined(_MINOSL_)
3159 +#include <min_osl.h>
3160 +#elif PMON
3161 +#include <pmon_osl.h>
3162 +#elif defined(MACOSX)
3163 +#include <macosx_osl.h>
3164 +#else
3165 +#error "Unsupported OSL requested"
3166 +#endif
3167 +
3168 +/* handy */
3169 +#define SET_REG(r, mask, val) W_REG((r), ((R_REG(r) & ~(mask)) | (val)))
3170 +#define MAXPRIO 7 /* 0-7 */
3171 +
3172 +#endif /* _osl_h_ */
3173 diff -Nur linux-2.4.32/arch/mips/bcm947xx/include/pcicfg.h linux-2.4.32-brcm/arch/mips/bcm947xx/include/pcicfg.h
3174 --- linux-2.4.32/arch/mips/bcm947xx/include/pcicfg.h 1970-01-01 01:00:00.000000000 +0100
3175 +++ linux-2.4.32-brcm/arch/mips/bcm947xx/include/pcicfg.h 2005-12-16 23:39:10.752824750 +0100
3176 @@ -0,0 +1,451 @@
3177 +/*
3178 + * pcicfg.h: PCI configuration constants and structures.
3179 + *
3180 + * Copyright 2005, Broadcom Corporation
3181 + * All Rights Reserved.
3182 + *
3183 + * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY
3184 + * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM
3185 + * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS
3186 + * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE.
3187 + *
3188 + * $Id$
3189 + */
3190 +
3191 +#ifndef _h_pci_
3192 +#define _h_pci_
3193 +
3194 +/* The following inside ifndef's so we don't collide with NTDDK.H */
3195 +#ifndef PCI_MAX_BUS
3196 +#define PCI_MAX_BUS 0x100
3197 +#endif
3198 +#ifndef PCI_MAX_DEVICES
3199 +#define PCI_MAX_DEVICES 0x20
3200 +#endif
3201 +#ifndef PCI_MAX_FUNCTION
3202 +#define PCI_MAX_FUNCTION 0x8
3203 +#endif
3204 +
3205 +#ifndef PCI_INVALID_VENDORID
3206 +#define PCI_INVALID_VENDORID 0xffff
3207 +#endif
3208 +#ifndef PCI_INVALID_DEVICEID
3209 +#define PCI_INVALID_DEVICEID 0xffff
3210 +#endif
3211 +
3212 +
3213 +/* Convert between bus-slot-function-register and config addresses */
3214 +
3215 +#define PCICFG_BUS_SHIFT 16 /* Bus shift */
3216 +#define PCICFG_SLOT_SHIFT 11 /* Slot shift */
3217 +#define PCICFG_FUN_SHIFT 8 /* Function shift */
3218 +#define PCICFG_OFF_SHIFT 0 /* Register shift */
3219 +
3220 +#define PCICFG_BUS_MASK 0xff /* Bus mask */
3221 +#define PCICFG_SLOT_MASK 0x1f /* Slot mask */
3222 +#define PCICFG_FUN_MASK 7 /* Function mask */
3223 +#define PCICFG_OFF_MASK 0xff /* Bus mask */
3224 +
3225 +#define PCI_CONFIG_ADDR(b, s, f, o) \
3226 + ((((b) & PCICFG_BUS_MASK) << PCICFG_BUS_SHIFT) \
3227 + | (((s) & PCICFG_SLOT_MASK) << PCICFG_SLOT_SHIFT) \
3228 + | (((f) & PCICFG_FUN_MASK) << PCICFG_FUN_SHIFT) \
3229 + | (((o) & PCICFG_OFF_MASK) << PCICFG_OFF_SHIFT))
3230 +
3231 +#define PCI_CONFIG_BUS(a) (((a) >> PCICFG_BUS_SHIFT) & PCICFG_BUS_MASK)
3232 +#define PCI_CONFIG_SLOT(a) (((a) >> PCICFG_SLOT_SHIFT) & PCICFG_SLOT_MASK)
3233 +#define PCI_CONFIG_FUN(a) (((a) >> PCICFG_FUN_SHIFT) & PCICFG_FUN_MASK)
3234 +#define PCI_CONFIG_OFF(a) (((a) >> PCICFG_OFF_SHIFT) & PCICFG_OFF_MASK)
3235 +
3236 +/* PCIE Config space accessing MACROS*/
3237 +
3238 +#define PCIECFG_BUS_SHIFT 24 /* Bus shift */
3239 +#define PCIECFG_SLOT_SHIFT 19 /* Slot/Device shift */
3240 +#define PCIECFG_FUN_SHIFT 16 /* Function shift */
3241 +#define PCIECFG_OFF_SHIFT 0 /* Register shift */
3242 +
3243 +#define PCIECFG_BUS_MASK 0xff /* Bus mask */
3244 +#define PCIECFG_SLOT_MASK 0x1f /* Slot/Device mask */
3245 +#define PCIECFG_FUN_MASK 7 /* Function mask */
3246 +#define PCIECFG_OFF_MASK 0x3ff /* Register mask */
3247 +
3248 +#define PCIE_CONFIG_ADDR(b, s, f, o) \
3249 + ((((b) & PCIECFG_BUS_MASK) << PCIECFG_BUS_SHIFT) \
3250 + | (((s) & PCIECFG_SLOT_MASK) << PCIECFG_SLOT_SHIFT) \
3251 + | (((f) & PCIECFG_FUN_MASK) << PCIECFG_FUN_SHIFT) \
3252 + | (((o) & PCIECFG_OFF_MASK) << PCIECFG_OFF_SHIFT))
3253 +
3254 +#define PCIE_CONFIG_BUS(a) (((a) >> PCIECFG_BUS_SHIFT) & PCIECFG_BUS_MASK)
3255 +#define PCIE_CONFIG_SLOT(a) (((a) >> PCIECFG_SLOT_SHIFT) & PCIECFG_SLOT_MASK)
3256 +#define PCIE_CONFIG_FUN(a) (((a) >> PCIECFG_FUN_SHIFT) & PCIECFG_FUN_MASK)
3257 +#define PCIE_CONFIG_OFF(a) (((a) >> PCIECFG_OFF_SHIFT) & PCIECFG_OFF_MASK)
3258 +
3259 +
3260 +/* The actual config space */
3261 +
3262 +#define PCI_BAR_MAX 6
3263 +
3264 +#define PCI_ROM_BAR 8
3265 +
3266 +#define PCR_RSVDA_MAX 2
3267 +
3268 +/* pci config status reg has a bit to indicate that capability ptr is present*/
3269 +
3270 +#define PCI_CAPPTR_PRESENT 0x0010
3271 +
3272 +typedef struct _pci_config_regs {
3273 + unsigned short vendor;
3274 + unsigned short device;
3275 + unsigned short command;
3276 + unsigned short status;
3277 + unsigned char rev_id;
3278 + unsigned char prog_if;
3279 + unsigned char sub_class;
3280 + unsigned char base_class;
3281 + unsigned char cache_line_size;
3282 + unsigned char latency_timer;
3283 + unsigned char header_type;
3284 + unsigned char bist;
3285 + unsigned long base[PCI_BAR_MAX];
3286 + unsigned long cardbus_cis;
3287 + unsigned short subsys_vendor;
3288 + unsigned short subsys_id;
3289 + unsigned long baserom;
3290 + unsigned long rsvd_a[PCR_RSVDA_MAX];
3291 + unsigned char int_line;
3292 + unsigned char int_pin;
3293 + unsigned char min_gnt;
3294 + unsigned char max_lat;
3295 + unsigned char dev_dep[192];
3296 +} pci_config_regs;
3297 +
3298 +#define SZPCR (sizeof (pci_config_regs))
3299 +#define MINSZPCR 64 /* offsetof (dev_dep[0] */
3300 +
3301 +/* A structure for the config registers is nice, but in most
3302 + * systems the config space is not memory mapped, so we need
3303 + * filed offsetts. :-(
3304 + */
3305 +#define PCI_CFG_VID 0
3306 +#define PCI_CFG_DID 2
3307 +#define PCI_CFG_CMD 4
3308 +#define PCI_CFG_STAT 6
3309 +#define PCI_CFG_REV 8
3310 +#define PCI_CFG_PROGIF 9
3311 +#define PCI_CFG_SUBCL 0xa
3312 +#define PCI_CFG_BASECL 0xb
3313 +#define PCI_CFG_CLSZ 0xc
3314 +#define PCI_CFG_LATTIM 0xd
3315 +#define PCI_CFG_HDR 0xe
3316 +#define PCI_CFG_BIST 0xf
3317 +#define PCI_CFG_BAR0 0x10
3318 +#define PCI_CFG_BAR1 0x14
3319 +#define PCI_CFG_BAR2 0x18
3320 +#define PCI_CFG_BAR3 0x1c
3321 +#define PCI_CFG_BAR4 0x20
3322 +#define PCI_CFG_BAR5 0x24
3323 +#define PCI_CFG_CIS 0x28
3324 +#define PCI_CFG_SVID 0x2c
3325 +#define PCI_CFG_SSID 0x2e
3326 +#define PCI_CFG_ROMBAR 0x30
3327 +#define PCI_CFG_CAPPTR 0x34
3328 +#define PCI_CFG_INT 0x3c
3329 +#define PCI_CFG_PIN 0x3d
3330 +#define PCI_CFG_MINGNT 0x3e
3331 +#define PCI_CFG_MAXLAT 0x3f
3332 +
3333 +/* Classes and subclasses */
3334 +
3335 +typedef enum {
3336 + PCI_CLASS_OLD = 0,
3337 + PCI_CLASS_DASDI,
3338 + PCI_CLASS_NET,
3339 + PCI_CLASS_DISPLAY,
3340 + PCI_CLASS_MMEDIA,
3341 + PCI_CLASS_MEMORY,
3342 + PCI_CLASS_BRIDGE,
3343 + PCI_CLASS_COMM,
3344 + PCI_CLASS_BASE,
3345 + PCI_CLASS_INPUT,
3346 + PCI_CLASS_DOCK,
3347 + PCI_CLASS_CPU,
3348 + PCI_CLASS_SERIAL,
3349 + PCI_CLASS_INTELLIGENT = 0xe,
3350 + PCI_CLASS_SATELLITE,
3351 + PCI_CLASS_CRYPT,
3352 + PCI_CLASS_DSP,
3353 + PCI_CLASS_MAX
3354 +} pci_classes;
3355 +
3356 +typedef enum {
3357 + PCI_DASDI_SCSI,
3358 + PCI_DASDI_IDE,
3359 + PCI_DASDI_FLOPPY,
3360 + PCI_DASDI_IPI,
3361 + PCI_DASDI_RAID,
3362 + PCI_DASDI_OTHER = 0x80
3363 +} pci_dasdi_subclasses;
3364 +
3365 +typedef enum {
3366 + PCI_NET_ETHER,
3367 + PCI_NET_TOKEN,
3368 + PCI_NET_FDDI,
3369 + PCI_NET_ATM,
3370 + PCI_NET_OTHER = 0x80
3371 +} pci_net_subclasses;
3372 +
3373 +typedef enum {
3374 + PCI_DISPLAY_VGA,
3375 + PCI_DISPLAY_XGA,
3376 + PCI_DISPLAY_3D,
3377 + PCI_DISPLAY_OTHER = 0x80
3378 +} pci_display_subclasses;
3379 +
3380 +typedef enum {
3381 + PCI_MMEDIA_VIDEO,
3382 + PCI_MMEDIA_AUDIO,
3383 + PCI_MMEDIA_PHONE,
3384 + PCI_MEDIA_OTHER = 0x80
3385 +} pci_mmedia_subclasses;
3386 +
3387 +typedef enum {
3388 + PCI_MEMORY_RAM,
3389 + PCI_MEMORY_FLASH,
3390 + PCI_MEMORY_OTHER = 0x80
3391 +} pci_memory_subclasses;
3392 +
3393 +typedef enum {
3394 + PCI_BRIDGE_HOST,
3395 + PCI_BRIDGE_ISA,
3396 + PCI_BRIDGE_EISA,
3397 + PCI_BRIDGE_MC,
3398 + PCI_BRIDGE_PCI,
3399 + PCI_BRIDGE_PCMCIA,
3400 + PCI_BRIDGE_NUBUS,
3401 + PCI_BRIDGE_CARDBUS,
3402 + PCI_BRIDGE_RACEWAY,
3403 + PCI_BRIDGE_OTHER = 0x80
3404 +} pci_bridge_subclasses;
3405 +
3406 +typedef enum {
3407 + PCI_COMM_UART,
3408 + PCI_COMM_PARALLEL,
3409 + PCI_COMM_MULTIUART,
3410 + PCI_COMM_MODEM,
3411 + PCI_COMM_OTHER = 0x80
3412 +} pci_comm_subclasses;
3413 +
3414 +typedef enum {
3415 + PCI_BASE_PIC,
3416 + PCI_BASE_DMA,
3417 + PCI_BASE_TIMER,
3418 + PCI_BASE_RTC,
3419 + PCI_BASE_PCI_HOTPLUG,
3420 + PCI_BASE_OTHER = 0x80
3421 +} pci_base_subclasses;
3422 +
3423 +typedef enum {
3424 + PCI_INPUT_KBD,
3425 + PCI_INPUT_PEN,
3426 + PCI_INPUT_MOUSE,
3427 + PCI_INPUT_SCANNER,
3428 + PCI_INPUT_GAMEPORT,
3429 + PCI_INPUT_OTHER = 0x80
3430 +} pci_input_subclasses;
3431 +
3432 +typedef enum {
3433 + PCI_DOCK_GENERIC,
3434 + PCI_DOCK_OTHER = 0x80
3435 +} pci_dock_subclasses;
3436 +
3437 +typedef enum {
3438 + PCI_CPU_386,
3439 + PCI_CPU_486,
3440 + PCI_CPU_PENTIUM,
3441 + PCI_CPU_ALPHA = 0x10,
3442 + PCI_CPU_POWERPC = 0x20,
3443 + PCI_CPU_MIPS = 0x30,
3444 + PCI_CPU_COPROC = 0x40,
3445 + PCI_CPU_OTHER = 0x80
3446 +} pci_cpu_subclasses;
3447 +
3448 +typedef enum {
3449 + PCI_SERIAL_IEEE1394,
3450 + PCI_SERIAL_ACCESS,
3451 + PCI_SERIAL_SSA,
3452 + PCI_SERIAL_USB,
3453 + PCI_SERIAL_FIBER,
3454 + PCI_SERIAL_SMBUS,
3455 + PCI_SERIAL_OTHER = 0x80
3456 +} pci_serial_subclasses;
3457 +
3458 +typedef enum {
3459 + PCI_INTELLIGENT_I2O,
3460 +} pci_intelligent_subclasses;
3461 +
3462 +typedef enum {
3463 + PCI_SATELLITE_TV,
3464 + PCI_SATELLITE_AUDIO,
3465 + PCI_SATELLITE_VOICE,
3466 + PCI_SATELLITE_DATA,
3467 + PCI_SATELLITE_OTHER = 0x80
3468 +} pci_satellite_subclasses;
3469 +
3470 +typedef enum {
3471 + PCI_CRYPT_NETWORK,
3472 + PCI_CRYPT_ENTERTAINMENT,
3473 + PCI_CRYPT_OTHER = 0x80
3474 +} pci_crypt_subclasses;
3475 +
3476 +typedef enum {
3477 + PCI_DSP_DPIO,
3478 + PCI_DSP_OTHER = 0x80
3479 +} pci_dsp_subclasses;
3480 +
3481 +/* Header types */
3482 +typedef enum {
3483 + PCI_HEADER_NORMAL,
3484 + PCI_HEADER_BRIDGE,
3485 + PCI_HEADER_CARDBUS
3486 +} pci_header_types;
3487 +
3488 +
3489 +/* Overlay for a PCI-to-PCI bridge */
3490 +
3491 +#define PPB_RSVDA_MAX 2
3492 +#define PPB_RSVDD_MAX 8
3493 +
3494 +typedef struct _ppb_config_regs {
3495 + unsigned short vendor;
3496 + unsigned short device;
3497 + unsigned short command;
3498 + unsigned short status;
3499 + unsigned char rev_id;
3500 + unsigned char prog_if;
3501 + unsigned char sub_class;
3502 + unsigned char base_class;
3503 + unsigned char cache_line_size;
3504 + unsigned char latency_timer;
3505 + unsigned char header_type;
3506 + unsigned char bist;
3507 + unsigned long rsvd_a[PPB_RSVDA_MAX];
3508 + unsigned char prim_bus;
3509 + unsigned char sec_bus;
3510 + unsigned char sub_bus;
3511 + unsigned char sec_lat;
3512 + unsigned char io_base;
3513 + unsigned char io_lim;
3514 + unsigned short sec_status;
3515 + unsigned short mem_base;
3516 + unsigned short mem_lim;
3517 + unsigned short pf_mem_base;
3518 + unsigned short pf_mem_lim;
3519 + unsigned long pf_mem_base_hi;
3520 + unsigned long pf_mem_lim_hi;
3521 + unsigned short io_base_hi;
3522 + unsigned short io_lim_hi;
3523 + unsigned short subsys_vendor;
3524 + unsigned short subsys_id;
3525 + unsigned long rsvd_b;
3526 + unsigned char rsvd_c;
3527 + unsigned char int_pin;
3528 + unsigned short bridge_ctrl;
3529 + unsigned char chip_ctrl;
3530 + unsigned char diag_ctrl;
3531 + unsigned short arb_ctrl;
3532 + unsigned long rsvd_d[PPB_RSVDD_MAX];
3533 + unsigned char dev_dep[192];
3534 +} ppb_config_regs;
3535 +
3536 +
3537 +/* PCI CAPABILITY DEFINES */
3538 +#define PCI_CAP_POWERMGMTCAP_ID 0x01
3539 +#define PCI_CAP_MSICAP_ID 0x05
3540 +#define PCI_CAP_PCIECAP_ID 0x10
3541 +
3542 +/* Data structure to define the Message Signalled Interrupt facility
3543 + * Valid for PCI and PCIE configurations */
3544 +typedef struct _pciconfig_cap_msi {
3545 + unsigned char capID;
3546 + unsigned char nextptr;
3547 + unsigned short msgctrl;
3548 + unsigned int msgaddr;
3549 +} pciconfig_cap_msi;
3550 +
3551 +/* Data structure to define the Power managment facility
3552 + * Valid for PCI and PCIE configurations */
3553 +typedef struct _pciconfig_cap_pwrmgmt {
3554 + unsigned char capID;
3555 + unsigned char nextptr;
3556 + unsigned short pme_cap;
3557 + unsigned short pme_sts_ctrl;
3558 + unsigned char pme_bridge_ext;
3559 + unsigned char data;
3560 +} pciconfig_cap_pwrmgmt;
3561 +
3562 +/* Data structure to define the PCIE capability */
3563 +typedef struct _pciconfig_cap_pcie {
3564 + unsigned char capID;
3565 + unsigned char nextptr;
3566 + unsigned short pcie_cap;
3567 + unsigned int dev_cap;
3568 + unsigned short dev_ctrl;
3569 + unsigned short dev_status;
3570 + unsigned int link_cap;
3571 + unsigned short link_ctrl;
3572 + unsigned short link_status;
3573 +} pciconfig_cap_pcie;
3574 +
3575 +/* PCIE Enhanced CAPABILITY DEFINES */
3576 +#define PCIE_EXTCFG_OFFSET 0x100
3577 +#define PCIE_ADVERRREP_CAPID 0x0001
3578 +#define PCIE_VC_CAPID 0x0002
3579 +#define PCIE_DEVSNUM_CAPID 0x0003
3580 +#define PCIE_PWRBUDGET_CAPID 0x0004
3581 +
3582 +/* Header to define the PCIE specific capabilities in the extended config space */
3583 +typedef struct _pcie_enhanced_caphdr {
3584 + unsigned short capID;
3585 + unsigned short cap_ver : 4;
3586 + unsigned short next_ptr : 12;
3587 +} pcie_enhanced_caphdr;
3588 +
3589 +
3590 +/* Everything below is BRCM HND proprietary */
3591 +
3592 +#define PCI_BAR0_WIN 0x80 /* backplane addres space accessed by BAR0 */
3593 +#define PCI_BAR1_WIN 0x84 /* backplane addres space accessed by BAR1 */
3594 +#define PCI_SPROM_CONTROL 0x88 /* sprom property control */
3595 +#define PCI_BAR1_CONTROL 0x8c /* BAR1 region burst control */
3596 +#define PCI_INT_STATUS 0x90 /* PCI and other cores interrupts */
3597 +#define PCI_INT_MASK 0x94 /* mask of PCI and other cores interrupts */
3598 +#define PCI_TO_SB_MB 0x98 /* signal backplane interrupts */
3599 +#define PCI_BACKPLANE_ADDR 0xA0 /* address an arbitrary location on the system backplane */
3600 +#define PCI_BACKPLANE_DATA 0xA4 /* data at the location specified by above address register */
3601 +#define PCI_GPIO_IN 0xb0 /* pci config space gpio input (>=rev3) */
3602 +#define PCI_GPIO_OUT 0xb4 /* pci config space gpio output (>=rev3) */
3603 +#define PCI_GPIO_OUTEN 0xb8 /* pci config space gpio output enable (>=rev3) */
3604 +
3605 +#define PCI_BAR0_SPROM_OFFSET (4 * 1024) /* bar0 + 4K accesses external sprom */
3606 +#define PCI_BAR0_PCIREGS_OFFSET (6 * 1024) /* bar0 + 6K accesses pci core registers */
3607 +
3608 +/* PCI_INT_STATUS */
3609 +#define PCI_SBIM_STATUS_SERR 0x4 /* backplane SBErr interrupt status */
3610 +
3611 +/* PCI_INT_MASK */
3612 +#define PCI_SBIM_SHIFT 8 /* backplane core interrupt mask bits offset */
3613 +#define PCI_SBIM_MASK 0xff00 /* backplane core interrupt mask */
3614 +#define PCI_SBIM_MASK_SERR 0x4 /* backplane SBErr interrupt mask */
3615 +
3616 +/* PCI_SPROM_CONTROL */
3617 +#define SPROM_BLANK 0x04 /* indicating a blank sprom */
3618 +#define SPROM_WRITEEN 0x10 /* sprom write enable */
3619 +#define SPROM_BOOTROM_WE 0x20 /* external bootrom write enable */
3620 +
3621 +#define SPROM_SIZE 256 /* sprom size in 16-bit */
3622 +#define SPROM_CRC_RANGE 64 /* crc cover range in 16-bit */
3623 +
3624 +/* PCI_CFG_CMD_STAT */
3625 +#define PCI_CFG_CMD_STAT_TA 0x08000000 /* target abort status */
3626 +
3627 +#endif
3628 diff -Nur linux-2.4.32/arch/mips/bcm947xx/include/sbchipc.h linux-2.4.32-brcm/arch/mips/bcm947xx/include/sbchipc.h
3629 --- linux-2.4.32/arch/mips/bcm947xx/include/sbchipc.h 1970-01-01 01:00:00.000000000 +0100
3630 +++ linux-2.4.32-brcm/arch/mips/bcm947xx/include/sbchipc.h 2005-12-16 23:39:10.932836000 +0100
3631 @@ -0,0 +1,440 @@
3632 +/*
3633 + * SiliconBackplane Chipcommon core hardware definitions.
3634 + *
3635 + * The chipcommon core provides chip identification, SB control,
3636 + * jtag, 0/1/2 uarts, clock frequency control, a watchdog interrupt timer,
3637 + * gpio interface, extbus, and support for serial and parallel flashes.
3638 + *
3639 + * $Id$
3640 + * Copyright 2005, Broadcom Corporation
3641 + * All Rights Reserved.
3642 + *
3643 + * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY
3644 + * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM
3645 + * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS
3646 + * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE.
3647 + *
3648 + */
3649 +
3650 +#ifndef _SBCHIPC_H
3651 +#define _SBCHIPC_H
3652 +
3653 +
3654 +#ifndef _LANGUAGE_ASSEMBLY
3655 +
3656 +/* cpp contortions to concatenate w/arg prescan */
3657 +#ifndef PAD
3658 +#define _PADLINE(line) pad ## line
3659 +#define _XSTR(line) _PADLINE(line)
3660 +#define PAD _XSTR(__LINE__)
3661 +#endif /* PAD */
3662 +
3663 +typedef volatile struct {
3664 + uint32 chipid; /* 0x0 */
3665 + uint32 capabilities;
3666 + uint32 corecontrol; /* corerev >= 1 */
3667 + uint32 bist;
3668 +
3669 + /* OTP */
3670 + uint32 otpstatus; /* 0x10, corerev >= 10 */
3671 + uint32 otpcontrol;
3672 + uint32 otpprog;
3673 + uint32 PAD;
3674 +
3675 + /* Interrupt control */
3676 + uint32 intstatus; /* 0x20 */
3677 + uint32 intmask;
3678 + uint32 chipcontrol; /* 0x28, rev >= 11 */
3679 + uint32 chipstatus; /* 0x2c, rev >= 11 */
3680 +
3681 + /* Jtag Master */
3682 + uint32 jtagcmd; /* 0x30, rev >= 10 */
3683 + uint32 jtagir;
3684 + uint32 jtagdr;
3685 + uint32 jtagctrl;
3686 +
3687 + /* serial flash interface registers */
3688 + uint32 flashcontrol; /* 0x40 */
3689 + uint32 flashaddress;
3690 + uint32 flashdata;
3691 + uint32 PAD[1];
3692 +
3693 + /* Silicon backplane configuration broadcast control */
3694 + uint32 broadcastaddress; /* 0x50 */
3695 + uint32 broadcastdata;
3696 + uint32 PAD[2];
3697 +
3698 + /* gpio - cleared only by power-on-reset */
3699 + uint32 gpioin; /* 0x60 */
3700 + uint32 gpioout;
3701 + uint32 gpioouten;
3702 + uint32 gpiocontrol;
3703 + uint32 gpiointpolarity;
3704 + uint32 gpiointmask;
3705 + uint32 PAD[2];
3706 +
3707 + /* Watchdog timer */
3708 + uint32 watchdog; /* 0x80 */
3709 + uint32 PAD[1];
3710 +
3711 + /*GPIO based LED powersave registers corerev >= 16*/
3712 + uint32 gpiotimerval; /*0x88 */
3713 + uint32 gpiotimeroutmask;
3714 +
3715 + /* clock control */
3716 + uint32 clockcontrol_n; /* 0x90 */
3717 + uint32 clockcontrol_sb; /* aka m0 */
3718 + uint32 clockcontrol_pci; /* aka m1 */
3719 + uint32 clockcontrol_m2; /* mii/uart/mipsref */
3720 + uint32 clockcontrol_mips; /* aka m3 */
3721 + uint32 clkdiv; /* corerev >= 3 */
3722 + uint32 PAD[2];
3723 +
3724 + /* pll delay registers (corerev >= 4) */
3725 + uint32 pll_on_delay; /* 0xb0 */
3726 + uint32 fref_sel_delay;
3727 + uint32 slow_clk_ctl; /* 5 < corerev < 10 */
3728 + uint32 PAD[1];
3729 +
3730 + /* Instaclock registers (corerev >= 10) */
3731 + uint32 system_clk_ctl; /* 0xc0 */
3732 + uint32 clkstatestretch;
3733 + uint32 PAD[14];
3734 +
3735 + /* ExtBus control registers (corerev >= 3) */
3736 + uint32 pcmcia_config; /* 0x100 */
3737 + uint32 pcmcia_memwait;
3738 + uint32 pcmcia_attrwait;
3739 + uint32 pcmcia_iowait;
3740 + uint32 ide_config;
3741 + uint32 ide_memwait;
3742 + uint32 ide_attrwait;
3743 + uint32 ide_iowait;
3744 + uint32 prog_config;
3745 + uint32 prog_waitcount;
3746 + uint32 flash_config;
3747 + uint32 flash_waitcount;
3748 + uint32 PAD[116];
3749 +
3750 + /* uarts */
3751 + uint8 uart0data; /* 0x300 */
3752 + uint8 uart0imr;
3753 + uint8 uart0fcr;
3754 + uint8 uart0lcr;
3755 + uint8 uart0mcr;
3756 + uint8 uart0lsr;
3757 + uint8 uart0msr;
3758 + uint8 uart0scratch;
3759 + uint8 PAD[248]; /* corerev >= 1 */
3760 +
3761 + uint8 uart1data; /* 0x400 */
3762 + uint8 uart1imr;
3763 + uint8 uart1fcr;
3764 + uint8 uart1lcr;
3765 + uint8 uart1mcr;
3766 + uint8 uart1lsr;
3767 + uint8 uart1msr;
3768 + uint8 uart1scratch;
3769 +} chipcregs_t;
3770 +
3771 +#endif /* _LANGUAGE_ASSEMBLY */
3772 +
3773 +#define CC_CHIPID 0
3774 +#define CC_CAPABILITIES 4
3775 +#define CC_JTAGCMD 0x30
3776 +#define CC_JTAGIR 0x34
3777 +#define CC_JTAGDR 0x38
3778 +#define CC_JTAGCTRL 0x3c
3779 +#define CC_WATCHDOG 0x80
3780 +#define CC_CLKC_N 0x90
3781 +#define CC_CLKC_M0 0x94
3782 +#define CC_CLKC_M1 0x98
3783 +#define CC_CLKC_M2 0x9c
3784 +#define CC_CLKC_M3 0xa0
3785 +#define CC_CLKDIV 0xa4
3786 +#define CC_SYS_CLK_CTL 0xc0
3787 +#define CC_OTP 0x800
3788 +
3789 +/* chipid */
3790 +#define CID_ID_MASK 0x0000ffff /* Chip Id mask */
3791 +#define CID_REV_MASK 0x000f0000 /* Chip Revision mask */
3792 +#define CID_REV_SHIFT 16 /* Chip Revision shift */
3793 +#define CID_PKG_MASK 0x00f00000 /* Package Option mask */
3794 +#define CID_PKG_SHIFT 20 /* Package Option shift */
3795 +#define CID_CC_MASK 0x0f000000 /* CoreCount (corerev >= 4) */
3796 +#define CID_CC_SHIFT 24
3797 +
3798 +/* capabilities */
3799 +#define CAP_UARTS_MASK 0x00000003 /* Number of uarts */
3800 +#define CAP_MIPSEB 0x00000004 /* MIPS is in big-endian mode */
3801 +#define CAP_UCLKSEL 0x00000018 /* UARTs clock select */
3802 +#define CAP_UINTCLK 0x00000008 /* UARTs are driven by internal divided clock */
3803 +#define CAP_UARTGPIO 0x00000020 /* UARTs own Gpio's 15:12 */
3804 +#define CAP_EXTBUS 0x00000040 /* External bus present */
3805 +#define CAP_FLASH_MASK 0x00000700 /* Type of flash */
3806 +#define CAP_PLL_MASK 0x00038000 /* Type of PLL */
3807 +#define CAP_PWR_CTL 0x00040000 /* Power control */
3808 +#define CAP_OTPSIZE 0x00380000 /* OTP Size (0 = none) */
3809 +#define CAP_OTPSIZE_SHIFT 19 /* OTP Size shift */
3810 +#define CAP_OTPSIZE_BASE 5 /* OTP Size base */
3811 +#define CAP_JTAGP 0x00400000 /* JTAG Master Present */
3812 +#define CAP_ROM 0x00800000 /* Internal boot rom active */
3813 +
3814 +/* PLL type */
3815 +#define PLL_NONE 0x00000000
3816 +#define PLL_TYPE1 0x00010000 /* 48Mhz base, 3 dividers */
3817 +#define PLL_TYPE2 0x00020000 /* 48Mhz, 4 dividers */
3818 +#define PLL_TYPE3 0x00030000 /* 25Mhz, 2 dividers */
3819 +#define PLL_TYPE4 0x00008000 /* 48Mhz, 4 dividers */
3820 +#define PLL_TYPE5 0x00018000 /* 25Mhz, 4 dividers */
3821 +#define PLL_TYPE6 0x00028000 /* 100/200 or 120/240 only */
3822 +#define PLL_TYPE7 0x00038000 /* 25Mhz, 4 dividers */
3823 +
3824 +/* corecontrol */
3825 +#define CC_UARTCLKO 0x00000001 /* Drive UART with internal clock */
3826 +#define CC_SE 0x00000002 /* sync clk out enable (corerev >= 3) */
3827 +
3828 +/* Fields in the otpstatus register */
3829 +#define OTPS_PROGFAIL 0x80000000
3830 +#define OTPS_PROTECT 0x00000007
3831 +#define OTPS_HW_PROTECT 0x00000001
3832 +#define OTPS_SW_PROTECT 0x00000002
3833 +#define OTPS_CID_PROTECT 0x00000004
3834 +
3835 +/* Fields in the otpcontrol register */
3836 +#define OTPC_RECWAIT 0xff000000
3837 +#define OTPC_PROGWAIT 0x00ffff00
3838 +#define OTPC_PRW_SHIFT 8
3839 +#define OTPC_MAXFAIL 0x00000038
3840 +#define OTPC_VSEL 0x00000006
3841 +#define OTPC_SELVL 0x00000001
3842 +
3843 +/* Fields in otpprog */
3844 +#define OTPP_COL_MASK 0x000000ff
3845 +#define OTPP_ROW_MASK 0x0000ff00
3846 +#define OTPP_ROW_SHIFT 8
3847 +#define OTPP_READERR 0x10000000
3848 +#define OTPP_VALUE 0x20000000
3849 +#define OTPP_VALUE_SHIFT 29
3850 +#define OTPP_READ 0x40000000
3851 +#define OTPP_START 0x80000000
3852 +#define OTPP_BUSY 0x80000000
3853 +
3854 +/* jtagcmd */
3855 +#define JCMD_START 0x80000000
3856 +#define JCMD_BUSY 0x80000000
3857 +#define JCMD_PAUSE 0x40000000
3858 +#define JCMD0_ACC_MASK 0x0000f000
3859 +#define JCMD0_ACC_IRDR 0x00000000
3860 +#define JCMD0_ACC_DR 0x00001000
3861 +#define JCMD0_ACC_IR 0x00002000
3862 +#define JCMD0_ACC_RESET 0x00003000
3863 +#define JCMD0_ACC_IRPDR 0x00004000
3864 +#define JCMD0_ACC_PDR 0x00005000
3865 +#define JCMD0_IRW_MASK 0x00000f00
3866 +#define JCMD_ACC_MASK 0x000f0000 /* Changes for corerev 11 */
3867 +#define JCMD_ACC_IRDR 0x00000000
3868 +#define JCMD_ACC_DR 0x00010000
3869 +#define JCMD_ACC_IR 0x00020000
3870 +#define JCMD_ACC_RESET 0x00030000
3871 +#define JCMD_ACC_IRPDR 0x00040000
3872 +#define JCMD_ACC_PDR 0x00050000
3873 +#define JCMD_IRW_MASK 0x00001f00
3874 +#define JCMD_IRW_SHIFT 8
3875 +#define JCMD_DRW_MASK 0x0000003f
3876 +
3877 +/* jtagctrl */
3878 +#define JCTRL_FORCE_CLK 4 /* Force clock */
3879 +#define JCTRL_EXT_EN 2 /* Enable external targets */
3880 +#define JCTRL_EN 1 /* Enable Jtag master */
3881 +
3882 +/* Fields in clkdiv */
3883 +#define CLKD_SFLASH 0x0f000000
3884 +#define CLKD_SFLASH_SHIFT 24
3885 +#define CLKD_OTP 0x000f0000
3886 +#define CLKD_OTP_SHIFT 16
3887 +#define CLKD_JTAG 0x00000f00
3888 +#define CLKD_JTAG_SHIFT 8
3889 +#define CLKD_UART 0x000000ff
3890 +
3891 +/* intstatus/intmask */
3892 +#define CI_GPIO 0x00000001 /* gpio intr */
3893 +#define CI_EI 0x00000002 /* ro: ext intr pin (corerev >= 3) */
3894 +#define CI_WDRESET 0x80000000 /* watchdog reset occurred */
3895 +
3896 +/* slow_clk_ctl */
3897 +#define SCC_SS_MASK 0x00000007 /* slow clock source mask */
3898 +#define SCC_SS_LPO 0x00000000 /* source of slow clock is LPO */
3899 +#define SCC_SS_XTAL 0x00000001 /* source of slow clock is crystal */
3900 +#define SCC_SS_PCI 0x00000002 /* source of slow clock is PCI */
3901 +#define SCC_LF 0x00000200 /* LPOFreqSel, 1: 160Khz, 0: 32KHz */
3902 +#define SCC_LP 0x00000400 /* LPOPowerDown, 1: LPO is disabled, 0: LPO is enabled */
3903 +#define SCC_FS 0x00000800 /* ForceSlowClk, 1: sb/cores running on slow clock, 0: power logic control */
3904 +#define SCC_IP 0x00001000 /* IgnorePllOffReq, 1/0: power logic ignores/honors PLL clock disable requests from core */
3905 +#define SCC_XC 0x00002000 /* XtalControlEn, 1/0: power logic does/doesn't disable crystal when appropriate */
3906 +#define SCC_XP 0x00004000 /* XtalPU (RO), 1/0: crystal running/disabled */
3907 +#define SCC_CD_MASK 0xffff0000 /* ClockDivider (SlowClk = 1/(4+divisor)) */
3908 +#define SCC_CD_SHIFT 16
3909 +
3910 +/* system_clk_ctl */
3911 +#define SYCC_IE 0x00000001 /* ILPen: Enable Idle Low Power */
3912 +#define SYCC_AE 0x00000002 /* ALPen: Enable Active Low Power */
3913 +#define SYCC_FP 0x00000004 /* ForcePLLOn */
3914 +#define SYCC_AR 0x00000008 /* Force ALP (or HT if ALPen is not set */
3915 +#define SYCC_HR 0x00000010 /* Force HT */
3916 +#define SYCC_CD_MASK 0xffff0000 /* ClkDiv (ILP = 1/(4+divisor)) */
3917 +#define SYCC_CD_SHIFT 16
3918 +
3919 +/* gpiotimerval*/
3920 +#define GPIO_ONTIME_SHIFT 16
3921 +
3922 +/* clockcontrol_n */
3923 +#define CN_N1_MASK 0x3f /* n1 control */
3924 +#define CN_N2_MASK 0x3f00 /* n2 control */
3925 +#define CN_N2_SHIFT 8
3926 +#define CN_PLLC_MASK 0xf0000 /* pll control */
3927 +#define CN_PLLC_SHIFT 16
3928 +
3929 +/* clockcontrol_sb/pci/uart */
3930 +#define CC_M1_MASK 0x3f /* m1 control */
3931 +#define CC_M2_MASK 0x3f00 /* m2 control */
3932 +#define CC_M2_SHIFT 8
3933 +#define CC_M3_MASK 0x3f0000 /* m3 control */
3934 +#define CC_M3_SHIFT 16
3935 +#define CC_MC_MASK 0x1f000000 /* mux control */
3936 +#define CC_MC_SHIFT 24
3937 +
3938 +/* N3M Clock control magic field values */
3939 +#define CC_F6_2 0x02 /* A factor of 2 in */
3940 +#define CC_F6_3 0x03 /* 6-bit fields like */
3941 +#define CC_F6_4 0x05 /* N1, M1 or M3 */
3942 +#define CC_F6_5 0x09
3943 +#define CC_F6_6 0x11
3944 +#define CC_F6_7 0x21
3945 +
3946 +#define CC_F5_BIAS 5 /* 5-bit fields get this added */
3947 +
3948 +#define CC_MC_BYPASS 0x08
3949 +#define CC_MC_M1 0x04
3950 +#define CC_MC_M1M2 0x02
3951 +#define CC_MC_M1M2M3 0x01
3952 +#define CC_MC_M1M3 0x11
3953 +
3954 +/* Type 2 Clock control magic field values */
3955 +#define CC_T2_BIAS 2 /* n1, n2, m1 & m3 bias */
3956 +#define CC_T2M2_BIAS 3 /* m2 bias */
3957 +
3958 +#define CC_T2MC_M1BYP 1
3959 +#define CC_T2MC_M2BYP 2
3960 +#define CC_T2MC_M3BYP 4
3961 +
3962 +/* Type 6 Clock control magic field values */
3963 +#define CC_T6_MMASK 1 /* bits of interest in m */
3964 +#define CC_T6_M0 120000000 /* sb clock for m = 0 */
3965 +#define CC_T6_M1 100000000 /* sb clock for m = 1 */
3966 +#define SB2MIPS_T6(sb) (2 * (sb))
3967 +
3968 +/* Common clock base */
3969 +#define CC_CLOCK_BASE1 24000000 /* Half the clock freq */
3970 +#define CC_CLOCK_BASE2 12500000 /* Alternate crystal on some PLL's */
3971 +
3972 +/* Clock control values for 200Mhz in 5350 */
3973 +#define CLKC_5350_N 0x0311
3974 +#define CLKC_5350_M 0x04020009
3975 +
3976 +/* Flash types in the chipcommon capabilities register */
3977 +#define FLASH_NONE 0x000 /* No flash */
3978 +#define SFLASH_ST 0x100 /* ST serial flash */
3979 +#define SFLASH_AT 0x200 /* Atmel serial flash */
3980 +#define PFLASH 0x700 /* Parallel flash */
3981 +
3982 +/* Bits in the config registers */
3983 +#define CC_CFG_EN 0x0001 /* Enable */
3984 +#define CC_CFG_EM_MASK 0x000e /* Extif Mode */
3985 +#define CC_CFG_EM_ASYNC 0x0002 /* Async/Parallel flash */
3986 +#define CC_CFG_EM_SYNC 0x0004 /* Synchronous */
3987 +#define CC_CFG_EM_PCMCIA 0x0008 /* PCMCIA */
3988 +#define CC_CFG_EM_IDE 0x000a /* IDE */
3989 +#define CC_CFG_DS 0x0010 /* Data size, 0=8bit, 1=16bit */
3990 +#define CC_CFG_CD_MASK 0x0060 /* Sync: Clock divisor */
3991 +#define CC_CFG_CE 0x0080 /* Sync: Clock enable */
3992 +#define CC_CFG_SB 0x0100 /* Sync: Size/Bytestrobe */
3993 +
3994 +/* Start/busy bit in flashcontrol */
3995 +#define SFLASH_START 0x80000000
3996 +#define SFLASH_BUSY SFLASH_START
3997 +
3998 +/* flashcontrol opcodes for ST flashes */
3999 +#define SFLASH_ST_WREN 0x0006 /* Write Enable */
4000 +#define SFLASH_ST_WRDIS 0x0004 /* Write Disable */
4001 +#define SFLASH_ST_RDSR 0x0105 /* Read Status Register */
4002 +#define SFLASH_ST_WRSR 0x0101 /* Write Status Register */
4003 +#define SFLASH_ST_READ 0x0303 /* Read Data Bytes */
4004 +#define SFLASH_ST_PP 0x0302 /* Page Program */
4005 +#define SFLASH_ST_SE 0x02d8 /* Sector Erase */
4006 +#define SFLASH_ST_BE 0x00c7 /* Bulk Erase */
4007 +#define SFLASH_ST_DP 0x00b9 /* Deep Power-down */
4008 +#define SFLASH_ST_RES 0x03ab /* Read Electronic Signature */
4009 +
4010 +/* Status register bits for ST flashes */
4011 +#define SFLASH_ST_WIP 0x01 /* Write In Progress */
4012 +#define SFLASH_ST_WEL 0x02 /* Write Enable Latch */
4013 +#define SFLASH_ST_BP_MASK 0x1c /* Block Protect */
4014 +#define SFLASH_ST_BP_SHIFT 2
4015 +#define SFLASH_ST_SRWD 0x80 /* Status Register Write Disable */
4016 +
4017 +/* flashcontrol opcodes for Atmel flashes */
4018 +#define SFLASH_AT_READ 0x07e8
4019 +#define SFLASH_AT_PAGE_READ 0x07d2
4020 +#define SFLASH_AT_BUF1_READ
4021 +#define SFLASH_AT_BUF2_READ
4022 +#define SFLASH_AT_STATUS 0x01d7
4023 +#define SFLASH_AT_BUF1_WRITE 0x0384
4024 +#define SFLASH_AT_BUF2_WRITE 0x0387
4025 +#define SFLASH_AT_BUF1_ERASE_PROGRAM 0x0283
4026 +#define SFLASH_AT_BUF2_ERASE_PROGRAM 0x0286
4027 +#define SFLASH_AT_BUF1_PROGRAM 0x0288
4028 +#define SFLASH_AT_BUF2_PROGRAM 0x0289
4029 +#define SFLASH_AT_PAGE_ERASE 0x0281
4030 +#define SFLASH_AT_BLOCK_ERASE 0x0250
4031 +#define SFLASH_AT_BUF1_WRITE_ERASE_PROGRAM 0x0382
4032 +#define SFLASH_AT_BUF2_WRITE_ERASE_PROGRAM 0x0385
4033 +#define SFLASH_AT_BUF1_LOAD 0x0253
4034 +#define SFLASH_AT_BUF2_LOAD 0x0255
4035 +#define SFLASH_AT_BUF1_COMPARE 0x0260
4036 +#define SFLASH_AT_BUF2_COMPARE 0x0261
4037 +#define SFLASH_AT_BUF1_REPROGRAM 0x0258
4038 +#define SFLASH_AT_BUF2_REPROGRAM 0x0259
4039 +
4040 +/* Status register bits for Atmel flashes */
4041 +#define SFLASH_AT_READY 0x80
4042 +#define SFLASH_AT_MISMATCH 0x40
4043 +#define SFLASH_AT_ID_MASK 0x38
4044 +#define SFLASH_AT_ID_SHIFT 3
4045 +
4046 +/* OTP regions */
4047 +#define OTP_HW_REGION OTPS_HW_PROTECT
4048 +#define OTP_SW_REGION OTPS_SW_PROTECT
4049 +#define OTP_CID_REGION OTPS_CID_PROTECT
4050 +
4051 +/* OTP regions (Byte offsets from otp size) */
4052 +#define OTP_SWLIM_OFF (-8)
4053 +#define OTP_CIDBASE_OFF 0
4054 +#define OTP_CIDLIM_OFF 8
4055 +
4056 +/* Predefined OTP words (Word offset from otp size) */
4057 +#define OTP_BOUNDARY_OFF (-4)
4058 +#define OTP_HWSIGN_OFF (-3)
4059 +#define OTP_SWSIGN_OFF (-2)
4060 +#define OTP_CIDSIGN_OFF (-1)
4061 +
4062 +#define OTP_CID_OFF 0
4063 +#define OTP_PKG_OFF 1
4064 +#define OTP_FID_OFF 2
4065 +#define OTP_RSV_OFF 3
4066 +#define OTP_LIM_OFF 4
4067 +
4068 +#define OTP_SIGNATURE 0x578a
4069 +#define OTP_MAGIC 0x4e56
4070 +
4071 +#endif /* _SBCHIPC_H */
4072 diff -Nur linux-2.4.32/arch/mips/bcm947xx/include/sbconfig.h linux-2.4.32-brcm/arch/mips/bcm947xx/include/sbconfig.h
4073 --- linux-2.4.32/arch/mips/bcm947xx/include/sbconfig.h 1970-01-01 01:00:00.000000000 +0100
4074 +++ linux-2.4.32-brcm/arch/mips/bcm947xx/include/sbconfig.h 2005-12-16 23:39:10.932836000 +0100
4075 @@ -0,0 +1,342 @@
4076 +/*
4077 + * Broadcom SiliconBackplane hardware register definitions.
4078 + *
4079 + * Copyright 2005, Broadcom Corporation
4080 + * All Rights Reserved.
4081 + *
4082 + * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY
4083 + * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM
4084 + * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS
4085 + * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE.
4086 + * $Id$
4087 + */
4088 +
4089 +#ifndef _SBCONFIG_H
4090 +#define _SBCONFIG_H
4091 +
4092 +/* cpp contortions to concatenate w/arg prescan */
4093 +#ifndef PAD
4094 +#define _PADLINE(line) pad ## line
4095 +#define _XSTR(line) _PADLINE(line)
4096 +#define PAD _XSTR(__LINE__)
4097 +#endif
4098 +
4099 +/*
4100 + * SiliconBackplane Address Map.
4101 + * All regions may not exist on all chips.
4102 + */
4103 +#define SB_SDRAM_BASE 0x00000000 /* Physical SDRAM */
4104 +#define SB_PCI_MEM 0x08000000 /* Host Mode sb2pcitranslation0 (64 MB) */
4105 +#define SB_PCI_CFG 0x0c000000 /* Host Mode sb2pcitranslation1 (64 MB) */
4106 +#define SB_SDRAM_SWAPPED 0x10000000 /* Byteswapped Physical SDRAM */
4107 +#define SB_ENUM_BASE 0x18000000 /* Enumeration space base */
4108 +#define SB_ENUM_LIM 0x18010000 /* Enumeration space limit */
4109 +
4110 +#define SB_FLASH2 0x1c000000 /* Flash Region 2 (region 1 shadowed here) */
4111 +#define SB_FLASH2_SZ 0x02000000 /* Size of Flash Region 2 */
4112 +
4113 +#define SB_EXTIF_BASE 0x1f000000 /* External Interface region base address */
4114 +#define SB_FLASH1 0x1fc00000 /* Flash Region 1 */
4115 +#define SB_FLASH1_SZ 0x00400000 /* Size of Flash Region 1 */
4116 +
4117 +#define SB_PCI_DMA 0x40000000 /* Client Mode sb2pcitranslation2 (1 GB) */
4118 +#define SB_PCI_DMA_SZ 0x40000000 /* Client Mode sb2pcitranslation2 size in bytes */
4119 +#define SB_PCIE_DMA_L32 0x00000000 /* PCIE Client Mode sb2pcitranslation2 (2 ZettaBytes), low 32 bits */
4120 +#define SB_PCIE_DMA_H32 0x80000000 /* PCIE Client Mode sb2pcitranslation2 (2 ZettaBytes), high 32 bits */
4121 +#define SB_EUART (SB_EXTIF_BASE + 0x00800000)
4122 +#define SB_LED (SB_EXTIF_BASE + 0x00900000)
4123 +
4124 +
4125 +/* enumeration space related defs */
4126 +#define SB_CORE_SIZE 0x1000 /* each core gets 4Kbytes for registers */
4127 +#define SB_MAXCORES ((SB_ENUM_LIM - SB_ENUM_BASE)/SB_CORE_SIZE)
4128 +#define SBCONFIGOFF 0xf00 /* core sbconfig regs are top 256bytes of regs */
4129 +#define SBCONFIGSIZE 256 /* sizeof (sbconfig_t) */
4130 +
4131 +/* mips address */
4132 +#define SB_EJTAG 0xff200000 /* MIPS EJTAG space (2M) */
4133 +
4134 +/*
4135 + * Sonics Configuration Space Registers.
4136 + */
4137 +#define SBIPSFLAG 0x08
4138 +#define SBTPSFLAG 0x18
4139 +#define SBTMERRLOGA 0x48 /* sonics >= 2.3 */
4140 +#define SBTMERRLOG 0x50 /* sonics >= 2.3 */
4141 +#define SBADMATCH3 0x60
4142 +#define SBADMATCH2 0x68
4143 +#define SBADMATCH1 0x70
4144 +#define SBIMSTATE 0x90
4145 +#define SBINTVEC 0x94
4146 +#define SBTMSTATELOW 0x98
4147 +#define SBTMSTATEHIGH 0x9c
4148 +#define SBBWA0 0xa0
4149 +#define SBIMCONFIGLOW 0xa8
4150 +#define SBIMCONFIGHIGH 0xac
4151 +#define SBADMATCH0 0xb0
4152 +#define SBTMCONFIGLOW 0xb8
4153 +#define SBTMCONFIGHIGH 0xbc
4154 +#define SBBCONFIG 0xc0
4155 +#define SBBSTATE 0xc8
4156 +#define SBACTCNFG 0xd8
4157 +#define SBFLAGST 0xe8
4158 +#define SBIDLOW 0xf8
4159 +#define SBIDHIGH 0xfc
4160 +
4161 +#ifndef _LANGUAGE_ASSEMBLY
4162 +
4163 +typedef volatile struct _sbconfig {
4164 + uint32 PAD[2];
4165 + uint32 sbipsflag; /* initiator port ocp slave flag */
4166 + uint32 PAD[3];
4167 + uint32 sbtpsflag; /* target port ocp slave flag */
4168 + uint32 PAD[11];
4169 + uint32 sbtmerrloga; /* (sonics >= 2.3) */
4170 + uint32 PAD;
4171 + uint32 sbtmerrlog; /* (sonics >= 2.3) */
4172 + uint32 PAD[3];
4173 + uint32 sbadmatch3; /* address match3 */
4174 + uint32 PAD;
4175 + uint32 sbadmatch2; /* address match2 */
4176 + uint32 PAD;
4177 + uint32 sbadmatch1; /* address match1 */
4178 + uint32 PAD[7];
4179 + uint32 sbimstate; /* initiator agent state */
4180 + uint32 sbintvec; /* interrupt mask */
4181 + uint32 sbtmstatelow; /* target state */
4182 + uint32 sbtmstatehigh; /* target state */
4183 + uint32 sbbwa0; /* bandwidth allocation table0 */
4184 + uint32 PAD;
4185 + uint32 sbimconfiglow; /* initiator configuration */
4186 + uint32 sbimconfighigh; /* initiator configuration */
4187 + uint32 sbadmatch0; /* address match0 */
4188 + uint32 PAD;
4189 + uint32 sbtmconfiglow; /* target configuration */
4190 + uint32 sbtmconfighigh; /* target configuration */
4191 + uint32 sbbconfig; /* broadcast configuration */
4192 + uint32 PAD;
4193 + uint32 sbbstate; /* broadcast state */
4194 + uint32 PAD[3];
4195 + uint32 sbactcnfg; /* activate configuration */
4196 + uint32 PAD[3];
4197 + uint32 sbflagst; /* current sbflags */
4198 + uint32 PAD[3];
4199 + uint32 sbidlow; /* identification */
4200 + uint32 sbidhigh; /* identification */
4201 +} sbconfig_t;
4202 +
4203 +#endif /* _LANGUAGE_ASSEMBLY */
4204 +
4205 +/* sbipsflag */
4206 +#define SBIPS_INT1_MASK 0x3f /* which sbflags get routed to mips interrupt 1 */
4207 +#define SBIPS_INT1_SHIFT 0
4208 +#define SBIPS_INT2_MASK 0x3f00 /* which sbflags get routed to mips interrupt 2 */
4209 +#define SBIPS_INT2_SHIFT 8
4210 +#define SBIPS_INT3_MASK 0x3f0000 /* which sbflags get routed to mips interrupt 3 */
4211 +#define SBIPS_INT3_SHIFT 16
4212 +#define SBIPS_INT4_MASK 0x3f000000 /* which sbflags get routed to mips interrupt 4 */
4213 +#define SBIPS_INT4_SHIFT 24
4214 +
4215 +/* sbtpsflag */
4216 +#define SBTPS_NUM0_MASK 0x3f /* interrupt sbFlag # generated by this core */
4217 +#define SBTPS_F0EN0 0x40 /* interrupt is always sent on the backplane */
4218 +
4219 +/* sbtmerrlog */
4220 +#define SBTMEL_CM 0x00000007 /* command */
4221 +#define SBTMEL_CI 0x0000ff00 /* connection id */
4222 +#define SBTMEL_EC 0x0f000000 /* error code */
4223 +#define SBTMEL_ME 0x80000000 /* multiple error */
4224 +
4225 +/* sbimstate */
4226 +#define SBIM_PC 0xf /* pipecount */
4227 +#define SBIM_AP_MASK 0x30 /* arbitration policy */
4228 +#define SBIM_AP_BOTH 0x00 /* use both timeslaces and token */
4229 +#define SBIM_AP_TS 0x10 /* use timesliaces only */
4230 +#define SBIM_AP_TK 0x20 /* use token only */
4231 +#define SBIM_AP_RSV 0x30 /* reserved */
4232 +#define SBIM_IBE 0x20000 /* inbanderror */
4233 +#define SBIM_TO 0x40000 /* timeout */
4234 +#define SBIM_BY 0x01800000 /* busy (sonics >= 2.3) */
4235 +#define SBIM_RJ 0x02000000 /* reject (sonics >= 2.3) */
4236 +
4237 +/* sbtmstatelow */
4238 +#define SBTML_RESET 0x1 /* reset */
4239 +#define SBTML_REJ_MASK 0x6 /* reject */
4240 +#define SBTML_REJ_SHIFT 1
4241 +#define SBTML_CLK 0x10000 /* clock enable */
4242 +#define SBTML_FGC 0x20000 /* force gated clocks on */
4243 +#define SBTML_FL_MASK 0x3ffc0000 /* core-specific flags */
4244 +#define SBTML_PE 0x40000000 /* pme enable */
4245 +#define SBTML_BE 0x80000000 /* bist enable */
4246 +
4247 +/* sbtmstatehigh */
4248 +#define SBTMH_SERR 0x1 /* serror */
4249 +#define SBTMH_INT 0x2 /* interrupt */
4250 +#define SBTMH_BUSY 0x4 /* busy */
4251 +#define SBTMH_TO 0x00000020 /* timeout (sonics >= 2.3) */
4252 +#define SBTMH_FL_MASK 0x1fff0000 /* core-specific flags */
4253 +#define SBTMH_DMA64 0x10000000 /* supports DMA with 64-bit addresses */
4254 +#define SBTMH_GCR 0x20000000 /* gated clock request */
4255 +#define SBTMH_BISTF 0x40000000 /* bist failed */
4256 +#define SBTMH_BISTD 0x80000000 /* bist done */
4257 +
4258 +
4259 +/* sbbwa0 */
4260 +#define SBBWA_TAB0_MASK 0xffff /* lookup table 0 */
4261 +#define SBBWA_TAB1_MASK 0xffff /* lookup table 1 */
4262 +#define SBBWA_TAB1_SHIFT 16
4263 +
4264 +/* sbimconfiglow */
4265 +#define SBIMCL_STO_MASK 0x7 /* service timeout */
4266 +#define SBIMCL_RTO_MASK 0x70 /* request timeout */
4267 +#define SBIMCL_RTO_SHIFT 4
4268 +#define SBIMCL_CID_MASK 0xff0000 /* connection id */
4269 +#define SBIMCL_CID_SHIFT 16
4270 +
4271 +/* sbimconfighigh */
4272 +#define SBIMCH_IEM_MASK 0xc /* inband error mode */
4273 +#define SBIMCH_TEM_MASK 0x30 /* timeout error mode */
4274 +#define SBIMCH_TEM_SHIFT 4
4275 +#define SBIMCH_BEM_MASK 0xc0 /* bus error mode */
4276 +#define SBIMCH_BEM_SHIFT 6
4277 +
4278 +/* sbadmatch0 */
4279 +#define SBAM_TYPE_MASK 0x3 /* address type */
4280 +#define SBAM_AD64 0x4 /* reserved */
4281 +#define SBAM_ADINT0_MASK 0xf8 /* type0 size */
4282 +#define SBAM_ADINT0_SHIFT 3
4283 +#define SBAM_ADINT1_MASK 0x1f8 /* type1 size */
4284 +#define SBAM_ADINT1_SHIFT 3
4285 +#define SBAM_ADINT2_MASK 0x1f8 /* type2 size */
4286 +#define SBAM_ADINT2_SHIFT 3
4287 +#define SBAM_ADEN 0x400 /* enable */
4288 +#define SBAM_ADNEG 0x800 /* negative decode */
4289 +#define SBAM_BASE0_MASK 0xffffff00 /* type0 base address */
4290 +#define SBAM_BASE0_SHIFT 8
4291 +#define SBAM_BASE1_MASK 0xfffff000 /* type1 base address for the core */
4292 +#define SBAM_BASE1_SHIFT 12
4293 +#define SBAM_BASE2_MASK 0xffff0000 /* type2 base address for the core */
4294 +#define SBAM_BASE2_SHIFT 16
4295 +
4296 +/* sbtmconfiglow */
4297 +#define SBTMCL_CD_MASK 0xff /* clock divide */
4298 +#define SBTMCL_CO_MASK 0xf800 /* clock offset */
4299 +#define SBTMCL_CO_SHIFT 11
4300 +#define SBTMCL_IF_MASK 0xfc0000 /* interrupt flags */
4301 +#define SBTMCL_IF_SHIFT 18
4302 +#define SBTMCL_IM_MASK 0x3000000 /* interrupt mode */
4303 +#define SBTMCL_IM_SHIFT 24
4304 +
4305 +/* sbtmconfighigh */
4306 +#define SBTMCH_BM_MASK 0x3 /* busy mode */
4307 +#define SBTMCH_RM_MASK 0x3 /* retry mode */
4308 +#define SBTMCH_RM_SHIFT 2
4309 +#define SBTMCH_SM_MASK 0x30 /* stop mode */
4310 +#define SBTMCH_SM_SHIFT 4
4311 +#define SBTMCH_EM_MASK 0x300 /* sb error mode */
4312 +#define SBTMCH_EM_SHIFT 8
4313 +#define SBTMCH_IM_MASK 0xc00 /* int mode */
4314 +#define SBTMCH_IM_SHIFT 10
4315 +
4316 +/* sbbconfig */
4317 +#define SBBC_LAT_MASK 0x3 /* sb latency */
4318 +#define SBBC_MAX0_MASK 0xf0000 /* maxccntr0 */
4319 +#define SBBC_MAX0_SHIFT 16
4320 +#define SBBC_MAX1_MASK 0xf00000 /* maxccntr1 */
4321 +#define SBBC_MAX1_SHIFT 20
4322 +
4323 +/* sbbstate */
4324 +#define SBBS_SRD 0x1 /* st reg disable */
4325 +#define SBBS_HRD 0x2 /* hold reg disable */
4326 +
4327 +/* sbidlow */
4328 +#define SBIDL_CS_MASK 0x3 /* config space */
4329 +#define SBIDL_AR_MASK 0x38 /* # address ranges supported */
4330 +#define SBIDL_AR_SHIFT 3
4331 +#define SBIDL_SYNCH 0x40 /* sync */
4332 +#define SBIDL_INIT 0x80 /* initiator */
4333 +#define SBIDL_MINLAT_MASK 0xf00 /* minimum backplane latency */
4334 +#define SBIDL_MINLAT_SHIFT 8
4335 +#define SBIDL_MAXLAT 0xf000 /* maximum backplane latency */
4336 +#define SBIDL_MAXLAT_SHIFT 12
4337 +#define SBIDL_FIRST 0x10000 /* this initiator is first */
4338 +#define SBIDL_CW_MASK 0xc0000 /* cycle counter width */
4339 +#define SBIDL_CW_SHIFT 18
4340 +#define SBIDL_TP_MASK 0xf00000 /* target ports */
4341 +#define SBIDL_TP_SHIFT 20
4342 +#define SBIDL_IP_MASK 0xf000000 /* initiator ports */
4343 +#define SBIDL_IP_SHIFT 24
4344 +#define SBIDL_RV_MASK 0xf0000000 /* sonics backplane revision code */
4345 +#define SBIDL_RV_SHIFT 28
4346 +#define SBIDL_RV_2_2 0x00000000 /* version 2.2 or earlier */
4347 +#define SBIDL_RV_2_3 0x10000000 /* version 2.3 */
4348 +
4349 +/* sbidhigh */
4350 +#define SBIDH_RC_MASK 0x000f /* revision code */
4351 +#define SBIDH_RCE_MASK 0x7000 /* revision code extension field */
4352 +#define SBIDH_RCE_SHIFT 8
4353 +#define SBCOREREV(sbidh) \
4354 + ((((sbidh) & SBIDH_RCE_MASK) >> SBIDH_RCE_SHIFT) | ((sbidh) & SBIDH_RC_MASK))
4355 +#define SBIDH_CC_MASK 0x8ff0 /* core code */
4356 +#define SBIDH_CC_SHIFT 4
4357 +#define SBIDH_VC_MASK 0xffff0000 /* vendor code */
4358 +#define SBIDH_VC_SHIFT 16
4359 +
4360 +#define SB_COMMIT 0xfd8 /* update buffered registers value */
4361 +
4362 +/* vendor codes */
4363 +#define SB_VEND_BCM 0x4243 /* Broadcom's SB vendor code */
4364 +
4365 +/* core codes */
4366 +#define SB_CC 0x800 /* chipcommon core */
4367 +#define SB_ILINE20 0x801 /* iline20 core */
4368 +#define SB_SDRAM 0x803 /* sdram core */
4369 +#define SB_PCI 0x804 /* pci core */
4370 +#define SB_MIPS 0x805 /* mips core */
4371 +#define SB_ENET 0x806 /* enet mac core */
4372 +#define SB_CODEC 0x807 /* v90 codec core */
4373 +#define SB_USB 0x808 /* usb 1.1 host/device core */
4374 +#define SB_ADSL 0x809 /* ADSL core */
4375 +#define SB_ILINE100 0x80a /* iline100 core */
4376 +#define SB_IPSEC 0x80b /* ipsec core */
4377 +#define SB_PCMCIA 0x80d /* pcmcia core */
4378 +#define SB_SOCRAM 0x80e /* internal memory core */
4379 +#define SB_MEMC 0x80f /* memc sdram core */
4380 +#define SB_EXTIF 0x811 /* external interface core */
4381 +#define SB_D11 0x812 /* 802.11 MAC core */
4382 +#define SB_MIPS33 0x816 /* mips3302 core */
4383 +#define SB_USB11H 0x817 /* usb 1.1 host core */
4384 +#define SB_USB11D 0x818 /* usb 1.1 device core */
4385 +#define SB_USB20H 0x819 /* usb 2.0 host core */
4386 +#define SB_USB20D 0x81a /* usb 2.0 device core */
4387 +#define SB_SDIOH 0x81b /* sdio host core */
4388 +#define SB_ROBO 0x81c /* roboswitch core */
4389 +#define SB_ATA100 0x81d /* parallel ATA core */
4390 +#define SB_SATAXOR 0x81e /* serial ATA & XOR DMA core */
4391 +#define SB_GIGETH 0x81f /* gigabit ethernet core */
4392 +#define SB_PCIE 0x820 /* pci express core */
4393 +#define SB_SRAMC 0x822 /* SRAM controller core */
4394 +#define SB_MINIMAC 0x823 /* MINI MAC/phy core */
4395 +
4396 +#define SB_CC_IDX 0 /* chipc, when present, is always core 0 */
4397 +
4398 +/* Not really related to Silicon Backplane, but a couple of software
4399 + * conventions for the use the flash space:
4400 + */
4401 +
4402 +/* Minumum amount of flash we support */
4403 +#define FLASH_MIN 0x00020000 /* Minimum flash size */
4404 +
4405 +/* A boot/binary may have an embedded block that describes its size */
4406 +#define BISZ_OFFSET 0x3e0 /* At this offset into the binary */
4407 +#define BISZ_MAGIC 0x4249535a /* Marked with this value: 'BISZ' */
4408 +#define BISZ_MAGIC_IDX 0 /* Word 0: magic */
4409 +#define BISZ_TXTST_IDX 1 /* 1: text start */
4410 +#define BISZ_TXTEND_IDX 2 /* 2: text start */
4411 +#define BISZ_DATAST_IDX 3 /* 3: text start */
4412 +#define BISZ_DATAEND_IDX 4 /* 4: text start */
4413 +#define BISZ_BSSST_IDX 5 /* 5: text start */
4414 +#define BISZ_BSSEND_IDX 6 /* 6: text start */
4415 +#define BISZ_SIZE 7 /* descriptor size in 32-bit intergers */
4416 +
4417 +#endif /* _SBCONFIG_H */
4418 diff -Nur linux-2.4.32/arch/mips/bcm947xx/include/sbextif.h linux-2.4.32-brcm/arch/mips/bcm947xx/include/sbextif.h
4419 --- linux-2.4.32/arch/mips/bcm947xx/include/sbextif.h 1970-01-01 01:00:00.000000000 +0100
4420 +++ linux-2.4.32-brcm/arch/mips/bcm947xx/include/sbextif.h 2005-12-16 23:39:10.932836000 +0100
4421 @@ -0,0 +1,242 @@
4422 +/*
4423 + * Hardware-specific External Interface I/O core definitions
4424 + * for the BCM47xx family of SiliconBackplane-based chips.
4425 + *
4426 + * The External Interface core supports a total of three external chip selects
4427 + * supporting external interfaces. One of the external chip selects is
4428 + * used for Flash, one is used for PCMCIA, and the other may be
4429 + * programmed to support either a synchronous interface or an
4430 + * asynchronous interface. The asynchronous interface can be used to
4431 + * support external devices such as UARTs and the BCM2019 Bluetooth
4432 + * baseband processor.
4433 + * The external interface core also contains 2 on-chip 16550 UARTs, clock
4434 + * frequency control, a watchdog interrupt timer, and a GPIO interface.
4435 + *
4436 + * Copyright 2005, Broadcom Corporation
4437 + * All Rights Reserved.
4438 + *
4439 + * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY
4440 + * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM
4441 + * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS
4442 + * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE.
4443 + * $Id$
4444 + */
4445 +
4446 +#ifndef _SBEXTIF_H
4447 +#define _SBEXTIF_H
4448 +
4449 +/* external interface address space */
4450 +#define EXTIF_PCMCIA_MEMBASE(x) (x)
4451 +#define EXTIF_PCMCIA_IOBASE(x) ((x) + 0x100000)
4452 +#define EXTIF_PCMCIA_CFGBASE(x) ((x) + 0x200000)
4453 +#define EXTIF_CFGIF_BASE(x) ((x) + 0x800000)
4454 +#define EXTIF_FLASH_BASE(x) ((x) + 0xc00000)
4455 +
4456 +/* cpp contortions to concatenate w/arg prescan */
4457 +#ifndef PAD
4458 +#define _PADLINE(line) pad ## line
4459 +#define _XSTR(line) _PADLINE(line)
4460 +#define PAD _XSTR(__LINE__)
4461 +#endif /* PAD */
4462 +
4463 +/*
4464 + * The multiple instances of output and output enable registers
4465 + * are present to allow driver software for multiple cores to control
4466 + * gpio outputs without needing to share a single register pair.
4467 + */
4468 +struct gpiouser {
4469 + uint32 out;
4470 + uint32 outen;
4471 +};
4472 +#define NGPIOUSER 5
4473 +
4474 +typedef volatile struct {
4475 + uint32 corecontrol;
4476 + uint32 extstatus;
4477 + uint32 PAD[2];
4478 +
4479 + /* pcmcia control registers */
4480 + uint32 pcmcia_config;
4481 + uint32 pcmcia_memwait;
4482 + uint32 pcmcia_attrwait;
4483 + uint32 pcmcia_iowait;
4484 +
4485 + /* programmable interface control registers */
4486 + uint32 prog_config;
4487 + uint32 prog_waitcount;
4488 +
4489 + /* flash control registers */
4490 + uint32 flash_config;
4491 + uint32 flash_waitcount;
4492 + uint32 PAD[4];
4493 +
4494 + uint32 watchdog;
4495 +
4496 + /* clock control */
4497 + uint32 clockcontrol_n;
4498 + uint32 clockcontrol_sb;
4499 + uint32 clockcontrol_pci;
4500 + uint32 clockcontrol_mii;
4501 + uint32 PAD[3];
4502 +
4503 + /* gpio */
4504 + uint32 gpioin;
4505 + struct gpiouser gpio[NGPIOUSER];
4506 + uint32 PAD;
4507 + uint32 ejtagouten;
4508 + uint32 gpiointpolarity;
4509 + uint32 gpiointmask;
4510 + uint32 PAD[153];
4511 +
4512 + uint8 uartdata;
4513 + uint8 PAD[3];
4514 + uint8 uartimer;
4515 + uint8 PAD[3];
4516 + uint8 uartfcr;
4517 + uint8 PAD[3];
4518 + uint8 uartlcr;
4519 + uint8 PAD[3];
4520 + uint8 uartmcr;
4521 + uint8 PAD[3];
4522 + uint8 uartlsr;
4523 + uint8 PAD[3];
4524 + uint8 uartmsr;
4525 + uint8 PAD[3];
4526 + uint8 uartscratch;
4527 + uint8 PAD[3];
4528 +} extifregs_t;
4529 +
4530 +/* corecontrol */
4531 +#define CC_UE (1 << 0) /* uart enable */
4532 +
4533 +/* extstatus */
4534 +#define ES_EM (1 << 0) /* endian mode (ro) */
4535 +#define ES_EI (1 << 1) /* external interrupt pin (ro) */
4536 +#define ES_GI (1 << 2) /* gpio interrupt pin (ro) */
4537 +
4538 +/* gpio bit mask */
4539 +#define GPIO_BIT0 (1 << 0)
4540 +#define GPIO_BIT1 (1 << 1)
4541 +#define GPIO_BIT2 (1 << 2)
4542 +#define GPIO_BIT3 (1 << 3)
4543 +#define GPIO_BIT4 (1 << 4)
4544 +#define GPIO_BIT5 (1 << 5)
4545 +#define GPIO_BIT6 (1 << 6)
4546 +#define GPIO_BIT7 (1 << 7)
4547 +
4548 +
4549 +/* pcmcia/prog/flash_config */
4550 +#define CF_EN (1 << 0) /* enable */
4551 +#define CF_EM_MASK 0xe /* mode */
4552 +#define CF_EM_SHIFT 1
4553 +#define CF_EM_FLASH 0x0 /* flash/asynchronous mode */
4554 +#define CF_EM_SYNC 0x2 /* synchronous mode */
4555 +#define CF_EM_PCMCIA 0x4 /* pcmcia mode */
4556 +#define CF_DS (1 << 4) /* destsize: 0=8bit, 1=16bit */
4557 +#define CF_BS (1 << 5) /* byteswap */
4558 +#define CF_CD_MASK 0xc0 /* clock divider */
4559 +#define CF_CD_SHIFT 6
4560 +#define CF_CD_DIV2 0x0 /* backplane/2 */
4561 +#define CF_CD_DIV3 0x40 /* backplane/3 */
4562 +#define CF_CD_DIV4 0x80 /* backplane/4 */
4563 +#define CF_CE (1 << 8) /* clock enable */
4564 +#define CF_SB (1 << 9) /* size/bytestrobe (synch only) */
4565 +
4566 +/* pcmcia_memwait */
4567 +#define PM_W0_MASK 0x3f /* waitcount0 */
4568 +#define PM_W1_MASK 0x1f00 /* waitcount1 */
4569 +#define PM_W1_SHIFT 8
4570 +#define PM_W2_MASK 0x1f0000 /* waitcount2 */
4571 +#define PM_W2_SHIFT 16
4572 +#define PM_W3_MASK 0x1f000000 /* waitcount3 */
4573 +#define PM_W3_SHIFT 24
4574 +
4575 +/* pcmcia_attrwait */
4576 +#define PA_W0_MASK 0x3f /* waitcount0 */
4577 +#define PA_W1_MASK 0x1f00 /* waitcount1 */
4578 +#define PA_W1_SHIFT 8
4579 +#define PA_W2_MASK 0x1f0000 /* waitcount2 */
4580 +#define PA_W2_SHIFT 16
4581 +#define PA_W3_MASK 0x1f000000 /* waitcount3 */
4582 +#define PA_W3_SHIFT 24
4583 +
4584 +/* pcmcia_iowait */
4585 +#define PI_W0_MASK 0x3f /* waitcount0 */
4586 +#define PI_W1_MASK 0x1f00 /* waitcount1 */
4587 +#define PI_W1_SHIFT 8
4588 +#define PI_W2_MASK 0x1f0000 /* waitcount2 */
4589 +#define PI_W2_SHIFT 16
4590 +#define PI_W3_MASK 0x1f000000 /* waitcount3 */
4591 +#define PI_W3_SHIFT 24
4592 +
4593 +/* prog_waitcount */
4594 +#define PW_W0_MASK 0x0000001f /* waitcount0 */
4595 +#define PW_W1_MASK 0x00001f00 /* waitcount1 */
4596 +#define PW_W1_SHIFT 8
4597 +#define PW_W2_MASK 0x001f0000 /* waitcount2 */
4598 +#define PW_W2_SHIFT 16
4599 +#define PW_W3_MASK 0x1f000000 /* waitcount3 */
4600 +#define PW_W3_SHIFT 24
4601 +
4602 +#define PW_W0 0x0000000c
4603 +#define PW_W1 0x00000a00
4604 +#define PW_W2 0x00020000
4605 +#define PW_W3 0x01000000
4606 +
4607 +/* flash_waitcount */
4608 +#define FW_W0_MASK 0x1f /* waitcount0 */
4609 +#define FW_W1_MASK 0x1f00 /* waitcount1 */
4610 +#define FW_W1_SHIFT 8
4611 +#define FW_W2_MASK 0x1f0000 /* waitcount2 */
4612 +#define FW_W2_SHIFT 16
4613 +#define FW_W3_MASK 0x1f000000 /* waitcount3 */
4614 +#define FW_W3_SHIFT 24
4615 +
4616 +/* watchdog */
4617 +#define WATCHDOG_CLOCK 48000000 /* Hz */
4618 +
4619 +/* clockcontrol_n */
4620 +#define CN_N1_MASK 0x3f /* n1 control */
4621 +#define CN_N2_MASK 0x3f00 /* n2 control */
4622 +#define CN_N2_SHIFT 8
4623 +
4624 +/* clockcontrol_sb/pci/mii */
4625 +#define CC_M1_MASK 0x3f /* m1 control */
4626 +#define CC_M2_MASK 0x3f00 /* m2 control */
4627 +#define CC_M2_SHIFT 8
4628 +#define CC_M3_MASK 0x3f0000 /* m3 control */
4629 +#define CC_M3_SHIFT 16
4630 +#define CC_MC_MASK 0x1f000000 /* mux control */
4631 +#define CC_MC_SHIFT 24
4632 +
4633 +/* Clock control default values */
4634 +#define CC_DEF_N 0x0009 /* Default values for bcm4710 */
4635 +#define CC_DEF_100 0x04020011
4636 +#define CC_DEF_33 0x11030011
4637 +#define CC_DEF_25 0x11050011
4638 +
4639 +/* Clock control values for 125Mhz */
4640 +#define CC_125_N 0x0802
4641 +#define CC_125_M 0x04020009
4642 +#define CC_125_M25 0x11090009
4643 +#define CC_125_M33 0x11090005
4644 +
4645 +/* Clock control magic field values */
4646 +#define CC_F6_2 0x02 /* A factor of 2 in */
4647 +#define CC_F6_3 0x03 /* 6-bit fields like */
4648 +#define CC_F6_4 0x05 /* N1, M1 or M3 */
4649 +#define CC_F6_5 0x09
4650 +#define CC_F6_6 0x11
4651 +#define CC_F6_7 0x21
4652 +
4653 +#define CC_F5_BIAS 5 /* 5-bit fields get this added */
4654 +
4655 +#define CC_MC_BYPASS 0x08
4656 +#define CC_MC_M1 0x04
4657 +#define CC_MC_M1M2 0x02
4658 +#define CC_MC_M1M2M3 0x01
4659 +#define CC_MC_M1M3 0x11
4660 +
4661 +#define CC_CLOCK_BASE 24000000 /* Half the clock freq. in the 4710 */
4662 +
4663 +#endif /* _SBEXTIF_H */
4664 diff -Nur linux-2.4.32/arch/mips/bcm947xx/include/sbhnddma.h linux-2.4.32-brcm/arch/mips/bcm947xx/include/sbhnddma.h
4665 --- linux-2.4.32/arch/mips/bcm947xx/include/sbhnddma.h 1970-01-01 01:00:00.000000000 +0100
4666 +++ linux-2.4.32-brcm/arch/mips/bcm947xx/include/sbhnddma.h 2005-12-16 23:39:10.932836000 +0100
4667 @@ -0,0 +1,312 @@
4668 +/*
4669 + * Generic Broadcom Home Networking Division (HND) DMA engine HW interface
4670 + * This supports the following chips: BCM42xx, 44xx, 47xx .
4671 + *
4672 + * Copyright 2005, Broadcom Corporation
4673 + * All Rights Reserved.
4674 + *
4675 + * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY
4676 + * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM
4677 + * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS
4678 + * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE.
4679 + * $Id$
4680 + */
4681 +
4682 +#ifndef _sbhnddma_h_
4683 +#define _sbhnddma_h_
4684 +
4685 +
4686 +/* 2byte-wide pio register set per channel(xmt or rcv) */
4687 +typedef volatile struct {
4688 + uint16 fifocontrol;
4689 + uint16 fifodata;
4690 + uint16 fifofree; /* only valid in xmt channel, not in rcv channel */
4691 + uint16 PAD;
4692 +} pio2regs_t;
4693 +
4694 +/* a pair of pio channels(tx and rx) */
4695 +typedef volatile struct {
4696 + pio2regs_t tx;
4697 + pio2regs_t rx;
4698 +} pio2regp_t;
4699 +
4700 +/* 4byte-wide pio register set per channel(xmt or rcv) */
4701 +typedef volatile struct {
4702 + uint32 fifocontrol;
4703 + uint32 fifodata;
4704 +} pio4regs_t;
4705 +
4706 +/* a pair of pio channels(tx and rx) */
4707 +typedef volatile struct {
4708 + pio4regs_t tx;
4709 + pio4regs_t rx;
4710 +} pio4regp_t;
4711 +
4712 +
4713 +
4714 +/* DMA structure:
4715 + * support two DMA engines: 32 bits address or 64 bit addressing
4716 + * basic DMA register set is per channel(transmit or receive)
4717 + * a pair of channels is defined for convenience
4718 + */
4719 +
4720 +
4721 +/*** 32 bits addressing ***/
4722 +
4723 +/* dma registers per channel(xmt or rcv) */
4724 +typedef volatile struct {
4725 + uint32 control; /* enable, et al */
4726 + uint32 addr; /* descriptor ring base address (4K aligned) */
4727 + uint32 ptr; /* last descriptor posted to chip */
4728 + uint32 status; /* current active descriptor, et al */
4729 +} dma32regs_t;
4730 +
4731 +typedef volatile struct {
4732 + dma32regs_t xmt; /* dma tx channel */
4733 + dma32regs_t rcv; /* dma rx channel */
4734 +} dma32regp_t;
4735 +
4736 +typedef volatile struct { /* diag access */
4737 + uint32 fifoaddr; /* diag address */
4738 + uint32 fifodatalow; /* low 32bits of data */
4739 + uint32 fifodatahigh; /* high 32bits of data */
4740 + uint32 pad; /* reserved */
4741 +} dma32diag_t;
4742 +
4743 +/*
4744 + * DMA Descriptor
4745 + * Descriptors are only read by the hardware, never written back.
4746 + */
4747 +typedef volatile struct {
4748 + uint32 ctrl; /* misc control bits & bufcount */
4749 + uint32 addr; /* data buffer address */
4750 +} dma32dd_t;
4751 +
4752 +/*
4753 + * Each descriptor ring must be 4096byte aligned, and fit within a single 4096byte page.
4754 + */
4755 +#define D32MAXRINGSZ 4096
4756 +#define D32RINGALIGN 4096
4757 +#define D32MAXDD (D32MAXRINGSZ / sizeof (dma32dd_t))
4758 +
4759 +/* transmit channel control */
4760 +#define XC_XE ((uint32)1 << 0) /* transmit enable */
4761 +#define XC_SE ((uint32)1 << 1) /* transmit suspend request */
4762 +#define XC_LE ((uint32)1 << 2) /* loopback enable */
4763 +#define XC_FL ((uint32)1 << 4) /* flush request */
4764 +#define XC_AE ((uint32)3 << 16) /* address extension bits */
4765 +#define XC_AE_SHIFT 16
4766 +
4767 +/* transmit descriptor table pointer */
4768 +#define XP_LD_MASK 0xfff /* last valid descriptor */
4769 +
4770 +/* transmit channel status */
4771 +#define XS_CD_MASK 0x0fff /* current descriptor pointer */
4772 +#define XS_XS_MASK 0xf000 /* transmit state */
4773 +#define XS_XS_SHIFT 12
4774 +#define XS_XS_DISABLED 0x0000 /* disabled */
4775 +#define XS_XS_ACTIVE 0x1000 /* active */
4776 +#define XS_XS_IDLE 0x2000 /* idle wait */
4777 +#define XS_XS_STOPPED 0x3000 /* stopped */
4778 +#define XS_XS_SUSP 0x4000 /* suspend pending */
4779 +#define XS_XE_MASK 0xf0000 /* transmit errors */
4780 +#define XS_XE_SHIFT 16
4781 +#define XS_XE_NOERR 0x00000 /* no error */
4782 +#define XS_XE_DPE 0x10000 /* descriptor protocol error */
4783 +#define XS_XE_DFU 0x20000 /* data fifo underrun */
4784 +#define XS_XE_BEBR 0x30000 /* bus error on buffer read */
4785 +#define XS_XE_BEDA 0x40000 /* bus error on descriptor access */
4786 +#define XS_AD_MASK 0xfff00000 /* active descriptor */
4787 +#define XS_AD_SHIFT 20
4788 +
4789 +/* receive channel control */
4790 +#define RC_RE ((uint32)1 << 0) /* receive enable */
4791 +#define RC_RO_MASK 0xfe /* receive frame offset */
4792 +#define RC_RO_SHIFT 1
4793 +#define RC_FM ((uint32)1 << 8) /* direct fifo receive (pio) mode */
4794 +#define RC_AE ((uint32)3 << 16) /* address extension bits */
4795 +#define RC_AE_SHIFT 16
4796 +
4797 +/* receive descriptor table pointer */
4798 +#define RP_LD_MASK 0xfff /* last valid descriptor */
4799 +
4800 +/* receive channel status */
4801 +#define RS_CD_MASK 0x0fff /* current descriptor pointer */
4802 +#define RS_RS_MASK 0xf000 /* receive state */
4803 +#define RS_RS_SHIFT 12
4804 +#define RS_RS_DISABLED 0x0000 /* disabled */
4805 +#define RS_RS_ACTIVE 0x1000 /* active */
4806 +#define RS_RS_IDLE 0x2000 /* idle wait */
4807 +#define RS_RS_STOPPED 0x3000 /* reserved */
4808 +#define RS_RE_MASK 0xf0000 /* receive errors */
4809 +#define RS_RE_SHIFT 16
4810 +#define RS_RE_NOERR 0x00000 /* no error */
4811 +#define RS_RE_DPE 0x10000 /* descriptor protocol error */
4812 +#define RS_RE_DFO 0x20000 /* data fifo overflow */
4813 +#define RS_RE_BEBW 0x30000 /* bus error on buffer write */
4814 +#define RS_RE_BEDA 0x40000 /* bus error on descriptor access */
4815 +#define RS_AD_MASK 0xfff00000 /* active descriptor */
4816 +#define RS_AD_SHIFT 20
4817 +
4818 +/* fifoaddr */
4819 +#define FA_OFF_MASK 0xffff /* offset */
4820 +#define FA_SEL_MASK 0xf0000 /* select */
4821 +#define FA_SEL_SHIFT 16
4822 +#define FA_SEL_XDD 0x00000 /* transmit dma data */
4823 +#define FA_SEL_XDP 0x10000 /* transmit dma pointers */
4824 +#define FA_SEL_RDD 0x40000 /* receive dma data */
4825 +#define FA_SEL_RDP 0x50000 /* receive dma pointers */
4826 +#define FA_SEL_XFD 0x80000 /* transmit fifo data */
4827 +#define FA_SEL_XFP 0x90000 /* transmit fifo pointers */
4828 +#define FA_SEL_RFD 0xc0000 /* receive fifo data */
4829 +#define FA_SEL_RFP 0xd0000 /* receive fifo pointers */
4830 +#define FA_SEL_RSD 0xe0000 /* receive frame status data */
4831 +#define FA_SEL_RSP 0xf0000 /* receive frame status pointers */
4832 +
4833 +/* descriptor control flags */
4834 +#define CTRL_BC_MASK 0x1fff /* buffer byte count */
4835 +#define CTRL_AE ((uint32)3 << 16) /* address extension bits */
4836 +#define CTRL_AE_SHIFT 16
4837 +#define CTRL_EOT ((uint32)1 << 28) /* end of descriptor table */
4838 +#define CTRL_IOC ((uint32)1 << 29) /* interrupt on completion */
4839 +#define CTRL_EOF ((uint32)1 << 30) /* end of frame */
4840 +#define CTRL_SOF ((uint32)1 << 31) /* start of frame */
4841 +
4842 +/* control flags in the range [27:20] are core-specific and not defined here */
4843 +#define CTRL_CORE_MASK 0x0ff00000
4844 +
4845 +/*** 64 bits addressing ***/
4846 +
4847 +/* dma registers per channel(xmt or rcv) */
4848 +typedef volatile struct {
4849 + uint32 control; /* enable, et al */
4850 + uint32 ptr; /* last descriptor posted to chip */
4851 + uint32 addrlow; /* descriptor ring base address low 32-bits (8K aligned) */
4852 + uint32 addrhigh; /* descriptor ring base address bits 63:32 (8K aligned) */
4853 + uint32 status0; /* current descriptor, xmt state */
4854 + uint32 status1; /* active descriptor, xmt error */
4855 +} dma64regs_t;
4856 +
4857 +typedef volatile struct {
4858 + dma64regs_t tx; /* dma64 tx channel */
4859 + dma64regs_t rx; /* dma64 rx channel */
4860 +} dma64regp_t;
4861 +
4862 +typedef volatile struct { /* diag access */
4863 + uint32 fifoaddr; /* diag address */
4864 + uint32 fifodatalow; /* low 32bits of data */
4865 + uint32 fifodatahigh; /* high 32bits of data */
4866 + uint32 pad; /* reserved */
4867 +} dma64diag_t;
4868 +
4869 +/*
4870 + * DMA Descriptor
4871 + * Descriptors are only read by the hardware, never written back.
4872 + */
4873 +typedef volatile struct {
4874 + uint32 ctrl1; /* misc control bits & bufcount */
4875 + uint32 ctrl2; /* buffer count and address extension */
4876 + uint32 addrlow; /* memory address of the first byte of the date buffer, bits 31:0 */
4877 + uint32 addrhigh; /* memory address of the first byte of the date buffer, bits 63:32 */
4878 +} dma64dd_t;
4879 +
4880 +/*
4881 + * Each descriptor ring must be 8kB aligned, and fit within a contiguous 8kB physical addresss.
4882 + */
4883 +#define D64MAXRINGSZ 8192
4884 +#define D64RINGALIGN 8192
4885 +#define D64MAXDD (D64MAXRINGSZ / sizeof (dma64dd_t))
4886 +
4887 +/* transmit channel control */
4888 +#define D64_XC_XE 0x00000001 /* transmit enable */
4889 +#define D64_XC_SE 0x00000002 /* transmit suspend request */
4890 +#define D64_XC_LE 0x00000004 /* loopback enable */
4891 +#define D64_XC_FL 0x00000010 /* flush request */
4892 +#define D64_XC_AE 0x00110000 /* address extension bits */
4893 +#define D64_XC_AE_SHIFT 16
4894 +
4895 +/* transmit descriptor table pointer */
4896 +#define D64_XP_LD_MASK 0x00000fff /* last valid descriptor */
4897 +
4898 +/* transmit channel status */
4899 +#define D64_XS0_CD_MASK 0x00001fff /* current descriptor pointer */
4900 +#define D64_XS0_XS_MASK 0xf0000000 /* transmit state */
4901 +#define D64_XS0_XS_SHIFT 28
4902 +#define D64_XS0_XS_DISABLED 0x00000000 /* disabled */
4903 +#define D64_XS0_XS_ACTIVE 0x10000000 /* active */
4904 +#define D64_XS0_XS_IDLE 0x20000000 /* idle wait */
4905 +#define D64_XS0_XS_STOPPED 0x30000000 /* stopped */
4906 +#define D64_XS0_XS_SUSP 0x40000000 /* suspend pending */
4907 +
4908 +#define D64_XS1_AD_MASK 0x0001ffff /* active descriptor */
4909 +#define D64_XS1_XE_MASK 0xf0000000 /* transmit errors */
4910 +#define D64_XS1_XE_SHIFT 28
4911 +#define D64_XS1_XE_NOERR 0x00000000 /* no error */
4912 +#define D64_XS1_XE_DPE 0x10000000 /* descriptor protocol error */
4913 +#define D64_XS1_XE_DFU 0x20000000 /* data fifo underrun */
4914 +#define D64_XS1_XE_DTE 0x30000000 /* data transfer error */
4915 +#define D64_XS1_XE_DESRE 0x40000000 /* descriptor read error */
4916 +#define D64_XS1_XE_COREE 0x50000000 /* core error */
4917 +
4918 +/* receive channel control */
4919 +#define D64_RC_RE 0x00000001 /* receive enable */
4920 +#define D64_RC_RO_MASK 0x000000fe /* receive frame offset */
4921 +#define D64_RC_RO_SHIFT 1
4922 +#define D64_RC_FM 0x00000100 /* direct fifo receive (pio) mode */
4923 +#define D64_RC_AE 0x00110000 /* address extension bits */
4924 +#define D64_RC_AE_SHIFT 16
4925 +
4926 +/* receive descriptor table pointer */
4927 +#define D64_RP_LD_MASK 0x00000fff /* last valid descriptor */
4928 +
4929 +/* receive channel status */
4930 +#define D64_RS0_CD_MASK 0x00001fff /* current descriptor pointer */
4931 +#define D64_RS0_RS_MASK 0xf0000000 /* receive state */
4932 +#define D64_RS0_RS_SHIFT 28
4933 +#define D64_RS0_RS_DISABLED 0x00000000 /* disabled */
4934 +#define D64_RS0_RS_ACTIVE 0x10000000 /* active */
4935 +#define D64_RS0_RS_IDLE 0x20000000 /* idle wait */
4936 +#define D64_RS0_RS_STOPPED 0x30000000 /* stopped */
4937 +#define D64_RS0_RS_SUSP 0x40000000 /* suspend pending */
4938 +
4939 +#define D64_RS1_AD_MASK 0x0001ffff /* active descriptor */
4940 +#define D64_RS1_RE_MASK 0xf0000000 /* receive errors */
4941 +#define D64_RS1_RE_SHIFT 28
4942 +#define D64_RS1_RE_NOERR 0x00000000 /* no error */
4943 +#define D64_RS1_RE_DPO 0x10000000 /* descriptor protocol error */
4944 +#define D64_RS1_RE_DFU 0x20000000 /* data fifo overflow */
4945 +#define D64_RS1_RE_DTE 0x30000000 /* data transfer error */
4946 +#define D64_RS1_RE_DESRE 0x40000000 /* descriptor read error */
4947 +#define D64_RS1_RE_COREE 0x50000000 /* core error */
4948 +
4949 +/* fifoaddr */
4950 +#define D64_FA_OFF_MASK 0xffff /* offset */
4951 +#define D64_FA_SEL_MASK 0xf0000 /* select */
4952 +#define D64_FA_SEL_SHIFT 16
4953 +#define D64_FA_SEL_XDD 0x00000 /* transmit dma data */
4954 +#define D64_FA_SEL_XDP 0x10000 /* transmit dma pointers */
4955 +#define D64_FA_SEL_RDD 0x40000 /* receive dma data */
4956 +#define D64_FA_SEL_RDP 0x50000 /* receive dma pointers */
4957 +#define D64_FA_SEL_XFD 0x80000 /* transmit fifo data */
4958 +#define D64_FA_SEL_XFP 0x90000 /* transmit fifo pointers */
4959 +#define D64_FA_SEL_RFD 0xc0000 /* receive fifo data */
4960 +#define D64_FA_SEL_RFP 0xd0000 /* receive fifo pointers */
4961 +#define D64_FA_SEL_RSD 0xe0000 /* receive frame status data */
4962 +#define D64_FA_SEL_RSP 0xf0000 /* receive frame status pointers */
4963 +
4964 +/* descriptor control flags 1 */
4965 +#define D64_CTRL1_EOT ((uint32)1 << 28) /* end of descriptor table */
4966 +#define D64_CTRL1_IOC ((uint32)1 << 29) /* interrupt on completion */
4967 +#define D64_CTRL1_EOF ((uint32)1 << 30) /* end of frame */
4968 +#define D64_CTRL1_SOF ((uint32)1 << 31) /* start of frame */
4969 +
4970 +/* descriptor control flags 2 */
4971 +#define D64_CTRL2_BC_MASK 0x00007fff /* buffer byte count mask */
4972 +#define D64_CTRL2_AE 0x00110000 /* address extension bits */
4973 +#define D64_CTRL2_AE_SHIFT 16
4974 +
4975 +/* control flags in the range [27:20] are core-specific and not defined here */
4976 +#define D64_CTRL_CORE_MASK 0x0ff00000
4977 +
4978 +
4979 +#endif /* _sbhnddma_h_ */
4980 diff -Nur linux-2.4.32/arch/mips/bcm947xx/include/sbmemc.h linux-2.4.32-brcm/arch/mips/bcm947xx/include/sbmemc.h
4981 --- linux-2.4.32/arch/mips/bcm947xx/include/sbmemc.h 1970-01-01 01:00:00.000000000 +0100
4982 +++ linux-2.4.32-brcm/arch/mips/bcm947xx/include/sbmemc.h 2005-12-16 23:39:10.932836000 +0100
4983 @@ -0,0 +1,148 @@
4984 +/*
4985 + * BCM47XX Sonics SiliconBackplane DDR/SDRAM controller core hardware definitions.
4986 + *
4987 + * Copyright 2005, Broadcom Corporation
4988 + * All Rights Reserved.
4989 + *
4990 + * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY
4991 + * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM
4992 + * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS
4993 + * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE.
4994 + *
4995 + * $Id$
4996 + */
4997 +
4998 +#ifndef _SBMEMC_H
4999 +#define _SBMEMC_H
5000 +
5001 +#ifdef _LANGUAGE_ASSEMBLY
5002 +
5003 +#define MEMC_CONTROL 0x00
5004 +#define MEMC_CONFIG 0x04
5005 +#define MEMC_REFRESH 0x08
5006 +#define MEMC_BISTSTAT 0x0c
5007 +#define MEMC_MODEBUF 0x10
5008 +#define MEMC_BKCLS 0x14
5009 +#define MEMC_PRIORINV 0x18
5010 +#define MEMC_DRAMTIM 0x1c
5011 +#define MEMC_INTSTAT 0x20
5012 +#define MEMC_INTMASK 0x24
5013 +#define MEMC_INTINFO 0x28
5014 +#define MEMC_NCDLCTL 0x30
5015 +#define MEMC_RDNCDLCOR 0x34
5016 +#define MEMC_WRNCDLCOR 0x38
5017 +#define MEMC_MISCDLYCTL 0x3c
5018 +#define MEMC_DQSGATENCDL 0x40
5019 +#define MEMC_SPARE 0x44
5020 +#define MEMC_TPADDR 0x48
5021 +#define MEMC_TPDATA 0x4c
5022 +#define MEMC_BARRIER 0x50
5023 +#define MEMC_CORE 0x54
5024 +
5025 +
5026 +#else
5027 +
5028 +/* Sonics side: MEMC core registers */
5029 +typedef volatile struct sbmemcregs {
5030 + uint32 control;
5031 + uint32 config;
5032 + uint32 refresh;
5033 + uint32 biststat;
5034 + uint32 modebuf;
5035 + uint32 bkcls;
5036 + uint32 priorinv;
5037 + uint32 dramtim;
5038 + uint32 intstat;
5039 + uint32 intmask;
5040 + uint32 intinfo;
5041 + uint32 reserved1;
5042 + uint32 ncdlctl;
5043 + uint32 rdncdlcor;
5044 + uint32 wrncdlcor;
5045 + uint32 miscdlyctl;
5046 + uint32 dqsgatencdl;
5047 + uint32 spare;
5048 + uint32 tpaddr;
5049 + uint32 tpdata;
5050 + uint32 barrier;
5051 + uint32 core;
5052 +} sbmemcregs_t;
5053 +
5054 +#endif
5055 +
5056 +/* MEMC Core Init values (OCP ID 0x80f) */
5057 +
5058 +/* For sdr: */
5059 +#define MEMC_SD_CONFIG_INIT 0x00048000
5060 +#define MEMC_SD_DRAMTIM2_INIT 0x000754d8
5061 +#define MEMC_SD_DRAMTIM3_INIT 0x000754da
5062 +#define MEMC_SD_RDNCDLCOR_INIT 0x00000000
5063 +#define MEMC_SD_WRNCDLCOR_INIT 0x49351200
5064 +#define MEMC_SD1_WRNCDLCOR_INIT 0x14500200 /* For corerev 1 (4712) */
5065 +#define MEMC_SD_MISCDLYCTL_INIT 0x00061c1b
5066 +#define MEMC_SD1_MISCDLYCTL_INIT 0x00021416 /* For corerev 1 (4712) */
5067 +#define MEMC_SD_CONTROL_INIT0 0x00000002
5068 +#define MEMC_SD_CONTROL_INIT1 0x00000008
5069 +#define MEMC_SD_CONTROL_INIT2 0x00000004
5070 +#define MEMC_SD_CONTROL_INIT3 0x00000010
5071 +#define MEMC_SD_CONTROL_INIT4 0x00000001
5072 +#define MEMC_SD_MODEBUF_INIT 0x00000000
5073 +#define MEMC_SD_REFRESH_INIT 0x0000840f
5074 +
5075 +
5076 +/* This is for SDRM8X8X4 */
5077 +#define MEMC_SDR_INIT 0x0008
5078 +#define MEMC_SDR_MODE 0x32
5079 +#define MEMC_SDR_NCDL 0x00020032
5080 +#define MEMC_SDR1_NCDL 0x0002020f /* For corerev 1 (4712) */
5081 +
5082 +/* For ddr: */
5083 +#define MEMC_CONFIG_INIT 0x00048000
5084 +#define MEMC_DRAMTIM2_INIT 0x000754d8
5085 +#define MEMC_DRAMTIM25_INIT 0x000754d9
5086 +#define MEMC_RDNCDLCOR_INIT 0x00000000
5087 +#define MEMC_RDNCDLCOR_SIMINIT 0xf6f6f6f6 /* For hdl sim */
5088 +#define MEMC_WRNCDLCOR_INIT 0x49351200
5089 +#define MEMC_1_WRNCDLCOR_INIT 0x14500200
5090 +#define MEMC_DQSGATENCDL_INIT 0x00030000
5091 +#define MEMC_MISCDLYCTL_INIT 0x21061c1b
5092 +#define MEMC_1_MISCDLYCTL_INIT 0x21021400
5093 +#define MEMC_NCDLCTL_INIT 0x00002001
5094 +#define MEMC_CONTROL_INIT0 0x00000002
5095 +#define MEMC_CONTROL_INIT1 0x00000008
5096 +#define MEMC_MODEBUF_INIT0 0x00004000
5097 +#define MEMC_CONTROL_INIT2 0x00000010
5098 +#define MEMC_MODEBUF_INIT1 0x00000100
5099 +#define MEMC_CONTROL_INIT3 0x00000010
5100 +#define MEMC_CONTROL_INIT4 0x00000008
5101 +#define MEMC_REFRESH_INIT 0x0000840f
5102 +#define MEMC_CONTROL_INIT5 0x00000004
5103 +#define MEMC_MODEBUF_INIT2 0x00000000
5104 +#define MEMC_CONTROL_INIT6 0x00000010
5105 +#define MEMC_CONTROL_INIT7 0x00000001
5106 +
5107 +
5108 +/* This is for DDRM16X16X2 */
5109 +#define MEMC_DDR_INIT 0x0009
5110 +#define MEMC_DDR_MODE 0x62
5111 +#define MEMC_DDR_NCDL 0x0005050a
5112 +#define MEMC_DDR1_NCDL 0x00000a0a /* For corerev 1 (4712) */
5113 +
5114 +/* mask for sdr/ddr calibration registers */
5115 +#define MEMC_RDNCDLCOR_RD_MASK 0x000000ff
5116 +#define MEMC_WRNCDLCOR_WR_MASK 0x000000ff
5117 +#define MEMC_DQSGATENCDL_G_MASK 0x000000ff
5118 +
5119 +/* masks for miscdlyctl registers */
5120 +#define MEMC_MISC_SM_MASK 0x30000000
5121 +#define MEMC_MISC_SM_SHIFT 28
5122 +#define MEMC_MISC_SD_MASK 0x0f000000
5123 +#define MEMC_MISC_SD_SHIFT 24
5124 +
5125 +/* hw threshhold for calculating wr/rd for sdr memc */
5126 +#define MEMC_CD_THRESHOLD 128
5127 +
5128 +/* Low bit of init register says if memc is ddr or sdr */
5129 +#define MEMC_CONFIG_DDR 0x00000001
5130 +
5131 +#endif /* _SBMEMC_H */
5132 diff -Nur linux-2.4.32/arch/mips/bcm947xx/include/sbmips.h linux-2.4.32-brcm/arch/mips/bcm947xx/include/sbmips.h
5133 --- linux-2.4.32/arch/mips/bcm947xx/include/sbmips.h 1970-01-01 01:00:00.000000000 +0100
5134 +++ linux-2.4.32-brcm/arch/mips/bcm947xx/include/sbmips.h 2005-12-16 23:39:10.936836250 +0100
5135 @@ -0,0 +1,62 @@
5136 +/*
5137 + * Broadcom SiliconBackplane MIPS definitions
5138 + *
5139 + * SB MIPS cores are custom MIPS32 processors with SiliconBackplane
5140 + * OCP interfaces. The CP0 processor ID is 0x00024000, where bits
5141 + * 23:16 mean Broadcom and bits 15:8 mean a MIPS core with an OCP
5142 + * interface. The core revision is stored in the SB ID register in SB
5143 + * configuration space.
5144 + *
5145 + * Copyright 2005, Broadcom Corporation
5146 + * All Rights Reserved.
5147 + *
5148 + * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY
5149 + * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM
5150 + * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS
5151 + * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE.
5152 + *
5153 + * $Id$
5154 + */
5155 +
5156 +#ifndef _SBMIPS_H
5157 +#define _SBMIPS_H
5158 +
5159 +#include <mipsinc.h>
5160 +
5161 +#ifndef _LANGUAGE_ASSEMBLY
5162 +
5163 +/* cpp contortions to concatenate w/arg prescan */
5164 +#ifndef PAD
5165 +#define _PADLINE(line) pad ## line
5166 +#define _XSTR(line) _PADLINE(line)
5167 +#define PAD _XSTR(__LINE__)
5168 +#endif /* PAD */
5169 +
5170 +typedef volatile struct {
5171 + uint32 corecontrol;
5172 + uint32 PAD[2];
5173 + uint32 biststatus;
5174 + uint32 PAD[4];
5175 + uint32 intstatus;
5176 + uint32 intmask;
5177 + uint32 timer;
5178 +} mipsregs_t;
5179 +
5180 +extern uint32 sb_flag(sb_t *sbh);
5181 +extern uint sb_irq(sb_t *sbh);
5182 +
5183 +extern void BCMINIT(sb_serial_init)(sb_t *sbh, void (*add)(void *regs, uint irq, uint baud_base, uint reg_shift));
5184 +
5185 +extern void *sb_jtagm_init(sb_t *sbh, uint clkd, bool exttap);
5186 +extern void sb_jtagm_disable(void *h);
5187 +extern uint32 jtag_rwreg(void *h, uint32 ir, uint32 dr);
5188 +extern void BCMINIT(sb_mips_init)(sb_t *sbh);
5189 +extern uint32 BCMINIT(sb_mips_clock)(sb_t *sbh);
5190 +extern bool BCMINIT(sb_mips_setclock)(sb_t *sbh, uint32 mipsclock, uint32 sbclock, uint32 pciclock);
5191 +extern void BCMINIT(enable_pfc)(uint32 mode);
5192 +extern uint32 BCMINIT(sb_memc_get_ncdl)(sb_t *sbh);
5193 +
5194 +
5195 +#endif /* _LANGUAGE_ASSEMBLY */
5196 +
5197 +#endif /* _SBMIPS_H */
5198 diff -Nur linux-2.4.32/arch/mips/bcm947xx/include/sbpcie.h linux-2.4.32-brcm/arch/mips/bcm947xx/include/sbpcie.h
5199 --- linux-2.4.32/arch/mips/bcm947xx/include/sbpcie.h 1970-01-01 01:00:00.000000000 +0100
5200 +++ linux-2.4.32-brcm/arch/mips/bcm947xx/include/sbpcie.h 2005-12-16 23:39:10.936836250 +0100
5201 @@ -0,0 +1,199 @@
5202 +/*
5203 + * BCM43XX SiliconBackplane PCIE core hardware definitions.
5204 + *
5205 + * $Id:
5206 + * Copyright 2005, Broadcom Corporation
5207 + * All Rights Reserved.
5208 + *
5209 + * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY
5210 + * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM
5211 + * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS
5212 + * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE.
5213 + */
5214 +
5215 +#ifndef _SBPCIE_H
5216 +#define _SBPCIE_H
5217 +
5218 +/* cpp contortions to concatenate w/arg prescan */
5219 +#ifndef PAD
5220 +#define _PADLINE(line) pad ## line
5221 +#define _XSTR(line) _PADLINE(line)
5222 +#define PAD _XSTR(__LINE__)
5223 +#endif
5224 +
5225 +/* PCIE Enumeration space offsets*/
5226 +#define PCIE_CORE_CONFIG_OFFSET 0x0
5227 +#define PCIE_FUNC0_CONFIG_OFFSET 0x400
5228 +#define PCIE_FUNC1_CONFIG_OFFSET 0x500
5229 +#define PCIE_FUNC2_CONFIG_OFFSET 0x600
5230 +#define PCIE_FUNC3_CONFIG_OFFSET 0x700
5231 +#define PCIE_SPROM_SHADOW_OFFSET 0x800
5232 +#define PCIE_SBCONFIG_OFFSET 0xE00
5233 +
5234 +/* PCIE Bar0 Address Mapping. Each function maps 16KB config space */
5235 +#define PCIE_BAR0_WINMAPCORE_OFFSET 0x0
5236 +#define PCIE_BAR0_EXTSPROM_OFFSET 0x1000
5237 +#define PCIE_BAR0_PCIECORE_OFFSET 0x2000
5238 +#define PCIE_BAR0_CCCOREREG_OFFSET 0x3000
5239 +
5240 +/* SB side: PCIE core and host control registers */
5241 +typedef struct sbpcieregs {
5242 +
5243 + uint32 PAD[3];
5244 + uint32 biststatus; /* bist Status: 0x00C*/
5245 + uint32 PAD[6];
5246 + uint32 sbtopcimailbox; /* sb to pcie mailbox: 0x028*/
5247 + uint32 PAD[54];
5248 + uint32 sbtopcie0; /* sb to pcie translation 0: 0x100 */
5249 + uint32 sbtopcie1; /* sb to pcie translation 1: 0x104 */
5250 + uint32 sbtopcie2; /* sb to pcie translation 2: 0x108 */
5251 + uint32 PAD[4];
5252 +
5253 + /* pcie core supports in direct access to config space */
5254 + uint32 configaddr; /* pcie config space access: Address field: 0x120*/
5255 + uint32 configdata; /* pcie config space access: Data field: 0x124*/
5256 +
5257 + /* mdio access to serdes */
5258 + uint32 mdiocontrol; /* controls the mdio access: 0x128 */
5259 + uint32 mdiodata; /* Data to the mdio access: 0x12c */
5260 +
5261 + /* pcie protocol phy/dllp/tlp register access mechanism*/
5262 + uint32 pcieaddr; /* address of the internal registeru: 0x130 */
5263 + uint32 pciedata; /* Data to/from the internal regsiter: 0x134 */
5264 +
5265 + uint32 PAD[434];
5266 + uint16 sprom[36]; /* SPROM shadow Area */
5267 +} sbpcieregs_t;
5268 +
5269 +/* SB to PCIE translation masks */
5270 +#define SBTOPCIE0_MASK 0xfc000000
5271 +#define SBTOPCIE1_MASK 0xfc000000
5272 +#define SBTOPCIE2_MASK 0xc0000000
5273 +
5274 +/* Access type bits (0:1)*/
5275 +#define SBTOPCIE_MEM 0
5276 +#define SBTOPCIE_IO 1
5277 +#define SBTOPCIE_CFG0 2
5278 +#define SBTOPCIE_CFG1 3
5279 +
5280 +/*Prefetch enable bit 2*/
5281 +#define SBTOPCIE_PF 4
5282 +
5283 +/*Write Burst enable for memory write bit 3*/
5284 +#define SBTOPCIE_WR_BURST 8
5285 +
5286 +/* config access */
5287 +#define CONFIGADDR_FUNC_MASK 0x7000
5288 +#define CONFIGADDR_FUNC_SHF 12
5289 +#define CONFIGADDR_REG_MASK 0x0FFF
5290 +#define CONFIGADDR_REG_SHF 0
5291 +
5292 +/* PCIE protocol regs Indirect Address */
5293 +#define PCIEADDR_PROT_MASK 0x300
5294 +#define PCIEADDR_PROT_SHF 8
5295 +#define PCIEADDR_PL_TLP 0
5296 +#define PCIEADDR_PL_DLLP 1
5297 +#define PCIEADDR_PL_PLP 2
5298 +
5299 +/* PCIE protocol PHY diagnostic registers */
5300 +#define PCIE_PLP_MODEREG 0x200 /* Mode*/
5301 +#define PCIE_PLP_STATUSREG 0x204 /* Status*/
5302 +#define PCIE_PLP_LTSSMCTRLREG 0x208 /* LTSSM control */
5303 +#define PCIE_PLP_LTLINKNUMREG 0x20c /* Link Training Link number*/
5304 +#define PCIE_PLP_LTLANENUMREG 0x210 /* Link Training Lane number*/
5305 +#define PCIE_PLP_LTNFTSREG 0x214 /* Link Training N_FTS */
5306 +#define PCIE_PLP_ATTNREG 0x218 /* Attention */
5307 +#define PCIE_PLP_ATTNMASKREG 0x21C /* Attention Mask */
5308 +#define PCIE_PLP_RXERRCTR 0x220 /* Rx Error */
5309 +#define PCIE_PLP_RXFRMERRCTR 0x224 /* Rx Framing Error*/
5310 +#define PCIE_PLP_RXERRTHRESHREG 0x228 /* Rx Error threshold */
5311 +#define PCIE_PLP_TESTCTRLREG 0x22C /* Test Control reg*/
5312 +#define PCIE_PLP_SERDESCTRLOVRDREG 0x230 /* SERDES Control Override */
5313 +#define PCIE_PLP_TIMINGOVRDREG 0x234 /* Timing param override */
5314 +#define PCIE_PLP_RXTXSMDIAGREG 0x238 /* RXTX State Machine Diag*/
5315 +#define PCIE_PLP_LTSSMDIAGREG 0x23C /* LTSSM State Machine Diag*/
5316 +
5317 +/* PCIE protocol DLLP diagnostic registers */
5318 +#define PCIE_DLLP_LCREG 0x100 /* Link Control*/
5319 +#define PCIE_DLLP_LSREG 0x104 /* Link Status */
5320 +#define PCIE_DLLP_LAREG 0x108 /* Link Attention*/
5321 +#define PCIE_DLLP_LAMASKREG 0x10C /* Link Attention Mask */
5322 +#define PCIE_DLLP_NEXTTXSEQNUMREG 0x110 /* Next Tx Seq Num*/
5323 +#define PCIE_DLLP_ACKEDTXSEQNUMREG 0x114 /* Acked Tx Seq Num*/
5324 +#define PCIE_DLLP_PURGEDTXSEQNUMREG 0x118 /* Purged Tx Seq Num*/
5325 +#define PCIE_DLLP_RXSEQNUMREG 0x11C /* Rx Sequence Number */
5326 +#define PCIE_DLLP_LRREG 0x120 /* Link Replay*/
5327 +#define PCIE_DLLP_LACKTOREG 0x124 /* Link Ack Timeout*/
5328 +#define PCIE_DLLP_PMTHRESHREG 0x128 /* Power Management Threshold*/
5329 +#define PCIE_DLLP_RTRYWPREG 0x12C /* Retry buffer write ptr*/
5330 +#define PCIE_DLLP_RTRYRPREG 0x130 /* Retry buffer Read ptr*/
5331 +#define PCIE_DLLP_RTRYPPREG 0x134 /* Retry buffer Purged ptr*/
5332 +#define PCIE_DLLP_RTRRWREG 0x138 /* Retry buffer Read/Write*/
5333 +#define PCIE_DLLP_ECTHRESHREG 0x13C /* Error Count Threshold */
5334 +#define PCIE_DLLP_TLPERRCTRREG 0x140 /* TLP Error Counter */
5335 +#define PCIE_DLLP_ERRCTRREG 0x144 /* Error Counter*/
5336 +#define PCIE_DLLP_NAKRXCTRREG 0x148 /* NAK Received Counter*/
5337 +#define PCIE_DLLP_TESTREG 0x14C /* Test */
5338 +#define PCIE_DLLP_PKTBIST 0x150 /* Packet BIST*/
5339 +
5340 +/* PCIE protocol TLP diagnostic registers */
5341 +#define PCIE_TLP_CONFIGREG 0x000 /* Configuration */
5342 +#define PCIE_TLP_WORKAROUNDSREG 0x004 /* TLP Workarounds */
5343 +#define PCIE_TLP_WRDMAUPPER 0x010 /* Write DMA Upper Address*/
5344 +#define PCIE_TLP_WRDMALOWER 0x014 /* Write DMA Lower Address*/
5345 +#define PCIE_TLP_WRDMAREQ_LBEREG 0x018 /* Write DMA Len/ByteEn Req*/
5346 +#define PCIE_TLP_RDDMAUPPER 0x01C /* Read DMA Upper Address*/
5347 +#define PCIE_TLP_RDDMALOWER 0x020 /* Read DMA Lower Address*/
5348 +#define PCIE_TLP_RDDMALENREG 0x024 /* Read DMA Len Req*/
5349 +#define PCIE_TLP_MSIDMAUPPER 0x028 /* MSI DMA Upper Address*/
5350 +#define PCIE_TLP_MSIDMALOWER 0x02C /* MSI DMA Lower Address*/
5351 +#define PCIE_TLP_MSIDMALENREG 0x030 /* MSI DMA Len Req*/
5352 +#define PCIE_TLP_SLVREQLENREG 0x034 /* Slave Request Len*/
5353 +#define PCIE_TLP_FCINPUTSREQ 0x038 /* Flow Control Inputs*/
5354 +#define PCIE_TLP_TXSMGRSREQ 0x03C /* Tx StateMachine and Gated Req*/
5355 +#define PCIE_TLP_ADRACKCNTARBLEN 0x040 /* Address Ack XferCnt and ARB Len*/
5356 +#define PCIE_TLP_DMACPLHDR0 0x044 /* DMA Completion Hdr 0*/
5357 +#define PCIE_TLP_DMACPLHDR1 0x048 /* DMA Completion Hdr 1*/
5358 +#define PCIE_TLP_DMACPLHDR2 0x04C /* DMA Completion Hdr 2*/
5359 +#define PCIE_TLP_DMACPLMISC0 0x050 /* DMA Completion Misc0 */
5360 +#define PCIE_TLP_DMACPLMISC1 0x054 /* DMA Completion Misc1 */
5361 +#define PCIE_TLP_DMACPLMISC2 0x058 /* DMA Completion Misc2 */
5362 +#define PCIE_TLP_SPTCTRLLEN 0x05C /* Split Controller Req len*/
5363 +#define PCIE_TLP_SPTCTRLMSIC0 0x060 /* Split Controller Misc 0*/
5364 +#define PCIE_TLP_SPTCTRLMSIC1 0x064 /* Split Controller Misc 1*/
5365 +#define PCIE_TLP_BUSDEVFUNC 0x068 /* Bus/Device/Func*/
5366 +#define PCIE_TLP_RESETCTR 0x06C /* Reset Counter*/
5367 +#define PCIE_TLP_RTRYBUF 0x070 /* Retry Buffer value*/
5368 +#define PCIE_TLP_TGTDEBUG1 0x074 /* Target Debug Reg1*/
5369 +#define PCIE_TLP_TGTDEBUG2 0x078 /* Target Debug Reg2*/
5370 +#define PCIE_TLP_TGTDEBUG3 0x07C /* Target Debug Reg3*/
5371 +#define PCIE_TLP_TGTDEBUG4 0x080 /* Target Debug Reg4*/
5372 +
5373 +/* MDIO control */
5374 +#define MDIOCTL_DIVISOR_MASK 0x7f /* clock to be used on MDIO */
5375 +#define MDIOCTL_DIVISOR_VAL 0x2
5376 +#define MDIOCTL_PREAM_EN 0x80 /* Enable preamble sequnce */
5377 +#define MDIOCTL_ACCESS_DONE 0x100 /* Tranaction complete */
5378 +
5379 +/* MDIO Data */
5380 +#define MDIODATA_MASK 0x0000ffff /* data 2 bytes */
5381 +#define MDIODATA_TA 0x00020000 /* Turnaround */
5382 +#define MDIODATA_REGADDR_SHF 18 /* Regaddr shift */
5383 +#define MDIODATA_REGADDR_MASK 0x003c0000 /* Regaddr Mask */
5384 +#define MDIODATA_DEVADDR_SHF 22 /* Physmedia devaddr shift */
5385 +#define MDIODATA_DEVADDR_MASK 0x0fc00000 /* Physmedia devaddr Mask */
5386 +#define MDIODATA_WRITE 0x10000000 /* write Transaction */
5387 +#define MDIODATA_READ 0x20000000 /* Read Transaction */
5388 +#define MDIODATA_START 0x40000000 /* start of Transaction */
5389 +
5390 +/* MDIO devices (SERDES modules) */
5391 +#define MDIODATA_DEV_PLL 0x1d /* SERDES PLL Dev */
5392 +#define MDIODATA_DEV_TX 0x1e /* SERDES TX Dev */
5393 +#define MDIODATA_DEV_RX 0x1f /* SERDES RX Dev */
5394 +
5395 +/* SERDES registers */
5396 +#define SERDES_RX_TIMER1 2 /* Rx Timer1 */
5397 +#define SERDES_RX_CDR 6 /* CDR */
5398 +#define SERDES_RX_CDRBW 7 /* CDR BW */
5399 +
5400 +#endif /* _SBPCIE_H */
5401 diff -Nur linux-2.4.32/arch/mips/bcm947xx/include/sbpci.h linux-2.4.32-brcm/arch/mips/bcm947xx/include/sbpci.h
5402 --- linux-2.4.32/arch/mips/bcm947xx/include/sbpci.h 1970-01-01 01:00:00.000000000 +0100
5403 +++ linux-2.4.32-brcm/arch/mips/bcm947xx/include/sbpci.h 2005-12-16 23:39:10.936836250 +0100
5404 @@ -0,0 +1,122 @@
5405 +/*
5406 + * BCM47XX Sonics SiliconBackplane PCI core hardware definitions.
5407 + *
5408 + * $Id$
5409 + * Copyright 2005, Broadcom Corporation
5410 + * All Rights Reserved.
5411 + *
5412 + * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY
5413 + * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM
5414 + * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS
5415 + * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE.
5416 + */
5417 +
5418 +#ifndef _SBPCI_H
5419 +#define _SBPCI_H
5420 +
5421 +/* cpp contortions to concatenate w/arg prescan */
5422 +#ifndef PAD
5423 +#define _PADLINE(line) pad ## line
5424 +#define _XSTR(line) _PADLINE(line)
5425 +#define PAD _XSTR(__LINE__)
5426 +#endif
5427 +
5428 +/* Sonics side: PCI core and host control registers */
5429 +typedef struct sbpciregs {
5430 + uint32 control; /* PCI control */
5431 + uint32 PAD[3];
5432 + uint32 arbcontrol; /* PCI arbiter control */
5433 + uint32 PAD[3];
5434 + uint32 intstatus; /* Interrupt status */
5435 + uint32 intmask; /* Interrupt mask */
5436 + uint32 sbtopcimailbox; /* Sonics to PCI mailbox */
5437 + uint32 PAD[9];
5438 + uint32 bcastaddr; /* Sonics broadcast address */
5439 + uint32 bcastdata; /* Sonics broadcast data */
5440 + uint32 PAD[2];
5441 + uint32 gpioin; /* ro: gpio input (>=rev2) */
5442 + uint32 gpioout; /* rw: gpio output (>=rev2) */
5443 + uint32 gpioouten; /* rw: gpio output enable (>= rev2) */
5444 + uint32 gpiocontrol; /* rw: gpio control (>= rev2) */
5445 + uint32 PAD[36];
5446 + uint32 sbtopci0; /* Sonics to PCI translation 0 */
5447 + uint32 sbtopci1; /* Sonics to PCI translation 1 */
5448 + uint32 sbtopci2; /* Sonics to PCI translation 2 */
5449 + uint32 PAD[445];
5450 + uint16 sprom[36]; /* SPROM shadow Area */
5451 + uint32 PAD[46];
5452 +} sbpciregs_t;
5453 +
5454 +/* PCI control */
5455 +#define PCI_RST_OE 0x01 /* When set, drives PCI_RESET out to pin */
5456 +#define PCI_RST 0x02 /* Value driven out to pin */
5457 +#define PCI_CLK_OE 0x04 /* When set, drives clock as gated by PCI_CLK out to pin */
5458 +#define PCI_CLK 0x08 /* Gate for clock driven out to pin */
5459 +
5460 +/* PCI arbiter control */
5461 +#define PCI_INT_ARB 0x01 /* When set, use an internal arbiter */
5462 +#define PCI_EXT_ARB 0x02 /* When set, use an external arbiter */
5463 +#define PCI_PARKID_MASK 0x06 /* Selects which agent is parked on an idle bus */
5464 +#define PCI_PARKID_SHIFT 1
5465 +#define PCI_PARKID_LAST 0 /* Last requestor */
5466 +#define PCI_PARKID_4710 1 /* 4710 */
5467 +#define PCI_PARKID_EXTREQ0 2 /* External requestor 0 */
5468 +#define PCI_PARKID_EXTREQ1 3 /* External requestor 1 */
5469 +
5470 +/* Interrupt status/mask */
5471 +#define PCI_INTA 0x01 /* PCI INTA# is asserted */
5472 +#define PCI_INTB 0x02 /* PCI INTB# is asserted */
5473 +#define PCI_SERR 0x04 /* PCI SERR# has been asserted (write one to clear) */
5474 +#define PCI_PERR 0x08 /* PCI PERR# has been asserted (write one to clear) */
5475 +#define PCI_PME 0x10 /* PCI PME# is asserted */
5476 +
5477 +/* (General) PCI/SB mailbox interrupts, two bits per pci function */
5478 +#define MAILBOX_F0_0 0x100 /* function 0, int 0 */
5479 +#define MAILBOX_F0_1 0x200 /* function 0, int 1 */
5480 +#define MAILBOX_F1_0 0x400 /* function 1, int 0 */
5481 +#define MAILBOX_F1_1 0x800 /* function 1, int 1 */
5482 +#define MAILBOX_F2_0 0x1000 /* function 2, int 0 */
5483 +#define MAILBOX_F2_1 0x2000 /* function 2, int 1 */
5484 +#define MAILBOX_F3_0 0x4000 /* function 3, int 0 */
5485 +#define MAILBOX_F3_1 0x8000 /* function 3, int 1 */
5486 +
5487 +/* Sonics broadcast address */
5488 +#define BCAST_ADDR_MASK 0xff /* Broadcast register address */
5489 +
5490 +/* Sonics to PCI translation types */
5491 +#define SBTOPCI0_MASK 0xfc000000
5492 +#define SBTOPCI1_MASK 0xfc000000
5493 +#define SBTOPCI2_MASK 0xc0000000
5494 +#define SBTOPCI_MEM 0
5495 +#define SBTOPCI_IO 1
5496 +#define SBTOPCI_CFG0 2
5497 +#define SBTOPCI_CFG1 3
5498 +#define SBTOPCI_PREF 0x4 /* prefetch enable */
5499 +#define SBTOPCI_BURST 0x8 /* burst enable */
5500 +#define SBTOPCI_RC_MASK 0x30 /* read command (>= rev11) */
5501 +#define SBTOPCI_RC_READ 0x00 /* memory read */
5502 +#define SBTOPCI_RC_READLINE 0x10 /* memory read line */
5503 +#define SBTOPCI_RC_READMULTI 0x20 /* memory read multiple */
5504 +
5505 +/* PCI core index in SROM shadow area */
5506 +#define SRSH_PI_OFFSET 0 /* first word */
5507 +#define SRSH_PI_MASK 0xf000 /* bit 15:12 */
5508 +#define SRSH_PI_SHIFT 12 /* bit 15:12 */
5509 +
5510 +/* PCI side: Reserved PCI configuration registers (see pcicfg.h) */
5511 +#define cap_list rsvd_a[0]
5512 +#define bar0_window dev_dep[0x80 - 0x40]
5513 +#define bar1_window dev_dep[0x84 - 0x40]
5514 +#define sprom_control dev_dep[0x88 - 0x40]
5515 +
5516 +#ifndef _LANGUAGE_ASSEMBLY
5517 +
5518 +extern int sbpci_read_config(sb_t *sbh, uint bus, uint dev, uint func, uint off, void *buf, int len);
5519 +extern int sbpci_write_config(sb_t *sbh, uint bus, uint dev, uint func, uint off, void *buf, int len);
5520 +extern void sbpci_ban(uint16 core);
5521 +extern int sbpci_init(sb_t *sbh);
5522 +extern void sbpci_check(sb_t *sbh);
5523 +
5524 +#endif /* !_LANGUAGE_ASSEMBLY */
5525 +
5526 +#endif /* _SBPCI_H */
5527 diff -Nur linux-2.4.32/arch/mips/bcm947xx/include/sbpcmcia.h linux-2.4.32-brcm/arch/mips/bcm947xx/include/sbpcmcia.h
5528 --- linux-2.4.32/arch/mips/bcm947xx/include/sbpcmcia.h 1970-01-01 01:00:00.000000000 +0100
5529 +++ linux-2.4.32-brcm/arch/mips/bcm947xx/include/sbpcmcia.h 2005-12-16 23:39:10.936836250 +0100
5530 @@ -0,0 +1,146 @@
5531 +/*
5532 + * BCM43XX Sonics SiliconBackplane PCMCIA core hardware definitions.
5533 + *
5534 + * $Id$
5535 + * Copyright 2005, Broadcom Corporation
5536 + * All Rights Reserved.
5537 + *
5538 + * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY
5539 + * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM
5540 + * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS
5541 + * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE.
5542 + */
5543 +
5544 +#ifndef _SBPCMCIA_H
5545 +#define _SBPCMCIA_H
5546 +
5547 +
5548 +/* All the addresses that are offsets in attribute space are divided
5549 + * by two to account for the fact that odd bytes are invalid in
5550 + * attribute space and our read/write routines make the space appear
5551 + * as if they didn't exist. Still we want to show the original numbers
5552 + * as documented in the hnd_pcmcia core manual.
5553 + */
5554 +
5555 +/* PCMCIA Function Configuration Registers */
5556 +#define PCMCIA_FCR (0x700 / 2)
5557 +
5558 +#define FCR0_OFF 0
5559 +#define FCR1_OFF (0x40 / 2)
5560 +#define FCR2_OFF (0x80 / 2)
5561 +#define FCR3_OFF (0xc0 / 2)
5562 +
5563 +#define PCMCIA_FCR0 (0x700 / 2)
5564 +#define PCMCIA_FCR1 (0x740 / 2)
5565 +#define PCMCIA_FCR2 (0x780 / 2)
5566 +#define PCMCIA_FCR3 (0x7c0 / 2)
5567 +
5568 +/* Standard PCMCIA FCR registers */
5569 +
5570 +#define PCMCIA_COR 0
5571 +
5572 +#define COR_RST 0x80
5573 +#define COR_LEV 0x40
5574 +#define COR_IRQEN 0x04
5575 +#define COR_BLREN 0x01
5576 +#define COR_FUNEN 0x01
5577 +
5578 +
5579 +#define PCICIA_FCSR (2 / 2)
5580 +#define PCICIA_PRR (4 / 2)
5581 +#define PCICIA_SCR (6 / 2)
5582 +#define PCICIA_ESR (8 / 2)
5583 +
5584 +
5585 +#define PCM_MEMOFF 0x0000
5586 +#define F0_MEMOFF 0x1000
5587 +#define F1_MEMOFF 0x2000
5588 +#define F2_MEMOFF 0x3000
5589 +#define F3_MEMOFF 0x4000
5590 +
5591 +/* Memory base in the function fcr's */
5592 +#define MEM_ADDR0 (0x728 / 2)
5593 +#define MEM_ADDR1 (0x72a / 2)
5594 +#define MEM_ADDR2 (0x72c / 2)
5595 +
5596 +/* PCMCIA base plus Srom access in fcr0: */
5597 +#define PCMCIA_ADDR0 (0x072e / 2)
5598 +#define PCMCIA_ADDR1 (0x0730 / 2)
5599 +#define PCMCIA_ADDR2 (0x0732 / 2)
5600 +
5601 +#define MEM_SEG (0x0734 / 2)
5602 +#define SROM_CS (0x0736 / 2)
5603 +#define SROM_DATAL (0x0738 / 2)
5604 +#define SROM_DATAH (0x073a / 2)
5605 +#define SROM_ADDRL (0x073c / 2)
5606 +#define SROM_ADDRH (0x073e / 2)
5607 +
5608 +/* Values for srom_cs: */
5609 +#define SROM_IDLE 0
5610 +#define SROM_WRITE 1
5611 +#define SROM_READ 2
5612 +#define SROM_WEN 4
5613 +#define SROM_WDS 7
5614 +#define SROM_DONE 8
5615 +
5616 +/* CIS stuff */
5617 +
5618 +/* The CIS stops where the FCRs start */
5619 +#define CIS_SIZE PCMCIA_FCR
5620 +
5621 +/* Standard tuples we know about */
5622 +
5623 +#define CISTPL_MANFID 0x20 /* Manufacturer and device id */
5624 +#define CISTPL_FUNCE 0x22 /* Function extensions */
5625 +#define CISTPL_CFTABLE 0x1b /* Config table entry */
5626 +
5627 +/* Function extensions for LANs */
5628 +
5629 +#define LAN_TECH 1 /* Technology type */
5630 +#define LAN_SPEED 2 /* Raw bit rate */
5631 +#define LAN_MEDIA 3 /* Transmission media */
5632 +#define LAN_NID 4 /* Node identification (aka MAC addr) */
5633 +#define LAN_CONN 5 /* Connector standard */
5634 +
5635 +
5636 +/* CFTable */
5637 +#define CFTABLE_REGWIN_2K 0x08 /* 2k reg windows size */
5638 +#define CFTABLE_REGWIN_4K 0x10 /* 4k reg windows size */
5639 +#define CFTABLE_REGWIN_8K 0x20 /* 8k reg windows size */
5640 +
5641 +/* Vendor unique tuples are 0x80-0x8f. Within Broadcom we'll
5642 + * take one for HNBU, and use "extensions" (a la FUNCE) within it.
5643 + */
5644 +
5645 +#define CISTPL_BRCM_HNBU 0x80
5646 +
5647 +/* Subtypes of BRCM_HNBU: */
5648 +
5649 +#define HNBU_SROMREV 0x00 /* A byte with sromrev, 1 if not present */
5650 +#define HNBU_CHIPID 0x01 /* Six bytes with PCI vendor &
5651 + * device id and chiprev
5652 + */
5653 +#define HNBU_BOARDREV 0x02 /* Two bytes board revision */
5654 +#define HNBU_PAPARMS 0x03 /* PA parameters: 1 (old), 8 (sreomrev == 1)
5655 + * or 9 (sromrev > 1) bytes */
5656 +#define HNBU_OEM 0x04 /* Eight bytes OEM data (sromrev == 1) */
5657 +#define HNBU_CC 0x05 /* Default country code (sromrev == 1) */
5658 +#define HNBU_AA 0x06 /* Antennas available */
5659 +#define HNBU_AG 0x07 /* Antenna gain */
5660 +#define HNBU_BOARDFLAGS 0x08 /* board flags (2 or 4 bytes) */
5661 +#define HNBU_LEDS 0x09 /* LED set */
5662 +#define HNBU_CCODE 0x0a /* Country code (2 bytes ascii + 1 byte cctl)
5663 + * in rev 2
5664 + */
5665 +#define HNBU_CCKPO 0x0b /* 2 byte cck power offsets in rev 3 */
5666 +#define HNBU_OFDMPO 0x0c /* 4 byte 11g ofdm power offsets in rev 3 */
5667 +
5668 +
5669 +/* sbtmstatelow */
5670 +#define SBTML_INT_ACK 0x40000 /* ack the sb interrupt */
5671 +#define SBTML_INT_EN 0x20000 /* enable sb interrupt */
5672 +
5673 +/* sbtmstatehigh */
5674 +#define SBTMH_INT_STATUS 0x40000 /* sb interrupt status */
5675 +
5676 +#endif /* _SBPCMCIA_H */
5677 diff -Nur linux-2.4.32/arch/mips/bcm947xx/include/sbsdram.h linux-2.4.32-brcm/arch/mips/bcm947xx/include/sbsdram.h
5678 --- linux-2.4.32/arch/mips/bcm947xx/include/sbsdram.h 1970-01-01 01:00:00.000000000 +0100
5679 +++ linux-2.4.32-brcm/arch/mips/bcm947xx/include/sbsdram.h 2005-12-16 23:39:10.936836250 +0100
5680 @@ -0,0 +1,75 @@
5681 +/*
5682 + * BCM47XX Sonics SiliconBackplane SDRAM controller core hardware definitions.
5683 + *
5684 + * Copyright 2005, Broadcom Corporation
5685 + * All Rights Reserved.
5686 + *
5687 + * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY
5688 + * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM
5689 + * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS
5690 + * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE.
5691 + * $Id$
5692 + */
5693 +
5694 +#ifndef _SBSDRAM_H
5695 +#define _SBSDRAM_H
5696 +
5697 +#ifndef _LANGUAGE_ASSEMBLY
5698 +
5699 +/* Sonics side: SDRAM core registers */
5700 +typedef volatile struct sbsdramregs {
5701 + uint32 initcontrol; /* Generates external SDRAM initialization sequence */
5702 + uint32 config; /* Initializes external SDRAM mode register */
5703 + uint32 refresh; /* Controls external SDRAM refresh rate */
5704 + uint32 pad1;
5705 + uint32 pad2;
5706 +} sbsdramregs_t;
5707 +
5708 +#endif
5709 +
5710 +/* SDRAM initialization control (initcontrol) register bits */
5711 +#define SDRAM_CBR 0x0001 /* Writing 1 generates refresh cycle and toggles bit */
5712 +#define SDRAM_PRE 0x0002 /* Writing 1 generates precharge cycle and toggles bit */
5713 +#define SDRAM_MRS 0x0004 /* Writing 1 generates mode register select cycle and toggles bit */
5714 +#define SDRAM_EN 0x0008 /* When set, enables access to SDRAM */
5715 +#define SDRAM_16Mb 0x0000 /* Use 16 Megabit SDRAM */
5716 +#define SDRAM_64Mb 0x0010 /* Use 64 Megabit SDRAM */
5717 +#define SDRAM_128Mb 0x0020 /* Use 128 Megabit SDRAM */
5718 +#define SDRAM_RSVMb 0x0030 /* Use special SDRAM */
5719 +#define SDRAM_RST 0x0080 /* Writing 1 causes soft reset of controller */
5720 +#define SDRAM_SELFREF 0x0100 /* Writing 1 enables self refresh mode */
5721 +#define SDRAM_PWRDOWN 0x0200 /* Writing 1 causes controller to power down */
5722 +#define SDRAM_32BIT 0x0400 /* When set, indicates 32 bit SDRAM interface */
5723 +#define SDRAM_9BITCOL 0x0800 /* When set, indicates 9 bit column */
5724 +
5725 +/* SDRAM configuration (config) register bits */
5726 +#define SDRAM_BURSTFULL 0x0000 /* Use full page bursts */
5727 +#define SDRAM_BURST8 0x0001 /* Use burst of 8 */
5728 +#define SDRAM_BURST4 0x0002 /* Use burst of 4 */
5729 +#define SDRAM_BURST2 0x0003 /* Use burst of 2 */
5730 +#define SDRAM_CAS3 0x0000 /* Use CAS latency of 3 */
5731 +#define SDRAM_CAS2 0x0004 /* Use CAS latency of 2 */
5732 +
5733 +/* SDRAM refresh control (refresh) register bits */
5734 +#define SDRAM_REF(p) (((p)&0xff) | SDRAM_REF_EN) /* Refresh period */
5735 +#define SDRAM_REF_EN 0x8000 /* Writing 1 enables periodic refresh */
5736 +
5737 +/* SDRAM Core default Init values (OCP ID 0x803) */
5738 +#define SDRAM_INIT MEM4MX16X2
5739 +#define SDRAM_CONFIG SDRAM_BURSTFULL
5740 +#define SDRAM_REFRESH SDRAM_REF(0x40)
5741 +
5742 +#define MEM1MX16 0x009 /* 2 MB */
5743 +#define MEM1MX16X2 0x409 /* 4 MB */
5744 +#define MEM2MX8X2 0x809 /* 4 MB */
5745 +#define MEM2MX8X4 0xc09 /* 8 MB */
5746 +#define MEM2MX32 0x439 /* 8 MB */
5747 +#define MEM4MX16 0x019 /* 8 MB */
5748 +#define MEM4MX16X2 0x419 /* 16 MB */
5749 +#define MEM8MX8X2 0x819 /* 16 MB */
5750 +#define MEM8MX16 0x829 /* 16 MB */
5751 +#define MEM4MX32 0x429 /* 16 MB */
5752 +#define MEM8MX8X4 0xc19 /* 32 MB */
5753 +#define MEM8MX16X2 0xc29 /* 32 MB */
5754 +
5755 +#endif /* _SBSDRAM_H */
5756 diff -Nur linux-2.4.32/arch/mips/bcm947xx/include/sbsocram.h linux-2.4.32-brcm/arch/mips/bcm947xx/include/sbsocram.h
5757 --- linux-2.4.32/arch/mips/bcm947xx/include/sbsocram.h 1970-01-01 01:00:00.000000000 +0100
5758 +++ linux-2.4.32-brcm/arch/mips/bcm947xx/include/sbsocram.h 2005-12-16 23:39:10.936836250 +0100
5759 @@ -0,0 +1,37 @@
5760 +/*
5761 + * BCM47XX Sonics SiliconBackplane embedded ram core
5762 + *
5763 + * Copyright 2005, Broadcom Corporation
5764 + * All Rights Reserved.
5765 + *
5766 + * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY
5767 + * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM
5768 + * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS
5769 + * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE.
5770 + *
5771 + * $Id$
5772 + */
5773 +
5774 +#ifndef _SBSOCRAM_H
5775 +#define _SBSOCRAM_H
5776 +
5777 +#define SOCRAM_MEMSIZE 0x00
5778 +#define SOCRAM_BISTSTAT 0x0c
5779 +
5780 +
5781 +#ifndef _LANGUAGE_ASSEMBLY
5782 +
5783 +/* Memcsocram core registers */
5784 +typedef volatile struct sbsocramregs {
5785 + uint32 memsize;
5786 + uint32 biststat;
5787 +} sbsocramregs_t;
5788 +
5789 +#endif
5790 +
5791 +/* Them memory size is 2 to the power of the following
5792 + * base added to the contents of the memsize register.
5793 + */
5794 +#define SOCRAM_MEMSIZE_BASESHIFT 16
5795 +
5796 +#endif /* _SBSOCRAM_H */
5797 diff -Nur linux-2.4.32/arch/mips/bcm947xx/include/sbutils.h linux-2.4.32-brcm/arch/mips/bcm947xx/include/sbutils.h
5798 --- linux-2.4.32/arch/mips/bcm947xx/include/sbutils.h 1970-01-01 01:00:00.000000000 +0100
5799 +++ linux-2.4.32-brcm/arch/mips/bcm947xx/include/sbutils.h 2005-12-16 23:39:10.936836250 +0100
5800 @@ -0,0 +1,140 @@
5801 +/*
5802 + * Misc utility routines for accessing chip-specific features
5803 + * of Broadcom HNBU SiliconBackplane-based chips.
5804 + *
5805 + * Copyright 2005, Broadcom Corporation
5806 + * All Rights Reserved.
5807 + *
5808 + * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY
5809 + * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM
5810 + * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS
5811 + * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE.
5812 + *
5813 + * $Id$
5814 + */
5815 +
5816 +#ifndef _sbutils_h_
5817 +#define _sbutils_h_
5818 +
5819 +/*
5820 + * Datastructure to export all chip specific common variables
5821 + * public (read-only) portion of sbutils handle returned by
5822 + * sb_attach()/sb_kattach()
5823 +*/
5824 +
5825 +struct sb_pub {
5826 +
5827 + uint bustype; /* SB_BUS, PCI_BUS */
5828 + uint buscoretype; /* SB_PCI, SB_PCMCIA, SB_PCIE*/
5829 + uint buscorerev; /* buscore rev */
5830 + uint buscoreidx; /* buscore index */
5831 + int ccrev; /* chip common core rev */
5832 + uint boardtype; /* board type */
5833 + uint boardvendor; /* board vendor */
5834 + uint chip; /* chip number */
5835 + uint chiprev; /* chip revision */
5836 + uint chippkg; /* chip package option */
5837 + uint sonicsrev; /* sonics backplane rev */
5838 +};
5839 +
5840 +typedef const struct sb_pub sb_t;
5841 +
5842 +/*
5843 + * Many of the routines below take an 'sbh' handle as their first arg.
5844 + * Allocate this by calling sb_attach(). Free it by calling sb_detach().
5845 + * At any one time, the sbh is logically focused on one particular sb core
5846 + * (the "current core").
5847 + * Use sb_setcore() or sb_setcoreidx() to change the association to another core.
5848 + */
5849 +
5850 +/* exported externs */
5851 +extern sb_t * BCMINIT(sb_attach)(uint pcidev, osl_t *osh, void *regs, uint bustype, void *sdh, char **vars, int *varsz);
5852 +extern sb_t * BCMINIT(sb_kattach)(void);
5853 +extern void sb_detach(sb_t *sbh);
5854 +extern uint BCMINIT(sb_chip)(sb_t *sbh);
5855 +extern uint BCMINIT(sb_chiprev)(sb_t *sbh);
5856 +extern uint BCMINIT(sb_chipcrev)(sb_t *sbh);
5857 +extern uint BCMINIT(sb_chippkg)(sb_t *sbh);
5858 +extern uint BCMINIT(sb_pcirev)(sb_t *sbh);
5859 +extern bool BCMINIT(sb_war16165)(sb_t *sbh);
5860 +extern uint BCMINIT(sb_pcmciarev)(sb_t *sbh);
5861 +extern uint BCMINIT(sb_boardvendor)(sb_t *sbh);
5862 +extern uint BCMINIT(sb_boardtype)(sb_t *sbh);
5863 +extern uint sb_bus(sb_t *sbh);
5864 +extern uint sb_buscoretype(sb_t *sbh);
5865 +extern uint sb_buscorerev(sb_t *sbh);
5866 +extern uint sb_corelist(sb_t *sbh, uint coreid[]);
5867 +extern uint sb_coreid(sb_t *sbh);
5868 +extern uint sb_coreidx(sb_t *sbh);
5869 +extern uint sb_coreunit(sb_t *sbh);
5870 +extern uint sb_corevendor(sb_t *sbh);
5871 +extern uint sb_corerev(sb_t *sbh);
5872 +extern void *sb_osh(sb_t *sbh);
5873 +extern void *sb_coreregs(sb_t *sbh);
5874 +extern uint32 sb_coreflags(sb_t *sbh, uint32 mask, uint32 val);
5875 +extern uint32 sb_coreflagshi(sb_t *sbh, uint32 mask, uint32 val);
5876 +extern bool sb_iscoreup(sb_t *sbh);
5877 +extern void *sb_setcoreidx(sb_t *sbh, uint coreidx);
5878 +extern void *sb_setcore(sb_t *sbh, uint coreid, uint coreunit);
5879 +extern int sb_corebist(sb_t *sbh, uint coreid, uint coreunit);
5880 +extern void sb_commit(sb_t *sbh);
5881 +extern uint32 sb_base(uint32 admatch);
5882 +extern uint32 sb_size(uint32 admatch);
5883 +extern void sb_core_reset(sb_t *sbh, uint32 bits);
5884 +extern void sb_core_tofixup(sb_t *sbh);
5885 +extern void sb_core_disable(sb_t *sbh, uint32 bits);
5886 +extern uint32 sb_clock_rate(uint32 pll_type, uint32 n, uint32 m);
5887 +extern uint32 sb_clock(sb_t *sbh);
5888 +extern void sb_pci_setup(sb_t *sbh, uint coremask);
5889 +extern void sb_pcmcia_init(sb_t *sbh);
5890 +extern void sb_watchdog(sb_t *sbh, uint ticks);
5891 +extern void *sb_gpiosetcore(sb_t *sbh);
5892 +extern uint32 sb_gpiocontrol(sb_t *sbh, uint32 mask, uint32 val, uint8 priority);
5893 +extern uint32 sb_gpioouten(sb_t *sbh, uint32 mask, uint32 val, uint8 priority);
5894 +extern uint32 sb_gpioout(sb_t *sbh, uint32 mask, uint32 val, uint8 priority);
5895 +extern uint32 sb_gpioin(sb_t *sbh);
5896 +extern uint32 sb_gpiointpolarity(sb_t *sbh, uint32 mask, uint32 val, uint8 priority);
5897 +extern uint32 sb_gpiointmask(sb_t *sbh, uint32 mask, uint32 val, uint8 priority);
5898 +extern uint32 sb_gpioled(sb_t *sbh, uint32 mask, uint32 val);
5899 +extern uint32 sb_gpioreserve(sb_t *sbh, uint32 gpio_num, uint8 priority);
5900 +extern uint32 sb_gpiorelease(sb_t *sbh, uint32 gpio_num, uint8 priority);
5901 +
5902 +extern void sb_clkctl_init(sb_t *sbh);
5903 +extern uint16 sb_clkctl_fast_pwrup_delay(sb_t *sbh);
5904 +extern bool sb_clkctl_clk(sb_t *sbh, uint mode);
5905 +extern int sb_clkctl_xtal(sb_t *sbh, uint what, bool on);
5906 +extern void sb_register_intr_callback(sb_t *sbh, void *intrsoff_fn,
5907 + void *intrsrestore_fn, void *intrsenabled_fn, void *intr_arg);
5908 +extern uint32 sb_set_initiator_to(sb_t *sbh, uint32 to);
5909 +extern void sb_corepciid(sb_t *sbh, uint16 *pcivendor, uint16 *pcidevice,
5910 + uint8 *pciclass, uint8 *pcisubclass, uint8 *pciprogif);
5911 +extern uint sb_pcie_readreg(void *sbh, void* arg1, uint offset);
5912 +extern uint sb_pcie_writereg(sb_t *sbh, void *arg1, uint offset, uint val);
5913 +extern uint32 sb_gpiotimerval(sb_t *sbh, uint32 mask, uint32 val);
5914 +
5915 +
5916 +
5917 +/*
5918 +* Build device path. Path size must be >= SB_DEVPATH_BUFSZ.
5919 +* The returned path is NULL terminated and has trailing '/'.
5920 +* Return 0 on success, nonzero otherwise.
5921 +*/
5922 +extern int sb_devpath(sb_t *sbh, char *path, int size);
5923 +
5924 +/* clkctl xtal what flags */
5925 +#define XTAL 0x1 /* primary crystal oscillator (2050) */
5926 +#define PLL 0x2 /* main chip pll */
5927 +
5928 +/* clkctl clk mode */
5929 +#define CLK_FAST 0 /* force fast (pll) clock */
5930 +#define CLK_DYNAMIC 2 /* enable dynamic clock control */
5931 +
5932 +
5933 +/* GPIO usage priorities */
5934 +#define GPIO_DRV_PRIORITY 0
5935 +#define GPIO_APP_PRIORITY 1
5936 +
5937 +/* device path */
5938 +#define SB_DEVPATH_BUFSZ 16 /* min buffer size in bytes */
5939 +
5940 +#endif /* _sbutils_h_ */
5941 diff -Nur linux-2.4.32/arch/mips/bcm947xx/include/sflash.h linux-2.4.32-brcm/arch/mips/bcm947xx/include/sflash.h
5942 --- linux-2.4.32/arch/mips/bcm947xx/include/sflash.h 1970-01-01 01:00:00.000000000 +0100
5943 +++ linux-2.4.32-brcm/arch/mips/bcm947xx/include/sflash.h 2005-12-16 23:39:10.936836250 +0100
5944 @@ -0,0 +1,36 @@
5945 +/*
5946 + * Broadcom SiliconBackplane chipcommon serial flash interface
5947 + *
5948 + * Copyright 2005, Broadcom Corporation
5949 + * All Rights Reserved.
5950 + *
5951 + * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY
5952 + * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM
5953 + * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS
5954 + * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE.
5955 + *
5956 + * $Id$
5957 + */
5958 +
5959 +#ifndef _sflash_h_
5960 +#define _sflash_h_
5961 +
5962 +#include <typedefs.h>
5963 +#include <sbchipc.h>
5964 +
5965 +struct sflash {
5966 + uint blocksize; /* Block size */
5967 + uint numblocks; /* Number of blocks */
5968 + uint32 type; /* Type */
5969 + uint size; /* Total size in bytes */
5970 +};
5971 +
5972 +/* Utility functions */
5973 +extern int sflash_poll(chipcregs_t *cc, uint offset);
5974 +extern int sflash_read(chipcregs_t *cc, uint offset, uint len, uchar *buf);
5975 +extern int sflash_write(chipcregs_t *cc, uint offset, uint len, const uchar *buf);
5976 +extern int sflash_erase(chipcregs_t *cc, uint offset);
5977 +extern int sflash_commit(chipcregs_t *cc, uint offset, uint len, const uchar *buf);
5978 +extern struct sflash * sflash_init(chipcregs_t *cc);
5979 +
5980 +#endif /* _sflash_h_ */
5981 diff -Nur linux-2.4.32/arch/mips/bcm947xx/include/trxhdr.h linux-2.4.32-brcm/arch/mips/bcm947xx/include/trxhdr.h
5982 --- linux-2.4.32/arch/mips/bcm947xx/include/trxhdr.h 1970-01-01 01:00:00.000000000 +0100
5983 +++ linux-2.4.32-brcm/arch/mips/bcm947xx/include/trxhdr.h 2005-12-16 23:39:10.940836500 +0100
5984 @@ -0,0 +1,33 @@
5985 +/*
5986 + * TRX image file header format.
5987 + *
5988 + * Copyright 2005, Broadcom Corporation
5989 + * All Rights Reserved.
5990 + *
5991 + * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY
5992 + * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM
5993 + * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS
5994 + * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE.
5995 + *
5996 + * $Id$
5997 + */
5998 +
5999 +#include <typedefs.h>
6000 +
6001 +#define TRX_MAGIC 0x30524448 /* "HDR0" */
6002 +#define TRX_VERSION 1
6003 +#define TRX_MAX_LEN 0x3A0000
6004 +#define TRX_NO_HEADER 1 /* Do not write TRX header */
6005 +#define TRX_GZ_FILES 0x2 /* Contains up to TRX_MAX_OFFSET individual gzip files */
6006 +#define TRX_MAX_OFFSET 3
6007 +
6008 +struct trx_header {
6009 + uint32 magic; /* "HDR0" */
6010 + uint32 len; /* Length of file including header */
6011 + uint32 crc32; /* 32-bit CRC from flag_version to end of file */
6012 + uint32 flag_version; /* 0:15 flags, 16:31 version */
6013 + uint32 offsets[TRX_MAX_OFFSET]; /* Offsets of partitions from start of header */
6014 +};
6015 +
6016 +/* Compatibility */
6017 +typedef struct trx_header TRXHDR, *PTRXHDR;
6018 diff -Nur linux-2.4.32/arch/mips/bcm947xx/include/typedefs.h linux-2.4.32-brcm/arch/mips/bcm947xx/include/typedefs.h
6019 --- linux-2.4.32/arch/mips/bcm947xx/include/typedefs.h 1970-01-01 01:00:00.000000000 +0100
6020 +++ linux-2.4.32-brcm/arch/mips/bcm947xx/include/typedefs.h 2005-12-16 23:39:10.940836500 +0100
6021 @@ -0,0 +1,326 @@
6022 +/*
6023 + * Copyright 2005, Broadcom Corporation
6024 + * All Rights Reserved.
6025 + *
6026 + * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY
6027 + * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM
6028 + * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS
6029 + * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE.
6030 + * $Id$
6031 + */
6032 +
6033 +#ifndef _TYPEDEFS_H_
6034 +#define _TYPEDEFS_H_
6035 +
6036 +
6037 +/* Define 'SITE_TYPEDEFS' in the compile to include a site specific
6038 + * typedef file "site_typedefs.h".
6039 + *
6040 + * If 'SITE_TYPEDEFS' is not defined, then the "Inferred Typedefs"
6041 + * section of this file makes inferences about the compile environment
6042 + * based on defined symbols and possibly compiler pragmas.
6043 + *
6044 + * Following these two sections is the "Default Typedefs"
6045 + * section. This section is only prcessed if 'USE_TYPEDEF_DEFAULTS' is
6046 + * defined. This section has a default set of typedefs and a few
6047 + * proprocessor symbols (TRUE, FALSE, NULL, ...).
6048 + */
6049 +
6050 +#ifdef SITE_TYPEDEFS
6051 +
6052 +/*******************************************************************************
6053 + * Site Specific Typedefs
6054 + *******************************************************************************/
6055 +
6056 +#include "site_typedefs.h"
6057 +
6058 +#else
6059 +
6060 +/*******************************************************************************
6061 + * Inferred Typedefs
6062 + *******************************************************************************/
6063 +
6064 +/* Infer the compile environment based on preprocessor symbols and pramas.
6065 + * Override type definitions as needed, and include configuration dependent
6066 + * header files to define types.
6067 + */
6068 +
6069 +#ifdef __cplusplus
6070 +
6071 +#define TYPEDEF_BOOL
6072 +#ifndef FALSE
6073 +#define FALSE false
6074 +#endif
6075 +#ifndef TRUE
6076 +#define TRUE true
6077 +#endif
6078 +
6079 +#else /* ! __cplusplus */
6080 +
6081 +#if defined(_WIN32)
6082 +
6083 +#define TYPEDEF_BOOL
6084 +typedef unsigned char bool; /* consistent w/BOOL */
6085 +
6086 +#endif /* _WIN32 */
6087 +
6088 +#endif /* ! __cplusplus */
6089 +
6090 +/* use the Windows ULONG_PTR type when compiling for 64 bit */
6091 +#if defined(_WIN64)
6092 +#include <basetsd.h>
6093 +#define TYPEDEF_UINTPTR
6094 +typedef ULONG_PTR uintptr;
6095 +#endif
6096 +
6097 +#ifdef _HNDRTE_
6098 +typedef long unsigned int size_t;
6099 +#endif
6100 +
6101 +#ifdef _MSC_VER /* Microsoft C */
6102 +#define TYPEDEF_INT64
6103 +#define TYPEDEF_UINT64
6104 +typedef signed __int64 int64;
6105 +typedef unsigned __int64 uint64;
6106 +#endif
6107 +
6108 +#if defined(MACOSX) && defined(KERNEL)
6109 +#define TYPEDEF_BOOL
6110 +#endif
6111 +
6112 +
6113 +#if defined(linux)
6114 +#define TYPEDEF_UINT
6115 +#define TYPEDEF_USHORT
6116 +#define TYPEDEF_ULONG
6117 +#endif
6118 +
6119 +#if !defined(linux) && !defined(_WIN32) && !defined(PMON) && !defined(_CFE_) && !defined(_HNDRTE_) && !defined(_MINOSL_)
6120 +#define TYPEDEF_UINT
6121 +#define TYPEDEF_USHORT
6122 +#endif
6123 +
6124 +
6125 +/* Do not support the (u)int64 types with strict ansi for GNU C */
6126 +#if defined(__GNUC__) && defined(__STRICT_ANSI__)
6127 +#define TYPEDEF_INT64
6128 +#define TYPEDEF_UINT64
6129 +#endif
6130 +
6131 +/* ICL accepts unsigned 64 bit type only, and complains in ANSI mode
6132 + * for singned or unsigned */
6133 +#if defined(__ICL)
6134 +
6135 +#define TYPEDEF_INT64
6136 +
6137 +#if defined(__STDC__)
6138 +#define TYPEDEF_UINT64
6139 +#endif
6140 +
6141 +#endif /* __ICL */
6142 +
6143 +
6144 +#if !defined(_WIN32) && !defined(PMON) && !defined(_CFE_) && !defined(_HNDRTE_) && !defined(_MINOSL_)
6145 +
6146 +/* pick up ushort & uint from standard types.h */
6147 +#if defined(linux) && defined(__KERNEL__)
6148 +
6149 +#include <linux/types.h> /* sys/types.h and linux/types.h are oil and water */
6150 +
6151 +#else
6152 +
6153 +#include <sys/types.h>
6154 +
6155 +#endif
6156 +
6157 +#endif /* !_WIN32 && !PMON && !_CFE_ && !_HNDRTE_ && !_MINOSL_ */
6158 +
6159 +#if defined(MACOSX) && defined(KERNEL)
6160 +#include <IOKit/IOTypes.h>
6161 +#endif
6162 +
6163 +
6164 +/* use the default typedefs in the next section of this file */
6165 +#define USE_TYPEDEF_DEFAULTS
6166 +
6167 +#endif /* SITE_TYPEDEFS */
6168 +
6169 +
6170 +/*******************************************************************************
6171 + * Default Typedefs
6172 + *******************************************************************************/
6173 +
6174 +#ifdef USE_TYPEDEF_DEFAULTS
6175 +#undef USE_TYPEDEF_DEFAULTS
6176 +
6177 +#ifndef TYPEDEF_BOOL
6178 +typedef /*@abstract@*/ unsigned char bool;
6179 +#endif
6180 +
6181 +/*----------------------- define uchar, ushort, uint, ulong ------------------*/
6182 +
6183 +#ifndef TYPEDEF_UCHAR
6184 +typedef unsigned char uchar;
6185 +#endif
6186 +
6187 +#ifndef TYPEDEF_USHORT
6188 +typedef unsigned short ushort;
6189 +#endif
6190 +
6191 +#ifndef TYPEDEF_UINT
6192 +typedef unsigned int uint;
6193 +#endif
6194 +
6195 +#ifndef TYPEDEF_ULONG
6196 +typedef unsigned long ulong;
6197 +#endif
6198 +
6199 +/*----------------------- define [u]int8/16/32/64, uintptr --------------------*/
6200 +
6201 +#ifndef TYPEDEF_UINT8
6202 +typedef unsigned char uint8;
6203 +#endif
6204 +
6205 +#ifndef TYPEDEF_UINT16
6206 +typedef unsigned short uint16;
6207 +#endif
6208 +
6209 +#ifndef TYPEDEF_UINT32
6210 +typedef unsigned int uint32;
6211 +#endif
6212 +
6213 +#ifndef TYPEDEF_UINT64
6214 +typedef unsigned long long uint64;
6215 +#endif
6216 +
6217 +#ifndef TYPEDEF_UINTPTR
6218 +typedef unsigned int uintptr;
6219 +#endif
6220 +
6221 +#ifndef TYPEDEF_INT8
6222 +typedef signed char int8;
6223 +#endif
6224 +
6225 +#ifndef TYPEDEF_INT16
6226 +typedef signed short int16;
6227 +#endif
6228 +
6229 +#ifndef TYPEDEF_INT32
6230 +typedef signed int int32;
6231 +#endif
6232 +
6233 +#ifndef TYPEDEF_INT64
6234 +typedef signed long long int64;
6235 +#endif
6236 +
6237 +/*----------------------- define float32/64, float_t -----------------------*/
6238 +
6239 +#ifndef TYPEDEF_FLOAT32
6240 +typedef float float32;
6241 +#endif
6242 +
6243 +#ifndef TYPEDEF_FLOAT64
6244 +typedef double float64;
6245 +#endif
6246 +
6247 +/*
6248 + * abstracted floating point type allows for compile time selection of
6249 + * single or double precision arithmetic. Compiling with -DFLOAT32
6250 + * selects single precision; the default is double precision.
6251 + */
6252 +
6253 +#ifndef TYPEDEF_FLOAT_T
6254 +
6255 +#if defined(FLOAT32)
6256 +typedef float32 float_t;
6257 +#else /* default to double precision floating point */
6258 +typedef float64 float_t;
6259 +#endif
6260 +
6261 +#endif /* TYPEDEF_FLOAT_T */
6262 +
6263 +/*----------------------- define macro values -----------------------------*/
6264 +
6265 +#ifndef FALSE
6266 +#define FALSE 0
6267 +#endif
6268 +
6269 +#ifndef TRUE
6270 +#define TRUE 1
6271 +#endif
6272 +
6273 +#ifndef NULL
6274 +#define NULL 0
6275 +#endif
6276 +
6277 +#ifndef OFF
6278 +#define OFF 0
6279 +#endif
6280 +
6281 +#ifndef ON
6282 +#define ON 1
6283 +#endif
6284 +
6285 +#define AUTO (-1)
6286 +
6287 +/* Reclaiming text and data :
6288 + The following macros specify special linker sections that can be reclaimed
6289 + after a system is considered 'up'.
6290 + */
6291 +#if defined(__GNUC__) && defined(BCMRECLAIM)
6292 +extern bool bcmreclaimed;
6293 +#define BCMINITDATA(_data) __attribute__ ((__section__ (".dataini." #_data))) _data##_ini
6294 +#define BCMINITFN(_fn) __attribute__ ((__section__ (".textini." #_fn))) _fn##_ini
6295 +#define BCMINIT(_id) _id##_ini
6296 +#else
6297 +#define BCMINITDATA(_data) _data
6298 +#define BCMINITFN(_fn) _fn
6299 +#define BCMINIT(_id) _id
6300 +#define bcmreclaimed 0
6301 +#endif
6302 +
6303 +/*----------------------- define PTRSZ, INLINE ----------------------------*/
6304 +
6305 +#ifndef PTRSZ
6306 +#define PTRSZ sizeof (char*)
6307 +#endif
6308 +
6309 +#ifndef INLINE
6310 +
6311 +#ifdef _MSC_VER
6312 +
6313 +#define INLINE __inline
6314 +
6315 +#elif __GNUC__
6316 +
6317 +#define INLINE __inline__
6318 +
6319 +#else
6320 +
6321 +#define INLINE
6322 +
6323 +#endif /* _MSC_VER */
6324 +
6325 +#endif /* INLINE */
6326 +
6327 +#undef TYPEDEF_BOOL
6328 +#undef TYPEDEF_UCHAR
6329 +#undef TYPEDEF_USHORT
6330 +#undef TYPEDEF_UINT
6331 +#undef TYPEDEF_ULONG
6332 +#undef TYPEDEF_UINT8
6333 +#undef TYPEDEF_UINT16
6334 +#undef TYPEDEF_UINT32
6335 +#undef TYPEDEF_UINT64
6336 +#undef TYPEDEF_UINTPTR
6337 +#undef TYPEDEF_INT8
6338 +#undef TYPEDEF_INT16
6339 +#undef TYPEDEF_INT32
6340 +#undef TYPEDEF_INT64
6341 +#undef TYPEDEF_FLOAT32
6342 +#undef TYPEDEF_FLOAT64
6343 +#undef TYPEDEF_FLOAT_T
6344 +
6345 +#endif /* USE_TYPEDEF_DEFAULTS */
6346 +
6347 +#endif /* _TYPEDEFS_H_ */
6348 diff -Nur linux-2.4.32/arch/mips/bcm947xx/Makefile linux-2.4.32-brcm/arch/mips/bcm947xx/Makefile
6349 --- linux-2.4.32/arch/mips/bcm947xx/Makefile 1970-01-01 01:00:00.000000000 +0100
6350 +++ linux-2.4.32-brcm/arch/mips/bcm947xx/Makefile 2005-12-19 01:56:51.733868750 +0100
6351 @@ -0,0 +1,15 @@
6352 +#
6353 +# Makefile for the BCM947xx specific kernel interface routines
6354 +# under Linux.
6355 +#
6356 +
6357 +EXTRA_CFLAGS+=-I$(TOPDIR)/arch/mips/bcm947xx/include -DBCMDRIVER
6358 +
6359 +O_TARGET := bcm947xx.o
6360 +
6361 +export-objs := nvram_linux.o setup.o
6362 +obj-y := prom.o setup.o time.o sbmips.o gpio.o
6363 +obj-y += nvram.o nvram_linux.o sflash.o cfe_env.o
6364 +obj-$(CONFIG_PCI) += sbpci.o pcibios.o
6365 +
6366 +include $(TOPDIR)/Rules.make
6367 diff -Nur linux-2.4.32/arch/mips/bcm947xx/nvram.c linux-2.4.32-brcm/arch/mips/bcm947xx/nvram.c
6368 --- linux-2.4.32/arch/mips/bcm947xx/nvram.c 1970-01-01 01:00:00.000000000 +0100
6369 +++ linux-2.4.32-brcm/arch/mips/bcm947xx/nvram.c 2005-12-19 01:05:00.079582750 +0100
6370 @@ -0,0 +1,320 @@
6371 +/*
6372 + * NVRAM variable manipulation (common)
6373 + *
6374 + * Copyright 2004, Broadcom Corporation
6375 + * All Rights Reserved.
6376 + *
6377 + * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY
6378 + * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM
6379 + * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS
6380 + * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE.
6381 + *
6382 + */
6383 +
6384 +#include <typedefs.h>
6385 +#include <osl.h>
6386 +#include <bcmendian.h>
6387 +#include <bcmnvram.h>
6388 +#include <bcmutils.h>
6389 +#include <sbsdram.h>
6390 +
6391 +extern struct nvram_tuple * BCMINIT(_nvram_realloc)(struct nvram_tuple *t, const char *name, const char *value);
6392 +extern void BCMINIT(_nvram_free)(struct nvram_tuple *t);
6393 +extern int BCMINIT(_nvram_read)(void *buf);
6394 +
6395 +char * BCMINIT(_nvram_get)(const char *name);
6396 +int BCMINIT(_nvram_set)(const char *name, const char *value);
6397 +int BCMINIT(_nvram_unset)(const char *name);
6398 +int BCMINIT(_nvram_getall)(char *buf, int count);
6399 +int BCMINIT(_nvram_commit)(struct nvram_header *header);
6400 +int BCMINIT(_nvram_init)(void);
6401 +void BCMINIT(_nvram_exit)(void);
6402 +
6403 +static struct nvram_tuple * BCMINITDATA(nvram_hash)[257];
6404 +static struct nvram_tuple * nvram_dead;
6405 +
6406 +/* Free all tuples. Should be locked. */
6407 +static void
6408 +BCMINITFN(nvram_free)(void)
6409 +{
6410 + uint i;
6411 + struct nvram_tuple *t, *next;
6412 +
6413 + /* Free hash table */
6414 + for (i = 0; i < ARRAYSIZE(BCMINIT(nvram_hash)); i++) {
6415 + for (t = BCMINIT(nvram_hash)[i]; t; t = next) {
6416 + next = t->next;
6417 + BCMINIT(_nvram_free)(t);
6418 + }
6419 + BCMINIT(nvram_hash)[i] = NULL;
6420 + }
6421 +
6422 + /* Free dead table */
6423 + for (t = nvram_dead; t; t = next) {
6424 + next = t->next;
6425 + BCMINIT(_nvram_free)(t);
6426 + }
6427 + nvram_dead = NULL;
6428 +
6429 + /* Indicate to per-port code that all tuples have been freed */
6430 + BCMINIT(_nvram_free)(NULL);
6431 +}
6432 +
6433 +/* String hash */
6434 +static INLINE uint
6435 +hash(const char *s)
6436 +{
6437 + uint hash = 0;
6438 +
6439 + while (*s)
6440 + hash = 31 * hash + *s++;
6441 +
6442 + return hash;
6443 +}
6444 +
6445 +/* (Re)initialize the hash table. Should be locked. */
6446 +static int
6447 +BCMINITFN(nvram_rehash)(struct nvram_header *header)
6448 +{
6449 + char buf[] = "0xXXXXXXXX", *name, *value, *end, *eq;
6450 +
6451 + /* (Re)initialize hash table */
6452 + BCMINIT(nvram_free)();
6453 +
6454 + /* Parse and set "name=value\0 ... \0\0" */
6455 + name = (char *) &header[1];
6456 + end = (char *) header + NVRAM_SPACE - 2;
6457 + end[0] = end[1] = '\0';
6458 + for (; *name; name = value + strlen(value) + 1) {
6459 + if (!(eq = strchr(name, '=')))
6460 + break;
6461 + *eq = '\0';
6462 + value = eq + 1;
6463 + BCMINIT(_nvram_set)(name, value);
6464 + *eq = '=';
6465 + }
6466 +
6467 + /* Set special SDRAM parameters */
6468 + if (!BCMINIT(_nvram_get)("sdram_init")) {
6469 + sprintf(buf, "0x%04X", (uint16)(header->crc_ver_init >> 16));
6470 + BCMINIT(_nvram_set)("sdram_init", buf);
6471 + }
6472 + if (!BCMINIT(_nvram_get)("sdram_config")) {
6473 + sprintf(buf, "0x%04X", (uint16)(header->config_refresh & 0xffff));
6474 + BCMINIT(_nvram_set)("sdram_config", buf);
6475 + }
6476 + if (!BCMINIT(_nvram_get)("sdram_refresh")) {
6477 + sprintf(buf, "0x%04X", (uint16)((header->config_refresh >> 16) & 0xffff));
6478 + BCMINIT(_nvram_set)("sdram_refresh", buf);
6479 + }
6480 + if (!BCMINIT(_nvram_get)("sdram_ncdl")) {
6481 + sprintf(buf, "0x%08X", header->config_ncdl);
6482 + BCMINIT(_nvram_set)("sdram_ncdl", buf);
6483 + }
6484 +
6485 + return 0;
6486 +}
6487 +
6488 +/* Get the value of an NVRAM variable. Should be locked. */
6489 +char *
6490 +BCMINITFN(_nvram_get)(const char *name)
6491 +{
6492 + uint i;
6493 + struct nvram_tuple *t;
6494 + char *value;
6495 +
6496 + if (!name)
6497 + return NULL;
6498 +
6499 + /* Hash the name */
6500 + i = hash(name) % ARRAYSIZE(BCMINIT(nvram_hash));
6501 +
6502 + /* Find the associated tuple in the hash table */
6503 + for (t = BCMINIT(nvram_hash)[i]; t && strcmp(t->name, name); t = t->next);
6504 +
6505 + value = t ? t->value : NULL;
6506 +
6507 + return value;
6508 +}
6509 +
6510 +/* Get the value of an NVRAM variable. Should be locked. */
6511 +int
6512 +BCMINITFN(_nvram_set)(const char *name, const char *value)
6513 +{
6514 + uint i;
6515 + struct nvram_tuple *t, *u, **prev;
6516 +
6517 + /* Hash the name */
6518 + i = hash(name) % ARRAYSIZE(BCMINIT(nvram_hash));
6519 +
6520 + /* Find the associated tuple in the hash table */
6521 + for (prev = &BCMINIT(nvram_hash)[i], t = *prev; t && strcmp(t->name, name); prev = &t->next, t = *prev);
6522 +
6523 + /* (Re)allocate tuple */
6524 + if (!(u = BCMINIT(_nvram_realloc)(t, name, value)))
6525 + return -12; /* -ENOMEM */
6526 +
6527 + /* Value reallocated */
6528 + if (t && t == u)
6529 + return 0;
6530 +
6531 + /* Move old tuple to the dead table */
6532 + if (t) {
6533 + *prev = t->next;
6534 + t->next = nvram_dead;
6535 + nvram_dead = t;
6536 + }
6537 +
6538 + /* Add new tuple to the hash table */
6539 + u->next = BCMINIT(nvram_hash)[i];
6540 + BCMINIT(nvram_hash)[i] = u;
6541 +
6542 + return 0;
6543 +}
6544 +
6545 +/* Unset the value of an NVRAM variable. Should be locked. */
6546 +int
6547 +BCMINITFN(_nvram_unset)(const char *name)
6548 +{
6549 + uint i;
6550 + struct nvram_tuple *t, **prev;
6551 +
6552 + if (!name)
6553 + return 0;
6554 +
6555 + /* Hash the name */
6556 + i = hash(name) % ARRAYSIZE(BCMINIT(nvram_hash));
6557 +
6558 + /* Find the associated tuple in the hash table */
6559 + for (prev = &BCMINIT(nvram_hash)[i], t = *prev; t && strcmp(t->name, name); prev = &t->next, t = *prev);
6560 +
6561 + /* Move it to the dead table */
6562 + if (t) {
6563 + *prev = t->next;
6564 + t->next = nvram_dead;
6565 + nvram_dead = t;
6566 + }
6567 +
6568 + return 0;
6569 +}
6570 +
6571 +/* Get all NVRAM variables. Should be locked. */
6572 +int
6573 +BCMINITFN(_nvram_getall)(char *buf, int count)
6574 +{
6575 + uint i;
6576 + struct nvram_tuple *t;
6577 + int len = 0;
6578 +
6579 + bzero(buf, count);
6580 +
6581 + /* Write name=value\0 ... \0\0 */
6582 + for (i = 0; i < ARRAYSIZE(BCMINIT(nvram_hash)); i++) {
6583 + for (t = BCMINIT(nvram_hash)[i]; t; t = t->next) {
6584 + if ((count - len) > (strlen(t->name) + 1 + strlen(t->value) + 1))
6585 + len += sprintf(buf + len, "%s=%s", t->name, t->value) + 1;
6586 + else
6587 + break;
6588 + }
6589 + }
6590 +
6591 + return 0;
6592 +}
6593 +
6594 +/* Regenerate NVRAM. Should be locked. */
6595 +int
6596 +BCMINITFN(_nvram_commit)(struct nvram_header *header)
6597 +{
6598 + char *init, *config, *refresh, *ncdl;
6599 + char *ptr, *end;
6600 + int i;
6601 + struct nvram_tuple *t;
6602 + struct nvram_header tmp;
6603 + uint8 crc;
6604 +
6605 + /* Regenerate header */
6606 + header->magic = NVRAM_MAGIC;
6607 + header->crc_ver_init = (NVRAM_VERSION << 8);
6608 + if (!(init = BCMINIT(_nvram_get)("sdram_init")) ||
6609 + !(config = BCMINIT(_nvram_get)("sdram_config")) ||
6610 + !(refresh = BCMINIT(_nvram_get)("sdram_refresh")) ||
6611 + !(ncdl = BCMINIT(_nvram_get)("sdram_ncdl"))) {
6612 + header->crc_ver_init |= SDRAM_INIT << 16;
6613 + header->config_refresh = SDRAM_CONFIG;
6614 + header->config_refresh |= SDRAM_REFRESH << 16;
6615 + header->config_ncdl = 0;
6616 + } else {
6617 + header->crc_ver_init |= (bcm_strtoul(init, NULL, 0) & 0xffff) << 16;
6618 + header->config_refresh = bcm_strtoul(config, NULL, 0) & 0xffff;
6619 + header->config_refresh |= (bcm_strtoul(refresh, NULL, 0) & 0xffff) << 16;
6620 + header->config_ncdl = bcm_strtoul(ncdl, NULL, 0);
6621 + }
6622 +
6623 + /* Clear data area */
6624 + ptr = (char *) header + sizeof(struct nvram_header);
6625 + bzero(ptr, NVRAM_SPACE - sizeof(struct nvram_header));
6626 +
6627 + /* Leave space for a double NUL at the end */
6628 + end = (char *) header + NVRAM_SPACE - 2;
6629 +
6630 + /* Write out all tuples */
6631 + for (i = 0; i < ARRAYSIZE(BCMINIT(nvram_hash)); i++) {
6632 + for (t = BCMINIT(nvram_hash)[i]; t; t = t->next) {
6633 + if ((ptr + strlen(t->name) + 1 + strlen(t->value) + 1) > end)
6634 + break;
6635 + ptr += sprintf(ptr, "%s=%s", t->name, t->value) + 1;
6636 + }
6637 + }
6638 +
6639 + /* End with a double NUL */
6640 + ptr += 2;
6641 +
6642 + /* Set new length */
6643 + header->len = ROUNDUP(ptr - (char *) header, 4);
6644 +
6645 + /* Little-endian CRC8 over the last 11 bytes of the header */
6646 + tmp.crc_ver_init = htol32(header->crc_ver_init);
6647 + tmp.config_refresh = htol32(header->config_refresh);
6648 + tmp.config_ncdl = htol32(header->config_ncdl);
6649 + crc = hndcrc8((char *) &tmp + 9, sizeof(struct nvram_header) - 9, CRC8_INIT_VALUE);
6650 +
6651 + /* Continue CRC8 over data bytes */
6652 + crc = hndcrc8((char *) &header[1], header->len - sizeof(struct nvram_header), crc);
6653 +
6654 + /* Set new CRC8 */
6655 + header->crc_ver_init |= crc;
6656 +
6657 + /* Reinitialize hash table */
6658 + return BCMINIT(nvram_rehash)(header);
6659 +}
6660 +
6661 +/* Initialize hash table. Should be locked. */
6662 +int
6663 +BCMINITFN(_nvram_init)(void)
6664 +{
6665 + struct nvram_header *header;
6666 + int ret;
6667 + void *osh;
6668 +
6669 + /* get kernel osl handler */
6670 + osh = osl_attach(NULL);
6671 +
6672 + if (!(header = (struct nvram_header *) MALLOC(osh, NVRAM_SPACE))) {
6673 + printf("nvram_init: out of memory, malloced %d bytes\n", MALLOCED(osh));
6674 + return -12; /* -ENOMEM */
6675 + }
6676 +
6677 + if ((ret = BCMINIT(_nvram_read)(header)) == 0 &&
6678 + header->magic == NVRAM_MAGIC)
6679 + BCMINIT(nvram_rehash)(header);
6680 +
6681 + MFREE(osh, header, NVRAM_SPACE);
6682 + return ret;
6683 +}
6684 +
6685 +/* Free hash table. Should be locked. */
6686 +void
6687 +BCMINITFN(_nvram_exit)(void)
6688 +{
6689 + BCMINIT(nvram_free)();
6690 +}
6691 diff -Nur linux-2.4.32/arch/mips/bcm947xx/nvram_linux.c linux-2.4.32-brcm/arch/mips/bcm947xx/nvram_linux.c
6692 --- linux-2.4.32/arch/mips/bcm947xx/nvram_linux.c 1970-01-01 01:00:00.000000000 +0100
6693 +++ linux-2.4.32-brcm/arch/mips/bcm947xx/nvram_linux.c 2005-12-19 01:09:59.782313000 +0100
6694 @@ -0,0 +1,653 @@
6695 +/*
6696 + * NVRAM variable manipulation (Linux kernel half)
6697 + *
6698 + * Copyright 2005, Broadcom Corporation
6699 + * All Rights Reserved.
6700 + *
6701 + * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY
6702 + * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM
6703 + * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS
6704 + * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE.
6705 + *
6706 + */
6707 +
6708 +#include <linux/config.h>
6709 +#include <linux/init.h>
6710 +#include <linux/module.h>
6711 +#include <linux/kernel.h>
6712 +#include <linux/string.h>
6713 +#include <linux/interrupt.h>
6714 +#include <linux/spinlock.h>
6715 +#include <linux/slab.h>
6716 +#include <linux/bootmem.h>
6717 +#include <linux/wrapper.h>
6718 +#include <linux/fs.h>
6719 +#include <linux/miscdevice.h>
6720 +#include <linux/mtd/mtd.h>
6721 +#include <asm/addrspace.h>
6722 +#include <asm/io.h>
6723 +#include <asm/uaccess.h>
6724 +
6725 +#include <typedefs.h>
6726 +#include <bcmendian.h>
6727 +#include <bcmnvram.h>
6728 +#include <bcmutils.h>
6729 +#include <sbconfig.h>
6730 +#include <sbchipc.h>
6731 +#include <sbutils.h>
6732 +#include <sbmips.h>
6733 +#include <sflash.h>
6734 +
6735 +/* In BSS to minimize text size and page aligned so it can be mmap()-ed */
6736 +static char nvram_buf[NVRAM_SPACE] __attribute__((aligned(PAGE_SIZE)));
6737 +
6738 +#ifdef MODULE
6739 +
6740 +#define early_nvram_get(name) nvram_get(name)
6741 +
6742 +#else /* !MODULE */
6743 +
6744 +/* Global SB handle */
6745 +extern void *bcm947xx_sbh;
6746 +extern spinlock_t bcm947xx_sbh_lock;
6747 +
6748 +static int cfe_env;
6749 +extern char *cfe_env_get(char *nv_buf, const char *name);
6750 +
6751 +/* Convenience */
6752 +#define sbh bcm947xx_sbh
6753 +#define sbh_lock bcm947xx_sbh_lock
6754 +#define KB * 1024
6755 +#define MB * 1024 * 1024
6756 +
6757 +/* Probe for NVRAM header */
6758 +static void __init
6759 +early_nvram_init(void)
6760 +{
6761 + struct nvram_header *header;
6762 + chipcregs_t *cc;
6763 + struct sflash *info = NULL;
6764 + int i;
6765 + uint32 base, off, lim;
6766 + u32 *src, *dst;
6767 +
6768 + if ((cc = sb_setcore(sbh, SB_CC, 0)) != NULL) {
6769 + base = KSEG1ADDR(SB_FLASH2);
6770 + switch (readl(&cc->capabilities) & CAP_FLASH_MASK) {
6771 + case PFLASH:
6772 + lim = SB_FLASH2_SZ;
6773 + break;
6774 +
6775 + case SFLASH_ST:
6776 + case SFLASH_AT:
6777 + if ((info = sflash_init(cc)) == NULL)
6778 + return;
6779 + lim = info->size;
6780 + break;
6781 +
6782 + case FLASH_NONE:
6783 + default:
6784 + return;
6785 + }
6786 + } else {
6787 + /* extif assumed, Stop at 4 MB */
6788 + base = KSEG1ADDR(SB_FLASH1);
6789 + lim = SB_FLASH1_SZ;
6790 + }
6791 +
6792 + /* XXX: hack for supporting the CFE environment stuff on WGT634U */
6793 + src = (u32 *) KSEG1ADDR(base + 8 * 1024 * 1024 - 0x2000);
6794 + dst = (u32 *) nvram_buf;
6795 + if ((lim == 0x02000000) && ((*src & 0xff00ff) == 0x000001)) {
6796 + printk("early_nvram_init: WGT634U NVRAM found.\n");
6797 +
6798 + for (i = 0; i < 0x1ff0; i++) {
6799 + if (*src == 0xFFFFFFFF)
6800 + break;
6801 + *dst++ = *src++;
6802 + }
6803 + cfe_env = 1;
6804 + return;
6805 + }
6806 +
6807 + off = FLASH_MIN;
6808 + while (off <= lim) {
6809 + /* Windowed flash access */
6810 + header = (struct nvram_header *) KSEG1ADDR(base + off - NVRAM_SPACE);
6811 + if (header->magic == NVRAM_MAGIC)
6812 + goto found;
6813 + off <<= 1;
6814 + }
6815 +
6816 + /* Try embedded NVRAM at 4 KB and 1 KB as last resorts */
6817 + header = (struct nvram_header *) KSEG1ADDR(base + 4 KB);
6818 + if (header->magic == NVRAM_MAGIC)
6819 + goto found;
6820 +
6821 + header = (struct nvram_header *) KSEG1ADDR(base + 1 KB);
6822 + if (header->magic == NVRAM_MAGIC)
6823 + goto found;
6824 +
6825 + printk("early_nvram_init: NVRAM not found\n");
6826 + return;
6827 +
6828 +found:
6829 + src = (u32 *) header;
6830 + dst = (u32 *) nvram_buf;
6831 + for (i = 0; i < sizeof(struct nvram_header); i += 4)
6832 + *dst++ = *src++;
6833 + for (; i < header->len && i < NVRAM_SPACE; i += 4)
6834 + *dst++ = ltoh32(*src++);
6835 +}
6836 +
6837 +/* Early (before mm or mtd) read-only access to NVRAM */
6838 +static char * __init
6839 +early_nvram_get(const char *name)
6840 +{
6841 + char *var, *value, *end, *eq;
6842 +
6843 + if (!name)
6844 + return NULL;
6845 +
6846 + /* Too early? */
6847 + if (sbh == NULL)
6848 + return NULL;
6849 +
6850 + if (!nvram_buf[0])
6851 + early_nvram_init();
6852 +
6853 + if (cfe_env)
6854 + return cfe_env_get(nvram_buf, name);
6855 +
6856 + /* Look for name=value and return value */
6857 + var = &nvram_buf[sizeof(struct nvram_header)];
6858 + end = nvram_buf + sizeof(nvram_buf) - 2;
6859 + end[0] = end[1] = '\0';
6860 + for (; *var; var = value + strlen(value) + 1) {
6861 + if (!(eq = strchr(var, '=')))
6862 + break;
6863 + value = eq + 1;
6864 + if ((eq - var) == strlen(name) && strncmp(var, name, (eq - var)) == 0)
6865 + return value;
6866 + }
6867 +
6868 + return NULL;
6869 +}
6870 +
6871 +#endif /* !MODULE */
6872 +
6873 +extern char * _nvram_get(const char *name);
6874 +extern int _nvram_set(const char *name, const char *value);
6875 +extern int _nvram_unset(const char *name);
6876 +extern int _nvram_getall(char *buf, int count);
6877 +extern int _nvram_commit(struct nvram_header *header);
6878 +extern int _nvram_init(void);
6879 +extern void _nvram_exit(void);
6880 +
6881 +/* Globals */
6882 +static spinlock_t nvram_lock = SPIN_LOCK_UNLOCKED;
6883 +static struct semaphore nvram_sem;
6884 +static unsigned long nvram_offset = 0;
6885 +static int nvram_major = -1;
6886 +static devfs_handle_t nvram_handle = NULL;
6887 +static struct mtd_info *nvram_mtd = NULL;
6888 +
6889 +int
6890 +_nvram_read(char *buf)
6891 +{
6892 + struct nvram_header *header = (struct nvram_header *) buf;
6893 + size_t len;
6894 +
6895 + if (!nvram_mtd ||
6896 + MTD_READ(nvram_mtd, nvram_mtd->size - NVRAM_SPACE, NVRAM_SPACE, &len, buf) ||
6897 + len != NVRAM_SPACE ||
6898 + header->magic != NVRAM_MAGIC) {
6899 + /* Maybe we can recover some data from early initialization */
6900 + memcpy(buf, nvram_buf, NVRAM_SPACE);
6901 + }
6902 +
6903 + return 0;
6904 +}
6905 +
6906 +struct nvram_tuple *
6907 +_nvram_realloc(struct nvram_tuple *t, const char *name, const char *value)
6908 +{
6909 + if ((nvram_offset + strlen(value) + 1) > NVRAM_SPACE)
6910 + return NULL;
6911 +
6912 + if (!t) {
6913 + if (!(t = kmalloc(sizeof(struct nvram_tuple) + strlen(name) + 1, GFP_ATOMIC)))
6914 + return NULL;
6915 +
6916 + /* Copy name */
6917 + t->name = (char *) &t[1];
6918 + strcpy(t->name, name);
6919 +
6920 + t->value = NULL;
6921 + }
6922 +
6923 + /* Copy value */
6924 + if (!t->value || strcmp(t->value, value)) {
6925 + t->value = &nvram_buf[nvram_offset];
6926 + strcpy(t->value, value);
6927 + nvram_offset += strlen(value) + 1;
6928 + }
6929 +
6930 + return t;
6931 +}
6932 +
6933 +void
6934 +_nvram_free(struct nvram_tuple *t)
6935 +{
6936 + if (!t)
6937 + nvram_offset = 0;
6938 + else
6939 + kfree(t);
6940 +}
6941 +
6942 +int
6943 +nvram_set(const char *name, const char *value)
6944 +{
6945 + unsigned long flags;
6946 + int ret;
6947 + struct nvram_header *header;
6948 +
6949 + spin_lock_irqsave(&nvram_lock, flags);
6950 + if ((ret = _nvram_set(name, value))) {
6951 + /* Consolidate space and try again */
6952 + if ((header = kmalloc(NVRAM_SPACE, GFP_ATOMIC))) {
6953 + if (_nvram_commit(header) == 0)
6954 + ret = _nvram_set(name, value);
6955 + kfree(header);
6956 + }
6957 + }
6958 + spin_unlock_irqrestore(&nvram_lock, flags);
6959 +
6960 + return ret;
6961 +}
6962 +
6963 +char *
6964 +real_nvram_get(const char *name)
6965 +{
6966 + unsigned long flags;
6967 + char *value;
6968 +
6969 + spin_lock_irqsave(&nvram_lock, flags);
6970 + value = _nvram_get(name);
6971 + spin_unlock_irqrestore(&nvram_lock, flags);
6972 +
6973 + return value;
6974 +}
6975 +
6976 +char *
6977 +nvram_get(const char *name)
6978 +{
6979 + if (nvram_major >= 0)
6980 + return real_nvram_get(name);
6981 + else
6982 + return early_nvram_get(name);
6983 +}
6984 +
6985 +int
6986 +nvram_unset(const char *name)
6987 +{
6988 + unsigned long flags;
6989 + int ret;
6990 +
6991 + spin_lock_irqsave(&nvram_lock, flags);
6992 + ret = _nvram_unset(name);
6993 + spin_unlock_irqrestore(&nvram_lock, flags);
6994 +
6995 + return ret;
6996 +}
6997 +
6998 +static void
6999 +erase_callback(struct erase_info *done)
7000 +{
7001 + wait_queue_head_t *wait_q = (wait_queue_head_t *) done->priv;
7002 + wake_up(wait_q);
7003 +}
7004 +
7005 +int
7006 +nvram_commit(void)
7007 +{
7008 + char *buf;
7009 + size_t erasesize, len;
7010 + unsigned int i;
7011 + int ret;
7012 + struct nvram_header *header;
7013 + unsigned long flags;
7014 + u_int32_t offset;
7015 + DECLARE_WAITQUEUE(wait, current);
7016 + wait_queue_head_t wait_q;
7017 + struct erase_info erase;
7018 +
7019 + if (!nvram_mtd) {
7020 + printk("nvram_commit: NVRAM not found\n");
7021 + return -ENODEV;
7022 + }
7023 +
7024 + if (in_interrupt()) {
7025 + printk("nvram_commit: not committing in interrupt\n");
7026 + return -EINVAL;
7027 + }
7028 +
7029 + /* Backup sector blocks to be erased */
7030 + erasesize = ROUNDUP(NVRAM_SPACE, nvram_mtd->erasesize);
7031 + if (!(buf = kmalloc(erasesize, GFP_KERNEL))) {
7032 + printk("nvram_commit: out of memory\n");
7033 + return -ENOMEM;
7034 + }
7035 +
7036 + down(&nvram_sem);
7037 +
7038 + if ((i = erasesize - NVRAM_SPACE) > 0) {
7039 + offset = nvram_mtd->size - erasesize;
7040 + len = 0;
7041 + ret = MTD_READ(nvram_mtd, offset, i, &len, buf);
7042 + if (ret || len != i) {
7043 + printk("nvram_commit: read error ret = %d, len = %d/%d\n", ret, len, i);
7044 + ret = -EIO;
7045 + goto done;
7046 + }
7047 + header = (struct nvram_header *)(buf + i);
7048 + } else {
7049 + offset = nvram_mtd->size - NVRAM_SPACE;
7050 + header = (struct nvram_header *)buf;
7051 + }
7052 +
7053 + /* Regenerate NVRAM */
7054 + spin_lock_irqsave(&nvram_lock, flags);
7055 + ret = _nvram_commit(header);
7056 + spin_unlock_irqrestore(&nvram_lock, flags);
7057 + if (ret)
7058 + goto done;
7059 +
7060 + /* Erase sector blocks */
7061 + init_waitqueue_head(&wait_q);
7062 + for (; offset < nvram_mtd->size - NVRAM_SPACE + header->len; offset += nvram_mtd->erasesize) {
7063 + erase.mtd = nvram_mtd;
7064 + erase.addr = offset;
7065 + erase.len = nvram_mtd->erasesize;
7066 + erase.callback = erase_callback;
7067 + erase.priv = (u_long) &wait_q;
7068 +
7069 + set_current_state(TASK_INTERRUPTIBLE);
7070 + add_wait_queue(&wait_q, &wait);
7071 +
7072 + /* Unlock sector blocks */
7073 + if (nvram_mtd->unlock)
7074 + nvram_mtd->unlock(nvram_mtd, offset, nvram_mtd->erasesize);
7075 +
7076 + if ((ret = MTD_ERASE(nvram_mtd, &erase))) {
7077 + set_current_state(TASK_RUNNING);
7078 + remove_wait_queue(&wait_q, &wait);
7079 + printk("nvram_commit: erase error\n");
7080 + goto done;
7081 + }
7082 +
7083 + /* Wait for erase to finish */
7084 + schedule();
7085 + remove_wait_queue(&wait_q, &wait);
7086 + }
7087 +
7088 + /* Write partition up to end of data area */
7089 + offset = nvram_mtd->size - erasesize;
7090 + i = erasesize - NVRAM_SPACE + header->len;
7091 + ret = MTD_WRITE(nvram_mtd, offset, i, &len, buf);
7092 + if (ret || len != i) {
7093 + printk("nvram_commit: write error\n");
7094 + ret = -EIO;
7095 + goto done;
7096 + }
7097 +
7098 + offset = nvram_mtd->size - erasesize;
7099 + ret = MTD_READ(nvram_mtd, offset, 4, &len, buf);
7100 +
7101 + done:
7102 + up(&nvram_sem);
7103 + kfree(buf);
7104 + return ret;
7105 +}
7106 +
7107 +int
7108 +nvram_getall(char *buf, int count)
7109 +{
7110 + unsigned long flags;
7111 + int ret;
7112 +
7113 + spin_lock_irqsave(&nvram_lock, flags);
7114 + ret = _nvram_getall(buf, count);
7115 + spin_unlock_irqrestore(&nvram_lock, flags);
7116 +
7117 + return ret;
7118 +}
7119 +
7120 +EXPORT_SYMBOL(nvram_get);
7121 +EXPORT_SYMBOL(nvram_getall);
7122 +EXPORT_SYMBOL(nvram_set);
7123 +EXPORT_SYMBOL(nvram_unset);
7124 +EXPORT_SYMBOL(nvram_commit);
7125 +
7126 +/* User mode interface below */
7127 +
7128 +static ssize_t
7129 +dev_nvram_read(struct file *file, char *buf, size_t count, loff_t *ppos)
7130 +{
7131 + char tmp[100], *name = tmp, *value;
7132 + ssize_t ret;
7133 + unsigned long off;
7134 +
7135 + if (count > sizeof(tmp)) {
7136 + if (!(name = kmalloc(count, GFP_KERNEL)))
7137 + return -ENOMEM;
7138 + }
7139 +
7140 + if (copy_from_user(name, buf, count)) {
7141 + ret = -EFAULT;
7142 + goto done;
7143 + }
7144 +
7145 + if (*name == '\0') {
7146 + /* Get all variables */
7147 + ret = nvram_getall(name, count);
7148 + if (ret == 0) {
7149 + if (copy_to_user(buf, name, count)) {
7150 + ret = -EFAULT;
7151 + goto done;
7152 + }
7153 + ret = count;
7154 + }
7155 + } else {
7156 + if (!(value = nvram_get(name))) {
7157 + ret = 0;
7158 + goto done;
7159 + }
7160 +
7161 + /* Provide the offset into mmap() space */
7162 + off = (unsigned long) value - (unsigned long) nvram_buf;
7163 +
7164 + if (put_user(off, (unsigned long *) buf)) {
7165 + ret = -EFAULT;
7166 + goto done;
7167 + }
7168 +
7169 + ret = sizeof(unsigned long);
7170 + }
7171 +
7172 + flush_cache_all();
7173 +
7174 +done:
7175 + if (name != tmp)
7176 + kfree(name);
7177 +
7178 + return ret;
7179 +}
7180 +
7181 +static ssize_t
7182 +dev_nvram_write(struct file *file, const char *buf, size_t count, loff_t *ppos)
7183 +{
7184 + char tmp[100], *name = tmp, *value;
7185 + ssize_t ret;
7186 +
7187 + if (count > sizeof(tmp)) {
7188 + if (!(name = kmalloc(count, GFP_KERNEL)))
7189 + return -ENOMEM;
7190 + }
7191 +
7192 + if (copy_from_user(name, buf, count)) {
7193 + ret = -EFAULT;
7194 + goto done;
7195 + }
7196 +
7197 + value = name;
7198 + name = strsep(&value, "=");
7199 + if (value)
7200 + ret = nvram_set(name, value) ? : count;
7201 + else
7202 + ret = nvram_unset(name) ? : count;
7203 +
7204 + done:
7205 + if (name != tmp)
7206 + kfree(name);
7207 +
7208 + return ret;
7209 +}
7210 +
7211 +static int
7212 +dev_nvram_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg)
7213 +{
7214 + if (cmd != NVRAM_MAGIC)
7215 + return -EINVAL;
7216 + return nvram_commit();
7217 +}
7218 +
7219 +static int
7220 +dev_nvram_mmap(struct file *file, struct vm_area_struct *vma)
7221 +{
7222 + unsigned long offset = virt_to_phys(nvram_buf);
7223 +
7224 + if (remap_page_range(vma->vm_start, offset, vma->vm_end-vma->vm_start,
7225 + vma->vm_page_prot))
7226 + return -EAGAIN;
7227 +
7228 + return 0;
7229 +}
7230 +
7231 +static int
7232 +dev_nvram_open(struct inode *inode, struct file * file)
7233 +{
7234 + MOD_INC_USE_COUNT;
7235 + return 0;
7236 +}
7237 +
7238 +static int
7239 +dev_nvram_release(struct inode *inode, struct file * file)
7240 +{
7241 + MOD_DEC_USE_COUNT;
7242 + return 0;
7243 +}
7244 +
7245 +static struct file_operations dev_nvram_fops = {
7246 + owner: THIS_MODULE,
7247 + open: dev_nvram_open,
7248 + release: dev_nvram_release,
7249 + read: dev_nvram_read,
7250 + write: dev_nvram_write,
7251 + ioctl: dev_nvram_ioctl,
7252 + mmap: dev_nvram_mmap,
7253 +};
7254 +
7255 +static void
7256 +dev_nvram_exit(void)
7257 +{
7258 + int order = 0;
7259 + struct page *page, *end;
7260 +
7261 + if (nvram_handle)
7262 + devfs_unregister(nvram_handle);
7263 +
7264 + if (nvram_major >= 0)
7265 + devfs_unregister_chrdev(nvram_major, "nvram");
7266 +
7267 + if (nvram_mtd)
7268 + put_mtd_device(nvram_mtd);
7269 +
7270 + while ((PAGE_SIZE << order) < NVRAM_SPACE)
7271 + order++;
7272 + end = virt_to_page(nvram_buf + (PAGE_SIZE << order) - 1);
7273 + for (page = virt_to_page(nvram_buf); page <= end; page++)
7274 + mem_map_unreserve(page);
7275 +
7276 + _nvram_exit();
7277 +}
7278 +
7279 +static int __init
7280 +dev_nvram_init(void)
7281 +{
7282 + int order = 0, ret = 0;
7283 + struct page *page, *end;
7284 + unsigned int i;
7285 +
7286 + /* Allocate and reserve memory to mmap() */
7287 + while ((PAGE_SIZE << order) < NVRAM_SPACE)
7288 + order++;
7289 + end = virt_to_page(nvram_buf + (PAGE_SIZE << order) - 1);
7290 + for (page = virt_to_page(nvram_buf); page <= end; page++)
7291 + mem_map_reserve(page);
7292 +
7293 +#ifdef CONFIG_MTD
7294 + /* Find associated MTD device */
7295 + for (i = 0; i < MAX_MTD_DEVICES; i++) {
7296 + nvram_mtd = get_mtd_device(NULL, i);
7297 + if (nvram_mtd) {
7298 + if (!strcmp(nvram_mtd->name, "nvram") &&
7299 + nvram_mtd->size >= NVRAM_SPACE)
7300 + break;
7301 + put_mtd_device(nvram_mtd);
7302 + }
7303 + }
7304 + if (i >= MAX_MTD_DEVICES)
7305 + nvram_mtd = NULL;
7306 +#endif
7307 +
7308 + /* Initialize hash table lock */
7309 + spin_lock_init(&nvram_lock);
7310 +
7311 + /* Initialize commit semaphore */
7312 + init_MUTEX(&nvram_sem);
7313 +
7314 + /* Register char device */
7315 + if ((nvram_major = devfs_register_chrdev(0, "nvram", &dev_nvram_fops)) < 0) {
7316 + ret = nvram_major;
7317 + goto err;
7318 + }
7319 +
7320 + /* Initialize hash table */
7321 + _nvram_init();
7322 +
7323 + /* Create /dev/nvram handle */
7324 + nvram_handle = devfs_register(NULL, "nvram", DEVFS_FL_NONE, nvram_major, 0,
7325 + S_IFCHR | S_IRUSR | S_IWUSR | S_IRGRP, &dev_nvram_fops, NULL);
7326 +
7327 + /* Set the SDRAM NCDL value into NVRAM if not already done */
7328 + if (getintvar(NULL, "sdram_ncdl") == 0) {
7329 + unsigned int ncdl;
7330 + char buf[] = "0x00000000";
7331 +
7332 + if ((ncdl = sb_memc_get_ncdl(sbh))) {
7333 + sprintf(buf, "0x%08x", ncdl);
7334 + nvram_set("sdram_ncdl", buf);
7335 + nvram_commit();
7336 + }
7337 + }
7338 +
7339 + return 0;
7340 +
7341 + err:
7342 + dev_nvram_exit();
7343 + return ret;
7344 +}
7345 +
7346 +module_init(dev_nvram_init);
7347 +module_exit(dev_nvram_exit);
7348 diff -Nur linux-2.4.32/arch/mips/bcm947xx/pcibios.c linux-2.4.32-brcm/arch/mips/bcm947xx/pcibios.c
7349 --- linux-2.4.32/arch/mips/bcm947xx/pcibios.c 1970-01-01 01:00:00.000000000 +0100
7350 +++ linux-2.4.32-brcm/arch/mips/bcm947xx/pcibios.c 2005-12-16 23:39:10.944836750 +0100
7351 @@ -0,0 +1,355 @@
7352 +/*
7353 + * Low-Level PCI and SB support for BCM47xx (Linux support code)
7354 + *
7355 + * Copyright 2005, Broadcom Corporation
7356 + * All Rights Reserved.
7357 + *
7358 + * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY
7359 + * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM
7360 + * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS
7361 + * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE.
7362 + *
7363 + * $Id$
7364 + */
7365 +
7366 +#include <linux/config.h>
7367 +#include <linux/types.h>
7368 +#include <linux/kernel.h>
7369 +#include <linux/sched.h>
7370 +#include <linux/pci.h>
7371 +#include <linux/init.h>
7372 +#include <linux/delay.h>
7373 +#include <asm/io.h>
7374 +#include <asm/irq.h>
7375 +#include <asm/paccess.h>
7376 +
7377 +#include <typedefs.h>
7378 +#include <bcmutils.h>
7379 +#include <sbconfig.h>
7380 +#include <sbutils.h>
7381 +#include <sbpci.h>
7382 +#include <pcicfg.h>
7383 +#include <bcmdevs.h>
7384 +#include <bcmnvram.h>
7385 +
7386 +/* Global SB handle */
7387 +extern sb_t *bcm947xx_sbh;
7388 +extern spinlock_t bcm947xx_sbh_lock;
7389 +
7390 +/* Convenience */
7391 +#define sbh bcm947xx_sbh
7392 +#define sbh_lock bcm947xx_sbh_lock
7393 +
7394 +static int
7395 +sbpci_read_config_byte(struct pci_dev *dev, int where, u8 *value)
7396 +{
7397 + unsigned long flags;
7398 + int ret;
7399 +
7400 + spin_lock_irqsave(&sbh_lock, flags);
7401 + ret = sbpci_read_config(sbh, dev->bus->number, PCI_SLOT(dev->devfn), PCI_FUNC(dev->devfn), where, value, sizeof(*value));
7402 + spin_unlock_irqrestore(&sbh_lock, flags);
7403 + return ret ? PCIBIOS_DEVICE_NOT_FOUND : PCIBIOS_SUCCESSFUL;
7404 +}
7405 +
7406 +static int
7407 +sbpci_read_config_word(struct pci_dev *dev, int where, u16 *value)
7408 +{
7409 + unsigned long flags;
7410 + int ret;
7411 +
7412 + spin_lock_irqsave(&sbh_lock, flags);
7413 + ret = sbpci_read_config(sbh, dev->bus->number, PCI_SLOT(dev->devfn), PCI_FUNC(dev->devfn), where, value, sizeof(*value));
7414 + spin_unlock_irqrestore(&sbh_lock, flags);
7415 + return ret ? PCIBIOS_DEVICE_NOT_FOUND : PCIBIOS_SUCCESSFUL;
7416 +}
7417 +
7418 +static int
7419 +sbpci_read_config_dword(struct pci_dev *dev, int where, u32 *value)
7420 +{
7421 + unsigned long flags;
7422 + int ret;
7423 +
7424 + spin_lock_irqsave(&sbh_lock, flags);
7425 + ret = sbpci_read_config(sbh, dev->bus->number, PCI_SLOT(dev->devfn), PCI_FUNC(dev->devfn), where, value, sizeof(*value));
7426 + spin_unlock_irqrestore(&sbh_lock, flags);
7427 + return ret ? PCIBIOS_DEVICE_NOT_FOUND : PCIBIOS_SUCCESSFUL;
7428 +}
7429 +
7430 +static int
7431 +sbpci_write_config_byte(struct pci_dev *dev, int where, u8 value)
7432 +{
7433 + unsigned long flags;
7434 + int ret;
7435 +
7436 + spin_lock_irqsave(&sbh_lock, flags);
7437 + ret = sbpci_write_config(sbh, dev->bus->number, PCI_SLOT(dev->devfn), PCI_FUNC(dev->devfn), where, &value, sizeof(value));
7438 + spin_unlock_irqrestore(&sbh_lock, flags);
7439 + return ret ? PCIBIOS_DEVICE_NOT_FOUND : PCIBIOS_SUCCESSFUL;
7440 +}
7441 +
7442 +static int
7443 +sbpci_write_config_word(struct pci_dev *dev, int where, u16 value)
7444 +{
7445 + unsigned long flags;
7446 + int ret;
7447 +
7448 + spin_lock_irqsave(&sbh_lock, flags);
7449 + ret = sbpci_write_config(sbh, dev->bus->number, PCI_SLOT(dev->devfn), PCI_FUNC(dev->devfn), where, &value, sizeof(value));
7450 + spin_unlock_irqrestore(&sbh_lock, flags);
7451 + return ret ? PCIBIOS_DEVICE_NOT_FOUND : PCIBIOS_SUCCESSFUL;
7452 +}
7453 +
7454 +static int
7455 +sbpci_write_config_dword(struct pci_dev *dev, int where, u32 value)
7456 +{
7457 + unsigned long flags;
7458 + int ret;
7459 +
7460 + spin_lock_irqsave(&sbh_lock, flags);
7461 + ret = sbpci_write_config(sbh, dev->bus->number, PCI_SLOT(dev->devfn), PCI_FUNC(dev->devfn), where, &value, sizeof(value));
7462 + spin_unlock_irqrestore(&sbh_lock, flags);
7463 + return ret ? PCIBIOS_DEVICE_NOT_FOUND : PCIBIOS_SUCCESSFUL;
7464 +}
7465 +
7466 +static struct pci_ops pcibios_ops = {
7467 + sbpci_read_config_byte,
7468 + sbpci_read_config_word,
7469 + sbpci_read_config_dword,
7470 + sbpci_write_config_byte,
7471 + sbpci_write_config_word,
7472 + sbpci_write_config_dword
7473 +};
7474 +
7475 +
7476 +void __init
7477 +pcibios_init(void)
7478 +{
7479 + ulong flags;
7480 +
7481 + if (!(sbh = sb_kattach()))
7482 + panic("sb_kattach failed");
7483 + spin_lock_init(&sbh_lock);
7484 +
7485 + spin_lock_irqsave(&sbh_lock, flags);
7486 + sbpci_init(sbh);
7487 + spin_unlock_irqrestore(&sbh_lock, flags);
7488 +
7489 + set_io_port_base((unsigned long) ioremap_nocache(SB_PCI_MEM, 0x04000000));
7490 +
7491 + mdelay(300); //By Joey for Atheros Card
7492 +
7493 + /* Scan the SB bus */
7494 + pci_scan_bus(0, &pcibios_ops, NULL);
7495 +
7496 +}
7497 +
7498 +char * __init
7499 +pcibios_setup(char *str)
7500 +{
7501 + if (!strncmp(str, "ban=", 4)) {
7502 + sbpci_ban(simple_strtoul(str + 4, NULL, 0));
7503 + return NULL;
7504 + }
7505 +
7506 + return (str);
7507 +}
7508 +
7509 +static u32 pci_iobase = 0x100;
7510 +static u32 pci_membase = SB_PCI_DMA;
7511 +
7512 +void __init
7513 +pcibios_fixup_bus(struct pci_bus *b)
7514 +{
7515 + struct list_head *ln;
7516 + struct pci_dev *d;
7517 + struct resource *res;
7518 + int pos, size;
7519 + u32 *base;
7520 + u8 irq;
7521 +
7522 + printk("PCI: Fixing up bus %d\n", b->number);
7523 +
7524 + /* Fix up SB */
7525 + if (b->number == 0) {
7526 + for (ln=b->devices.next; ln != &b->devices; ln=ln->next) {
7527 + d = pci_dev_b(ln);
7528 + /* Fix up interrupt lines */
7529 + pci_read_config_byte(d, PCI_INTERRUPT_LINE, &irq);
7530 + d->irq = irq + 2;
7531 + pci_write_config_byte(d, PCI_INTERRUPT_LINE, d->irq);
7532 + }
7533 + }
7534 +
7535 + /* Fix up external PCI */
7536 + else {
7537 + for (ln=b->devices.next; ln != &b->devices; ln=ln->next) {
7538 + d = pci_dev_b(ln);
7539 + /* Fix up resource bases */
7540 + for (pos = 0; pos < 6; pos++) {
7541 + res = &d->resource[pos];
7542 + base = (res->flags & IORESOURCE_IO) ? &pci_iobase : &pci_membase;
7543 + if (res->end) {
7544 + size = res->end - res->start + 1;
7545 + if (*base & (size - 1))
7546 + *base = (*base + size) & ~(size - 1);
7547 + res->start = *base;
7548 + res->end = res->start + size - 1;
7549 + *base += size;
7550 + pci_write_config_dword(d, PCI_BASE_ADDRESS_0 + (pos << 2), res->start);
7551 + }
7552 + /* Fix up PCI bridge BAR0 only */
7553 + if (b->number == 1 && PCI_SLOT(d->devfn) == 0)
7554 + break;
7555 + }
7556 + /* Fix up interrupt lines */
7557 + if (pci_find_device(VENDOR_BROADCOM, SB_PCI, NULL))
7558 + d->irq = (pci_find_device(VENDOR_BROADCOM, SB_PCI, NULL))->irq;
7559 + pci_write_config_byte(d, PCI_INTERRUPT_LINE, d->irq);
7560 + }
7561 + }
7562 +}
7563 +
7564 +unsigned int
7565 +pcibios_assign_all_busses(void)
7566 +{
7567 + return 1;
7568 +}
7569 +
7570 +void
7571 +pcibios_align_resource(void *data, struct resource *res,
7572 + unsigned long size, unsigned long align)
7573 +{
7574 +}
7575 +
7576 +int
7577 +pcibios_enable_resources(struct pci_dev *dev)
7578 +{
7579 + u16 cmd, old_cmd;
7580 + int idx;
7581 + struct resource *r;
7582 +
7583 + /* External PCI only */
7584 + if (dev->bus->number == 0)
7585 + return 0;
7586 +
7587 + pci_read_config_word(dev, PCI_COMMAND, &cmd);
7588 + old_cmd = cmd;
7589 + for(idx=0; idx<6; idx++) {
7590 + r = &dev->resource[idx];
7591 + if (r->flags & IORESOURCE_IO)
7592 + cmd |= PCI_COMMAND_IO;
7593 + if (r->flags & IORESOURCE_MEM)
7594 + cmd |= PCI_COMMAND_MEMORY;
7595 + }
7596 + if (dev->resource[PCI_ROM_RESOURCE].start)
7597 + cmd |= PCI_COMMAND_MEMORY;
7598 + if (cmd != old_cmd) {
7599 + printk("PCI: Enabling device %s (%04x -> %04x)\n", dev->slot_name, old_cmd, cmd);
7600 + pci_write_config_word(dev, PCI_COMMAND, cmd);
7601 + }
7602 + return 0;
7603 +}
7604 +
7605 +int
7606 +pcibios_enable_device(struct pci_dev *dev, int mask)
7607 +{
7608 + ulong flags;
7609 + uint coreidx;
7610 +
7611 + /* External PCI device enable */
7612 + if (dev->bus->number != 0)
7613 + return pcibios_enable_resources(dev);
7614 +
7615 + /* These cores come out of reset enabled */
7616 + if (dev->device == SB_MIPS ||
7617 + dev->device == SB_MIPS33 ||
7618 + dev->device == SB_EXTIF ||
7619 + dev->device == SB_CC)
7620 + return 0;
7621 +
7622 + spin_lock_irqsave(&sbh_lock, flags);
7623 + coreidx = sb_coreidx(sbh);
7624 + if (!sb_setcoreidx(sbh, PCI_SLOT(dev->devfn)))
7625 + return PCIBIOS_DEVICE_NOT_FOUND;
7626 +
7627 + /*
7628 + * The USB core requires a special bit to be set during core
7629 + * reset to enable host (OHCI) mode. Resetting the SB core in
7630 + * pcibios_enable_device() is a hack for compatibility with
7631 + * vanilla usb-ohci so that it does not have to know about
7632 + * SB. A driver that wants to use the USB core in device mode
7633 + * should know about SB and should reset the bit back to 0
7634 + * after calling pcibios_enable_device().
7635 + */
7636 + if (sb_coreid(sbh) == SB_USB) {
7637 + sb_core_disable(sbh, sb_coreflags(sbh, 0, 0));
7638 + sb_core_reset(sbh, 1 << 29);
7639 + } else
7640 + sb_core_reset(sbh, 0);
7641 +
7642 + sb_setcoreidx(sbh, coreidx);
7643 + spin_unlock_irqrestore(&sbh_lock, flags);
7644 +
7645 + return 0;
7646 +}
7647 +
7648 +void
7649 +pcibios_update_resource(struct pci_dev *dev, struct resource *root,
7650 + struct resource *res, int resource)
7651 +{
7652 + unsigned long where, size;
7653 + u32 reg;
7654 +
7655 + /* External PCI only */
7656 + if (dev->bus->number == 0)
7657 + return;
7658 +
7659 + where = PCI_BASE_ADDRESS_0 + (resource * 4);
7660 + size = res->end - res->start;
7661 + pci_read_config_dword(dev, where, &reg);
7662 + reg = (reg & size) | (((u32)(res->start - root->start)) & ~size);
7663 + pci_write_config_dword(dev, where, reg);
7664 +}
7665 +
7666 +static void __init
7667 +quirk_sbpci_bridge(struct pci_dev *dev)
7668 +{
7669 + if (dev->bus->number != 1 || PCI_SLOT(dev->devfn) != 0)
7670 + return;
7671 +
7672 + printk("PCI: Fixing up bridge\n");
7673 +
7674 + /* Enable PCI bridge bus mastering and memory space */
7675 + pci_set_master(dev);
7676 + pcibios_enable_resources(dev);
7677 +
7678 + /* Enable PCI bridge BAR1 prefetch and burst */
7679 + pci_write_config_dword(dev, PCI_BAR1_CONTROL, 3);
7680 +}
7681 +
7682 +struct pci_fixup pcibios_fixups[] = {
7683 + { PCI_FIXUP_HEADER, PCI_ANY_ID, PCI_ANY_ID, quirk_sbpci_bridge },
7684 + { 0 }
7685 +};
7686 +
7687 +/*
7688 + * If we set up a device for bus mastering, we need to check the latency
7689 + * timer as certain crappy BIOSes forget to set it properly.
7690 + */
7691 +unsigned int pcibios_max_latency = 255;
7692 +
7693 +void pcibios_set_master(struct pci_dev *dev)
7694 +{
7695 + u8 lat;
7696 + pci_read_config_byte(dev, PCI_LATENCY_TIMER, &lat);
7697 + if (lat < 16)
7698 + lat = (64 <= pcibios_max_latency) ? 64 : pcibios_max_latency;
7699 + else if (lat > pcibios_max_latency)
7700 + lat = pcibios_max_latency;
7701 + else
7702 + return;
7703 + printk(KERN_DEBUG "PCI: Setting latency timer of device %s to %d\n", dev->slot_name, lat);
7704 + pci_write_config_byte(dev, PCI_LATENCY_TIMER, lat);
7705 +}
7706 +
7707 diff -Nur linux-2.4.32/arch/mips/bcm947xx/prom.c linux-2.4.32-brcm/arch/mips/bcm947xx/prom.c
7708 --- linux-2.4.32/arch/mips/bcm947xx/prom.c 1970-01-01 01:00:00.000000000 +0100
7709 +++ linux-2.4.32-brcm/arch/mips/bcm947xx/prom.c 2005-12-16 23:39:10.944836750 +0100
7710 @@ -0,0 +1,41 @@
7711 +/*
7712 + * Early initialization code for BCM94710 boards
7713 + *
7714 + * Copyright 2004, Broadcom Corporation
7715 + * All Rights Reserved.
7716 + *
7717 + * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY
7718 + * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM
7719 + * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS
7720 + * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE.
7721 + *
7722 + * $Id: prom.c,v 1.1 2005/03/16 13:49:59 wbx Exp $
7723 + */
7724 +
7725 +#include <linux/config.h>
7726 +#include <linux/init.h>
7727 +#include <linux/kernel.h>
7728 +#include <linux/types.h>
7729 +#include <asm/bootinfo.h>
7730 +
7731 +void __init
7732 +prom_init(int argc, const char **argv)
7733 +{
7734 + unsigned long mem;
7735 +
7736 + mips_machgroup = MACH_GROUP_BRCM;
7737 + mips_machtype = MACH_BCM947XX;
7738 +
7739 + /* Figure out memory size by finding aliases */
7740 + for (mem = (1 << 20); mem < (128 << 20); mem += (1 << 20)) {
7741 + if (*(unsigned long *)((unsigned long)(prom_init) + mem) ==
7742 + *(unsigned long *)(prom_init))
7743 + break;
7744 + }
7745 + add_memory_region(0, mem, BOOT_MEM_RAM);
7746 +}
7747 +
7748 +void __init
7749 +prom_free_prom_memory(void)
7750 +{
7751 +}
7752 diff -Nur linux-2.4.32/arch/mips/bcm947xx/sbmips.c linux-2.4.32-brcm/arch/mips/bcm947xx/sbmips.c
7753 --- linux-2.4.32/arch/mips/bcm947xx/sbmips.c 1970-01-01 01:00:00.000000000 +0100
7754 +++ linux-2.4.32-brcm/arch/mips/bcm947xx/sbmips.c 2005-12-16 23:39:10.944836750 +0100
7755 @@ -0,0 +1,1038 @@
7756 +/*
7757 + * BCM47XX Sonics SiliconBackplane MIPS core routines
7758 + *
7759 + * Copyright 2005, Broadcom Corporation
7760 + * All Rights Reserved.
7761 + *
7762 + * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY
7763 + * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM
7764 + * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS
7765 + * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE.
7766 + *
7767 + * $Id$
7768 + */
7769 +
7770 +#include <typedefs.h>
7771 +#include <osl.h>
7772 +#include <sbutils.h>
7773 +#include <bcmdevs.h>
7774 +#include <bcmnvram.h>
7775 +#include <bcmutils.h>
7776 +#include <hndmips.h>
7777 +#include <sbconfig.h>
7778 +#include <sbextif.h>
7779 +#include <sbchipc.h>
7780 +#include <sbmemc.h>
7781 +#include <mipsinc.h>
7782 +#include <sbutils.h>
7783 +
7784 +/*
7785 + * Returns TRUE if an external UART exists at the given base
7786 + * register.
7787 + */
7788 +static bool
7789 +BCMINITFN(serial_exists)(uint8 *regs)
7790 +{
7791 + uint8 save_mcr, status1;
7792 +
7793 + save_mcr = R_REG(&regs[UART_MCR]);
7794 + W_REG(&regs[UART_MCR], UART_MCR_LOOP | 0x0a);
7795 + status1 = R_REG(&regs[UART_MSR]) & 0xf0;
7796 + W_REG(&regs[UART_MCR], save_mcr);
7797 +
7798 + return (status1 == 0x90);
7799 +}
7800 +
7801 +/*
7802 + * Initializes UART access. The callback function will be called once
7803 + * per found UART.
7804 + */
7805 +void
7806 +BCMINITFN(sb_serial_init)(sb_t *sbh, void (*add)(void *regs, uint irq, uint baud_base, uint reg_shift))
7807 +{
7808 + void *regs;
7809 + ulong base;
7810 + uint irq;
7811 + int i, n;
7812 +
7813 + if ((regs = sb_setcore(sbh, SB_EXTIF, 0))) {
7814 + extifregs_t *eir = (extifregs_t *) regs;
7815 + sbconfig_t *sb;
7816 +
7817 + /* Determine external UART register base */
7818 + sb = (sbconfig_t *)((ulong) eir + SBCONFIGOFF);
7819 + base = EXTIF_CFGIF_BASE(sb_base(R_REG(&sb->sbadmatch1)));
7820 +
7821 + /* Determine IRQ */
7822 + irq = sb_irq(sbh);
7823 +
7824 + /* Disable GPIO interrupt initially */
7825 + W_REG(&eir->gpiointpolarity, 0);
7826 + W_REG(&eir->gpiointmask, 0);
7827 +
7828 + /* Search for external UARTs */
7829 + n = 2;
7830 + for (i = 0; i < 2; i++) {
7831 + regs = (void *) REG_MAP(base + (i * 8), 8);
7832 + if (BCMINIT(serial_exists)(regs)) {
7833 + /* Set GPIO 1 to be the external UART IRQ */
7834 + W_REG(&eir->gpiointmask, 2);
7835 + if (add)
7836 + add(regs, irq, 13500000, 0);
7837 + }
7838 + }
7839 +
7840 + /* Add internal UART if enabled */
7841 + if (R_REG(&eir->corecontrol) & CC_UE)
7842 + if (add)
7843 + add((void *) &eir->uartdata, irq, sb_clock(sbh), 2);
7844 + } else if ((regs = sb_setcore(sbh, SB_CC, 0))) {
7845 + chipcregs_t *cc = (chipcregs_t *) regs;
7846 + uint32 rev, cap, pll, baud_base, div;
7847 +
7848 + /* Determine core revision and capabilities */
7849 + rev = sb_corerev(sbh);
7850 + cap = R_REG(&cc->capabilities);
7851 + pll = cap & CAP_PLL_MASK;
7852 +
7853 + /* Determine IRQ */
7854 + irq = sb_irq(sbh);
7855 +
7856 + if (pll == PLL_TYPE1) {
7857 + /* PLL clock */
7858 + baud_base = sb_clock_rate(pll,
7859 + R_REG(&cc->clockcontrol_n),
7860 + R_REG(&cc->clockcontrol_m2));
7861 + div = 1;
7862 + } else {
7863 + if (rev >= 11) {
7864 + /* Fixed ALP clock */
7865 + baud_base = 20000000;
7866 + div = 1;
7867 + /* Set the override bit so we don't divide it */
7868 + W_REG(&cc->corecontrol, CC_UARTCLKO);
7869 + } else if (rev >= 3) {
7870 + /* Internal backplane clock */
7871 + baud_base = sb_clock(sbh);
7872 + div = 2; /* Minimum divisor */
7873 + W_REG(&cc->clkdiv,
7874 + ((R_REG(&cc->clkdiv) & ~CLKD_UART) | div));
7875 + } else {
7876 + /* Fixed internal backplane clock */
7877 + baud_base = 88000000;
7878 + div = 48;
7879 + }
7880 +
7881 + /* Clock source depends on strapping if UartClkOverride is unset */
7882 + if ((rev > 0) &&
7883 + ((R_REG(&cc->corecontrol) & CC_UARTCLKO) == 0)) {
7884 + if ((cap & CAP_UCLKSEL) == CAP_UINTCLK) {
7885 + /* Internal divided backplane clock */
7886 + baud_base /= div;
7887 + } else {
7888 + /* Assume external clock of 1.8432 MHz */
7889 + baud_base = 1843200;
7890 + }
7891 + }
7892 + }
7893 +
7894 + /* Add internal UARTs */
7895 + n = cap & CAP_UARTS_MASK;
7896 + for (i = 0; i < n; i++) {
7897 + /* Register offset changed after revision 0 */
7898 + if (rev)
7899 + regs = (void *)((ulong) &cc->uart0data + (i * 256));
7900 + else
7901 + regs = (void *)((ulong) &cc->uart0data + (i * 8));
7902 +
7903 + if (add)
7904 + add(regs, irq, baud_base, 0);
7905 + }
7906 + }
7907 +}
7908 +
7909 +/*
7910 + * Initialize jtag master and return handle for
7911 + * jtag_rwreg. Returns NULL on failure.
7912 + */
7913 +void *
7914 +sb_jtagm_init(sb_t *sbh, uint clkd, bool exttap)
7915 +{
7916 + void *regs;
7917 +
7918 + if ((regs = sb_setcore(sbh, SB_CC, 0)) != NULL) {
7919 + chipcregs_t *cc = (chipcregs_t *) regs;
7920 + uint32 tmp;
7921 +
7922 + /*
7923 + * Determine jtagm availability from
7924 + * core revision and capabilities.
7925 + */
7926 + tmp = sb_corerev(sbh);
7927 + /*
7928 + * Corerev 10 has jtagm, but the only chip
7929 + * with it does not have a mips, and
7930 + * the layout of the jtagcmd register is
7931 + * different. We'll only accept >= 11.
7932 + */
7933 + if (tmp < 11)
7934 + return (NULL);
7935 +
7936 + tmp = R_REG(&cc->capabilities);
7937 + if ((tmp & CAP_JTAGP) == 0)
7938 + return (NULL);
7939 +
7940 + /* Set clock divider if requested */
7941 + if (clkd != 0) {
7942 + tmp = R_REG(&cc->clkdiv);
7943 + tmp = (tmp & ~CLKD_JTAG) |
7944 + ((clkd << CLKD_JTAG_SHIFT) & CLKD_JTAG);
7945 + W_REG(&cc->clkdiv, tmp);
7946 + }
7947 +
7948 + /* Enable jtagm */
7949 + tmp = JCTRL_EN | (exttap ? JCTRL_EXT_EN : 0);
7950 + W_REG(&cc->jtagctrl, tmp);
7951 + }
7952 +
7953 + return (regs);
7954 +}
7955 +
7956 +void
7957 +sb_jtagm_disable(void *h)
7958 +{
7959 + chipcregs_t *cc = (chipcregs_t *)h;
7960 +
7961 + W_REG(&cc->jtagctrl, R_REG(&cc->jtagctrl) & ~JCTRL_EN);
7962 +}
7963 +
7964 +/*
7965 + * Read/write a jtag register. Assumes a target with
7966 + * 8 bit IR and 32 bit DR.
7967 + */
7968 +#define IRWIDTH 8
7969 +#define DRWIDTH 32
7970 +uint32
7971 +jtag_rwreg(void *h, uint32 ir, uint32 dr)
7972 +{
7973 + chipcregs_t *cc = (chipcregs_t *) h;
7974 + uint32 tmp;
7975 +
7976 + W_REG(&cc->jtagir, ir);
7977 + W_REG(&cc->jtagdr, dr);
7978 + tmp = JCMD_START | JCMD_ACC_IRDR |
7979 + ((IRWIDTH - 1) << JCMD_IRW_SHIFT) |
7980 + (DRWIDTH - 1);
7981 + W_REG(&cc->jtagcmd, tmp);
7982 + while (((tmp = R_REG(&cc->jtagcmd)) & JCMD_BUSY) == JCMD_BUSY) {
7983 + /* OSL_DELAY(1); */
7984 + }
7985 +
7986 + tmp = R_REG(&cc->jtagdr);
7987 + return (tmp);
7988 +}
7989 +
7990 +/* Returns the SB interrupt flag of the current core. */
7991 +uint32
7992 +sb_flag(sb_t *sbh)
7993 +{
7994 + void *regs;
7995 + sbconfig_t *sb;
7996 +
7997 + regs = sb_coreregs(sbh);
7998 + sb = (sbconfig_t *)((ulong) regs + SBCONFIGOFF);
7999 +
8000 + return (R_REG(&sb->sbtpsflag) & SBTPS_NUM0_MASK);
8001 +}
8002 +
8003 +static const uint32 sbips_int_mask[] = {
8004 + 0,
8005 + SBIPS_INT1_MASK,
8006 + SBIPS_INT2_MASK,
8007 + SBIPS_INT3_MASK,
8008 + SBIPS_INT4_MASK
8009 +};
8010 +
8011 +static const uint32 sbips_int_shift[] = {
8012 + 0,
8013 + 0,
8014 + SBIPS_INT2_SHIFT,
8015 + SBIPS_INT3_SHIFT,
8016 + SBIPS_INT4_SHIFT
8017 +};
8018 +
8019 +/*
8020 + * Returns the MIPS IRQ assignment of the current core. If unassigned,
8021 + * 0 is returned.
8022 + */
8023 +uint
8024 +sb_irq(sb_t *sbh)
8025 +{
8026 + uint idx;
8027 + void *regs;
8028 + sbconfig_t *sb;
8029 + uint32 flag, sbipsflag;
8030 + uint irq = 0;
8031 +
8032 + flag = sb_flag(sbh);
8033 +
8034 + idx = sb_coreidx(sbh);
8035 +
8036 + if ((regs = sb_setcore(sbh, SB_MIPS, 0)) ||
8037 + (regs = sb_setcore(sbh, SB_MIPS33, 0))) {
8038 + sb = (sbconfig_t *)((ulong) regs + SBCONFIGOFF);
8039 +
8040 + /* sbipsflag specifies which core is routed to interrupts 1 to 4 */
8041 + sbipsflag = R_REG(&sb->sbipsflag);
8042 + for (irq = 1; irq <= 4; irq++) {
8043 + if (((sbipsflag & sbips_int_mask[irq]) >> sbips_int_shift[irq]) == flag)
8044 + break;
8045 + }
8046 + if (irq == 5)
8047 + irq = 0;
8048 + }
8049 +
8050 + sb_setcoreidx(sbh, idx);
8051 +
8052 + return irq;
8053 +}
8054 +
8055 +/* Clears the specified MIPS IRQ. */
8056 +static void
8057 +BCMINITFN(sb_clearirq)(sb_t *sbh, uint irq)
8058 +{
8059 + void *regs;
8060 + sbconfig_t *sb;
8061 +
8062 + if (!(regs = sb_setcore(sbh, SB_MIPS, 0)) &&
8063 + !(regs = sb_setcore(sbh, SB_MIPS33, 0)))
8064 + ASSERT(regs);
8065 + sb = (sbconfig_t *)((ulong) regs + SBCONFIGOFF);
8066 +
8067 + if (irq == 0)
8068 + W_REG(&sb->sbintvec, 0);
8069 + else
8070 + OR_REG(&sb->sbipsflag, sbips_int_mask[irq]);
8071 +}
8072 +
8073 +/*
8074 + * Assigns the specified MIPS IRQ to the specified core. Shared MIPS
8075 + * IRQ 0 may be assigned more than once.
8076 + */
8077 +static void
8078 +BCMINITFN(sb_setirq)(sb_t *sbh, uint irq, uint coreid, uint coreunit)
8079 +{
8080 + void *regs;
8081 + sbconfig_t *sb;
8082 + uint32 flag;
8083 +
8084 + regs = sb_setcore(sbh, coreid, coreunit);
8085 + ASSERT(regs);
8086 + flag = sb_flag(sbh);
8087 +
8088 + if (!(regs = sb_setcore(sbh, SB_MIPS, 0)) &&
8089 + !(regs = sb_setcore(sbh, SB_MIPS33, 0)))
8090 + ASSERT(regs);
8091 + sb = (sbconfig_t *)((ulong) regs + SBCONFIGOFF);
8092 +
8093 + if (irq == 0)
8094 + OR_REG(&sb->sbintvec, 1 << flag);
8095 + else {
8096 + flag <<= sbips_int_shift[irq];
8097 + ASSERT(!(flag & ~sbips_int_mask[irq]));
8098 + flag |= R_REG(&sb->sbipsflag) & ~sbips_int_mask[irq];
8099 + W_REG(&sb->sbipsflag, flag);
8100 + }
8101 +}
8102 +
8103 +/*
8104 + * Initializes clocks and interrupts. SB and NVRAM access must be
8105 + * initialized prior to calling.
8106 + */
8107 +void
8108 +BCMINITFN(sb_mips_init)(sb_t *sbh)
8109 +{
8110 + ulong hz, ns, tmp;
8111 + extifregs_t *eir;
8112 + chipcregs_t *cc;
8113 + char *value;
8114 + uint irq;
8115 +
8116 + /* Figure out current SB clock speed */
8117 + if ((hz = sb_clock(sbh)) == 0)
8118 + hz = 100000000;
8119 + ns = 1000000000 / hz;
8120 +
8121 + /* Setup external interface timing */
8122 + if ((eir = sb_setcore(sbh, SB_EXTIF, 0))) {
8123 + /* Initialize extif so we can get to the LEDs and external UART */
8124 + W_REG(&eir->prog_config, CF_EN);
8125 +
8126 + /* Set timing for the flash */
8127 + tmp = CEIL(10, ns) << FW_W3_SHIFT; /* W3 = 10nS */
8128 + tmp = tmp | (CEIL(40, ns) << FW_W1_SHIFT); /* W1 = 40nS */
8129 + tmp = tmp | CEIL(120, ns); /* W0 = 120nS */
8130 + W_REG(&eir->prog_waitcount, tmp); /* 0x01020a0c for a 100Mhz clock */
8131 +
8132 + /* Set programmable interface timing for external uart */
8133 + tmp = CEIL(10, ns) << FW_W3_SHIFT; /* W3 = 10nS */
8134 + tmp = tmp | (CEIL(20, ns) << FW_W2_SHIFT); /* W2 = 20nS */
8135 + tmp = tmp | (CEIL(100, ns) << FW_W1_SHIFT); /* W1 = 100nS */
8136 + tmp = tmp | CEIL(120, ns); /* W0 = 120nS */
8137 + W_REG(&eir->prog_waitcount, tmp); /* 0x01020a0c for a 100Mhz clock */
8138 + } else if ((cc = sb_setcore(sbh, SB_CC, 0))) {
8139 + /* Set timing for the flash */
8140 + tmp = CEIL(10, ns) << FW_W3_SHIFT; /* W3 = 10nS */
8141 + tmp |= CEIL(10, ns) << FW_W1_SHIFT; /* W1 = 10nS */
8142 + tmp |= CEIL(120, ns); /* W0 = 120nS */
8143 +
8144 + // Added by Chen-I for 5365
8145 + if (BCMINIT(sb_chip)(sbh) == BCM5365_DEVICE_ID)
8146 + {
8147 + W_REG(&cc->flash_waitcount, tmp);
8148 + W_REG(&cc->pcmcia_memwait, tmp);
8149 + }
8150 + else
8151 + {
8152 + if (sb_corerev(sbh) < 9)
8153 + W_REG(&cc->flash_waitcount, tmp);
8154 +
8155 + if ((sb_corerev(sbh) < 9) ||
8156 + ((BCMINIT(sb_chip)(sbh) == BCM5350_DEVICE_ID) && BCMINIT(sb_chiprev)(sbh) == 0)) {
8157 + W_REG(&cc->pcmcia_memwait, tmp);
8158 + }
8159 + }
8160 + }
8161 +
8162 + /* Chip specific initialization */
8163 + switch (BCMINIT(sb_chip)(sbh)) {
8164 + case BCM4710_DEVICE_ID:
8165 + /* Clear interrupt map */
8166 + for (irq = 0; irq <= 4; irq++)
8167 + BCMINIT(sb_clearirq)(sbh, irq);
8168 + BCMINIT(sb_setirq)(sbh, 0, SB_CODEC, 0);
8169 + BCMINIT(sb_setirq)(sbh, 0, SB_EXTIF, 0);
8170 + BCMINIT(sb_setirq)(sbh, 2, SB_ENET, 1);
8171 + BCMINIT(sb_setirq)(sbh, 3, SB_ILINE20, 0);
8172 + BCMINIT(sb_setirq)(sbh, 4, SB_PCI, 0);
8173 + ASSERT(eir);
8174 + value = BCMINIT(nvram_get)("et0phyaddr");
8175 + if (value && !strcmp(value, "31")) {
8176 + /* Enable internal UART */
8177 + W_REG(&eir->corecontrol, CC_UE);
8178 + /* Give USB its own interrupt */
8179 + BCMINIT(sb_setirq)(sbh, 1, SB_USB, 0);
8180 + } else {
8181 + /* Disable internal UART */
8182 + W_REG(&eir->corecontrol, 0);
8183 + /* Give Ethernet its own interrupt */
8184 + BCMINIT(sb_setirq)(sbh, 1, SB_ENET, 0);
8185 + BCMINIT(sb_setirq)(sbh, 0, SB_USB, 0);
8186 + }
8187 + break;
8188 + case BCM5350_DEVICE_ID:
8189 + /* Clear interrupt map */
8190 + for (irq = 0; irq <= 4; irq++)
8191 + BCMINIT(sb_clearirq)(sbh, irq);
8192 + BCMINIT(sb_setirq)(sbh, 0, SB_CC, 0);
8193 + BCMINIT(sb_setirq)(sbh, 1, SB_D11, 0);
8194 + BCMINIT(sb_setirq)(sbh, 2, SB_ENET, 0);
8195 + BCMINIT(sb_setirq)(sbh, 3, SB_PCI, 0);
8196 + BCMINIT(sb_setirq)(sbh, 4, SB_USB, 0);
8197 + break;
8198 + }
8199 +}
8200 +
8201 +uint32
8202 +BCMINITFN(sb_mips_clock)(sb_t *sbh)
8203 +{
8204 + extifregs_t *eir;
8205 + chipcregs_t *cc;
8206 + uint32 n, m;
8207 + uint idx;
8208 + uint32 pll_type, rate = 0;
8209 +
8210 + /* get index of the current core */
8211 + idx = sb_coreidx(sbh);
8212 + pll_type = PLL_TYPE1;
8213 +
8214 + /* switch to extif or chipc core */
8215 + if ((eir = (extifregs_t *) sb_setcore(sbh, SB_EXTIF, 0))) {
8216 + n = R_REG(&eir->clockcontrol_n);
8217 + m = R_REG(&eir->clockcontrol_sb);
8218 + } else if ((cc = (chipcregs_t *) sb_setcore(sbh, SB_CC, 0))) {
8219 + pll_type = R_REG(&cc->capabilities) & CAP_PLL_MASK;
8220 + n = R_REG(&cc->clockcontrol_n);
8221 + if ((pll_type == PLL_TYPE2) ||
8222 + (pll_type == PLL_TYPE4) ||
8223 + (pll_type == PLL_TYPE6) ||
8224 + (pll_type == PLL_TYPE7))
8225 + m = R_REG(&cc->clockcontrol_mips);
8226 + else if (pll_type == PLL_TYPE5) {
8227 + rate = 200000000;
8228 + goto out;
8229 + }
8230 + else if (pll_type == PLL_TYPE3) {
8231 + if (BCMINIT(sb_chip)(sbh) == BCM5365_DEVICE_ID) { /* 5365 is also type3 */
8232 + rate = 200000000;
8233 + goto out;
8234 + } else
8235 + m = R_REG(&cc->clockcontrol_m2); /* 5350 uses m2 to control mips */
8236 + } else
8237 + m = R_REG(&cc->clockcontrol_sb);
8238 + } else
8239 + goto out;
8240 +
8241 + // Added by Chen-I for 5365
8242 + if (BCMINIT(sb_chip)(sbh) == BCM5365_DEVICE_ID)
8243 + rate = 100000000;
8244 + else
8245 + /* calculate rate */
8246 + rate = sb_clock_rate(pll_type, n, m);
8247 +
8248 + if (pll_type == PLL_TYPE6)
8249 + rate = SB2MIPS_T6(rate);
8250 +
8251 +out:
8252 + /* switch back to previous core */
8253 + sb_setcoreidx(sbh, idx);
8254 +
8255 + return rate;
8256 +}
8257 +
8258 +#define ALLINTS (IE_IRQ0 | IE_IRQ1 | IE_IRQ2 | IE_IRQ3 | IE_IRQ4)
8259 +
8260 +static void
8261 +BCMINITFN(handler)(void)
8262 +{
8263 + /* Step 11 */
8264 + __asm__ (
8265 + ".set\tmips32\n\t"
8266 + "ssnop\n\t"
8267 + "ssnop\n\t"
8268 + /* Disable interrupts */
8269 + /* MTC0(C0_STATUS, 0, MFC0(C0_STATUS, 0) & ~(ALLINTS | STO_IE)); */
8270 + "mfc0 $15, $12\n\t"
8271 + /* Just a Hack to not to use reg 'at' which was causing problems on 4704 A2 */
8272 + "li $14, -31746\n\t"
8273 + "and $15, $15, $14\n\t"
8274 + "mtc0 $15, $12\n\t"
8275 + "eret\n\t"
8276 + "nop\n\t"
8277 + "nop\n\t"
8278 + ".set\tmips0"
8279 + );
8280 +}
8281 +
8282 +/* The following MUST come right after handler() */
8283 +static void
8284 +BCMINITFN(afterhandler)(void)
8285 +{
8286 +}
8287 +
8288 +/*
8289 + * Set the MIPS, backplane and PCI clocks as closely as possible.
8290 + */
8291 +bool
8292 +BCMINITFN(sb_mips_setclock)(sb_t *sbh, uint32 mipsclock, uint32 sbclock, uint32 pciclock)
8293 +{
8294 + extifregs_t *eir = NULL;
8295 + chipcregs_t *cc = NULL;
8296 + mipsregs_t *mipsr = NULL;
8297 + volatile uint32 *clockcontrol_n, *clockcontrol_sb, *clockcontrol_pci, *clockcontrol_m2;
8298 + uint32 orig_n, orig_sb, orig_pci, orig_m2, orig_mips, orig_ratio_parm, orig_ratio_cfg;
8299 + uint32 pll_type, sync_mode;
8300 + uint ic_size, ic_lsize;
8301 + uint idx, i;
8302 + typedef struct {
8303 + uint32 mipsclock;
8304 + uint16 n;
8305 + uint32 sb;
8306 + uint32 pci33;
8307 + uint32 pci25;
8308 + } n3m_table_t;
8309 + static n3m_table_t BCMINITDATA(type1_table)[] = {
8310 + { 96000000, 0x0303, 0x04020011, 0x11030011, 0x11050011 }, /* 96.000 32.000 24.000 */
8311 + { 100000000, 0x0009, 0x04020011, 0x11030011, 0x11050011 }, /* 100.000 33.333 25.000 */
8312 + { 104000000, 0x0802, 0x04020011, 0x11050009, 0x11090009 }, /* 104.000 31.200 24.960 */
8313 + { 108000000, 0x0403, 0x04020011, 0x11050009, 0x02000802 }, /* 108.000 32.400 24.923 */
8314 + { 112000000, 0x0205, 0x04020011, 0x11030021, 0x02000403 }, /* 112.000 32.000 24.889 */
8315 + { 115200000, 0x0303, 0x04020009, 0x11030011, 0x11050011 }, /* 115.200 32.000 24.000 */
8316 + { 120000000, 0x0011, 0x04020011, 0x11050011, 0x11090011 }, /* 120.000 30.000 24.000 */
8317 + { 124800000, 0x0802, 0x04020009, 0x11050009, 0x11090009 }, /* 124.800 31.200 24.960 */
8318 + { 128000000, 0x0305, 0x04020011, 0x11050011, 0x02000305 }, /* 128.000 32.000 24.000 */
8319 + { 132000000, 0x0603, 0x04020011, 0x11050011, 0x02000305 }, /* 132.000 33.000 24.750 */
8320 + { 136000000, 0x0c02, 0x04020011, 0x11090009, 0x02000603 }, /* 136.000 32.640 24.727 */
8321 + { 140000000, 0x0021, 0x04020011, 0x11050021, 0x02000c02 }, /* 140.000 30.000 24.706 */
8322 + { 144000000, 0x0405, 0x04020011, 0x01020202, 0x11090021 }, /* 144.000 30.857 24.686 */
8323 + { 150857142, 0x0605, 0x04020021, 0x02000305, 0x02000605 }, /* 150.857 33.000 24.000 */
8324 + { 152000000, 0x0e02, 0x04020011, 0x11050021, 0x02000e02 }, /* 152.000 32.571 24.000 */
8325 + { 156000000, 0x0802, 0x04020005, 0x11050009, 0x11090009 }, /* 156.000 31.200 24.960 */
8326 + { 160000000, 0x0309, 0x04020011, 0x11090011, 0x02000309 }, /* 160.000 32.000 24.000 */
8327 + { 163200000, 0x0c02, 0x04020009, 0x11090009, 0x02000603 }, /* 163.200 32.640 24.727 */
8328 + { 168000000, 0x0205, 0x04020005, 0x11030021, 0x02000403 }, /* 168.000 32.000 24.889 */
8329 + { 176000000, 0x0602, 0x04020003, 0x11050005, 0x02000602 }, /* 176.000 33.000 24.000 */
8330 + };
8331 + typedef struct {
8332 + uint32 mipsclock;
8333 + uint16 n;
8334 + uint32 m2; /* that is the clockcontrol_m2 */
8335 + } type3_table_t;
8336 + static type3_table_t type3_table[] = { /* for 5350, mips clock is always double sb clock */
8337 + { 150000000, 0x311, 0x4020005 },
8338 + { 200000000, 0x311, 0x4020003 },
8339 + };
8340 + typedef struct {
8341 + uint32 mipsclock;
8342 + uint32 sbclock;
8343 + uint16 n;
8344 + uint32 sb;
8345 + uint32 pci33;
8346 + uint32 m2;
8347 + uint32 m3;
8348 + uint32 ratio_cfg;
8349 + uint32 ratio_parm;
8350 + } n4m_table_t;
8351 +
8352 + static n4m_table_t BCMINITDATA(type2_table)[] = {
8353 + { 180000000, 80000000, 0x0403, 0x01010000, 0x01020300, 0x01020600, 0x05000100, 8, 0x012a00a9 },
8354 + { 180000000, 90000000, 0x0403, 0x01000100, 0x01020300, 0x01000100, 0x05000100, 11, 0x0aaa0555 },
8355 + { 200000000, 100000000, 0x0303, 0x02010000, 0x02040001, 0x02010000, 0x06000001, 11, 0x0aaa0555 },
8356 + { 211200000, 105600000, 0x0902, 0x01000200, 0x01030400, 0x01000200, 0x05000200, 11, 0x0aaa0555 },
8357 + { 220800000, 110400000, 0x1500, 0x01000200, 0x01030400, 0x01000200, 0x05000200, 11, 0x0aaa0555 },
8358 + { 230400000, 115200000, 0x0604, 0x01000200, 0x01020600, 0x01000200, 0x05000200, 11, 0x0aaa0555 },
8359 + { 234000000, 104000000, 0x0b01, 0x01010000, 0x01010700, 0x01020600, 0x05000100, 8, 0x012a00a9 },
8360 + { 240000000, 120000000, 0x0803, 0x01000200, 0x01020600, 0x01000200, 0x05000200, 11, 0x0aaa0555 },
8361 + { 252000000, 126000000, 0x0504, 0x01000100, 0x01020500, 0x01000100, 0x05000100, 11, 0x0aaa0555 },
8362 + { 264000000, 132000000, 0x0903, 0x01000200, 0x01020700, 0x01000200, 0x05000200, 11, 0x0aaa0555 },
8363 + { 270000000, 120000000, 0x0703, 0x01010000, 0x01030400, 0x01020600, 0x05000100, 8, 0x012a00a9 },
8364 + { 276000000, 122666666, 0x1500, 0x01010000, 0x01030400, 0x01020600, 0x05000100, 8, 0x012a00a9 },
8365 + { 280000000, 140000000, 0x0503, 0x01000000, 0x01010600, 0x01000000, 0x05000000, 11, 0x0aaa0555 },
8366 + { 288000000, 128000000, 0x0604, 0x01010000, 0x01030400, 0x01020600, 0x05000100, 8, 0x012a00a9 },
8367 + { 288000000, 144000000, 0x0404, 0x01000000, 0x01010600, 0x01000000, 0x05000000, 11, 0x0aaa0555 },
8368 + { 300000000, 133333333, 0x0803, 0x01010000, 0x01020600, 0x01020600, 0x05000100, 8, 0x012a00a9 },
8369 + { 300000000, 150000000, 0x0803, 0x01000100, 0x01020600, 0x01000100, 0x05000100, 11, 0x0aaa0555 }
8370 + };
8371 +
8372 + static n4m_table_t BCMINITDATA(type4_table)[] = {
8373 + { 192000000, 96000000, 0x0702, 0x04000011, 0x11030011, 0x04000011, 0x04000003, 11, 0x0aaa0555 },
8374 + { 198000000, 99000000, 0x0603, 0x11020005, 0x11030011, 0x11020005, 0x04000005, 11, 0x0aaa0555 },
8375 + { 200000000, 100000000, 0x0009, 0x04020011, 0x11030011, 0x04020011, 0x04020003, 11, 0x0aaa0555 },
8376 + { 204000000, 102000000, 0x0c02, 0x11020005, 0x01030303, 0x11020005, 0x04000005, 11, 0x0aaa0555 },
8377 + { 208000000, 104000000, 0x0802, 0x11030002, 0x11090005, 0x11030002, 0x04000003, 11, 0x0aaa0555 },
8378 + { 210000000, 105000000, 0x0209, 0x11020005, 0x01030303, 0x11020005, 0x04000005, 11, 0x0aaa0555 },
8379 + { 216000000, 108000000, 0x0111, 0x11020005, 0x01030303, 0x11020005, 0x04000005, 11, 0x0aaa0555 },
8380 + { 224000000, 112000000, 0x0205, 0x11030002, 0x02002103, 0x11030002, 0x04000003, 11, 0x0aaa0555 },
8381 + { 228000000, 101333333, 0x0e02, 0x11030003, 0x11210005, 0x01030305, 0x04000005, 8, 0x012a00a9 },
8382 + { 228000000, 114000000, 0x0e02, 0x11020005, 0x11210005, 0x11020005, 0x04000005, 11, 0x0aaa0555 },
8383 + { 240000000, 102857143, 0x0109, 0x04000021, 0x01050203, 0x11030021, 0x04000003, 13, 0x254a14a9 },
8384 + { 240000000, 120000000, 0x0109, 0x11030002, 0x01050203, 0x11030002, 0x04000003, 11, 0x0aaa0555 },
8385 + { 252000000, 100800000, 0x0203, 0x04000009, 0x11050005, 0x02000209, 0x04000002, 9, 0x02520129 },
8386 + { 252000000, 126000000, 0x0203, 0x04000005, 0x11050005, 0x04000005, 0x04000002, 11, 0x0aaa0555 },
8387 + { 264000000, 132000000, 0x0602, 0x04000005, 0x11050005, 0x04000005, 0x04000002, 11, 0x0aaa0555 },
8388 + { 272000000, 116571428, 0x0c02, 0x04000021, 0x02000909, 0x02000221, 0x04000003, 13, 0x254a14a9 },
8389 + { 280000000, 120000000, 0x0209, 0x04000021, 0x01030303, 0x02000221, 0x04000003, 13, 0x254a14a9 },
8390 + { 288000000, 123428571, 0x0111, 0x04000021, 0x01030303, 0x02000221, 0x04000003, 13, 0x254a14a9 },
8391 + { 300000000, 120000000, 0x0009, 0x04000009, 0x01030203, 0x02000902, 0x04000002, 9, 0x02520129 },
8392 + { 300000000, 150000000, 0x0009, 0x04000005, 0x01030203, 0x04000005, 0x04000002, 11, 0x0aaa0555 }
8393 + };
8394 +
8395 + static n4m_table_t BCMINITDATA(type7_table)[] = {
8396 + { 183333333, 91666666, 0x0605, 0x04000011, 0x11030011, 0x04000011, 0x04000003, 11, 0x0aaa0555 },
8397 + { 187500000, 93750000, 0x0a03, 0x04000011, 0x11030011, 0x04000011, 0x04000003, 11, 0x0aaa0555 },
8398 + { 196875000, 98437500, 0x1003, 0x11020005, 0x11050011, 0x11020005, 0x04000005, 11, 0x0aaa0555 },
8399 + { 200000000, 100000000, 0x0311, 0x04000011, 0x11030011, 0x04000009, 0x04000003, 11, 0x0aaa0555 },
8400 + { 200000000, 100000000, 0x0311, 0x04020011, 0x11030011, 0x04020011, 0x04020003, 11, 0x0aaa0555 },
8401 + { 206250000, 103125000, 0x1103, 0x11020005, 0x11050011, 0x11020005, 0x04000005, 11, 0x0aaa0555 },
8402 + { 212500000, 106250000, 0x0c05, 0x11020005, 0x01030303, 0x11020005, 0x04000005, 11, 0x0aaa0555 },
8403 + { 215625000, 107812500, 0x1203, 0x11090009, 0x11050005, 0x11020005, 0x04000005, 11, 0x0aaa0555 },
8404 + { 216666666, 108333333, 0x0805, 0x11020003, 0x11030011, 0x11020003, 0x04000003, 11, 0x0aaa0555 },
8405 + { 225000000, 112500000, 0x0d03, 0x11020003, 0x11030011, 0x11020003, 0x04000003, 11, 0x0aaa0555 },
8406 + { 233333333, 116666666, 0x0905, 0x11020003, 0x11030011, 0x11020003, 0x04000003, 11, 0x0aaa0555 },
8407 + { 237500000, 118750000, 0x0e05, 0x11020005, 0x11210005, 0x11020005, 0x04000005, 11, 0x0aaa0555 },
8408 + { 240000000, 120000000, 0x0b11, 0x11020009, 0x11210009, 0x11020009, 0x04000009, 11, 0x0aaa0555 },
8409 + { 250000000, 125000000, 0x0f03, 0x11020003, 0x11210003, 0x11020003, 0x04000003, 11, 0x0aaa0555 }
8410 + };
8411 +
8412 + ulong start, end, dst;
8413 + bool ret = FALSE;
8414 +
8415 + /* get index of the current core */
8416 + idx = sb_coreidx(sbh);
8417 + clockcontrol_m2 = NULL;
8418 +
8419 + /* switch to extif or chipc core */
8420 + if ((eir = (extifregs_t *) sb_setcore(sbh, SB_EXTIF, 0))) {
8421 + pll_type = PLL_TYPE1;
8422 + clockcontrol_n = &eir->clockcontrol_n;
8423 + clockcontrol_sb = &eir->clockcontrol_sb;
8424 + clockcontrol_pci = &eir->clockcontrol_pci;
8425 + clockcontrol_m2 = &cc->clockcontrol_m2;
8426 + } else if ((cc = (chipcregs_t *) sb_setcore(sbh, SB_CC, 0))) {
8427 + pll_type = R_REG(&cc->capabilities) & CAP_PLL_MASK;
8428 + if (pll_type == PLL_TYPE6) {
8429 + clockcontrol_n = NULL;
8430 + clockcontrol_sb = NULL;
8431 + clockcontrol_pci = NULL;
8432 + } else {
8433 + clockcontrol_n = &cc->clockcontrol_n;
8434 + clockcontrol_sb = &cc->clockcontrol_sb;
8435 + clockcontrol_pci = &cc->clockcontrol_pci;
8436 + clockcontrol_m2 = &cc->clockcontrol_m2;
8437 + }
8438 + } else
8439 + goto done;
8440 +
8441 + if (pll_type == PLL_TYPE6) {
8442 + /* Silence compilers */
8443 + orig_n = orig_sb = orig_pci = 0;
8444 + } else {
8445 + /* Store the current clock register values */
8446 + orig_n = R_REG(clockcontrol_n);
8447 + orig_sb = R_REG(clockcontrol_sb);
8448 + orig_pci = R_REG(clockcontrol_pci);
8449 + }
8450 +
8451 + if (pll_type == PLL_TYPE1) {
8452 + /* Keep the current PCI clock if not specified */
8453 + if (pciclock == 0) {
8454 + pciclock = sb_clock_rate(pll_type, R_REG(clockcontrol_n), R_REG(clockcontrol_pci));
8455 + pciclock = (pciclock <= 25000000) ? 25000000 : 33000000;
8456 + }
8457 +
8458 + /* Search for the closest MIPS clock less than or equal to a preferred value */
8459 + for (i = 0; i < ARRAYSIZE(BCMINIT(type1_table)); i++) {
8460 + ASSERT(BCMINIT(type1_table)[i].mipsclock ==
8461 + sb_clock_rate(pll_type, BCMINIT(type1_table)[i].n, BCMINIT(type1_table)[i].sb));
8462 + if (BCMINIT(type1_table)[i].mipsclock > mipsclock)
8463 + break;
8464 + }
8465 + if (i == 0) {
8466 + ret = FALSE;
8467 + goto done;
8468 + } else {
8469 + ret = TRUE;
8470 + i--;
8471 + }
8472 + ASSERT(BCMINIT(type1_table)[i].mipsclock <= mipsclock);
8473 +
8474 + /* No PLL change */
8475 + if ((orig_n == BCMINIT(type1_table)[i].n) &&
8476 + (orig_sb == BCMINIT(type1_table)[i].sb) &&
8477 + (orig_pci == BCMINIT(type1_table)[i].pci33))
8478 + goto done;
8479 +
8480 + /* Set the PLL controls */
8481 + W_REG(clockcontrol_n, BCMINIT(type1_table)[i].n);
8482 + W_REG(clockcontrol_sb, BCMINIT(type1_table)[i].sb);
8483 + if (pciclock == 25000000)
8484 + W_REG(clockcontrol_pci, BCMINIT(type1_table)[i].pci25);
8485 + else
8486 + W_REG(clockcontrol_pci, BCMINIT(type1_table)[i].pci33);
8487 +
8488 + /* Reset */
8489 + sb_watchdog(sbh, 1);
8490 +
8491 + while (1);
8492 + } else if ((pll_type == PLL_TYPE3) &&
8493 + (BCMINIT(sb_chip)(sbh) != BCM5365_DEVICE_ID)) {
8494 + /* 5350 */
8495 + /* Search for the closest MIPS clock less than or equal to a preferred value */
8496 +
8497 + for (i = 0; i < ARRAYSIZE(type3_table); i++) {
8498 + if (type3_table[i].mipsclock > mipsclock)
8499 + break;
8500 + }
8501 + if (i == 0) {
8502 + ret = FALSE;
8503 + goto done;
8504 + } else {
8505 + ret = TRUE;
8506 + i--;
8507 + }
8508 + ASSERT(type3_table[i].mipsclock <= mipsclock);
8509 +
8510 + /* No PLL change */
8511 + orig_m2 = R_REG(&cc->clockcontrol_m2);
8512 + if ((orig_n == type3_table[i].n) &&
8513 + (orig_m2 == type3_table[i].m2)) {
8514 + goto done;
8515 + }
8516 +
8517 + /* Set the PLL controls */
8518 + W_REG(clockcontrol_n, type3_table[i].n);
8519 + W_REG(clockcontrol_m2, type3_table[i].m2);
8520 +
8521 + /* Reset */
8522 + sb_watchdog(sbh, 1);
8523 + while (1);
8524 + } else if ((pll_type == PLL_TYPE2) ||
8525 + (pll_type == PLL_TYPE4) ||
8526 + (pll_type == PLL_TYPE6) ||
8527 + (pll_type == PLL_TYPE7)) {
8528 + n4m_table_t *table = NULL, *te;
8529 + uint tabsz = 0;
8530 +
8531 + ASSERT(cc);
8532 +
8533 + orig_mips = R_REG(&cc->clockcontrol_mips);
8534 +
8535 + if (pll_type == PLL_TYPE6) {
8536 + uint32 new_mips = 0;
8537 +
8538 + ret = TRUE;
8539 + if (mipsclock <= SB2MIPS_T6(CC_T6_M1))
8540 + new_mips = CC_T6_MMASK;
8541 +
8542 + if (orig_mips == new_mips)
8543 + goto done;
8544 +
8545 + W_REG(&cc->clockcontrol_mips, new_mips);
8546 + goto end_fill;
8547 + }
8548 +
8549 + if (pll_type == PLL_TYPE2) {
8550 + table = BCMINIT(type2_table);
8551 + tabsz = ARRAYSIZE(BCMINIT(type2_table));
8552 + } else if (pll_type == PLL_TYPE4) {
8553 + table = BCMINIT(type4_table);
8554 + tabsz = ARRAYSIZE(BCMINIT(type4_table));
8555 + } else if (pll_type == PLL_TYPE7) {
8556 + table = BCMINIT(type7_table);
8557 + tabsz = ARRAYSIZE(BCMINIT(type7_table));
8558 + } else
8559 + ASSERT("No table for plltype" == NULL);
8560 +
8561 + /* Store the current clock register values */
8562 + orig_m2 = R_REG(&cc->clockcontrol_m2);
8563 + orig_ratio_parm = 0;
8564 + orig_ratio_cfg = 0;
8565 +
8566 + /* Look up current ratio */
8567 + for (i = 0; i < tabsz; i++) {
8568 + if ((orig_n == table[i].n) &&
8569 + (orig_sb == table[i].sb) &&
8570 + (orig_pci == table[i].pci33) &&
8571 + (orig_m2 == table[i].m2) &&
8572 + (orig_mips == table[i].m3)) {
8573 + orig_ratio_parm = table[i].ratio_parm;
8574 + orig_ratio_cfg = table[i].ratio_cfg;
8575 + break;
8576 + }
8577 + }
8578 +
8579 + /* Search for the closest MIPS clock greater or equal to a preferred value */
8580 + for (i = 0; i < tabsz; i++) {
8581 + ASSERT(table[i].mipsclock ==
8582 + sb_clock_rate(pll_type, table[i].n, table[i].m3));
8583 + if ((mipsclock <= table[i].mipsclock) &&
8584 + ((sbclock == 0) || (sbclock <= table[i].sbclock)))
8585 + break;
8586 + }
8587 + if (i == tabsz) {
8588 + ret = FALSE;
8589 + goto done;
8590 + } else {
8591 + te = &table[i];
8592 + ret = TRUE;
8593 + }
8594 +
8595 + /* No PLL change */
8596 + if ((orig_n == te->n) &&
8597 + (orig_sb == te->sb) &&
8598 + (orig_pci == te->pci33) &&
8599 + (orig_m2 == te->m2) &&
8600 + (orig_mips == te->m3))
8601 + goto done;
8602 +
8603 + /* Set the PLL controls */
8604 + W_REG(clockcontrol_n, te->n);
8605 + W_REG(clockcontrol_sb, te->sb);
8606 + W_REG(clockcontrol_pci, te->pci33);
8607 + W_REG(&cc->clockcontrol_m2, te->m2);
8608 + W_REG(&cc->clockcontrol_mips, te->m3);
8609 +
8610 + /* Set the chipcontrol bit to change mipsref to the backplane divider if needed */
8611 + if ((pll_type == PLL_TYPE7) &&
8612 + (te->sb != te->m2) &&
8613 + (sb_clock_rate(pll_type, te->n, te->m2) == 120000000))
8614 + W_REG(&cc->chipcontrol, R_REG(&cc->chipcontrol) | 0x100);
8615 +
8616 + /* No ratio change */
8617 + if (orig_ratio_parm == te->ratio_parm)
8618 + goto end_fill;
8619 +
8620 + icache_probe(MFC0(C0_CONFIG, 1), &ic_size, &ic_lsize);
8621 +
8622 + /* Preload the code into the cache */
8623 + start = ((ulong) &&start_fill) & ~(ic_lsize - 1);
8624 + end = ((ulong) &&end_fill + (ic_lsize - 1)) & ~(ic_lsize - 1);
8625 + while (start < end) {
8626 + cache_op(start, Fill_I);
8627 + start += ic_lsize;
8628 + }
8629 +
8630 + /* Copy the handler */
8631 + start = (ulong) &BCMINIT(handler);
8632 + end = (ulong) &BCMINIT(afterhandler);
8633 + dst = KSEG1ADDR(0x180);
8634 + for (i = 0; i < (end - start); i += 4)
8635 + *((ulong *)(dst + i)) = *((ulong *)(start + i));
8636 +
8637 + /* Preload handler into the cache one line at a time */
8638 + for (i = 0; i < (end - start); i += 4)
8639 + cache_op(dst + i, Fill_I);
8640 +
8641 + /* Clear BEV bit */
8642 + MTC0(C0_STATUS, 0, MFC0(C0_STATUS, 0) & ~ST0_BEV);
8643 +
8644 + /* Enable interrupts */
8645 + MTC0(C0_STATUS, 0, MFC0(C0_STATUS, 0) | (ALLINTS | ST0_IE));
8646 +
8647 + /* Enable MIPS timer interrupt */
8648 + if (!(mipsr = sb_setcore(sbh, SB_MIPS, 0)) &&
8649 + !(mipsr = sb_setcore(sbh, SB_MIPS33, 0)))
8650 + ASSERT(mipsr);
8651 + W_REG(&mipsr->intmask, 1);
8652 +
8653 + start_fill:
8654 + /* step 1, set clock ratios */
8655 + MTC0(C0_BROADCOM, 3, te->ratio_parm);
8656 + MTC0(C0_BROADCOM, 1, te->ratio_cfg);
8657 +
8658 + /* step 2: program timer intr */
8659 + W_REG(&mipsr->timer, 100);
8660 + (void) R_REG(&mipsr->timer);
8661 +
8662 + /* step 3, switch to async */
8663 + sync_mode = MFC0(C0_BROADCOM, 4);
8664 + MTC0(C0_BROADCOM, 4, 1 << 22);
8665 +
8666 + /* step 4, set cfg active */
8667 + MTC0(C0_BROADCOM, 2, 0x9);
8668 +
8669 +
8670 + /* steps 5 & 6 */
8671 + __asm__ __volatile__ (
8672 + ".set\tmips3\n\t"
8673 + "wait\n\t"
8674 + ".set\tmips0"
8675 + );
8676 +
8677 + /* step 7, clear cfg_active */
8678 + MTC0(C0_BROADCOM, 2, 0);
8679 +
8680 + /* Additional Step: set back to orig sync mode */
8681 + MTC0(C0_BROADCOM, 4, sync_mode);
8682 +
8683 + /* step 8, fake soft reset */
8684 + MTC0(C0_BROADCOM, 5, MFC0(C0_BROADCOM, 5) | 4);
8685 +
8686 + end_fill:
8687 + /* step 9 set watchdog timer */
8688 + sb_watchdog(sbh, 20);
8689 + (void) R_REG(&cc->chipid);
8690 +
8691 + /* step 11 */
8692 + __asm__ __volatile__ (
8693 + ".set\tmips3\n\t"
8694 + "sync\n\t"
8695 + "wait\n\t"
8696 + ".set\tmips0"
8697 + );
8698 + while (1);
8699 + }
8700 +
8701 +done:
8702 + /* switch back to previous core */
8703 + sb_setcoreidx(sbh, idx);
8704 +
8705 + return ret;
8706 +}
8707 +
8708 +/*
8709 + * This also must be run from the cache on 47xx
8710 + * so there are no mips core BIU ops in progress
8711 + * when the PFC is enabled.
8712 + */
8713 +
8714 +static void
8715 +BCMINITFN(_enable_pfc)(uint32 mode)
8716 +{
8717 + /* write range */
8718 + *(volatile uint32 *)PFC_CR1 = 0xffff0000;
8719 +
8720 + /* enable */
8721 + *(volatile uint32 *)PFC_CR0 = mode;
8722 +}
8723 +
8724 +void
8725 +BCMINITFN(enable_pfc)(uint32 mode)
8726 +{
8727 + ulong start, end;
8728 + int i;
8729 +
8730 + /* If auto then choose the correct mode for this
8731 + platform, currently we only ever select one mode */
8732 + if (mode == PFC_AUTO)
8733 + mode = PFC_INST;
8734 +
8735 + /* enable prefetch cache if available */
8736 + if (MFC0(C0_BROADCOM, 0) & BRCM_PFC_AVAIL) {
8737 + start = (ulong) &BCMINIT(_enable_pfc);
8738 + end = (ulong) &BCMINIT(enable_pfc);
8739 +
8740 + /* Preload handler into the cache one line at a time */
8741 + for (i = 0; i < (end - start); i += 4)
8742 + cache_op(start + i, Fill_I);
8743 +
8744 + BCMINIT(_enable_pfc)(mode);
8745 + }
8746 +}
8747 +
8748 +/* returns the ncdl value to be programmed into sdram_ncdl for calibration */
8749 +uint32
8750 +BCMINITFN(sb_memc_get_ncdl)(sb_t *sbh)
8751 +{
8752 + sbmemcregs_t *memc;
8753 + uint32 ret = 0;
8754 + uint32 config, rd, wr, misc, dqsg, cd, sm, sd;
8755 + uint idx, rev;
8756 +
8757 + idx = sb_coreidx(sbh);
8758 +
8759 + memc = (sbmemcregs_t *)sb_setcore(sbh, SB_MEMC, 0);
8760 + if (memc == 0)
8761 + goto out;
8762 +
8763 + rev = sb_corerev(sbh);
8764 +
8765 + config = R_REG(&memc->config);
8766 + wr = R_REG(&memc->wrncdlcor);
8767 + rd = R_REG(&memc->rdncdlcor);
8768 + misc = R_REG(&memc->miscdlyctl);
8769 + dqsg = R_REG(&memc->dqsgatencdl);
8770 +
8771 + rd &= MEMC_RDNCDLCOR_RD_MASK;
8772 + wr &= MEMC_WRNCDLCOR_WR_MASK;
8773 + dqsg &= MEMC_DQSGATENCDL_G_MASK;
8774 +
8775 + if (config & MEMC_CONFIG_DDR) {
8776 + ret = (wr << 16) | (rd << 8) | dqsg;
8777 + } else {
8778 + if (rev > 0)
8779 + cd = rd;
8780 + else
8781 + cd = (rd == MEMC_CD_THRESHOLD) ? rd : (wr + MEMC_CD_THRESHOLD);
8782 + sm = (misc & MEMC_MISC_SM_MASK) >> MEMC_MISC_SM_SHIFT;
8783 + sd = (misc & MEMC_MISC_SD_MASK) >> MEMC_MISC_SD_SHIFT;
8784 + ret = (sm << 16) | (sd << 8) | cd;
8785 + }
8786 +
8787 +out:
8788 + /* switch back to previous core */
8789 + sb_setcoreidx(sbh, idx);
8790 +
8791 + return ret;
8792 +}
8793 +
8794 diff -Nur linux-2.4.32/arch/mips/bcm947xx/sbpci.c linux-2.4.32-brcm/arch/mips/bcm947xx/sbpci.c
8795 --- linux-2.4.32/arch/mips/bcm947xx/sbpci.c 1970-01-01 01:00:00.000000000 +0100
8796 +++ linux-2.4.32-brcm/arch/mips/bcm947xx/sbpci.c 2005-12-16 23:39:10.948837000 +0100
8797 @@ -0,0 +1,588 @@
8798 +/*
8799 + * Low-Level PCI and SB support for BCM47xx
8800 + *
8801 + * Copyright 2005, Broadcom Corporation
8802 + * All Rights Reserved.
8803 + *
8804 + * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY
8805 + * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM
8806 + * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS
8807 + * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE.
8808 + *
8809 + * $Id$
8810 + */
8811 +
8812 +#include <typedefs.h>
8813 +#include <pcicfg.h>
8814 +#include <bcmdevs.h>
8815 +#include <sbconfig.h>
8816 +#include <osl.h>
8817 +#include <sbutils.h>
8818 +#include <sbpci.h>
8819 +#include <bcmendian.h>
8820 +#include <bcmutils.h>
8821 +#include <bcmnvram.h>
8822 +#include <hndmips.h>
8823 +
8824 +/* Can free sbpci_init() memory after boot */
8825 +#ifndef linux
8826 +#define __init
8827 +#endif
8828 +
8829 +/* Emulated configuration space */
8830 +static pci_config_regs sb_config_regs[SB_MAXCORES];
8831 +
8832 +/* Banned cores */
8833 +static uint16 pci_ban[32] = { 0 };
8834 +static uint pci_banned = 0;
8835 +
8836 +/* CardBus mode */
8837 +static bool cardbus = FALSE;
8838 +
8839 +/* Disable PCI host core */
8840 +static bool pci_disabled = FALSE;
8841 +
8842 +/*
8843 + * Functions for accessing external PCI configuration space
8844 + */
8845 +
8846 +/* Assume one-hot slot wiring */
8847 +#define PCI_SLOT_MAX 16
8848 +
8849 +static uint32
8850 +config_cmd(sb_t *sbh, uint bus, uint dev, uint func, uint off)
8851 +{
8852 + uint coreidx;
8853 + sbpciregs_t *regs;
8854 + uint32 addr = 0;
8855 +
8856 + /* CardBusMode supports only one device */
8857 + if (cardbus && dev > 1)
8858 + return 0;
8859 +
8860 + coreidx = sb_coreidx(sbh);
8861 + regs = (sbpciregs_t *) sb_setcore(sbh, SB_PCI, 0);
8862 +
8863 + /* Type 0 transaction */
8864 + if (bus == 1) {
8865 + /* Skip unwired slots */
8866 + if (dev < PCI_SLOT_MAX) {
8867 + /* Slide the PCI window to the appropriate slot */
8868 + W_REG(&regs->sbtopci1, SBTOPCI_CFG0 | ((1 << (dev + 16)) & SBTOPCI1_MASK));
8869 + addr = SB_PCI_CFG | ((1 << (dev + 16)) & ~SBTOPCI1_MASK) |
8870 + (func << 8) | (off & ~3);
8871 + }
8872 + }
8873 +
8874 + /* Type 1 transaction */
8875 + else {
8876 + W_REG(&regs->sbtopci1, SBTOPCI_CFG1);
8877 + addr = SB_PCI_CFG | (bus << 16) | (dev << 11) | (func << 8) | (off & ~3);
8878 + }
8879 +
8880 + sb_setcoreidx(sbh, coreidx);
8881 +
8882 + return addr;
8883 +}
8884 +
8885 +static int
8886 +extpci_read_config(sb_t *sbh, uint bus, uint dev, uint func, uint off, void *buf, int len)
8887 +{
8888 + uint32 addr, *reg = NULL, val;
8889 + int ret = 0;
8890 +
8891 + if (pci_disabled ||
8892 + !(addr = config_cmd(sbh, bus, dev, func, off)) ||
8893 + !(reg = (uint32 *) REG_MAP(addr, len)) ||
8894 + BUSPROBE(val, reg))
8895 + val = 0xffffffff;
8896 +
8897 + val >>= 8 * (off & 3);
8898 + if (len == 4)
8899 + *((uint32 *) buf) = val;
8900 + else if (len == 2)
8901 + *((uint16 *) buf) = (uint16) val;
8902 + else if (len == 1)
8903 + *((uint8 *) buf) = (uint8) val;
8904 + else
8905 + ret = -1;
8906 +
8907 + if (reg)
8908 + REG_UNMAP(reg);
8909 +
8910 + return ret;
8911 +}
8912 +
8913 +static int
8914 +extpci_write_config(sb_t *sbh, uint bus, uint dev, uint func, uint off, void *buf, int len)
8915 +{
8916 + uint32 addr, *reg = NULL, val;
8917 + int ret = 0;
8918 +
8919 + if (pci_disabled ||
8920 + !(addr = config_cmd(sbh, bus, dev, func, off)) ||
8921 + !(reg = (uint32 *) REG_MAP(addr, len)) ||
8922 + BUSPROBE(val, reg))
8923 + goto done;
8924 +
8925 + if (len == 4)
8926 + val = *((uint32 *) buf);
8927 + else if (len == 2) {
8928 + val &= ~(0xffff << (8 * (off & 3)));
8929 + val |= *((uint16 *) buf) << (8 * (off & 3));
8930 + } else if (len == 1) {
8931 + val &= ~(0xff << (8 * (off & 3)));
8932 + val |= *((uint8 *) buf) << (8 * (off & 3));
8933 + } else
8934 + ret = -1;
8935 +
8936 + W_REG(reg, val);
8937 +
8938 + done:
8939 + if (reg)
8940 + REG_UNMAP(reg);
8941 +
8942 + return ret;
8943 +}
8944 +
8945 +/*
8946 + * Functions for accessing translated SB configuration space
8947 + */
8948 +
8949 +static int
8950 +sb_read_config(sb_t *sbh, uint bus, uint dev, uint func, uint off, void *buf, int len)
8951 +{
8952 + pci_config_regs *cfg;
8953 +
8954 + if (dev >= SB_MAXCORES || (off + len) > sizeof(pci_config_regs))
8955 + return -1;
8956 + cfg = &sb_config_regs[dev];
8957 +
8958 + ASSERT(ISALIGNED(off, len));
8959 + ASSERT(ISALIGNED((uintptr)buf, len));
8960 +
8961 + if (len == 4)
8962 + *((uint32 *) buf) = ltoh32(*((uint32 *)((ulong) cfg + off)));
8963 + else if (len == 2)
8964 + *((uint16 *) buf) = ltoh16(*((uint16 *)((ulong) cfg + off)));
8965 + else if (len == 1)
8966 + *((uint8 *) buf) = *((uint8 *)((ulong) cfg + off));
8967 + else
8968 + return -1;
8969 +
8970 + return 0;
8971 +}
8972 +
8973 +static int
8974 +sb_write_config(sb_t *sbh, uint bus, uint dev, uint func, uint off, void *buf, int len)
8975 +{
8976 + uint coreidx, n;
8977 + void *regs;
8978 + sbconfig_t *sb;
8979 + pci_config_regs *cfg;
8980 +
8981 + if (dev >= SB_MAXCORES || (off + len) > sizeof(pci_config_regs))
8982 + return -1;
8983 + cfg = &sb_config_regs[dev];
8984 +
8985 + ASSERT(ISALIGNED(off, len));
8986 + ASSERT(ISALIGNED((uintptr)buf, len));
8987 +
8988 + /* Emulate BAR sizing */
8989 + if (off >= OFFSETOF(pci_config_regs, base[0]) && off <= OFFSETOF(pci_config_regs, base[3]) &&
8990 + len == 4 && *((uint32 *) buf) == ~0) {
8991 + coreidx = sb_coreidx(sbh);
8992 + if ((regs = sb_setcoreidx(sbh, dev))) {
8993 + sb = (sbconfig_t *)((ulong) regs + SBCONFIGOFF);
8994 + /* Highest numbered address match register */
8995 + n = (R_REG(&sb->sbidlow) & SBIDL_AR_MASK) >> SBIDL_AR_SHIFT;
8996 + if (off == OFFSETOF(pci_config_regs, base[0]))
8997 + cfg->base[0] = ~(sb_size(R_REG(&sb->sbadmatch0)) - 1);
8998 + else if (off == OFFSETOF(pci_config_regs, base[1]) && n >= 1)
8999 + cfg->base[1] = ~(sb_size(R_REG(&sb->sbadmatch1)) - 1);
9000 + else if (off == OFFSETOF(pci_config_regs, base[2]) && n >= 2)
9001 + cfg->base[2] = ~(sb_size(R_REG(&sb->sbadmatch2)) - 1);
9002 + else if (off == OFFSETOF(pci_config_regs, base[3]) && n >= 3)
9003 + cfg->base[3] = ~(sb_size(R_REG(&sb->sbadmatch3)) - 1);
9004 + }
9005 + sb_setcoreidx(sbh, coreidx);
9006 + return 0;
9007 + }
9008 +
9009 + if (len == 4)
9010 + *((uint32 *)((ulong) cfg + off)) = htol32(*((uint32 *) buf));
9011 + else if (len == 2)
9012 + *((uint16 *)((ulong) cfg + off)) = htol16(*((uint16 *) buf));
9013 + else if (len == 1)
9014 + *((uint8 *)((ulong) cfg + off)) = *((uint8 *) buf);
9015 + else
9016 + return -1;
9017 +
9018 + return 0;
9019 +}
9020 +
9021 +int
9022 +sbpci_read_config(sb_t *sbh, uint bus, uint dev, uint func, uint off, void *buf, int len)
9023 +{
9024 + if (bus == 0)
9025 + return sb_read_config(sbh, bus, dev, func, off, buf, len);
9026 + else
9027 + return extpci_read_config(sbh, bus, dev, func, off, buf, len);
9028 +}
9029 +
9030 +int
9031 +sbpci_write_config(sb_t *sbh, uint bus, uint dev, uint func, uint off, void *buf, int len)
9032 +{
9033 + if (bus == 0)
9034 + return sb_write_config(sbh, bus, dev, func, off, buf, len);
9035 + else
9036 + return extpci_write_config(sbh, bus, dev, func, off, buf, len);
9037 +}
9038 +
9039 +void
9040 +sbpci_ban(uint16 core)
9041 +{
9042 + if (pci_banned < ARRAYSIZE(pci_ban))
9043 + pci_ban[pci_banned++] = core;
9044 +}
9045 +
9046 +static int
9047 +sbpci_init_pci(sb_t *sbh)
9048 +{
9049 + uint chip, chiprev, chippkg, host;
9050 + uint32 boardflags;
9051 + sbpciregs_t *pci;
9052 + sbconfig_t *sb;
9053 + uint32 val;
9054 +
9055 + chip = sb_chip(sbh);
9056 + chiprev = sb_chiprev(sbh);
9057 + chippkg = sb_chippkg(sbh);
9058 +
9059 + if (!(pci = (sbpciregs_t *) sb_setcore(sbh, SB_PCI, 0))) {
9060 + printf("PCI: no core\n");
9061 + pci_disabled = TRUE;
9062 + return -1;
9063 + }
9064 + sb_core_reset(sbh, 0);
9065 +
9066 + boardflags = (uint32) getintvar(NULL, "boardflags");
9067 +
9068 + if ((chip == BCM4310_DEVICE_ID) && (chiprev == 0))
9069 + pci_disabled = TRUE;
9070 +
9071 + /*
9072 + * The 200-pin BCM4712 package does not bond out PCI. Even when
9073 + * PCI is bonded out, some boards may leave the pins
9074 + * floating.
9075 + */
9076 + if (((chip == BCM4712_DEVICE_ID) &&
9077 + ((chippkg == BCM4712SMALL_PKG_ID) ||
9078 + (chippkg == BCM4712MID_PKG_ID))) ||
9079 + (boardflags & BFL_NOPCI))
9080 + pci_disabled = TRUE;
9081 +
9082 + /*
9083 + * If the PCI core should not be touched (disabled, not bonded
9084 + * out, or pins floating), do not even attempt to access core
9085 + * registers. Otherwise, try to determine if it is in host
9086 + * mode.
9087 + */
9088 + if (pci_disabled)
9089 + host = 0;
9090 + else
9091 + host = !BUSPROBE(val, &pci->control);
9092 +
9093 + if (!host) {
9094 + /* Disable PCI interrupts in client mode */
9095 + sb = (sbconfig_t *)((ulong) pci + SBCONFIGOFF);
9096 + W_REG(&sb->sbintvec, 0);
9097 +
9098 + /* Disable the PCI bridge in client mode */
9099 + sbpci_ban(SB_PCI);
9100 + printf("PCI: Disabled\n");
9101 + } else {
9102 + /* Reset the external PCI bus and enable the clock */
9103 + W_REG(&pci->control, 0x5); /* enable the tristate drivers */
9104 + W_REG(&pci->control, 0xd); /* enable the PCI clock */
9105 + OSL_DELAY(150); /* delay > 100 us */
9106 + W_REG(&pci->control, 0xf); /* deassert PCI reset */
9107 + W_REG(&pci->arbcontrol, PCI_INT_ARB); /* use internal arbiter */
9108 + OSL_DELAY(1); /* delay 1 us */
9109 +
9110 + /* Enable CardBusMode */
9111 + cardbus = nvram_match("cardbus", "1");
9112 + if (cardbus) {
9113 + printf("PCI: Enabling CardBus\n");
9114 + /* GPIO 1 resets the CardBus device on bcm94710ap */
9115 + sb_gpioout(sbh, 1, 1, GPIO_DRV_PRIORITY);
9116 + sb_gpioouten(sbh, 1, 1, GPIO_DRV_PRIORITY);
9117 + W_REG(&pci->sprom[0], R_REG(&pci->sprom[0]) | 0x400);
9118 + }
9119 +
9120 + /* 64 MB I/O access window */
9121 + W_REG(&pci->sbtopci0, SBTOPCI_IO);
9122 + /* 64 MB configuration access window */
9123 + W_REG(&pci->sbtopci1, SBTOPCI_CFG0);
9124 + /* 1 GB memory access window */
9125 + W_REG(&pci->sbtopci2, SBTOPCI_MEM | SB_PCI_DMA);
9126 +
9127 + /* Enable PCI bridge BAR0 prefetch and burst */
9128 + val = 6;
9129 + sbpci_write_config(sbh, 1, 0, 0, PCI_CFG_CMD, &val, sizeof(val));
9130 +
9131 + /* Enable PCI interrupts */
9132 + W_REG(&pci->intmask, PCI_INTA);
9133 + }
9134 +
9135 + return 0;
9136 +}
9137 +
9138 +static int
9139 +sbpci_init_cores(sb_t *sbh)
9140 +{
9141 + uint chip, chiprev, chippkg, coreidx, i;
9142 + sbconfig_t *sb;
9143 + pci_config_regs *cfg;
9144 + void *regs;
9145 + char varname[8];
9146 + uint wlidx = 0;
9147 + uint16 vendor, core;
9148 + uint8 class, subclass, progif;
9149 + uint32 val;
9150 + uint32 sbips_int_mask[] = { 0, SBIPS_INT1_MASK, SBIPS_INT2_MASK, SBIPS_INT3_MASK, SBIPS_INT4_MASK };
9151 + uint32 sbips_int_shift[] = { 0, 0, SBIPS_INT2_SHIFT, SBIPS_INT3_SHIFT, SBIPS_INT4_SHIFT };
9152 +
9153 + chip = sb_chip(sbh);
9154 + chiprev = sb_chiprev(sbh);
9155 + chippkg = sb_chippkg(sbh);
9156 + coreidx = sb_coreidx(sbh);
9157 +
9158 + /* Scan the SB bus */
9159 + bzero(sb_config_regs, sizeof(sb_config_regs));
9160 + for (cfg = sb_config_regs; cfg < &sb_config_regs[SB_MAXCORES]; cfg++) {
9161 + cfg->vendor = 0xffff;
9162 + if (!(regs = sb_setcoreidx(sbh, cfg - sb_config_regs)))
9163 + continue;
9164 + sb = (sbconfig_t *)((ulong) regs + SBCONFIGOFF);
9165 +
9166 + /* Read ID register and parse vendor and core */
9167 + val = R_REG(&sb->sbidhigh);
9168 + vendor = (val & SBIDH_VC_MASK) >> SBIDH_VC_SHIFT;
9169 + core = (val & SBIDH_CC_MASK) >> SBIDH_CC_SHIFT;
9170 + progif = 0;
9171 +
9172 + /* Check if this core is banned */
9173 + for (i = 0; i < pci_banned; i++)
9174 + if (core == pci_ban[i])
9175 + break;
9176 + if (i < pci_banned)
9177 + continue;
9178 +
9179 + /* Known vendor translations */
9180 + switch (vendor) {
9181 + case SB_VEND_BCM:
9182 + vendor = VENDOR_BROADCOM;
9183 + break;
9184 + }
9185 +
9186 + /* Determine class based on known core codes */
9187 + switch (core) {
9188 + case SB_ILINE20:
9189 + class = PCI_CLASS_NET;
9190 + subclass = PCI_NET_ETHER;
9191 + core = BCM47XX_ILINE_ID;
9192 + break;
9193 + case SB_ILINE100:
9194 + class = PCI_CLASS_NET;
9195 + subclass = PCI_NET_ETHER;
9196 + core = BCM4610_ILINE_ID;
9197 + break;
9198 + case SB_ENET:
9199 + class = PCI_CLASS_NET;
9200 + subclass = PCI_NET_ETHER;
9201 + core = BCM47XX_ENET_ID;
9202 + break;
9203 + case SB_SDRAM:
9204 + case SB_MEMC:
9205 + class = PCI_CLASS_MEMORY;
9206 + subclass = PCI_MEMORY_RAM;
9207 + break;
9208 + case SB_PCI:
9209 + class = PCI_CLASS_BRIDGE;
9210 + subclass = PCI_BRIDGE_PCI;
9211 + break;
9212 + case SB_MIPS:
9213 + case SB_MIPS33:
9214 + class = PCI_CLASS_CPU;
9215 + subclass = PCI_CPU_MIPS;
9216 + break;
9217 + case SB_CODEC:
9218 + class = PCI_CLASS_COMM;
9219 + subclass = PCI_COMM_MODEM;
9220 + core = BCM47XX_V90_ID;
9221 + break;
9222 + case SB_USB:
9223 + class = PCI_CLASS_SERIAL;
9224 + subclass = PCI_SERIAL_USB;
9225 + progif = 0x10; /* OHCI */
9226 + core = BCM47XX_USB_ID;
9227 + break;
9228 + case SB_USB11H:
9229 + class = PCI_CLASS_SERIAL;
9230 + subclass = PCI_SERIAL_USB;
9231 + progif = 0x10; /* OHCI */
9232 + core = BCM47XX_USBH_ID;
9233 + break;
9234 + case SB_USB11D:
9235 + class = PCI_CLASS_SERIAL;
9236 + subclass = PCI_SERIAL_USB;
9237 + core = BCM47XX_USBD_ID;
9238 + break;
9239 + case SB_IPSEC:
9240 + class = PCI_CLASS_CRYPT;
9241 + subclass = PCI_CRYPT_NETWORK;
9242 + core = BCM47XX_IPSEC_ID;
9243 + break;
9244 + case SB_ROBO:
9245 + class = PCI_CLASS_NET;
9246 + subclass = PCI_NET_OTHER;
9247 + core = BCM47XX_ROBO_ID;
9248 + break;
9249 + case SB_EXTIF:
9250 + case SB_CC:
9251 + class = PCI_CLASS_MEMORY;
9252 + subclass = PCI_MEMORY_FLASH;
9253 + break;
9254 + case SB_D11:
9255 + class = PCI_CLASS_NET;
9256 + subclass = PCI_NET_OTHER;
9257 + /* Let an nvram variable override this */
9258 + sprintf(varname, "wl%did", wlidx);
9259 + wlidx++;
9260 + if ((core = getintvar(NULL, varname)) == 0) {
9261 + if (chip == BCM4712_DEVICE_ID) {
9262 + if (chippkg == BCM4712SMALL_PKG_ID)
9263 + core = BCM4306_D11G_ID;
9264 + else
9265 + core = BCM4306_D11DUAL_ID;
9266 + } else {
9267 + /* 4310 */
9268 + core = BCM4310_D11B_ID;
9269 + }
9270 + }
9271 + break;
9272 +
9273 + default:
9274 + class = subclass = progif = 0xff;
9275 + break;
9276 + }
9277 +
9278 + /* Supported translations */
9279 + cfg->vendor = htol16(vendor);
9280 + cfg->device = htol16(core);
9281 + cfg->rev_id = chiprev;
9282 + cfg->prog_if = progif;
9283 + cfg->sub_class = subclass;
9284 + cfg->base_class = class;
9285 + cfg->base[0] = htol32(sb_base(R_REG(&sb->sbadmatch0)));
9286 + cfg->base[1] = htol32(sb_base(R_REG(&sb->sbadmatch1)));
9287 + cfg->base[2] = htol32(sb_base(R_REG(&sb->sbadmatch2)));
9288 + cfg->base[3] = htol32(sb_base(R_REG(&sb->sbadmatch3)));
9289 + cfg->base[4] = 0;
9290 + cfg->base[5] = 0;
9291 + if (class == PCI_CLASS_BRIDGE && subclass == PCI_BRIDGE_PCI)
9292 + cfg->header_type = PCI_HEADER_BRIDGE;
9293 + else
9294 + cfg->header_type = PCI_HEADER_NORMAL;
9295 + /* Save core interrupt flag */
9296 + cfg->int_pin = R_REG(&sb->sbtpsflag) & SBTPS_NUM0_MASK;
9297 + /* Default to MIPS shared interrupt 0 */
9298 + cfg->int_line = 0;
9299 + /* MIPS sbipsflag maps core interrupt flags to interrupts 1 through 4 */
9300 + if ((regs = sb_setcore(sbh, SB_MIPS, 0)) ||
9301 + (regs = sb_setcore(sbh, SB_MIPS33, 0))) {
9302 + sb = (sbconfig_t *)((ulong) regs + SBCONFIGOFF);
9303 + val = R_REG(&sb->sbipsflag);
9304 + for (cfg->int_line = 1; cfg->int_line <= 4; cfg->int_line++) {
9305 + if (((val & sbips_int_mask[cfg->int_line]) >> sbips_int_shift[cfg->int_line]) == cfg->int_pin)
9306 + break;
9307 + }
9308 + if (cfg->int_line > 4)
9309 + cfg->int_line = 0;
9310 + }
9311 + /* Emulated core */
9312 + *((uint32 *) &cfg->sprom_control) = 0xffffffff;
9313 + }
9314 +
9315 + sb_setcoreidx(sbh, coreidx);
9316 + return 0;
9317 +}
9318 +
9319 +int __init
9320 +sbpci_init(sb_t *sbh)
9321 +{
9322 + sbpci_init_pci(sbh);
9323 + sbpci_init_cores(sbh);
9324 + return 0;
9325 +}
9326 +
9327 +void
9328 +sbpci_check(sb_t *sbh)
9329 +{
9330 + uint coreidx;
9331 + sbpciregs_t *pci;
9332 + uint32 sbtopci1;
9333 + uint32 buf[64], *ptr, i;
9334 + ulong pa;
9335 + volatile uint j;
9336 +
9337 + coreidx = sb_coreidx(sbh);
9338 + pci = (sbpciregs_t *) sb_setcore(sbh, SB_PCI, 0);
9339 +
9340 + /* Clear the test array */
9341 + pa = (ulong) DMA_MAP(NULL, buf, sizeof(buf), DMA_RX, NULL);
9342 + ptr = (uint32 *) OSL_UNCACHED(&buf[0]);
9343 + memset(ptr, 0, sizeof(buf));
9344 +
9345 + /* Point PCI window 1 to memory */
9346 + sbtopci1 = R_REG(&pci->sbtopci1);
9347 + W_REG(&pci->sbtopci1, SBTOPCI_MEM | (pa & SBTOPCI1_MASK));
9348 +
9349 + /* Fill the test array via PCI window 1 */
9350 + ptr = (uint32 *) REG_MAP(SB_PCI_CFG + (pa & ~SBTOPCI1_MASK), sizeof(buf));
9351 + for (i = 0; i < ARRAYSIZE(buf); i++) {
9352 + for (j = 0; j < 2; j++);
9353 + W_REG(&ptr[i], i);
9354 + }
9355 + REG_UNMAP(ptr);
9356 +
9357 + /* Restore PCI window 1 */
9358 + W_REG(&pci->sbtopci1, sbtopci1);
9359 +
9360 + /* Check the test array */
9361 + DMA_UNMAP(NULL, pa, sizeof(buf), DMA_RX, NULL);
9362 + ptr = (uint32 *) OSL_UNCACHED(&buf[0]);
9363 + for (i = 0; i < ARRAYSIZE(buf); i++) {
9364 + if (ptr[i] != i)
9365 + break;
9366 + }
9367 +
9368 + /* Change the clock if the test fails */
9369 + if (i < ARRAYSIZE(buf)) {
9370 + uint32 req, cur;
9371 +
9372 + cur = sb_clock(sbh);
9373 + printf("PCI: Test failed at %d MHz\n", (cur + 500000) / 1000000);
9374 + for (req = 104000000; req < 176000000; req += 4000000) {
9375 + printf("PCI: Resetting to %d MHz\n", (req + 500000) / 1000000);
9376 + /* This will only reset if the clocks are valid and have changed */
9377 + sb_mips_setclock(sbh, req, 0, 0);
9378 + }
9379 + /* Should not reach here */
9380 + ASSERT(0);
9381 + }
9382 +
9383 + sb_setcoreidx(sbh, coreidx);
9384 +}
9385 +
9386 diff -Nur linux-2.4.32/arch/mips/bcm947xx/setup.c linux-2.4.32-brcm/arch/mips/bcm947xx/setup.c
9387 --- linux-2.4.32/arch/mips/bcm947xx/setup.c 1970-01-01 01:00:00.000000000 +0100
9388 +++ linux-2.4.32-brcm/arch/mips/bcm947xx/setup.c 2005-12-20 00:29:40.187416500 +0100
9389 @@ -0,0 +1,234 @@
9390 +/*
9391 + * Generic setup routines for Broadcom MIPS boards
9392 + *
9393 + * Copyright (C) 2005 Felix Fietkau <nbd@openwrt.org>
9394 + *
9395 + * This program is free software; you can redistribute it and/or modify it
9396 + * under the terms of the GNU General Public License as published by the
9397 + * Free Software Foundation; either version 2 of the License, or (at your
9398 + * option) any later version.
9399 + *
9400 + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
9401 + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
9402 + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
9403 + * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
9404 + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
9405 + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
9406 + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
9407 + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
9408 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
9409 + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
9410 + *
9411 + * You should have received a copy of the GNU General Public License along
9412 + * with this program; if not, write to the Free Software Foundation, Inc.,
9413 + * 675 Mass Ave, Cambridge, MA 02139, USA.
9414 + *
9415 + *
9416 + * Copyright 2005, Broadcom Corporation
9417 + * All Rights Reserved.
9418 + *
9419 + * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY
9420 + * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM
9421 + * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS
9422 + * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE.
9423 + *
9424 + */
9425 +
9426 +#include <linux/config.h>
9427 +#include <linux/init.h>
9428 +#include <linux/kernel.h>
9429 +#include <linux/module.h>
9430 +#include <linux/serialP.h>
9431 +#include <linux/ide.h>
9432 +#include <asm/bootinfo.h>
9433 +#include <asm/cpu.h>
9434 +#include <asm/time.h>
9435 +#include <asm/reboot.h>
9436 +
9437 +#include <typedefs.h>
9438 +#include <osl.h>
9439 +#include <sbutils.h>
9440 +#include <bcmutils.h>
9441 +#include <bcmnvram.h>
9442 +#include <sbmips.h>
9443 +#include <trxhdr.h>
9444 +
9445 +/* Global SB handle */
9446 +sb_t *bcm947xx_sbh = NULL;
9447 +spinlock_t bcm947xx_sbh_lock = SPIN_LOCK_UNLOCKED;
9448 +
9449 +/* Convenience */
9450 +#define sbh bcm947xx_sbh
9451 +#define sbh_lock bcm947xx_sbh_lock
9452 +
9453 +extern void bcm947xx_time_init(void);
9454 +extern void bcm947xx_timer_setup(struct irqaction *irq);
9455 +
9456 +#ifdef CONFIG_REMOTE_DEBUG
9457 +extern void set_debug_traps(void);
9458 +extern void rs_kgdb_hook(struct serial_state *);
9459 +extern void breakpoint(void);
9460 +#endif
9461 +
9462 +#if defined(CONFIG_BLK_DEV_IDE) || defined(CONFIG_BLK_DEV_IDE_MODULE)
9463 +extern struct ide_ops std_ide_ops;
9464 +#endif
9465 +
9466 +/* Kernel command line */
9467 +char arcs_cmdline[CL_SIZE] __initdata = CONFIG_CMDLINE;
9468 +
9469 +void
9470 +bcm947xx_machine_restart(char *command)
9471 +{
9472 + printk("Please stand by while rebooting the system...\n");
9473 +
9474 + /* Set the watchdog timer to reset immediately */
9475 + __cli();
9476 + sb_watchdog(sbh, 1);
9477 + while (1);
9478 +}
9479 +
9480 +void
9481 +bcm947xx_machine_halt(void)
9482 +{
9483 + printk("System halted\n");
9484 +
9485 + /* Disable interrupts and watchdog and spin forever */
9486 + __cli();
9487 + sb_watchdog(sbh, 0);
9488 + while (1);
9489 +}
9490 +
9491 +#ifdef CONFIG_SERIAL
9492 +
9493 +static int ser_line = 0;
9494 +
9495 +typedef struct {
9496 + void *regs;
9497 + uint irq;
9498 + uint baud_base;
9499 + uint reg_shift;
9500 +} serial_port;
9501 +
9502 +static serial_port ports[4];
9503 +static int num_ports = 0;
9504 +
9505 +static void
9506 +serial_add(void *regs, uint irq, uint baud_base, uint reg_shift)
9507 +{
9508 + ports[num_ports].regs = regs;
9509 + ports[num_ports].irq = irq;
9510 + ports[num_ports].baud_base = baud_base;
9511 + ports[num_ports].reg_shift = reg_shift;
9512 + num_ports++;
9513 +}
9514 +
9515 +static void
9516 +do_serial_add(serial_port *port)
9517 +{
9518 + void *regs;
9519 + uint irq;
9520 + uint baud_base;
9521 + uint reg_shift;
9522 + struct serial_struct s;
9523 +
9524 + regs = port->regs;
9525 + irq = port->irq;
9526 + baud_base = port->baud_base;
9527 + reg_shift = port->reg_shift;
9528 +
9529 + memset(&s, 0, sizeof(s));
9530 +
9531 + s.line = ser_line++;
9532 + s.iomem_base = regs;
9533 + s.irq = irq + 2;
9534 + s.baud_base = baud_base / 16;
9535 + s.flags = ASYNC_BOOT_AUTOCONF;
9536 + s.io_type = SERIAL_IO_MEM;
9537 + s.iomem_reg_shift = reg_shift;
9538 +
9539 + if (early_serial_setup(&s) != 0) {
9540 + printk(KERN_ERR "Serial setup failed!\n");
9541 + }
9542 +}
9543 +
9544 +#endif /* CONFIG_SERIAL */
9545 +
9546 +void __init
9547 +brcm_setup(void)
9548 +{
9549 + char *s;
9550 + int i;
9551 + char *value;
9552 +
9553 + /* Get global SB handle */
9554 + sbh = sb_kattach();
9555 +
9556 + /* Initialize clocks and interrupts */
9557 + sb_mips_init(sbh);
9558 +
9559 + if (BCM330X(current_cpu_data.processor_id) &&
9560 + (read_c0_diag() & BRCM_PFC_AVAIL)) {
9561 + /*
9562 + * Now that the sbh is inited set the proper PFC value
9563 + */
9564 + printk("Setting the PFC to its default value\n");
9565 + enable_pfc(PFC_AUTO);
9566 + }
9567 +
9568 +
9569 +#ifdef CONFIG_SERIAL
9570 + sb_serial_init(sbh, serial_add);
9571 +
9572 + /* reverse serial ports if nvram variable starts with console=ttyS1 */
9573 + /* Initialize UARTs */
9574 + s = nvram_get("kernel_args");
9575 + if (!s) s = "";
9576 + if (!strncmp(s, "console=ttyS1", 13)) {
9577 + for (i = num_ports; i; i--)
9578 + do_serial_add(&ports[i - 1]);
9579 + } else {
9580 + for (i = 0; i < num_ports; i++)
9581 + do_serial_add(&ports[i]);
9582 + }
9583 +#endif
9584 +
9585 +#if defined(CONFIG_BLK_DEV_IDE) || defined(CONFIG_BLK_DEV_IDE_MODULE)
9586 + ide_ops = &std_ide_ops;
9587 +#endif
9588 +
9589 + /* Override default command line arguments */
9590 + value = nvram_get("kernel_cmdline");
9591 + if (value && strlen(value) && strncmp(value, "empty", 5))
9592 + strncpy(arcs_cmdline, value, sizeof(arcs_cmdline));
9593 +
9594 +
9595 + /* Generic setup */
9596 + _machine_restart = bcm947xx_machine_restart;
9597 + _machine_halt = bcm947xx_machine_halt;
9598 + _machine_power_off = bcm947xx_machine_halt;
9599 +
9600 + board_time_init = bcm947xx_time_init;
9601 + board_timer_setup = bcm947xx_timer_setup;
9602 +}
9603 +
9604 +const char *
9605 +get_system_type(void)
9606 +{
9607 + static char s[32];
9608 +
9609 + if (bcm947xx_sbh) {
9610 + sprintf(s, "Broadcom BCM%X chip rev %d", sb_chip(bcm947xx_sbh),
9611 + sb_chiprev(bcm947xx_sbh));
9612 + return s;
9613 + }
9614 + else
9615 + return "Broadcom BCM947XX";
9616 +}
9617 +
9618 +void __init
9619 +bus_error_init(void)
9620 +{
9621 +}
9622 +
9623 +EXPORT_SYMBOL(bcm947xx_sbh);
9624 diff -Nur linux-2.4.32/arch/mips/bcm947xx/sflash.c linux-2.4.32-brcm/arch/mips/bcm947xx/sflash.c
9625 --- linux-2.4.32/arch/mips/bcm947xx/sflash.c 1970-01-01 01:00:00.000000000 +0100
9626 +++ linux-2.4.32-brcm/arch/mips/bcm947xx/sflash.c 2005-12-16 23:39:10.948837000 +0100
9627 @@ -0,0 +1,418 @@
9628 +/*
9629 + * Broadcom SiliconBackplane chipcommon serial flash interface
9630 + *
9631 + * Copyright 2005, Broadcom Corporation
9632 + * All Rights Reserved.
9633 + *
9634 + * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY
9635 + * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM
9636 + * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS
9637 + * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE.
9638 + *
9639 + * $Id$
9640 + */
9641 +
9642 +#include <osl.h>
9643 +#include <typedefs.h>
9644 +#include <sbconfig.h>
9645 +#include <sbchipc.h>
9646 +#include <mipsinc.h>
9647 +#include <bcmutils.h>
9648 +#include <bcmdevs.h>
9649 +#include <sflash.h>
9650 +
9651 +/* Private global state */
9652 +static struct sflash sflash;
9653 +
9654 +/* Issue a serial flash command */
9655 +static INLINE void
9656 +sflash_cmd(chipcregs_t *cc, uint opcode)
9657 +{
9658 + W_REG(&cc->flashcontrol, SFLASH_START | opcode);
9659 + while (R_REG(&cc->flashcontrol) & SFLASH_BUSY);
9660 +}
9661 +
9662 +/* Initialize serial flash access */
9663 +struct sflash *
9664 +sflash_init(chipcregs_t *cc)
9665 +{
9666 + uint32 id, id2;
9667 +
9668 + bzero(&sflash, sizeof(sflash));
9669 +
9670 + sflash.type = R_REG(&cc->capabilities) & CAP_FLASH_MASK;
9671 +
9672 + switch (sflash.type) {
9673 + case SFLASH_ST:
9674 + /* Probe for ST chips */
9675 + sflash_cmd(cc, SFLASH_ST_DP);
9676 + sflash_cmd(cc, SFLASH_ST_RES);
9677 + id = R_REG(&cc->flashdata);
9678 + switch (id) {
9679 + case 0x11:
9680 + /* ST M25P20 2 Mbit Serial Flash */
9681 + sflash.blocksize = 64 * 1024;
9682 + sflash.numblocks = 4;
9683 + break;
9684 + case 0x12:
9685 + /* ST M25P40 4 Mbit Serial Flash */
9686 + sflash.blocksize = 64 * 1024;
9687 + sflash.numblocks = 8;
9688 + break;
9689 + case 0x13:
9690 + /* ST M25P80 8 Mbit Serial Flash */
9691 + sflash.blocksize = 64 * 1024;
9692 + sflash.numblocks = 16;
9693 + break;
9694 + case 0x14:
9695 + /* ST M25P16 16 Mbit Serial Flash */
9696 + sflash.blocksize = 64 * 1024;
9697 + sflash.numblocks = 32;
9698 + break;
9699 + case 0x15:
9700 + /* ST M25P32 32 Mbit Serial Flash */
9701 + sflash.blocksize = 64 * 1024;
9702 + sflash.numblocks = 64;
9703 + break;
9704 + case 0xbf:
9705 + W_REG(&cc->flashaddress, 1);
9706 + sflash_cmd(cc, SFLASH_ST_RES);
9707 + id2 = R_REG(&cc->flashdata);
9708 + if (id2 == 0x44) {
9709 + /* SST M25VF80 4 Mbit Serial Flash */
9710 + sflash.blocksize = 64 * 1024;
9711 + sflash.numblocks = 8;
9712 + }
9713 + break;
9714 + }
9715 + break;
9716 +
9717 + case SFLASH_AT:
9718 + /* Probe for Atmel chips */
9719 + sflash_cmd(cc, SFLASH_AT_STATUS);
9720 + id = R_REG(&cc->flashdata) & 0x3c;
9721 + switch (id) {
9722 + case 0xc:
9723 + /* Atmel AT45DB011 1Mbit Serial Flash */
9724 + sflash.blocksize = 256;
9725 + sflash.numblocks = 512;
9726 + break;
9727 + case 0x14:
9728 + /* Atmel AT45DB021 2Mbit Serial Flash */
9729 + sflash.blocksize = 256;
9730 + sflash.numblocks = 1024;
9731 + break;
9732 + case 0x1c:
9733 + /* Atmel AT45DB041 4Mbit Serial Flash */
9734 + sflash.blocksize = 256;
9735 + sflash.numblocks = 2048;
9736 + break;
9737 + case 0x24:
9738 + /* Atmel AT45DB081 8Mbit Serial Flash */
9739 + sflash.blocksize = 256;
9740 + sflash.numblocks = 4096;
9741 + break;
9742 + case 0x2c:
9743 + /* Atmel AT45DB161 16Mbit Serial Flash */
9744 + sflash.blocksize = 512;
9745 + sflash.numblocks = 4096;
9746 + break;
9747 + case 0x34:
9748 + /* Atmel AT45DB321 32Mbit Serial Flash */
9749 + sflash.blocksize = 512;
9750 + sflash.numblocks = 8192;
9751 + break;
9752 + case 0x3c:
9753 + /* Atmel AT45DB642 64Mbit Serial Flash */
9754 + sflash.blocksize = 1024;
9755 + sflash.numblocks = 8192;
9756 + break;
9757 + }
9758 + break;
9759 + }
9760 +
9761 + sflash.size = sflash.blocksize * sflash.numblocks;
9762 + return sflash.size ? &sflash : NULL;
9763 +}
9764 +
9765 +/* Read len bytes starting at offset into buf. Returns number of bytes read. */
9766 +int
9767 +sflash_read(chipcregs_t *cc, uint offset, uint len, uchar *buf)
9768 +{
9769 + int cnt;
9770 + uint32 *from, *to;
9771 +
9772 + if (!len)
9773 + return 0;
9774 +
9775 + if ((offset + len) > sflash.size)
9776 + return -22;
9777 +
9778 + if ((len >= 4) && (offset & 3))
9779 + cnt = 4 - (offset & 3);
9780 + else if ((len >= 4) && ((uint32)buf & 3))
9781 + cnt = 4 - ((uint32)buf & 3);
9782 + else
9783 + cnt = len;
9784 +
9785 + from = (uint32 *)KSEG1ADDR(SB_FLASH2 + offset);
9786 + to = (uint32 *)buf;
9787 +
9788 + if (cnt < 4) {
9789 + bcopy(from, to, cnt);
9790 + return cnt;
9791 + }
9792 +
9793 + while (cnt >= 4) {
9794 + *to++ = *from++;
9795 + cnt -= 4;
9796 + }
9797 +
9798 + return (len - cnt);
9799 +}
9800 +
9801 +/* Poll for command completion. Returns zero when complete. */
9802 +int
9803 +sflash_poll(chipcregs_t *cc, uint offset)
9804 +{
9805 + if (offset >= sflash.size)
9806 + return -22;
9807 +
9808 + switch (sflash.type) {
9809 + case SFLASH_ST:
9810 + /* Check for ST Write In Progress bit */
9811 + sflash_cmd(cc, SFLASH_ST_RDSR);
9812 + return R_REG(&cc->flashdata) & SFLASH_ST_WIP;
9813 + case SFLASH_AT:
9814 + /* Check for Atmel Ready bit */
9815 + sflash_cmd(cc, SFLASH_AT_STATUS);
9816 + return !(R_REG(&cc->flashdata) & SFLASH_AT_READY);
9817 + }
9818 +
9819 + return 0;
9820 +}
9821 +
9822 +/* Write len bytes starting at offset into buf. Returns number of bytes
9823 + * written. Caller should poll for completion.
9824 + */
9825 +int
9826 +sflash_write(chipcregs_t *cc, uint offset, uint len, const uchar *buf)
9827 +{
9828 + struct sflash *sfl;
9829 + int ret = 0;
9830 + bool is4712b0;
9831 + uint32 page, byte, mask;
9832 +
9833 + if (!len)
9834 + return 0;
9835 +
9836 + if ((offset + len) > sflash.size)
9837 + return -22;
9838 +
9839 + sfl = &sflash;
9840 + switch (sfl->type) {
9841 + case SFLASH_ST:
9842 + mask = R_REG(&cc->chipid);
9843 + is4712b0 = (((mask & CID_ID_MASK) == BCM4712_DEVICE_ID) &&
9844 + ((mask & CID_REV_MASK) == (3 << CID_REV_SHIFT)));
9845 + /* Enable writes */
9846 + sflash_cmd(cc, SFLASH_ST_WREN);
9847 + if (is4712b0) {
9848 + mask = 1 << 14;
9849 + W_REG(&cc->flashaddress, offset);
9850 + W_REG(&cc->flashdata, *buf++);
9851 + /* Set chip select */
9852 + OR_REG(&cc->gpioout, mask);
9853 + /* Issue a page program with the first byte */
9854 + sflash_cmd(cc, SFLASH_ST_PP);
9855 + ret = 1;
9856 + offset++;
9857 + len--;
9858 + while (len > 0) {
9859 + if ((offset & 255) == 0) {
9860 + /* Page boundary, drop cs and return */
9861 + AND_REG(&cc->gpioout, ~mask);
9862 + if (!sflash_poll(cc, offset)) {
9863 + /* Flash rejected command */
9864 + return -11;
9865 + }
9866 + return ret;
9867 + } else {
9868 + /* Write single byte */
9869 + sflash_cmd(cc, *buf++);
9870 + }
9871 + ret++;
9872 + offset++;
9873 + len--;
9874 + }
9875 + /* All done, drop cs if needed */
9876 + if ((offset & 255) != 1) {
9877 + /* Drop cs */
9878 + AND_REG(&cc->gpioout, ~mask);
9879 + if (!sflash_poll(cc, offset)) {
9880 + /* Flash rejected command */
9881 + return -12;
9882 + }
9883 + }
9884 + } else {
9885 + ret = 1;
9886 + W_REG(&cc->flashaddress, offset);
9887 + W_REG(&cc->flashdata, *buf);
9888 + /* Page program */
9889 + sflash_cmd(cc, SFLASH_ST_PP);
9890 + }
9891 + break;
9892 + case SFLASH_AT:
9893 + mask = sfl->blocksize - 1;
9894 + page = (offset & ~mask) << 1;
9895 + byte = offset & mask;
9896 + /* Read main memory page into buffer 1 */
9897 + if (byte || len < sfl->blocksize) {
9898 + W_REG(&cc->flashaddress, page);
9899 + sflash_cmd(cc, SFLASH_AT_BUF1_LOAD);
9900 + /* 250 us for AT45DB321B */
9901 + SPINWAIT(sflash_poll(cc, offset), 1000);
9902 + ASSERT(!sflash_poll(cc, offset));
9903 + }
9904 + /* Write into buffer 1 */
9905 + for (ret = 0; ret < len && byte < sfl->blocksize; ret++) {
9906 + W_REG(&cc->flashaddress, byte++);
9907 + W_REG(&cc->flashdata, *buf++);
9908 + sflash_cmd(cc, SFLASH_AT_BUF1_WRITE);
9909 + }
9910 + /* Write buffer 1 into main memory page */
9911 + W_REG(&cc->flashaddress, page);
9912 + sflash_cmd(cc, SFLASH_AT_BUF1_PROGRAM);
9913 + break;
9914 + }
9915 +
9916 + return ret;
9917 +}
9918 +
9919 +/* Erase a region. Returns number of bytes scheduled for erasure.
9920 + * Caller should poll for completion.
9921 + */
9922 +int
9923 +sflash_erase(chipcregs_t *cc, uint offset)
9924 +{
9925 + struct sflash *sfl;
9926 +
9927 + if (offset >= sflash.size)
9928 + return -22;
9929 +
9930 + sfl = &sflash;
9931 + switch (sfl->type) {
9932 + case SFLASH_ST:
9933 + sflash_cmd(cc, SFLASH_ST_WREN);
9934 + W_REG(&cc->flashaddress, offset);
9935 + sflash_cmd(cc, SFLASH_ST_SE);
9936 + return sfl->blocksize;
9937 + case SFLASH_AT:
9938 + W_REG(&cc->flashaddress, offset << 1);
9939 + sflash_cmd(cc, SFLASH_AT_PAGE_ERASE);
9940 + return sfl->blocksize;
9941 + }
9942 +
9943 + return 0;
9944 +}
9945 +
9946 +/*
9947 + * writes the appropriate range of flash, a NULL buf simply erases
9948 + * the region of flash
9949 + */
9950 +int
9951 +sflash_commit(chipcregs_t *cc, uint offset, uint len, const uchar *buf)
9952 +{
9953 + struct sflash *sfl;
9954 + uchar *block = NULL, *cur_ptr, *blk_ptr;
9955 + uint blocksize = 0, mask, cur_offset, cur_length, cur_retlen, remainder;
9956 + uint blk_offset, blk_len, copied;
9957 + int bytes, ret = 0;
9958 +
9959 + /* Check address range */
9960 + if (len <= 0)
9961 + return 0;
9962 +
9963 + sfl = &sflash;
9964 + if ((offset + len) > sfl->size)
9965 + return -1;
9966 +
9967 + blocksize = sfl->blocksize;
9968 + mask = blocksize - 1;
9969 +
9970 + /* Allocate a block of mem */
9971 + if (!(block = MALLOC(NULL, blocksize)))
9972 + return -1;
9973 +
9974 + while (len) {
9975 + /* Align offset */
9976 + cur_offset = offset & ~mask;
9977 + cur_length = blocksize;
9978 + cur_ptr = block;
9979 +
9980 + remainder = blocksize - (offset & mask);
9981 + if (len < remainder)
9982 + cur_retlen = len;
9983 + else
9984 + cur_retlen = remainder;
9985 +
9986 + /* buf == NULL means erase only */
9987 + if (buf) {
9988 + /* Copy existing data into holding block if necessary */
9989 + if ((offset & mask) || (len < blocksize)) {
9990 + blk_offset = cur_offset;
9991 + blk_len = cur_length;
9992 + blk_ptr = cur_ptr;
9993 +
9994 + /* Copy entire block */
9995 + while(blk_len) {
9996 + copied = sflash_read(cc, blk_offset, blk_len, blk_ptr);
9997 + blk_offset += copied;
9998 + blk_len -= copied;
9999 + blk_ptr += copied;
10000 + }
10001 + }
10002 +
10003 + /* Copy input data into holding block */
10004 + memcpy(cur_ptr + (offset & mask), buf, cur_retlen);
10005 + }
10006 +
10007 + /* Erase block */
10008 + if ((ret = sflash_erase(cc, (uint) cur_offset)) < 0)
10009 + goto done;
10010 + while (sflash_poll(cc, (uint) cur_offset));
10011 +
10012 + /* buf == NULL means erase only */
10013 + if (!buf) {
10014 + offset += cur_retlen;
10015 + len -= cur_retlen;
10016 + continue;
10017 + }
10018 +
10019 + /* Write holding block */
10020 + while (cur_length > 0) {
10021 + if ((bytes = sflash_write(cc,
10022 + (uint) cur_offset,
10023 + (uint) cur_length,
10024 + (uchar *) cur_ptr)) < 0) {
10025 + ret = bytes;
10026 + goto done;
10027 + }
10028 + while (sflash_poll(cc, (uint) cur_offset));
10029 + cur_offset += bytes;
10030 + cur_length -= bytes;
10031 + cur_ptr += bytes;
10032 + }
10033 +
10034 + offset += cur_retlen;
10035 + len -= cur_retlen;
10036 + buf += cur_retlen;
10037 + }
10038 +
10039 + ret = len;
10040 +done:
10041 + if (block)
10042 + MFREE(NULL, block, blocksize);
10043 + return ret;
10044 +}
10045 +
10046 diff -Nur linux-2.4.32/arch/mips/bcm947xx/time.c linux-2.4.32-brcm/arch/mips/bcm947xx/time.c
10047 --- linux-2.4.32/arch/mips/bcm947xx/time.c 1970-01-01 01:00:00.000000000 +0100
10048 +++ linux-2.4.32-brcm/arch/mips/bcm947xx/time.c 2005-12-16 23:39:10.948837000 +0100
10049 @@ -0,0 +1,118 @@
10050 +/*
10051 + * Copyright 2004, Broadcom Corporation
10052 + * All Rights Reserved.
10053 + *
10054 + * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY
10055 + * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM
10056 + * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS
10057 + * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE.
10058 + *
10059 + * $Id: time.c,v 1.1 2005/03/16 13:49:59 wbx Exp $
10060 + */
10061 +#include <linux/config.h>
10062 +#include <linux/init.h>
10063 +#include <linux/kernel.h>
10064 +#include <linux/sched.h>
10065 +#include <linux/serial_reg.h>
10066 +#include <linux/interrupt.h>
10067 +#include <asm/addrspace.h>
10068 +#include <asm/io.h>
10069 +#include <asm/time.h>
10070 +
10071 +#include <typedefs.h>
10072 +#include <osl.h>
10073 +#include <sbutils.h>
10074 +#include <bcmnvram.h>
10075 +#include <sbconfig.h>
10076 +#include <sbextif.h>
10077 +#include <sbmips.h>
10078 +
10079 +/* Global SB handle */
10080 +extern void *bcm947xx_sbh;
10081 +extern spinlock_t bcm947xx_sbh_lock;
10082 +
10083 +/* Convenience */
10084 +#define sbh bcm947xx_sbh
10085 +#define sbh_lock bcm947xx_sbh_lock
10086 +
10087 +extern int panic_timeout;
10088 +static int watchdog = 0;
10089 +static u8 *mcr = NULL;
10090 +
10091 +void __init
10092 +bcm947xx_time_init(void)
10093 +{
10094 + unsigned int hz;
10095 + extifregs_t *eir;
10096 +
10097 + /*
10098 + * Use deterministic values for initial counter interrupt
10099 + * so that calibrate delay avoids encountering a counter wrap.
10100 + */
10101 + write_c0_count(0);
10102 + write_c0_compare(0xffff);
10103 +
10104 + if (!(hz = sb_mips_clock(sbh)))
10105 + hz = 100000000;
10106 +
10107 + printk("CPU: BCM%04x rev %d at %d MHz\n", sb_chip(sbh), sb_chiprev(sbh),
10108 + (hz + 500000) / 1000000);
10109 +
10110 + /* Set MIPS counter frequency for fixed_rate_gettimeoffset() */
10111 + mips_hpt_frequency = hz / 2;
10112 +
10113 + /* Set watchdog interval in ms */
10114 + watchdog = simple_strtoul(nvram_safe_get("watchdog"), NULL, 0);
10115 +
10116 + /* Please set the watchdog to 3 sec if it is less than 3 but not equal to 0 */
10117 + if (watchdog > 0) {
10118 + if (watchdog < 3000)
10119 + watchdog = 3000;
10120 + }
10121 +
10122 +
10123 + /* Set panic timeout in seconds */
10124 + panic_timeout = watchdog / 1000;
10125 +
10126 + /* Setup blink */
10127 + if ((eir = sb_setcore(sbh, SB_EXTIF, 0))) {
10128 + sbconfig_t *sb = (sbconfig_t *)((unsigned int) eir + SBCONFIGOFF);
10129 + unsigned long base = EXTIF_CFGIF_BASE(sb_base(readl(&sb->sbadmatch1)));
10130 + mcr = (u8 *) ioremap_nocache(base + UART_MCR, 1);
10131 + }
10132 +}
10133 +
10134 +static void
10135 +bcm947xx_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs)
10136 +{
10137 + /* Generic MIPS timer code */
10138 + timer_interrupt(irq, dev_id, regs);
10139 +
10140 + /* Set the watchdog timer to reset after the specified number of ms */
10141 + if (watchdog > 0)
10142 + sb_watchdog(sbh, WATCHDOG_CLOCK / 1000 * watchdog);
10143 +
10144 +#ifdef CONFIG_HWSIM
10145 + (*((int *)0xa0000f1c))++;
10146 +#else
10147 + /* Blink one of the LEDs in the external UART */
10148 + if (mcr && !(jiffies % (HZ/2)))
10149 + writeb(readb(mcr) ^ UART_MCR_OUT2, mcr);
10150 +#endif
10151 +}
10152 +
10153 +static struct irqaction bcm947xx_timer_irqaction = {
10154 + bcm947xx_timer_interrupt,
10155 + SA_INTERRUPT,
10156 + 0,
10157 + "timer",
10158 + NULL,
10159 + NULL
10160 +};
10161 +
10162 +void __init
10163 +bcm947xx_timer_setup(struct irqaction *irq)
10164 +{
10165 + /* Enable the timer interrupt */
10166 + setup_irq(7, &bcm947xx_timer_irqaction);
10167 +}
10168 diff -Nur linux-2.4.32/arch/mips/config-shared.in linux-2.4.32-brcm/arch/mips/config-shared.in
10169 --- linux-2.4.32/arch/mips/config-shared.in 2005-01-19 15:09:27.000000000 +0100
10170 +++ linux-2.4.32-brcm/arch/mips/config-shared.in 2005-12-16 23:39:11.080845250 +0100
10171 @@ -205,6 +205,14 @@
10172 fi
10173 define_bool CONFIG_MIPS_RTC y
10174 fi
10175 +dep_bool 'Support for Broadcom MIPS-based boards' CONFIG_MIPS_BRCM $CONFIG_EXPERIMENTAL
10176 +dep_bool 'Support for Broadcom BCM947XX' CONFIG_BCM947XX $CONFIG_MIPS_BRCM
10177 +if [ "$CONFIG_BCM947XX" = "y" ] ; then
10178 + bool ' Support for Broadcom BCM4710' CONFIG_BCM4710
10179 + bool ' Support for Broadcom BCM4310' CONFIG_BCM4310
10180 + bool ' Support for Broadcom BCM4704' CONFIG_BCM4704
10181 + bool ' Support for Broadcom BCM5365' CONFIG_BCM5365
10182 +fi
10183 bool 'Support for SNI RM200 PCI' CONFIG_SNI_RM200_PCI
10184 bool 'Support for TANBAC TB0226 (Mbase)' CONFIG_TANBAC_TB0226
10185 bool 'Support for TANBAC TB0229 (VR4131DIMM)' CONFIG_TANBAC_TB0229
10186 @@ -226,6 +234,11 @@
10187 define_bool CONFIG_RWSEM_XCHGADD_ALGORITHM n
10188
10189 #
10190 +# Provide an option for a default kernel command line
10191 +#
10192 +string 'Default kernel command string' CONFIG_CMDLINE ""
10193 +
10194 +#
10195 # Select some configuration options automatically based on user selections.
10196 #
10197 if [ "$CONFIG_ACER_PICA_61" = "y" ]; then
10198 @@ -533,6 +546,13 @@
10199 define_bool CONFIG_SWAP_IO_SPACE_L y
10200 define_bool CONFIG_BOOT_ELF32 y
10201 fi
10202 +if [ "$CONFIG_BCM947XX" = "y" ] ; then
10203 + define_bool CONFIG_PCI y
10204 + define_bool CONFIG_NONCOHERENT_IO y
10205 + define_bool CONFIG_NEW_TIME_C y
10206 + define_bool CONFIG_NEW_IRQ y
10207 + define_bool CONFIG_HND y
10208 +fi
10209 if [ "$CONFIG_SNI_RM200_PCI" = "y" ]; then
10210 define_bool CONFIG_ARC32 y
10211 define_bool CONFIG_ARC_MEMORY y
10212 @@ -1011,7 +1031,11 @@
10213
10214 bool 'Are you using a crosscompiler' CONFIG_CROSSCOMPILE
10215 bool 'Enable run-time debugging' CONFIG_RUNTIME_DEBUG
10216 -bool 'Remote GDB kernel debugging' CONFIG_KGDB
10217 +if [ "$CONFIG_BCM947XX" = "y" ] ; then
10218 + bool 'Remote GDB kernel debugging' CONFIG_REMOTE_DEBUG
10219 +else
10220 + bool 'Remote GDB kernel debugging' CONFIG_KGDB
10221 +fi
10222 dep_bool ' Console output to GDB' CONFIG_GDB_CONSOLE $CONFIG_KGDB
10223 if [ "$CONFIG_KGDB" = "y" ]; then
10224 define_bool CONFIG_DEBUG_INFO y
10225 diff -Nur linux-2.4.32/arch/mips/kernel/cpu-probe.c linux-2.4.32-brcm/arch/mips/kernel/cpu-probe.c
10226 --- linux-2.4.32/arch/mips/kernel/cpu-probe.c 2005-01-19 15:09:29.000000000 +0100
10227 +++ linux-2.4.32-brcm/arch/mips/kernel/cpu-probe.c 2005-12-16 23:39:11.084845500 +0100
10228 @@ -174,7 +174,7 @@
10229
10230 static inline void cpu_probe_legacy(struct cpuinfo_mips *c)
10231 {
10232 - switch (c->processor_id & 0xff00) {
10233 + switch (c->processor_id & PRID_IMP_MASK) {
10234 case PRID_IMP_R2000:
10235 c->cputype = CPU_R2000;
10236 c->isa_level = MIPS_CPU_ISA_I;
10237 @@ -184,7 +184,7 @@
10238 c->tlbsize = 64;
10239 break;
10240 case PRID_IMP_R3000:
10241 - if ((c->processor_id & 0xff) == PRID_REV_R3000A)
10242 + if ((c->processor_id & PRID_REV_MASK) == PRID_REV_R3000A)
10243 if (cpu_has_confreg())
10244 c->cputype = CPU_R3081E;
10245 else
10246 @@ -199,12 +199,12 @@
10247 break;
10248 case PRID_IMP_R4000:
10249 if (read_c0_config() & CONF_SC) {
10250 - if ((c->processor_id & 0xff) >= PRID_REV_R4400)
10251 + if ((c->processor_id & PRID_REV_MASK) >= PRID_REV_R4400)
10252 c->cputype = CPU_R4400PC;
10253 else
10254 c->cputype = CPU_R4000PC;
10255 } else {
10256 - if ((c->processor_id & 0xff) >= PRID_REV_R4400)
10257 + if ((c->processor_id & PRID_REV_MASK) >= PRID_REV_R4400)
10258 c->cputype = CPU_R4400SC;
10259 else
10260 c->cputype = CPU_R4000SC;
10261 @@ -450,7 +450,7 @@
10262 static inline void cpu_probe_mips(struct cpuinfo_mips *c)
10263 {
10264 decode_config1(c);
10265 - switch (c->processor_id & 0xff00) {
10266 + switch (c->processor_id & PRID_IMP_MASK) {
10267 case PRID_IMP_4KC:
10268 c->cputype = CPU_4KC;
10269 c->isa_level = MIPS_CPU_ISA_M32;
10270 @@ -491,10 +491,10 @@
10271 {
10272 decode_config1(c);
10273 c->options |= MIPS_CPU_PREFETCH;
10274 - switch (c->processor_id & 0xff00) {
10275 + switch (c->processor_id & PRID_IMP_MASK) {
10276 case PRID_IMP_AU1_REV1:
10277 case PRID_IMP_AU1_REV2:
10278 - switch ((c->processor_id >> 24) & 0xff) {
10279 + switch ((c->processor_id >> 24) & PRID_REV_MASK) {
10280 case 0:
10281 c->cputype = CPU_AU1000;
10282 break;
10283 @@ -522,10 +522,34 @@
10284 }
10285 }
10286
10287 +static inline void cpu_probe_broadcom(struct cpuinfo_mips *c)
10288 +{
10289 + decode_config1(c);
10290 + c->options |= MIPS_CPU_PREFETCH;
10291 + switch (c->processor_id & PRID_IMP_MASK) {
10292 + case PRID_IMP_BCM4710:
10293 + c->cputype = CPU_BCM4710;
10294 + c->options = MIPS_CPU_TLB | MIPS_CPU_4KEX |
10295 + MIPS_CPU_4KTLB | MIPS_CPU_COUNTER;
10296 + c->scache.flags = MIPS_CACHE_NOT_PRESENT;
10297 + break;
10298 + case PRID_IMP_4KC:
10299 + case PRID_IMP_BCM3302:
10300 + c->cputype = CPU_BCM3302;
10301 + c->options = MIPS_CPU_TLB | MIPS_CPU_4KEX |
10302 + MIPS_CPU_4KTLB | MIPS_CPU_COUNTER;
10303 + c->scache.flags = MIPS_CACHE_NOT_PRESENT;
10304 + break;
10305 + default:
10306 + c->cputype = CPU_UNKNOWN;
10307 + break;
10308 + }
10309 +}
10310 +
10311 static inline void cpu_probe_sibyte(struct cpuinfo_mips *c)
10312 {
10313 decode_config1(c);
10314 - switch (c->processor_id & 0xff00) {
10315 + switch (c->processor_id & PRID_IMP_MASK) {
10316 case PRID_IMP_SB1:
10317 c->cputype = CPU_SB1;
10318 c->isa_level = MIPS_CPU_ISA_M64;
10319 @@ -547,7 +571,7 @@
10320 static inline void cpu_probe_sandcraft(struct cpuinfo_mips *c)
10321 {
10322 decode_config1(c);
10323 - switch (c->processor_id & 0xff00) {
10324 + switch (c->processor_id & PRID_IMP_MASK) {
10325 case PRID_IMP_SR71000:
10326 c->cputype = CPU_SR71000;
10327 c->isa_level = MIPS_CPU_ISA_M64;
10328 @@ -572,7 +596,7 @@
10329 c->cputype = CPU_UNKNOWN;
10330
10331 c->processor_id = read_c0_prid();
10332 - switch (c->processor_id & 0xff0000) {
10333 + switch (c->processor_id & PRID_COMP_MASK) {
10334
10335 case PRID_COMP_LEGACY:
10336 cpu_probe_legacy(c);
10337 @@ -583,6 +607,9 @@
10338 case PRID_COMP_ALCHEMY:
10339 cpu_probe_alchemy(c);
10340 break;
10341 + case PRID_COMP_BROADCOM:
10342 + cpu_probe_broadcom(c);
10343 + break;
10344 case PRID_COMP_SIBYTE:
10345 cpu_probe_sibyte(c);
10346 break;
10347 diff -Nur linux-2.4.32/arch/mips/kernel/head.S linux-2.4.32-brcm/arch/mips/kernel/head.S
10348 --- linux-2.4.32/arch/mips/kernel/head.S 2005-01-19 15:09:29.000000000 +0100
10349 +++ linux-2.4.32-brcm/arch/mips/kernel/head.S 2005-12-16 23:39:11.084845500 +0100
10350 @@ -28,12 +28,20 @@
10351 #include <asm/mipsregs.h>
10352 #include <asm/stackframe.h>
10353
10354 +#ifdef CONFIG_BCM4710
10355 +#undef eret
10356 +#define eret nop; nop; eret
10357 +#endif
10358 +
10359 .text
10360 + j kernel_entry
10361 + nop
10362 +
10363 /*
10364 * Reserved space for exception handlers.
10365 * Necessary for machines which link their kernels at KSEG0.
10366 */
10367 - .fill 0x400
10368 + .fill 0x3f4
10369
10370 /* The following two symbols are used for kernel profiling. */
10371 EXPORT(stext)
10372 diff -Nur linux-2.4.32/arch/mips/kernel/proc.c linux-2.4.32-brcm/arch/mips/kernel/proc.c
10373 --- linux-2.4.32/arch/mips/kernel/proc.c 2005-01-19 15:09:29.000000000 +0100
10374 +++ linux-2.4.32-brcm/arch/mips/kernel/proc.c 2005-12-16 23:39:11.084845500 +0100
10375 @@ -78,9 +78,10 @@
10376 [CPU_AU1550] "Au1550",
10377 [CPU_24K] "MIPS 24K",
10378 [CPU_AU1200] "Au1200",
10379 + [CPU_BCM4710] "BCM4710",
10380 + [CPU_BCM3302] "BCM3302",
10381 };
10382
10383 -
10384 static int show_cpuinfo(struct seq_file *m, void *v)
10385 {
10386 unsigned int version = current_cpu_data.processor_id;
10387 diff -Nur linux-2.4.32/arch/mips/kernel/setup.c linux-2.4.32-brcm/arch/mips/kernel/setup.c
10388 --- linux-2.4.32/arch/mips/kernel/setup.c 2005-01-19 15:09:29.000000000 +0100
10389 +++ linux-2.4.32-brcm/arch/mips/kernel/setup.c 2005-12-16 23:39:11.140849000 +0100
10390 @@ -495,6 +495,7 @@
10391 void swarm_setup(void);
10392 void hp_setup(void);
10393 void au1x00_setup(void);
10394 + void brcm_setup(void);
10395 void frame_info_init(void);
10396
10397 frame_info_init();
10398 @@ -693,6 +694,11 @@
10399 pmc_yosemite_setup();
10400 break;
10401 #endif
10402 +#if defined(CONFIG_BCM4710) || defined(CONFIG_BCM4310)
10403 + case MACH_GROUP_BRCM:
10404 + brcm_setup();
10405 + break;
10406 +#endif
10407 default:
10408 panic("Unsupported architecture");
10409 }
10410 diff -Nur linux-2.4.32/arch/mips/kernel/traps.c linux-2.4.32-brcm/arch/mips/kernel/traps.c
10411 --- linux-2.4.32/arch/mips/kernel/traps.c 2005-01-19 15:09:29.000000000 +0100
10412 +++ linux-2.4.32-brcm/arch/mips/kernel/traps.c 2005-12-16 23:39:11.140849000 +0100
10413 @@ -913,6 +913,7 @@
10414 void __init trap_init(void)
10415 {
10416 extern char except_vec1_generic;
10417 + extern char except_vec2_generic;
10418 extern char except_vec3_generic, except_vec3_r4000;
10419 extern char except_vec_ejtag_debug;
10420 extern char except_vec4;
10421 @@ -922,6 +923,7 @@
10422
10423 /* Copy the generic exception handler code to it's final destination. */
10424 memcpy((void *)(KSEG0 + 0x80), &except_vec1_generic, 0x80);
10425 + memcpy((void *)(KSEG0 + 0x100), &except_vec2_generic, 0x80);
10426
10427 /*
10428 * Setup default vectors
10429 @@ -980,6 +982,12 @@
10430 set_except_vector(13, handle_tr);
10431 set_except_vector(22, handle_mdmx);
10432
10433 + if (current_cpu_data.cputype == CPU_SB1) {
10434 + /* Enable timer interrupt and scd mapped interrupt */
10435 + clear_c0_status(0xf000);
10436 + set_c0_status(0xc00);
10437 + }
10438 +
10439 if (cpu_has_fpu && !cpu_has_nofpuex)
10440 set_except_vector(15, handle_fpe);
10441
10442 diff -Nur linux-2.4.32/arch/mips/Makefile linux-2.4.32-brcm/arch/mips/Makefile
10443 --- linux-2.4.32/arch/mips/Makefile 2005-01-19 15:09:26.000000000 +0100
10444 +++ linux-2.4.32-brcm/arch/mips/Makefile 2005-12-16 23:39:10.668819500 +0100
10445 @@ -715,6 +715,19 @@
10446 endif
10447
10448 #
10449 +# Broadcom BCM947XX variants
10450 +#
10451 +ifdef CONFIG_BCM947XX
10452 +LIBS += arch/mips/bcm947xx/generic/brcm.o arch/mips/bcm947xx/bcm947xx.o
10453 +SUBDIRS += arch/mips/bcm947xx/generic arch/mips/bcm947xx
10454 +LOADADDR := 0x80001000
10455 +
10456 +zImage: vmlinux
10457 + $(MAKE) -C arch/$(ARCH)/bcm947xx/compressed
10458 +export LOADADDR
10459 +endif
10460 +
10461 +#
10462 # Choosing incompatible machines durings configuration will result in
10463 # error messages during linking. Select a default linkscript if
10464 # none has been choosen above.
10465 @@ -767,6 +780,7 @@
10466 $(MAKE) -C arch/$(ARCH)/tools clean
10467 $(MAKE) -C arch/mips/baget clean
10468 $(MAKE) -C arch/mips/lasat clean
10469 + $(MAKE) -C arch/mips/bcm947xx/compressed clean
10470
10471 archmrproper:
10472 @$(MAKEBOOT) mrproper
10473 diff -Nur linux-2.4.32/arch/mips/mm/c-r4k.c linux-2.4.32-brcm/arch/mips/mm/c-r4k.c
10474 --- linux-2.4.32/arch/mips/mm/c-r4k.c 2005-01-19 15:09:29.000000000 +0100
10475 +++ linux-2.4.32-brcm/arch/mips/mm/c-r4k.c 2005-12-16 23:39:11.144849250 +0100
10476 @@ -1114,3 +1114,47 @@
10477 build_clear_page();
10478 build_copy_page();
10479 }
10480 +
10481 +#ifdef CONFIG_BCM4704
10482 +static void __init mips32_icache_fill(unsigned long addr, uint nbytes)
10483 +{
10484 + unsigned long ic_lsize = current_cpu_data.icache.linesz;
10485 + int i;
10486 + for (i = 0; i < nbytes; i += ic_lsize)
10487 + fill_icache_line((addr + i));
10488 +}
10489 +
10490 +/*
10491 + * This must be run from the cache on 4704A0
10492 + * so there are no mips core BIU ops in progress
10493 + * when the PFC is enabled.
10494 + */
10495 +#define PFC_CR0 0xff400000 /* control reg 0 */
10496 +#define PFC_CR1 0xff400004 /* control reg 1 */
10497 +static void __init enable_pfc(u32 mode)
10498 +{
10499 + /* write range */
10500 + *(volatile u32 *)PFC_CR1 = 0xffff0000;
10501 +
10502 + /* enable */
10503 + *(volatile u32 *)PFC_CR0 = mode;
10504 +}
10505 +#endif
10506 +
10507 +
10508 +void check_enable_mips_pfc(int val)
10509 +{
10510 +
10511 +#ifdef CONFIG_BCM4704
10512 + struct cpuinfo_mips *c = &current_cpu_data;
10513 +
10514 + /* enable prefetch cache */
10515 + if (((c->processor_id & (PRID_COMP_MASK | PRID_IMP_MASK)) == PRID_IMP_BCM3302)
10516 + && (read_c0_diag() & (1 << 29))) {
10517 + mips32_icache_fill((unsigned long) &enable_pfc, 64);
10518 + enable_pfc(val);
10519 + }
10520 +#endif
10521 +}
10522 +
10523 +
10524 diff -Nur linux-2.4.32/arch/mips/pci/Makefile linux-2.4.32-brcm/arch/mips/pci/Makefile
10525 --- linux-2.4.32/arch/mips/pci/Makefile 2005-01-19 15:09:29.000000000 +0100
10526 +++ linux-2.4.32-brcm/arch/mips/pci/Makefile 2005-12-16 23:39:11.144849250 +0100
10527 @@ -13,7 +13,9 @@
10528 obj-$(CONFIG_MIPS_MSC) += ops-msc.o
10529 obj-$(CONFIG_MIPS_NILE4) += ops-nile4.o
10530 obj-$(CONFIG_SNI_RM200_PCI) += ops-sni.o
10531 +ifndef CONFIG_BCM947XX
10532 obj-y += pci.o
10533 +endif
10534 obj-$(CONFIG_PCI_AUTO) += pci_auto.o
10535
10536 include $(TOPDIR)/Rules.make
10537 diff -Nur linux-2.4.32/drivers/char/serial.c linux-2.4.32-brcm/drivers/char/serial.c
10538 --- linux-2.4.32/drivers/char/serial.c 2005-11-16 20:12:54.000000000 +0100
10539 +++ linux-2.4.32-brcm/drivers/char/serial.c 2005-12-16 23:39:11.200852750 +0100
10540 @@ -422,6 +422,10 @@
10541 return inb(info->port+1);
10542 #endif
10543 case SERIAL_IO_MEM:
10544 +#ifdef CONFIG_BCM4310
10545 + readb((unsigned long) info->iomem_base +
10546 + (UART_SCR<<info->iomem_reg_shift));
10547 +#endif
10548 return readb((unsigned long) info->iomem_base +
10549 (offset<<info->iomem_reg_shift));
10550 default:
10551 @@ -442,6 +446,9 @@
10552 case SERIAL_IO_MEM:
10553 writeb(value, (unsigned long) info->iomem_base +
10554 (offset<<info->iomem_reg_shift));
10555 +#ifdef CONFIG_BCM4704
10556 + *((volatile unsigned int *) KSEG1ADDR(0x18000000));
10557 +#endif
10558 break;
10559 default:
10560 outb(value, info->port+offset);
10561 @@ -1704,7 +1711,7 @@
10562 /* Special case since 134 is really 134.5 */
10563 quot = (2*baud_base / 269);
10564 else if (baud)
10565 - quot = baud_base / baud;
10566 + quot = (baud_base + (baud / 2)) / baud;
10567 }
10568 /* If the quotient is zero refuse the change */
10569 if (!quot && old_termios) {
10570 @@ -1721,12 +1728,12 @@
10571 /* Special case since 134 is really 134.5 */
10572 quot = (2*baud_base / 269);
10573 else if (baud)
10574 - quot = baud_base / baud;
10575 + quot = (baud_base + (baud / 2)) / baud;
10576 }
10577 }
10578 /* As a last resort, if the quotient is zero, default to 9600 bps */
10579 if (!quot)
10580 - quot = baud_base / 9600;
10581 + quot = (baud_base + 4800) / 9600;
10582 /*
10583 * Work around a bug in the Oxford Semiconductor 952 rev B
10584 * chip which causes it to seriously miscalculate baud rates
10585 @@ -5982,6 +5989,13 @@
10586 * Divisor, bytesize and parity
10587 */
10588 state = rs_table + co->index;
10589 + /*
10590 + * Safe guard: state structure must have been initialized
10591 + */
10592 + if (state->iomem_base == NULL) {
10593 + printk("!unable to setup serial console!\n");
10594 + return -1;
10595 + }
10596 if (doflow)
10597 state->flags |= ASYNC_CONS_FLOW;
10598 info = &async_sercons;
10599 @@ -5995,7 +6009,7 @@
10600 info->io_type = state->io_type;
10601 info->iomem_base = state->iomem_base;
10602 info->iomem_reg_shift = state->iomem_reg_shift;
10603 - quot = state->baud_base / baud;
10604 + quot = (state->baud_base + (baud / 2)) / baud;
10605 cval = cflag & (CSIZE | CSTOPB);
10606 #if defined(__powerpc__) || defined(__alpha__)
10607 cval >>= 8;
10608 diff -Nur linux-2.4.32/drivers/net/Config.in linux-2.4.32-brcm/drivers/net/Config.in
10609 --- linux-2.4.32/drivers/net/Config.in 2005-01-19 15:09:56.000000000 +0100
10610 +++ linux-2.4.32-brcm/drivers/net/Config.in 2005-12-16 23:39:11.232854750 +0100
10611 @@ -2,6 +2,8 @@
10612 # Network device configuration
10613 #
10614
10615 +tristate 'Broadcom Home Network Division' CONFIG_HND $CONFIG_PCI
10616 +
10617 source drivers/net/arcnet/Config.in
10618
10619 tristate 'Dummy net driver support' CONFIG_DUMMY
10620 diff -Nur linux-2.4.32/drivers/net/hnd/bcmsrom.c linux-2.4.32-brcm/drivers/net/hnd/bcmsrom.c
10621 --- linux-2.4.32/drivers/net/hnd/bcmsrom.c 1970-01-01 01:00:00.000000000 +0100
10622 +++ linux-2.4.32-brcm/drivers/net/hnd/bcmsrom.c 2005-12-16 23:39:11.284858000 +0100
10623 @@ -0,0 +1,938 @@
10624 +/*
10625 + * Misc useful routines to access NIC SROM/OTP .
10626 + *
10627 + * Copyright 2005, Broadcom Corporation
10628 + * All Rights Reserved.
10629 + *
10630 + * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY
10631 + * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM
10632 + * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS
10633 + * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE.
10634 + * $Id$
10635 + */
10636 +
10637 +#include <typedefs.h>
10638 +#include <osl.h>
10639 +#include <bcmutils.h>
10640 +#include <bcmsrom.h>
10641 +#include <bcmdevs.h>
10642 +#include <bcmendian.h>
10643 +#include <sbpcmcia.h>
10644 +#include <pcicfg.h>
10645 +#include <sbutils.h>
10646 +#include <bcmnvram.h>
10647 +
10648 +struct ether_addr {
10649 + uint8 octet[6];
10650 +} PACKED;
10651 +
10652 +#define VARS_MAX 4096 /* should be reduced */
10653 +
10654 +#define WRITE_ENABLE_DELAY 500 /* 500 ms after write enable/disable toggle */
10655 +#define WRITE_WORD_DELAY 20 /* 20 ms between each word write */
10656 +
10657 +static int initvars_srom_pci(void *sbh, void *curmap, char **vars, int *count);
10658 +static int initvars_cis_pcmcia(void *sbh, osl_t *osh, char **vars, int *count);
10659 +static int initvars_flash_sb(void *sbh, char **vars, int *count);
10660 +static int srom_parsecis(osl_t *osh, uint8 *cis, char **vars, int *count);
10661 +static int sprom_cmd_pcmcia(osl_t *osh, uint8 cmd);
10662 +static int sprom_read_pcmcia(osl_t *osh, uint16 addr, uint16 *data);
10663 +static int sprom_write_pcmcia(osl_t *osh, uint16 addr, uint16 data);
10664 +static int sprom_read_pci(uint16 *sprom, uint wordoff, uint16 *buf, uint nwords, bool check_crc);
10665 +
10666 +static int initvars_table(osl_t *osh, char *start, char *end, char **vars, uint *count);
10667 +static int initvars_flash(osl_t *osh, char **vp, int len, char *devpath);
10668 +
10669 +/*
10670 + * Initialize local vars from the right source for this platform.
10671 + * Return 0 on success, nonzero on error.
10672 + */
10673 +int
10674 +srom_var_init(void *sbh, uint bustype, void *curmap, osl_t *osh, char **vars, int *count)
10675 +{
10676 + ASSERT(bustype == BUSTYPE(bustype));
10677 + if (vars == NULL || count == NULL)
10678 + return (0);
10679 +
10680 + switch (BUSTYPE(bustype)) {
10681 + case SB_BUS:
10682 + case JTAG_BUS:
10683 + return initvars_flash_sb(sbh, vars, count);
10684 +
10685 + case PCI_BUS:
10686 + ASSERT(curmap); /* can not be NULL */
10687 + return initvars_srom_pci(sbh, curmap, vars, count);
10688 +
10689 + case PCMCIA_BUS:
10690 + return initvars_cis_pcmcia(sbh, osh, vars, count);
10691 +
10692 +
10693 + default:
10694 + ASSERT(0);
10695 + }
10696 + return (-1);
10697 +}
10698 +
10699 +/* support only 16-bit word read from srom */
10700 +int
10701 +srom_read(uint bustype, void *curmap, osl_t *osh, uint byteoff, uint nbytes, uint16 *buf)
10702 +{
10703 + void *srom;
10704 + uint i, off, nw;
10705 +
10706 + ASSERT(bustype == BUSTYPE(bustype));
10707 +
10708 + /* check input - 16-bit access only */
10709 + if (byteoff & 1 || nbytes & 1 || (byteoff + nbytes) > (SPROM_SIZE * 2))
10710 + return 1;
10711 +
10712 + off = byteoff / 2;
10713 + nw = nbytes / 2;
10714 +
10715 + if (BUSTYPE(bustype) == PCI_BUS) {
10716 + if (!curmap)
10717 + return 1;
10718 + srom = (uchar*)curmap + PCI_BAR0_SPROM_OFFSET;
10719 + if (sprom_read_pci(srom, off, buf, nw, FALSE))
10720 + return 1;
10721 + } else if (BUSTYPE(bustype) == PCMCIA_BUS) {
10722 + for (i = 0; i < nw; i++) {
10723 + if (sprom_read_pcmcia(osh, (uint16)(off + i), (uint16*)(buf + i)))
10724 + return 1;
10725 + }
10726 + } else {
10727 + return 1;
10728 + }
10729 +
10730 + return 0;
10731 +}
10732 +
10733 +/* support only 16-bit word write into srom */
10734 +int
10735 +srom_write(uint bustype, void *curmap, osl_t *osh, uint byteoff, uint nbytes, uint16 *buf)
10736 +{
10737 + uint16 *srom;
10738 + uint i, off, nw, crc_range;
10739 + uint16 image[SPROM_SIZE], *p;
10740 + uint8 crc;
10741 + volatile uint32 val32;
10742 +
10743 + ASSERT(bustype == BUSTYPE(bustype));
10744 +
10745 + /* check input - 16-bit access only */
10746 + if (byteoff & 1 || nbytes & 1 || (byteoff + nbytes) > (SPROM_SIZE * 2))
10747 + return 1;
10748 +
10749 + crc_range = (((BUSTYPE(bustype) == PCMCIA_BUS) || (BUSTYPE(bustype) == SDIO_BUS)) ? SPROM_SIZE : SPROM_CRC_RANGE) * 2;
10750 +
10751 + /* if changes made inside crc cover range */
10752 + if (byteoff < crc_range) {
10753 + nw = (((byteoff + nbytes) > crc_range) ? byteoff + nbytes : crc_range) / 2;
10754 + /* read data including entire first 64 words from srom */
10755 + if (srom_read(bustype, curmap, osh, 0, nw * 2, image))
10756 + return 1;
10757 + /* make changes */
10758 + bcopy((void*)buf, (void*)&image[byteoff / 2], nbytes);
10759 + /* calculate crc */
10760 + htol16_buf(image, crc_range);
10761 + crc = ~hndcrc8((uint8 *)image, crc_range - 1, CRC8_INIT_VALUE);
10762 + ltoh16_buf(image, crc_range);
10763 + image[(crc_range / 2) - 1] = (crc << 8) | (image[(crc_range / 2) - 1] & 0xff);
10764 + p = image;
10765 + off = 0;
10766 + } else {
10767 + p = buf;
10768 + off = byteoff / 2;
10769 + nw = nbytes / 2;
10770 + }
10771 +
10772 + if (BUSTYPE(bustype) == PCI_BUS) {
10773 + srom = (uint16*)((uchar*)curmap + PCI_BAR0_SPROM_OFFSET);
10774 + /* enable writes to the SPROM */
10775 + val32 = OSL_PCI_READ_CONFIG(osh, PCI_SPROM_CONTROL, sizeof(uint32));
10776 + val32 |= SPROM_WRITEEN;
10777 + OSL_PCI_WRITE_CONFIG(osh, PCI_SPROM_CONTROL, sizeof(uint32), val32);
10778 + bcm_mdelay(WRITE_ENABLE_DELAY);
10779 + /* write srom */
10780 + for (i = 0; i < nw; i++) {
10781 + W_REG(&srom[off + i], p[i]);
10782 + bcm_mdelay(WRITE_WORD_DELAY);
10783 + }
10784 + /* disable writes to the SPROM */
10785 + OSL_PCI_WRITE_CONFIG(osh, PCI_SPROM_CONTROL, sizeof(uint32), val32 & ~SPROM_WRITEEN);
10786 + } else if (BUSTYPE(bustype) == PCMCIA_BUS) {
10787 + /* enable writes to the SPROM */
10788 + if (sprom_cmd_pcmcia(osh, SROM_WEN))
10789 + return 1;
10790 + bcm_mdelay(WRITE_ENABLE_DELAY);
10791 + /* write srom */
10792 + for (i = 0; i < nw; i++) {
10793 + sprom_write_pcmcia(osh, (uint16)(off + i), p[i]);
10794 + bcm_mdelay(WRITE_WORD_DELAY);
10795 + }
10796 + /* disable writes to the SPROM */
10797 + if (sprom_cmd_pcmcia(osh, SROM_WDS))
10798 + return 1;
10799 + } else {
10800 + return 1;
10801 + }
10802 +
10803 + bcm_mdelay(WRITE_ENABLE_DELAY);
10804 + return 0;
10805 +}
10806 +
10807 +
10808 +static int
10809 +srom_parsecis(osl_t *osh, uint8 *cis, char **vars, int *count)
10810 +{
10811 + char eabuf[32];
10812 + char *vp, *base;
10813 + uint8 tup, tlen, sromrev = 1;
10814 + int i, j;
10815 + uint varsize;
10816 + bool ag_init = FALSE;
10817 + uint32 w32;
10818 +
10819 + ASSERT(vars);
10820 + ASSERT(count);
10821 +
10822 + base = vp = MALLOC(osh, VARS_MAX);
10823 + ASSERT(vp);
10824 + if (!vp)
10825 + return -2;
10826 +
10827 + i = 0;
10828 + do {
10829 + tup = cis[i++];
10830 + tlen = cis[i++];
10831 + if ((i + tlen) >= CIS_SIZE)
10832 + break;
10833 +
10834 + switch (tup) {
10835 + case CISTPL_MANFID:
10836 + vp += sprintf(vp, "manfid=%d", (cis[i + 1] << 8) + cis[i]);
10837 + vp++;
10838 + vp += sprintf(vp, "prodid=%d", (cis[i + 3] << 8) + cis[i + 2]);
10839 + vp++;
10840 + break;
10841 +
10842 + case CISTPL_FUNCE:
10843 + if (cis[i] == LAN_NID) {
10844 + ASSERT(cis[i + 1] == 6);
10845 + bcm_ether_ntoa((uchar*)&cis[i + 2], eabuf);
10846 + vp += sprintf(vp, "il0macaddr=%s", eabuf);
10847 + vp++;
10848 + }
10849 + break;
10850 +
10851 + case CISTPL_CFTABLE:
10852 + vp += sprintf(vp, "regwindowsz=%d", (cis[i + 7] << 8) | cis[i + 6]);
10853 + vp++;
10854 + break;
10855 +
10856 + case CISTPL_BRCM_HNBU:
10857 + switch (cis[i]) {
10858 + case HNBU_SROMREV:
10859 + sromrev = cis[i + 1];
10860 + break;
10861 +
10862 + case HNBU_CHIPID:
10863 + vp += sprintf(vp, "vendid=%d", (cis[i + 2] << 8) + cis[i + 1]);
10864 + vp++;
10865 + vp += sprintf(vp, "devid=%d", (cis[i + 4] << 8) + cis[i + 3]);
10866 + vp++;
10867 + if (tlen == 7) {
10868 + vp += sprintf(vp, "chiprev=%d", (cis[i + 6] << 8) + cis[i + 5]);
10869 + vp++;
10870 + }
10871 + break;
10872 +
10873 + case HNBU_BOARDREV:
10874 + vp += sprintf(vp, "boardrev=%d", cis[i + 1]);
10875 + vp++;
10876 + break;
10877 +
10878 + case HNBU_AA:
10879 + vp += sprintf(vp, "aa0=%d", cis[i + 1]);
10880 + vp++;
10881 + break;
10882 +
10883 + case HNBU_AG:
10884 + vp += sprintf(vp, "ag0=%d", cis[i + 1]);
10885 + vp++;
10886 + ag_init = TRUE;
10887 + break;
10888 +
10889 + case HNBU_CC:
10890 + ASSERT(sromrev > 1);
10891 + vp += sprintf(vp, "cc=%d", cis[i + 1]);
10892 + vp++;
10893 + break;
10894 +
10895 + case HNBU_PAPARMS:
10896 + if (tlen == 2) {
10897 + ASSERT(sromrev == 1);
10898 + vp += sprintf(vp, "pa0maxpwr=%d", cis[i + 1]);
10899 + vp++;
10900 + } else if (tlen >= 9) {
10901 + if (tlen == 10) {
10902 + ASSERT(sromrev == 2);
10903 + vp += sprintf(vp, "opo=%d", cis[i + 9]);
10904 + vp++;
10905 + } else
10906 + ASSERT(tlen == 9);
10907 +
10908 + for (j = 0; j < 3; j++) {
10909 + vp += sprintf(vp, "pa0b%d=%d", j,
10910 + (cis[i + (j * 2) + 2] << 8) + cis[i + (j * 2) + 1]);
10911 + vp++;
10912 + }
10913 + vp += sprintf(vp, "pa0itssit=%d", cis[i + 7]);
10914 + vp++;
10915 + vp += sprintf(vp, "pa0maxpwr=%d", cis[i + 8]);
10916 + vp++;
10917 + } else
10918 + ASSERT(tlen >= 9);
10919 + break;
10920 +
10921 + case HNBU_OEM:
10922 + ASSERT(sromrev == 1);
10923 + vp += sprintf(vp, "oem=%02x%02x%02x%02x%02x%02x%02x%02x",
10924 + cis[i + 1], cis[i + 2], cis[i + 3], cis[i + 4],
10925 + cis[i + 5], cis[i + 6], cis[i + 7], cis[i + 8]);
10926 + vp++;
10927 + break;
10928 +
10929 + case HNBU_BOARDFLAGS:
10930 + w32 = (cis[i + 2] << 8) + cis[i + 1];
10931 + if (tlen == 5)
10932 + w32 |= (cis[i + 4] << 24) + (cis[i + 3] << 16);
10933 + vp += sprintf(vp, "boardflags=0x%x", w32);
10934 + vp++;
10935 + break;
10936 +
10937 + case HNBU_LEDS:
10938 + if (cis[i + 1] != 0xff) {
10939 + vp += sprintf(vp, "wl0gpio0=%d", cis[i + 1]);
10940 + vp++;
10941 + }
10942 + if (cis[i + 2] != 0xff) {
10943 + vp += sprintf(vp, "wl0gpio1=%d", cis[i + 2]);
10944 + vp++;
10945 + }
10946 + if (cis[i + 3] != 0xff) {
10947 + vp += sprintf(vp, "wl0gpio2=%d", cis[i + 3]);
10948 + vp++;
10949 + }
10950 + if (cis[i + 4] != 0xff) {
10951 + vp += sprintf(vp, "wl0gpio3=%d", cis[i + 4]);
10952 + vp++;
10953 + }
10954 + break;
10955 +
10956 + case HNBU_CCODE:
10957 + ASSERT(sromrev > 1);
10958 + vp += sprintf(vp, "ccode=%c%c", cis[i + 1], cis[i + 2]);
10959 + vp++;
10960 + vp += sprintf(vp, "cctl=0x%x", cis[i + 3]);
10961 + vp++;
10962 + break;
10963 +
10964 + case HNBU_CCKPO:
10965 + ASSERT(sromrev > 2);
10966 + vp += sprintf(vp, "cckpo=0x%x", (cis[i + 2] << 8) | cis[i + 1]);
10967 + vp++;
10968 + break;
10969 +
10970 + case HNBU_OFDMPO:
10971 + ASSERT(sromrev > 2);
10972 + vp += sprintf(vp, "ofdmpo=0x%x", (cis[i + 4] << 24) |
10973 + (cis[i + 3] << 16) | (cis[i + 2] << 8) | cis[i + 1]);
10974 + vp++;
10975 + break;
10976 + }
10977 + break;
10978 +
10979 + }
10980 + i += tlen;
10981 + } while (tup != 0xff);
10982 +
10983 + /* Set the srom version */
10984 + vp += sprintf(vp, "sromrev=%d", sromrev);
10985 + vp++;
10986 +
10987 + /* if there is no antenna gain field, set default */
10988 + if (ag_init == FALSE) {
10989 + ASSERT(sromrev == 1);
10990 + vp += sprintf(vp, "ag0=%d", 0xff);
10991 + vp++;
10992 + }
10993 +
10994 + /* final nullbyte terminator */
10995 + *vp++ = '\0';
10996 + varsize = (uint)(vp - base);
10997 +
10998 + ASSERT((vp - base) < VARS_MAX);
10999 +
11000 + if (varsize == VARS_MAX) {
11001 + *vars = base;
11002 + } else {
11003 + vp = MALLOC(osh, varsize);
11004 + ASSERT(vp);
11005 + if (vp)
11006 + bcopy(base, vp, varsize);
11007 + MFREE(osh, base, VARS_MAX);
11008 + *vars = vp;
11009 + if (!vp) {
11010 + *count = 0;
11011 + return -2;
11012 + }
11013 + }
11014 + *count = varsize;
11015 +
11016 + return (0);
11017 +}
11018 +
11019 +
11020 +/* set PCMCIA sprom command register */
11021 +static int
11022 +sprom_cmd_pcmcia(osl_t *osh, uint8 cmd)
11023 +{
11024 + uint8 status = 0;
11025 + uint wait_cnt = 1000;
11026 +
11027 + /* write sprom command register */
11028 + OSL_PCMCIA_WRITE_ATTR(osh, SROM_CS, &cmd, 1);
11029 +
11030 + /* wait status */
11031 + while (wait_cnt--) {
11032 + OSL_PCMCIA_READ_ATTR(osh, SROM_CS, &status, 1);
11033 + if (status & SROM_DONE)
11034 + return 0;
11035 + }
11036 +
11037 + return 1;
11038 +}
11039 +
11040 +/* read a word from the PCMCIA srom */
11041 +static int
11042 +sprom_read_pcmcia(osl_t *osh, uint16 addr, uint16 *data)
11043 +{
11044 + uint8 addr_l, addr_h, data_l, data_h;
11045 +
11046 + addr_l = (uint8)((addr * 2) & 0xff);
11047 + addr_h = (uint8)(((addr * 2) >> 8) & 0xff);
11048 +
11049 + /* set address */
11050 + OSL_PCMCIA_WRITE_ATTR(osh, SROM_ADDRH, &addr_h, 1);
11051 + OSL_PCMCIA_WRITE_ATTR(osh, SROM_ADDRL, &addr_l, 1);
11052 +
11053 + /* do read */
11054 + if (sprom_cmd_pcmcia(osh, SROM_READ))
11055 + return 1;
11056 +
11057 + /* read data */
11058 + data_h = data_l = 0;
11059 + OSL_PCMCIA_READ_ATTR(osh, SROM_DATAH, &data_h, 1);
11060 + OSL_PCMCIA_READ_ATTR(osh, SROM_DATAL, &data_l, 1);
11061 +
11062 + *data = (data_h << 8) | data_l;
11063 + return 0;
11064 +}
11065 +
11066 +/* write a word to the PCMCIA srom */
11067 +static int
11068 +sprom_write_pcmcia(osl_t *osh, uint16 addr, uint16 data)
11069 +{
11070 + uint8 addr_l, addr_h, data_l, data_h;
11071 +
11072 + addr_l = (uint8)((addr * 2) & 0xff);
11073 + addr_h = (uint8)(((addr * 2) >> 8) & 0xff);
11074 + data_l = (uint8)(data & 0xff);
11075 + data_h = (uint8)((data >> 8) & 0xff);
11076 +
11077 + /* set address */
11078 + OSL_PCMCIA_WRITE_ATTR(osh, SROM_ADDRH, &addr_h, 1);
11079 + OSL_PCMCIA_WRITE_ATTR(osh, SROM_ADDRL, &addr_l, 1);
11080 +
11081 + /* write data */
11082 + OSL_PCMCIA_WRITE_ATTR(osh, SROM_DATAH, &data_h, 1);
11083 + OSL_PCMCIA_WRITE_ATTR(osh, SROM_DATAL, &data_l, 1);
11084 +
11085 + /* do write */
11086 + return sprom_cmd_pcmcia(osh, SROM_WRITE);
11087 +}
11088 +
11089 +/*
11090 + * Read in and validate sprom.
11091 + * Return 0 on success, nonzero on error.
11092 + */
11093 +static int
11094 +sprom_read_pci(uint16 *sprom, uint wordoff, uint16 *buf, uint nwords, bool check_crc)
11095 +{
11096 + int err = 0;
11097 + uint i;
11098 +
11099 + /* read the sprom */
11100 + for (i = 0; i < nwords; i++)
11101 + buf[i] = R_REG(&sprom[wordoff + i]);
11102 +
11103 + if (check_crc) {
11104 + /* fixup the endianness so crc8 will pass */
11105 + htol16_buf(buf, nwords * 2);
11106 + if (hndcrc8((uint8*)buf, nwords * 2, CRC8_INIT_VALUE) != CRC8_GOOD_VALUE)
11107 + err = 1;
11108 + /* now correct the endianness of the byte array */
11109 + ltoh16_buf(buf, nwords * 2);
11110 + }
11111 +
11112 + return err;
11113 +}
11114 +
11115 +/*
11116 +* Create variable table from memory.
11117 +* Return 0 on success, nonzero on error.
11118 +*/
11119 +static int
11120 +initvars_table(osl_t *osh, char *start, char *end, char **vars, uint *count)
11121 +{
11122 + int c = (int)(end - start);
11123 +
11124 + /* do it only when there is more than just the null string */
11125 + if (c > 1) {
11126 + char *vp = MALLOC(osh, c);
11127 + ASSERT(vp);
11128 + if (!vp)
11129 + return BCME_NOMEM;
11130 + bcopy(start, vp, c);
11131 + *vars = vp;
11132 + *count = c;
11133 + }
11134 + else {
11135 + *vars = NULL;
11136 + *count = 0;
11137 + }
11138 +
11139 + return 0;
11140 +}
11141 +
11142 +/*
11143 +* Find variables with <devpath> from flash. 'base' points to the beginning
11144 +* of the table upon enter and to the end of the table upon exit when success.
11145 +* Return 0 on success, nonzero on error.
11146 +*/
11147 +static int
11148 +initvars_flash(osl_t *osh, char **base, int size, char *devpath)
11149 +{
11150 + char *vp = *base;
11151 + char *flash;
11152 + int err;
11153 + char *s;
11154 + uint l, dl, copy_len;
11155 +
11156 + /* allocate memory and read in flash */
11157 + if (!(flash = MALLOC(osh, NVRAM_SPACE)))
11158 + return BCME_NOMEM;
11159 + if ((err = BCMINIT(nvram_getall)(flash, NVRAM_SPACE)))
11160 + goto exit;
11161 +
11162 + /* grab vars with the <devpath> prefix in name */
11163 + dl = strlen(devpath);
11164 + for (s = flash; s && *s; s += l + 1) {
11165 + l = strlen(s);
11166 +
11167 + /* skip non-matching variable */
11168 + if (strncmp(s, devpath, dl))
11169 + continue;
11170 +
11171 + /* is there enough room to copy? */
11172 + copy_len = l - dl + 1;
11173 + if (size < (int)copy_len) {
11174 + err = BCME_BUFTOOSHORT;
11175 + goto exit;
11176 + }
11177 +
11178 + /* no prefix, just the name=value */
11179 + strcpy(vp, &s[dl]);
11180 + vp += copy_len;
11181 + size -= copy_len;
11182 + }
11183 +
11184 + /* add null string as terminator */
11185 + if (size < 1) {
11186 + err = BCME_BUFTOOSHORT;
11187 + goto exit;
11188 + }
11189 + *vp++ = '\0';
11190 +
11191 + *base = vp;
11192 +
11193 +exit: MFREE(osh, flash, NVRAM_SPACE);
11194 + return err;
11195 +}
11196 +
11197 +/*
11198 + * Initialize nonvolatile variable table from flash.
11199 + * Return 0 on success, nonzero on error.
11200 + */
11201 +static int
11202 +initvars_flash_sb(void *sbh, char **vars, int *count)
11203 +{
11204 + osl_t *osh = sb_osh(sbh);
11205 + char devpath[SB_DEVPATH_BUFSZ];
11206 + char *vp, *base;
11207 + int err;
11208 +
11209 + ASSERT(vars);
11210 + ASSERT(count);
11211 +
11212 + if ((err = sb_devpath(sbh, devpath, sizeof(devpath))))
11213 + return err;
11214 +
11215 + base = vp = MALLOC(osh, VARS_MAX);
11216 + ASSERT(vp);
11217 + if (!vp)
11218 + return BCME_NOMEM;
11219 +
11220 + if ((err = initvars_flash(osh, &vp, VARS_MAX, devpath)))
11221 + goto err;
11222 +
11223 + err = initvars_table(osh, base, vp, vars, count);
11224 +
11225 +err: MFREE(osh, base, VARS_MAX);
11226 + return err;
11227 +}
11228 +
11229 +/*
11230 + * Initialize nonvolatile variable table from sprom.
11231 + * Return 0 on success, nonzero on error.
11232 + */
11233 +static int
11234 +initvars_srom_pci(void *sbh, void *curmap, char **vars, int *count)
11235 +{
11236 + uint16 w, b[64];
11237 + uint8 sromrev;
11238 + struct ether_addr ea;
11239 + char eabuf[32];
11240 + uint32 w32;
11241 + int woff, i;
11242 + char *vp, *base;
11243 + osl_t *osh = sb_osh(sbh);
11244 + bool flash = FALSE;
11245 + char name[SB_DEVPATH_BUFSZ+16], *value;
11246 + char devpath[SB_DEVPATH_BUFSZ];
11247 + int err;
11248 +
11249 + /*
11250 + * Apply CRC over SROM content regardless SROM is present or not,
11251 + * and use variable <devpath>sromrev's existance in flash to decide
11252 + * if we should return an error when CRC fails or read SROM variables
11253 + * from flash.
11254 + */
11255 + if (sprom_read_pci((void*)((int8*)curmap + PCI_BAR0_SPROM_OFFSET), 0, b, sizeof(b)/sizeof(b[0]), TRUE)) {
11256 + if ((err = sb_devpath(sbh, devpath, sizeof(devpath))))
11257 + return err;
11258 + sprintf(name, "%ssromrev", devpath);
11259 + if (!(value = getvar(NULL, name)))
11260 + return (-1);
11261 + sromrev = (uint8)bcm_strtoul(value, NULL, 0);
11262 + flash = TRUE;
11263 + }
11264 + /* srom is good */
11265 + else {
11266 + /* top word of sprom contains version and crc8 */
11267 + sromrev = b[63] & 0xff;
11268 + /* bcm4401 sroms misprogrammed */
11269 + if (sromrev == 0x10)
11270 + sromrev = 1;
11271 + }
11272 +
11273 + /* srom version check */
11274 + if (sromrev > 3)
11275 + return (-2);
11276 +
11277 + ASSERT(vars);
11278 + ASSERT(count);
11279 +
11280 + base = vp = MALLOC(osh, VARS_MAX);
11281 + ASSERT(vp);
11282 + if (!vp)
11283 + return -2;
11284 +
11285 + /* read variables from flash */
11286 + if (flash) {
11287 + if ((err = initvars_flash(osh, &vp, VARS_MAX, devpath)))
11288 + goto err;
11289 + goto done;
11290 + }
11291 +
11292 + vp += sprintf(vp, "sromrev=%d", sromrev);
11293 + vp++;
11294 +
11295 + if (sromrev >= 3) {
11296 + /* New section takes over the 3th hardware function space */
11297 +
11298 + /* Words 22+23 are 11a (mid) ofdm power offsets */
11299 + w32 = ((uint32)b[23] << 16) | b[22];
11300 + vp += sprintf(vp, "ofdmapo=%d", w32);
11301 + vp++;
11302 +
11303 + /* Words 24+25 are 11a (low) ofdm power offsets */
11304 + w32 = ((uint32)b[25] << 16) | b[24];
11305 + vp += sprintf(vp, "ofdmalpo=%d", w32);
11306 + vp++;
11307 +
11308 + /* Words 26+27 are 11a (high) ofdm power offsets */
11309 + w32 = ((uint32)b[27] << 16) | b[26];
11310 + vp += sprintf(vp, "ofdmahpo=%d", w32);
11311 + vp++;
11312 +
11313 + /*GPIO LED Powersave duty cycle (oncount >> 24) (offcount >> 8)*/
11314 + w32 = ((uint32)b[43] << 24) | ((uint32)b[42] << 8);
11315 + vp += sprintf(vp, "gpiotimerval=%d", w32);
11316 +
11317 + /*GPIO LED Powersave duty cycle (oncount >> 24) (offcount >> 8)*/
11318 + w32 = ((uint32)((unsigned char)(b[21] >> 8) & 0xFF) << 24) | /* oncount*/
11319 + ((uint32)((unsigned char)(b[21] & 0xFF)) << 8); /* offcount */
11320 + vp += sprintf(vp, "gpiotimerval=%d", w32);
11321 +
11322 + vp++;
11323 + }
11324 +
11325 + if (sromrev >= 2) {
11326 + /* New section takes over the 4th hardware function space */
11327 +
11328 + /* Word 29 is max power 11a high/low */
11329 + w = b[29];
11330 + vp += sprintf(vp, "pa1himaxpwr=%d", w & 0xff);
11331 + vp++;
11332 + vp += sprintf(vp, "pa1lomaxpwr=%d", (w >> 8) & 0xff);
11333 + vp++;
11334 +
11335 + /* Words 30-32 set the 11alow pa settings,
11336 + * 33-35 are the 11ahigh ones.
11337 + */
11338 + for (i = 0; i < 3; i++) {
11339 + vp += sprintf(vp, "pa1lob%d=%d", i, b[30 + i]);
11340 + vp++;
11341 + vp += sprintf(vp, "pa1hib%d=%d", i, b[33 + i]);
11342 + vp++;
11343 + }
11344 + w = b[59];
11345 + if (w == 0)
11346 + vp += sprintf(vp, "ccode=");
11347 + else
11348 + vp += sprintf(vp, "ccode=%c%c", (w >> 8), (w & 0xff));
11349 + vp++;
11350 +
11351 + }
11352 +
11353 + /* parameter section of sprom starts at byte offset 72 */
11354 + woff = 72/2;
11355 +
11356 + /* first 6 bytes are il0macaddr */
11357 + ea.octet[0] = (b[woff] >> 8) & 0xff;
11358 + ea.octet[1] = b[woff] & 0xff;
11359 + ea.octet[2] = (b[woff+1] >> 8) & 0xff;
11360 + ea.octet[3] = b[woff+1] & 0xff;
11361 + ea.octet[4] = (b[woff+2] >> 8) & 0xff;
11362 + ea.octet[5] = b[woff+2] & 0xff;
11363 + woff += 3;
11364 + bcm_ether_ntoa((uchar*)&ea, eabuf);
11365 + vp += sprintf(vp, "il0macaddr=%s", eabuf);
11366 + vp++;
11367 +
11368 + /* next 6 bytes are et0macaddr */
11369 + ea.octet[0] = (b[woff] >> 8) & 0xff;
11370 + ea.octet[1] = b[woff] & 0xff;
11371 + ea.octet[2] = (b[woff+1] >> 8) & 0xff;
11372 + ea.octet[3] = b[woff+1] & 0xff;
11373 + ea.octet[4] = (b[woff+2] >> 8) & 0xff;
11374 + ea.octet[5] = b[woff+2] & 0xff;
11375 + woff += 3;
11376 + bcm_ether_ntoa((uchar*)&ea, eabuf);
11377 + vp += sprintf(vp, "et0macaddr=%s", eabuf);
11378 + vp++;
11379 +
11380 + /* next 6 bytes are et1macaddr */
11381 + ea.octet[0] = (b[woff] >> 8) & 0xff;
11382 + ea.octet[1] = b[woff] & 0xff;
11383 + ea.octet[2] = (b[woff+1] >> 8) & 0xff;
11384 + ea.octet[3] = b[woff+1] & 0xff;
11385 + ea.octet[4] = (b[woff+2] >> 8) & 0xff;
11386 + ea.octet[5] = b[woff+2] & 0xff;
11387 + woff += 3;
11388 + bcm_ether_ntoa((uchar*)&ea, eabuf);
11389 + vp += sprintf(vp, "et1macaddr=%s", eabuf);
11390 + vp++;
11391 +
11392 + /*
11393 + * Enet phy settings one or two singles or a dual
11394 + * Bits 4-0 : MII address for enet0 (0x1f for not there)
11395 + * Bits 9-5 : MII address for enet1 (0x1f for not there)
11396 + * Bit 14 : Mdio for enet0
11397 + * Bit 15 : Mdio for enet1
11398 + */
11399 + w = b[woff];
11400 + vp += sprintf(vp, "et0phyaddr=%d", (w & 0x1f));
11401 + vp++;
11402 + vp += sprintf(vp, "et1phyaddr=%d", ((w >> 5) & 0x1f));
11403 + vp++;
11404 + vp += sprintf(vp, "et0mdcport=%d", ((w >> 14) & 0x1));
11405 + vp++;
11406 + vp += sprintf(vp, "et1mdcport=%d", ((w >> 15) & 0x1));
11407 + vp++;
11408 +
11409 + /* Word 46 has board rev, antennas 0/1 & Country code/control */
11410 + w = b[46];
11411 + vp += sprintf(vp, "boardrev=%d", w & 0xff);
11412 + vp++;
11413 +
11414 + if (sromrev > 1)
11415 + vp += sprintf(vp, "cctl=%d", (w >> 8) & 0xf);
11416 + else
11417 + vp += sprintf(vp, "cc=%d", (w >> 8) & 0xf);
11418 + vp++;
11419 +
11420 + vp += sprintf(vp, "aa0=%d", (w >> 12) & 0x3);
11421 + vp++;
11422 +
11423 + vp += sprintf(vp, "aa1=%d", (w >> 14) & 0x3);
11424 + vp++;
11425 +
11426 + /* Words 47-49 set the (wl) pa settings */
11427 + woff = 47;
11428 +
11429 + for (i = 0; i < 3; i++) {
11430 + vp += sprintf(vp, "pa0b%d=%d", i, b[woff+i]);
11431 + vp++;
11432 + vp += sprintf(vp, "pa1b%d=%d", i, b[woff+i+6]);
11433 + vp++;
11434 + }
11435 +
11436 + /*
11437 + * Words 50-51 set the customer-configured wl led behavior.
11438 + * 8 bits/gpio pin. High bit: activehi=0, activelo=1;
11439 + * LED behavior values defined in wlioctl.h .
11440 + */
11441 + w = b[50];
11442 + if ((w != 0) && (w != 0xffff)) {
11443 + /* gpio0 */
11444 + vp += sprintf(vp, "wl0gpio0=%d", (w & 0xff));
11445 + vp++;
11446 +
11447 + /* gpio1 */
11448 + vp += sprintf(vp, "wl0gpio1=%d", (w >> 8) & 0xff);
11449 + vp++;
11450 + }
11451 + w = b[51];
11452 + if ((w != 0) && (w != 0xffff)) {
11453 + /* gpio2 */
11454 + vp += sprintf(vp, "wl0gpio2=%d", w & 0xff);
11455 + vp++;
11456 +
11457 + /* gpio3 */
11458 + vp += sprintf(vp, "wl0gpio3=%d", (w >> 8) & 0xff);
11459 + vp++;
11460 + }
11461 +
11462 + /* Word 52 is max power 0/1 */
11463 + w = b[52];
11464 + vp += sprintf(vp, "pa0maxpwr=%d", w & 0xff);
11465 + vp++;
11466 + vp += sprintf(vp, "pa1maxpwr=%d", (w >> 8) & 0xff);
11467 + vp++;
11468 +
11469 + /* Word 56 is idle tssi target 0/1 */
11470 + w = b[56];
11471 + vp += sprintf(vp, "pa0itssit=%d", w & 0xff);
11472 + vp++;
11473 + vp += sprintf(vp, "pa1itssit=%d", (w >> 8) & 0xff);
11474 + vp++;
11475 +
11476 + /* Word 57 is boardflags, if not programmed make it zero */
11477 + w32 = (uint32)b[57];
11478 + if (w32 == 0xffff) w32 = 0;
11479 + if (sromrev > 1) {
11480 + /* Word 28 is the high bits of boardflags */
11481 + w32 |= (uint32)b[28] << 16;
11482 + }
11483 + vp += sprintf(vp, "boardflags=%d", w32);
11484 + vp++;
11485 +
11486 + /* Word 58 is antenna gain 0/1 */
11487 + w = b[58];
11488 + vp += sprintf(vp, "ag0=%d", w & 0xff);
11489 + vp++;
11490 +
11491 + vp += sprintf(vp, "ag1=%d", (w >> 8) & 0xff);
11492 + vp++;
11493 +
11494 + if (sromrev == 1) {
11495 + /* set the oem string */
11496 + vp += sprintf(vp, "oem=%02x%02x%02x%02x%02x%02x%02x%02x",
11497 + ((b[59] >> 8) & 0xff), (b[59] & 0xff),
11498 + ((b[60] >> 8) & 0xff), (b[60] & 0xff),
11499 + ((b[61] >> 8) & 0xff), (b[61] & 0xff),
11500 + ((b[62] >> 8) & 0xff), (b[62] & 0xff));
11501 + vp++;
11502 + } else if (sromrev == 2) {
11503 + /* Word 60 OFDM tx power offset from CCK level */
11504 + /* OFDM Power Offset - opo */
11505 + vp += sprintf(vp, "opo=%d", b[60] & 0xff);
11506 + vp++;
11507 + } else {
11508 + /* Word 60: cck power offsets */
11509 + vp += sprintf(vp, "cckpo=%d", b[60]);
11510 + vp++;
11511 +
11512 + /* Words 61+62: 11g ofdm power offsets */
11513 + w32 = ((uint32)b[62] << 16) | b[61];
11514 + vp += sprintf(vp, "ofdmgpo=%d", w32);
11515 + vp++;
11516 + }
11517 +
11518 + /* final nullbyte terminator */
11519 + *vp++ = '\0';
11520 +
11521 + ASSERT((vp - base) <= VARS_MAX);
11522 +
11523 +done: err = initvars_table(osh, base, vp, vars, count);
11524 +
11525 +err: MFREE(osh, base, VARS_MAX);
11526 + return err;
11527 +}
11528 +
11529 +/*
11530 + * Read the cis and call parsecis to initialize the vars.
11531 + * Return 0 on success, nonzero on error.
11532 + */
11533 +static int
11534 +initvars_cis_pcmcia(void *sbh, osl_t *osh, char **vars, int *count)
11535 +{
11536 + uint8 *cis = NULL;
11537 + int rc;
11538 + uint data_sz;
11539 +
11540 + data_sz = (sb_pcmciarev(sbh) == 1) ? (SPROM_SIZE * 2) : CIS_SIZE;
11541 +
11542 + if ((cis = MALLOC(osh, data_sz)) == NULL)
11543 + return (-2);
11544 +
11545 + if (sb_pcmciarev(sbh) == 1) {
11546 + if (srom_read(PCMCIA_BUS, (void *)NULL, osh, 0, data_sz, (uint16 *)cis)) {
11547 + MFREE(osh, cis, data_sz);
11548 + return (-1);
11549 + }
11550 + /* fix up endianess for 16-bit data vs 8-bit parsing */
11551 + ltoh16_buf((uint16 *)cis, data_sz);
11552 + } else
11553 + OSL_PCMCIA_READ_ATTR(osh, 0, cis, data_sz);
11554 +
11555 + rc = srom_parsecis(osh, cis, vars, count);
11556 +
11557 + MFREE(osh, cis, data_sz);
11558 +
11559 + return (rc);
11560 +}
11561 +
11562 diff -Nur linux-2.4.32/drivers/net/hnd/bcmutils.c linux-2.4.32-brcm/drivers/net/hnd/bcmutils.c
11563 --- linux-2.4.32/drivers/net/hnd/bcmutils.c 1970-01-01 01:00:00.000000000 +0100
11564 +++ linux-2.4.32-brcm/drivers/net/hnd/bcmutils.c 2005-12-16 23:39:11.288858250 +0100
11565 @@ -0,0 +1,1081 @@
11566 +/*
11567 + * Misc useful OS-independent routines.
11568 + *
11569 + * Copyright 2005, Broadcom Corporation
11570 + * All Rights Reserved.
11571 + *
11572 + * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY
11573 + * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM
11574 + * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS
11575 + * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE.
11576 + * $Id$
11577 + */
11578 +
11579 +#include <typedefs.h>
11580 +#ifdef BCMDRIVER
11581 +#include <osl.h>
11582 +#include <sbutils.h>
11583 +#include <bcmnvram.h>
11584 +#else
11585 +#include <stdio.h>
11586 +#include <string.h>
11587 +#endif
11588 +#include <bcmutils.h>
11589 +#include <bcmendian.h>
11590 +#include <bcmdevs.h>
11591 +
11592 +#ifdef BCMDRIVER
11593 +/* copy a pkt buffer chain into a buffer */
11594 +uint
11595 +pktcopy(osl_t *osh, void *p, uint offset, int len, uchar *buf)
11596 +{
11597 + uint n, ret = 0;
11598 +
11599 + if (len < 0)
11600 + len = 4096; /* "infinite" */
11601 +
11602 + /* skip 'offset' bytes */
11603 + for (; p && offset; p = PKTNEXT(osh, p)) {
11604 + if (offset < (uint)PKTLEN(osh, p))
11605 + break;
11606 + offset -= PKTLEN(osh, p);
11607 + }
11608 +
11609 + if (!p)
11610 + return 0;
11611 +
11612 + /* copy the data */
11613 + for (; p && len; p = PKTNEXT(osh, p)) {
11614 + n = MIN((uint)PKTLEN(osh, p) - offset, (uint)len);
11615 + bcopy(PKTDATA(osh, p) + offset, buf, n);
11616 + buf += n;
11617 + len -= n;
11618 + ret += n;
11619 + offset = 0;
11620 + }
11621 +
11622 + return ret;
11623 +}
11624 +
11625 +/* return total length of buffer chain */
11626 +uint
11627 +pkttotlen(osl_t *osh, void *p)
11628 +{
11629 + uint total;
11630 +
11631 + total = 0;
11632 + for (; p; p = PKTNEXT(osh, p))
11633 + total += PKTLEN(osh, p);
11634 + return (total);
11635 +}
11636 +
11637 +void
11638 +pktq_init(struct pktq *q, uint maxlen, const uint8 prio_map[])
11639 +{
11640 + q->head = q->tail = NULL;
11641 + q->maxlen = maxlen;
11642 + q->len = 0;
11643 + if (prio_map) {
11644 + q->priority = TRUE;
11645 + bcopy(prio_map, q->prio_map, sizeof(q->prio_map));
11646 + }
11647 + else
11648 + q->priority = FALSE;
11649 +}
11650 +
11651 +/* should always check pktq_full before calling pktenq */
11652 +void
11653 +pktenq(struct pktq *q, void *p, bool lifo)
11654 +{
11655 + void *next, *prev;
11656 +
11657 + /* allow 10 pkts slack */
11658 + ASSERT(q->len < (q->maxlen + 10));
11659 +
11660 + /* Queueing chains not allowed */
11661 + ASSERT(PKTLINK(p) == NULL);
11662 +
11663 + /* Queue is empty */
11664 + if (q->tail == NULL) {
11665 + ASSERT(q->head == NULL);
11666 + q->head = q->tail = p;
11667 + }
11668 +
11669 + /* Insert at head or tail */
11670 + else if (q->priority == FALSE) {
11671 + /* Insert at head (LIFO) */
11672 + if (lifo) {
11673 + PKTSETLINK(p, q->head);
11674 + q->head = p;
11675 + }
11676 + /* Insert at tail (FIFO) */
11677 + else {
11678 + ASSERT(PKTLINK(q->tail) == NULL);
11679 + PKTSETLINK(q->tail, p);
11680 + PKTSETLINK(p, NULL);
11681 + q->tail = p;
11682 + }
11683 + }
11684 +
11685 + /* Insert by priority */
11686 + else {
11687 + /* legal priorities 0-7 */
11688 + ASSERT(PKTPRIO(p) <= MAXPRIO);
11689 +
11690 + ASSERT(q->head);
11691 + ASSERT(q->tail);
11692 + /* Shortcut to insertion at tail */
11693 + if (_pktq_pri(q, PKTPRIO(p)) < _pktq_pri(q, PKTPRIO(q->tail)) ||
11694 + (!lifo && _pktq_pri(q, PKTPRIO(p)) <= _pktq_pri(q, PKTPRIO(q->tail)))) {
11695 + prev = q->tail;
11696 + next = NULL;
11697 + }
11698 + /* Insert at head or in the middle */
11699 + else {
11700 + prev = NULL;
11701 + next = q->head;
11702 + }
11703 + /* Walk the queue */
11704 + for (; next; prev = next, next = PKTLINK(next)) {
11705 + /* Priority queue invariant */
11706 + ASSERT(!prev || _pktq_pri(q, PKTPRIO(prev)) >= _pktq_pri(q, PKTPRIO(next)));
11707 + /* Insert at head of string of packets of same priority (LIFO) */
11708 + if (lifo) {
11709 + if (_pktq_pri(q, PKTPRIO(p)) >= _pktq_pri(q, PKTPRIO(next)))
11710 + break;
11711 + }
11712 + /* Insert at tail of string of packets of same priority (FIFO) */
11713 + else {
11714 + if (_pktq_pri(q, PKTPRIO(p)) > _pktq_pri(q, PKTPRIO(next)))
11715 + break;
11716 + }
11717 + }
11718 + /* Insert at tail */
11719 + if (next == NULL) {
11720 + ASSERT(PKTLINK(q->tail) == NULL);
11721 + PKTSETLINK(q->tail, p);
11722 + PKTSETLINK(p, NULL);
11723 + q->tail = p;
11724 + }
11725 + /* Insert in the middle */
11726 + else if (prev) {
11727 + PKTSETLINK(prev, p);
11728 + PKTSETLINK(p, next);
11729 + }
11730 + /* Insert at head */
11731 + else {
11732 + PKTSETLINK(p, q->head);
11733 + q->head = p;
11734 + }
11735 + }
11736 +
11737 + /* List invariants after insertion */
11738 + ASSERT(q->head);
11739 + ASSERT(PKTLINK(q->tail) == NULL);
11740 +
11741 + q->len++;
11742 +}
11743 +
11744 +/* dequeue packet at head */
11745 +void*
11746 +pktdeq(struct pktq *q)
11747 +{
11748 + void *p;
11749 +
11750 + if ((p = q->head)) {
11751 + ASSERT(q->tail);
11752 + q->head = PKTLINK(p);
11753 + PKTSETLINK(p, NULL);
11754 + q->len--;
11755 + if (q->head == NULL)
11756 + q->tail = NULL;
11757 + }
11758 + else {
11759 + ASSERT(q->tail == NULL);
11760 + }
11761 +
11762 + return (p);
11763 +}
11764 +
11765 +/* dequeue packet at tail */
11766 +void*
11767 +pktdeqtail(struct pktq *q)
11768 +{
11769 + void *p;
11770 + void *next, *prev;
11771 +
11772 + if (q->head == q->tail) { /* last packet on queue or queue empty */
11773 + p = q->head;
11774 + q->head = q->tail = NULL;
11775 + q->len = 0;
11776 + return(p);
11777 + }
11778 +
11779 + /* start walk at head */
11780 + prev = NULL;
11781 + next = q->head;
11782 +
11783 + /* Walk the queue to find prev of q->tail */
11784 + for (; next; prev = next, next = PKTLINK(next)) {
11785 + if (next == q->tail)
11786 + break;
11787 + }
11788 +
11789 + ASSERT(prev);
11790 +
11791 + PKTSETLINK(prev, NULL);
11792 + q->tail = prev;
11793 + q->len--;
11794 + p = next;
11795 +
11796 + return (p);
11797 +}
11798 +
11799 +unsigned char bcm_ctype[] = {
11800 + _BCM_C,_BCM_C,_BCM_C,_BCM_C,_BCM_C,_BCM_C,_BCM_C,_BCM_C, /* 0-7 */
11801 + _BCM_C,_BCM_C|_BCM_S,_BCM_C|_BCM_S,_BCM_C|_BCM_S,_BCM_C|_BCM_S,_BCM_C|_BCM_S,_BCM_C,_BCM_C, /* 8-15 */
11802 + _BCM_C,_BCM_C,_BCM_C,_BCM_C,_BCM_C,_BCM_C,_BCM_C,_BCM_C, /* 16-23 */
11803 + _BCM_C,_BCM_C,_BCM_C,_BCM_C,_BCM_C,_BCM_C,_BCM_C,_BCM_C, /* 24-31 */
11804 + _BCM_S|_BCM_SP,_BCM_P,_BCM_P,_BCM_P,_BCM_P,_BCM_P,_BCM_P,_BCM_P, /* 32-39 */
11805 + _BCM_P,_BCM_P,_BCM_P,_BCM_P,_BCM_P,_BCM_P,_BCM_P,_BCM_P, /* 40-47 */
11806 + _BCM_D,_BCM_D,_BCM_D,_BCM_D,_BCM_D,_BCM_D,_BCM_D,_BCM_D, /* 48-55 */
11807 + _BCM_D,_BCM_D,_BCM_P,_BCM_P,_BCM_P,_BCM_P,_BCM_P,_BCM_P, /* 56-63 */
11808 + _BCM_P,_BCM_U|_BCM_X,_BCM_U|_BCM_X,_BCM_U|_BCM_X,_BCM_U|_BCM_X,_BCM_U|_BCM_X,_BCM_U|_BCM_X,_BCM_U, /* 64-71 */
11809 + _BCM_U,_BCM_U,_BCM_U,_BCM_U,_BCM_U,_BCM_U,_BCM_U,_BCM_U, /* 72-79 */
11810 + _BCM_U,_BCM_U,_BCM_U,_BCM_U,_BCM_U,_BCM_U,_BCM_U,_BCM_U, /* 80-87 */
11811 + _BCM_U,_BCM_U,_BCM_U,_BCM_P,_BCM_P,_BCM_P,_BCM_P,_BCM_P, /* 88-95 */
11812 + _BCM_P,_BCM_L|_BCM_X,_BCM_L|_BCM_X,_BCM_L|_BCM_X,_BCM_L|_BCM_X,_BCM_L|_BCM_X,_BCM_L|_BCM_X,_BCM_L, /* 96-103 */
11813 + _BCM_L,_BCM_L,_BCM_L,_BCM_L,_BCM_L,_BCM_L,_BCM_L,_BCM_L, /* 104-111 */
11814 + _BCM_L,_BCM_L,_BCM_L,_BCM_L,_BCM_L,_BCM_L,_BCM_L,_BCM_L, /* 112-119 */
11815 + _BCM_L,_BCM_L,_BCM_L,_BCM_P,_BCM_P,_BCM_P,_BCM_P,_BCM_C, /* 120-127 */
11816 + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 128-143 */
11817 + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 144-159 */
11818 + _BCM_S|_BCM_SP,_BCM_P,_BCM_P,_BCM_P,_BCM_P,_BCM_P,_BCM_P,_BCM_P,_BCM_P,_BCM_P,_BCM_P,_BCM_P,_BCM_P,_BCM_P,_BCM_P,_BCM_P, /* 160-175 */
11819 + _BCM_P,_BCM_P,_BCM_P,_BCM_P,_BCM_P,_BCM_P,_BCM_P,_BCM_P,_BCM_P,_BCM_P,_BCM_P,_BCM_P,_BCM_P,_BCM_P,_BCM_P,_BCM_P, /* 176-191 */
11820 + _BCM_U,_BCM_U,_BCM_U,_BCM_U,_BCM_U,_BCM_U,_BCM_U,_BCM_U,_BCM_U,_BCM_U,_BCM_U,_BCM_U,_BCM_U,_BCM_U,_BCM_U,_BCM_U, /* 192-207 */
11821 + _BCM_U,_BCM_U,_BCM_U,_BCM_U,_BCM_U,_BCM_U,_BCM_U,_BCM_P,_BCM_U,_BCM_U,_BCM_U,_BCM_U,_BCM_U,_BCM_U,_BCM_U,_BCM_L, /* 208-223 */
11822 + _BCM_L,_BCM_L,_BCM_L,_BCM_L,_BCM_L,_BCM_L,_BCM_L,_BCM_L,_BCM_L,_BCM_L,_BCM_L,_BCM_L,_BCM_L,_BCM_L,_BCM_L,_BCM_L, /* 224-239 */
11823 + _BCM_L,_BCM_L,_BCM_L,_BCM_L,_BCM_L,_BCM_L,_BCM_L,_BCM_P,_BCM_L,_BCM_L,_BCM_L,_BCM_L,_BCM_L,_BCM_L,_BCM_L,_BCM_L /* 240-255 */
11824 +};
11825 +
11826 +uchar
11827 +bcm_toupper(uchar c)
11828 +{
11829 + if (bcm_islower(c))
11830 + c -= 'a'-'A';
11831 + return (c);
11832 +}
11833 +
11834 +ulong
11835 +bcm_strtoul(char *cp, char **endp, uint base)
11836 +{
11837 + ulong result, value;
11838 + bool minus;
11839 +
11840 + minus = FALSE;
11841 +
11842 + while (bcm_isspace(*cp))
11843 + cp++;
11844 +
11845 + if (cp[0] == '+')
11846 + cp++;
11847 + else if (cp[0] == '-') {
11848 + minus = TRUE;
11849 + cp++;
11850 + }
11851 +
11852 + if (base == 0) {
11853 + if (cp[0] == '0') {
11854 + if ((cp[1] == 'x') || (cp[1] == 'X')) {
11855 + base = 16;
11856 + cp = &cp[2];
11857 + } else {
11858 + base = 8;
11859 + cp = &cp[1];
11860 + }
11861 + } else
11862 + base = 10;
11863 + } else if (base == 16 && (cp[0] == '0') && ((cp[1] == 'x') || (cp[1] == 'X'))) {
11864 + cp = &cp[2];
11865 + }
11866 +
11867 + result = 0;
11868 +
11869 + while (bcm_isxdigit(*cp) &&
11870 + (value = bcm_isdigit(*cp) ? *cp-'0' : bcm_toupper(*cp)-'A'+10) < base) {
11871 + result = result*base + value;
11872 + cp++;
11873 + }
11874 +
11875 + if (minus)
11876 + result = (ulong)(result * -1);
11877 +
11878 + if (endp)
11879 + *endp = (char *)cp;
11880 +
11881 + return (result);
11882 +}
11883 +
11884 +uint
11885 +bcm_atoi(char *s)
11886 +{
11887 + uint n;
11888 +
11889 + n = 0;
11890 +
11891 + while (bcm_isdigit(*s))
11892 + n = (n * 10) + *s++ - '0';
11893 + return (n);
11894 +}
11895 +
11896 +/* return pointer to location of substring 'needle' in 'haystack' */
11897 +char*
11898 +bcmstrstr(char *haystack, char *needle)
11899 +{
11900 + int len, nlen;
11901 + int i;
11902 +
11903 + if ((haystack == NULL) || (needle == NULL))
11904 + return (haystack);
11905 +
11906 + nlen = strlen(needle);
11907 + len = strlen(haystack) - nlen + 1;
11908 +
11909 + for (i = 0; i < len; i++)
11910 + if (bcmp(needle, &haystack[i], nlen) == 0)
11911 + return (&haystack[i]);
11912 + return (NULL);
11913 +}
11914 +
11915 +char*
11916 +bcmstrcat(char *dest, const char *src)
11917 +{
11918 + strcpy(&dest[strlen(dest)], src);
11919 + return (dest);
11920 +}
11921 +
11922 +#if defined(CONFIG_USBRNDIS_RETAIL) || defined(NDIS_MINIPORT_DRIVER)
11923 +/* registry routine buffer preparation utility functions:
11924 + * parameter order is like strncpy, but returns count
11925 + * of bytes copied. Minimum bytes copied is null char(1)/wchar(2)
11926 + */
11927 +ulong
11928 +wchar2ascii(
11929 + char *abuf,
11930 + ushort *wbuf,
11931 + ushort wbuflen,
11932 + ulong abuflen
11933 +)
11934 +{
11935 + ulong copyct = 1;
11936 + ushort i;
11937 +
11938 + if (abuflen == 0)
11939 + return 0;
11940 +
11941 + /* wbuflen is in bytes */
11942 + wbuflen /= sizeof(ushort);
11943 +
11944 + for (i = 0; i < wbuflen; ++i) {
11945 + if (--abuflen == 0)
11946 + break;
11947 + *abuf++ = (char) *wbuf++;
11948 + ++copyct;
11949 + }
11950 + *abuf = '\0';
11951 +
11952 + return copyct;
11953 +}
11954 +#endif
11955 +
11956 +char*
11957 +bcm_ether_ntoa(char *ea, char *buf)
11958 +{
11959 + sprintf(buf,"%02x:%02x:%02x:%02x:%02x:%02x",
11960 + (uchar)ea[0]&0xff, (uchar)ea[1]&0xff, (uchar)ea[2]&0xff,
11961 + (uchar)ea[3]&0xff, (uchar)ea[4]&0xff, (uchar)ea[5]&0xff);
11962 + return (buf);
11963 +}
11964 +
11965 +/* parse a xx:xx:xx:xx:xx:xx format ethernet address */
11966 +int
11967 +bcm_ether_atoe(char *p, char *ea)
11968 +{
11969 + int i = 0;
11970 +
11971 + for (;;) {
11972 + ea[i++] = (char) bcm_strtoul(p, &p, 16);
11973 + if (!*p++ || i == 6)
11974 + break;
11975 + }
11976 +
11977 + return (i == 6);
11978 +}
11979 +
11980 +void
11981 +bcm_mdelay(uint ms)
11982 +{
11983 + uint i;
11984 +
11985 + for (i = 0; i < ms; i++) {
11986 + OSL_DELAY(1000);
11987 + }
11988 +}
11989 +
11990 +/*
11991 + * Search the name=value vars for a specific one and return its value.
11992 + * Returns NULL if not found.
11993 + */
11994 +char*
11995 +getvar(char *vars, char *name)
11996 +{
11997 + char *s;
11998 + int len;
11999 +
12000 + len = strlen(name);
12001 +
12002 + /* first look in vars[] */
12003 + for (s = vars; s && *s; ) {
12004 + if ((bcmp(s, name, len) == 0) && (s[len] == '='))
12005 + return (&s[len+1]);
12006 +
12007 + while (*s++)
12008 + ;
12009 + }
12010 +
12011 + /* then query nvram */
12012 + return (BCMINIT(nvram_get)(name));
12013 +}
12014 +
12015 +/*
12016 + * Search the vars for a specific one and return its value as
12017 + * an integer. Returns 0 if not found.
12018 + */
12019 +int
12020 +getintvar(char *vars, char *name)
12021 +{
12022 + char *val;
12023 +
12024 + if ((val = getvar(vars, name)) == NULL)
12025 + return (0);
12026 +
12027 + return (bcm_strtoul(val, NULL, 0));
12028 +}
12029 +
12030 +
12031 +/* Search for token in comma separated token-string */
12032 +static int
12033 +findmatch(char *string, char *name)
12034 +{
12035 + uint len;
12036 + char *c;
12037 +
12038 + len = strlen(name);
12039 + while ((c = strchr(string, ',')) != NULL) {
12040 + if (len == (uint)(c - string) && !strncmp(string, name, len))
12041 + return 1;
12042 + string = c + 1;
12043 + }
12044 +
12045 + return (!strcmp(string, name));
12046 +}
12047 +
12048 +/* Return gpio pin number assigned to the named pin */
12049 +/*
12050 +* Variable should be in format:
12051 +*
12052 +* gpio<N>=pin_name,pin_name
12053 +*
12054 +* This format allows multiple features to share the gpio with mutual
12055 +* understanding.
12056 +*
12057 +* 'def_pin' is returned if a specific gpio is not defined for the requested functionality
12058 +* and if def_pin is not used by others.
12059 +*/
12060 +uint
12061 +getgpiopin(char *vars, char *pin_name, uint def_pin)
12062 +{
12063 + char name[] = "gpioXXXX";
12064 + char *val;
12065 + uint pin;
12066 +
12067 + /* Go thru all possibilities till a match in pin name */
12068 + for (pin = 0; pin < GPIO_NUMPINS; pin ++) {
12069 + sprintf(name, "gpio%d", pin);
12070 + val = getvar(vars, name);
12071 + if (val && findmatch(val, pin_name))
12072 + return pin;
12073 + }
12074 +
12075 + if (def_pin != GPIO_PIN_NOTDEFINED) {
12076 + /* make sure the default pin is not used by someone else */
12077 + sprintf(name, "gpio%d", def_pin);
12078 + if (getvar(vars, name)) {
12079 + def_pin = GPIO_PIN_NOTDEFINED;
12080 + }
12081 + }
12082 +
12083 + return def_pin;
12084 +}
12085 +
12086 +
12087 +static char bcm_undeferrstr[BCME_STRLEN];
12088 +
12089 +static const char *bcmerrorstrtable[] = \
12090 +{ "OK", /* 0 */
12091 + "Undefined error", /* BCME_ERROR */
12092 + "Bad Argument", /* BCME_BADARG*/
12093 + "Bad Option", /* BCME_BADOPTION*/
12094 + "Not up", /* BCME_NOTUP */
12095 + "Not down", /* BCME_NOTDOWN */
12096 + "Not AP", /* BCME_NOTAP */
12097 + "Not STA", /* BCME_NOTSTA */
12098 + "Bad Key Index", /* BCME_BADKEYIDX */
12099 + "Radio Off", /* BCME_RADIOOFF */
12100 + "Not band locked", /* BCME_NOTBANDLOCKED */
12101 + "No clock", /* BCME_NOCLK */
12102 + "Bad Rate valueset", /* BCME_BADRATESET */
12103 + "Bad Band", /* BCME_BADBAND */
12104 + "Buffer too short", /* BCME_BUFTOOSHORT */
12105 + "Buffer too length", /* BCME_BUFTOOLONG */
12106 + "Busy", /* BCME_BUSY */
12107 + "Not Associated", /* BCME_NOTASSOCIATED */
12108 + "Bad SSID len", /* BCME_BADSSIDLEN */
12109 + "Out of Range Channel", /* BCME_OUTOFRANGECHAN */
12110 + "Bad Channel", /* BCME_BADCHAN */
12111 + "Bad Address", /* BCME_BADADDR */
12112 + "Not Enough Resources", /* BCME_NORESOURCE */
12113 + "Unsupported", /* BCME_UNSUPPORTED */
12114 + "Bad length", /* BCME_BADLENGTH */
12115 + "Not Ready", /* BCME_NOTREADY */
12116 + "Not Permitted", /* BCME_EPERM */
12117 + "No Memory", /* BCME_NOMEM */
12118 + "Associated", /* BCME_ASSOCIATED */
12119 + "Not In Range", /* BCME_RANGE */
12120 + "Not Found" /* BCME_NOTFOUND */
12121 + };
12122 +
12123 +/* Convert the Error codes into related Error strings */
12124 +const char *
12125 +bcmerrorstr(int bcmerror)
12126 +{
12127 + int abs_bcmerror;
12128 +
12129 + abs_bcmerror = ABS(bcmerror);
12130 +
12131 + /* check if someone added a bcmerror code but forgot to add errorstring */
12132 + ASSERT(ABS(BCME_LAST) == (ARRAYSIZE(bcmerrorstrtable) - 1));
12133 + if ( (bcmerror > 0) || (abs_bcmerror > ABS(BCME_LAST))) {
12134 + sprintf(bcm_undeferrstr, "undefined Error %d", bcmerror);
12135 + return bcm_undeferrstr;
12136 + }
12137 +
12138 + ASSERT((strlen((char*)bcmerrorstrtable[abs_bcmerror])) < BCME_STRLEN);
12139 +
12140 + return bcmerrorstrtable[abs_bcmerror];
12141 +}
12142 +#endif /* #ifdef BCMDRIVER */
12143 +
12144 +
12145 +/*******************************************************************************
12146 + * crc8
12147 + *
12148 + * Computes a crc8 over the input data using the polynomial:
12149 + *
12150 + * x^8 + x^7 +x^6 + x^4 + x^2 + 1
12151 + *
12152 + * The caller provides the initial value (either CRC8_INIT_VALUE
12153 + * or the previous returned value) to allow for processing of
12154 + * discontiguous blocks of data. When generating the CRC the
12155 + * caller is responsible for complementing the final return value
12156 + * and inserting it into the byte stream. When checking, a final
12157 + * return value of CRC8_GOOD_VALUE indicates a valid CRC.
12158 + *
12159 + * Reference: Dallas Semiconductor Application Note 27
12160 + * Williams, Ross N., "A Painless Guide to CRC Error Detection Algorithms",
12161 + * ver 3, Aug 1993, ross@guest.adelaide.edu.au, Rocksoft Pty Ltd.,
12162 + * ftp://ftp.rocksoft.com/clients/rocksoft/papers/crc_v3.txt
12163 + *
12164 + ******************************************************************************/
12165 +
12166 +static uint8 crc8_table[256] = {
12167 + 0x00, 0xF7, 0xB9, 0x4E, 0x25, 0xD2, 0x9C, 0x6B,
12168 + 0x4A, 0xBD, 0xF3, 0x04, 0x6F, 0x98, 0xD6, 0x21,
12169 + 0x94, 0x63, 0x2D, 0xDA, 0xB1, 0x46, 0x08, 0xFF,
12170 + 0xDE, 0x29, 0x67, 0x90, 0xFB, 0x0C, 0x42, 0xB5,
12171 + 0x7F, 0x88, 0xC6, 0x31, 0x5A, 0xAD, 0xE3, 0x14,
12172 + 0x35, 0xC2, 0x8C, 0x7B, 0x10, 0xE7, 0xA9, 0x5E,
12173 + 0xEB, 0x1C, 0x52, 0xA5, 0xCE, 0x39, 0x77, 0x80,
12174 + 0xA1, 0x56, 0x18, 0xEF, 0x84, 0x73, 0x3D, 0xCA,
12175 + 0xFE, 0x09, 0x47, 0xB0, 0xDB, 0x2C, 0x62, 0x95,
12176 + 0xB4, 0x43, 0x0D, 0xFA, 0x91, 0x66, 0x28, 0xDF,
12177 + 0x6A, 0x9D, 0xD3, 0x24, 0x4F, 0xB8, 0xF6, 0x01,
12178 + 0x20, 0xD7, 0x99, 0x6E, 0x05, 0xF2, 0xBC, 0x4B,
12179 + 0x81, 0x76, 0x38, 0xCF, 0xA4, 0x53, 0x1D, 0xEA,
12180 + 0xCB, 0x3C, 0x72, 0x85, 0xEE, 0x19, 0x57, 0xA0,
12181 + 0x15, 0xE2, 0xAC, 0x5B, 0x30, 0xC7, 0x89, 0x7E,
12182 + 0x5F, 0xA8, 0xE6, 0x11, 0x7A, 0x8D, 0xC3, 0x34,
12183 + 0xAB, 0x5C, 0x12, 0xE5, 0x8E, 0x79, 0x37, 0xC0,
12184 + 0xE1, 0x16, 0x58, 0xAF, 0xC4, 0x33, 0x7D, 0x8A,
12185 + 0x3F, 0xC8, 0x86, 0x71, 0x1A, 0xED, 0xA3, 0x54,
12186 + 0x75, 0x82, 0xCC, 0x3B, 0x50, 0xA7, 0xE9, 0x1E,
12187 + 0xD4, 0x23, 0x6D, 0x9A, 0xF1, 0x06, 0x48, 0xBF,
12188 + 0x9E, 0x69, 0x27, 0xD0, 0xBB, 0x4C, 0x02, 0xF5,
12189 + 0x40, 0xB7, 0xF9, 0x0E, 0x65, 0x92, 0xDC, 0x2B,
12190 + 0x0A, 0xFD, 0xB3, 0x44, 0x2F, 0xD8, 0x96, 0x61,
12191 + 0x55, 0xA2, 0xEC, 0x1B, 0x70, 0x87, 0xC9, 0x3E,
12192 + 0x1F, 0xE8, 0xA6, 0x51, 0x3A, 0xCD, 0x83, 0x74,
12193 + 0xC1, 0x36, 0x78, 0x8F, 0xE4, 0x13, 0x5D, 0xAA,
12194 + 0x8B, 0x7C, 0x32, 0xC5, 0xAE, 0x59, 0x17, 0xE0,
12195 + 0x2A, 0xDD, 0x93, 0x64, 0x0F, 0xF8, 0xB6, 0x41,
12196 + 0x60, 0x97, 0xD9, 0x2E, 0x45, 0xB2, 0xFC, 0x0B,
12197 + 0xBE, 0x49, 0x07, 0xF0, 0x9B, 0x6C, 0x22, 0xD5,
12198 + 0xF4, 0x03, 0x4D, 0xBA, 0xD1, 0x26, 0x68, 0x9F
12199 +};
12200 +
12201 +#define CRC_INNER_LOOP(n, c, x) \
12202 + (c) = ((c) >> 8) ^ crc##n##_table[((c) ^ (x)) & 0xff]
12203 +
12204 +uint8
12205 +hndcrc8(
12206 + uint8 *pdata, /* pointer to array of data to process */
12207 + uint nbytes, /* number of input data bytes to process */
12208 + uint8 crc /* either CRC8_INIT_VALUE or previous return value */
12209 +)
12210 +{
12211 + /* hard code the crc loop instead of using CRC_INNER_LOOP macro
12212 + * to avoid the undefined and unnecessary (uint8 >> 8) operation. */
12213 + while (nbytes-- > 0)
12214 + crc = crc8_table[(crc ^ *pdata++) & 0xff];
12215 +
12216 + return crc;
12217 +}
12218 +
12219 +/*******************************************************************************
12220 + * crc16
12221 + *
12222 + * Computes a crc16 over the input data using the polynomial:
12223 + *
12224 + * x^16 + x^12 +x^5 + 1
12225 + *
12226 + * The caller provides the initial value (either CRC16_INIT_VALUE
12227 + * or the previous returned value) to allow for processing of
12228 + * discontiguous blocks of data. When generating the CRC the
12229 + * caller is responsible for complementing the final return value
12230 + * and inserting it into the byte stream. When checking, a final
12231 + * return value of CRC16_GOOD_VALUE indicates a valid CRC.
12232 + *
12233 + * Reference: Dallas Semiconductor Application Note 27
12234 + * Williams, Ross N., "A Painless Guide to CRC Error Detection Algorithms",
12235 + * ver 3, Aug 1993, ross@guest.adelaide.edu.au, Rocksoft Pty Ltd.,
12236 + * ftp://ftp.rocksoft.com/clients/rocksoft/papers/crc_v3.txt
12237 + *
12238 + ******************************************************************************/
12239 +
12240 +static uint16 crc16_table[256] = {
12241 + 0x0000, 0x1189, 0x2312, 0x329B, 0x4624, 0x57AD, 0x6536, 0x74BF,
12242 + 0x8C48, 0x9DC1, 0xAF5A, 0xBED3, 0xCA6C, 0xDBE5, 0xE97E, 0xF8F7,
12243 + 0x1081, 0x0108, 0x3393, 0x221A, 0x56A5, 0x472C, 0x75B7, 0x643E,
12244 + 0x9CC9, 0x8D40, 0xBFDB, 0xAE52, 0xDAED, 0xCB64, 0xF9FF, 0xE876,
12245 + 0x2102, 0x308B, 0x0210, 0x1399, 0x6726, 0x76AF, 0x4434, 0x55BD,
12246 + 0xAD4A, 0xBCC3, 0x8E58, 0x9FD1, 0xEB6E, 0xFAE7, 0xC87C, 0xD9F5,
12247 + 0x3183, 0x200A, 0x1291, 0x0318, 0x77A7, 0x662E, 0x54B5, 0x453C,
12248 + 0xBDCB, 0xAC42, 0x9ED9, 0x8F50, 0xFBEF, 0xEA66, 0xD8FD, 0xC974,
12249 + 0x4204, 0x538D, 0x6116, 0x709F, 0x0420, 0x15A9, 0x2732, 0x36BB,
12250 + 0xCE4C, 0xDFC5, 0xED5E, 0xFCD7, 0x8868, 0x99E1, 0xAB7A, 0xBAF3,
12251 + 0x5285, 0x430C, 0x7197, 0x601E, 0x14A1, 0x0528, 0x37B3, 0x263A,
12252 + 0xDECD, 0xCF44, 0xFDDF, 0xEC56, 0x98E9, 0x8960, 0xBBFB, 0xAA72,
12253 + 0x6306, 0x728F, 0x4014, 0x519D, 0x2522, 0x34AB, 0x0630, 0x17B9,
12254 + 0xEF4E, 0xFEC7, 0xCC5C, 0xDDD5, 0xA96A, 0xB8E3, 0x8A78, 0x9BF1,
12255 + 0x7387, 0x620E, 0x5095, 0x411C, 0x35A3, 0x242A, 0x16B1, 0x0738,
12256 + 0xFFCF, 0xEE46, 0xDCDD, 0xCD54, 0xB9EB, 0xA862, 0x9AF9, 0x8B70,
12257 + 0x8408, 0x9581, 0xA71A, 0xB693, 0xC22C, 0xD3A5, 0xE13E, 0xF0B7,
12258 + 0x0840, 0x19C9, 0x2B52, 0x3ADB, 0x4E64, 0x5FED, 0x6D76, 0x7CFF,
12259 + 0x9489, 0x8500, 0xB79B, 0xA612, 0xD2AD, 0xC324, 0xF1BF, 0xE036,
12260 + 0x18C1, 0x0948, 0x3BD3, 0x2A5A, 0x5EE5, 0x4F6C, 0x7DF7, 0x6C7E,
12261 + 0xA50A, 0xB483, 0x8618, 0x9791, 0xE32E, 0xF2A7, 0xC03C, 0xD1B5,
12262 + 0x2942, 0x38CB, 0x0A50, 0x1BD9, 0x6F66, 0x7EEF, 0x4C74, 0x5DFD,
12263 + 0xB58B, 0xA402, 0x9699, 0x8710, 0xF3AF, 0xE226, 0xD0BD, 0xC134,
12264 + 0x39C3, 0x284A, 0x1AD1, 0x0B58, 0x7FE7, 0x6E6E, 0x5CF5, 0x4D7C,
12265 + 0xC60C, 0xD785, 0xE51E, 0xF497, 0x8028, 0x91A1, 0xA33A, 0xB2B3,
12266 + 0x4A44, 0x5BCD, 0x6956, 0x78DF, 0x0C60, 0x1DE9, 0x2F72, 0x3EFB,
12267 + 0xD68D, 0xC704, 0xF59F, 0xE416, 0x90A9, 0x8120, 0xB3BB, 0xA232,
12268 + 0x5AC5, 0x4B4C, 0x79D7, 0x685E, 0x1CE1, 0x0D68, 0x3FF3, 0x2E7A,
12269 + 0xE70E, 0xF687, 0xC41C, 0xD595, 0xA12A, 0xB0A3, 0x8238, 0x93B1,
12270 + 0x6B46, 0x7ACF, 0x4854, 0x59DD, 0x2D62, 0x3CEB, 0x0E70, 0x1FF9,
12271 + 0xF78F, 0xE606, 0xD49D, 0xC514, 0xB1AB, 0xA022, 0x92B9, 0x8330,
12272 + 0x7BC7, 0x6A4E, 0x58D5, 0x495C, 0x3DE3, 0x2C6A, 0x1EF1, 0x0F78
12273 +};
12274 +
12275 +uint16
12276 +hndcrc16(
12277 + uint8 *pdata, /* pointer to array of data to process */
12278 + uint nbytes, /* number of input data bytes to process */
12279 + uint16 crc /* either CRC16_INIT_VALUE or previous return value */
12280 +)
12281 +{
12282 + while (nbytes-- > 0)
12283 + CRC_INNER_LOOP(16, crc, *pdata++);
12284 + return crc;
12285 +}
12286 +
12287 +static uint32 crc32_table[256] = {
12288 + 0x00000000, 0x77073096, 0xEE0E612C, 0x990951BA,
12289 + 0x076DC419, 0x706AF48F, 0xE963A535, 0x9E6495A3,
12290 + 0x0EDB8832, 0x79DCB8A4, 0xE0D5E91E, 0x97D2D988,
12291 + 0x09B64C2B, 0x7EB17CBD, 0xE7B82D07, 0x90BF1D91,
12292 + 0x1DB71064, 0x6AB020F2, 0xF3B97148, 0x84BE41DE,
12293 + 0x1ADAD47D, 0x6DDDE4EB, 0xF4D4B551, 0x83D385C7,
12294 + 0x136C9856, 0x646BA8C0, 0xFD62F97A, 0x8A65C9EC,
12295 + 0x14015C4F, 0x63066CD9, 0xFA0F3D63, 0x8D080DF5,
12296 + 0x3B6E20C8, 0x4C69105E, 0xD56041E4, 0xA2677172,
12297 + 0x3C03E4D1, 0x4B04D447, 0xD20D85FD, 0xA50AB56B,
12298 + 0x35B5A8FA, 0x42B2986C, 0xDBBBC9D6, 0xACBCF940,
12299 + 0x32D86CE3, 0x45DF5C75, 0xDCD60DCF, 0xABD13D59,
12300 + 0x26D930AC, 0x51DE003A, 0xC8D75180, 0xBFD06116,
12301 + 0x21B4F4B5, 0x56B3C423, 0xCFBA9599, 0xB8BDA50F,
12302 + 0x2802B89E, 0x5F058808, 0xC60CD9B2, 0xB10BE924,
12303 + 0x2F6F7C87, 0x58684C11, 0xC1611DAB, 0xB6662D3D,
12304 + 0x76DC4190, 0x01DB7106, 0x98D220BC, 0xEFD5102A,
12305 + 0x71B18589, 0x06B6B51F, 0x9FBFE4A5, 0xE8B8D433,
12306 + 0x7807C9A2, 0x0F00F934, 0x9609A88E, 0xE10E9818,
12307 + 0x7F6A0DBB, 0x086D3D2D, 0x91646C97, 0xE6635C01,
12308 + 0x6B6B51F4, 0x1C6C6162, 0x856530D8, 0xF262004E,
12309 + 0x6C0695ED, 0x1B01A57B, 0x8208F4C1, 0xF50FC457,
12310 + 0x65B0D9C6, 0x12B7E950, 0x8BBEB8EA, 0xFCB9887C,
12311 + 0x62DD1DDF, 0x15DA2D49, 0x8CD37CF3, 0xFBD44C65,
12312 + 0x4DB26158, 0x3AB551CE, 0xA3BC0074, 0xD4BB30E2,
12313 + 0x4ADFA541, 0x3DD895D7, 0xA4D1C46D, 0xD3D6F4FB,
12314 + 0x4369E96A, 0x346ED9FC, 0xAD678846, 0xDA60B8D0,
12315 + 0x44042D73, 0x33031DE5, 0xAA0A4C5F, 0xDD0D7CC9,
12316 + 0x5005713C, 0x270241AA, 0xBE0B1010, 0xC90C2086,
12317 + 0x5768B525, 0x206F85B3, 0xB966D409, 0xCE61E49F,
12318 + 0x5EDEF90E, 0x29D9C998, 0xB0D09822, 0xC7D7A8B4,
12319 + 0x59B33D17, 0x2EB40D81, 0xB7BD5C3B, 0xC0BA6CAD,
12320 + 0xEDB88320, 0x9ABFB3B6, 0x03B6E20C, 0x74B1D29A,
12321 + 0xEAD54739, 0x9DD277AF, 0x04DB2615, 0x73DC1683,
12322 + 0xE3630B12, 0x94643B84, 0x0D6D6A3E, 0x7A6A5AA8,
12323 + 0xE40ECF0B, 0x9309FF9D, 0x0A00AE27, 0x7D079EB1,
12324 + 0xF00F9344, 0x8708A3D2, 0x1E01F268, 0x6906C2FE,
12325 + 0xF762575D, 0x806567CB, 0x196C3671, 0x6E6B06E7,
12326 + 0xFED41B76, 0x89D32BE0, 0x10DA7A5A, 0x67DD4ACC,
12327 + 0xF9B9DF6F, 0x8EBEEFF9, 0x17B7BE43, 0x60B08ED5,
12328 + 0xD6D6A3E8, 0xA1D1937E, 0x38D8C2C4, 0x4FDFF252,
12329 + 0xD1BB67F1, 0xA6BC5767, 0x3FB506DD, 0x48B2364B,
12330 + 0xD80D2BDA, 0xAF0A1B4C, 0x36034AF6, 0x41047A60,
12331 + 0xDF60EFC3, 0xA867DF55, 0x316E8EEF, 0x4669BE79,
12332 + 0xCB61B38C, 0xBC66831A, 0x256FD2A0, 0x5268E236,
12333 + 0xCC0C7795, 0xBB0B4703, 0x220216B9, 0x5505262F,
12334 + 0xC5BA3BBE, 0xB2BD0B28, 0x2BB45A92, 0x5CB36A04,
12335 + 0xC2D7FFA7, 0xB5D0CF31, 0x2CD99E8B, 0x5BDEAE1D,
12336 + 0x9B64C2B0, 0xEC63F226, 0x756AA39C, 0x026D930A,
12337 + 0x9C0906A9, 0xEB0E363F, 0x72076785, 0x05005713,
12338 + 0x95BF4A82, 0xE2B87A14, 0x7BB12BAE, 0x0CB61B38,
12339 + 0x92D28E9B, 0xE5D5BE0D, 0x7CDCEFB7, 0x0BDBDF21,
12340 + 0x86D3D2D4, 0xF1D4E242, 0x68DDB3F8, 0x1FDA836E,
12341 + 0x81BE16CD, 0xF6B9265B, 0x6FB077E1, 0x18B74777,
12342 + 0x88085AE6, 0xFF0F6A70, 0x66063BCA, 0x11010B5C,
12343 + 0x8F659EFF, 0xF862AE69, 0x616BFFD3, 0x166CCF45,
12344 + 0xA00AE278, 0xD70DD2EE, 0x4E048354, 0x3903B3C2,
12345 + 0xA7672661, 0xD06016F7, 0x4969474D, 0x3E6E77DB,
12346 + 0xAED16A4A, 0xD9D65ADC, 0x40DF0B66, 0x37D83BF0,
12347 + 0xA9BCAE53, 0xDEBB9EC5, 0x47B2CF7F, 0x30B5FFE9,
12348 + 0xBDBDF21C, 0xCABAC28A, 0x53B39330, 0x24B4A3A6,
12349 + 0xBAD03605, 0xCDD70693, 0x54DE5729, 0x23D967BF,
12350 + 0xB3667A2E, 0xC4614AB8, 0x5D681B02, 0x2A6F2B94,
12351 + 0xB40BBE37, 0xC30C8EA1, 0x5A05DF1B, 0x2D02EF8D
12352 +};
12353 +
12354 +uint32
12355 +hndcrc32(
12356 + uint8 *pdata, /* pointer to array of data to process */
12357 + uint nbytes, /* number of input data bytes to process */
12358 + uint32 crc /* either CRC32_INIT_VALUE or previous return value */
12359 +)
12360 +{
12361 + uint8 *pend;
12362 +#ifdef __mips__
12363 + uint8 tmp[4];
12364 + ulong *tptr = (ulong *)tmp;
12365 +
12366 + /* in case the beginning of the buffer isn't aligned */
12367 + pend = (uint8 *)((uint)(pdata + 3) & 0xfffffffc);
12368 + nbytes -= (pend - pdata);
12369 + while (pdata < pend)
12370 + CRC_INNER_LOOP(32, crc, *pdata++);
12371 +
12372 + /* handle bulk of data as 32-bit words */
12373 + pend = pdata + (nbytes & 0xfffffffc);
12374 + while (pdata < pend) {
12375 + tptr = *((ulong *) pdata);
12376 + *((ulong *) pdata) += 1;
12377 + CRC_INNER_LOOP(32, crc, tmp[0]);
12378 + CRC_INNER_LOOP(32, crc, tmp[1]);
12379 + CRC_INNER_LOOP(32, crc, tmp[2]);
12380 + CRC_INNER_LOOP(32, crc, tmp[3]);
12381 + }
12382 +
12383 + /* 1-3 bytes at end of buffer */
12384 + pend = pdata + (nbytes & 0x03);
12385 + while (pdata < pend)
12386 + CRC_INNER_LOOP(32, crc, *pdata++);
12387 +#else
12388 + pend = pdata + nbytes;
12389 + while (pdata < pend)
12390 + CRC_INNER_LOOP(32, crc, *pdata++);
12391 +#endif
12392 +
12393 + return crc;
12394 +}
12395 +
12396 +#ifdef notdef
12397 +#define CLEN 1499
12398 +#define CBUFSIZ (CLEN+4)
12399 +#define CNBUFS 5
12400 +
12401 +void testcrc32(void)
12402 +{
12403 + uint j,k,l;
12404 + uint8 *buf;
12405 + uint len[CNBUFS];
12406 + uint32 crcr;
12407 + uint32 crc32tv[CNBUFS] =
12408 + {0xd2cb1faa, 0xd385c8fa, 0xf5b4f3f3, 0x55789e20, 0x00343110};
12409 +
12410 + ASSERT((buf = MALLOC(CBUFSIZ*CNBUFS)) != NULL);
12411 +
12412 + /* step through all possible alignments */
12413 + for (l=0;l<=4;l++) {
12414 + for (j=0; j<CNBUFS; j++) {
12415 + len[j] = CLEN;
12416 + for (k=0; k<len[j]; k++)
12417 + *(buf + j*CBUFSIZ + (k+l)) = (j+k) & 0xff;
12418 + }
12419 +
12420 + for (j=0; j<CNBUFS; j++) {
12421 + crcr = crc32(buf + j*CBUFSIZ + l, len[j], CRC32_INIT_VALUE);
12422 + ASSERT(crcr == crc32tv[j]);
12423 + }
12424 + }
12425 +
12426 + MFREE(buf, CBUFSIZ*CNBUFS);
12427 + return;
12428 +}
12429 +#endif
12430 +
12431 +
12432 +/*
12433 + * Advance from the current 1-byte tag/1-byte length/variable-length value
12434 + * triple, to the next, returning a pointer to the next.
12435 + * If the current or next TLV is invalid (does not fit in given buffer length),
12436 + * NULL is returned.
12437 + * *buflen is not modified if the TLV elt parameter is invalid, or is decremented
12438 + * by the TLV paramter's length if it is valid.
12439 + */
12440 +bcm_tlv_t *
12441 +bcm_next_tlv(bcm_tlv_t *elt, int *buflen)
12442 +{
12443 + int len;
12444 +
12445 + /* validate current elt */
12446 + if (!bcm_valid_tlv(elt, *buflen))
12447 + return NULL;
12448 +
12449 + /* advance to next elt */
12450 + len = elt->len;
12451 + elt = (bcm_tlv_t*)(elt->data + len);
12452 + *buflen -= (2 + len);
12453 +
12454 + /* validate next elt */
12455 + if (!bcm_valid_tlv(elt, *buflen))
12456 + return NULL;
12457 +
12458 + return elt;
12459 +}
12460 +
12461 +/*
12462 + * Traverse a string of 1-byte tag/1-byte length/variable-length value
12463 + * triples, returning a pointer to the substring whose first element
12464 + * matches tag
12465 + */
12466 +bcm_tlv_t *
12467 +bcm_parse_tlvs(void *buf, int buflen, uint key)
12468 +{
12469 + bcm_tlv_t *elt;
12470 + int totlen;
12471 +
12472 + elt = (bcm_tlv_t*)buf;
12473 + totlen = buflen;
12474 +
12475 + /* find tagged parameter */
12476 + while (totlen >= 2) {
12477 + int len = elt->len;
12478 +
12479 + /* validate remaining totlen */
12480 + if ((elt->id == key) && (totlen >= (len + 2)))
12481 + return (elt);
12482 +
12483 + elt = (bcm_tlv_t*)((uint8*)elt + (len + 2));
12484 + totlen -= (len + 2);
12485 + }
12486 +
12487 + return NULL;
12488 +}
12489 +
12490 +/*
12491 + * Traverse a string of 1-byte tag/1-byte length/variable-length value
12492 + * triples, returning a pointer to the substring whose first element
12493 + * matches tag. Stop parsing when we see an element whose ID is greater
12494 + * than the target key.
12495 + */
12496 +bcm_tlv_t *
12497 +bcm_parse_ordered_tlvs(void *buf, int buflen, uint key)
12498 +{
12499 + bcm_tlv_t *elt;
12500 + int totlen;
12501 +
12502 + elt = (bcm_tlv_t*)buf;
12503 + totlen = buflen;
12504 +
12505 + /* find tagged parameter */
12506 + while (totlen >= 2) {
12507 + uint id = elt->id;
12508 + int len = elt->len;
12509 +
12510 + /* Punt if we start seeing IDs > than target key */
12511 + if (id > key)
12512 + return(NULL);
12513 +
12514 + /* validate remaining totlen */
12515 + if ((id == key) && (totlen >= (len + 2)))
12516 + return (elt);
12517 +
12518 + elt = (bcm_tlv_t*)((uint8*)elt + (len + 2));
12519 + totlen -= (len + 2);
12520 + }
12521 + return NULL;
12522 +}
12523 +/* routine to dump fields in a fileddesc structure */
12524 +
12525 +uint
12526 +bcmdumpfields(readreg_rtn read_rtn, void *arg0, void *arg1, struct fielddesc *fielddesc_array, char *buf, uint32 bufsize)
12527 +{
12528 + uint filled_len;
12529 + uint len;
12530 + struct fielddesc *cur_ptr;
12531 +
12532 + filled_len = 0;
12533 + cur_ptr = fielddesc_array;
12534 +
12535 + while (bufsize > (filled_len + 64)) {
12536 + if (cur_ptr->nameandfmt == NULL)
12537 + break;
12538 + len = sprintf(buf, cur_ptr->nameandfmt, read_rtn(arg0, arg1, cur_ptr->offset));
12539 + buf += len;
12540 + filled_len += len;
12541 + cur_ptr++;
12542 + }
12543 + return filled_len;
12544 +}
12545 +
12546 +uint
12547 +bcm_mkiovar(char *name, char *data, uint datalen, char *buf, uint buflen)
12548 +{
12549 + uint len;
12550 +
12551 + len = strlen(name) + 1;
12552 +
12553 + if ((len + datalen) > buflen)
12554 + return 0;
12555 +
12556 + strcpy(buf, name);
12557 +
12558 + /* append data onto the end of the name string */
12559 + memcpy(&buf[len], data, datalen);
12560 + len += datalen;
12561 +
12562 + return len;
12563 +}
12564 +
12565 +/* Quarter dBm units to mW
12566 + * Table starts at QDBM_OFFSET, so the first entry is mW for qdBm=153
12567 + * Table is offset so the last entry is largest mW value that fits in
12568 + * a uint16.
12569 + */
12570 +
12571 +#define QDBM_OFFSET 153
12572 +#define QDBM_TABLE_LEN 40
12573 +
12574 +/* Smallest mW value that will round up to the first table entry, QDBM_OFFSET.
12575 + * Value is ( mW(QDBM_OFFSET - 1) + mW(QDBM_OFFSET) ) / 2
12576 + */
12577 +#define QDBM_TABLE_LOW_BOUND 6493
12578 +
12579 +/* Largest mW value that will round down to the last table entry,
12580 + * QDBM_OFFSET + QDBM_TABLE_LEN-1.
12581 + * Value is ( mW(QDBM_OFFSET + QDBM_TABLE_LEN - 1) + mW(QDBM_OFFSET + QDBM_TABLE_LEN) ) / 2.
12582 + */
12583 +#define QDBM_TABLE_HIGH_BOUND 64938
12584 +
12585 +static const uint16 nqdBm_to_mW_map[QDBM_TABLE_LEN] = {
12586 +/* qdBm: +0 +1 +2 +3 +4 +5 +6 +7 */
12587 +/* 153: */ 6683, 7079, 7499, 7943, 8414, 8913, 9441, 10000,
12588 +/* 161: */ 10593, 11220, 11885, 12589, 13335, 14125, 14962, 15849,
12589 +/* 169: */ 16788, 17783, 18836, 19953, 21135, 22387, 23714, 25119,
12590 +/* 177: */ 26607, 28184, 29854, 31623, 33497, 35481, 37584, 39811,
12591 +/* 185: */ 42170, 44668, 47315, 50119, 53088, 56234, 59566, 63096
12592 +};
12593 +
12594 +uint16
12595 +bcm_qdbm_to_mw(uint8 qdbm)
12596 +{
12597 + uint factor = 1;
12598 + int idx = qdbm - QDBM_OFFSET;
12599 +
12600 + if (idx > QDBM_TABLE_LEN) {
12601 + /* clamp to max uint16 mW value */
12602 + return 0xFFFF;
12603 + }
12604 +
12605 + /* scale the qdBm index up to the range of the table 0-40
12606 + * where an offset of 40 qdBm equals a factor of 10 mW.
12607 + */
12608 + while (idx < 0) {
12609 + idx += 40;
12610 + factor *= 10;
12611 + }
12612 +
12613 + /* return the mW value scaled down to the correct factor of 10,
12614 + * adding in factor/2 to get proper rounding. */
12615 + return ((nqdBm_to_mW_map[idx] + factor/2) / factor);
12616 +}
12617 +
12618 +uint8
12619 +bcm_mw_to_qdbm(uint16 mw)
12620 +{
12621 + uint8 qdbm;
12622 + int offset;
12623 + uint mw_uint = mw;
12624 + uint boundary;
12625 +
12626 + /* handle boundary case */
12627 + if (mw_uint <= 1)
12628 + return 0;
12629 +
12630 + offset = QDBM_OFFSET;
12631 +
12632 + /* move mw into the range of the table */
12633 + while (mw_uint < QDBM_TABLE_LOW_BOUND) {
12634 + mw_uint *= 10;
12635 + offset -= 40;
12636 + }
12637 +
12638 + for (qdbm = 0; qdbm < QDBM_TABLE_LEN-1; qdbm++) {
12639 + boundary = nqdBm_to_mW_map[qdbm] + (nqdBm_to_mW_map[qdbm+1] - nqdBm_to_mW_map[qdbm])/2;
12640 + if (mw_uint < boundary) break;
12641 + }
12642 +
12643 + qdbm += (uint8)offset;
12644 +
12645 + return(qdbm);
12646 +}
12647 diff -Nur linux-2.4.32/drivers/net/hnd/hnddma.c linux-2.4.32-brcm/drivers/net/hnd/hnddma.c
12648 --- linux-2.4.32/drivers/net/hnd/hnddma.c 1970-01-01 01:00:00.000000000 +0100
12649 +++ linux-2.4.32-brcm/drivers/net/hnd/hnddma.c 2005-12-16 23:39:11.288858250 +0100
12650 @@ -0,0 +1,1527 @@
12651 +/*
12652 + * Generic Broadcom Home Networking Division (HND) DMA module.
12653 + * This supports the following chips: BCM42xx, 44xx, 47xx .
12654 + *
12655 + * Copyright 2005, Broadcom Corporation
12656 + * All Rights Reserved.
12657 + *
12658 + * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY
12659 + * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM
12660 + * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS
12661 + * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE.
12662 + *
12663 + * $Id$
12664 + */
12665 +
12666 +#include <typedefs.h>
12667 +#include <osl.h>
12668 +#include <bcmendian.h>
12669 +#include <sbconfig.h>
12670 +#include <bcmutils.h>
12671 +#include <bcmdevs.h>
12672 +#include <sbutils.h>
12673 +
12674 +struct dma_info; /* forward declaration */
12675 +#define di_t struct dma_info
12676 +
12677 +#include <sbhnddma.h>
12678 +#include <hnddma.h>
12679 +
12680 +/* debug/trace */
12681 +#define DMA_ERROR(args)
12682 +#define DMA_TRACE(args)
12683 +
12684 +/* default dma message level (if input msg_level pointer is null in dma_attach()) */
12685 +static uint dma_msg_level =
12686 + 0;
12687 +
12688 +#define MAXNAMEL 8
12689 +
12690 +/* dma engine software state */
12691 +typedef struct dma_info {
12692 + hnddma_t hnddma; /* exported structure */
12693 + uint *msg_level; /* message level pointer */
12694 + char name[MAXNAMEL]; /* callers name for diag msgs */
12695 +
12696 + void *osh; /* os handle */
12697 + sb_t *sbh; /* sb handle */
12698 +
12699 + bool dma64; /* dma64 enabled */
12700 + bool addrext; /* this dma engine supports DmaExtendedAddrChanges */
12701 +
12702 + dma32regs_t *d32txregs; /* 32 bits dma tx engine registers */
12703 + dma32regs_t *d32rxregs; /* 32 bits dma rx engine registers */
12704 + dma64regs_t *d64txregs; /* 64 bits dma tx engine registers */
12705 + dma64regs_t *d64rxregs; /* 64 bits dma rx engine registers */
12706 +
12707 + uint32 dma64align; /* either 8k or 4k depends on number of dd */
12708 + dma32dd_t *txd32; /* pointer to dma32 tx descriptor ring */
12709 + dma64dd_t *txd64; /* pointer to dma64 tx descriptor ring */
12710 + uint ntxd; /* # tx descriptors tunable */
12711 + uint txin; /* index of next descriptor to reclaim */
12712 + uint txout; /* index of next descriptor to post */
12713 + uint txavail; /* # free tx descriptors */
12714 + void **txp; /* pointer to parallel array of pointers to packets */
12715 + ulong txdpa; /* physical address of descriptor ring */
12716 + uint txdalign; /* #bytes added to alloc'd mem to align txd */
12717 + uint txdalloc; /* #bytes allocated for the ring */
12718 +
12719 + dma32dd_t *rxd32; /* pointer to dma32 rx descriptor ring */
12720 + dma64dd_t *rxd64; /* pointer to dma64 rx descriptor ring */
12721 + uint nrxd; /* # rx descriptors tunable */
12722 + uint rxin; /* index of next descriptor to reclaim */
12723 + uint rxout; /* index of next descriptor to post */
12724 + void **rxp; /* pointer to parallel array of pointers to packets */
12725 + ulong rxdpa; /* physical address of descriptor ring */
12726 + uint rxdalign; /* #bytes added to alloc'd mem to align rxd */
12727 + uint rxdalloc; /* #bytes allocated for the ring */
12728 +
12729 + /* tunables */
12730 + uint rxbufsize; /* rx buffer size in bytes */
12731 + uint nrxpost; /* # rx buffers to keep posted */
12732 + uint rxoffset; /* rxcontrol offset */
12733 + uint ddoffsetlow; /* add to get dma address of descriptor ring, low 32 bits */
12734 + uint ddoffsethigh; /* add to get dma address of descriptor ring, high 32 bits */
12735 + uint dataoffsetlow; /* add to get dma address of data buffer, low 32 bits */
12736 + uint dataoffsethigh; /* add to get dma address of data buffer, high 32 bits */
12737 +} dma_info_t;
12738 +
12739 +#ifdef BCMDMA64
12740 +#define DMA64_ENAB(di) ((di)->dma64)
12741 +#else
12742 +#define DMA64_ENAB(di) (0)
12743 +#endif
12744 +
12745 +/* descriptor bumping macros */
12746 +#define XXD(x, n) ((x) & ((n) - 1))
12747 +#define TXD(x) XXD((x), di->ntxd)
12748 +#define RXD(x) XXD((x), di->nrxd)
12749 +#define NEXTTXD(i) TXD(i + 1)
12750 +#define PREVTXD(i) TXD(i - 1)
12751 +#define NEXTRXD(i) RXD(i + 1)
12752 +#define NTXDACTIVE(h, t) TXD(t - h)
12753 +#define NRXDACTIVE(h, t) RXD(t - h)
12754 +
12755 +/* macros to convert between byte offsets and indexes */
12756 +#define B2I(bytes, type) ((bytes) / sizeof(type))
12757 +#define I2B(index, type) ((index) * sizeof(type))
12758 +
12759 +#define PCI32ADDR_HIGH 0xc0000000 /* address[31:30] */
12760 +#define PCI32ADDR_HIGH_SHIFT 30
12761 +
12762 +
12763 +/* prototypes */
12764 +static bool dma_isaddrext(dma_info_t *di);
12765 +static bool dma_alloc(dma_info_t *di, uint direction);
12766 +
12767 +static bool dma32_alloc(dma_info_t *di, uint direction);
12768 +static void dma32_txreset(dma_info_t *di);
12769 +static void dma32_rxreset(dma_info_t *di);
12770 +static bool dma32_txsuspendedidle(dma_info_t *di);
12771 +static int dma32_txfast(dma_info_t *di, void *p0, uint32 coreflags);
12772 +static void* dma32_getnexttxp(dma_info_t *di, bool forceall);
12773 +static void* dma32_getnextrxp(dma_info_t *di, bool forceall);
12774 +static void dma32_txrotate(di_t *di);
12775 +
12776 +/* prototype or stubs */
12777 +#ifdef BCMDMA64
12778 +static bool dma64_alloc(dma_info_t *di, uint direction);
12779 +static void dma64_txreset(dma_info_t *di);
12780 +static void dma64_rxreset(dma_info_t *di);
12781 +static bool dma64_txsuspendedidle(dma_info_t *di);
12782 +static int dma64_txfast(dma_info_t *di, void *p0, uint32 coreflags);
12783 +static void* dma64_getnexttxp(dma_info_t *di, bool forceall);
12784 +static void* dma64_getnextrxp(dma_info_t *di, bool forceall);
12785 +static void dma64_txrotate(di_t *di);
12786 +#else
12787 +static bool dma64_alloc(dma_info_t *di, uint direction) { return TRUE; }
12788 +static void dma64_txreset(dma_info_t *di) {}
12789 +static void dma64_rxreset(dma_info_t *di) {}
12790 +static bool dma64_txsuspendedidle(dma_info_t *di) { return TRUE;}
12791 +static int dma64_txfast(dma_info_t *di, void *p0, uint32 coreflags) { return 0; }
12792 +static void* dma64_getnexttxp(dma_info_t *di, bool forceall) { return NULL; }
12793 +static void* dma64_getnextrxp(dma_info_t *di, bool forceall) { return NULL; }
12794 +static void dma64_txrotate(di_t *di) { return; }
12795 +#endif
12796 +
12797 +/* old dmaregs struct for compatibility */
12798 +typedef volatile struct {
12799 + /* transmit channel */
12800 + uint32 xmtcontrol; /* enable, et al */
12801 + uint32 xmtaddr; /* descriptor ring base address (4K aligned) */
12802 + uint32 xmtptr; /* last descriptor posted to chip */
12803 + uint32 xmtstatus; /* current active descriptor, et al */
12804 +
12805 + /* receive channel */
12806 + uint32 rcvcontrol; /* enable, et al */
12807 + uint32 rcvaddr; /* descriptor ring base address (4K aligned) */
12808 + uint32 rcvptr; /* last descriptor posted to chip */
12809 + uint32 rcvstatus; /* current active descriptor, et al */
12810 +} dmaregs_t;
12811 +
12812 +typedef struct {
12813 + uint ddoffset;
12814 + uint dataoffset;
12815 +} compat_data;
12816 +
12817 +static compat_data *ugly_hack = NULL;
12818 +
12819 +void*
12820 +dma_attold(void *drv, void *osh, char *name, dmaregs_t *regs, uint ntxd, uint nrxd,
12821 + uint rxbufsize, uint nrxpost, uint rxoffset, uint ddoffset, uint dataoffset, uint *msg_level)
12822 +{
12823 + dma32regs_t *dtx = regs;
12824 + dma32regs_t *drx = dtx + 1;
12825 +
12826 + ugly_hack = kmalloc(sizeof(ugly_hack), GFP_KERNEL);
12827 + ugly_hack->ddoffset = ddoffset;
12828 + ugly_hack->dataoffset = dataoffset;
12829 + dma_attach((osl_t *) osh, name, NULL, dtx, drx, ntxd, nrxd, rxbufsize, nrxpost, rxoffset, msg_level);
12830 + ugly_hack = NULL;
12831 +}
12832 +
12833 +
12834 +void*
12835 +dma_attach(osl_t *osh, char *name, sb_t *sbh, void *dmaregstx, void *dmaregsrx,
12836 + uint ntxd, uint nrxd, uint rxbufsize, uint nrxpost, uint rxoffset, uint *msg_level)
12837 +{
12838 + dma_info_t *di;
12839 + uint size;
12840 +
12841 + /* allocate private info structure */
12842 + if ((di = MALLOC(osh, sizeof (dma_info_t))) == NULL) {
12843 + return (NULL);
12844 + }
12845 + bzero((char*)di, sizeof (dma_info_t));
12846 +
12847 + di->msg_level = msg_level ? msg_level : &dma_msg_level;
12848 +
12849 + if (sbh != NULL)
12850 + di->dma64 = ((sb_coreflagshi(sbh, 0, 0) & SBTMH_DMA64) == SBTMH_DMA64);
12851 +
12852 +#ifndef BCMDMA64
12853 + if (di->dma64) {
12854 + DMA_ERROR(("dma_attach: driver doesn't have the capability to support 64 bits DMA\n"));
12855 + goto fail;
12856 + }
12857 +#endif
12858 +
12859 + /* check arguments */
12860 + ASSERT(ISPOWEROF2(ntxd));
12861 + ASSERT(ISPOWEROF2(nrxd));
12862 + if (nrxd == 0)
12863 + ASSERT(dmaregsrx == NULL);
12864 + if (ntxd == 0)
12865 + ASSERT(dmaregstx == NULL);
12866 +
12867 +
12868 + /* init dma reg pointer */
12869 + if (di->dma64) {
12870 + ASSERT(ntxd <= D64MAXDD);
12871 + ASSERT(nrxd <= D64MAXDD);
12872 + di->d64txregs = (dma64regs_t *)dmaregstx;
12873 + di->d64rxregs = (dma64regs_t *)dmaregsrx;
12874 +
12875 + di->dma64align = D64RINGALIGN;
12876 + if ((ntxd < D64MAXDD / 2) && (nrxd < D64MAXDD / 2)) {
12877 + /* for smaller dd table, HW relax the alignment requirement */
12878 + di->dma64align = D64RINGALIGN / 2;
12879 + }
12880 + } else {
12881 + ASSERT(ntxd <= D32MAXDD);
12882 + ASSERT(nrxd <= D32MAXDD);
12883 + di->d32txregs = (dma32regs_t *)dmaregstx;
12884 + di->d32rxregs = (dma32regs_t *)dmaregsrx;
12885 + }
12886 +
12887 +
12888 + /* make a private copy of our callers name */
12889 + strncpy(di->name, name, MAXNAMEL);
12890 + di->name[MAXNAMEL-1] = '\0';
12891 +
12892 + di->osh = osh;
12893 + di->sbh = sbh;
12894 +
12895 + /* save tunables */
12896 + di->ntxd = ntxd;
12897 + di->nrxd = nrxd;
12898 + di->rxbufsize = rxbufsize;
12899 + di->nrxpost = nrxpost;
12900 + di->rxoffset = rxoffset;
12901 +
12902 + /*
12903 + * figure out the DMA physical address offset for dd and data
12904 + * for old chips w/o sb, use zero
12905 + * for new chips w sb,
12906 + * PCI/PCIE: they map silicon backplace address to zero based memory, need offset
12907 + * Other bus: use zero
12908 + * SB_BUS BIGENDIAN kludge: use sdram swapped region for data buffer, not descriptor
12909 + */
12910 + di->ddoffsetlow = 0;
12911 + di->dataoffsetlow = 0;
12912 + if (ugly_hack != NULL) {
12913 + di->ddoffsetlow = ugly_hack->ddoffset;
12914 + di->dataoffsetlow = ugly_hack->dataoffset;
12915 + di->ddoffsethigh = 0;
12916 + di->dataoffsethigh = 0;
12917 + } else if (sbh != NULL) {
12918 + if (sbh->bustype == PCI_BUS) { /* for pci bus, add offset */
12919 + if ((sbh->buscoretype == SB_PCIE) && di->dma64){
12920 + di->ddoffsetlow = 0;
12921 + di->ddoffsethigh = SB_PCIE_DMA_H32;
12922 + } else {
12923 + di->ddoffsetlow = SB_PCI_DMA;
12924 + di->ddoffsethigh = 0;
12925 + }
12926 + di->dataoffsetlow = di->ddoffsetlow;
12927 + di->dataoffsethigh = di->ddoffsethigh;
12928 + }
12929 +#if defined(__mips__) && defined(IL_BIGENDIAN)
12930 + /* use sdram swapped region for data buffers but not dma descriptors */
12931 + di->dataoffsetlow = di->dataoffsetlow + SB_SDRAM_SWAPPED;
12932 +#endif
12933 + }
12934 +
12935 + di->addrext = ((ugly_hack == NULL) ? dma_isaddrext(di) : 0);
12936 +
12937 + DMA_TRACE(("%s: dma_attach: osh %p ntxd %d nrxd %d rxbufsize %d nrxpost %d rxoffset %d ddoffset 0x%x dataoffset 0x%x\n",
12938 + name, osh, ntxd, nrxd, rxbufsize, nrxpost, rxoffset, di->ddoffsetlow, di->dataoffsetlow));
12939 +
12940 + /* allocate tx packet pointer vector */
12941 + if (ntxd) {
12942 + size = ntxd * sizeof (void*);
12943 + if ((di->txp = MALLOC(osh, size)) == NULL) {
12944 + DMA_ERROR(("%s: dma_attach: out of tx memory, malloced %d bytes\n", di->name, MALLOCED(osh)));
12945 + goto fail;
12946 + }
12947 + bzero((char*)di->txp, size);
12948 + }
12949 +
12950 + /* allocate rx packet pointer vector */
12951 + if (nrxd) {
12952 + size = nrxd * sizeof (void*);
12953 + if ((di->rxp = MALLOC(osh, size)) == NULL) {
12954 + DMA_ERROR(("%s: dma_attach: out of rx memory, malloced %d bytes\n", di->name, MALLOCED(osh)));
12955 + goto fail;
12956 + }
12957 + bzero((char*)di->rxp, size);
12958 + }
12959 +
12960 + /* allocate transmit descriptor ring, only need ntxd descriptors but it must be aligned */
12961 + if (ntxd) {
12962 + if (!dma_alloc(di, DMA_TX))
12963 + goto fail;
12964 + }
12965 +
12966 + /* allocate receive descriptor ring, only need nrxd descriptors but it must be aligned */
12967 + if (nrxd) {
12968 + if (!dma_alloc(di, DMA_RX))
12969 + goto fail;
12970 + }
12971 +
12972 + if ((di->ddoffsetlow == SB_PCI_DMA) && (di->txdpa > SB_PCI_DMA_SZ) && !di->addrext) {
12973 + DMA_ERROR(("%s: dma_attach: txdpa 0x%lx: addrext not supported\n", di->name, di->txdpa));
12974 + goto fail;
12975 + }
12976 + if ((di->ddoffsetlow == SB_PCI_DMA) && (di->rxdpa > SB_PCI_DMA_SZ) && !di->addrext) {
12977 + DMA_ERROR(("%s: dma_attach: rxdpa 0x%lx: addrext not supported\n", di->name, di->rxdpa));
12978 + goto fail;
12979 + }
12980 +
12981 + return ((void*)di);
12982 +
12983 +fail:
12984 + dma_detach((void*)di);
12985 + return (NULL);
12986 +}
12987 +
12988 +static bool
12989 +dma_alloc(dma_info_t *di, uint direction)
12990 +{
12991 + if (DMA64_ENAB(di)) {
12992 + return dma64_alloc(di, direction);
12993 + } else {
12994 + return dma32_alloc(di, direction);
12995 + }
12996 +}
12997 +
12998 +/* may be called with core in reset */
12999 +void
13000 +dma_detach(dma_info_t *di)
13001 +{
13002 + if (di == NULL)
13003 + return;
13004 +
13005 + DMA_TRACE(("%s: dma_detach\n", di->name));
13006 +
13007 + /* shouldn't be here if descriptors are unreclaimed */
13008 + ASSERT(di->txin == di->txout);
13009 + ASSERT(di->rxin == di->rxout);
13010 +
13011 + /* free dma descriptor rings */
13012 + if (di->txd32)
13013 + DMA_FREE_CONSISTENT(di->osh, ((int8*)di->txd32 - di->txdalign), di->txdalloc, (di->txdpa - di->txdalign));
13014 + if (di->rxd32)
13015 + DMA_FREE_CONSISTENT(di->osh, ((int8*)di->rxd32 - di->rxdalign), di->rxdalloc, (di->rxdpa - di->rxdalign));
13016 +
13017 + /* free packet pointer vectors */
13018 + if (di->txp)
13019 + MFREE(di->osh, (void*)di->txp, (di->ntxd * sizeof (void*)));
13020 + if (di->rxp)
13021 + MFREE(di->osh, (void*)di->rxp, (di->nrxd * sizeof (void*)));
13022 +
13023 + /* free our private info structure */
13024 + MFREE(di->osh, (void*)di, sizeof (dma_info_t));
13025 +}
13026 +
13027 +/* return TRUE if this dma engine supports DmaExtendedAddrChanges, otherwise FALSE */
13028 +static bool
13029 +dma_isaddrext(dma_info_t *di)
13030 +{
13031 + uint32 w;
13032 +
13033 + if (DMA64_ENAB(di)) {
13034 + OR_REG(&di->d64txregs->control, D64_XC_AE);
13035 + w = R_REG(&di->d32txregs->control);
13036 + AND_REG(&di->d32txregs->control, ~D64_XC_AE);
13037 + return ((w & XC_AE) == D64_XC_AE);
13038 + } else {
13039 + OR_REG(&di->d32txregs->control, XC_AE);
13040 + w = R_REG(&di->d32txregs->control);
13041 + AND_REG(&di->d32txregs->control, ~XC_AE);
13042 + return ((w & XC_AE) == XC_AE);
13043 + }
13044 +}
13045 +
13046 +void
13047 +dma_txreset(dma_info_t *di)
13048 +{
13049 + DMA_TRACE(("%s: dma_txreset\n", di->name));
13050 +
13051 + if (DMA64_ENAB(di))
13052 + dma64_txreset(di);
13053 + else
13054 + dma32_txreset(di);
13055 +}
13056 +
13057 +void
13058 +dma_rxreset(dma_info_t *di)
13059 +{
13060 + DMA_TRACE(("%s: dma_rxreset\n", di->name));
13061 +
13062 + if (DMA64_ENAB(di))
13063 + dma64_rxreset(di);
13064 + else
13065 + dma32_rxreset(di);
13066 +}
13067 +
13068 +/* initialize descriptor table base address */
13069 +static void
13070 +dma_ddtable_init(dma_info_t *di, uint direction, ulong pa)
13071 +{
13072 + if (DMA64_ENAB(di)) {
13073 + if (direction == DMA_TX) {
13074 + W_REG(&di->d64txregs->addrlow, pa + di->ddoffsetlow);
13075 + W_REG(&di->d64txregs->addrhigh, di->ddoffsethigh);
13076 + } else {
13077 + W_REG(&di->d64rxregs->addrlow, pa + di->ddoffsetlow);
13078 + W_REG(&di->d64rxregs->addrhigh, di->ddoffsethigh);
13079 + }
13080 + } else {
13081 + uint32 offset = di->ddoffsetlow;
13082 + if ((offset != SB_PCI_DMA) || !(pa & PCI32ADDR_HIGH)) {
13083 + if (direction == DMA_TX)
13084 + W_REG(&di->d32txregs->addr, (pa + offset));
13085 + else
13086 + W_REG(&di->d32rxregs->addr, (pa + offset));
13087 + } else {
13088 + /* dma32 address extension */
13089 + uint32 ae;
13090 + ASSERT(di->addrext);
13091 + ae = (pa & PCI32ADDR_HIGH) >> PCI32ADDR_HIGH_SHIFT;
13092 +
13093 + if (direction == DMA_TX) {
13094 + W_REG(&di->d32txregs->addr, ((pa & ~PCI32ADDR_HIGH) + offset));
13095 + SET_REG(&di->d32txregs->control, XC_AE, (ae << XC_AE_SHIFT));
13096 + } else {
13097 + W_REG(&di->d32rxregs->addr, ((pa & ~PCI32ADDR_HIGH) + offset));
13098 + SET_REG(&di->d32rxregs->control, RC_AE, (ae << RC_AE_SHIFT));
13099 + }
13100 + }
13101 + }
13102 +}
13103 +
13104 +/* init the tx or rx descriptor */
13105 +static INLINE void
13106 +dma32_dd_upd(dma_info_t *di, dma32dd_t *ddring, ulong pa, uint outidx, uint32 *ctrl)
13107 +{
13108 + uint offset = di->dataoffsetlow;
13109 +
13110 + if ((offset != SB_PCI_DMA) || !(pa & PCI32ADDR_HIGH)) {
13111 + W_SM(&ddring[outidx].addr, BUS_SWAP32(pa + offset));
13112 + W_SM(&ddring[outidx].ctrl, BUS_SWAP32(*ctrl));
13113 + } else {
13114 + /* address extension */
13115 + uint32 ae;
13116 + ASSERT(di->addrext);
13117 + ae = (pa & PCI32ADDR_HIGH) >> PCI32ADDR_HIGH_SHIFT;
13118 +
13119 + *ctrl |= (ae << CTRL_AE_SHIFT);
13120 + W_SM(&ddring[outidx].addr, BUS_SWAP32((pa & ~PCI32ADDR_HIGH) + offset));
13121 + W_SM(&ddring[outidx].ctrl, BUS_SWAP32(*ctrl));
13122 + }
13123 +}
13124 +
13125 +/* init the tx or rx descriptor */
13126 +static INLINE void
13127 +dma64_dd_upd(dma_info_t *di, dma64dd_t *ddring, ulong pa, uint outidx, uint32 *flags, uint32 bufcount)
13128 +{
13129 + uint32 bufaddr_low = pa + di->dataoffsetlow;
13130 + uint32 bufaddr_high = 0 + di->dataoffsethigh;
13131 +
13132 + uint32 ctrl2 = bufcount & D64_CTRL2_BC_MASK;
13133 +
13134 + W_SM(&ddring[outidx].addrlow, BUS_SWAP32(bufaddr_low));
13135 + W_SM(&ddring[outidx].addrhigh, BUS_SWAP32(bufaddr_high));
13136 + W_SM(&ddring[outidx].ctrl1, BUS_SWAP32(*flags));
13137 + W_SM(&ddring[outidx].ctrl2, BUS_SWAP32(ctrl2));
13138 +}
13139 +
13140 +void
13141 +dma_txinit(dma_info_t *di)
13142 +{
13143 + DMA_TRACE(("%s: dma_txinit\n", di->name));
13144 +
13145 + di->txin = di->txout = 0;
13146 + di->txavail = di->ntxd - 1;
13147 +
13148 + /* clear tx descriptor ring */
13149 + if (DMA64_ENAB(di)) {
13150 + BZERO_SM((void*)di->txd64, (di->ntxd * sizeof (dma64dd_t)));
13151 + W_REG(&di->d64txregs->control, XC_XE);
13152 + dma_ddtable_init(di, DMA_TX, di->txdpa);
13153 + } else {
13154 + BZERO_SM((void*)di->txd32, (di->ntxd * sizeof (dma32dd_t)));
13155 + W_REG(&di->d32txregs->control, XC_XE);
13156 + dma_ddtable_init(di, DMA_TX, di->txdpa);
13157 + }
13158 +}
13159 +
13160 +bool
13161 +dma_txenabled(dma_info_t *di)
13162 +{
13163 + uint32 xc;
13164 +
13165 + /* If the chip is dead, it is not enabled :-) */
13166 + if (DMA64_ENAB(di)) {
13167 + xc = R_REG(&di->d64txregs->control);
13168 + return ((xc != 0xffffffff) && (xc & D64_XC_XE));
13169 + } else {
13170 + xc = R_REG(&di->d32txregs->control);
13171 + return ((xc != 0xffffffff) && (xc & XC_XE));
13172 + }
13173 +}
13174 +
13175 +void
13176 +dma_txsuspend(dma_info_t *di)
13177 +{
13178 + DMA_TRACE(("%s: dma_txsuspend\n", di->name));
13179 + if (DMA64_ENAB(di))
13180 + OR_REG(&di->d64txregs->control, D64_XC_SE);
13181 + else
13182 + OR_REG(&di->d32txregs->control, XC_SE);
13183 +}
13184 +
13185 +void
13186 +dma_txresume(dma_info_t *di)
13187 +{
13188 + DMA_TRACE(("%s: dma_txresume\n", di->name));
13189 + if (DMA64_ENAB(di))
13190 + AND_REG(&di->d64txregs->control, ~D64_XC_SE);
13191 + else
13192 + AND_REG(&di->d32txregs->control, ~XC_SE);
13193 +}
13194 +
13195 +bool
13196 +dma_txsuspendedidle(dma_info_t *di)
13197 +{
13198 + if (DMA64_ENAB(di))
13199 + return dma64_txsuspendedidle(di);
13200 + else
13201 + return dma32_txsuspendedidle(di);
13202 +}
13203 +
13204 +bool
13205 +dma_txsuspended(dma_info_t *di)
13206 +{
13207 + if (DMA64_ENAB(di))
13208 + return ((R_REG(&di->d64txregs->control) & D64_XC_SE) == D64_XC_SE);
13209 + else
13210 + return ((R_REG(&di->d32txregs->control) & XC_SE) == XC_SE);
13211 +}
13212 +
13213 +bool
13214 +dma_txstopped(dma_info_t *di)
13215 +{
13216 + if (DMA64_ENAB(di))
13217 + return ((R_REG(&di->d64txregs->status0) & D64_XS0_XS_MASK) == D64_XS0_XS_STOPPED);
13218 + else
13219 + return ((R_REG(&di->d32txregs->status) & XS_XS_MASK) == XS_XS_STOPPED);
13220 +}
13221 +
13222 +bool
13223 +dma_rxstopped(dma_info_t *di)
13224 +{
13225 + if (DMA64_ENAB(di))
13226 + return ((R_REG(&di->d64rxregs->status0) & D64_RS0_RS_MASK) == D64_RS0_RS_STOPPED);
13227 + else
13228 + return ((R_REG(&di->d32rxregs->status) & RS_RS_MASK) == RS_RS_STOPPED);
13229 +}
13230 +
13231 +void
13232 +dma_fifoloopbackenable(dma_info_t *di)
13233 +{
13234 + DMA_TRACE(("%s: dma_fifoloopbackenable\n", di->name));
13235 + if (DMA64_ENAB(di))
13236 + OR_REG(&di->d64txregs->control, D64_XC_LE);
13237 + else
13238 + OR_REG(&di->d32txregs->control, XC_LE);
13239 +}
13240 +
13241 +void
13242 +dma_rxinit(dma_info_t *di)
13243 +{
13244 + DMA_TRACE(("%s: dma_rxinit\n", di->name));
13245 +
13246 + di->rxin = di->rxout = 0;
13247 +
13248 + /* clear rx descriptor ring */
13249 + if (DMA64_ENAB(di)) {
13250 + BZERO_SM((void*)di->rxd64, (di->nrxd * sizeof (dma64dd_t)));
13251 + dma_rxenable(di);
13252 + dma_ddtable_init(di, DMA_RX, di->rxdpa);
13253 + } else {
13254 + BZERO_SM((void*)di->rxd32, (di->nrxd * sizeof (dma32dd_t)));
13255 + dma_rxenable(di);
13256 + dma_ddtable_init(di, DMA_RX, di->rxdpa);
13257 + }
13258 +}
13259 +
13260 +void
13261 +dma_rxenable(dma_info_t *di)
13262 +{
13263 + DMA_TRACE(("%s: dma_rxenable\n", di->name));
13264 + if (DMA64_ENAB(di))
13265 + W_REG(&di->d64rxregs->control, ((di->rxoffset << D64_RC_RO_SHIFT) | D64_RC_RE));
13266 + else
13267 + W_REG(&di->d32rxregs->control, ((di->rxoffset << RC_RO_SHIFT) | RC_RE));
13268 +}
13269 +
13270 +bool
13271 +dma_rxenabled(dma_info_t *di)
13272 +{
13273 + uint32 rc;
13274 +
13275 + if (DMA64_ENAB(di)) {
13276 + rc = R_REG(&di->d64rxregs->control);
13277 + return ((rc != 0xffffffff) && (rc & D64_RC_RE));
13278 + } else {
13279 + rc = R_REG(&di->d32rxregs->control);
13280 + return ((rc != 0xffffffff) && (rc & RC_RE));
13281 + }
13282 +}
13283 +
13284 +
13285 +/* !! tx entry routine */
13286 +int
13287 +dma_txfast(dma_info_t *di, void *p0, uint32 coreflags)
13288 +{
13289 + if (DMA64_ENAB(di)) {
13290 + return dma64_txfast(di, p0, coreflags);
13291 + } else {
13292 + return dma32_txfast(di, p0, coreflags);
13293 + }
13294 +}
13295 +
13296 +/* !! rx entry routine, returns a pointer to the next frame received, or NULL if there are no more */
13297 +void*
13298 +dma_rx(dma_info_t *di)
13299 +{
13300 + void *p;
13301 + uint len;
13302 + int skiplen = 0;
13303 +
13304 + while ((p = dma_getnextrxp(di, FALSE))) {
13305 + /* skip giant packets which span multiple rx descriptors */
13306 + if (skiplen > 0) {
13307 + skiplen -= di->rxbufsize;
13308 + if (skiplen < 0)
13309 + skiplen = 0;
13310 + PKTFREE(di->osh, p, FALSE);
13311 + continue;
13312 + }
13313 +
13314 + len = ltoh16(*(uint16*)(PKTDATA(di->osh, p)));
13315 + DMA_TRACE(("%s: dma_rx len %d\n", di->name, len));
13316 +
13317 + /* bad frame length check */
13318 + if (len > (di->rxbufsize - di->rxoffset)) {
13319 + DMA_ERROR(("%s: dma_rx: bad frame length (%d)\n", di->name, len));
13320 + if (len > 0)
13321 + skiplen = len - (di->rxbufsize - di->rxoffset);
13322 + PKTFREE(di->osh, p, FALSE);
13323 + di->hnddma.rxgiants++;
13324 + continue;
13325 + }
13326 +
13327 + /* set actual length */
13328 + PKTSETLEN(di->osh, p, (di->rxoffset + len));
13329 +
13330 + break;
13331 + }
13332 +
13333 + return (p);
13334 +}
13335 +
13336 +/* post receive buffers */
13337 +void
13338 +dma_rxfill(dma_info_t *di)
13339 +{
13340 + void *p;
13341 + uint rxin, rxout;
13342 + uint32 ctrl;
13343 + uint n;
13344 + uint i;
13345 + uint32 pa;
13346 + uint rxbufsize;
13347 +
13348 + /*
13349 + * Determine how many receive buffers we're lacking
13350 + * from the full complement, allocate, initialize,
13351 + * and post them, then update the chip rx lastdscr.
13352 + */
13353 +
13354 + rxin = di->rxin;
13355 + rxout = di->rxout;
13356 + rxbufsize = di->rxbufsize;
13357 +
13358 + n = di->nrxpost - NRXDACTIVE(rxin, rxout);
13359 +
13360 + DMA_TRACE(("%s: dma_rxfill: post %d\n", di->name, n));
13361 +
13362 + for (i = 0; i < n; i++) {
13363 + if ((p = PKTGET(di->osh, rxbufsize, FALSE)) == NULL) {
13364 + DMA_ERROR(("%s: dma_rxfill: out of rxbufs\n", di->name));
13365 + di->hnddma.rxnobuf++;
13366 + break;
13367 + }
13368 +
13369 + /* Do a cached write instead of uncached write since DMA_MAP
13370 + * will flush the cache. */
13371 + *(uint32*)(PKTDATA(di->osh, p)) = 0;
13372 +
13373 + pa = (uint32) DMA_MAP(di->osh, PKTDATA(di->osh, p), rxbufsize, DMA_RX, p);
13374 + ASSERT(ISALIGNED(pa, 4));
13375 +
13376 + /* save the free packet pointer */
13377 + ASSERT(di->rxp[rxout] == NULL);
13378 + di->rxp[rxout] = p;
13379 +
13380 + if (DMA64_ENAB(di)) {
13381 + /* prep the descriptor control value */
13382 + if (rxout == (di->nrxd - 1))
13383 + ctrl = CTRL_EOT;
13384 +
13385 + dma64_dd_upd(di, di->rxd64, pa, rxout, &ctrl, rxbufsize);
13386 + } else {
13387 + /* prep the descriptor control value */
13388 + ctrl = rxbufsize;
13389 + if (rxout == (di->nrxd - 1))
13390 + ctrl |= CTRL_EOT;
13391 + dma32_dd_upd(di, di->rxd32, pa, rxout, &ctrl);
13392 + }
13393 +
13394 + rxout = NEXTRXD(rxout);
13395 + }
13396 +
13397 + di->rxout = rxout;
13398 +
13399 + /* update the chip lastdscr pointer */
13400 + if (DMA64_ENAB(di)) {
13401 + W_REG(&di->d64rxregs->ptr, I2B(rxout, dma64dd_t));
13402 + } else {
13403 + W_REG(&di->d32rxregs->ptr, I2B(rxout, dma32dd_t));
13404 + }
13405 +}
13406 +
13407 +void
13408 +dma_txreclaim(dma_info_t *di, bool forceall)
13409 +{
13410 + void *p;
13411 +
13412 + DMA_TRACE(("%s: dma_txreclaim %s\n", di->name, forceall ? "all" : ""));
13413 +
13414 + while ((p = dma_getnexttxp(di, forceall)))
13415 + PKTFREE(di->osh, p, TRUE);
13416 +}
13417 +
13418 +/*
13419 + * Reclaim next completed txd (txds if using chained buffers) and
13420 + * return associated packet.
13421 + * If 'force' is true, reclaim txd(s) and return associated packet
13422 + * regardless of the value of the hardware "curr" pointer.
13423 + */
13424 +void*
13425 +dma_getnexttxp(dma_info_t *di, bool forceall)
13426 +{
13427 + if (DMA64_ENAB(di)) {
13428 + return dma64_getnexttxp(di, forceall);
13429 + } else {
13430 + return dma32_getnexttxp(di, forceall);
13431 + }
13432 +}
13433 +
13434 +/* like getnexttxp but no reclaim */
13435 +void*
13436 +dma_peeknexttxp(dma_info_t *di)
13437 +{
13438 + uint end, i;
13439 +
13440 + if (DMA64_ENAB(di)) {
13441 + end = B2I(R_REG(&di->d64txregs->status0) & D64_XS0_CD_MASK, dma64dd_t);
13442 + } else {
13443 + end = B2I(R_REG(&di->d32txregs->status) & XS_CD_MASK, dma32dd_t);
13444 + }
13445 +
13446 + for (i = di->txin; i != end; i = NEXTTXD(i))
13447 + if (di->txp[i])
13448 + return (di->txp[i]);
13449 +
13450 + return (NULL);
13451 +}
13452 +
13453 +/*
13454 + * Rotate all active tx dma ring entries "forward" by (ActiveDescriptor - txin).
13455 + */
13456 +void
13457 +dma_txrotate(di_t *di)
13458 +{
13459 + if (DMA64_ENAB(di)) {
13460 + dma64_txrotate(di);
13461 + } else {
13462 + dma32_txrotate(di);
13463 + }
13464 +}
13465 +
13466 +void
13467 +dma_rxreclaim(dma_info_t *di)
13468 +{
13469 + void *p;
13470 +
13471 + DMA_TRACE(("%s: dma_rxreclaim\n", di->name));
13472 +
13473 + while ((p = dma_getnextrxp(di, TRUE)))
13474 + PKTFREE(di->osh, p, FALSE);
13475 +}
13476 +
13477 +void *
13478 +dma_getnextrxp(dma_info_t *di, bool forceall)
13479 +{
13480 + if (DMA64_ENAB(di)) {
13481 + return dma64_getnextrxp(di, forceall);
13482 + } else {
13483 + return dma32_getnextrxp(di, forceall);
13484 + }
13485 +}
13486 +
13487 +uintptr
13488 +dma_getvar(dma_info_t *di, char *name)
13489 +{
13490 + if (!strcmp(name, "&txavail"))
13491 + return ((uintptr) &di->txavail);
13492 + else {
13493 + ASSERT(0);
13494 + }
13495 + return (0);
13496 +}
13497 +
13498 +void
13499 +dma_txblock(dma_info_t *di)
13500 +{
13501 + di->txavail = 0;
13502 +}
13503 +
13504 +void
13505 +dma_txunblock(dma_info_t *di)
13506 +{
13507 + di->txavail = di->ntxd - NTXDACTIVE(di->txin, di->txout) - 1;
13508 +}
13509 +
13510 +uint
13511 +dma_txactive(dma_info_t *di)
13512 +{
13513 + return (NTXDACTIVE(di->txin, di->txout));
13514 +}
13515 +
13516 +void
13517 +dma_rxpiomode(dma32regs_t *regs)
13518 +{
13519 + W_REG(&regs->control, RC_FM);
13520 +}
13521 +
13522 +void
13523 +dma_txpioloopback(dma32regs_t *regs)
13524 +{
13525 + OR_REG(&regs->control, XC_LE);
13526 +}
13527 +
13528 +
13529 +
13530 +
13531 +/*** 32 bits DMA non-inline functions ***/
13532 +static bool
13533 +dma32_alloc(dma_info_t *di, uint direction)
13534 +{
13535 + uint size;
13536 + uint ddlen;
13537 + void *va;
13538 +
13539 + ddlen = sizeof (dma32dd_t);
13540 +
13541 + size = (direction == DMA_TX) ? (di->ntxd * ddlen) : (di->nrxd * ddlen);
13542 +
13543 + if (!ISALIGNED(DMA_CONSISTENT_ALIGN, D32RINGALIGN))
13544 + size += D32RINGALIGN;
13545 +
13546 +
13547 + if (direction == DMA_TX) {
13548 + if ((va = DMA_ALLOC_CONSISTENT(di->osh, size, &di->txdpa)) == NULL) {
13549 + DMA_ERROR(("%s: dma_attach: DMA_ALLOC_CONSISTENT(ntxd) failed\n", di->name));
13550 + return FALSE;
13551 + }
13552 +
13553 + di->txd32 = (dma32dd_t*) ROUNDUP((uintptr)va, D32RINGALIGN);
13554 + di->txdalign = (uint)((int8*)di->txd32 - (int8*)va);
13555 + di->txdpa += di->txdalign;
13556 + di->txdalloc = size;
13557 + ASSERT(ISALIGNED((uintptr)di->txd32, D32RINGALIGN));
13558 + } else {
13559 + if ((va = DMA_ALLOC_CONSISTENT(di->osh, size, &di->rxdpa)) == NULL) {
13560 + DMA_ERROR(("%s: dma_attach: DMA_ALLOC_CONSISTENT(nrxd) failed\n", di->name));
13561 + return FALSE;
13562 + }
13563 + di->rxd32 = (dma32dd_t*) ROUNDUP((uintptr)va, D32RINGALIGN);
13564 + di->rxdalign = (uint)((int8*)di->rxd32 - (int8*)va);
13565 + di->rxdpa += di->rxdalign;
13566 + di->rxdalloc = size;
13567 + ASSERT(ISALIGNED((uintptr)di->rxd32, D32RINGALIGN));
13568 + }
13569 +
13570 + return TRUE;
13571 +}
13572 +
13573 +static void
13574 +dma32_txreset(dma_info_t *di)
13575 +{
13576 + uint32 status;
13577 +
13578 + /* suspend tx DMA first */
13579 + W_REG(&di->d32txregs->control, XC_SE);
13580 + SPINWAIT((status = (R_REG(&di->d32txregs->status) & XS_XS_MASK)) != XS_XS_DISABLED &&
13581 + status != XS_XS_IDLE &&
13582 + status != XS_XS_STOPPED,
13583 + 10000);
13584 +
13585 + W_REG(&di->d32txregs->control, 0);
13586 + SPINWAIT((status = (R_REG(&di->d32txregs->status) & XS_XS_MASK)) != XS_XS_DISABLED,
13587 + 10000);
13588 +
13589 + if (status != XS_XS_DISABLED) {
13590 + DMA_ERROR(("%s: dma_txreset: dma cannot be stopped\n", di->name));
13591 + }
13592 +
13593 + /* wait for the last transaction to complete */
13594 + OSL_DELAY(300);
13595 +}
13596 +
13597 +static void
13598 +dma32_rxreset(dma_info_t *di)
13599 +{
13600 + uint32 status;
13601 +
13602 + W_REG(&di->d32rxregs->control, 0);
13603 + SPINWAIT((status = (R_REG(&di->d32rxregs->status) & RS_RS_MASK)) != RS_RS_DISABLED,
13604 + 10000);
13605 +
13606 + if (status != RS_RS_DISABLED) {
13607 + DMA_ERROR(("%s: dma_rxreset: dma cannot be stopped\n", di->name));
13608 + }
13609 +}
13610 +
13611 +static bool
13612 +dma32_txsuspendedidle(dma_info_t *di)
13613 +{
13614 + if (!(R_REG(&di->d32txregs->control) & XC_SE))
13615 + return 0;
13616 +
13617 + if ((R_REG(&di->d32txregs->status) & XS_XS_MASK) != XS_XS_IDLE)
13618 + return 0;
13619 +
13620 + OSL_DELAY(2);
13621 + return ((R_REG(&di->d32txregs->status) & XS_XS_MASK) == XS_XS_IDLE);
13622 +}
13623 +
13624 +/*
13625 + * supports full 32bit dma engine buffer addressing so
13626 + * dma buffers can cross 4 Kbyte page boundaries.
13627 + */
13628 +static int
13629 +dma32_txfast(dma_info_t *di, void *p0, uint32 coreflags)
13630 +{
13631 + void *p, *next;
13632 + uchar *data;
13633 + uint len;
13634 + uint txout;
13635 + uint32 ctrl;
13636 + uint32 pa;
13637 +
13638 + DMA_TRACE(("%s: dma_txfast\n", di->name));
13639 +
13640 + txout = di->txout;
13641 + ctrl = 0;
13642 +
13643 + /*
13644 + * Walk the chain of packet buffers
13645 + * allocating and initializing transmit descriptor entries.
13646 + */
13647 + for (p = p0; p; p = next) {
13648 + data = PKTDATA(di->osh, p);
13649 + len = PKTLEN(di->osh, p);
13650 + next = PKTNEXT(di->osh, p);
13651 +
13652 + /* return nonzero if out of tx descriptors */
13653 + if (NEXTTXD(txout) == di->txin)
13654 + goto outoftxd;
13655 +
13656 + if (len == 0)
13657 + continue;
13658 +
13659 + /* get physical address of buffer start */
13660 + pa = (uint32) DMA_MAP(di->osh, data, len, DMA_TX, p);
13661 +
13662 + /* build the descriptor control value */
13663 + ctrl = len & CTRL_BC_MASK;
13664 +
13665 + ctrl |= coreflags;
13666 +
13667 + if (p == p0)
13668 + ctrl |= CTRL_SOF;
13669 + if (next == NULL)
13670 + ctrl |= (CTRL_IOC | CTRL_EOF);
13671 + if (txout == (di->ntxd - 1))
13672 + ctrl |= CTRL_EOT;
13673 +
13674 + if (DMA64_ENAB(di)) {
13675 + dma64_dd_upd(di, di->txd64, pa, txout, &ctrl, len);
13676 + } else {
13677 + dma32_dd_upd(di, di->txd32, pa, txout, &ctrl);
13678 + }
13679 +
13680 + ASSERT(di->txp[txout] == NULL);
13681 +
13682 + txout = NEXTTXD(txout);
13683 + }
13684 +
13685 + /* if last txd eof not set, fix it */
13686 + if (!(ctrl & CTRL_EOF))
13687 + W_SM(&di->txd32[PREVTXD(txout)].ctrl, BUS_SWAP32(ctrl | CTRL_IOC | CTRL_EOF));
13688 +
13689 + /* save the packet */
13690 + di->txp[PREVTXD(txout)] = p0;
13691 +
13692 + /* bump the tx descriptor index */
13693 + di->txout = txout;
13694 +
13695 + /* kick the chip */
13696 + if (DMA64_ENAB(di)) {
13697 + W_REG(&di->d64txregs->ptr, I2B(txout, dma64dd_t));
13698 + } else {
13699 + W_REG(&di->d32txregs->ptr, I2B(txout, dma32dd_t));
13700 + }
13701 +
13702 + /* tx flow control */
13703 + di->txavail = di->ntxd - NTXDACTIVE(di->txin, di->txout) - 1;
13704 +
13705 + return (0);
13706 +
13707 + outoftxd:
13708 + DMA_ERROR(("%s: dma_txfast: out of txds\n", di->name));
13709 + PKTFREE(di->osh, p0, TRUE);
13710 + di->txavail = 0;
13711 + di->hnddma.txnobuf++;
13712 + return (-1);
13713 +}
13714 +
13715 +static void*
13716 +dma32_getnexttxp(dma_info_t *di, bool forceall)
13717 +{
13718 + uint start, end, i;
13719 + void *txp;
13720 +
13721 + DMA_TRACE(("%s: dma_getnexttxp %s\n", di->name, forceall ? "all" : ""));
13722 +
13723 + txp = NULL;
13724 +
13725 + start = di->txin;
13726 + if (forceall)
13727 + end = di->txout;
13728 + else
13729 + end = B2I(R_REG(&di->d32txregs->status) & XS_CD_MASK, dma32dd_t);
13730 +
13731 + if ((start == 0) && (end > di->txout))
13732 + goto bogus;
13733 +
13734 + for (i = start; i != end && !txp; i = NEXTTXD(i)) {
13735 + DMA_UNMAP(di->osh, (BUS_SWAP32(R_SM(&di->txd32[i].addr)) - di->dataoffsetlow),
13736 + (BUS_SWAP32(R_SM(&di->txd32[i].ctrl)) & CTRL_BC_MASK), DMA_TX, di->txp[i]);
13737 +
13738 + W_SM(&di->txd32[i].addr, 0xdeadbeef);
13739 + txp = di->txp[i];
13740 + di->txp[i] = NULL;
13741 + }
13742 +
13743 + di->txin = i;
13744 +
13745 + /* tx flow control */
13746 + di->txavail = di->ntxd - NTXDACTIVE(di->txin, di->txout) - 1;
13747 +
13748 + return (txp);
13749 +
13750 +bogus:
13751 +/*
13752 + DMA_ERROR(("dma_getnexttxp: bogus curr: start %d end %d txout %d force %d\n",
13753 + start, end, di->txout, forceall));
13754 +*/
13755 + return (NULL);
13756 +}
13757 +
13758 +static void *
13759 +dma32_getnextrxp(dma_info_t *di, bool forceall)
13760 +{
13761 + uint i;
13762 + void *rxp;
13763 +
13764 + /* if forcing, dma engine must be disabled */
13765 + ASSERT(!forceall || !dma_rxenabled(di));
13766 +
13767 + i = di->rxin;
13768 +
13769 + /* return if no packets posted */
13770 + if (i == di->rxout)
13771 + return (NULL);
13772 +
13773 + /* ignore curr if forceall */
13774 + if (!forceall && (i == B2I(R_REG(&di->d32rxregs->status) & RS_CD_MASK, dma32dd_t)))
13775 + return (NULL);
13776 +
13777 + /* get the packet pointer that corresponds to the rx descriptor */
13778 + rxp = di->rxp[i];
13779 + ASSERT(rxp);
13780 + di->rxp[i] = NULL;
13781 +
13782 + /* clear this packet from the descriptor ring */
13783 + DMA_UNMAP(di->osh, (BUS_SWAP32(R_SM(&di->rxd32[i].addr)) - di->dataoffsetlow),
13784 + di->rxbufsize, DMA_RX, rxp);
13785 + W_SM(&di->rxd32[i].addr, 0xdeadbeef);
13786 +
13787 + di->rxin = NEXTRXD(i);
13788 +
13789 + return (rxp);
13790 +}
13791 +
13792 +static void
13793 +dma32_txrotate(di_t *di)
13794 +{
13795 + uint ad;
13796 + uint nactive;
13797 + uint rot;
13798 + uint old, new;
13799 + uint32 w;
13800 + uint first, last;
13801 +
13802 + ASSERT(dma_txsuspendedidle(di));
13803 +
13804 + nactive = dma_txactive(di);
13805 + ad = B2I(((R_REG(&di->d32txregs->status) & XS_AD_MASK) >> XS_AD_SHIFT), dma32dd_t);
13806 + rot = TXD(ad - di->txin);
13807 +
13808 + ASSERT(rot < di->ntxd);
13809 +
13810 + /* full-ring case is a lot harder - don't worry about this */
13811 + if (rot >= (di->ntxd - nactive)) {
13812 + DMA_ERROR(("%s: dma_txrotate: ring full - punt\n", di->name));
13813 + return;
13814 + }
13815 +
13816 + first = di->txin;
13817 + last = PREVTXD(di->txout);
13818 +
13819 + /* move entries starting at last and moving backwards to first */
13820 + for (old = last; old != PREVTXD(first); old = PREVTXD(old)) {
13821 + new = TXD(old + rot);
13822 +
13823 + /*
13824 + * Move the tx dma descriptor.
13825 + * EOT is set only in the last entry in the ring.
13826 + */
13827 + w = R_SM(&di->txd32[old].ctrl) & ~CTRL_EOT;
13828 + if (new == (di->ntxd - 1))
13829 + w |= CTRL_EOT;
13830 + W_SM(&di->txd32[new].ctrl, w);
13831 + W_SM(&di->txd32[new].addr, R_SM(&di->txd32[old].addr));
13832 +
13833 + /* zap the old tx dma descriptor address field */
13834 + W_SM(&di->txd32[old].addr, 0xdeadbeef);
13835 +
13836 + /* move the corresponding txp[] entry */
13837 + ASSERT(di->txp[new] == NULL);
13838 + di->txp[new] = di->txp[old];
13839 + di->txp[old] = NULL;
13840 + }
13841 +
13842 + /* update txin and txout */
13843 + di->txin = ad;
13844 + di->txout = TXD(di->txout + rot);
13845 + di->txavail = di->ntxd - NTXDACTIVE(di->txin, di->txout) - 1;
13846 +
13847 + /* kick the chip */
13848 + W_REG(&di->d32txregs->ptr, I2B(di->txout, dma32dd_t));
13849 +}
13850 +
13851 +/*** 64 bits DMA non-inline functions ***/
13852 +
13853 +#ifdef BCMDMA64
13854 +
13855 +static bool
13856 +dma64_alloc(dma_info_t *di, uint direction)
13857 +{
13858 + uint size;
13859 + uint ddlen;
13860 + uint32 alignbytes;
13861 + void *va;
13862 +
13863 + ddlen = sizeof (dma64dd_t);
13864 +
13865 + size = (direction == DMA_TX) ? (di->ntxd * ddlen) : (di->nrxd * ddlen);
13866 +
13867 + alignbytes = di->dma64align;
13868 +
13869 + if (!ISALIGNED(DMA_CONSISTENT_ALIGN, alignbytes))
13870 + size += alignbytes;
13871 +
13872 +
13873 + if (direction == DMA_TX) {
13874 + if ((va = DMA_ALLOC_CONSISTENT(di->osh, size, &di->txdpa)) == NULL) {
13875 + DMA_ERROR(("%s: dma_attach: DMA_ALLOC_CONSISTENT(ntxd) failed\n", di->name));
13876 + return FALSE;
13877 + }
13878 +
13879 + di->txd64 = (dma64dd_t*) ROUNDUP((uintptr)va, alignbytes);
13880 + di->txdalign = (uint)((int8*)di->txd64 - (int8*)va);
13881 + di->txdpa += di->txdalign;
13882 + di->txdalloc = size;
13883 + ASSERT(ISALIGNED((uintptr)di->txd64, alignbytes));
13884 + } else {
13885 + if ((va = DMA_ALLOC_CONSISTENT(di->osh, size, &di->rxdpa)) == NULL) {
13886 + DMA_ERROR(("%s: dma_attach: DMA_ALLOC_CONSISTENT(nrxd) failed\n", di->name));
13887 + return FALSE;
13888 + }
13889 + di->rxd64 = (dma64dd_t*) ROUNDUP((uintptr)va, alignbytes);
13890 + di->rxdalign = (uint)((int8*)di->rxd64 - (int8*)va);
13891 + di->rxdpa += di->rxdalign;
13892 + di->rxdalloc = size;
13893 + ASSERT(ISALIGNED((uintptr)di->rxd64, alignbytes));
13894 + }
13895 +
13896 + return TRUE;
13897 +}
13898 +
13899 +static void
13900 +dma64_txreset(dma_info_t *di)
13901 +{
13902 + uint32 status;
13903 +
13904 + /* suspend tx DMA first */
13905 + W_REG(&di->d64txregs->control, D64_XC_SE);
13906 + SPINWAIT((status = (R_REG(&di->d64txregs->status0) & D64_XS0_XS_MASK)) != D64_XS0_XS_DISABLED &&
13907 + status != D64_XS0_XS_IDLE &&
13908 + status != D64_XS0_XS_STOPPED,
13909 + 10000);
13910 +
13911 + W_REG(&di->d64txregs->control, 0);
13912 + SPINWAIT((status = (R_REG(&di->d64txregs->status0) & D64_XS0_XS_MASK)) != D64_XS0_XS_DISABLED,
13913 + 10000);
13914 +
13915 + if (status != D64_XS0_XS_DISABLED) {
13916 + DMA_ERROR(("%s: dma_txreset: dma cannot be stopped\n", di->name));
13917 + }
13918 +
13919 + /* wait for the last transaction to complete */
13920 + OSL_DELAY(300);
13921 +}
13922 +
13923 +static void
13924 +dma64_rxreset(dma_info_t *di)
13925 +{
13926 + uint32 status;
13927 +
13928 + W_REG(&di->d64rxregs->control, 0);
13929 + SPINWAIT((status = (R_REG(&di->d64rxregs->status0) & D64_RS0_RS_MASK)) != D64_RS0_RS_DISABLED,
13930 + 10000);
13931 +
13932 + if (status != D64_RS0_RS_DISABLED) {
13933 + DMA_ERROR(("%s: dma_rxreset: dma cannot be stopped\n", di->name));
13934 + }
13935 +}
13936 +
13937 +static bool
13938 +dma64_txsuspendedidle(dma_info_t *di)
13939 +{
13940 +
13941 + if (!(R_REG(&di->d64txregs->control) & D64_XC_SE))
13942 + return 0;
13943 +
13944 + if ((R_REG(&di->d64txregs->status0) & D64_XS0_XS_MASK) == D64_XS0_XS_IDLE)
13945 + return 1;
13946 +
13947 + return 0;
13948 +}
13949 +
13950 +/*
13951 + * supports full 32bit dma engine buffer addressing so
13952 + * dma buffers can cross 4 Kbyte page boundaries.
13953 + */
13954 +static int
13955 +dma64_txfast(dma_info_t *di, void *p0, uint32 coreflags)
13956 +{
13957 + void *p, *next;
13958 + uchar *data;
13959 + uint len;
13960 + uint txout;
13961 + uint32 flags;
13962 + uint32 pa;
13963 +
13964 + DMA_TRACE(("%s: dma_txfast\n", di->name));
13965 +
13966 + txout = di->txout;
13967 + flags = 0;
13968 +
13969 + /*
13970 + * Walk the chain of packet buffers
13971 + * allocating and initializing transmit descriptor entries.
13972 + */
13973 + for (p = p0; p; p = next) {
13974 + data = PKTDATA(di->osh, p);
13975 + len = PKTLEN(di->osh, p);
13976 + next = PKTNEXT(di->osh, p);
13977 +
13978 + /* return nonzero if out of tx descriptors */
13979 + if (NEXTTXD(txout) == di->txin)
13980 + goto outoftxd;
13981 +
13982 + if (len == 0)
13983 + continue;
13984 +
13985 + /* get physical address of buffer start */
13986 + pa = (uint32) DMA_MAP(di->osh, data, len, DMA_TX, p);
13987 +
13988 + flags = coreflags;
13989 +
13990 + if (p == p0)
13991 + flags |= D64_CTRL1_SOF;
13992 + if (next == NULL)
13993 + flags |= (D64_CTRL1_IOC | D64_CTRL1_EOF);
13994 + if (txout == (di->ntxd - 1))
13995 + flags |= D64_CTRL1_EOT;
13996 +
13997 + dma64_dd_upd(di, di->txd64, pa, txout, &flags, len);
13998 +
13999 + ASSERT(di->txp[txout] == NULL);
14000 +
14001 + txout = NEXTTXD(txout);
14002 + }
14003 +
14004 + /* if last txd eof not set, fix it */
14005 + if (!(flags & D64_CTRL1_EOF))
14006 + W_SM(&di->txd64[PREVTXD(txout)].ctrl1, BUS_SWAP32(flags | D64_CTRL1_IOC | D64_CTRL1_EOF));
14007 +
14008 + /* save the packet */
14009 + di->txp[PREVTXD(txout)] = p0;
14010 +
14011 + /* bump the tx descriptor index */
14012 + di->txout = txout;
14013 +
14014 + /* kick the chip */
14015 + W_REG(&di->d64txregs->ptr, I2B(txout, dma64dd_t));
14016 +
14017 + /* tx flow control */
14018 + di->txavail = di->ntxd - NTXDACTIVE(di->txin, di->txout) - 1;
14019 +
14020 + return (0);
14021 +
14022 +outoftxd:
14023 + DMA_ERROR(("%s: dma_txfast: out of txds\n", di->name));
14024 + PKTFREE(di->osh, p0, TRUE);
14025 + di->txavail = 0;
14026 + di->hnddma.txnobuf++;
14027 + return (-1);
14028 +}
14029 +
14030 +static void*
14031 +dma64_getnexttxp(dma_info_t *di, bool forceall)
14032 +{
14033 + uint start, end, i;
14034 + void *txp;
14035 +
14036 + DMA_TRACE(("%s: dma_getnexttxp %s\n", di->name, forceall ? "all" : ""));
14037 +
14038 + txp = NULL;
14039 +
14040 + start = di->txin;
14041 + if (forceall)
14042 + end = di->txout;
14043 + else
14044 + end = B2I(R_REG(&di->d64txregs->status0) & D64_XS0_CD_MASK, dma64dd_t);
14045 +
14046 + if ((start == 0) && (end > di->txout))
14047 + goto bogus;
14048 +
14049 + for (i = start; i != end && !txp; i = NEXTTXD(i)) {
14050 + DMA_UNMAP(di->osh, (BUS_SWAP32(R_SM(&di->txd64[i].addrlow)) - di->dataoffsetlow),
14051 + (BUS_SWAP32(R_SM(&di->txd64[i].ctrl2)) & D64_CTRL2_BC_MASK), DMA_TX, di->txp[i]);
14052 +
14053 + W_SM(&di->txd64[i].addrlow, 0xdeadbeef);
14054 + W_SM(&di->txd64[i].addrhigh, 0xdeadbeef);
14055 +
14056 + txp = di->txp[i];
14057 + di->txp[i] = NULL;
14058 + }
14059 +
14060 + di->txin = i;
14061 +
14062 + /* tx flow control */
14063 + di->txavail = di->ntxd - NTXDACTIVE(di->txin, di->txout) - 1;
14064 +
14065 + return (txp);
14066 +
14067 +bogus:
14068 +/*
14069 + DMA_ERROR(("dma_getnexttxp: bogus curr: start %d end %d txout %d force %d\n",
14070 + start, end, di->txout, forceall));
14071 +*/
14072 + return (NULL);
14073 +}
14074 +
14075 +static void *
14076 +dma64_getnextrxp(dma_info_t *di, bool forceall)
14077 +{
14078 + uint i;
14079 + void *rxp;
14080 +
14081 + /* if forcing, dma engine must be disabled */
14082 + ASSERT(!forceall || !dma_rxenabled(di));
14083 +
14084 + i = di->rxin;
14085 +
14086 + /* return if no packets posted */
14087 + if (i == di->rxout)
14088 + return (NULL);
14089 +
14090 + /* ignore curr if forceall */
14091 + if (!forceall && (i == B2I(R_REG(&di->d64rxregs->status0) & D64_RS0_CD_MASK, dma64dd_t)))
14092 + return (NULL);
14093 +
14094 + /* get the packet pointer that corresponds to the rx descriptor */
14095 + rxp = di->rxp[i];
14096 + ASSERT(rxp);
14097 + di->rxp[i] = NULL;
14098 +
14099 + /* clear this packet from the descriptor ring */
14100 + DMA_UNMAP(di->osh, (BUS_SWAP32(R_SM(&di->rxd64[i].addrlow)) - di->dataoffsetlow),
14101 + di->rxbufsize, DMA_RX, rxp);
14102 +
14103 + W_SM(&di->rxd64[i].addrlow, 0xdeadbeef);
14104 + W_SM(&di->rxd64[i].addrhigh, 0xdeadbeef);
14105 +
14106 + di->rxin = NEXTRXD(i);
14107 +
14108 + return (rxp);
14109 +}
14110 +
14111 +static void
14112 +dma64_txrotate(di_t *di)
14113 +{
14114 + uint ad;
14115 + uint nactive;
14116 + uint rot;
14117 + uint old, new;
14118 + uint32 w;
14119 + uint first, last;
14120 +
14121 + ASSERT(dma_txsuspendedidle(di));
14122 +
14123 + nactive = dma_txactive(di);
14124 + ad = B2I((R_REG(&di->d64txregs->status1) & D64_XS1_AD_MASK), dma64dd_t);
14125 + rot = TXD(ad - di->txin);
14126 +
14127 + ASSERT(rot < di->ntxd);
14128 +
14129 + /* full-ring case is a lot harder - don't worry about this */
14130 + if (rot >= (di->ntxd - nactive)) {
14131 + DMA_ERROR(("%s: dma_txrotate: ring full - punt\n", di->name));
14132 + return;
14133 + }
14134 +
14135 + first = di->txin;
14136 + last = PREVTXD(di->txout);
14137 +
14138 + /* move entries starting at last and moving backwards to first */
14139 + for (old = last; old != PREVTXD(first); old = PREVTXD(old)) {
14140 + new = TXD(old + rot);
14141 +
14142 + /*
14143 + * Move the tx dma descriptor.
14144 + * EOT is set only in the last entry in the ring.
14145 + */
14146 + w = R_SM(&di->txd64[old].ctrl1) & ~D64_CTRL1_EOT;
14147 + if (new == (di->ntxd - 1))
14148 + w |= D64_CTRL1_EOT;
14149 + W_SM(&di->txd64[new].ctrl1, w);
14150 +
14151 + w = R_SM(&di->txd64[old].ctrl2);
14152 + W_SM(&di->txd64[new].ctrl2, w);
14153 +
14154 + W_SM(&di->txd64[new].addrlow, R_SM(&di->txd64[old].addrlow));
14155 + W_SM(&di->txd64[new].addrhigh, R_SM(&di->txd64[old].addrhigh));
14156 +
14157 + /* zap the old tx dma descriptor address field */
14158 + W_SM(&di->txd64[old].addrlow, 0xdeadbeef);
14159 + W_SM(&di->txd64[old].addrhigh, 0xdeadbeef);
14160 +
14161 + /* move the corresponding txp[] entry */
14162 + ASSERT(di->txp[new] == NULL);
14163 + di->txp[new] = di->txp[old];
14164 + di->txp[old] = NULL;
14165 + }
14166 +
14167 + /* update txin and txout */
14168 + di->txin = ad;
14169 + di->txout = TXD(di->txout + rot);
14170 + di->txavail = di->ntxd - NTXDACTIVE(di->txin, di->txout) - 1;
14171 +
14172 + /* kick the chip */
14173 + W_REG(&di->d64txregs->ptr, I2B(di->txout, dma64dd_t));
14174 +}
14175 +
14176 +#endif
14177 +
14178 diff -Nur linux-2.4.32/drivers/net/hnd/linux_osl.c linux-2.4.32-brcm/drivers/net/hnd/linux_osl.c
14179 --- linux-2.4.32/drivers/net/hnd/linux_osl.c 1970-01-01 01:00:00.000000000 +0100
14180 +++ linux-2.4.32-brcm/drivers/net/hnd/linux_osl.c 2005-12-16 23:39:11.292858500 +0100
14181 @@ -0,0 +1,708 @@
14182 +/*
14183 + * Linux OS Independent Layer
14184 + *
14185 + * Copyright 2005, Broadcom Corporation
14186 + * All Rights Reserved.
14187 + *
14188 + * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY
14189 + * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM
14190 + * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS
14191 + * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE.
14192 + *
14193 + * $Id$
14194 + */
14195 +
14196 +#define LINUX_OSL
14197 +
14198 +#include <typedefs.h>
14199 +#include <bcmendian.h>
14200 +#include <linux/module.h>
14201 +#include <linuxver.h>
14202 +#include <osl.h>
14203 +#include <bcmutils.h>
14204 +#include <linux/delay.h>
14205 +#ifdef mips
14206 +#include <asm/paccess.h>
14207 +#endif
14208 +#include <pcicfg.h>
14209 +
14210 +#define PCI_CFG_RETRY 10
14211 +
14212 +#define OS_HANDLE_MAGIC 0x1234abcd
14213 +#define BCM_MEM_FILENAME_LEN 24
14214 +
14215 +typedef struct bcm_mem_link {
14216 + struct bcm_mem_link *prev;
14217 + struct bcm_mem_link *next;
14218 + uint size;
14219 + int line;
14220 + char file[BCM_MEM_FILENAME_LEN];
14221 +} bcm_mem_link_t;
14222 +
14223 +struct os_handle {
14224 + uint magic;
14225 + void *pdev;
14226 + uint malloced;
14227 + uint failed;
14228 + bcm_mem_link_t *dbgmem_list;
14229 +};
14230 +
14231 +static int16 linuxbcmerrormap[] = \
14232 +{ 0, /* 0 */
14233 + -EINVAL, /* BCME_ERROR */
14234 + -EINVAL, /* BCME_BADARG*/
14235 + -EINVAL, /* BCME_BADOPTION*/
14236 + -EINVAL, /* BCME_NOTUP */
14237 + -EINVAL, /* BCME_NOTDOWN */
14238 + -EINVAL, /* BCME_NOTAP */
14239 + -EINVAL, /* BCME_NOTSTA */
14240 + -EINVAL, /* BCME_BADKEYIDX */
14241 + -EINVAL, /* BCME_RADIOOFF */
14242 + -EINVAL, /* BCME_NOTBANDLOCKED */
14243 + -EINVAL, /* BCME_NOCLK */
14244 + -EINVAL, /* BCME_BADRATESET */
14245 + -EINVAL, /* BCME_BADBAND */
14246 + -E2BIG, /* BCME_BUFTOOSHORT */
14247 + -E2BIG, /* BCME_BUFTOOLONG */
14248 + -EBUSY, /* BCME_BUSY */
14249 + -EINVAL, /* BCME_NOTASSOCIATED */
14250 + -EINVAL, /* BCME_BADSSIDLEN */
14251 + -EINVAL, /* BCME_OUTOFRANGECHAN */
14252 + -EINVAL, /* BCME_BADCHAN */
14253 + -EFAULT, /* BCME_BADADDR */
14254 + -ENOMEM, /* BCME_NORESOURCE */
14255 + -EOPNOTSUPP, /* BCME_UNSUPPORTED */
14256 + -EMSGSIZE, /* BCME_BADLENGTH */
14257 + -EINVAL, /* BCME_NOTREADY */
14258 + -EPERM, /* BCME_NOTPERMITTED */
14259 + -ENOMEM, /* BCME_NOMEM */
14260 + -EINVAL, /* BCME_ASSOCIATED */
14261 + -ERANGE, /* BCME_RANGE */
14262 + -EINVAL /* BCME_NOTFOUND */
14263 +};
14264 +
14265 +/* translate bcmerrors into linux errors*/
14266 +int
14267 +osl_error(int bcmerror)
14268 +{
14269 + int abs_bcmerror;
14270 + int array_size = ARRAYSIZE(linuxbcmerrormap);
14271 +
14272 + abs_bcmerror = ABS(bcmerror);
14273 +
14274 + if (bcmerror > 0)
14275 + abs_bcmerror = 0;
14276 +
14277 + else if (abs_bcmerror >= array_size)
14278 + abs_bcmerror = BCME_ERROR;
14279 +
14280 + return linuxbcmerrormap[abs_bcmerror];
14281 +}
14282 +
14283 +osl_t *
14284 +osl_attach(void *pdev)
14285 +{
14286 + osl_t *osh;
14287 +
14288 + osh = kmalloc(sizeof(osl_t), GFP_ATOMIC);
14289 + ASSERT(osh);
14290 +
14291 + /*
14292 + * check the cases where
14293 + * 1.Error code Added to bcmerror table, but forgot to add it to the OS
14294 + * dependent error code
14295 + * 2. Error code is added to the bcmerror table, but forgot to add the
14296 + * corresponding errorstring(dummy call to bcmerrorstr)
14297 + */
14298 + bcmerrorstr(0);
14299 + ASSERT(ABS(BCME_LAST) == (ARRAYSIZE(linuxbcmerrormap) - 1));
14300 +
14301 + osh->magic = OS_HANDLE_MAGIC;
14302 + osh->malloced = 0;
14303 + osh->failed = 0;
14304 + osh->dbgmem_list = NULL;
14305 + osh->pdev = pdev;
14306 +
14307 + return osh;
14308 +}
14309 +
14310 +void
14311 +osl_detach(osl_t *osh)
14312 +{
14313 + ASSERT(osh && (osh->magic == OS_HANDLE_MAGIC));
14314 + kfree(osh);
14315 +}
14316 +
14317 +void*
14318 +osl_pktget(osl_t *osh, uint len, bool send)
14319 +{
14320 + struct sk_buff *skb;
14321 +
14322 + if ((skb = dev_alloc_skb(len)) == NULL)
14323 + return (NULL);
14324 +
14325 + skb_put(skb, len);
14326 +
14327 + /* ensure the cookie field is cleared */
14328 + PKTSETCOOKIE(skb, NULL);
14329 +
14330 + return ((void*) skb);
14331 +}
14332 +
14333 +void
14334 +osl_pktfree(void *p)
14335 +{
14336 + struct sk_buff *skb, *nskb;
14337 +
14338 + skb = (struct sk_buff*) p;
14339 +
14340 + /* perversion: we use skb->next to chain multi-skb packets */
14341 + while (skb) {
14342 + nskb = skb->next;
14343 + skb->next = NULL;
14344 + if (skb->destructor) {
14345 + /* cannot kfree_skb() on hard IRQ (net/core/skbuff.c) if destructor exists */
14346 + dev_kfree_skb_any(skb);
14347 + } else {
14348 + /* can free immediately (even in_irq()) if destructor does not exist */
14349 + dev_kfree_skb(skb);
14350 + }
14351 + skb = nskb;
14352 + }
14353 +}
14354 +
14355 +uint32
14356 +osl_pci_read_config(osl_t *osh, uint offset, uint size)
14357 +{
14358 + uint val;
14359 + uint retry=PCI_CFG_RETRY;
14360 +
14361 + ASSERT((osh && (osh->magic == OS_HANDLE_MAGIC)));
14362 +
14363 + /* only 4byte access supported */
14364 + ASSERT(size == 4);
14365 +
14366 + do {
14367 + pci_read_config_dword(osh->pdev, offset, &val);
14368 + if (val != 0xffffffff)
14369 + break;
14370 + } while (retry--);
14371 +
14372 +
14373 + return (val);
14374 +}
14375 +
14376 +void
14377 +osl_pci_write_config(osl_t *osh, uint offset, uint size, uint val)
14378 +{
14379 + uint retry=PCI_CFG_RETRY;
14380 +
14381 + ASSERT((osh && (osh->magic == OS_HANDLE_MAGIC)));
14382 +
14383 + /* only 4byte access supported */
14384 + ASSERT(size == 4);
14385 +
14386 + do {
14387 + pci_write_config_dword(osh->pdev, offset, val);
14388 + if (offset!=PCI_BAR0_WIN)
14389 + break;
14390 + if (osl_pci_read_config(osh,offset,size) == val)
14391 + break;
14392 + } while (retry--);
14393 +
14394 +}
14395 +
14396 +/* return bus # for the pci device pointed by osh->pdev */
14397 +uint
14398 +osl_pci_bus(osl_t *osh)
14399 +{
14400 + ASSERT(osh && (osh->magic == OS_HANDLE_MAGIC) && osh->pdev);
14401 +
14402 + return ((struct pci_dev *)osh->pdev)->bus->number;
14403 +}
14404 +
14405 +/* return slot # for the pci device pointed by osh->pdev */
14406 +uint
14407 +osl_pci_slot(osl_t *osh)
14408 +{
14409 + ASSERT(osh && (osh->magic == OS_HANDLE_MAGIC) && osh->pdev);
14410 +
14411 + return PCI_SLOT(((struct pci_dev *)osh->pdev)->devfn);
14412 +}
14413 +
14414 +static void
14415 +osl_pcmcia_attr(osl_t *osh, uint offset, char *buf, int size, bool write)
14416 +{
14417 +}
14418 +
14419 +void
14420 +osl_pcmcia_read_attr(osl_t *osh, uint offset, void *buf, int size)
14421 +{
14422 + osl_pcmcia_attr(osh, offset, (char *) buf, size, FALSE);
14423 +}
14424 +
14425 +void
14426 +osl_pcmcia_write_attr(osl_t *osh, uint offset, void *buf, int size)
14427 +{
14428 + osl_pcmcia_attr(osh, offset, (char *) buf, size, TRUE);
14429 +}
14430 +
14431 +
14432 +#ifdef BCMDBG_MEM
14433 +
14434 +void*
14435 +osl_debug_malloc(osl_t *osh, uint size, int line, char* file)
14436 +{
14437 + bcm_mem_link_t *p;
14438 + char* basename;
14439 +
14440 + ASSERT(size);
14441 +
14442 + if ((p = (bcm_mem_link_t*)osl_malloc(osh, sizeof(bcm_mem_link_t) + size)) == NULL)
14443 + return (NULL);
14444 +
14445 + p->size = size;
14446 + p->line = line;
14447 +
14448 + basename = strrchr(file, '/');
14449 + /* skip the '/' */
14450 + if (basename)
14451 + basename++;
14452 +
14453 + if (!basename)
14454 + basename = file;
14455 +
14456 + strncpy(p->file, basename, BCM_MEM_FILENAME_LEN);
14457 + p->file[BCM_MEM_FILENAME_LEN - 1] = '\0';
14458 +
14459 + /* link this block */
14460 + p->prev = NULL;
14461 + p->next = osh->dbgmem_list;
14462 + if (p->next)
14463 + p->next->prev = p;
14464 + osh->dbgmem_list = p;
14465 +
14466 + return p + 1;
14467 +}
14468 +
14469 +void
14470 +osl_debug_mfree(osl_t *osh, void *addr, uint size, int line, char* file)
14471 +{
14472 + bcm_mem_link_t *p = (bcm_mem_link_t *)((int8*)addr - sizeof(bcm_mem_link_t));
14473 +
14474 + ASSERT((osh && (osh->magic == OS_HANDLE_MAGIC)));
14475 +
14476 + if (p->size == 0) {
14477 + printk("osl_debug_mfree: double free on addr 0x%x size %d at line %d file %s\n",
14478 + (uint)addr, size, line, file);
14479 + ASSERT(p->size);
14480 + return;
14481 + }
14482 +
14483 + if (p->size != size) {
14484 + printk("osl_debug_mfree: dealloc size %d does not match alloc size %d on addr 0x%x at line %d file %s\n",
14485 + size, p->size, (uint)addr, line, file);
14486 + ASSERT(p->size == size);
14487 + return;
14488 + }
14489 +
14490 + /* unlink this block */
14491 + if (p->prev)
14492 + p->prev->next = p->next;
14493 + if (p->next)
14494 + p->next->prev = p->prev;
14495 + if (osh->dbgmem_list == p)
14496 + osh->dbgmem_list = p->next;
14497 + p->next = p->prev = NULL;
14498 +
14499 + osl_mfree(osh, p, size + sizeof(bcm_mem_link_t));
14500 +}
14501 +
14502 +char*
14503 +osl_debug_memdump(osl_t *osh, char *buf, uint sz)
14504 +{
14505 + bcm_mem_link_t *p;
14506 + char *obuf;
14507 +
14508 + ASSERT((osh && (osh->magic == OS_HANDLE_MAGIC)));
14509 + obuf = buf;
14510 +
14511 + buf += sprintf(buf, " Address\tSize\tFile:line\n");
14512 + for (p = osh->dbgmem_list; p && ((buf - obuf) < (sz - 128)); p = p->next)
14513 + buf += sprintf(buf, "0x%08x\t%5d\t%s:%d\n",
14514 + (int)p + sizeof(bcm_mem_link_t), p->size, p->file, p->line);
14515 +
14516 + return (obuf);
14517 +}
14518 +
14519 +#endif /* BCMDBG_MEM */
14520 +
14521 +void*
14522 +osl_malloc(osl_t *osh, uint size)
14523 +{
14524 + void *addr;
14525 +
14526 + /* only ASSERT if osh is defined */
14527 + if (osh)
14528 + ASSERT(osh->magic == OS_HANDLE_MAGIC);
14529 +
14530 + if ((addr = kmalloc(size, GFP_ATOMIC)) == NULL) {
14531 + if(osh)
14532 + osh->failed++;
14533 + return (NULL);
14534 + }
14535 + if (osh)
14536 + osh->malloced += size;
14537 +
14538 + return (addr);
14539 +}
14540 +
14541 +void
14542 +osl_mfree(osl_t *osh, void *addr, uint size)
14543 +{
14544 + if (osh) {
14545 + ASSERT(osh->magic == OS_HANDLE_MAGIC);
14546 + osh->malloced -= size;
14547 + }
14548 + kfree(addr);
14549 +}
14550 +
14551 +uint
14552 +osl_malloced(osl_t *osh)
14553 +{
14554 + ASSERT((osh && (osh->magic == OS_HANDLE_MAGIC)));
14555 + return (osh->malloced);
14556 +}
14557 +
14558 +uint osl_malloc_failed(osl_t *osh)
14559 +{
14560 + ASSERT((osh && (osh->magic == OS_HANDLE_MAGIC)));
14561 + return (osh->failed);
14562 +}
14563 +
14564 +void*
14565 +osl_dma_alloc_consistent(osl_t *osh, uint size, ulong *pap)
14566 +{
14567 + ASSERT((osh && (osh->magic == OS_HANDLE_MAGIC)));
14568 +
14569 + return (pci_alloc_consistent(osh->pdev, size, (dma_addr_t*)pap));
14570 +}
14571 +
14572 +void
14573 +osl_dma_free_consistent(osl_t *osh, void *va, uint size, ulong pa)
14574 +{
14575 + ASSERT((osh && (osh->magic == OS_HANDLE_MAGIC)));
14576 +
14577 + pci_free_consistent(osh->pdev, size, va, (dma_addr_t)pa);
14578 +}
14579 +
14580 +uint
14581 +osl_dma_map(osl_t *osh, void *va, uint size, int direction)
14582 +{
14583 + int dir;
14584 +
14585 + ASSERT((osh && (osh->magic == OS_HANDLE_MAGIC)));
14586 + dir = (direction == DMA_TX)? PCI_DMA_TODEVICE: PCI_DMA_FROMDEVICE;
14587 + return (pci_map_single(osh->pdev, va, size, dir));
14588 +}
14589 +
14590 +void
14591 +osl_dma_unmap(osl_t *osh, uint pa, uint size, int direction)
14592 +{
14593 + int dir;
14594 +
14595 + ASSERT((osh && (osh->magic == OS_HANDLE_MAGIC)));
14596 + dir = (direction == DMA_TX)? PCI_DMA_TODEVICE: PCI_DMA_FROMDEVICE;
14597 + pci_unmap_single(osh->pdev, (uint32)pa, size, dir);
14598 +}
14599 +
14600 +#if defined(BINOSL)
14601 +void
14602 +osl_assert(char *exp, char *file, int line)
14603 +{
14604 + char tempbuf[255];
14605 +
14606 + sprintf(tempbuf, "assertion \"%s\" failed: file \"%s\", line %d\n", exp, file, line);
14607 + panic(tempbuf);
14608 +}
14609 +#endif /* BCMDBG || BINOSL */
14610 +
14611 +void
14612 +osl_delay(uint usec)
14613 +{
14614 + uint d;
14615 +
14616 + while (usec > 0) {
14617 + d = MIN(usec, 1000);
14618 + udelay(d);
14619 + usec -= d;
14620 + }
14621 +}
14622 +
14623 +/*
14624 + * BINOSL selects the slightly slower function-call-based binary compatible osl.
14625 + */
14626 +#ifdef BINOSL
14627 +
14628 +int
14629 +osl_printf(const char *format, ...)
14630 +{
14631 + va_list args;
14632 + char buf[1024];
14633 + int len;
14634 +
14635 + /* sprintf into a local buffer because there *is* no "vprintk()".. */
14636 + va_start(args, format);
14637 + len = vsprintf(buf, format, args);
14638 + va_end(args);
14639 +
14640 + if (len > sizeof (buf)) {
14641 + printk("osl_printf: buffer overrun\n");
14642 + return (0);
14643 + }
14644 +
14645 + return (printk(buf));
14646 +}
14647 +
14648 +int
14649 +osl_sprintf(char *buf, const char *format, ...)
14650 +{
14651 + va_list args;
14652 + int rc;
14653 +
14654 + va_start(args, format);
14655 + rc = vsprintf(buf, format, args);
14656 + va_end(args);
14657 + return (rc);
14658 +}
14659 +
14660 +int
14661 +osl_strcmp(const char *s1, const char *s2)
14662 +{
14663 + return (strcmp(s1, s2));
14664 +}
14665 +
14666 +int
14667 +osl_strncmp(const char *s1, const char *s2, uint n)
14668 +{
14669 + return (strncmp(s1, s2, n));
14670 +}
14671 +
14672 +int
14673 +osl_strlen(const char *s)
14674 +{
14675 + return (strlen(s));
14676 +}
14677 +
14678 +char*
14679 +osl_strcpy(char *d, const char *s)
14680 +{
14681 + return (strcpy(d, s));
14682 +}
14683 +
14684 +char*
14685 +osl_strncpy(char *d, const char *s, uint n)
14686 +{
14687 + return (strncpy(d, s, n));
14688 +}
14689 +
14690 +void
14691 +bcopy(const void *src, void *dst, int len)
14692 +{
14693 + memcpy(dst, src, len);
14694 +}
14695 +
14696 +int
14697 +bcmp(const void *b1, const void *b2, int len)
14698 +{
14699 + return (memcmp(b1, b2, len));
14700 +}
14701 +
14702 +void
14703 +bzero(void *b, int len)
14704 +{
14705 + memset(b, '\0', len);
14706 +}
14707 +
14708 +uint32
14709 +osl_readl(volatile uint32 *r)
14710 +{
14711 + return (readl(r));
14712 +}
14713 +
14714 +uint16
14715 +osl_readw(volatile uint16 *r)
14716 +{
14717 + return (readw(r));
14718 +}
14719 +
14720 +uint8
14721 +osl_readb(volatile uint8 *r)
14722 +{
14723 + return (readb(r));
14724 +}
14725 +
14726 +void
14727 +osl_writel(uint32 v, volatile uint32 *r)
14728 +{
14729 + writel(v, r);
14730 +}
14731 +
14732 +void
14733 +osl_writew(uint16 v, volatile uint16 *r)
14734 +{
14735 + writew(v, r);
14736 +}
14737 +
14738 +void
14739 +osl_writeb(uint8 v, volatile uint8 *r)
14740 +{
14741 + writeb(v, r);
14742 +}
14743 +
14744 +void *
14745 +osl_uncached(void *va)
14746 +{
14747 +#ifdef mips
14748 + return ((void*)KSEG1ADDR(va));
14749 +#else
14750 + return ((void*)va);
14751 +#endif
14752 +}
14753 +
14754 +uint
14755 +osl_getcycles(void)
14756 +{
14757 + uint cycles;
14758 +
14759 +#if defined(mips)
14760 + cycles = read_c0_count() * 2;
14761 +#elif defined(__i386__)
14762 + rdtscl(cycles);
14763 +#else
14764 + cycles = 0;
14765 +#endif
14766 + return cycles;
14767 +}
14768 +
14769 +void *
14770 +osl_reg_map(uint32 pa, uint size)
14771 +{
14772 + return (ioremap_nocache((unsigned long)pa, (unsigned long)size));
14773 +}
14774 +
14775 +void
14776 +osl_reg_unmap(void *va)
14777 +{
14778 + iounmap(va);
14779 +}
14780 +
14781 +int
14782 +osl_busprobe(uint32 *val, uint32 addr)
14783 +{
14784 +#ifdef mips
14785 + return get_dbe(*val, (uint32*)addr);
14786 +#else
14787 + *val = readl(addr);
14788 + return 0;
14789 +#endif
14790 +}
14791 +
14792 +uchar*
14793 +osl_pktdata(osl_t *osh, void *skb)
14794 +{
14795 + return (((struct sk_buff*)skb)->data);
14796 +}
14797 +
14798 +uint
14799 +osl_pktlen(osl_t *osh, void *skb)
14800 +{
14801 + return (((struct sk_buff*)skb)->len);
14802 +}
14803 +
14804 +uint
14805 +osl_pktheadroom(osl_t *osh, void *skb)
14806 +{
14807 + return (uint) skb_headroom((struct sk_buff *) skb);
14808 +}
14809 +
14810 +uint
14811 +osl_pkttailroom(osl_t *osh, void *skb)
14812 +{
14813 + return (uint) skb_tailroom((struct sk_buff *) skb);
14814 +}
14815 +
14816 +void*
14817 +osl_pktnext(osl_t *osh, void *skb)
14818 +{
14819 + return (((struct sk_buff*)skb)->next);
14820 +}
14821 +
14822 +void
14823 +osl_pktsetnext(void *skb, void *x)
14824 +{
14825 + ((struct sk_buff*)skb)->next = (struct sk_buff*)x;
14826 +}
14827 +
14828 +void
14829 +osl_pktsetlen(osl_t *osh, void *skb, uint len)
14830 +{
14831 + __skb_trim((struct sk_buff*)skb, len);
14832 +}
14833 +
14834 +uchar*
14835 +osl_pktpush(osl_t *osh, void *skb, int bytes)
14836 +{
14837 + return (skb_push((struct sk_buff*)skb, bytes));
14838 +}
14839 +
14840 +uchar*
14841 +osl_pktpull(osl_t *osh, void *skb, int bytes)
14842 +{
14843 + return (skb_pull((struct sk_buff*)skb, bytes));
14844 +}
14845 +
14846 +void*
14847 +osl_pktdup(osl_t *osh, void *skb)
14848 +{
14849 + return (skb_clone((struct sk_buff*)skb, GFP_ATOMIC));
14850 +}
14851 +
14852 +void*
14853 +osl_pktcookie(void *skb)
14854 +{
14855 + return ((void*)((struct sk_buff*)skb)->csum);
14856 +}
14857 +
14858 +void
14859 +osl_pktsetcookie(void *skb, void *x)
14860 +{
14861 + ((struct sk_buff*)skb)->csum = (uint)x;
14862 +}
14863 +
14864 +void*
14865 +osl_pktlink(void *skb)
14866 +{
14867 + return (((struct sk_buff*)skb)->prev);
14868 +}
14869 +
14870 +void
14871 +osl_pktsetlink(void *skb, void *x)
14872 +{
14873 + ((struct sk_buff*)skb)->prev = (struct sk_buff*)x;
14874 +}
14875 +
14876 +uint
14877 +osl_pktprio(void *skb)
14878 +{
14879 + return (((struct sk_buff*)skb)->priority);
14880 +}
14881 +
14882 +void
14883 +osl_pktsetprio(void *skb, uint x)
14884 +{
14885 + ((struct sk_buff*)skb)->priority = x;
14886 +}
14887 +
14888 +
14889 +#endif /* BINOSL */
14890 diff -Nur linux-2.4.32/drivers/net/hnd/Makefile linux-2.4.32-brcm/drivers/net/hnd/Makefile
14891 --- linux-2.4.32/drivers/net/hnd/Makefile 1970-01-01 01:00:00.000000000 +0100
14892 +++ linux-2.4.32-brcm/drivers/net/hnd/Makefile 2005-12-16 23:39:11.284858000 +0100
14893 @@ -0,0 +1,19 @@
14894 +#
14895 +# Makefile for the BCM47xx specific kernel interface routines
14896 +# under Linux.
14897 +#
14898 +
14899 +EXTRA_CFLAGS += -I$(TOPDIR)/arch/mips/bcm947xx/include -DBCMDRIVER
14900 +
14901 +O_TARGET := hnd.o
14902 +
14903 +HND_OBJS := bcmutils.o hnddma.o linux_osl.o sbutils.o bcmsrom.o
14904 +
14905 +export-objs := shared_ksyms.o
14906 +obj-y := shared_ksyms.o $(HND_OBJS)
14907 +obj-m := $(O_TARGET)
14908 +
14909 +include $(TOPDIR)/Rules.make
14910 +
14911 +shared_ksyms.c: shared_ksyms.sh $(HND_OBJS)
14912 + sh -e $< $(HND_OBJS) > $@
14913 diff -Nur linux-2.4.32/drivers/net/hnd/sbutils.c linux-2.4.32-brcm/drivers/net/hnd/sbutils.c
14914 --- linux-2.4.32/drivers/net/hnd/sbutils.c 1970-01-01 01:00:00.000000000 +0100
14915 +++ linux-2.4.32-brcm/drivers/net/hnd/sbutils.c 2005-12-16 23:39:11.316860000 +0100
14916 @@ -0,0 +1,2837 @@
14917 +/*
14918 + * Misc utility routines for accessing chip-specific features
14919 + * of the SiliconBackplane-based Broadcom chips.
14920 + *
14921 + * Copyright 2005, Broadcom Corporation
14922 + * All Rights Reserved.
14923 + *
14924 + * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY
14925 + * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM
14926 + * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS
14927 + * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE.
14928 + * $Id$
14929 + */
14930 +
14931 +#include <typedefs.h>
14932 +#include <osl.h>
14933 +#include <sbutils.h>
14934 +#include <bcmutils.h>
14935 +#include <bcmdevs.h>
14936 +#include <sbconfig.h>
14937 +#include <sbchipc.h>
14938 +#include <sbpci.h>
14939 +#include <sbpcie.h>
14940 +#include <pcicfg.h>
14941 +#include <sbpcmcia.h>
14942 +#include <sbextif.h>
14943 +#include <bcmsrom.h>
14944 +
14945 +/* debug/trace */
14946 +#define SB_ERROR(args)
14947 +
14948 +
14949 +typedef uint32 (*sb_intrsoff_t)(void *intr_arg);
14950 +typedef void (*sb_intrsrestore_t)(void *intr_arg, uint32 arg);
14951 +typedef bool (*sb_intrsenabled_t)(void *intr_arg);
14952 +
14953 +/* misc sb info needed by some of the routines */
14954 +typedef struct sb_info {
14955 +
14956 + struct sb_pub sb; /* back plane public state(must be first field of sb_info */
14957 +
14958 + void *osh; /* osl os handle */
14959 + void *sdh; /* bcmsdh handle */
14960 +
14961 + void *curmap; /* current regs va */
14962 + void *regs[SB_MAXCORES]; /* other regs va */
14963 +
14964 + uint curidx; /* current core index */
14965 + uint dev_coreid; /* the core provides driver functions */
14966 +
14967 + bool memseg; /* flag to toggle MEM_SEG register */
14968 +
14969 + uint gpioidx; /* gpio control core index */
14970 + uint gpioid; /* gpio control coretype */
14971 +
14972 + uint numcores; /* # discovered cores */
14973 + uint coreid[SB_MAXCORES]; /* id of each core */
14974 +
14975 + void *intr_arg; /* interrupt callback function arg */
14976 + sb_intrsoff_t intrsoff_fn; /* function turns chip interrupts off */
14977 + sb_intrsrestore_t intrsrestore_fn; /* function restore chip interrupts */
14978 + sb_intrsenabled_t intrsenabled_fn; /* function to check if chip interrupts are enabled */
14979 +
14980 +} sb_info_t;
14981 +
14982 +/* local prototypes */
14983 +static sb_info_t * BCMINIT(sb_doattach)(sb_info_t *si, uint devid, osl_t *osh, void *regs,
14984 + uint bustype, void *sdh, char **vars, int *varsz);
14985 +static void BCMINIT(sb_scan)(sb_info_t *si);
14986 +static uint sb_corereg(sb_info_t *si, uint coreidx, uint regoff, uint mask, uint val);
14987 +static uint _sb_coreidx(sb_info_t *si);
14988 +static uint sb_findcoreidx(sb_info_t *si, uint coreid, uint coreunit);
14989 +static uint BCMINIT(sb_pcidev2chip)(uint pcidev);
14990 +static uint BCMINIT(sb_chip2numcores)(uint chip);
14991 +static bool sb_ispcie(sb_info_t *si);
14992 +static bool sb_find_pci_capability(sb_info_t *si, uint8 req_cap_id, uchar *buf, uint32 *buflen);
14993 +static int sb_pci_fixcfg(sb_info_t *si);
14994 +
14995 +/* routines to access mdio slave device registers */
14996 +static int sb_pcie_mdiowrite(sb_info_t *si, uint physmedia, uint readdr, uint val);
14997 +static void BCMINIT(sb_war30841)(sb_info_t *si);
14998 +
14999 +/* delay needed between the mdio control/ mdiodata register data access */
15000 +#define PR28829_DELAY() OSL_DELAY(10)
15001 +
15002 +
15003 +/* global variable to indicate reservation/release of gpio's*/
15004 +static uint32 sb_gpioreservation = 0;
15005 +
15006 +#define SB_INFO(sbh) (sb_info_t*)sbh
15007 +#define SET_SBREG(sbh, r, mask, val) W_SBREG((sbh), (r), ((R_SBREG((sbh), (r)) & ~(mask)) | (val)))
15008 +#define GOODCOREADDR(x) (((x) >= SB_ENUM_BASE) && ((x) <= SB_ENUM_LIM) && ISALIGNED((x), SB_CORE_SIZE))
15009 +#define GOODREGS(regs) ((regs) && ISALIGNED((uintptr)(regs), SB_CORE_SIZE))
15010 +#define REGS2SB(va) (sbconfig_t*) ((int8*)(va) + SBCONFIGOFF)
15011 +#define GOODIDX(idx) (((uint)idx) < SB_MAXCORES)
15012 +#define BADIDX (SB_MAXCORES+1)
15013 +#define NOREV -1
15014 +
15015 +#define PCI(si) ((BUSTYPE(si->sb.bustype) == PCI_BUS) && (si->sb.buscoretype == SB_PCI))
15016 +#define PCIE(si) ((BUSTYPE(si->sb.bustype) == PCI_BUS) && (si->sb.buscoretype == SB_PCIE))
15017 +
15018 +/* sonicsrev */
15019 +#define SONICS_2_2 (SBIDL_RV_2_2 >> SBIDL_RV_SHIFT)
15020 +#define SONICS_2_3 (SBIDL_RV_2_3 >> SBIDL_RV_SHIFT)
15021 +
15022 +#define R_SBREG(sbh, sbr) sb_read_sbreg((sbh), (sbr))
15023 +#define W_SBREG(sbh, sbr, v) sb_write_sbreg((sbh), (sbr), (v))
15024 +#define AND_SBREG(sbh, sbr, v) W_SBREG((sbh), (sbr), (R_SBREG((sbh), (sbr)) & (v)))
15025 +#define OR_SBREG(sbh, sbr, v) W_SBREG((sbh), (sbr), (R_SBREG((sbh), (sbr)) | (v)))
15026 +
15027 +/*
15028 + * Macros to disable/restore function core(D11, ENET, ILINE20, etc) interrupts before/
15029 + * after core switching to avoid invalid register accesss inside ISR.
15030 + */
15031 +#define INTR_OFF(si, intr_val) \
15032 + if ((si)->intrsoff_fn && (si)->coreid[(si)->curidx] == (si)->dev_coreid) { \
15033 + intr_val = (*(si)->intrsoff_fn)((si)->intr_arg); }
15034 +#define INTR_RESTORE(si, intr_val) \
15035 + if ((si)->intrsrestore_fn && (si)->coreid[(si)->curidx] == (si)->dev_coreid) { \
15036 + (*(si)->intrsrestore_fn)((si)->intr_arg, intr_val); }
15037 +
15038 +/* dynamic clock control defines */
15039 +#define LPOMINFREQ 25000 /* low power oscillator min */
15040 +#define LPOMAXFREQ 43000 /* low power oscillator max */
15041 +#define XTALMINFREQ 19800000 /* 20 MHz - 1% */
15042 +#define XTALMAXFREQ 20200000 /* 20 MHz + 1% */
15043 +#define PCIMINFREQ 25000000 /* 25 MHz */
15044 +#define PCIMAXFREQ 34000000 /* 33 MHz + fudge */
15045 +
15046 +#define ILP_DIV_5MHZ 0 /* ILP = 5 MHz */
15047 +#define ILP_DIV_1MHZ 4 /* ILP = 1 MHz */
15048 +
15049 +#define MIN_DUMPBUFLEN 32 /* debug */
15050 +
15051 +/* different register spaces to access thr'u pcie indirect access*/
15052 +#define PCIE_CONFIGREGS 1
15053 +#define PCIE_PCIEREGS 2
15054 +
15055 +/* GPIO Based LED powersave defines */
15056 +#define DEFAULT_GPIO_ONTIME 10
15057 +#define DEFAULT_GPIO_OFFTIME 90
15058 +
15059 +#define DEFAULT_GPIOTIMERVAL ((DEFAULT_GPIO_ONTIME << GPIO_ONTIME_SHIFT) | DEFAULT_GPIO_OFFTIME)
15060 +
15061 +static uint32
15062 +sb_read_sbreg(sb_info_t *si, volatile uint32 *sbr)
15063 +{
15064 + uint8 tmp;
15065 + uint32 val, intr_val = 0;
15066 +
15067 +
15068 + /*
15069 + * compact flash only has 11 bits address, while we needs 12 bits address.
15070 + * MEM_SEG will be OR'd with other 11 bits address in hardware,
15071 + * so we program MEM_SEG with 12th bit when necessary(access sb regsiters).
15072 + * For normal PCMCIA bus(CFTable_regwinsz > 2k), do nothing special
15073 + */
15074 + if(si->memseg) {
15075 + INTR_OFF(si, intr_val);
15076 + tmp = 1;
15077 + OSL_PCMCIA_WRITE_ATTR(si->osh, MEM_SEG, &tmp, 1);
15078 + sbr = (uint32) ((uintptr) sbr & ~(1 << 11)); /* mask out bit 11*/
15079 + }
15080 +
15081 + val = R_REG(sbr);
15082 +
15083 + if(si->memseg) {
15084 + tmp = 0;
15085 + OSL_PCMCIA_WRITE_ATTR(si->osh, MEM_SEG, &tmp, 1);
15086 + INTR_RESTORE(si, intr_val);
15087 + }
15088 +
15089 + return (val);
15090 +}
15091 +
15092 +static void
15093 +sb_write_sbreg(sb_info_t *si, volatile uint32 *sbr, uint32 v)
15094 +{
15095 + uint8 tmp;
15096 + volatile uint32 dummy;
15097 + uint32 intr_val = 0;
15098 +
15099 +
15100 + /*
15101 + * compact flash only has 11 bits address, while we needs 12 bits address.
15102 + * MEM_SEG will be OR'd with other 11 bits address in hardware,
15103 + * so we program MEM_SEG with 12th bit when necessary(access sb regsiters).
15104 + * For normal PCMCIA bus(CFTable_regwinsz > 2k), do nothing special
15105 + */
15106 + if(si->memseg) {
15107 + INTR_OFF(si, intr_val);
15108 + tmp = 1;
15109 + OSL_PCMCIA_WRITE_ATTR(si->osh, MEM_SEG, &tmp, 1);
15110 + sbr = (uint32) ((uintptr) sbr & ~(1 << 11)); /* mask out bit 11*/
15111 + }
15112 +
15113 + if (BUSTYPE(si->sb.bustype) == PCMCIA_BUS) {
15114 +#ifdef IL_BIGENDIAN
15115 + dummy = R_REG(sbr);
15116 + W_REG(((volatile uint16 *)sbr + 1), (uint16)((v >> 16) & 0xffff));
15117 + dummy = R_REG(sbr);
15118 + W_REG((volatile uint16 *)sbr, (uint16)(v & 0xffff));
15119 +#else
15120 + dummy = R_REG(sbr);
15121 + W_REG((volatile uint16 *)sbr, (uint16)(v & 0xffff));
15122 + dummy = R_REG(sbr);
15123 + W_REG(((volatile uint16 *)sbr + 1), (uint16)((v >> 16) & 0xffff));
15124 +#endif
15125 + } else
15126 + W_REG(sbr, v);
15127 +
15128 + if(si->memseg) {
15129 + tmp = 0;
15130 + OSL_PCMCIA_WRITE_ATTR(si->osh, MEM_SEG, &tmp, 1);
15131 + INTR_RESTORE(si, intr_val);
15132 + }
15133 +}
15134 +
15135 +/*
15136 + * Allocate a sb handle.
15137 + * devid - pci device id (used to determine chip#)
15138 + * osh - opaque OS handle
15139 + * regs - virtual address of initial core registers
15140 + * bustype - pci/pcmcia/sb/sdio/etc
15141 + * vars - pointer to a pointer area for "environment" variables
15142 + * varsz - pointer to int to return the size of the vars
15143 + */
15144 +sb_t *
15145 +BCMINITFN(sb_attach)(uint devid, osl_t *osh, void *regs,
15146 + uint bustype, void *sdh, char **vars, int *varsz)
15147 +{
15148 + sb_info_t *si;
15149 +
15150 + /* alloc sb_info_t */
15151 + if ((si = MALLOC(osh, sizeof (sb_info_t))) == NULL) {
15152 + SB_ERROR(("sb_attach: malloc failed! malloced %d bytes\n", MALLOCED(osh)));
15153 + return (NULL);
15154 + }
15155 +
15156 + if (BCMINIT(sb_doattach)(si, devid, osh, regs, bustype, sdh, vars, varsz) == NULL) {
15157 + MFREE(osh, si, sizeof (sb_info_t));
15158 + return (NULL);
15159 + }
15160 + return (sb_t *)si;
15161 +}
15162 +
15163 +/* Using sb_kattach depends on SB_BUS support, either implicit */
15164 +/* no limiting BCMBUSTYPE value) or explicit (value is SB_BUS). */
15165 +#if !defined(BCMBUSTYPE) || (BCMBUSTYPE == SB_BUS)
15166 +
15167 +/* global kernel resource */
15168 +static sb_info_t ksi;
15169 +
15170 +/* generic kernel variant of sb_attach() */
15171 +sb_t *
15172 +BCMINITFN(sb_kattach)()
15173 +{
15174 + uint32 *regs;
15175 +
15176 + if (ksi.curmap == NULL) {
15177 + uint32 cid;
15178 +
15179 + regs = (uint32 *)REG_MAP(SB_ENUM_BASE, SB_CORE_SIZE);
15180 + cid = R_REG((uint32 *)regs);
15181 + if (((cid & CID_ID_MASK) == BCM4712_DEVICE_ID) &&
15182 + ((cid & CID_PKG_MASK) != BCM4712LARGE_PKG_ID) &&
15183 + ((cid & CID_REV_MASK) <= (3 << CID_REV_SHIFT))) {
15184 + uint32 *scc, val;
15185 +
15186 + scc = (uint32 *)((uchar*)regs + OFFSETOF(chipcregs_t, slow_clk_ctl));
15187 + val = R_REG(scc);
15188 + SB_ERROR((" initial scc = 0x%x\n", val));
15189 + val |= SCC_SS_XTAL;
15190 + W_REG(scc, val);
15191 + }
15192 +
15193 + if (BCMINIT(sb_doattach)(&ksi, BCM4710_DEVICE_ID, NULL, (void*)regs,
15194 + SB_BUS, NULL, NULL, NULL) == NULL) {
15195 + return NULL;
15196 + }
15197 + }
15198 +
15199 + return (sb_t *)&ksi;
15200 +}
15201 +#endif
15202 +
15203 +static sb_info_t *
15204 +BCMINITFN(sb_doattach)(sb_info_t *si, uint devid, osl_t *osh, void *regs,
15205 + uint bustype, void *sdh, char **vars, int *varsz)
15206 +{
15207 + uint origidx;
15208 + chipcregs_t *cc;
15209 + sbconfig_t *sb;
15210 + uint32 w;
15211 +
15212 + ASSERT(GOODREGS(regs));
15213 +
15214 + bzero((uchar*)si, sizeof (sb_info_t));
15215 +
15216 + si->sb.buscoreidx = si->gpioidx = BADIDX;
15217 +
15218 + si->osh = osh;
15219 + si->curmap = regs;
15220 + si->sdh = sdh;
15221 +
15222 + /* check to see if we are a sb core mimic'ing a pci core */
15223 + if (bustype == PCI_BUS) {
15224 + if (OSL_PCI_READ_CONFIG(osh, PCI_SPROM_CONTROL, sizeof (uint32)) == 0xffffffff)
15225 + bustype = SB_BUS;
15226 + else
15227 + bustype = PCI_BUS;
15228 + }
15229 +
15230 + si->sb.bustype = bustype;
15231 + if (si->sb.bustype != BUSTYPE(si->sb.bustype)) {
15232 + SB_ERROR(("sb_doattach: bus type %d does not match configured bus type %d\n",
15233 + si->sb.bustype, BUSTYPE(si->sb.bustype)));
15234 + return NULL;
15235 + }
15236 +
15237 + /* need to set memseg flag for CF card first before any sb registers access */
15238 + if (BUSTYPE(si->sb.bustype) == PCMCIA_BUS)
15239 + si->memseg = TRUE;
15240 +
15241 + /* kludge to enable the clock on the 4306 which lacks a slowclock */
15242 + if (BUSTYPE(si->sb.bustype) == PCI_BUS)
15243 + sb_clkctl_xtal(&si->sb, XTAL|PLL, ON);
15244 +
15245 + if (BUSTYPE(si->sb.bustype) == PCI_BUS) {
15246 + w = OSL_PCI_READ_CONFIG(osh, PCI_BAR0_WIN, sizeof (uint32));
15247 + if (!GOODCOREADDR(w))
15248 + OSL_PCI_WRITE_CONFIG(si->osh, PCI_BAR0_WIN, sizeof (uint32), SB_ENUM_BASE);
15249 + }
15250 +
15251 + /* initialize current core index value */
15252 + si->curidx = _sb_coreidx(si);
15253 +
15254 + if (si->curidx == BADIDX) {
15255 + SB_ERROR(("sb_doattach: bad core index\n"));
15256 + return NULL;
15257 + }
15258 +
15259 + /* get sonics backplane revision */
15260 + sb = REGS2SB(si->curmap);
15261 + si->sb.sonicsrev = (R_SBREG(si, &(sb)->sbidlow) & SBIDL_RV_MASK) >> SBIDL_RV_SHIFT;
15262 +
15263 + /* keep and reuse the initial register mapping */
15264 + origidx = si->curidx;
15265 + if (BUSTYPE(si->sb.bustype) == SB_BUS)
15266 + si->regs[origidx] = regs;
15267 +
15268 + /* is core-0 a chipcommon core? */
15269 + si->numcores = 1;
15270 + cc = (chipcregs_t*) sb_setcoreidx(&si->sb, 0);
15271 + if (sb_coreid(&si->sb) != SB_CC)
15272 + cc = NULL;
15273 +
15274 + /* determine chip id and rev */
15275 + if (cc) {
15276 + /* chip common core found! */
15277 + si->sb.chip = R_REG(&cc->chipid) & CID_ID_MASK;
15278 + si->sb.chiprev = (R_REG(&cc->chipid) & CID_REV_MASK) >> CID_REV_SHIFT;
15279 + si->sb.chippkg = (R_REG(&cc->chipid) & CID_PKG_MASK) >> CID_PKG_SHIFT;
15280 + } else {
15281 + /* The only pcmcia chip without a chipcommon core is a 4301 */
15282 + if (BUSTYPE(si->sb.bustype) == PCMCIA_BUS)
15283 + devid = BCM4301_DEVICE_ID;
15284 +
15285 + /* no chip common core -- must convert device id to chip id */
15286 + if ((si->sb.chip = BCMINIT(sb_pcidev2chip)(devid)) == 0) {
15287 + SB_ERROR(("sb_doattach: unrecognized device id 0x%04x\n", devid));
15288 + sb_setcoreidx(&si->sb, origidx);
15289 + return NULL;
15290 + }
15291 + }
15292 +
15293 + /* get chipcommon rev */
15294 + si->sb.ccrev = cc ? (int)sb_corerev(&si->sb) : NOREV;
15295 +
15296 + /* determine numcores */
15297 + if (cc && ((si->sb.ccrev == 4) || (si->sb.ccrev >= 6)))
15298 + si->numcores = (R_REG(&cc->chipid) & CID_CC_MASK) >> CID_CC_SHIFT;
15299 + else
15300 + si->numcores = BCMINIT(sb_chip2numcores)(si->sb.chip);
15301 +
15302 + /* return to original core */
15303 + sb_setcoreidx(&si->sb, origidx);
15304 +
15305 + /* sanity checks */
15306 + ASSERT(si->sb.chip);
15307 +
15308 + /* scan for cores */
15309 + BCMINIT(sb_scan)(si);
15310 +
15311 + /* fixup necessary chip/core configurations */
15312 + if (BUSTYPE(si->sb.bustype) == PCI_BUS) {
15313 + if (sb_pci_fixcfg(si)) {
15314 + SB_ERROR(("sb_doattach: sb_pci_fixcfg failed\n"));
15315 + return NULL;
15316 + }
15317 + }
15318 +
15319 + /* srom_var_init() depends on sb_scan() info */
15320 + if (srom_var_init(si, si->sb.bustype, si->curmap, osh, vars, varsz)) {
15321 + SB_ERROR(("sb_doattach: srom_var_init failed: bad srom\n"));
15322 + return (NULL);
15323 + }
15324 +
15325 + if (cc == NULL) {
15326 + /*
15327 + * The chip revision number is hardwired into all
15328 + * of the pci function config rev fields and is
15329 + * independent from the individual core revision numbers.
15330 + * For example, the "A0" silicon of each chip is chip rev 0.
15331 + * For PCMCIA we get it from the CIS instead.
15332 + */
15333 + if (BUSTYPE(si->sb.bustype) == PCMCIA_BUS) {
15334 + ASSERT(vars);
15335 + si->sb.chiprev = getintvar(*vars, "chiprev");
15336 + } else if (BUSTYPE(si->sb.bustype) == PCI_BUS) {
15337 + w = OSL_PCI_READ_CONFIG(osh, PCI_CFG_REV, sizeof (uint32));
15338 + si->sb.chiprev = w & 0xff;
15339 + } else
15340 + si->sb.chiprev = 0;
15341 + }
15342 +
15343 + if (BUSTYPE(si->sb.bustype) == PCMCIA_BUS) {
15344 + w = getintvar(*vars, "regwindowsz");
15345 + si->memseg = (w <= CFTABLE_REGWIN_2K) ? TRUE : FALSE;
15346 + }
15347 +
15348 + /* gpio control core is required */
15349 + if (!GOODIDX(si->gpioidx)) {
15350 + SB_ERROR(("sb_doattach: gpio control core not found\n"));
15351 + return NULL;
15352 + }
15353 +
15354 + /* get boardtype and boardrev */
15355 + switch (BUSTYPE(si->sb.bustype)) {
15356 + case PCI_BUS:
15357 + /* do a pci config read to get subsystem id and subvendor id */
15358 + w = OSL_PCI_READ_CONFIG(osh, PCI_CFG_SVID, sizeof (uint32));
15359 + si->sb.boardvendor = w & 0xffff;
15360 + si->sb.boardtype = (w >> 16) & 0xffff;
15361 + break;
15362 +
15363 + case PCMCIA_BUS:
15364 + case SDIO_BUS:
15365 + si->sb.boardvendor = getintvar(*vars, "manfid");
15366 + si->sb.boardtype = getintvar(*vars, "prodid");
15367 + break;
15368 +
15369 + case SB_BUS:
15370 + case JTAG_BUS:
15371 + si->sb.boardvendor = VENDOR_BROADCOM;
15372 + if ((si->sb.boardtype = getintvar(NULL, "boardtype")) == 0)
15373 + si->sb.boardtype = 0xffff;
15374 + break;
15375 + }
15376 +
15377 + if (si->sb.boardtype == 0) {
15378 + SB_ERROR(("sb_doattach: unknown board type\n"));
15379 + ASSERT(si->sb.boardtype);
15380 + }
15381 +
15382 + /* setup the GPIO based LED powersave register */
15383 + if (si->sb.ccrev >= 16) {
15384 + w = getintvar(*vars, "gpiotimerval");
15385 + if (!w)
15386 + w = DEFAULT_GPIOTIMERVAL;
15387 + sb_corereg(si, 0, OFFSETOF(chipcregs_t, gpiotimerval), ~0, w);
15388 + }
15389 +
15390 +
15391 + return (si);
15392 +}
15393 +
15394 +uint
15395 +sb_coreid(sb_t *sbh)
15396 +{
15397 + sb_info_t *si;
15398 + sbconfig_t *sb;
15399 +
15400 + si = SB_INFO(sbh);
15401 + sb = REGS2SB(si->curmap);
15402 +
15403 + return ((R_SBREG(si, &(sb)->sbidhigh) & SBIDH_CC_MASK) >> SBIDH_CC_SHIFT);
15404 +}
15405 +
15406 +uint
15407 +sb_coreidx(sb_t *sbh)
15408 +{
15409 + sb_info_t *si;
15410 +
15411 + si = SB_INFO(sbh);
15412 + return (si->curidx);
15413 +}
15414 +
15415 +/* return current index of core */
15416 +static uint
15417 +_sb_coreidx(sb_info_t *si)
15418 +{
15419 + sbconfig_t *sb;
15420 + uint32 sbaddr = 0;
15421 +
15422 + ASSERT(si);
15423 +
15424 + switch (BUSTYPE(si->sb.bustype)) {
15425 + case SB_BUS:
15426 + sb = REGS2SB(si->curmap);
15427 + sbaddr = sb_base(R_SBREG(si, &sb->sbadmatch0));
15428 + break;
15429 +
15430 + case PCI_BUS:
15431 + sbaddr = OSL_PCI_READ_CONFIG(si->osh, PCI_BAR0_WIN, sizeof (uint32));
15432 + break;
15433 +
15434 + case PCMCIA_BUS: {
15435 + uint8 tmp = 0;
15436 +
15437 + OSL_PCMCIA_READ_ATTR(si->osh, PCMCIA_ADDR0, &tmp, 1);
15438 + sbaddr = (uint)tmp << 12;
15439 + OSL_PCMCIA_READ_ATTR(si->osh, PCMCIA_ADDR1, &tmp, 1);
15440 + sbaddr |= (uint)tmp << 16;
15441 + OSL_PCMCIA_READ_ATTR(si->osh, PCMCIA_ADDR2, &tmp, 1);
15442 + sbaddr |= (uint)tmp << 24;
15443 + break;
15444 + }
15445 +
15446 +#ifdef BCMJTAG
15447 + case JTAG_BUS:
15448 + sbaddr = (uint32)si->curmap;
15449 + break;
15450 +#endif /* BCMJTAG */
15451 +
15452 + default:
15453 + ASSERT(0);
15454 + }
15455 +
15456 + if (!GOODCOREADDR(sbaddr))
15457 + return BADIDX;
15458 +
15459 + return ((sbaddr - SB_ENUM_BASE) / SB_CORE_SIZE);
15460 +}
15461 +
15462 +uint
15463 +sb_corevendor(sb_t *sbh)
15464 +{
15465 + sb_info_t *si;
15466 + sbconfig_t *sb;
15467 +
15468 + si = SB_INFO(sbh);
15469 + sb = REGS2SB(si->curmap);
15470 +
15471 + return ((R_SBREG(si, &(sb)->sbidhigh) & SBIDH_VC_MASK) >> SBIDH_VC_SHIFT);
15472 +}
15473 +
15474 +uint
15475 +sb_corerev(sb_t *sbh)
15476 +{
15477 + sb_info_t *si;
15478 + sbconfig_t *sb;
15479 + uint sbidh;
15480 +
15481 + si = SB_INFO(sbh);
15482 + sb = REGS2SB(si->curmap);
15483 + sbidh = R_SBREG(si, &(sb)->sbidhigh);
15484 +
15485 + return (SBCOREREV(sbidh));
15486 +}
15487 +
15488 +void *
15489 +sb_osh(sb_t *sbh)
15490 +{
15491 + sb_info_t *si;
15492 +
15493 + si = SB_INFO(sbh);
15494 + return si->osh;
15495 +}
15496 +
15497 +#define SBTML_ALLOW (SBTML_PE | SBTML_FGC | SBTML_FL_MASK)
15498 +
15499 +/* set/clear sbtmstatelow core-specific flags */
15500 +uint32
15501 +sb_coreflags(sb_t *sbh, uint32 mask, uint32 val)
15502 +{
15503 + sb_info_t *si;
15504 + sbconfig_t *sb;
15505 + uint32 w;
15506 +
15507 + si = SB_INFO(sbh);
15508 + sb = REGS2SB(si->curmap);
15509 +
15510 + ASSERT((val & ~mask) == 0);
15511 + ASSERT((mask & ~SBTML_ALLOW) == 0);
15512 +
15513 + /* mask and set */
15514 + if (mask || val) {
15515 + w = (R_SBREG(si, &sb->sbtmstatelow) & ~mask) | val;
15516 + W_SBREG(si, &sb->sbtmstatelow, w);
15517 + }
15518 +
15519 + /* return the new value */
15520 + return (R_SBREG(si, &sb->sbtmstatelow) & SBTML_ALLOW);
15521 +}
15522 +
15523 +/* set/clear sbtmstatehigh core-specific flags */
15524 +uint32
15525 +sb_coreflagshi(sb_t *sbh, uint32 mask, uint32 val)
15526 +{
15527 + sb_info_t *si;
15528 + sbconfig_t *sb;
15529 + uint32 w;
15530 +
15531 + si = SB_INFO(sbh);
15532 + sb = REGS2SB(si->curmap);
15533 +
15534 + ASSERT((val & ~mask) == 0);
15535 + ASSERT((mask & ~SBTMH_FL_MASK) == 0);
15536 +
15537 + /* mask and set */
15538 + if (mask || val) {
15539 + w = (R_SBREG(si, &sb->sbtmstatehigh) & ~mask) | val;
15540 + W_SBREG(si, &sb->sbtmstatehigh, w);
15541 + }
15542 +
15543 + /* return the new value */
15544 + return (R_SBREG(si, &sb->sbtmstatehigh) & SBTMH_FL_MASK);
15545 +}
15546 +
15547 +/* caller needs to take care of core-specific bist hazards */
15548 +int
15549 +sb_corebist(sb_t *sbh, uint coreid, uint coreunit)
15550 +{
15551 + uint32 sblo;
15552 + uint coreidx;
15553 + sb_info_t *si;
15554 + int result = 0;
15555 +
15556 + si = SB_INFO(sbh);
15557 +
15558 + coreidx = sb_findcoreidx(si, coreid, coreunit);
15559 + if (!GOODIDX(coreidx))
15560 + result = BCME_ERROR;
15561 + else {
15562 + sblo = sb_corereg(si, coreidx, SBCONFIGOFF + OFFSETOF(sbconfig_t, sbtmstatelow), 0, 0);
15563 + sb_corereg(si, coreidx, SBCONFIGOFF + OFFSETOF(sbconfig_t, sbtmstatelow), ~0, (sblo | SBTML_FGC | SBTML_BE));
15564 +
15565 + SPINWAIT(((sb_corereg(si, coreidx, SBCONFIGOFF + OFFSETOF(sbconfig_t, sbtmstatehigh), 0, 0) & SBTMH_BISTD) == 0), 100000);
15566 +
15567 + if (sb_corereg(si, coreidx, SBCONFIGOFF + OFFSETOF(sbconfig_t, sbtmstatehigh), 0, 0) & SBTMH_BISTF)
15568 + result = BCME_ERROR;
15569 +
15570 + sb_corereg(si, coreidx, SBCONFIGOFF + OFFSETOF(sbconfig_t, sbtmstatelow), ~0, sblo);
15571 + }
15572 +
15573 + return result;
15574 +}
15575 +
15576 +bool
15577 +sb_iscoreup(sb_t *sbh)
15578 +{
15579 + sb_info_t *si;
15580 + sbconfig_t *sb;
15581 +
15582 + si = SB_INFO(sbh);
15583 + sb = REGS2SB(si->curmap);
15584 +
15585 + return ((R_SBREG(si, &(sb)->sbtmstatelow) & (SBTML_RESET | SBTML_REJ_MASK | SBTML_CLK)) == SBTML_CLK);
15586 +}
15587 +
15588 +/*
15589 + * Switch to 'coreidx', issue a single arbitrary 32bit register mask&set operation,
15590 + * switch back to the original core, and return the new value.
15591 + */
15592 +static uint
15593 +sb_corereg(sb_info_t *si, uint coreidx, uint regoff, uint mask, uint val)
15594 +{
15595 + uint origidx;
15596 + uint32 *r;
15597 + uint w;
15598 + uint intr_val = 0;
15599 +
15600 + ASSERT(GOODIDX(coreidx));
15601 + ASSERT(regoff < SB_CORE_SIZE);
15602 + ASSERT((val & ~mask) == 0);
15603 +
15604 + INTR_OFF(si, intr_val);
15605 +
15606 + /* save current core index */
15607 + origidx = sb_coreidx(&si->sb);
15608 +
15609 + /* switch core */
15610 + r = (uint32*) ((uchar*) sb_setcoreidx(&si->sb, coreidx) + regoff);
15611 +
15612 + /* mask and set */
15613 + if (mask || val) {
15614 + if (regoff >= SBCONFIGOFF) {
15615 + w = (R_SBREG(si, r) & ~mask) | val;
15616 + W_SBREG(si, r, w);
15617 + } else {
15618 + w = (R_REG(r) & ~mask) | val;
15619 + W_REG(r, w);
15620 + }
15621 + }
15622 +
15623 + /* readback */
15624 + if (regoff >= SBCONFIGOFF)
15625 + w = R_SBREG(si, r);
15626 + else
15627 + w = R_REG(r);
15628 +
15629 + /* restore core index */
15630 + if (origidx != coreidx)
15631 + sb_setcoreidx(&si->sb, origidx);
15632 +
15633 + INTR_RESTORE(si, intr_val);
15634 + return (w);
15635 +}
15636 +
15637 +#define DWORD_ALIGN(x) (x & ~(0x03))
15638 +#define BYTE_POS(x) (x & 0x3)
15639 +#define WORD_POS(x) (x & 0x1)
15640 +
15641 +#define BYTE_SHIFT(x) (8 * BYTE_POS(x))
15642 +#define WORD_SHIFT(x) (16 * WORD_POS(x))
15643 +
15644 +#define BYTE_VAL(a, x) ((a >> BYTE_SHIFT(x)) & 0xFF)
15645 +#define WORD_VAL(a, x) ((a >> WORD_SHIFT(x)) & 0xFFFF)
15646 +
15647 +#define read_pci_cfg_byte(a) \
15648 + (BYTE_VAL(OSL_PCI_READ_CONFIG(si->osh, DWORD_ALIGN(a), 4), a) & 0xff)
15649 +
15650 +#define read_pci_cfg_write(a) \
15651 + (WORD_VAL(OSL_PCI_READ_CONFIG(si->osh, DWORD_ALIGN(a), 4), a) & 0xffff)
15652 +
15653 +
15654 +/* return TRUE if requested capability exists in the PCI config space */
15655 +static bool
15656 +sb_find_pci_capability(sb_info_t *si, uint8 req_cap_id, uchar *buf, uint32 *buflen)
15657 +{
15658 + uint8 cap_id;
15659 + uint8 cap_ptr;
15660 + uint32 bufsize;
15661 + uint8 byte_val;
15662 +
15663 + if (BUSTYPE(si->sb.bustype) != PCI_BUS)
15664 + return FALSE;
15665 +
15666 + /* check for Header type 0*/
15667 + byte_val = read_pci_cfg_byte(PCI_CFG_HDR);
15668 + if ((byte_val & 0x7f) != PCI_HEADER_NORMAL)
15669 + return FALSE;
15670 +
15671 + /* check if the capability pointer field exists */
15672 + byte_val = read_pci_cfg_byte(PCI_CFG_STAT);
15673 + if (!(byte_val & PCI_CAPPTR_PRESENT))
15674 + return FALSE;
15675 +
15676 + cap_ptr = read_pci_cfg_byte(PCI_CFG_CAPPTR);
15677 + /* check if the capability pointer is 0x00 */
15678 + if (cap_ptr == 0x00)
15679 + return FALSE;
15680 +
15681 +
15682 + /* loop thr'u the capability list and see if the pcie capabilty exists */
15683 +
15684 + cap_id = read_pci_cfg_byte(cap_ptr);
15685 +
15686 + while (cap_id != req_cap_id) {
15687 + cap_ptr = read_pci_cfg_byte((cap_ptr+1));
15688 + if (cap_ptr == 0x00) break;
15689 + cap_id = read_pci_cfg_byte(cap_ptr);
15690 + }
15691 + if (cap_id != req_cap_id) {
15692 + return FALSE;
15693 + }
15694 + /* found the caller requested capability */
15695 + if ((buf != NULL) && (buflen != NULL)) {
15696 + bufsize = *buflen;
15697 + if (!bufsize) goto end;
15698 + *buflen = 0;
15699 + /* copy the cpability data excluding cap ID and next ptr */
15700 + cap_ptr += 2;
15701 + if ((bufsize + cap_ptr) > SZPCR)
15702 + bufsize = SZPCR - cap_ptr;
15703 + *buflen = bufsize;
15704 + while (bufsize--) {
15705 + *buf = read_pci_cfg_byte(cap_ptr);
15706 + cap_ptr++;
15707 + buf++;
15708 + }
15709 + }
15710 +end:
15711 + return TRUE;
15712 +}
15713 +
15714 +/* return TRUE if PCIE capability exists the pci config space */
15715 +static bool
15716 +sb_ispcie(sb_info_t *si)
15717 +{
15718 + return(sb_find_pci_capability(si, PCI_CAP_PCIECAP_ID, NULL, NULL));
15719 +}
15720 +
15721 +/* scan the sb enumerated space to identify all cores */
15722 +static void
15723 +BCMINITFN(sb_scan)(sb_info_t *si)
15724 +{
15725 + uint origidx;
15726 + uint i;
15727 + bool pci;
15728 + bool pcie;
15729 + uint pciidx;
15730 + uint pcieidx;
15731 + uint pcirev;
15732 + uint pcierev;
15733 +
15734 +
15735 +
15736 + /* numcores should already be set */
15737 + ASSERT((si->numcores > 0) && (si->numcores <= SB_MAXCORES));
15738 +
15739 + /* save current core index */
15740 + origidx = sb_coreidx(&si->sb);
15741 +
15742 + si->sb.buscorerev = NOREV;
15743 + si->sb.buscoreidx = BADIDX;
15744 +
15745 + si->gpioidx = BADIDX;
15746 +
15747 + pci = pcie = FALSE;
15748 + pcirev = pcierev = NOREV;
15749 + pciidx = pcieidx = BADIDX;
15750 +
15751 + for (i = 0; i < si->numcores; i++) {
15752 + sb_setcoreidx(&si->sb, i);
15753 + si->coreid[i] = sb_coreid(&si->sb);
15754 +
15755 + if (si->coreid[i] == SB_PCI) {
15756 + pciidx = i;
15757 + pcirev = sb_corerev(&si->sb);
15758 + pci = TRUE;
15759 + } else if (si->coreid[i] == SB_PCIE) {
15760 + pcieidx = i;
15761 + pcierev = sb_corerev(&si->sb);
15762 + pcie = TRUE;
15763 + } else if (si->coreid[i] == SB_PCMCIA) {
15764 + si->sb.buscorerev = sb_corerev(&si->sb);
15765 + si->sb.buscoretype = si->coreid[i];
15766 + si->sb.buscoreidx = i;
15767 + }
15768 + }
15769 + if (pci && pcie) {
15770 + if (sb_ispcie(si))
15771 + pci = FALSE;
15772 + else
15773 + pcie = FALSE;
15774 + }
15775 + if (pci) {
15776 + si->sb.buscoretype = SB_PCI;
15777 + si->sb.buscorerev = pcirev;
15778 + si->sb.buscoreidx = pciidx;
15779 + }
15780 + else if (pcie) {
15781 + si->sb.buscoretype = SB_PCIE;
15782 + si->sb.buscorerev = pcierev;
15783 + si->sb.buscoreidx = pcieidx;
15784 + }
15785 +
15786 + /*
15787 + * Find the gpio "controlling core" type and index.
15788 + * Precedence:
15789 + * - if there's a chip common core - use that
15790 + * - else if there's a pci core (rev >= 2) - use that
15791 + * - else there had better be an extif core (4710 only)
15792 + */
15793 + if (GOODIDX(sb_findcoreidx(si, SB_CC, 0))) {
15794 + si->gpioidx = sb_findcoreidx(si, SB_CC, 0);
15795 + si->gpioid = SB_CC;
15796 + } else if (PCI(si) && (si->sb.buscorerev >= 2)) {
15797 + si->gpioidx = si->sb.buscoreidx;
15798 + si->gpioid = SB_PCI;
15799 + } else if (sb_findcoreidx(si, SB_EXTIF, 0)) {
15800 + si->gpioidx = sb_findcoreidx(si, SB_EXTIF, 0);
15801 + si->gpioid = SB_EXTIF;
15802 + } else
15803 + ASSERT(si->gpioidx != BADIDX);
15804 +
15805 + /* return to original core index */
15806 + sb_setcoreidx(&si->sb, origidx);
15807 +}
15808 +
15809 +/* may be called with core in reset */
15810 +void
15811 +sb_detach(sb_t *sbh)
15812 +{
15813 + sb_info_t *si;
15814 + uint idx;
15815 +
15816 + si = SB_INFO(sbh);
15817 +
15818 + if (si == NULL)
15819 + return;
15820 +
15821 + if (BUSTYPE(si->sb.bustype) == SB_BUS)
15822 + for (idx = 0; idx < SB_MAXCORES; idx++)
15823 + if (si->regs[idx]) {
15824 + REG_UNMAP(si->regs[idx]);
15825 + si->regs[idx] = NULL;
15826 + }
15827 +
15828 + if (si != &ksi)
15829 + MFREE(si->osh, si, sizeof (sb_info_t));
15830 +}
15831 +
15832 +/* use pci dev id to determine chip id for chips not having a chipcommon core */
15833 +static uint
15834 +BCMINITFN(sb_pcidev2chip)(uint pcidev)
15835 +{
15836 + if ((pcidev >= BCM4710_DEVICE_ID) && (pcidev <= BCM47XX_USB_ID))
15837 + return (BCM4710_DEVICE_ID);
15838 + if ((pcidev >= BCM4402_DEVICE_ID) && (pcidev <= BCM4402_V90_ID))
15839 + return (BCM4402_DEVICE_ID);
15840 + if (pcidev == BCM4401_ENET_ID)
15841 + return (BCM4402_DEVICE_ID);
15842 + if ((pcidev >= BCM4307_V90_ID) && (pcidev <= BCM4307_D11B_ID))
15843 + return (BCM4307_DEVICE_ID);
15844 + if (pcidev == BCM4301_DEVICE_ID)
15845 + return (BCM4301_DEVICE_ID);
15846 +
15847 + return (0);
15848 +}
15849 +
15850 +/* convert chip number to number of i/o cores */
15851 +static uint
15852 +BCMINITFN(sb_chip2numcores)(uint chip)
15853 +{
15854 + if (chip == BCM4710_DEVICE_ID)
15855 + return (9);
15856 + if (chip == BCM4402_DEVICE_ID)
15857 + return (3);
15858 + if ((chip == BCM4301_DEVICE_ID) || (chip == BCM4307_DEVICE_ID))
15859 + return (5);
15860 + if (chip == BCM4306_DEVICE_ID) /* < 4306c0 */
15861 + return (6);
15862 + if (chip == BCM4704_DEVICE_ID)
15863 + return (9);
15864 + if (chip == BCM5365_DEVICE_ID)
15865 + return (7);
15866 +
15867 + SB_ERROR(("sb_chip2numcores: unsupported chip 0x%x\n", chip));
15868 + ASSERT(0);
15869 + return (1);
15870 +}
15871 +
15872 +/* return index of coreid or BADIDX if not found */
15873 +static uint
15874 +sb_findcoreidx( sb_info_t *si, uint coreid, uint coreunit)
15875 +{
15876 + uint found;
15877 + uint i;
15878 +
15879 + found = 0;
15880 +
15881 + for (i = 0; i < si->numcores; i++)
15882 + if (si->coreid[i] == coreid) {
15883 + if (found == coreunit)
15884 + return (i);
15885 + found++;
15886 + }
15887 +
15888 + return (BADIDX);
15889 +}
15890 +
15891 +/*
15892 + * this function changes logical "focus" to the indiciated core,
15893 + * must be called with interrupt off.
15894 + * Moreover, callers should keep interrupts off during switching out of and back to d11 core
15895 + */
15896 +void*
15897 +sb_setcoreidx(sb_t *sbh, uint coreidx)
15898 +{
15899 + sb_info_t *si;
15900 + uint32 sbaddr;
15901 + uint8 tmp;
15902 +
15903 + si = SB_INFO(sbh);
15904 +
15905 + if (coreidx >= si->numcores)
15906 + return (NULL);
15907 +
15908 + /*
15909 + * If the user has provided an interrupt mask enabled function,
15910 + * then assert interrupts are disabled before switching the core.
15911 + */
15912 + ASSERT((si->intrsenabled_fn == NULL) || !(*(si)->intrsenabled_fn)((si)->intr_arg));
15913 +
15914 + sbaddr = SB_ENUM_BASE + (coreidx * SB_CORE_SIZE);
15915 +
15916 + switch (BUSTYPE(si->sb.bustype)) {
15917 + case SB_BUS:
15918 + /* map new one */
15919 + if (!si->regs[coreidx]) {
15920 + si->regs[coreidx] = (void*)REG_MAP(sbaddr, SB_CORE_SIZE);
15921 + ASSERT(GOODREGS(si->regs[coreidx]));
15922 + }
15923 + si->curmap = si->regs[coreidx];
15924 + break;
15925 +
15926 + case PCI_BUS:
15927 + /* point bar0 window */
15928 + OSL_PCI_WRITE_CONFIG(si->osh, PCI_BAR0_WIN, 4, sbaddr);
15929 + break;
15930 +
15931 + case PCMCIA_BUS:
15932 + tmp = (sbaddr >> 12) & 0x0f;
15933 + OSL_PCMCIA_WRITE_ATTR(si->osh, PCMCIA_ADDR0, &tmp, 1);
15934 + tmp = (sbaddr >> 16) & 0xff;
15935 + OSL_PCMCIA_WRITE_ATTR(si->osh, PCMCIA_ADDR1, &tmp, 1);
15936 + tmp = (sbaddr >> 24) & 0xff;
15937 + OSL_PCMCIA_WRITE_ATTR(si->osh, PCMCIA_ADDR2, &tmp, 1);
15938 + break;
15939 +#ifdef BCMJTAG
15940 + case JTAG_BUS:
15941 + /* map new one */
15942 + if (!si->regs[coreidx]) {
15943 + si->regs[coreidx] = (void *)sbaddr;
15944 + ASSERT(GOODREGS(si->regs[coreidx]));
15945 + }
15946 + si->curmap = si->regs[coreidx];
15947 + break;
15948 +#endif /* BCMJTAG */
15949 + }
15950 +
15951 + si->curidx = coreidx;
15952 +
15953 + return (si->curmap);
15954 +}
15955 +
15956 +/*
15957 + * this function changes logical "focus" to the indiciated core,
15958 + * must be called with interrupt off.
15959 + * Moreover, callers should keep interrupts off during switching out of and back to d11 core
15960 + */
15961 +void*
15962 +sb_setcore(sb_t *sbh, uint coreid, uint coreunit)
15963 +{
15964 + sb_info_t *si;
15965 + uint idx;
15966 +
15967 + si = SB_INFO(sbh);
15968 + idx = sb_findcoreidx(si, coreid, coreunit);
15969 + if (!GOODIDX(idx))
15970 + return (NULL);
15971 +
15972 + return (sb_setcoreidx(sbh, idx));
15973 +}
15974 +
15975 +/* return chip number */
15976 +uint
15977 +BCMINITFN(sb_chip)(sb_t *sbh)
15978 +{
15979 + sb_info_t *si;
15980 +
15981 + si = SB_INFO(sbh);
15982 + return (si->sb.chip);
15983 +}
15984 +
15985 +/* return chip revision number */
15986 +uint
15987 +BCMINITFN(sb_chiprev)(sb_t *sbh)
15988 +{
15989 + sb_info_t *si;
15990 +
15991 + si = SB_INFO(sbh);
15992 + return (si->sb.chiprev);
15993 +}
15994 +
15995 +/* return chip common revision number */
15996 +uint
15997 +BCMINITFN(sb_chipcrev)(sb_t *sbh)
15998 +{
15999 + sb_info_t *si;
16000 +
16001 + si = SB_INFO(sbh);
16002 + return (si->sb.ccrev);
16003 +}
16004 +
16005 +/* return chip package option */
16006 +uint
16007 +BCMINITFN(sb_chippkg)(sb_t *sbh)
16008 +{
16009 + sb_info_t *si;
16010 +
16011 + si = SB_INFO(sbh);
16012 + return (si->sb.chippkg);
16013 +}
16014 +
16015 +/* return PCI core rev. */
16016 +uint
16017 +BCMINITFN(sb_pcirev)(sb_t *sbh)
16018 +{
16019 + sb_info_t *si;
16020 +
16021 + si = SB_INFO(sbh);
16022 + return (si->sb.buscorerev);
16023 +}
16024 +
16025 +bool
16026 +BCMINITFN(sb_war16165)(sb_t *sbh)
16027 +{
16028 + sb_info_t *si;
16029 +
16030 + si = SB_INFO(sbh);
16031 +
16032 + return (PCI(si) && (si->sb.buscorerev <= 10));
16033 +}
16034 +
16035 +static void
16036 +BCMINITFN(sb_war30841)(sb_info_t *si)
16037 +{
16038 + sb_pcie_mdiowrite(si, MDIODATA_DEV_RX, SERDES_RX_TIMER1, 0x8128);
16039 + sb_pcie_mdiowrite(si, MDIODATA_DEV_RX, SERDES_RX_CDR, 0x0100);
16040 + sb_pcie_mdiowrite(si, MDIODATA_DEV_RX, SERDES_RX_CDRBW, 0x1466);
16041 +}
16042 +
16043 +/* return PCMCIA core rev. */
16044 +uint
16045 +BCMINITFN(sb_pcmciarev)(sb_t *sbh)
16046 +{
16047 + sb_info_t *si;
16048 +
16049 + si = SB_INFO(sbh);
16050 + return (si->sb.buscorerev);
16051 +}
16052 +
16053 +/* return board vendor id */
16054 +uint
16055 +BCMINITFN(sb_boardvendor)(sb_t *sbh)
16056 +{
16057 + sb_info_t *si;
16058 +
16059 + si = SB_INFO(sbh);
16060 + return (si->sb.boardvendor);
16061 +}
16062 +
16063 +/* return boardtype */
16064 +uint
16065 +BCMINITFN(sb_boardtype)(sb_t *sbh)
16066 +{
16067 + sb_info_t *si;
16068 + char *var;
16069 +
16070 + si = SB_INFO(sbh);
16071 +
16072 + if (BUSTYPE(si->sb.bustype) == SB_BUS && si->sb.boardtype == 0xffff) {
16073 + /* boardtype format is a hex string */
16074 + si->sb.boardtype = getintvar(NULL, "boardtype");
16075 +
16076 + /* backward compatibility for older boardtype string format */
16077 + if ((si->sb.boardtype == 0) && (var = getvar(NULL, "boardtype"))) {
16078 + if (!strcmp(var, "bcm94710dev"))
16079 + si->sb.boardtype = BCM94710D_BOARD;
16080 + else if (!strcmp(var, "bcm94710ap"))
16081 + si->sb.boardtype = BCM94710AP_BOARD;
16082 + else if (!strcmp(var, "bu4710"))
16083 + si->sb.boardtype = BU4710_BOARD;
16084 + else if (!strcmp(var, "bcm94702mn"))
16085 + si->sb.boardtype = BCM94702MN_BOARD;
16086 + else if (!strcmp(var, "bcm94710r1"))
16087 + si->sb.boardtype = BCM94710R1_BOARD;
16088 + else if (!strcmp(var, "bcm94710r4"))
16089 + si->sb.boardtype = BCM94710R4_BOARD;
16090 + else if (!strcmp(var, "bcm94702cpci"))
16091 + si->sb.boardtype = BCM94702CPCI_BOARD;
16092 + else if (!strcmp(var, "bcm95380_rr"))
16093 + si->sb.boardtype = BCM95380RR_BOARD;
16094 + }
16095 + }
16096 +
16097 + return (si->sb.boardtype);
16098 +}
16099 +
16100 +/* return bus type of sbh device */
16101 +uint
16102 +sb_bus(sb_t *sbh)
16103 +{
16104 + sb_info_t *si;
16105 +
16106 + si = SB_INFO(sbh);
16107 + return (si->sb.bustype);
16108 +}
16109 +
16110 +/* return bus core type */
16111 +uint
16112 +sb_buscoretype(sb_t *sbh)
16113 +{
16114 + sb_info_t *si;
16115 +
16116 + si = SB_INFO(sbh);
16117 +
16118 + return (si->sb.buscoretype);
16119 +}
16120 +
16121 +/* return bus core revision */
16122 +uint
16123 +sb_buscorerev(sb_t *sbh)
16124 +{
16125 + sb_info_t *si;
16126 + si = SB_INFO(sbh);
16127 +
16128 + return (si->sb.buscorerev);
16129 +}
16130 +
16131 +/* return list of found cores */
16132 +uint
16133 +sb_corelist(sb_t *sbh, uint coreid[])
16134 +{
16135 + sb_info_t *si;
16136 +
16137 + si = SB_INFO(sbh);
16138 +
16139 + bcopy((uchar*)si->coreid, (uchar*)coreid, (si->numcores * sizeof (uint)));
16140 + return (si->numcores);
16141 +}
16142 +
16143 +/* return current register mapping */
16144 +void *
16145 +sb_coreregs(sb_t *sbh)
16146 +{
16147 + sb_info_t *si;
16148 +
16149 + si = SB_INFO(sbh);
16150 + ASSERT(GOODREGS(si->curmap));
16151 +
16152 + return (si->curmap);
16153 +}
16154 +
16155 +
16156 +/* do buffered registers update */
16157 +void
16158 +sb_commit(sb_t *sbh)
16159 +{
16160 + sb_info_t *si;
16161 + uint origidx;
16162 + uint intr_val = 0;
16163 +
16164 + si = SB_INFO(sbh);
16165 +
16166 + origidx = si->curidx;
16167 + ASSERT(GOODIDX(origidx));
16168 +
16169 + INTR_OFF(si, intr_val);
16170 +
16171 + /* switch over to chipcommon core if there is one, else use pci */
16172 + if (si->sb.ccrev != NOREV) {
16173 + chipcregs_t *ccregs = (chipcregs_t *)sb_setcore(sbh, SB_CC, 0);
16174 +
16175 + /* do the buffer registers update */
16176 + W_REG(&ccregs->broadcastaddress, SB_COMMIT);
16177 + W_REG(&ccregs->broadcastdata, 0x0);
16178 + } else if (PCI(si)) {
16179 + sbpciregs_t *pciregs = (sbpciregs_t *)sb_setcore(sbh, SB_PCI, 0);
16180 +
16181 + /* do the buffer registers update */
16182 + W_REG(&pciregs->bcastaddr, SB_COMMIT);
16183 + W_REG(&pciregs->bcastdata, 0x0);
16184 + } else
16185 + ASSERT(0);
16186 +
16187 + /* restore core index */
16188 + sb_setcoreidx(sbh, origidx);
16189 + INTR_RESTORE(si, intr_val);
16190 +}
16191 +
16192 +/* reset and re-enable a core */
16193 +void
16194 +sb_core_reset(sb_t *sbh, uint32 bits)
16195 +{
16196 + sb_info_t *si;
16197 + sbconfig_t *sb;
16198 + volatile uint32 dummy;
16199 +
16200 + si = SB_INFO(sbh);
16201 + ASSERT(GOODREGS(si->curmap));
16202 + sb = REGS2SB(si->curmap);
16203 +
16204 + /*
16205 + * Must do the disable sequence first to work for arbitrary current core state.
16206 + */
16207 + sb_core_disable(sbh, bits);
16208 +
16209 + /*
16210 + * Now do the initialization sequence.
16211 + */
16212 +
16213 + /* set reset while enabling the clock and forcing them on throughout the core */
16214 + W_SBREG(si, &sb->sbtmstatelow, (SBTML_FGC | SBTML_CLK | SBTML_RESET | bits));
16215 + dummy = R_SBREG(si, &sb->sbtmstatelow);
16216 + OSL_DELAY(1);
16217 +
16218 + if (R_SBREG(si, &sb->sbtmstatehigh) & SBTMH_SERR) {
16219 + W_SBREG(si, &sb->sbtmstatehigh, 0);
16220 + }
16221 + if ((dummy = R_SBREG(si, &sb->sbimstate)) & (SBIM_IBE | SBIM_TO)) {
16222 + AND_SBREG(si, &sb->sbimstate, ~(SBIM_IBE | SBIM_TO));
16223 + }
16224 +
16225 + /* clear reset and allow it to propagate throughout the core */
16226 + W_SBREG(si, &sb->sbtmstatelow, (SBTML_FGC | SBTML_CLK | bits));
16227 + dummy = R_SBREG(si, &sb->sbtmstatelow);
16228 + OSL_DELAY(1);
16229 +
16230 + /* leave clock enabled */
16231 + W_SBREG(si, &sb->sbtmstatelow, (SBTML_CLK | bits));
16232 + dummy = R_SBREG(si, &sb->sbtmstatelow);
16233 + OSL_DELAY(1);
16234 +}
16235 +
16236 +void
16237 +sb_core_tofixup(sb_t *sbh)
16238 +{
16239 + sb_info_t *si;
16240 + sbconfig_t *sb;
16241 +
16242 + si = SB_INFO(sbh);
16243 +
16244 + if ( (BUSTYPE(si->sb.bustype) != PCI_BUS) || PCIE(si) || (PCI(si) && (si->sb.buscorerev >= 5)) )
16245 + return;
16246 +
16247 + ASSERT(GOODREGS(si->curmap));
16248 + sb = REGS2SB(si->curmap);
16249 +
16250 + if (BUSTYPE(si->sb.bustype) == SB_BUS) {
16251 + SET_SBREG(si, &sb->sbimconfiglow,
16252 + SBIMCL_RTO_MASK | SBIMCL_STO_MASK,
16253 + (0x5 << SBIMCL_RTO_SHIFT) | 0x3);
16254 + } else {
16255 + if (sb_coreid(sbh) == SB_PCI) {
16256 + SET_SBREG(si, &sb->sbimconfiglow,
16257 + SBIMCL_RTO_MASK | SBIMCL_STO_MASK,
16258 + (0x3 << SBIMCL_RTO_SHIFT) | 0x2);
16259 + } else {
16260 + SET_SBREG(si, &sb->sbimconfiglow, (SBIMCL_RTO_MASK | SBIMCL_STO_MASK), 0);
16261 + }
16262 + }
16263 +
16264 + sb_commit(sbh);
16265 +}
16266 +
16267 +/*
16268 + * Set the initiator timeout for the "master core".
16269 + * The master core is defined to be the core in control
16270 + * of the chip and so it issues accesses to non-memory
16271 + * locations (Because of dma *any* core can access memeory).
16272 + *
16273 + * The routine uses the bus to decide who is the master:
16274 + * SB_BUS => mips
16275 + * JTAG_BUS => chipc
16276 + * PCI_BUS => pci or pcie
16277 + * PCMCIA_BUS => pcmcia
16278 + * SDIO_BUS => pcmcia
16279 + *
16280 + * This routine exists so callers can disable initiator
16281 + * timeouts so accesses to very slow devices like otp
16282 + * won't cause an abort. The routine allows arbitrary
16283 + * settings of the service and request timeouts, though.
16284 + *
16285 + * Returns the timeout state before changing it or -1
16286 + * on error.
16287 + */
16288 +
16289 +#define TO_MASK (SBIMCL_RTO_MASK | SBIMCL_STO_MASK)
16290 +
16291 +uint32
16292 +sb_set_initiator_to(sb_t *sbh, uint32 to)
16293 +{
16294 + sb_info_t *si;
16295 + uint origidx, idx;
16296 + uint intr_val = 0;
16297 + uint32 tmp, ret = 0xffffffff;
16298 + sbconfig_t *sb;
16299 +
16300 + si = SB_INFO(sbh);
16301 +
16302 + if ((to & ~TO_MASK) != 0)
16303 + return ret;
16304 +
16305 + /* Figure out the master core */
16306 + idx = BADIDX;
16307 + switch (BUSTYPE(si->sb.bustype)) {
16308 + case PCI_BUS:
16309 + idx = si->sb.buscoreidx;
16310 + break;
16311 + case JTAG_BUS:
16312 + idx = SB_CC_IDX;
16313 + break;
16314 + case PCMCIA_BUS:
16315 + case SDIO_BUS:
16316 + idx = sb_findcoreidx(si, SB_PCMCIA, 0);
16317 + break;
16318 + case SB_BUS:
16319 + if ((idx = sb_findcoreidx(si, SB_MIPS33, 0)) == BADIDX)
16320 + idx = sb_findcoreidx(si, SB_MIPS, 0);
16321 + break;
16322 + default:
16323 + ASSERT(0);
16324 + }
16325 + if (idx == BADIDX)
16326 + return ret;
16327 +
16328 + INTR_OFF(si, intr_val);
16329 + origidx = sb_coreidx(sbh);
16330 +
16331 + sb = REGS2SB(sb_setcoreidx(sbh, idx));
16332 +
16333 + tmp = R_SBREG(si, &sb->sbimconfiglow);
16334 + ret = tmp & TO_MASK;
16335 + W_SBREG(si, &sb->sbimconfiglow, (tmp & ~TO_MASK) | to);
16336 +
16337 + sb_commit(sbh);
16338 + sb_setcoreidx(sbh, origidx);
16339 + INTR_RESTORE(si, intr_val);
16340 + return ret;
16341 +}
16342 +
16343 +void
16344 +sb_core_disable(sb_t *sbh, uint32 bits)
16345 +{
16346 + sb_info_t *si;
16347 + volatile uint32 dummy;
16348 + uint32 rej;
16349 + sbconfig_t *sb;
16350 +
16351 + si = SB_INFO(sbh);
16352 +
16353 + ASSERT(GOODREGS(si->curmap));
16354 + sb = REGS2SB(si->curmap);
16355 +
16356 + /* if core is already in reset, just return */
16357 + if (R_SBREG(si, &sb->sbtmstatelow) & SBTML_RESET)
16358 + return;
16359 +
16360 + /* reject value changed between sonics 2.2 and 2.3 */
16361 + if (si->sb.sonicsrev == SONICS_2_2)
16362 + rej = (1 << SBTML_REJ_SHIFT);
16363 + else
16364 + rej = (2 << SBTML_REJ_SHIFT);
16365 +
16366 + /* if clocks are not enabled, put into reset and return */
16367 + if ((R_SBREG(si, &sb->sbtmstatelow) & SBTML_CLK) == 0)
16368 + goto disable;
16369 +
16370 + /* set target reject and spin until busy is clear (preserve core-specific bits) */
16371 + OR_SBREG(si, &sb->sbtmstatelow, rej);
16372 + dummy = R_SBREG(si, &sb->sbtmstatelow);
16373 + OSL_DELAY(1);
16374 + SPINWAIT((R_SBREG(si, &sb->sbtmstatehigh) & SBTMH_BUSY), 100000);
16375 +
16376 + if (R_SBREG(si, &sb->sbidlow) & SBIDL_INIT) {
16377 + OR_SBREG(si, &sb->sbimstate, SBIM_RJ);
16378 + dummy = R_SBREG(si, &sb->sbimstate);
16379 + OSL_DELAY(1);
16380 + SPINWAIT((R_SBREG(si, &sb->sbimstate) & SBIM_BY), 100000);
16381 + }
16382 +
16383 + /* set reset and reject while enabling the clocks */
16384 + W_SBREG(si, &sb->sbtmstatelow, (bits | SBTML_FGC | SBTML_CLK | rej | SBTML_RESET));
16385 + dummy = R_SBREG(si, &sb->sbtmstatelow);
16386 + OSL_DELAY(10);
16387 +
16388 + /* don't forget to clear the initiator reject bit */
16389 + if (R_SBREG(si, &sb->sbidlow) & SBIDL_INIT)
16390 + AND_SBREG(si, &sb->sbimstate, ~SBIM_RJ);
16391 +
16392 +disable:
16393 + /* leave reset and reject asserted */
16394 + W_SBREG(si, &sb->sbtmstatelow, (bits | rej | SBTML_RESET));
16395 + OSL_DELAY(1);
16396 +}
16397 +
16398 +/* set chip watchdog reset timer to fire in 'ticks' backplane cycles */
16399 +void
16400 +sb_watchdog(sb_t *sbh, uint ticks)
16401 +{
16402 + sb_info_t *si = SB_INFO(sbh);
16403 +
16404 + /* instant NMI */
16405 + switch (si->gpioid) {
16406 + case SB_CC:
16407 + sb_corereg(si, 0, OFFSETOF(chipcregs_t, watchdog), ~0, ticks);
16408 + break;
16409 + case SB_EXTIF:
16410 + sb_corereg(si, si->gpioidx, OFFSETOF(extifregs_t, watchdog), ~0, ticks);
16411 + break;
16412 + }
16413 +}
16414 +
16415 +/* initialize the pcmcia core */
16416 +void
16417 +sb_pcmcia_init(sb_t *sbh)
16418 +{
16419 + sb_info_t *si;
16420 + uint8 cor;
16421 +
16422 + si = SB_INFO(sbh);
16423 +
16424 + /* enable d11 mac interrupts */
16425 + if (si->sb.chip == BCM4301_DEVICE_ID) {
16426 + /* Have to use FCR2 in 4301 */
16427 + OSL_PCMCIA_READ_ATTR(si->osh, PCMCIA_FCR2 + PCMCIA_COR, &cor, 1);
16428 + cor |= COR_IRQEN | COR_FUNEN;
16429 + OSL_PCMCIA_WRITE_ATTR(si->osh, PCMCIA_FCR2 + PCMCIA_COR, &cor, 1);
16430 + } else {
16431 + OSL_PCMCIA_READ_ATTR(si->osh, PCMCIA_FCR0 + PCMCIA_COR, &cor, 1);
16432 + cor |= COR_IRQEN | COR_FUNEN;
16433 + OSL_PCMCIA_WRITE_ATTR(si->osh, PCMCIA_FCR0 + PCMCIA_COR, &cor, 1);
16434 + }
16435 +
16436 +}
16437 +
16438 +
16439 +/*
16440 + * Configure the pci core for pci client (NIC) action
16441 + * coremask is the bitvec of cores by index to be enabled.
16442 + */
16443 +void
16444 +sb_pci_setup(sb_t *sbh, uint coremask)
16445 +{
16446 + sb_info_t *si;
16447 + sbconfig_t *sb;
16448 + sbpciregs_t *pciregs;
16449 + uint32 sbflag;
16450 + uint32 w;
16451 + uint idx;
16452 + int reg_val;
16453 +
16454 + si = SB_INFO(sbh);
16455 +
16456 + /* if not pci bus, we're done */
16457 + if (BUSTYPE(si->sb.bustype) != PCI_BUS)
16458 + return;
16459 +
16460 + ASSERT(PCI(si) || PCIE(si));
16461 + ASSERT(si->sb.buscoreidx != BADIDX);
16462 +
16463 + /* get current core index */
16464 + idx = si->curidx;
16465 +
16466 + /* we interrupt on this backplane flag number */
16467 + ASSERT(GOODREGS(si->curmap));
16468 + sb = REGS2SB(si->curmap);
16469 + sbflag = R_SBREG(si, &sb->sbtpsflag) & SBTPS_NUM0_MASK;
16470 +
16471 + /* switch over to pci core */
16472 + pciregs = (sbpciregs_t*) sb_setcoreidx(sbh, si->sb.buscoreidx);
16473 + sb = REGS2SB(pciregs);
16474 +
16475 + /*
16476 + * Enable sb->pci interrupts. Assume
16477 + * PCI rev 2.3 support was added in pci core rev 6 and things changed..
16478 + */
16479 + if (PCIE(si) || (PCI(si) && ((si->sb.buscorerev) >= 6))) {
16480 + /* pci config write to set this core bit in PCIIntMask */
16481 + w = OSL_PCI_READ_CONFIG(si->osh, PCI_INT_MASK, sizeof(uint32));
16482 + w |= (coremask << PCI_SBIM_SHIFT);
16483 + OSL_PCI_WRITE_CONFIG(si->osh, PCI_INT_MASK, sizeof(uint32), w);
16484 + } else {
16485 + /* set sbintvec bit for our flag number */
16486 + OR_SBREG(si, &sb->sbintvec, (1 << sbflag));
16487 + }
16488 +
16489 + if (PCI(si)) {
16490 + OR_REG(&pciregs->sbtopci2, (SBTOPCI_PREF|SBTOPCI_BURST));
16491 + if (si->sb.buscorerev >= 11)
16492 + OR_REG(&pciregs->sbtopci2, SBTOPCI_RC_READMULTI);
16493 + if (si->sb.buscorerev < 5) {
16494 + SET_SBREG(si, &sb->sbimconfiglow, SBIMCL_RTO_MASK | SBIMCL_STO_MASK,
16495 + (0x3 << SBIMCL_RTO_SHIFT) | 0x2);
16496 + sb_commit(sbh);
16497 + }
16498 + }
16499 +
16500 + if (PCIE(si) && (si->sb.buscorerev == 0)) {
16501 + reg_val = sb_pcie_readreg((void *)sbh, (void *)PCIE_PCIEREGS, PCIE_TLP_WORKAROUNDSREG);
16502 + reg_val |= 0x8;
16503 + sb_pcie_writereg((void *)sbh, (void *)PCIE_PCIEREGS, PCIE_TLP_WORKAROUNDSREG, reg_val);
16504 +
16505 + reg_val = sb_pcie_readreg((void *)sbh, (void *)PCIE_PCIEREGS, PCIE_DLLP_LCREG);
16506 + reg_val &= ~(0x40);
16507 + sb_pcie_writereg(sbh, (void *)PCIE_PCIEREGS, PCIE_DLLP_LCREG, reg_val);
16508 +
16509 + BCMINIT(sb_war30841)(si);
16510 + }
16511 +
16512 + /* switch back to previous core */
16513 + sb_setcoreidx(sbh, idx);
16514 +}
16515 +
16516 +uint32
16517 +sb_base(uint32 admatch)
16518 +{
16519 + uint32 base;
16520 + uint type;
16521 +
16522 + type = admatch & SBAM_TYPE_MASK;
16523 + ASSERT(type < 3);
16524 +
16525 + base = 0;
16526 +
16527 + if (type == 0) {
16528 + base = admatch & SBAM_BASE0_MASK;
16529 + } else if (type == 1) {
16530 + ASSERT(!(admatch & SBAM_ADNEG)); /* neg not supported */
16531 + base = admatch & SBAM_BASE1_MASK;
16532 + } else if (type == 2) {
16533 + ASSERT(!(admatch & SBAM_ADNEG)); /* neg not supported */
16534 + base = admatch & SBAM_BASE2_MASK;
16535 + }
16536 +
16537 + return (base);
16538 +}
16539 +
16540 +uint32
16541 +sb_size(uint32 admatch)
16542 +{
16543 + uint32 size;
16544 + uint type;
16545 +
16546 + type = admatch & SBAM_TYPE_MASK;
16547 + ASSERT(type < 3);
16548 +
16549 + size = 0;
16550 +
16551 + if (type == 0) {
16552 + size = 1 << (((admatch & SBAM_ADINT0_MASK) >> SBAM_ADINT0_SHIFT) + 1);
16553 + } else if (type == 1) {
16554 + ASSERT(!(admatch & SBAM_ADNEG)); /* neg not supported */
16555 + size = 1 << (((admatch & SBAM_ADINT1_MASK) >> SBAM_ADINT1_SHIFT) + 1);
16556 + } else if (type == 2) {
16557 + ASSERT(!(admatch & SBAM_ADNEG)); /* neg not supported */
16558 + size = 1 << (((admatch & SBAM_ADINT2_MASK) >> SBAM_ADINT2_SHIFT) + 1);
16559 + }
16560 +
16561 + return (size);
16562 +}
16563 +
16564 +/* return the core-type instantiation # of the current core */
16565 +uint
16566 +sb_coreunit(sb_t *sbh)
16567 +{
16568 + sb_info_t *si;
16569 + uint idx;
16570 + uint coreid;
16571 + uint coreunit;
16572 + uint i;
16573 +
16574 + si = SB_INFO(sbh);
16575 + coreunit = 0;
16576 +
16577 + idx = si->curidx;
16578 +
16579 + ASSERT(GOODREGS(si->curmap));
16580 + coreid = sb_coreid(sbh);
16581 +
16582 + /* count the cores of our type */
16583 + for (i = 0; i < idx; i++)
16584 + if (si->coreid[i] == coreid)
16585 + coreunit++;
16586 +
16587 + return (coreunit);
16588 +}
16589 +
16590 +static INLINE uint32
16591 +factor6(uint32 x)
16592 +{
16593 + switch (x) {
16594 + case CC_F6_2: return 2;
16595 + case CC_F6_3: return 3;
16596 + case CC_F6_4: return 4;
16597 + case CC_F6_5: return 5;
16598 + case CC_F6_6: return 6;
16599 + case CC_F6_7: return 7;
16600 + default: return 0;
16601 + }
16602 +}
16603 +
16604 +/* calculate the speed the SB would run at given a set of clockcontrol values */
16605 +uint32
16606 +sb_clock_rate(uint32 pll_type, uint32 n, uint32 m)
16607 +{
16608 + uint32 n1, n2, clock, m1, m2, m3, mc;
16609 +
16610 + n1 = n & CN_N1_MASK;
16611 + n2 = (n & CN_N2_MASK) >> CN_N2_SHIFT;
16612 +
16613 + if (pll_type == PLL_TYPE6) {
16614 + if (m & CC_T6_MMASK)
16615 + return CC_T6_M1;
16616 + else
16617 + return CC_T6_M0;
16618 + } else if ((pll_type == PLL_TYPE1) ||
16619 + (pll_type == PLL_TYPE3) ||
16620 + (pll_type == PLL_TYPE4) ||
16621 + (pll_type == PLL_TYPE7)) {
16622 + n1 = factor6(n1);
16623 + n2 += CC_F5_BIAS;
16624 + } else if (pll_type == PLL_TYPE2) {
16625 + n1 += CC_T2_BIAS;
16626 + n2 += CC_T2_BIAS;
16627 + ASSERT((n1 >= 2) && (n1 <= 7));
16628 + ASSERT((n2 >= 5) && (n2 <= 23));
16629 + } else if (pll_type == PLL_TYPE5) {
16630 + return (100000000);
16631 + } else
16632 + ASSERT(0);
16633 + /* PLL types 3 and 7 use BASE2 (25Mhz) */
16634 + if ((pll_type == PLL_TYPE3) ||
16635 + (pll_type == PLL_TYPE7)) {
16636 + clock = CC_CLOCK_BASE2 * n1 * n2;
16637 + }
16638 + else
16639 + clock = CC_CLOCK_BASE1 * n1 * n2;
16640 +
16641 + if (clock == 0)
16642 + return 0;
16643 +
16644 + m1 = m & CC_M1_MASK;
16645 + m2 = (m & CC_M2_MASK) >> CC_M2_SHIFT;
16646 + m3 = (m & CC_M3_MASK) >> CC_M3_SHIFT;
16647 + mc = (m & CC_MC_MASK) >> CC_MC_SHIFT;
16648 +
16649 + if ((pll_type == PLL_TYPE1) ||
16650 + (pll_type == PLL_TYPE3) ||
16651 + (pll_type == PLL_TYPE4) ||
16652 + (pll_type == PLL_TYPE7)) {
16653 + m1 = factor6(m1);
16654 + if ((pll_type == PLL_TYPE1) || (pll_type == PLL_TYPE3))
16655 + m2 += CC_F5_BIAS;
16656 + else
16657 + m2 = factor6(m2);
16658 + m3 = factor6(m3);
16659 +
16660 + switch (mc) {
16661 + case CC_MC_BYPASS: return (clock);
16662 + case CC_MC_M1: return (clock / m1);
16663 + case CC_MC_M1M2: return (clock / (m1 * m2));
16664 + case CC_MC_M1M2M3: return (clock / (m1 * m2 * m3));
16665 + case CC_MC_M1M3: return (clock / (m1 * m3));
16666 + default: return (0);
16667 + }
16668 + } else {
16669 + ASSERT(pll_type == PLL_TYPE2);
16670 +
16671 + m1 += CC_T2_BIAS;
16672 + m2 += CC_T2M2_BIAS;
16673 + m3 += CC_T2_BIAS;
16674 + ASSERT((m1 >= 2) && (m1 <= 7));
16675 + ASSERT((m2 >= 3) && (m2 <= 10));
16676 + ASSERT((m3 >= 2) && (m3 <= 7));
16677 +
16678 + if ((mc & CC_T2MC_M1BYP) == 0)
16679 + clock /= m1;
16680 + if ((mc & CC_T2MC_M2BYP) == 0)
16681 + clock /= m2;
16682 + if ((mc & CC_T2MC_M3BYP) == 0)
16683 + clock /= m3;
16684 +
16685 + return(clock);
16686 + }
16687 +}
16688 +
16689 +/* returns the current speed the SB is running at */
16690 +uint32
16691 +sb_clock(sb_t *sbh)
16692 +{
16693 + sb_info_t *si;
16694 + extifregs_t *eir;
16695 + chipcregs_t *cc;
16696 + uint32 n, m;
16697 + uint idx;
16698 + uint32 pll_type, rate;
16699 + uint intr_val = 0;
16700 +
16701 + si = SB_INFO(sbh);
16702 + idx = si->curidx;
16703 + pll_type = PLL_TYPE1;
16704 +
16705 + INTR_OFF(si, intr_val);
16706 +
16707 + /* switch to extif or chipc core */
16708 + if ((eir = (extifregs_t *) sb_setcore(sbh, SB_EXTIF, 0))) {
16709 + n = R_REG(&eir->clockcontrol_n);
16710 + m = R_REG(&eir->clockcontrol_sb);
16711 + } else if ((cc = (chipcregs_t *) sb_setcore(sbh, SB_CC, 0))) {
16712 + pll_type = R_REG(&cc->capabilities) & CAP_PLL_MASK;
16713 + n = R_REG(&cc->clockcontrol_n);
16714 + if (pll_type == PLL_TYPE6)
16715 + m = R_REG(&cc->clockcontrol_mips);
16716 + else if (pll_type == PLL_TYPE3)
16717 + {
16718 + // Added by Chen-I for 5365
16719 + if (BCMINIT(sb_chip)(sbh) == BCM5365_DEVICE_ID)
16720 + m = R_REG(&cc->clockcontrol_sb);
16721 + else
16722 + m = R_REG(&cc->clockcontrol_m2);
16723 + }
16724 + else
16725 + m = R_REG(&cc->clockcontrol_sb);
16726 + } else {
16727 + INTR_RESTORE(si, intr_val);
16728 + return 0;
16729 + }
16730 +
16731 + // Added by Chen-I for 5365
16732 + if (BCMINIT(sb_chip)(sbh) == BCM5365_DEVICE_ID)
16733 + {
16734 + rate = 100000000;
16735 + }
16736 + else
16737 + {
16738 + /* calculate rate */
16739 + rate = sb_clock_rate(pll_type, n, m);
16740 + if (pll_type == PLL_TYPE3)
16741 + rate = rate / 2;
16742 + }
16743 +
16744 + /* switch back to previous core */
16745 + sb_setcoreidx(sbh, idx);
16746 +
16747 + INTR_RESTORE(si, intr_val);
16748 +
16749 + return rate;
16750 +}
16751 +
16752 +/* change logical "focus" to the gpio core for optimized access */
16753 +void*
16754 +sb_gpiosetcore(sb_t *sbh)
16755 +{
16756 + sb_info_t *si;
16757 +
16758 + si = SB_INFO(sbh);
16759 +
16760 + return (sb_setcoreidx(sbh, si->gpioidx));
16761 +}
16762 +
16763 +/* mask&set gpiocontrol bits */
16764 +uint32
16765 +sb_gpiocontrol(sb_t *sbh, uint32 mask, uint32 val, uint8 priority)
16766 +{
16767 + sb_info_t *si;
16768 + uint regoff;
16769 +
16770 + si = SB_INFO(sbh);
16771 + regoff = 0;
16772 +
16773 + priority = GPIO_DRV_PRIORITY; /* compatibility hack */
16774 +
16775 + /* gpios could be shared on router platforms */
16776 + if ((BUSTYPE(si->sb.bustype) == SB_BUS) && (val || mask)) {
16777 + mask = priority ? (sb_gpioreservation & mask) :
16778 + ((sb_gpioreservation | mask) & ~(sb_gpioreservation));
16779 + val &= mask;
16780 + }
16781 +
16782 + switch (si->gpioid) {
16783 + case SB_CC:
16784 + regoff = OFFSETOF(chipcregs_t, gpiocontrol);
16785 + break;
16786 +
16787 + case SB_PCI:
16788 + regoff = OFFSETOF(sbpciregs_t, gpiocontrol);
16789 + break;
16790 +
16791 + case SB_EXTIF:
16792 + return (0);
16793 + }
16794 +
16795 + return (sb_corereg(si, si->gpioidx, regoff, mask, val));
16796 +}
16797 +
16798 +/* mask&set gpio output enable bits */
16799 +uint32
16800 +sb_gpioouten(sb_t *sbh, uint32 mask, uint32 val, uint8 priority)
16801 +{
16802 + sb_info_t *si;
16803 + uint regoff;
16804 +
16805 + si = SB_INFO(sbh);
16806 + regoff = 0;
16807 +
16808 + priority = GPIO_DRV_PRIORITY; /* compatibility hack */
16809 +
16810 + /* gpios could be shared on router platforms */
16811 + if ((BUSTYPE(si->sb.bustype) == SB_BUS) && (val || mask)) {
16812 + mask = priority ? (sb_gpioreservation & mask) :
16813 + ((sb_gpioreservation | mask) & ~(sb_gpioreservation));
16814 + val &= mask;
16815 + }
16816 +
16817 + switch (si->gpioid) {
16818 + case SB_CC:
16819 + regoff = OFFSETOF(chipcregs_t, gpioouten);
16820 + break;
16821 +
16822 + case SB_PCI:
16823 + regoff = OFFSETOF(sbpciregs_t, gpioouten);
16824 + break;
16825 +
16826 + case SB_EXTIF:
16827 + regoff = OFFSETOF(extifregs_t, gpio[0].outen);
16828 + break;
16829 + }
16830 +
16831 + return (sb_corereg(si, si->gpioidx, regoff, mask, val));
16832 +}
16833 +
16834 +/* mask&set gpio output bits */
16835 +uint32
16836 +sb_gpioout(sb_t *sbh, uint32 mask, uint32 val, uint8 priority)
16837 +{
16838 + sb_info_t *si;
16839 + uint regoff;
16840 +
16841 + si = SB_INFO(sbh);
16842 + regoff = 0;
16843 +
16844 + priority = GPIO_DRV_PRIORITY; /* compatibility hack */
16845 +
16846 + /* gpios could be shared on router platforms */
16847 + if ((BUSTYPE(si->sb.bustype) == SB_BUS) && (val || mask)) {
16848 + mask = priority ? (sb_gpioreservation & mask) :
16849 + ((sb_gpioreservation | mask) & ~(sb_gpioreservation));
16850 + val &= mask;
16851 + }
16852 +
16853 + switch (si->gpioid) {
16854 + case SB_CC:
16855 + regoff = OFFSETOF(chipcregs_t, gpioout);
16856 + break;
16857 +
16858 + case SB_PCI:
16859 + regoff = OFFSETOF(sbpciregs_t, gpioout);
16860 + break;
16861 +
16862 + case SB_EXTIF:
16863 + regoff = OFFSETOF(extifregs_t, gpio[0].out);
16864 + break;
16865 + }
16866 +
16867 + return (sb_corereg(si, si->gpioidx, regoff, mask, val));
16868 +}
16869 +
16870 +/* reserve one gpio */
16871 +uint32
16872 +sb_gpioreserve(sb_t *sbh, uint32 gpio_bitmask, uint8 priority)
16873 +{
16874 + sb_info_t *si;
16875 +
16876 + si = SB_INFO(sbh);
16877 +
16878 + priority = GPIO_DRV_PRIORITY; /* compatibility hack */
16879 +
16880 + /* only cores on SB_BUS share GPIO's and only applcation users need to reserve/release GPIO */
16881 + if ( (BUSTYPE(si->sb.bustype) != SB_BUS) || (!priority)) {
16882 + ASSERT((BUSTYPE(si->sb.bustype) == SB_BUS) && (priority));
16883 + return -1;
16884 + }
16885 + /* make sure only one bit is set */
16886 + if ((!gpio_bitmask) || ((gpio_bitmask) & (gpio_bitmask - 1))) {
16887 + ASSERT((gpio_bitmask) && !((gpio_bitmask) & (gpio_bitmask - 1)));
16888 + return -1;
16889 + }
16890 +
16891 + /* already reserved */
16892 + if (sb_gpioreservation & gpio_bitmask)
16893 + return -1;
16894 + /* set reservation */
16895 + sb_gpioreservation |= gpio_bitmask;
16896 +
16897 + return sb_gpioreservation;
16898 +}
16899 +
16900 +/* release one gpio */
16901 +/*
16902 + * releasing the gpio doesn't change the current value on the GPIO last write value
16903 + * persists till some one overwrites it
16904 +*/
16905 +
16906 +uint32
16907 +sb_gpiorelease(sb_t *sbh, uint32 gpio_bitmask, uint8 priority)
16908 +{
16909 + sb_info_t *si;
16910 +
16911 + si = SB_INFO(sbh);
16912 +
16913 + priority = GPIO_DRV_PRIORITY; /* compatibility hack */
16914 +
16915 + /* only cores on SB_BUS share GPIO's and only applcation users need to reserve/release GPIO */
16916 + if ( (BUSTYPE(si->sb.bustype) != SB_BUS) || (!priority)) {
16917 + ASSERT((BUSTYPE(si->sb.bustype) == SB_BUS) && (priority));
16918 + return -1;
16919 + }
16920 + /* make sure only one bit is set */
16921 + if ((!gpio_bitmask) || ((gpio_bitmask) & (gpio_bitmask - 1))) {
16922 + ASSERT((gpio_bitmask) && !((gpio_bitmask) & (gpio_bitmask - 1)));
16923 + return -1;
16924 + }
16925 +
16926 + /* already released */
16927 + if (!(sb_gpioreservation & gpio_bitmask))
16928 + return -1;
16929 +
16930 + /* clear reservation */
16931 + sb_gpioreservation &= ~gpio_bitmask;
16932 +
16933 + return sb_gpioreservation;
16934 +}
16935 +
16936 +/* return the current gpioin register value */
16937 +uint32
16938 +sb_gpioin(sb_t *sbh)
16939 +{
16940 + sb_info_t *si;
16941 + uint regoff;
16942 +
16943 + si = SB_INFO(sbh);
16944 + regoff = 0;
16945 +
16946 + switch (si->gpioid) {
16947 + case SB_CC:
16948 + regoff = OFFSETOF(chipcregs_t, gpioin);
16949 + break;
16950 +
16951 + case SB_PCI:
16952 + regoff = OFFSETOF(sbpciregs_t, gpioin);
16953 + break;
16954 +
16955 + case SB_EXTIF:
16956 + regoff = OFFSETOF(extifregs_t, gpioin);
16957 + break;
16958 + }
16959 +
16960 + return (sb_corereg(si, si->gpioidx, regoff, 0, 0));
16961 +}
16962 +
16963 +/* mask&set gpio interrupt polarity bits */
16964 +uint32
16965 +sb_gpiointpolarity(sb_t *sbh, uint32 mask, uint32 val, uint8 priority)
16966 +{
16967 + sb_info_t *si;
16968 + uint regoff;
16969 +
16970 + si = SB_INFO(sbh);
16971 + regoff = 0;
16972 +
16973 + priority = GPIO_DRV_PRIORITY; /* compatibility hack */
16974 +
16975 + /* gpios could be shared on router platforms */
16976 + if ((BUSTYPE(si->sb.bustype) == SB_BUS) && (val || mask)) {
16977 + mask = priority ? (sb_gpioreservation & mask) :
16978 + ((sb_gpioreservation | mask) & ~(sb_gpioreservation));
16979 + val &= mask;
16980 + }
16981 +
16982 + switch (si->gpioid) {
16983 + case SB_CC:
16984 + regoff = OFFSETOF(chipcregs_t, gpiointpolarity);
16985 + break;
16986 +
16987 + case SB_PCI:
16988 + /* pci gpio implementation does not support interrupt polarity */
16989 + ASSERT(0);
16990 + break;
16991 +
16992 + case SB_EXTIF:
16993 + regoff = OFFSETOF(extifregs_t, gpiointpolarity);
16994 + break;
16995 + }
16996 +
16997 + return (sb_corereg(si, si->gpioidx, regoff, mask, val));
16998 +}
16999 +
17000 +/* mask&set gpio interrupt mask bits */
17001 +uint32
17002 +sb_gpiointmask(sb_t *sbh, uint32 mask, uint32 val, uint8 priority)
17003 +{
17004 + sb_info_t *si;
17005 + uint regoff;
17006 +
17007 + si = SB_INFO(sbh);
17008 + regoff = 0;
17009 +
17010 + priority = GPIO_DRV_PRIORITY; /* compatibility hack */
17011 +
17012 + /* gpios could be shared on router platforms */
17013 + if ((BUSTYPE(si->sb.bustype) == SB_BUS) && (val || mask)) {
17014 + mask = priority ? (sb_gpioreservation & mask) :
17015 + ((sb_gpioreservation | mask) & ~(sb_gpioreservation));
17016 + val &= mask;
17017 + }
17018 +
17019 + switch (si->gpioid) {
17020 + case SB_CC:
17021 + regoff = OFFSETOF(chipcregs_t, gpiointmask);
17022 + break;
17023 +
17024 + case SB_PCI:
17025 + /* pci gpio implementation does not support interrupt mask */
17026 + ASSERT(0);
17027 + break;
17028 +
17029 + case SB_EXTIF:
17030 + regoff = OFFSETOF(extifregs_t, gpiointmask);
17031 + break;
17032 + }
17033 +
17034 + return (sb_corereg(si, si->gpioidx, regoff, mask, val));
17035 +}
17036 +
17037 +/* assign the gpio to an led */
17038 +uint32
17039 +sb_gpioled(sb_t *sbh, uint32 mask, uint32 val)
17040 +{
17041 + sb_info_t *si;
17042 +
17043 + si = SB_INFO(sbh);
17044 + if (si->sb.ccrev < 16)
17045 + return -1;
17046 +
17047 + /* gpio led powersave reg */
17048 + return(sb_corereg(si, 0, OFFSETOF(chipcregs_t, gpiotimeroutmask), mask, val));
17049 +}
17050 +
17051 +/* mask&set gpio timer val */
17052 +uint32
17053 +sb_gpiotimerval(sb_t *sbh, uint32 mask, uint32 gpiotimerval)
17054 +{
17055 + sb_info_t *si;
17056 + si = SB_INFO(sbh);
17057 +
17058 + if (si->sb.ccrev < 16)
17059 + return -1;
17060 +
17061 + return(sb_corereg(si, 0, OFFSETOF(chipcregs_t, gpiotimerval), mask, gpiotimerval));
17062 +}
17063 +
17064 +
17065 +/* return the slow clock source - LPO, XTAL, or PCI */
17066 +static uint
17067 +sb_slowclk_src(sb_info_t *si)
17068 +{
17069 + chipcregs_t *cc;
17070 +
17071 +
17072 + ASSERT(sb_coreid(&si->sb) == SB_CC);
17073 +
17074 + if (si->sb.ccrev < 6) {
17075 + if ((BUSTYPE(si->sb.bustype) == PCI_BUS)
17076 + && (OSL_PCI_READ_CONFIG(si->osh, PCI_GPIO_OUT, sizeof (uint32)) & PCI_CFG_GPIO_SCS))
17077 + return (SCC_SS_PCI);
17078 + else
17079 + return (SCC_SS_XTAL);
17080 + } else if (si->sb.ccrev < 10) {
17081 + cc = (chipcregs_t*) sb_setcoreidx(&si->sb, si->curidx);
17082 + return (R_REG(&cc->slow_clk_ctl) & SCC_SS_MASK);
17083 + } else /* Insta-clock */
17084 + return (SCC_SS_XTAL);
17085 +}
17086 +
17087 +/* return the ILP (slowclock) min or max frequency */
17088 +static uint
17089 +sb_slowclk_freq(sb_info_t *si, bool max)
17090 +{
17091 + chipcregs_t *cc;
17092 + uint32 slowclk;
17093 + uint div;
17094 +
17095 +
17096 + ASSERT(sb_coreid(&si->sb) == SB_CC);
17097 +
17098 + cc = (chipcregs_t*) sb_setcoreidx(&si->sb, si->curidx);
17099 +
17100 + /* shouldn't be here unless we've established the chip has dynamic clk control */
17101 + ASSERT(R_REG(&cc->capabilities) & CAP_PWR_CTL);
17102 +
17103 + slowclk = sb_slowclk_src(si);
17104 + if (si->sb.ccrev < 6) {
17105 + if (slowclk == SCC_SS_PCI)
17106 + return (max? (PCIMAXFREQ/64) : (PCIMINFREQ/64));
17107 + else
17108 + return (max? (XTALMAXFREQ/32) : (XTALMINFREQ/32));
17109 + } else if (si->sb.ccrev < 10) {
17110 + div = 4 * (((R_REG(&cc->slow_clk_ctl) & SCC_CD_MASK) >> SCC_CD_SHIFT) + 1);
17111 + if (slowclk == SCC_SS_LPO)
17112 + return (max? LPOMAXFREQ : LPOMINFREQ);
17113 + else if (slowclk == SCC_SS_XTAL)
17114 + return (max? (XTALMAXFREQ/div) : (XTALMINFREQ/div));
17115 + else if (slowclk == SCC_SS_PCI)
17116 + return (max? (PCIMAXFREQ/div) : (PCIMINFREQ/div));
17117 + else
17118 + ASSERT(0);
17119 + } else {
17120 + /* Chipc rev 10 is InstaClock */
17121 + div = R_REG(&cc->system_clk_ctl) >> SYCC_CD_SHIFT;
17122 + div = 4 * (div + 1);
17123 + return (max ? XTALMAXFREQ : (XTALMINFREQ/div));
17124 + }
17125 + return (0);
17126 +}
17127 +
17128 +static void
17129 +sb_clkctl_setdelay(sb_info_t *si, void *chipcregs)
17130 +{
17131 + chipcregs_t * cc;
17132 + uint slowmaxfreq, pll_delay, slowclk;
17133 + uint pll_on_delay, fref_sel_delay;
17134 +
17135 + pll_delay = PLL_DELAY;
17136 +
17137 + /* If the slow clock is not sourced by the xtal then add the xtal_on_delay
17138 + * since the xtal will also be powered down by dynamic clk control logic.
17139 + */
17140 + slowclk = sb_slowclk_src(si);
17141 + if (slowclk != SCC_SS_XTAL)
17142 + pll_delay += XTAL_ON_DELAY;
17143 +
17144 + /* Starting with 4318 it is ILP that is used for the delays */
17145 + slowmaxfreq = sb_slowclk_freq(si, (si->sb.ccrev >= 10) ? FALSE : TRUE);
17146 +
17147 + pll_on_delay = ((slowmaxfreq * pll_delay) + 999999) / 1000000;
17148 + fref_sel_delay = ((slowmaxfreq * FREF_DELAY) + 999999) / 1000000;
17149 +
17150 + cc = (chipcregs_t *)chipcregs;
17151 + W_REG(&cc->pll_on_delay, pll_on_delay);
17152 + W_REG(&cc->fref_sel_delay, fref_sel_delay);
17153 +}
17154 +
17155 +int
17156 +sb_pwrctl_slowclk(void *sbh, bool set, uint *div)
17157 +{
17158 + sb_info_t *si;
17159 + uint origidx;
17160 + chipcregs_t *cc;
17161 + uint intr_val = 0;
17162 + uint err = 0;
17163 +
17164 + si = SB_INFO(sbh);
17165 +
17166 + /* chipcommon cores prior to rev6 don't support slowclkcontrol */
17167 + if (si->sb.ccrev < 6)
17168 + return 1;
17169 +
17170 + /* chipcommon cores rev10 are a whole new ball game */
17171 + if (si->sb.ccrev >= 10)
17172 + return 1;
17173 +
17174 + if (set && ((*div % 4) || (*div < 4)))
17175 + return 2;
17176 +
17177 + INTR_OFF(si, intr_val);
17178 + origidx = si->curidx;
17179 + cc = (chipcregs_t*) sb_setcore(sbh, SB_CC, 0);
17180 + ASSERT(cc != NULL);
17181 +
17182 + if (!(R_REG(&cc->capabilities) & CAP_PWR_CTL)) {
17183 + err = 3;
17184 + goto done;
17185 + }
17186 +
17187 + if (set) {
17188 + SET_REG(&cc->slow_clk_ctl, SCC_CD_MASK, ((*div / 4 - 1) << SCC_CD_SHIFT));
17189 + sb_clkctl_setdelay(sbh, (void *)cc);
17190 + } else
17191 + *div = 4 * (((R_REG(&cc->slow_clk_ctl) & SCC_CD_MASK) >> SCC_CD_SHIFT) + 1);
17192 +
17193 +done:
17194 + sb_setcoreidx(sbh, origidx);
17195 + INTR_RESTORE(si, intr_val);
17196 + return err;
17197 +}
17198 +
17199 +/* initialize power control delay registers */
17200 +void sb_clkctl_init(sb_t *sbh)
17201 +{
17202 + sb_info_t *si;
17203 + uint origidx;
17204 + chipcregs_t *cc;
17205 +
17206 + si = SB_INFO(sbh);
17207 +
17208 + origidx = si->curidx;
17209 +
17210 + if ((cc = (chipcregs_t*) sb_setcore(sbh, SB_CC, 0)) == NULL)
17211 + return;
17212 +
17213 + if (!(R_REG(&cc->capabilities) & CAP_PWR_CTL))
17214 + goto done;
17215 +
17216 + /* 4317pc does not work with SlowClock less than 5 MHz */
17217 + if ((BUSTYPE(si->sb.bustype) == PCMCIA_BUS) && (si->sb.ccrev >= 6) && (si->sb.ccrev < 10))
17218 + SET_REG(&cc->slow_clk_ctl, SCC_CD_MASK, (ILP_DIV_5MHZ << SCC_CD_SHIFT));
17219 +
17220 + /* set all Instaclk chip ILP to 1 MHz */
17221 + else if (si->sb.ccrev >= 10)
17222 + SET_REG(&cc->system_clk_ctl, SYCC_CD_MASK, (ILP_DIV_1MHZ << SYCC_CD_SHIFT));
17223 +
17224 + sb_clkctl_setdelay(si, (void *)cc);
17225 +
17226 +done:
17227 + sb_setcoreidx(sbh, origidx);
17228 +}
17229 +void sb_pwrctl_init(sb_t *sbh)
17230 +{
17231 +sb_clkctl_init(sbh);
17232 +}
17233 +/* return the value suitable for writing to the dot11 core FAST_PWRUP_DELAY register */
17234 +uint16
17235 +sb_clkctl_fast_pwrup_delay(sb_t *sbh)
17236 +{
17237 + sb_info_t *si;
17238 + uint origidx;
17239 + chipcregs_t *cc;
17240 + uint slowminfreq;
17241 + uint16 fpdelay;
17242 + uint intr_val = 0;
17243 +
17244 + si = SB_INFO(sbh);
17245 + fpdelay = 0;
17246 + origidx = si->curidx;
17247 +
17248 + INTR_OFF(si, intr_val);
17249 +
17250 + if ((cc = (chipcregs_t*) sb_setcore(sbh, SB_CC, 0)) == NULL)
17251 + goto done;
17252 +
17253 + if (!(R_REG(&cc->capabilities) & CAP_PWR_CTL))
17254 + goto done;
17255 +
17256 + slowminfreq = sb_slowclk_freq(si, FALSE);
17257 + fpdelay = (((R_REG(&cc->pll_on_delay) + 2) * 1000000) + (slowminfreq - 1)) / slowminfreq;
17258 +
17259 +done:
17260 + sb_setcoreidx(sbh, origidx);
17261 + INTR_RESTORE(si, intr_val);
17262 + return (fpdelay);
17263 +}
17264 +uint16 sb_pwrctl_fast_pwrup_delay(sb_t *sbh)
17265 +{
17266 +return sb_clkctl_fast_pwrup_delay(sbh);
17267 +}
17268 +/* turn primary xtal and/or pll off/on */
17269 +int
17270 +sb_clkctl_xtal(sb_t *sbh, uint what, bool on)
17271 +{
17272 + sb_info_t *si;
17273 + uint32 in, out, outen;
17274 +
17275 + si = SB_INFO(sbh);
17276 +
17277 + switch (BUSTYPE(si->sb.bustype)) {
17278 +
17279 +
17280 + case PCMCIA_BUS:
17281 + return (0);
17282 +
17283 +
17284 + case PCI_BUS:
17285 +
17286 + /* pcie core doesn't have any mapping to control the xtal pu */
17287 + if (PCIE(si))
17288 + return -1;
17289 +
17290 + in = OSL_PCI_READ_CONFIG(si->osh, PCI_GPIO_IN, sizeof (uint32));
17291 + out = OSL_PCI_READ_CONFIG(si->osh, PCI_GPIO_OUT, sizeof (uint32));
17292 + outen = OSL_PCI_READ_CONFIG(si->osh, PCI_GPIO_OUTEN, sizeof (uint32));
17293 +
17294 + /*
17295 + * Avoid glitching the clock if GPRS is already using it.
17296 + * We can't actually read the state of the PLLPD so we infer it
17297 + * by the value of XTAL_PU which *is* readable via gpioin.
17298 + */
17299 + if (on && (in & PCI_CFG_GPIO_XTAL))
17300 + return (0);
17301 +
17302 + if (what & XTAL)
17303 + outen |= PCI_CFG_GPIO_XTAL;
17304 + if (what & PLL)
17305 + outen |= PCI_CFG_GPIO_PLL;
17306 +
17307 + if (on) {
17308 + /* turn primary xtal on */
17309 + if (what & XTAL) {
17310 + out |= PCI_CFG_GPIO_XTAL;
17311 + if (what & PLL)
17312 + out |= PCI_CFG_GPIO_PLL;
17313 + OSL_PCI_WRITE_CONFIG(si->osh, PCI_GPIO_OUT, sizeof (uint32), out);
17314 + OSL_PCI_WRITE_CONFIG(si->osh, PCI_GPIO_OUTEN, sizeof (uint32), outen);
17315 + OSL_DELAY(XTAL_ON_DELAY);
17316 + }
17317 +
17318 + /* turn pll on */
17319 + if (what & PLL) {
17320 + out &= ~PCI_CFG_GPIO_PLL;
17321 + OSL_PCI_WRITE_CONFIG(si->osh, PCI_GPIO_OUT, sizeof (uint32), out);
17322 + OSL_DELAY(2000);
17323 + }
17324 + } else {
17325 + if (what & XTAL)
17326 + out &= ~PCI_CFG_GPIO_XTAL;
17327 + if (what & PLL)
17328 + out |= PCI_CFG_GPIO_PLL;
17329 + OSL_PCI_WRITE_CONFIG(si->osh, PCI_GPIO_OUT, sizeof (uint32), out);
17330 + OSL_PCI_WRITE_CONFIG(si->osh, PCI_GPIO_OUTEN, sizeof (uint32), outen);
17331 + }
17332 +
17333 + default:
17334 + return (-1);
17335 + }
17336 +
17337 + return (0);
17338 +}
17339 +
17340 +int sb_pwrctl_xtal(sb_t *sbh, uint what, bool on)
17341 +{
17342 +return sb_clkctl_xtal(sbh,what,on);
17343 +}
17344 +
17345 +/* set dynamic clk control mode (forceslow, forcefast, dynamic) */
17346 +/* returns true if ignore pll off is set and false if it is not */
17347 +bool
17348 +sb_clkctl_clk(sb_t *sbh, uint mode)
17349 +{
17350 + sb_info_t *si;
17351 + uint origidx;
17352 + chipcregs_t *cc;
17353 + uint32 scc;
17354 + bool forcefastclk=FALSE;
17355 + uint intr_val = 0;
17356 +
17357 + si = SB_INFO(sbh);
17358 +
17359 + /* chipcommon cores prior to rev6 don't support dynamic clock control */
17360 + if (si->sb.ccrev < 6)
17361 + return (FALSE);
17362 +
17363 + /* chipcommon cores rev10 are a whole new ball game */
17364 + if (si->sb.ccrev >= 10)
17365 + return (FALSE);
17366 +
17367 + INTR_OFF(si, intr_val);
17368 +
17369 + origidx = si->curidx;
17370 +
17371 + cc = (chipcregs_t*) sb_setcore(sbh, SB_CC, 0);
17372 + ASSERT(cc != NULL);
17373 +
17374 + if (!(R_REG(&cc->capabilities) & CAP_PWR_CTL))
17375 + goto done;
17376 +
17377 + switch (mode) {
17378 + case CLK_FAST: /* force fast (pll) clock */
17379 + /* don't forget to force xtal back on before we clear SCC_DYN_XTAL.. */
17380 + sb_clkctl_xtal(&si->sb, XTAL, ON);
17381 +
17382 + SET_REG(&cc->slow_clk_ctl, (SCC_XC | SCC_FS | SCC_IP), SCC_IP);
17383 + break;
17384 +
17385 + case CLK_DYNAMIC: /* enable dynamic clock control */
17386 + scc = R_REG(&cc->slow_clk_ctl);
17387 + scc &= ~(SCC_FS | SCC_IP | SCC_XC);
17388 + if ((scc & SCC_SS_MASK) != SCC_SS_XTAL)
17389 + scc |= SCC_XC;
17390 + W_REG(&cc->slow_clk_ctl, scc);
17391 +
17392 + /* for dynamic control, we have to release our xtal_pu "force on" */
17393 + if (scc & SCC_XC)
17394 + sb_clkctl_xtal(&si->sb, XTAL, OFF);
17395 + break;
17396 +
17397 + default:
17398 + ASSERT(0);
17399 + }
17400 +
17401 + /* Is the h/w forcing the use of the fast clk */
17402 + forcefastclk = (bool)((R_REG(&cc->slow_clk_ctl) & SCC_IP) == SCC_IP);
17403 +
17404 +done:
17405 + sb_setcoreidx(sbh, origidx);
17406 + INTR_RESTORE(si, intr_val);
17407 + return (forcefastclk);
17408 +}
17409 +
17410 +bool sb_pwrctl_clk(sb_t *sbh, uint mode)
17411 +{
17412 +return sb_clkctl_clk(sbh, mode);
17413 +}
17414 +/* register driver interrupt disabling and restoring callback functions */
17415 +void
17416 +sb_register_intr_callback(sb_t *sbh, void *intrsoff_fn, void *intrsrestore_fn, void *intrsenabled_fn, void *intr_arg)
17417 +{
17418 + sb_info_t *si;
17419 +
17420 + si = SB_INFO(sbh);
17421 + si->intr_arg = intr_arg;
17422 + si->intrsoff_fn = (sb_intrsoff_t)intrsoff_fn;
17423 + si->intrsrestore_fn = (sb_intrsrestore_t)intrsrestore_fn;
17424 + si->intrsenabled_fn = (sb_intrsenabled_t)intrsenabled_fn;
17425 + /* save current core id. when this function called, the current core
17426 + * must be the core which provides driver functions(il, et, wl, etc.)
17427 + */
17428 + si->dev_coreid = si->coreid[si->curidx];
17429 +}
17430 +
17431 +
17432 +void
17433 +sb_corepciid(sb_t *sbh, uint16 *pcivendor, uint16 *pcidevice,
17434 + uint8 *pciclass, uint8 *pcisubclass, uint8 *pciprogif)
17435 +{
17436 + uint vendor, core, unit;
17437 + uint chip, chippkg;
17438 + char varname[8];
17439 + uint8 class, subclass, progif;
17440 +
17441 + vendor = sb_corevendor(sbh);
17442 + core = sb_coreid(sbh);
17443 + unit = sb_coreunit(sbh);
17444 +
17445 + chip = BCMINIT(sb_chip)(sbh);
17446 + chippkg = BCMINIT(sb_chippkg)(sbh);
17447 +
17448 + progif = 0;
17449 +
17450 + /* Known vendor translations */
17451 + switch (vendor) {
17452 + case SB_VEND_BCM:
17453 + vendor = VENDOR_BROADCOM;
17454 + break;
17455 + }
17456 +
17457 + /* Determine class based on known core codes */
17458 + switch (core) {
17459 + case SB_ILINE20:
17460 + class = PCI_CLASS_NET;
17461 + subclass = PCI_NET_ETHER;
17462 + core = BCM47XX_ILINE_ID;
17463 + break;
17464 + case SB_ENET:
17465 + class = PCI_CLASS_NET;
17466 + subclass = PCI_NET_ETHER;
17467 + core = BCM47XX_ENET_ID;
17468 + break;
17469 + case SB_SDRAM:
17470 + case SB_MEMC:
17471 + class = PCI_CLASS_MEMORY;
17472 + subclass = PCI_MEMORY_RAM;
17473 + break;
17474 + case SB_PCI:
17475 + case SB_PCIE:
17476 + class = PCI_CLASS_BRIDGE;
17477 + subclass = PCI_BRIDGE_PCI;
17478 + break;
17479 + case SB_MIPS:
17480 + case SB_MIPS33:
17481 + class = PCI_CLASS_CPU;
17482 + subclass = PCI_CPU_MIPS;
17483 + break;
17484 + case SB_CODEC:
17485 + class = PCI_CLASS_COMM;
17486 + subclass = PCI_COMM_MODEM;
17487 + core = BCM47XX_V90_ID;
17488 + break;
17489 + case SB_USB:
17490 + class = PCI_CLASS_SERIAL;
17491 + subclass = PCI_SERIAL_USB;
17492 + progif = 0x10; /* OHCI */
17493 + core = BCM47XX_USB_ID;
17494 + break;
17495 + case SB_USB11H:
17496 + class = PCI_CLASS_SERIAL;
17497 + subclass = PCI_SERIAL_USB;
17498 + progif = 0x10; /* OHCI */
17499 + core = BCM47XX_USBH_ID;
17500 + break;
17501 + case SB_USB11D:
17502 + class = PCI_CLASS_SERIAL;
17503 + subclass = PCI_SERIAL_USB;
17504 + core = BCM47XX_USBD_ID;
17505 + break;
17506 + case SB_IPSEC:
17507 + class = PCI_CLASS_CRYPT;
17508 + subclass = PCI_CRYPT_NETWORK;
17509 + core = BCM47XX_IPSEC_ID;
17510 + break;
17511 + case SB_ROBO:
17512 + class = PCI_CLASS_NET;
17513 + subclass = PCI_NET_OTHER;
17514 + core = BCM47XX_ROBO_ID;
17515 + break;
17516 + case SB_EXTIF:
17517 + case SB_CC:
17518 + class = PCI_CLASS_MEMORY;
17519 + subclass = PCI_MEMORY_FLASH;
17520 + break;
17521 + case SB_D11:
17522 + class = PCI_CLASS_NET;
17523 + subclass = PCI_NET_OTHER;
17524 + /* Let an nvram variable override this */
17525 + sprintf(varname, "wl%did", unit);
17526 + if ((core = getintvar(NULL, varname)) == 0) {
17527 + if (chip == BCM4712_DEVICE_ID) {
17528 + if (chippkg == BCM4712SMALL_PKG_ID)
17529 + core = BCM4306_D11G_ID;
17530 + else
17531 + core = BCM4306_D11DUAL_ID;
17532 + }
17533 + }
17534 + break;
17535 +
17536 + default:
17537 + class = subclass = progif = 0xff;
17538 + break;
17539 + }
17540 +
17541 + *pcivendor = (uint16)vendor;
17542 + *pcidevice = (uint16)core;
17543 + *pciclass = class;
17544 + *pcisubclass = subclass;
17545 + *pciprogif = progif;
17546 +}
17547 +
17548 +
17549 +
17550 +
17551 +/* use the mdio interface to write to mdio slaves */
17552 +static int
17553 +sb_pcie_mdiowrite(sb_info_t *si, uint physmedia, uint regaddr, uint val)
17554 +{
17555 + uint mdiodata;
17556 + uint i = 0;
17557 + sbpcieregs_t *pcieregs;
17558 +
17559 + pcieregs = (sbpcieregs_t*) sb_setcoreidx(&si->sb, si->sb.buscoreidx);
17560 + ASSERT (pcieregs);
17561 +
17562 + /* enable mdio access to SERDES */
17563 + W_REG((&pcieregs->mdiocontrol), MDIOCTL_PREAM_EN | MDIOCTL_DIVISOR_VAL);
17564 +
17565 + mdiodata = MDIODATA_START | MDIODATA_WRITE |
17566 + (physmedia << MDIODATA_DEVADDR_SHF) |
17567 + (regaddr << MDIODATA_REGADDR_SHF) | MDIODATA_TA | val;
17568 +
17569 + W_REG((&pcieregs->mdiodata), mdiodata);
17570 +
17571 + PR28829_DELAY();
17572 +
17573 + /* retry till the transaction is complete */
17574 + while ( i < 10 ) {
17575 + if (R_REG(&(pcieregs->mdiocontrol)) & MDIOCTL_ACCESS_DONE) {
17576 + /* Disable mdio access to SERDES */
17577 + W_REG((&pcieregs->mdiocontrol), 0);
17578 + return 0;
17579 + }
17580 + OSL_DELAY(1000);
17581 + i++;
17582 + }
17583 +
17584 + SB_ERROR(("sb_pcie_mdiowrite: timed out\n"));
17585 + /* Disable mdio access to SERDES */
17586 + W_REG((&pcieregs->mdiocontrol), 0);
17587 + ASSERT(0);
17588 + return 1;
17589 +
17590 +}
17591 +
17592 +/* indirect way to read pcie config regs*/
17593 +uint
17594 +sb_pcie_readreg(void *sb, void* arg1, uint offset)
17595 +{
17596 + sb_info_t *si;
17597 + sb_t *sbh;
17598 + uint retval = 0xFFFFFFFF;
17599 + sbpcieregs_t *pcieregs;
17600 + uint addrtype;
17601 +
17602 + sbh = (sb_t *)sb;
17603 + si = SB_INFO(sbh);
17604 + ASSERT (PCIE(si));
17605 +
17606 + pcieregs = (sbpcieregs_t *)sb_setcore(sbh, SB_PCIE, 0);
17607 + ASSERT (pcieregs);
17608 +
17609 + addrtype = (uint)((uintptr)arg1);
17610 + switch(addrtype) {
17611 + case PCIE_CONFIGREGS:
17612 + W_REG((&pcieregs->configaddr),offset);
17613 + retval = R_REG(&(pcieregs->configdata));
17614 + break;
17615 + case PCIE_PCIEREGS:
17616 + W_REG(&(pcieregs->pcieaddr),offset);
17617 + retval = R_REG(&(pcieregs->pciedata));
17618 + break;
17619 + default:
17620 + ASSERT(0);
17621 + break;
17622 + }
17623 + return retval;
17624 +}
17625 +
17626 +/* indirect way to write pcie config/mdio/pciecore regs*/
17627 +uint
17628 +sb_pcie_writereg(sb_t *sbh, void *arg1, uint offset, uint val)
17629 +{
17630 + sb_info_t *si;
17631 + sbpcieregs_t *pcieregs;
17632 + uint addrtype;
17633 +
17634 + si = SB_INFO(sbh);
17635 + ASSERT (PCIE(si));
17636 +
17637 + pcieregs = (sbpcieregs_t *)sb_setcore(sbh, SB_PCIE, 0);
17638 + ASSERT (pcieregs);
17639 +
17640 + addrtype = (uint)((uintptr)arg1);
17641 +
17642 + switch(addrtype) {
17643 + case PCIE_CONFIGREGS:
17644 + W_REG((&pcieregs->configaddr),offset);
17645 + W_REG((&pcieregs->configdata),val);
17646 + break;
17647 + case PCIE_PCIEREGS:
17648 + W_REG((&pcieregs->pcieaddr),offset);
17649 + W_REG((&pcieregs->pciedata),val);
17650 + break;
17651 + default:
17652 + ASSERT(0);
17653 + break;
17654 + }
17655 + return 0;
17656 +}
17657 +
17658 +
17659 +/* Build device path. Support SB, PCI, and JTAG for now. */
17660 +int
17661 +sb_devpath(sb_t *sbh, char *path, int size)
17662 +{
17663 + ASSERT(path);
17664 + ASSERT(size >= SB_DEVPATH_BUFSZ);
17665 +
17666 + switch (BUSTYPE((SB_INFO(sbh))->sb.bustype)) {
17667 + case SB_BUS:
17668 + case JTAG_BUS:
17669 + sprintf(path, "sb/%u/", sb_coreidx(sbh));
17670 + break;
17671 + case PCI_BUS:
17672 + ASSERT((SB_INFO(sbh))->osh);
17673 + sprintf(path, "pci/%u/%u/", OSL_PCI_BUS((SB_INFO(sbh))->osh),
17674 + OSL_PCI_SLOT((SB_INFO(sbh))->osh));
17675 + break;
17676 + case PCMCIA_BUS:
17677 + SB_ERROR(("sb_devpath: OSL_PCMCIA_BUS() not implemented, bus 1 assumed\n"));
17678 + SB_ERROR(("sb_devpath: OSL_PCMCIA_SLOT() not implemented, slot 1 assumed\n"));
17679 + sprintf(path, "pc/%u/%u/", 1, 1);
17680 + break;
17681 + case SDIO_BUS:
17682 + SB_ERROR(("sb_devpath: device 0 assumed\n"));
17683 + sprintf(path, "sd/%u/", sb_coreidx(sbh));
17684 + break;
17685 + default:
17686 + ASSERT(0);
17687 + break;
17688 + }
17689 +
17690 + return 0;
17691 +}
17692 +
17693 +/* Fix chip's configuration. The current core may be changed upon return */
17694 +static int
17695 +sb_pci_fixcfg(sb_info_t *si)
17696 +{
17697 + uint origidx, pciidx;
17698 + sbpciregs_t *pciregs;
17699 + sbpcieregs_t *pcieregs;
17700 + uint16 val16, *reg16;
17701 + char name[SB_DEVPATH_BUFSZ+16], *value;
17702 + char devpath[SB_DEVPATH_BUFSZ];
17703 +
17704 + ASSERT(BUSTYPE(si->sb.bustype) == PCI_BUS);
17705 +
17706 + /* Fix PCI(e) SROM shadow area */
17707 + /* save the current index */
17708 + origidx = sb_coreidx(&si->sb);
17709 +
17710 + /* check 'pi' is correct and fix it if not */
17711 + if (si->sb.buscoretype == SB_PCIE) {
17712 + pcieregs = (sbpcieregs_t *)sb_setcore(&si->sb, SB_PCIE, 0);
17713 + ASSERT(pcieregs);
17714 + reg16 = &pcieregs->sprom[SRSH_PI_OFFSET];
17715 + }
17716 + else if (si->sb.buscoretype == SB_PCI) {
17717 + pciregs = (sbpciregs_t *)sb_setcore(&si->sb, SB_PCI, 0);
17718 + ASSERT(pciregs);
17719 + reg16 = &pciregs->sprom[SRSH_PI_OFFSET];
17720 + }
17721 + else {
17722 + ASSERT(0);
17723 + return -1;
17724 + }
17725 + pciidx = sb_coreidx(&si->sb);
17726 + val16 = R_REG(reg16);
17727 + if (((val16 & SRSH_PI_MASK) >> SRSH_PI_SHIFT) != (uint16)pciidx) {
17728 + val16 = (uint16)(pciidx << SRSH_PI_SHIFT) | (val16 & ~SRSH_PI_MASK);
17729 + W_REG(reg16, val16);
17730 + }
17731 +
17732 + /* restore the original index */
17733 + sb_setcoreidx(&si->sb, origidx);
17734 +
17735 + /* Fix bar0window */
17736 + /* !do it last, it changes the current core! */
17737 + if (sb_devpath(&si->sb, devpath, sizeof(devpath)))
17738 + return -1;
17739 + sprintf(name, "%sb0w", devpath);
17740 + if ((value = getvar(NULL, name))) {
17741 + OSL_PCI_WRITE_CONFIG(si->osh, PCI_BAR0_WIN, sizeof(uint32),
17742 + bcm_strtoul(value, NULL, 16));
17743 + /* update curidx since the current core is changed */
17744 + si->curidx = _sb_coreidx(si);
17745 + if (si->curidx == BADIDX) {
17746 + SB_ERROR(("sb_pci_fixcfg: bad core index\n"));
17747 + return -1;
17748 + }
17749 + }
17750 +
17751 + return 0;
17752 +}
17753 +
17754 diff -Nur linux-2.4.32/drivers/net/hnd/shared_ksyms.sh linux-2.4.32-brcm/drivers/net/hnd/shared_ksyms.sh
17755 --- linux-2.4.32/drivers/net/hnd/shared_ksyms.sh 1970-01-01 01:00:00.000000000 +0100
17756 +++ linux-2.4.32-brcm/drivers/net/hnd/shared_ksyms.sh 2005-12-16 23:39:11.316860000 +0100
17757 @@ -0,0 +1,21 @@
17758 +#!/bin/sh
17759 +#
17760 +# Copyright 2004, Broadcom Corporation
17761 +# All Rights Reserved.
17762 +#
17763 +# THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY
17764 +# KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM
17765 +# SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS
17766 +# FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE.
17767 +#
17768 +# $Id: shared_ksyms.sh,v 1.1 2005/03/16 13:50:00 wbx Exp $
17769 +#
17770 +
17771 +cat <<EOF
17772 +#include <linux/config.h>
17773 +#include <linux/module.h>
17774 +EOF
17775 +
17776 +for file in $* ; do
17777 + ${NM} $file | sed -ne 's/[0-9A-Fa-f]* [DT] \([^ ]*\)/extern void \1; EXPORT_SYMBOL(\1);/p'
17778 +done
17779 diff -Nur linux-2.4.32/drivers/net/Makefile linux-2.4.32-brcm/drivers/net/Makefile
17780 --- linux-2.4.32/drivers/net/Makefile 2005-01-19 15:09:56.000000000 +0100
17781 +++ linux-2.4.32-brcm/drivers/net/Makefile 2005-12-16 23:39:11.284858000 +0100
17782 @@ -3,6 +3,8 @@
17783 # Makefile for the Linux network (ethercard) device drivers.
17784 #
17785
17786 +EXTRA_CFLAGS := -I$(TOPDIR)/arch/mips/bcm947xx/include
17787 +
17788 obj-y :=
17789 obj-m :=
17790 obj-n :=
17791 @@ -39,6 +41,8 @@
17792 obj-$(CONFIG_ISDN) += slhc.o
17793 endif
17794
17795 +subdir-$(CONFIG_HND) += hnd
17796 +subdir-$(CONFIG_WL) += wl
17797 subdir-$(CONFIG_NET_PCMCIA) += pcmcia
17798 subdir-$(CONFIG_NET_WIRELESS) += wireless
17799 subdir-$(CONFIG_TULIP) += tulip
17800 @@ -69,6 +74,13 @@
17801 obj-$(CONFIG_MYRI_SBUS) += myri_sbus.o
17802 obj-$(CONFIG_SUNGEM) += sungem.o
17803
17804 +ifeq ($(CONFIG_HND),y)
17805 + obj-y += hnd/hnd.o
17806 +endif
17807 +ifeq ($(CONFIG_WL),y)
17808 + obj-y += wl/wl.o
17809 +endif
17810 +
17811 obj-$(CONFIG_MACE) += mace.o
17812 obj-$(CONFIG_BMAC) += bmac.o
17813 obj-$(CONFIG_GMAC) += gmac.o
17814 diff -Nur linux-2.4.32/drivers/net/wireless/Config.in linux-2.4.32-brcm/drivers/net/wireless/Config.in
17815 --- linux-2.4.32/drivers/net/wireless/Config.in 2004-11-17 12:54:21.000000000 +0100
17816 +++ linux-2.4.32-brcm/drivers/net/wireless/Config.in 2005-12-16 23:39:11.364863000 +0100
17817 @@ -13,6 +13,7 @@
17818 fi
17819
17820 if [ "$CONFIG_PCI" = "y" ]; then
17821 + dep_tristate ' Proprietary Broadcom BCM43xx 802.11 Wireless support' CONFIG_WL
17822 dep_tristate ' Hermes in PLX9052 based PCI adaptor support (Netgear MA301 etc.) (EXPERIMENTAL)' CONFIG_PLX_HERMES $CONFIG_HERMES $CONFIG_EXPERIMENTAL
17823 dep_tristate ' Hermes in TMD7160/NCP130 based PCI adaptor support (Pheecom WL-PCI etc.) (EXPERIMENTAL)' CONFIG_TMD_HERMES $CONFIG_HERMES $CONFIG_EXPERIMENTAL
17824 dep_tristate ' Prism 2.5 PCI 802.11b adaptor support (EXPERIMENTAL)' CONFIG_PCI_HERMES $CONFIG_HERMES $CONFIG_EXPERIMENTAL
17825 diff -Nur linux-2.4.32/drivers/net/wl/Makefile linux-2.4.32-brcm/drivers/net/wl/Makefile
17826 --- linux-2.4.32/drivers/net/wl/Makefile 1970-01-01 01:00:00.000000000 +0100
17827 +++ linux-2.4.32-brcm/drivers/net/wl/Makefile 2005-12-16 23:39:11.364863000 +0100
17828 @@ -0,0 +1,26 @@
17829 +#
17830 +# Makefile for the Broadcom wl driver
17831 +#
17832 +# Copyright 2004, Broadcom Corporation
17833 +# All Rights Reserved.
17834 +#
17835 +# THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY
17836 +# KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM
17837 +# SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS
17838 +# FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE.
17839 +#
17840 +# $Id: Makefile,v 1.2 2005/03/29 03:32:18 mbm Exp $
17841 +
17842 +EXTRA_CFLAGS += -I$(TOPDIR)/arch/mips/bcm947xx/include
17843 +
17844 +O_TARGET := wl.o
17845 +
17846 +obj-y := apsta_aeskeywrap.o apsta_aes.o apsta_bcmwpa.o apsta_d11ucode.o
17847 +obj-y += apsta_hmac.o apsta_md5.o apsta_passhash.o apsta_prf.o apsta_rc4.o
17848 +obj-y += apsta_rijndael-alg-fst.o apsta_sha1.o apsta_tkhash.o apsta_wlc_led.o
17849 +obj-y += apsta_wlc_phy.o apsta_wlc_rate.o apsta_wlc_security.o
17850 +obj-y += apsta_wlc_sup.o apsta_wlc_wet.o apsta_wl_linux.o apsta_wlc.o
17851 +
17852 +obj-m := $(O_TARGET)
17853 +
17854 +include $(TOPDIR)/Rules.make
17855 diff -Nur linux-2.4.32/drivers/parport/Config.in linux-2.4.32-brcm/drivers/parport/Config.in
17856 --- linux-2.4.32/drivers/parport/Config.in 2004-02-18 14:36:31.000000000 +0100
17857 +++ linux-2.4.32-brcm/drivers/parport/Config.in 2005-12-16 23:39:11.364863000 +0100
17858 @@ -11,6 +11,7 @@
17859 tristate 'Parallel port support' CONFIG_PARPORT
17860 if [ "$CONFIG_PARPORT" != "n" ]; then
17861 dep_tristate ' PC-style hardware' CONFIG_PARPORT_PC $CONFIG_PARPORT
17862 + dep_tristate ' Asus WL500g parallel port' CONFIG_PARPORT_SPLINK $CONFIG_PARPORT
17863 if [ "$CONFIG_PARPORT_PC" != "n" -a "$CONFIG_SERIAL" != "n" ]; then
17864 if [ "$CONFIG_SERIAL" = "m" ]; then
17865 define_tristate CONFIG_PARPORT_PC_CML1 m
17866 diff -Nur linux-2.4.32/drivers/parport/Makefile linux-2.4.32-brcm/drivers/parport/Makefile
17867 --- linux-2.4.32/drivers/parport/Makefile 2004-08-08 01:26:05.000000000 +0200
17868 +++ linux-2.4.32-brcm/drivers/parport/Makefile 2005-12-16 23:39:11.364863000 +0100
17869 @@ -22,6 +22,7 @@
17870
17871 obj-$(CONFIG_PARPORT) += parport.o
17872 obj-$(CONFIG_PARPORT_PC) += parport_pc.o
17873 +obj-$(CONFIG_PARPORT_SPLINK) += parport_splink.o
17874 obj-$(CONFIG_PARPORT_PC_PCMCIA) += parport_cs.o
17875 obj-$(CONFIG_PARPORT_AMIGA) += parport_amiga.o
17876 obj-$(CONFIG_PARPORT_MFC3) += parport_mfc3.o
17877 diff -Nur linux-2.4.32/drivers/parport/parport_splink.c linux-2.4.32-brcm/drivers/parport/parport_splink.c
17878 --- linux-2.4.32/drivers/parport/parport_splink.c 1970-01-01 01:00:00.000000000 +0100
17879 +++ linux-2.4.32-brcm/drivers/parport/parport_splink.c 2005-12-16 23:39:11.364863000 +0100
17880 @@ -0,0 +1,345 @@
17881 +/* Low-level parallel port routines for the ASUS WL-500g built-in port
17882 + *
17883 + * Author: Nuno Grilo <nuno.grilo@netcabo.pt>
17884 + * Based on parport_pc source
17885 + */
17886 +
17887 +#include <linux/config.h>
17888 +#include <linux/module.h>
17889 +#include <linux/init.h>
17890 +#include <linux/ioport.h>
17891 +#include <linux/kernel.h>
17892 +#include <linux/slab.h>
17893 +#include <linux/parport.h>
17894 +#include <linux/parport_pc.h>
17895 +
17896 +#define SPLINK_ADDRESS 0xBF800010
17897 +
17898 +#undef DEBUG
17899 +
17900 +#ifdef DEBUG
17901 +#define DPRINTK printk
17902 +#else
17903 +#define DPRINTK(stuff...)
17904 +#endif
17905 +
17906 +
17907 +/* __parport_splink_frob_control differs from parport_splink_frob_control in that
17908 + * it doesn't do any extra masking. */
17909 +static __inline__ unsigned char __parport_splink_frob_control (struct parport *p,
17910 + unsigned char mask,
17911 + unsigned char val)
17912 +{
17913 + struct parport_pc_private *priv = p->physport->private_data;
17914 + unsigned char *io = (unsigned char *) p->base;
17915 + unsigned char ctr = priv->ctr;
17916 +#ifdef DEBUG_PARPORT
17917 + printk (KERN_DEBUG
17918 + "__parport_splink_frob_control(%02x,%02x): %02x -> %02x\n",
17919 + mask, val, ctr, ((ctr & ~mask) ^ val) & priv->ctr_writable);
17920 +#endif
17921 + ctr = (ctr & ~mask) ^ val;
17922 + ctr &= priv->ctr_writable; /* only write writable bits. */
17923 + *(io+2) = ctr;
17924 + priv->ctr = ctr; /* Update soft copy */
17925 + return ctr;
17926 +}
17927 +
17928 +
17929 +
17930 +static void parport_splink_data_forward (struct parport *p)
17931 +{
17932 + DPRINTK(KERN_DEBUG "parport_splink: parport_data_forward called\n");
17933 + __parport_splink_frob_control (p, 0x20, 0);
17934 +}
17935 +
17936 +static void parport_splink_data_reverse (struct parport *p)
17937 +{
17938 + DPRINTK(KERN_DEBUG "parport_splink: parport_data_forward called\n");
17939 + __parport_splink_frob_control (p, 0x20, 0x20);
17940 +}
17941 +
17942 +/*
17943 +static void parport_splink_interrupt(int irq, void *dev_id, struct pt_regs *regs)
17944 +{
17945 + DPRINTK(KERN_DEBUG "parport_splink: IRQ handler called\n");
17946 + parport_generic_irq(irq, (struct parport *) dev_id, regs);
17947 +}
17948 +*/
17949 +
17950 +static void parport_splink_enable_irq(struct parport *p)
17951 +{
17952 + DPRINTK(KERN_DEBUG "parport_splink: parport_splink_enable_irq called\n");
17953 + __parport_splink_frob_control (p, 0x10, 0x10);
17954 +}
17955 +
17956 +static void parport_splink_disable_irq(struct parport *p)
17957 +{
17958 + DPRINTK(KERN_DEBUG "parport_splink: parport_splink_disable_irq called\n");
17959 + __parport_splink_frob_control (p, 0x10, 0);
17960 +}
17961 +
17962 +static void parport_splink_init_state(struct pardevice *dev, struct parport_state *s)
17963 +{
17964 + DPRINTK(KERN_DEBUG "parport_splink: parport_splink_init_state called\n");
17965 + s->u.pc.ctr = 0xc | (dev->irq_func ? 0x10 : 0x0);
17966 + if (dev->irq_func &&
17967 + dev->port->irq != PARPORT_IRQ_NONE)
17968 + /* Set ackIntEn */
17969 + s->u.pc.ctr |= 0x10;
17970 +}
17971 +
17972 +static void parport_splink_save_state(struct parport *p, struct parport_state *s)
17973 +{
17974 + const struct parport_pc_private *priv = p->physport->private_data;
17975 + DPRINTK(KERN_DEBUG "parport_splink: parport_splink_save_state called\n");
17976 + s->u.pc.ctr = priv->ctr;
17977 +}
17978 +
17979 +static void parport_splink_restore_state(struct parport *p, struct parport_state *s)
17980 +{
17981 + struct parport_pc_private *priv = p->physport->private_data;
17982 + unsigned char *io = (unsigned char *) p->base;
17983 + unsigned char ctr = s->u.pc.ctr;
17984 +
17985 + DPRINTK(KERN_DEBUG "parport_splink: parport_splink_restore_state called\n");
17986 + *(io+2) = ctr;
17987 + priv->ctr = ctr;
17988 +}
17989 +
17990 +static void parport_splink_setup_interrupt(void) {
17991 + return;
17992 +}
17993 +
17994 +static void parport_splink_write_data(struct parport *p, unsigned char d) {
17995 + DPRINTK(KERN_DEBUG "parport_splink: write data called\n");
17996 + unsigned char *io = (unsigned char *) p->base;
17997 + *io = d;
17998 +}
17999 +
18000 +static unsigned char parport_splink_read_data(struct parport *p) {
18001 + DPRINTK(KERN_DEBUG "parport_splink: read data called\n");
18002 + unsigned char *io = (unsigned char *) p->base;
18003 + return *io;
18004 +}
18005 +
18006 +static void parport_splink_write_control(struct parport *p, unsigned char d)
18007 +{
18008 + const unsigned char wm = (PARPORT_CONTROL_STROBE |
18009 + PARPORT_CONTROL_AUTOFD |
18010 + PARPORT_CONTROL_INIT |
18011 + PARPORT_CONTROL_SELECT);
18012 +
18013 + DPRINTK(KERN_DEBUG "parport_splink: write control called\n");
18014 + /* Take this out when drivers have adapted to the newer interface. */
18015 + if (d & 0x20) {
18016 + printk (KERN_DEBUG "%s (%s): use data_reverse for this!\n",
18017 + p->name, p->cad->name);
18018 + parport_splink_data_reverse (p);
18019 + }
18020 +
18021 + __parport_splink_frob_control (p, wm, d & wm);
18022 +}
18023 +
18024 +static unsigned char parport_splink_read_control(struct parport *p)
18025 +{
18026 + const unsigned char wm = (PARPORT_CONTROL_STROBE |
18027 + PARPORT_CONTROL_AUTOFD |
18028 + PARPORT_CONTROL_INIT |
18029 + PARPORT_CONTROL_SELECT);
18030 + DPRINTK(KERN_DEBUG "parport_splink: read control called\n");
18031 + const struct parport_pc_private *priv = p->physport->private_data;
18032 + return priv->ctr & wm; /* Use soft copy */
18033 +}
18034 +
18035 +static unsigned char parport_splink_frob_control (struct parport *p, unsigned char mask,
18036 + unsigned char val)
18037 +{
18038 + const unsigned char wm = (PARPORT_CONTROL_STROBE |
18039 + PARPORT_CONTROL_AUTOFD |
18040 + PARPORT_CONTROL_INIT |
18041 + PARPORT_CONTROL_SELECT);
18042 +
18043 + DPRINTK(KERN_DEBUG "parport_splink: frob control called\n");
18044 + /* Take this out when drivers have adapted to the newer interface. */
18045 + if (mask & 0x20) {
18046 + printk (KERN_DEBUG "%s (%s): use data_%s for this!\n",
18047 + p->name, p->cad->name,
18048 + (val & 0x20) ? "reverse" : "forward");
18049 + if (val & 0x20)
18050 + parport_splink_data_reverse (p);
18051 + else
18052 + parport_splink_data_forward (p);
18053 + }
18054 +
18055 + /* Restrict mask and val to control lines. */
18056 + mask &= wm;
18057 + val &= wm;
18058 +
18059 + return __parport_splink_frob_control (p, mask, val);
18060 +}
18061 +
18062 +static unsigned char parport_splink_read_status(struct parport *p)
18063 +{
18064 + DPRINTK(KERN_DEBUG "parport_splink: read status called\n");
18065 + unsigned char *io = (unsigned char *) p->base;
18066 + return *(io+1);
18067 +}
18068 +
18069 +static void parport_splink_inc_use_count(void)
18070 +{
18071 +#ifdef MODULE
18072 + MOD_INC_USE_COUNT;
18073 +#endif
18074 +}
18075 +
18076 +static void parport_splink_dec_use_count(void)
18077 +{
18078 +#ifdef MODULE
18079 + MOD_DEC_USE_COUNT;
18080 +#endif
18081 +}
18082 +
18083 +static struct parport_operations parport_splink_ops =
18084 +{
18085 + parport_splink_write_data,
18086 + parport_splink_read_data,
18087 +
18088 + parport_splink_write_control,
18089 + parport_splink_read_control,
18090 + parport_splink_frob_control,
18091 +
18092 + parport_splink_read_status,
18093 +
18094 + parport_splink_enable_irq,
18095 + parport_splink_disable_irq,
18096 +
18097 + parport_splink_data_forward,
18098 + parport_splink_data_reverse,
18099 +
18100 + parport_splink_init_state,
18101 + parport_splink_save_state,
18102 + parport_splink_restore_state,
18103 +
18104 + parport_splink_inc_use_count,
18105 + parport_splink_dec_use_count,
18106 +
18107 + parport_ieee1284_epp_write_data,
18108 + parport_ieee1284_epp_read_data,
18109 + parport_ieee1284_epp_write_addr,
18110 + parport_ieee1284_epp_read_addr,
18111 +
18112 + parport_ieee1284_ecp_write_data,
18113 + parport_ieee1284_ecp_read_data,
18114 + parport_ieee1284_ecp_write_addr,
18115 +
18116 + parport_ieee1284_write_compat,
18117 + parport_ieee1284_read_nibble,
18118 + parport_ieee1284_read_byte,
18119 +};
18120 +
18121 +/* --- Initialisation code -------------------------------- */
18122 +
18123 +static struct parport *parport_splink_probe_port (unsigned long int base)
18124 +{
18125 + struct parport_pc_private *priv;
18126 + struct parport_operations *ops;
18127 + struct parport *p;
18128 +
18129 + if (check_mem_region(base, 3)) {
18130 + printk (KERN_DEBUG "parport (0x%lx): iomem region not available\n", base);
18131 + return NULL;
18132 + }
18133 + priv = kmalloc (sizeof (struct parport_pc_private), GFP_KERNEL);
18134 + if (!priv) {
18135 + printk (KERN_DEBUG "parport (0x%lx): no memory!\n", base);
18136 + return NULL;
18137 + }
18138 + ops = kmalloc (sizeof (struct parport_operations), GFP_KERNEL);
18139 + if (!ops) {
18140 + printk (KERN_DEBUG "parport (0x%lx): no memory for ops!\n",
18141 + base);
18142 + kfree (priv);
18143 + return NULL;
18144 + }
18145 + memcpy (ops, &parport_splink_ops, sizeof (struct parport_operations));
18146 + priv->ctr = 0xc;
18147 + priv->ctr_writable = 0xff;
18148 +
18149 + if (!(p = parport_register_port(base, PARPORT_IRQ_NONE,
18150 + PARPORT_DMA_NONE, ops))) {
18151 + printk (KERN_DEBUG "parport (0x%lx): registration failed!\n",
18152 + base);
18153 + kfree (priv);
18154 + kfree (ops);
18155 + return NULL;
18156 + }
18157 +
18158 + p->modes = PARPORT_MODE_PCSPP | PARPORT_MODE_SAFEININT;
18159 + p->size = (p->modes & PARPORT_MODE_EPP)?8:3;
18160 + p->private_data = priv;
18161 +
18162 + parport_proc_register(p);
18163 + request_mem_region (p->base, 3, p->name);
18164 +
18165 + /* Done probing. Now put the port into a sensible start-up state. */
18166 + parport_splink_write_data(p, 0);
18167 + parport_splink_data_forward (p);
18168 +
18169 + /* Now that we've told the sharing engine about the port, and
18170 + found out its characteristics, let the high-level drivers
18171 + know about it. */
18172 + parport_announce_port (p);
18173 +
18174 + DPRINTK(KERN_DEBUG "parport (0x%lx): init ok!\n",
18175 + base);
18176 + return p;
18177 +}
18178 +
18179 +static void parport_splink_unregister_port(struct parport *p) {
18180 + struct parport_pc_private *priv = p->private_data;
18181 + struct parport_operations *ops = p->ops;
18182 +
18183 + if (p->irq != PARPORT_IRQ_NONE)
18184 + free_irq(p->irq, p);
18185 + release_mem_region(p->base, 3);
18186 + parport_proc_unregister(p);
18187 + kfree (priv);
18188 + parport_unregister_port(p);
18189 + kfree (ops);
18190 +}
18191 +
18192 +
18193 +int parport_splink_init(void)
18194 +{
18195 + int ret;
18196 +
18197 + DPRINTK(KERN_DEBUG "parport_splink init called\n");
18198 + parport_splink_setup_interrupt();
18199 + ret = !parport_splink_probe_port(SPLINK_ADDRESS);
18200 +
18201 + return ret;
18202 +}
18203 +
18204 +void parport_splink_cleanup(void) {
18205 + struct parport *p = parport_enumerate(), *tmp;
18206 + DPRINTK(KERN_DEBUG "parport_splink cleanup called\n");
18207 + if (p->size) {
18208 + if (p->modes & PARPORT_MODE_PCSPP) {
18209 + while(p) {
18210 + tmp = p->next;
18211 + parport_splink_unregister_port(p);
18212 + p = tmp;
18213 + }
18214 + }
18215 + }
18216 +}
18217 +
18218 +MODULE_AUTHOR("Nuno Grilo <nuno.grilo@netcabo.pt>");
18219 +MODULE_DESCRIPTION("Parport Driver for ASUS WL-500g router builtin Port");
18220 +MODULE_SUPPORTED_DEVICE("ASUS WL-500g builtin Parallel Port");
18221 +MODULE_LICENSE("GPL");
18222 +
18223 +module_init(parport_splink_init)
18224 +module_exit(parport_splink_cleanup)
18225 +
18226 diff -Nur linux-2.4.32/drivers/pcmcia/bcm4710_generic.c linux-2.4.32-brcm/drivers/pcmcia/bcm4710_generic.c
18227 --- linux-2.4.32/drivers/pcmcia/bcm4710_generic.c 1970-01-01 01:00:00.000000000 +0100
18228 +++ linux-2.4.32-brcm/drivers/pcmcia/bcm4710_generic.c 2005-12-16 23:39:11.368863250 +0100
18229 @@ -0,0 +1,912 @@
18230 +/*
18231 + *
18232 + * bcm47xx pcmcia driver
18233 + *
18234 + * Copyright 2004, Broadcom Corporation
18235 + * All Rights Reserved.
18236 + *
18237 + * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY
18238 + * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM
18239 + * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS
18240 + * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE.
18241 + *
18242 + * Based on sa1100_generic.c from www.handhelds.org,
18243 + * and au1000_generic.c from oss.sgi.com.
18244 + *
18245 + * $Id: bcm4710_generic.c,v 1.1 2005/03/16 13:50:00 wbx Exp $
18246 + */
18247 +#include <linux/module.h>
18248 +#include <linux/init.h>
18249 +#include <linux/config.h>
18250 +#include <linux/delay.h>
18251 +#include <linux/ioport.h>
18252 +#include <linux/kernel.h>
18253 +#include <linux/tqueue.h>
18254 +#include <linux/timer.h>
18255 +#include <linux/mm.h>
18256 +#include <linux/proc_fs.h>
18257 +#include <linux/version.h>
18258 +#include <linux/types.h>
18259 +#include <linux/vmalloc.h>
18260 +
18261 +#include <pcmcia/version.h>
18262 +#include <pcmcia/cs_types.h>
18263 +#include <pcmcia/cs.h>
18264 +#include <pcmcia/ss.h>
18265 +#include <pcmcia/bulkmem.h>
18266 +#include <pcmcia/cistpl.h>
18267 +#include <pcmcia/bus_ops.h>
18268 +#include "cs_internal.h"
18269 +
18270 +#include <asm/io.h>
18271 +#include <asm/irq.h>
18272 +#include <asm/system.h>
18273 +
18274 +#include <typedefs.h>
18275 +#include <bcm4710.h>
18276 +#include <sbextif.h>
18277 +
18278 +#include "bcm4710pcmcia.h"
18279 +
18280 +#ifdef PCMCIA_DEBUG
18281 +static int pc_debug = PCMCIA_DEBUG;
18282 +#endif
18283 +
18284 +MODULE_DESCRIPTION("Linux PCMCIA Card Services: bcm47xx Socket Controller");
18285 +
18286 +/* This structure maintains housekeeping state for each socket, such
18287 + * as the last known values of the card detect pins, or the Card Services
18288 + * callback value associated with the socket:
18289 + */
18290 +static struct bcm47xx_pcmcia_socket *pcmcia_socket;
18291 +static int socket_count;
18292 +
18293 +
18294 +/* Returned by the low-level PCMCIA interface: */
18295 +static struct pcmcia_low_level *pcmcia_low_level;
18296 +
18297 +/* Event poll timer structure */
18298 +static struct timer_list poll_timer;
18299 +
18300 +
18301 +/* Prototypes for routines which are used internally: */
18302 +
18303 +static int bcm47xx_pcmcia_driver_init(void);
18304 +static void bcm47xx_pcmcia_driver_shutdown(void);
18305 +static void bcm47xx_pcmcia_task_handler(void *data);
18306 +static void bcm47xx_pcmcia_poll_event(unsigned long data);
18307 +static void bcm47xx_pcmcia_interrupt(int irq, void *dev, struct pt_regs *regs);
18308 +static struct tq_struct bcm47xx_pcmcia_task;
18309 +
18310 +#ifdef CONFIG_PROC_FS
18311 +static int bcm47xx_pcmcia_proc_status(char *buf, char **start,
18312 + off_t pos, int count, int *eof, void *data);
18313 +#endif
18314 +
18315 +
18316 +/* Prototypes for operations which are exported to the
18317 + * in-kernel PCMCIA core:
18318 + */
18319 +
18320 +static int bcm47xx_pcmcia_init(unsigned int sock);
18321 +static int bcm47xx_pcmcia_suspend(unsigned int sock);
18322 +static int bcm47xx_pcmcia_register_callback(unsigned int sock,
18323 + void (*handler)(void *, unsigned int), void *info);
18324 +static int bcm47xx_pcmcia_inquire_socket(unsigned int sock, socket_cap_t *cap);
18325 +static int bcm47xx_pcmcia_get_status(unsigned int sock, u_int *value);
18326 +static int bcm47xx_pcmcia_get_socket(unsigned int sock, socket_state_t *state);
18327 +static int bcm47xx_pcmcia_set_socket(unsigned int sock, socket_state_t *state);
18328 +static int bcm47xx_pcmcia_get_io_map(unsigned int sock, struct pccard_io_map *io);
18329 +static int bcm47xx_pcmcia_set_io_map(unsigned int sock, struct pccard_io_map *io);
18330 +static int bcm47xx_pcmcia_get_mem_map(unsigned int sock, struct pccard_mem_map *mem);
18331 +static int bcm47xx_pcmcia_set_mem_map(unsigned int sock, struct pccard_mem_map *mem);
18332 +#ifdef CONFIG_PROC_FS
18333 +static void bcm47xx_pcmcia_proc_setup(unsigned int sock, struct proc_dir_entry *base);
18334 +#endif
18335 +
18336 +static struct pccard_operations bcm47xx_pcmcia_operations = {
18337 + bcm47xx_pcmcia_init,
18338 + bcm47xx_pcmcia_suspend,
18339 + bcm47xx_pcmcia_register_callback,
18340 + bcm47xx_pcmcia_inquire_socket,
18341 + bcm47xx_pcmcia_get_status,
18342 + bcm47xx_pcmcia_get_socket,
18343 + bcm47xx_pcmcia_set_socket,
18344 + bcm47xx_pcmcia_get_io_map,
18345 + bcm47xx_pcmcia_set_io_map,
18346 + bcm47xx_pcmcia_get_mem_map,
18347 + bcm47xx_pcmcia_set_mem_map,
18348 +#ifdef CONFIG_PROC_FS
18349 + bcm47xx_pcmcia_proc_setup
18350 +#endif
18351 +};
18352 +
18353 +
18354 +/*
18355 + * bcm47xx_pcmcia_driver_init()
18356 + *
18357 + * This routine performs a basic sanity check to ensure that this
18358 + * kernel has been built with the appropriate board-specific low-level
18359 + * PCMCIA support, performs low-level PCMCIA initialization, registers
18360 + * this socket driver with Card Services, and then spawns the daemon
18361 + * thread which is the real workhorse of the socket driver.
18362 + *
18363 + * Please see linux/Documentation/arm/SA1100/PCMCIA for more information
18364 + * on the low-level kernel interface.
18365 + *
18366 + * Returns: 0 on success, -1 on error
18367 + */
18368 +static int __init bcm47xx_pcmcia_driver_init(void)
18369 +{
18370 + servinfo_t info;
18371 + struct pcmcia_init pcmcia_init;
18372 + struct pcmcia_state state;
18373 + unsigned int i;
18374 + unsigned long tmp;
18375 +
18376 +
18377 + printk("\nBCM47XX PCMCIA (CS release %s)\n", CS_RELEASE);
18378 +
18379 + CardServices(GetCardServicesInfo, &info);
18380 +
18381 + if (info.Revision != CS_RELEASE_CODE) {
18382 + printk(KERN_ERR "Card Services release codes do not match\n");
18383 + return -1;
18384 + }
18385 +
18386 +#ifdef CONFIG_BCM4710
18387 + pcmcia_low_level=&bcm4710_pcmcia_ops;
18388 +#else
18389 +#error Unsupported Broadcom BCM47XX board.
18390 +#endif
18391 +
18392 + pcmcia_init.handler=bcm47xx_pcmcia_interrupt;
18393 +
18394 + if ((socket_count = pcmcia_low_level->init(&pcmcia_init)) < 0) {
18395 + printk(KERN_ERR "Unable to initialize PCMCIA service.\n");
18396 + return -EIO;
18397 + } else {
18398 + printk("\t%d PCMCIA sockets initialized.\n", socket_count);
18399 + }
18400 +
18401 + pcmcia_socket =
18402 + kmalloc(sizeof(struct bcm47xx_pcmcia_socket) * socket_count,
18403 + GFP_KERNEL);
18404 + memset(pcmcia_socket, 0,
18405 + sizeof(struct bcm47xx_pcmcia_socket) * socket_count);
18406 + if (!pcmcia_socket) {
18407 + printk(KERN_ERR "Card Services can't get memory \n");
18408 + return -1;
18409 + }
18410 +
18411 + for (i = 0; i < socket_count; i++) {
18412 + if (pcmcia_low_level->socket_state(i, &state) < 0) {
18413 + printk(KERN_ERR "Unable to get PCMCIA status\n");
18414 + return -EIO;
18415 + }
18416 + pcmcia_socket[i].k_state = state;
18417 + pcmcia_socket[i].cs_state.csc_mask = SS_DETECT;
18418 +
18419 + if (i == 0) {
18420 + pcmcia_socket[i].virt_io =
18421 + (unsigned long)ioremap_nocache(EXTIF_PCMCIA_IOBASE(BCM4710_EXTIF), 0x1000);
18422 + /* Substract ioport base which gets added by in/out */
18423 + pcmcia_socket[i].virt_io -= mips_io_port_base;
18424 + pcmcia_socket[i].phys_attr =
18425 + (unsigned long)EXTIF_PCMCIA_CFGBASE(BCM4710_EXTIF);
18426 + pcmcia_socket[i].phys_mem =
18427 + (unsigned long)EXTIF_PCMCIA_MEMBASE(BCM4710_EXTIF);
18428 + } else {
18429 + printk(KERN_ERR "bcm4710: socket 1 not supported\n");
18430 + return 1;
18431 + }
18432 + }
18433 +
18434 + /* Only advertise as many sockets as we can detect: */
18435 + if (register_ss_entry(socket_count, &bcm47xx_pcmcia_operations) < 0) {
18436 + printk(KERN_ERR "Unable to register socket service routine\n");
18437 + return -ENXIO;
18438 + }
18439 +
18440 + /* Start the event poll timer.
18441 + * It will reschedule by itself afterwards.
18442 + */
18443 + bcm47xx_pcmcia_poll_event(0);
18444 +
18445 + DEBUG(1, "bcm4710: initialization complete\n");
18446 + return 0;
18447 +
18448 +}
18449 +
18450 +module_init(bcm47xx_pcmcia_driver_init);
18451 +
18452 +
18453 +/*
18454 + * bcm47xx_pcmcia_driver_shutdown()
18455 + *
18456 + * Invokes the low-level kernel service to free IRQs associated with this
18457 + * socket controller and reset GPIO edge detection.
18458 + */
18459 +static void __exit bcm47xx_pcmcia_driver_shutdown(void)
18460 +{
18461 + int i;
18462 +
18463 + del_timer_sync(&poll_timer);
18464 + unregister_ss_entry(&bcm47xx_pcmcia_operations);
18465 + pcmcia_low_level->shutdown();
18466 + flush_scheduled_tasks();
18467 + for (i = 0; i < socket_count; i++) {
18468 + if (pcmcia_socket[i].virt_io)
18469 + iounmap((void *)pcmcia_socket[i].virt_io);
18470 + if (pcmcia_socket[i].phys_attr)
18471 + iounmap((void *)pcmcia_socket[i].phys_attr);
18472 + if (pcmcia_socket[i].phys_mem)
18473 + iounmap((void *)pcmcia_socket[i].phys_mem);
18474 + }
18475 + DEBUG(1, "bcm4710: shutdown complete\n");
18476 +}
18477 +
18478 +module_exit(bcm47xx_pcmcia_driver_shutdown);
18479 +
18480 +/*
18481 + * bcm47xx_pcmcia_init()
18482 + * We perform all of the interesting initialization tasks in
18483 + * bcm47xx_pcmcia_driver_init().
18484 + *
18485 + * Returns: 0
18486 + */
18487 +static int bcm47xx_pcmcia_init(unsigned int sock)
18488 +{
18489 + DEBUG(1, "%s(): initializing socket %u\n", __FUNCTION__, sock);
18490 +
18491 + return 0;
18492 +}
18493 +
18494 +/*
18495 + * bcm47xx_pcmcia_suspend()
18496 + *
18497 + * We don't currently perform any actions on a suspend.
18498 + *
18499 + * Returns: 0
18500 + */
18501 +static int bcm47xx_pcmcia_suspend(unsigned int sock)
18502 +{
18503 + DEBUG(1, "%s(): suspending socket %u\n", __FUNCTION__, sock);
18504 +
18505 + return 0;
18506 +}
18507 +
18508 +
18509 +/*
18510 + * bcm47xx_pcmcia_events()
18511 + *
18512 + * Helper routine to generate a Card Services event mask based on
18513 + * state information obtained from the kernel low-level PCMCIA layer
18514 + * in a recent (and previous) sampling. Updates `prev_state'.
18515 + *
18516 + * Returns: an event mask for the given socket state.
18517 + */
18518 +static inline unsigned
18519 +bcm47xx_pcmcia_events(struct pcmcia_state *state,
18520 + struct pcmcia_state *prev_state,
18521 + unsigned int mask, unsigned int flags)
18522 +{
18523 + unsigned int events=0;
18524 +
18525 + if (state->bvd1 != prev_state->bvd1) {
18526 +
18527 + DEBUG(3, "%s(): card BVD1 value %u\n", __FUNCTION__, state->bvd1);
18528 +
18529 + events |= mask & (flags & SS_IOCARD) ? SS_STSCHG : SS_BATDEAD;
18530 + }
18531 +
18532 + if (state->bvd2 != prev_state->bvd2) {
18533 +
18534 + DEBUG(3, "%s(): card BVD2 value %u\n", __FUNCTION__, state->bvd2);
18535 +
18536 + events |= mask & (flags & SS_IOCARD) ? 0 : SS_BATWARN;
18537 + }
18538 +
18539 + if (state->detect != prev_state->detect) {
18540 +
18541 + DEBUG(3, "%s(): card detect value %u\n", __FUNCTION__, state->detect);
18542 +
18543 + events |= mask & SS_DETECT;
18544 + }
18545 +
18546 +
18547 + if (state->ready != prev_state->ready) {
18548 +
18549 + DEBUG(3, "%s(): card ready value %u\n", __FUNCTION__, state->ready);
18550 +
18551 + events |= mask & ((flags & SS_IOCARD) ? 0 : SS_READY);
18552 + }
18553 +
18554 + if (events != 0) {
18555 + DEBUG(2, "events: %s%s%s%s%s\n",
18556 + (events & SS_DETECT) ? "DETECT " : "",
18557 + (events & SS_READY) ? "READY " : "",
18558 + (events & SS_BATDEAD) ? "BATDEAD " : "",
18559 + (events & SS_BATWARN) ? "BATWARN " : "",
18560 + (events & SS_STSCHG) ? "STSCHG " : "");
18561 + }
18562 +
18563 + *prev_state=*state;
18564 + return events;
18565 +}
18566 +
18567 +
18568 +/*
18569 + * bcm47xx_pcmcia_task_handler()
18570 + *
18571 + * Processes serviceable socket events using the "eventd" thread context.
18572 + *
18573 + * Event processing (specifically, the invocation of the Card Services event
18574 + * callback) occurs in this thread rather than in the actual interrupt
18575 + * handler due to the use of scheduling operations in the PCMCIA core.
18576 + */
18577 +static void bcm47xx_pcmcia_task_handler(void *data)
18578 +{
18579 + struct pcmcia_state state;
18580 + int i, events, irq_status;
18581 +
18582 + DEBUG(4, "%s(): entering PCMCIA monitoring thread\n", __FUNCTION__);
18583 +
18584 + for (i = 0; i < socket_count; i++) {
18585 + if ((irq_status = pcmcia_low_level->socket_state(i, &state)) < 0)
18586 + printk(KERN_ERR "Error in kernel low-level PCMCIA service.\n");
18587 +
18588 + events = bcm47xx_pcmcia_events(&state,
18589 + &pcmcia_socket[i].k_state,
18590 + pcmcia_socket[i].cs_state.csc_mask,
18591 + pcmcia_socket[i].cs_state.flags);
18592 +
18593 + if (pcmcia_socket[i].handler != NULL) {
18594 + pcmcia_socket[i].handler(pcmcia_socket[i].handler_info,
18595 + events);
18596 + }
18597 + }
18598 +}
18599 +
18600 +static struct tq_struct bcm47xx_pcmcia_task = {
18601 + routine: bcm47xx_pcmcia_task_handler
18602 +};
18603 +
18604 +
18605 +/*
18606 + * bcm47xx_pcmcia_poll_event()
18607 + *
18608 + * Let's poll for events in addition to IRQs since IRQ only is unreliable...
18609 + */
18610 +static void bcm47xx_pcmcia_poll_event(unsigned long dummy)
18611 +{
18612 + DEBUG(4, "%s(): polling for events\n", __FUNCTION__);
18613 +
18614 + poll_timer.function = bcm47xx_pcmcia_poll_event;
18615 + poll_timer.expires = jiffies + BCM47XX_PCMCIA_POLL_PERIOD;
18616 + add_timer(&poll_timer);
18617 + schedule_task(&bcm47xx_pcmcia_task);
18618 +}
18619 +
18620 +
18621 +/*
18622 + * bcm47xx_pcmcia_interrupt()
18623 + *
18624 + * Service routine for socket driver interrupts (requested by the
18625 + * low-level PCMCIA init() operation via bcm47xx_pcmcia_thread()).
18626 + *
18627 + * The actual interrupt-servicing work is performed by
18628 + * bcm47xx_pcmcia_task(), largely because the Card Services event-
18629 + * handling code performs scheduling operations which cannot be
18630 + * executed from within an interrupt context.
18631 + */
18632 +static void
18633 +bcm47xx_pcmcia_interrupt(int irq, void *dev, struct pt_regs *regs)
18634 +{
18635 + DEBUG(3, "%s(): servicing IRQ %d\n", __FUNCTION__, irq);
18636 + schedule_task(&bcm47xx_pcmcia_task);
18637 +}
18638 +
18639 +
18640 +/*
18641 + * bcm47xx_pcmcia_register_callback()
18642 + *
18643 + * Implements the register_callback() operation for the in-kernel
18644 + * PCMCIA service (formerly SS_RegisterCallback in Card Services). If
18645 + * the function pointer `handler' is not NULL, remember the callback
18646 + * location in the state for `sock', and increment the usage counter
18647 + * for the driver module. (The callback is invoked from the interrupt
18648 + * service routine, bcm47xx_pcmcia_interrupt(), to notify Card Services
18649 + * of interesting events.) Otherwise, clear the callback pointer in the
18650 + * socket state and decrement the module usage count.
18651 + *
18652 + * Returns: 0
18653 + */
18654 +static int
18655 +bcm47xx_pcmcia_register_callback(unsigned int sock,
18656 + void (*handler)(void *, unsigned int), void *info)
18657 +{
18658 + if (handler == NULL) {
18659 + pcmcia_socket[sock].handler = NULL;
18660 + MOD_DEC_USE_COUNT;
18661 + } else {
18662 + MOD_INC_USE_COUNT;
18663 + pcmcia_socket[sock].handler = handler;
18664 + pcmcia_socket[sock].handler_info = info;
18665 + }
18666 + return 0;
18667 +}
18668 +
18669 +
18670 +/*
18671 + * bcm47xx_pcmcia_inquire_socket()
18672 + *
18673 + * Implements the inquire_socket() operation for the in-kernel PCMCIA
18674 + * service (formerly SS_InquireSocket in Card Services). Of note is
18675 + * the setting of the SS_CAP_PAGE_REGS bit in the `features' field of
18676 + * `cap' to "trick" Card Services into tolerating large "I/O memory"
18677 + * addresses. Also set is SS_CAP_STATIC_MAP, which disables the memory
18678 + * resource database check. (Mapped memory is set up within the socket
18679 + * driver itself.)
18680 + *
18681 + * In conjunction with the STATIC_MAP capability is a new field,
18682 + * `io_offset', recommended by David Hinds. Rather than go through
18683 + * the SetIOMap interface (which is not quite suited for communicating
18684 + * window locations up from the socket driver), we just pass up
18685 + * an offset which is applied to client-requested base I/O addresses
18686 + * in alloc_io_space().
18687 + *
18688 + * Returns: 0 on success, -1 if no pin has been configured for `sock'
18689 + */
18690 +static int
18691 +bcm47xx_pcmcia_inquire_socket(unsigned int sock, socket_cap_t *cap)
18692 +{
18693 + struct pcmcia_irq_info irq_info;
18694 +
18695 + if (sock >= socket_count) {
18696 + printk(KERN_ERR "bcm47xx: socket %u not configured\n", sock);
18697 + return -1;
18698 + }
18699 +
18700 + /* SS_CAP_PAGE_REGS: used by setup_cis_mem() in cistpl.c to set the
18701 + * force_low argument to validate_mem() in rsrc_mgr.c -- since in
18702 + * general, the mapped * addresses of the PCMCIA memory regions
18703 + * will not be within 0xffff, setting force_low would be
18704 + * undesirable.
18705 + *
18706 + * SS_CAP_STATIC_MAP: don't bother with the (user-configured) memory
18707 + * resource database; we instead pass up physical address ranges
18708 + * and allow other parts of Card Services to deal with remapping.
18709 + *
18710 + * SS_CAP_PCCARD: we can deal with 16-bit PCMCIA & CF cards, but
18711 + * not 32-bit CardBus devices.
18712 + */
18713 + cap->features = (SS_CAP_PAGE_REGS | SS_CAP_STATIC_MAP | SS_CAP_PCCARD);
18714 +
18715 + irq_info.sock = sock;
18716 + irq_info.irq = -1;
18717 +
18718 + if (pcmcia_low_level->get_irq_info(&irq_info) < 0) {
18719 + printk(KERN_ERR "Error obtaining IRQ info socket %u\n", sock);
18720 + return -1;
18721 + }
18722 +
18723 + cap->irq_mask = 0;
18724 + cap->map_size = PAGE_SIZE;
18725 + cap->pci_irq = irq_info.irq;
18726 + cap->io_offset = pcmcia_socket[sock].virt_io;
18727 +
18728 + return 0;
18729 +}
18730 +
18731 +
18732 +/*
18733 + * bcm47xx_pcmcia_get_status()
18734 + *
18735 + * Implements the get_status() operation for the in-kernel PCMCIA
18736 + * service (formerly SS_GetStatus in Card Services). Essentially just
18737 + * fills in bits in `status' according to internal driver state or
18738 + * the value of the voltage detect chipselect register.
18739 + *
18740 + * As a debugging note, during card startup, the PCMCIA core issues
18741 + * three set_socket() commands in a row the first with RESET deasserted,
18742 + * the second with RESET asserted, and the last with RESET deasserted
18743 + * again. Following the third set_socket(), a get_status() command will
18744 + * be issued. The kernel is looking for the SS_READY flag (see
18745 + * setup_socket(), reset_socket(), and unreset_socket() in cs.c).
18746 + *
18747 + * Returns: 0
18748 + */
18749 +static int
18750 +bcm47xx_pcmcia_get_status(unsigned int sock, unsigned int *status)
18751 +{
18752 + struct pcmcia_state state;
18753 +
18754 +
18755 + if ((pcmcia_low_level->socket_state(sock, &state)) < 0) {
18756 + printk(KERN_ERR "Unable to get PCMCIA status from kernel.\n");
18757 + return -1;
18758 + }
18759 +
18760 + pcmcia_socket[sock].k_state = state;
18761 +
18762 + *status = state.detect ? SS_DETECT : 0;
18763 +
18764 + *status |= state.ready ? SS_READY : 0;
18765 +
18766 + /* The power status of individual sockets is not available
18767 + * explicitly from the hardware, so we just remember the state
18768 + * and regurgitate it upon request:
18769 + */
18770 + *status |= pcmcia_socket[sock].cs_state.Vcc ? SS_POWERON : 0;
18771 +
18772 + if (pcmcia_socket[sock].cs_state.flags & SS_IOCARD)
18773 + *status |= state.bvd1 ? SS_STSCHG : 0;
18774 + else {
18775 + if (state.bvd1 == 0)
18776 + *status |= SS_BATDEAD;
18777 + else if (state.bvd2 == 0)
18778 + *status |= SS_BATWARN;
18779 + }
18780 +
18781 + *status |= state.vs_3v ? SS_3VCARD : 0;
18782 +
18783 + *status |= state.vs_Xv ? SS_XVCARD : 0;
18784 +
18785 + DEBUG(2, "\tstatus: %s%s%s%s%s%s%s%s\n",
18786 + (*status&SS_DETECT)?"DETECT ":"",
18787 + (*status&SS_READY)?"READY ":"",
18788 + (*status&SS_BATDEAD)?"BATDEAD ":"",
18789 + (*status&SS_BATWARN)?"BATWARN ":"",
18790 + (*status&SS_POWERON)?"POWERON ":"",
18791 + (*status&SS_STSCHG)?"STSCHG ":"",
18792 + (*status&SS_3VCARD)?"3VCARD ":"",
18793 + (*status&SS_XVCARD)?"XVCARD ":"");
18794 +
18795 + return 0;
18796 +}
18797 +
18798 +
18799 +/*
18800 + * bcm47xx_pcmcia_get_socket()
18801 + *
18802 + * Implements the get_socket() operation for the in-kernel PCMCIA
18803 + * service (formerly SS_GetSocket in Card Services). Not a very
18804 + * exciting routine.
18805 + *
18806 + * Returns: 0
18807 + */
18808 +static int
18809 +bcm47xx_pcmcia_get_socket(unsigned int sock, socket_state_t *state)
18810 +{
18811 + DEBUG(2, "%s() for sock %u\n", __FUNCTION__, sock);
18812 +
18813 + /* This information was given to us in an earlier call to set_socket(),
18814 + * so we're just regurgitating it here:
18815 + */
18816 + *state = pcmcia_socket[sock].cs_state;
18817 + return 0;
18818 +}
18819 +
18820 +
18821 +/*
18822 + * bcm47xx_pcmcia_set_socket()
18823 + *
18824 + * Implements the set_socket() operation for the in-kernel PCMCIA
18825 + * service (formerly SS_SetSocket in Card Services). We more or
18826 + * less punt all of this work and let the kernel handle the details
18827 + * of power configuration, reset, &c. We also record the value of
18828 + * `state' in order to regurgitate it to the PCMCIA core later.
18829 + *
18830 + * Returns: 0
18831 + */
18832 +static int
18833 +bcm47xx_pcmcia_set_socket(unsigned int sock, socket_state_t *state)
18834 +{
18835 + struct pcmcia_configure configure;
18836 +
18837 + DEBUG(2, "\tmask: %s%s%s%s%s%s\n\tflags: %s%s%s%s%s%s\n"
18838 + "\tVcc %d Vpp %d irq %d\n",
18839 + (state->csc_mask == 0) ? "<NONE>" : "",
18840 + (state->csc_mask & SS_DETECT) ? "DETECT " : "",
18841 + (state->csc_mask & SS_READY) ? "READY " : "",
18842 + (state->csc_mask & SS_BATDEAD) ? "BATDEAD " : "",
18843 + (state->csc_mask & SS_BATWARN) ? "BATWARN " : "",
18844 + (state->csc_mask & SS_STSCHG) ? "STSCHG " : "",
18845 + (state->flags == 0) ? "<NONE>" : "",
18846 + (state->flags & SS_PWR_AUTO) ? "PWR_AUTO " : "",
18847 + (state->flags & SS_IOCARD) ? "IOCARD " : "",
18848 + (state->flags & SS_RESET) ? "RESET " : "",
18849 + (state->flags & SS_SPKR_ENA) ? "SPKR_ENA " : "",
18850 + (state->flags & SS_OUTPUT_ENA) ? "OUTPUT_ENA " : "",
18851 + state->Vcc, state->Vpp, state->io_irq);
18852 +
18853 + configure.sock = sock;
18854 + configure.vcc = state->Vcc;
18855 + configure.vpp = state->Vpp;
18856 + configure.output = (state->flags & SS_OUTPUT_ENA) ? 1 : 0;
18857 + configure.speaker = (state->flags & SS_SPKR_ENA) ? 1 : 0;
18858 + configure.reset = (state->flags & SS_RESET) ? 1 : 0;
18859 +
18860 + if (pcmcia_low_level->configure_socket(&configure) < 0) {
18861 + printk(KERN_ERR "Unable to configure socket %u\n", sock);
18862 + return -1;
18863 + }
18864 +
18865 + pcmcia_socket[sock].cs_state = *state;
18866 + return 0;
18867 +}
18868 +
18869 +
18870 +/*
18871 + * bcm47xx_pcmcia_get_io_map()
18872 + *
18873 + * Implements the get_io_map() operation for the in-kernel PCMCIA
18874 + * service (formerly SS_GetIOMap in Card Services). Just returns an
18875 + * I/O map descriptor which was assigned earlier by a set_io_map().
18876 + *
18877 + * Returns: 0 on success, -1 if the map index was out of range
18878 + */
18879 +static int
18880 +bcm47xx_pcmcia_get_io_map(unsigned int sock, struct pccard_io_map *map)
18881 +{
18882 + DEBUG(2, "bcm47xx_pcmcia_get_io_map: sock %d\n", sock);
18883 +
18884 + if (map->map >= MAX_IO_WIN) {
18885 + printk(KERN_ERR "%s(): map (%d) out of range\n",
18886 + __FUNCTION__, map->map);
18887 + return -1;
18888 + }
18889 +
18890 + *map = pcmcia_socket[sock].io_map[map->map];
18891 + return 0;
18892 +}
18893 +
18894 +
18895 +/*
18896 + * bcm47xx_pcmcia_set_io_map()
18897 + *
18898 + * Implements the set_io_map() operation for the in-kernel PCMCIA
18899 + * service (formerly SS_SetIOMap in Card Services). We configure
18900 + * the map speed as requested, but override the address ranges
18901 + * supplied by Card Services.
18902 + *
18903 + * Returns: 0 on success, -1 on error
18904 + */
18905 +int
18906 +bcm47xx_pcmcia_set_io_map(unsigned int sock, struct pccard_io_map *map)
18907 +{
18908 + unsigned int speed;
18909 + unsigned long start;
18910 +
18911 + DEBUG(2, "\tmap %u speed %u\n\tstart 0x%08lx stop 0x%08lx\n"
18912 + "\tflags: %s%s%s%s%s%s%s%s\n",
18913 + map->map, map->speed, map->start, map->stop,
18914 + (map->flags == 0) ? "<NONE>" : "",
18915 + (map->flags & MAP_ACTIVE) ? "ACTIVE " : "",
18916 + (map->flags & MAP_16BIT) ? "16BIT " : "",
18917 + (map->flags & MAP_AUTOSZ) ? "AUTOSZ " : "",
18918 + (map->flags & MAP_0WS) ? "0WS " : "",
18919 + (map->flags & MAP_WRPROT) ? "WRPROT " : "",
18920 + (map->flags & MAP_USE_WAIT) ? "USE_WAIT " : "",
18921 + (map->flags & MAP_PREFETCH) ? "PREFETCH " : "");
18922 +
18923 + if (map->map >= MAX_IO_WIN) {
18924 + printk(KERN_ERR "%s(): map (%d) out of range\n",
18925 + __FUNCTION__, map->map);
18926 + return -1;
18927 + }
18928 +
18929 + if (map->flags & MAP_ACTIVE) {
18930 + speed = (map->speed > 0) ? map->speed : BCM47XX_PCMCIA_IO_SPEED;
18931 + pcmcia_socket[sock].speed_io = speed;
18932 + }
18933 +
18934 + start = map->start;
18935 +
18936 + if (map->stop == 1) {
18937 + map->stop = PAGE_SIZE - 1;
18938 + }
18939 +
18940 + map->start = pcmcia_socket[sock].virt_io;
18941 + map->stop = map->start + (map->stop - start);
18942 + pcmcia_socket[sock].io_map[map->map] = *map;
18943 + DEBUG(2, "set_io_map %d start %x stop %x\n",
18944 + map->map, map->start, map->stop);
18945 + return 0;
18946 +}
18947 +
18948 +
18949 +/*
18950 + * bcm47xx_pcmcia_get_mem_map()
18951 + *
18952 + * Implements the get_mem_map() operation for the in-kernel PCMCIA
18953 + * service (formerly SS_GetMemMap in Card Services). Just returns a
18954 + * memory map descriptor which was assigned earlier by a
18955 + * set_mem_map() request.
18956 + *
18957 + * Returns: 0 on success, -1 if the map index was out of range
18958 + */
18959 +static int
18960 +bcm47xx_pcmcia_get_mem_map(unsigned int sock, struct pccard_mem_map *map)
18961 +{
18962 + DEBUG(2, "%s() for sock %u\n", __FUNCTION__, sock);
18963 +
18964 + if (map->map >= MAX_WIN) {
18965 + printk(KERN_ERR "%s(): map (%d) out of range\n",
18966 + __FUNCTION__, map->map);
18967 + return -1;
18968 + }
18969 +
18970 + *map = pcmcia_socket[sock].mem_map[map->map];
18971 + return 0;
18972 +}
18973 +
18974 +
18975 +/*
18976 + * bcm47xx_pcmcia_set_mem_map()
18977 + *
18978 + * Implements the set_mem_map() operation for the in-kernel PCMCIA
18979 + * service (formerly SS_SetMemMap in Card Services). We configure
18980 + * the map speed as requested, but override the address ranges
18981 + * supplied by Card Services.
18982 + *
18983 + * Returns: 0 on success, -1 on error
18984 + */
18985 +static int
18986 +bcm47xx_pcmcia_set_mem_map(unsigned int sock, struct pccard_mem_map *map)
18987 +{
18988 + unsigned int speed;
18989 + unsigned long start;
18990 + u_long flags;
18991 +
18992 + if (map->map >= MAX_WIN) {
18993 + printk(KERN_ERR "%s(): map (%d) out of range\n",
18994 + __FUNCTION__, map->map);
18995 + return -1;
18996 + }
18997 +
18998 + DEBUG(2, "\tmap %u speed %u\n\tsys_start %#lx\n"
18999 + "\tsys_stop %#lx\n\tcard_start %#x\n"
19000 + "\tflags: %s%s%s%s%s%s%s%s\n",
19001 + map->map, map->speed, map->sys_start, map->sys_stop,
19002 + map->card_start, (map->flags == 0) ? "<NONE>" : "",
19003 + (map->flags & MAP_ACTIVE) ? "ACTIVE " : "",
19004 + (map->flags & MAP_16BIT) ? "16BIT " : "",
19005 + (map->flags & MAP_AUTOSZ) ? "AUTOSZ " : "",
19006 + (map->flags & MAP_0WS) ? "0WS " : "",
19007 + (map->flags & MAP_WRPROT) ? "WRPROT " : "",
19008 + (map->flags & MAP_ATTRIB) ? "ATTRIB " : "",
19009 + (map->flags & MAP_USE_WAIT) ? "USE_WAIT " : "");
19010 +
19011 + if (map->flags & MAP_ACTIVE) {
19012 + /* When clients issue RequestMap, the access speed is not always
19013 + * properly configured:
19014 + */
19015 + speed = (map->speed > 0) ? map->speed : BCM47XX_PCMCIA_MEM_SPEED;
19016 +
19017 + /* TBD */
19018 + if (map->flags & MAP_ATTRIB) {
19019 + pcmcia_socket[sock].speed_attr = speed;
19020 + } else {
19021 + pcmcia_socket[sock].speed_mem = speed;
19022 + }
19023 + }
19024 +
19025 + save_flags(flags);
19026 + cli();
19027 + start = map->sys_start;
19028 +
19029 + if (map->sys_stop == 0)
19030 + map->sys_stop = PAGE_SIZE - 1;
19031 +
19032 + if (map->flags & MAP_ATTRIB) {
19033 + map->sys_start = pcmcia_socket[sock].phys_attr +
19034 + map->card_start;
19035 + } else {
19036 + map->sys_start = pcmcia_socket[sock].phys_mem +
19037 + map->card_start;
19038 + }
19039 +
19040 + map->sys_stop = map->sys_start + (map->sys_stop - start);
19041 + pcmcia_socket[sock].mem_map[map->map] = *map;
19042 + restore_flags(flags);
19043 + DEBUG(2, "set_mem_map %d start %x stop %x card_start %x\n",
19044 + map->map, map->sys_start, map->sys_stop,
19045 + map->card_start);
19046 + return 0;
19047 +}
19048 +
19049 +
19050 +#if defined(CONFIG_PROC_FS)
19051 +
19052 +/*
19053 + * bcm47xx_pcmcia_proc_setup()
19054 + *
19055 + * Implements the proc_setup() operation for the in-kernel PCMCIA
19056 + * service (formerly SS_ProcSetup in Card Services).
19057 + *
19058 + * Returns: 0 on success, -1 on error
19059 + */
19060 +static void
19061 +bcm47xx_pcmcia_proc_setup(unsigned int sock, struct proc_dir_entry *base)
19062 +{
19063 + struct proc_dir_entry *entry;
19064 +
19065 + if ((entry = create_proc_entry("status", 0, base)) == NULL) {
19066 + printk(KERN_ERR "Unable to install \"status\" procfs entry\n");
19067 + return;
19068 + }
19069 +
19070 + entry->read_proc = bcm47xx_pcmcia_proc_status;
19071 + entry->data = (void *)sock;
19072 +}
19073 +
19074 +
19075 +/*
19076 + * bcm47xx_pcmcia_proc_status()
19077 + *
19078 + * Implements the /proc/bus/pccard/??/status file.
19079 + *
19080 + * Returns: the number of characters added to the buffer
19081 + */
19082 +static int
19083 +bcm47xx_pcmcia_proc_status(char *buf, char **start, off_t pos,
19084 + int count, int *eof, void *data)
19085 +{
19086 + char *p = buf;
19087 + unsigned int sock = (unsigned int)data;
19088 +
19089 + p += sprintf(p, "k_flags : %s%s%s%s%s%s%s\n",
19090 + pcmcia_socket[sock].k_state.detect ? "detect " : "",
19091 + pcmcia_socket[sock].k_state.ready ? "ready " : "",
19092 + pcmcia_socket[sock].k_state.bvd1 ? "bvd1 " : "",
19093 + pcmcia_socket[sock].k_state.bvd2 ? "bvd2 " : "",
19094 + pcmcia_socket[sock].k_state.wrprot ? "wrprot " : "",
19095 + pcmcia_socket[sock].k_state.vs_3v ? "vs_3v " : "",
19096 + pcmcia_socket[sock].k_state.vs_Xv ? "vs_Xv " : "");
19097 +
19098 + p += sprintf(p, "status : %s%s%s%s%s%s%s%s%s\n",
19099 + pcmcia_socket[sock].k_state.detect ? "SS_DETECT " : "",
19100 + pcmcia_socket[sock].k_state.ready ? "SS_READY " : "",
19101 + pcmcia_socket[sock].cs_state.Vcc ? "SS_POWERON " : "",
19102 + pcmcia_socket[sock].cs_state.flags & SS_IOCARD ? "SS_IOCARD " : "",
19103 + (pcmcia_socket[sock].cs_state.flags & SS_IOCARD &&
19104 + pcmcia_socket[sock].k_state.bvd1) ? "SS_STSCHG " : "",
19105 + ((pcmcia_socket[sock].cs_state.flags & SS_IOCARD) == 0 &&
19106 + (pcmcia_socket[sock].k_state.bvd1 == 0)) ? "SS_BATDEAD " : "",
19107 + ((pcmcia_socket[sock].cs_state.flags & SS_IOCARD) == 0 &&
19108 + (pcmcia_socket[sock].k_state.bvd2 == 0)) ? "SS_BATWARN " : "",
19109 + pcmcia_socket[sock].k_state.vs_3v ? "SS_3VCARD " : "",
19110 + pcmcia_socket[sock].k_state.vs_Xv ? "SS_XVCARD " : "");
19111 +
19112 + p += sprintf(p, "mask : %s%s%s%s%s\n",
19113 + pcmcia_socket[sock].cs_state.csc_mask & SS_DETECT ? "SS_DETECT " : "",
19114 + pcmcia_socket[sock].cs_state.csc_mask & SS_READY ? "SS_READY " : "",
19115 + pcmcia_socket[sock].cs_state.csc_mask & SS_BATDEAD ? "SS_BATDEAD " : "",
19116 + pcmcia_socket[sock].cs_state.csc_mask & SS_BATWARN ? "SS_BATWARN " : "",
19117 + pcmcia_socket[sock].cs_state.csc_mask & SS_STSCHG ? "SS_STSCHG " : "");
19118 +
19119 + p += sprintf(p, "cs_flags : %s%s%s%s%s\n",
19120 + pcmcia_socket[sock].cs_state.flags & SS_PWR_AUTO ?
19121 + "SS_PWR_AUTO " : "",
19122 + pcmcia_socket[sock].cs_state.flags & SS_IOCARD ?
19123 + "SS_IOCARD " : "",
19124 + pcmcia_socket[sock].cs_state.flags & SS_RESET ?
19125 + "SS_RESET " : "",
19126 + pcmcia_socket[sock].cs_state.flags & SS_SPKR_ENA ?
19127 + "SS_SPKR_ENA " : "",
19128 + pcmcia_socket[sock].cs_state.flags & SS_OUTPUT_ENA ?
19129 + "SS_OUTPUT_ENA " : "");
19130 +
19131 + p += sprintf(p, "Vcc : %d\n", pcmcia_socket[sock].cs_state.Vcc);
19132 + p += sprintf(p, "Vpp : %d\n", pcmcia_socket[sock].cs_state.Vpp);
19133 + p += sprintf(p, "irq : %d\n", pcmcia_socket[sock].cs_state.io_irq);
19134 + p += sprintf(p, "I/O : %u\n", pcmcia_socket[sock].speed_io);
19135 + p += sprintf(p, "attribute: %u\n", pcmcia_socket[sock].speed_attr);
19136 + p += sprintf(p, "common : %u\n", pcmcia_socket[sock].speed_mem);
19137 + return p-buf;
19138 +}
19139 +
19140 +
19141 +#endif /* defined(CONFIG_PROC_FS) */
19142 diff -Nur linux-2.4.32/drivers/pcmcia/bcm4710_pcmcia.c linux-2.4.32-brcm/drivers/pcmcia/bcm4710_pcmcia.c
19143 --- linux-2.4.32/drivers/pcmcia/bcm4710_pcmcia.c 1970-01-01 01:00:00.000000000 +0100
19144 +++ linux-2.4.32-brcm/drivers/pcmcia/bcm4710_pcmcia.c 2005-12-16 23:39:11.368863250 +0100
19145 @@ -0,0 +1,266 @@
19146 +/*
19147 + * BCM4710 specific pcmcia routines.
19148 + *
19149 + * Copyright 2004, Broadcom Corporation
19150 + * All Rights Reserved.
19151 + *
19152 + * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY
19153 + * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM
19154 + * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS
19155 + * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE.
19156 + *
19157 + * $Id: bcm4710_pcmcia.c,v 1.1 2005/03/16 13:50:00 wbx Exp $
19158 + */
19159 +#include <linux/module.h>
19160 +#include <linux/init.h>
19161 +#include <linux/config.h>
19162 +#include <linux/delay.h>
19163 +#include <linux/ioport.h>
19164 +#include <linux/kernel.h>
19165 +#include <linux/tqueue.h>
19166 +#include <linux/timer.h>
19167 +#include <linux/mm.h>
19168 +#include <linux/proc_fs.h>
19169 +#include <linux/version.h>
19170 +#include <linux/types.h>
19171 +#include <linux/pci.h>
19172 +
19173 +#include <pcmcia/version.h>
19174 +#include <pcmcia/cs_types.h>
19175 +#include <pcmcia/cs.h>
19176 +#include <pcmcia/ss.h>
19177 +#include <pcmcia/bulkmem.h>
19178 +#include <pcmcia/cistpl.h>
19179 +#include <pcmcia/bus_ops.h>
19180 +#include "cs_internal.h"
19181 +
19182 +#include <asm/io.h>
19183 +#include <asm/irq.h>
19184 +#include <asm/system.h>
19185 +
19186 +
19187 +#include <typedefs.h>
19188 +#include <bcmdevs.h>
19189 +#include <bcm4710.h>
19190 +#include <sbconfig.h>
19191 +#include <sbextif.h>
19192 +
19193 +#include "bcm4710pcmcia.h"
19194 +
19195 +/* Use a static var for irq dev_id */
19196 +static int bcm47xx_pcmcia_dev_id;
19197 +
19198 +/* Do we think we have a card or not? */
19199 +static int bcm47xx_pcmcia_present = 0;
19200 +
19201 +
19202 +static void bcm4710_pcmcia_reset(void)
19203 +{
19204 + extifregs_t *eir;
19205 + unsigned long s;
19206 + uint32 out0, out1, outen;
19207 +
19208 +
19209 + eir = (extifregs_t *) ioremap_nocache(BCM4710_REG_EXTIF, sizeof(extifregs_t));
19210 +
19211 + save_and_cli(s);
19212 +
19213 + /* Use gpio7 to reset the pcmcia slot */
19214 + outen = readl(&eir->gpio[0].outen);
19215 + outen |= BCM47XX_PCMCIA_RESET;
19216 + out0 = readl(&eir->gpio[0].out);
19217 + out0 &= ~(BCM47XX_PCMCIA_RESET);
19218 + out1 = out0 | BCM47XX_PCMCIA_RESET;
19219 +
19220 + writel(out0, &eir->gpio[0].out);
19221 + writel(outen, &eir->gpio[0].outen);
19222 + mdelay(1);
19223 + writel(out1, &eir->gpio[0].out);
19224 + mdelay(1);
19225 + writel(out0, &eir->gpio[0].out);
19226 +
19227 + restore_flags(s);
19228 +}
19229 +
19230 +
19231 +static int bcm4710_pcmcia_init(struct pcmcia_init *init)
19232 +{
19233 + struct pci_dev *pdev;
19234 + extifregs_t *eir;
19235 + uint32 outen, intp, intm, tmp;
19236 + uint16 *attrsp;
19237 + int rc = 0, i;
19238 + extern unsigned long bcm4710_cpu_cycle;
19239 +
19240 +
19241 + if (!(pdev = pci_find_device(VENDOR_BROADCOM, SB_EXTIF, NULL))) {
19242 + printk(KERN_ERR "bcm4710_pcmcia: extif not found\n");
19243 + return -ENODEV;
19244 + }
19245 + eir = (extifregs_t *) ioremap_nocache(pci_resource_start(pdev, 0), pci_resource_len(pdev, 0));
19246 +
19247 + /* Initialize the pcmcia i/f: 16bit no swap */
19248 + writel(CF_EM_PCMCIA | CF_DS | CF_EN, &eir->pcmcia_config);
19249 +
19250 +#ifdef notYet
19251 +
19252 + /* Set the timing for memory accesses */
19253 + tmp = (19 / bcm4710_cpu_cycle) << 24; /* W3 = 10nS */
19254 + tmp = tmp | ((29 / bcm4710_cpu_cycle) << 16); /* W2 = 20nS */
19255 + tmp = tmp | ((109 / bcm4710_cpu_cycle) << 8); /* W1 = 100nS */
19256 + tmp = tmp | (129 / bcm4710_cpu_cycle); /* W0 = 120nS */
19257 + writel(tmp, &eir->pcmcia_memwait); /* 0x01020a0c for a 100Mhz clock */
19258 +
19259 + /* Set the timing for I/O accesses */
19260 + tmp = (19 / bcm4710_cpu_cycle) << 24; /* W3 = 10nS */
19261 + tmp = tmp | ((29 / bcm4710_cpu_cycle) << 16); /* W2 = 20nS */
19262 + tmp = tmp | ((109 / bcm4710_cpu_cycle) << 8); /* W1 = 100nS */
19263 + tmp = tmp | (129 / bcm4710_cpu_cycle); /* W0 = 120nS */
19264 + writel(tmp, &eir->pcmcia_iowait); /* 0x01020a0c for a 100Mhz clock */
19265 +
19266 + /* Set the timing for attribute accesses */
19267 + tmp = (19 / bcm4710_cpu_cycle) << 24; /* W3 = 10nS */
19268 + tmp = tmp | ((29 / bcm4710_cpu_cycle) << 16); /* W2 = 20nS */
19269 + tmp = tmp | ((109 / bcm4710_cpu_cycle) << 8); /* W1 = 100nS */
19270 + tmp = tmp | (129 / bcm4710_cpu_cycle); /* W0 = 120nS */
19271 + writel(tmp, &eir->pcmcia_attrwait); /* 0x01020a0c for a 100Mhz clock */
19272 +
19273 +#endif
19274 + /* Make sure gpio0 and gpio5 are inputs */
19275 + outen = readl(&eir->gpio[0].outen);
19276 + outen &= ~(BCM47XX_PCMCIA_WP | BCM47XX_PCMCIA_STSCHG | BCM47XX_PCMCIA_RESET);
19277 + writel(outen, &eir->gpio[0].outen);
19278 +
19279 + /* Issue a reset to the pcmcia socket */
19280 + bcm4710_pcmcia_reset();
19281 +
19282 +#ifdef DO_BCM47XX_PCMCIA_INTERRUPTS
19283 + /* Setup gpio5 to be the STSCHG interrupt */
19284 + intp = readl(&eir->gpiointpolarity);
19285 + writel(intp | BCM47XX_PCMCIA_STSCHG, &eir->gpiointpolarity); /* Active low */
19286 + intm = readl(&eir->gpiointmask);
19287 + writel(intm | BCM47XX_PCMCIA_STSCHG, &eir->gpiointmask); /* Enable it */
19288 +#endif
19289 +
19290 + DEBUG(2, "bcm4710_pcmcia after reset:\n");
19291 + DEBUG(2, "\textstatus\t= 0x%08x:\n", readl(&eir->extstatus));
19292 + DEBUG(2, "\tpcmcia_config\t= 0x%08x:\n", readl(&eir->pcmcia_config));
19293 + DEBUG(2, "\tpcmcia_memwait\t= 0x%08x:\n", readl(&eir->pcmcia_memwait));
19294 + DEBUG(2, "\tpcmcia_attrwait\t= 0x%08x:\n", readl(&eir->pcmcia_attrwait));
19295 + DEBUG(2, "\tpcmcia_iowait\t= 0x%08x:\n", readl(&eir->pcmcia_iowait));
19296 + DEBUG(2, "\tgpioin\t\t= 0x%08x:\n", readl(&eir->gpioin));
19297 + DEBUG(2, "\tgpio_outen0\t= 0x%08x:\n", readl(&eir->gpio[0].outen));
19298 + DEBUG(2, "\tgpio_out0\t= 0x%08x:\n", readl(&eir->gpio[0].out));
19299 + DEBUG(2, "\tgpiointpolarity\t= 0x%08x:\n", readl(&eir->gpiointpolarity));
19300 + DEBUG(2, "\tgpiointmask\t= 0x%08x:\n", readl(&eir->gpiointmask));
19301 +
19302 +#ifdef DO_BCM47XX_PCMCIA_INTERRUPTS
19303 + /* Request pcmcia interrupt */
19304 + rc = request_irq(BCM47XX_PCMCIA_IRQ, init->handler, SA_INTERRUPT,
19305 + "PCMCIA Interrupt", &bcm47xx_pcmcia_dev_id);
19306 +#endif
19307 +
19308 + attrsp = (uint16 *)ioremap_nocache(EXTIF_PCMCIA_CFGBASE(BCM4710_EXTIF), 0x1000);
19309 + tmp = readw(&attrsp[0]);
19310 + DEBUG(2, "\tattr[0] = 0x%04x\n", tmp);
19311 + if ((tmp == 0x7fff) || (tmp == 0x7f00)) {
19312 + bcm47xx_pcmcia_present = 0;
19313 + } else {
19314 + bcm47xx_pcmcia_present = 1;
19315 + }
19316 +
19317 + /* There's only one socket */
19318 + return 1;
19319 +}
19320 +
19321 +static int bcm4710_pcmcia_shutdown(void)
19322 +{
19323 + extifregs_t *eir;
19324 + uint32 intm;
19325 +
19326 + eir = (extifregs_t *) ioremap_nocache(BCM4710_REG_EXTIF, sizeof(extifregs_t));
19327 +
19328 + /* Disable the pcmcia i/f */
19329 + writel(0, &eir->pcmcia_config);
19330 +
19331 + /* Reset gpio's */
19332 + intm = readl(&eir->gpiointmask);
19333 + writel(intm & ~BCM47XX_PCMCIA_STSCHG, &eir->gpiointmask); /* Disable it */
19334 +
19335 + free_irq(BCM47XX_PCMCIA_IRQ, &bcm47xx_pcmcia_dev_id);
19336 +
19337 + return 0;
19338 +}
19339 +
19340 +static int
19341 +bcm4710_pcmcia_socket_state(unsigned sock, struct pcmcia_state *state)
19342 +{
19343 + extifregs_t *eir;
19344 +
19345 + eir = (extifregs_t *) ioremap_nocache(BCM4710_REG_EXTIF, sizeof(extifregs_t));
19346 +
19347 +
19348 + if (sock != 0) {
19349 + printk(KERN_ERR "bcm4710 socket_state bad sock %d\n", sock);
19350 + return -1;
19351 + }
19352 +
19353 + if (bcm47xx_pcmcia_present) {
19354 + state->detect = 1;
19355 + state->ready = 1;
19356 + state->bvd1 = 1;
19357 + state->bvd2 = 1;
19358 + state->wrprot = (readl(&eir->gpioin) & BCM47XX_PCMCIA_WP) == BCM47XX_PCMCIA_WP;
19359 + state->vs_3v = 0;
19360 + state->vs_Xv = 0;
19361 + } else {
19362 + state->detect = 0;
19363 + state->ready = 0;
19364 + }
19365 +
19366 + return 1;
19367 +}
19368 +
19369 +
19370 +static int bcm4710_pcmcia_get_irq_info(struct pcmcia_irq_info *info)
19371 +{
19372 + if (info->sock >= BCM47XX_PCMCIA_MAX_SOCK) return -1;
19373 +
19374 + info->irq = BCM47XX_PCMCIA_IRQ;
19375 +
19376 + return 0;
19377 +}
19378 +
19379 +
19380 +static int
19381 +bcm4710_pcmcia_configure_socket(const struct pcmcia_configure *configure)
19382 +{
19383 + if (configure->sock >= BCM47XX_PCMCIA_MAX_SOCK) return -1;
19384 +
19385 +
19386 + DEBUG(2, "Vcc %dV Vpp %dV output %d speaker %d reset %d\n", configure->vcc,
19387 + configure->vpp, configure->output, configure->speaker, configure->reset);
19388 +
19389 + if ((configure->vcc != 50) || (configure->vpp != 50)) {
19390 + printk("%s: bad Vcc/Vpp (%d:%d)\n", __FUNCTION__, configure->vcc,
19391 + configure->vpp);
19392 + }
19393 +
19394 + if (configure->reset) {
19395 + /* Issue a reset to the pcmcia socket */
19396 + DEBUG(1, "%s: Reseting socket\n", __FUNCTION__);
19397 + bcm4710_pcmcia_reset();
19398 + }
19399 +
19400 +
19401 + return 0;
19402 +}
19403 +
19404 +struct pcmcia_low_level bcm4710_pcmcia_ops = {
19405 + bcm4710_pcmcia_init,
19406 + bcm4710_pcmcia_shutdown,
19407 + bcm4710_pcmcia_socket_state,
19408 + bcm4710_pcmcia_get_irq_info,
19409 + bcm4710_pcmcia_configure_socket
19410 +};
19411 +
19412 diff -Nur linux-2.4.32/drivers/pcmcia/bcm4710pcmcia.h linux-2.4.32-brcm/drivers/pcmcia/bcm4710pcmcia.h
19413 --- linux-2.4.32/drivers/pcmcia/bcm4710pcmcia.h 1970-01-01 01:00:00.000000000 +0100
19414 +++ linux-2.4.32-brcm/drivers/pcmcia/bcm4710pcmcia.h 2005-12-16 23:39:11.368863250 +0100
19415 @@ -0,0 +1,118 @@
19416 +/*
19417 + *
19418 + * bcm47xx pcmcia driver
19419 + *
19420 + * Copyright 2004, Broadcom Corporation
19421 + * All Rights Reserved.
19422 + *
19423 + * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY
19424 + * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM
19425 + * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS
19426 + * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE.
19427 + *
19428 + * Based on sa1100.h and include/asm-arm/arch-sa1100/pcmica.h
19429 + * from www.handhelds.org,
19430 + * and au1000_generic.c from oss.sgi.com.
19431 + *
19432 + * $Id: bcm4710pcmcia.h,v 1.1 2005/03/16 13:50:00 wbx Exp $
19433 + */
19434 +
19435 +#if !defined(_BCM4710PCMCIA_H)
19436 +#define _BCM4710PCMCIA_H
19437 +
19438 +#include <pcmcia/cs_types.h>
19439 +#include <pcmcia/ss.h>
19440 +#include <pcmcia/bulkmem.h>
19441 +#include <pcmcia/cistpl.h>
19442 +#include "cs_internal.h"
19443 +
19444 +
19445 +/* The 47xx can only support one socket */
19446 +#define BCM47XX_PCMCIA_MAX_SOCK 1
19447 +
19448 +/* In the bcm947xx gpio's are used for some pcmcia functions */
19449 +#define BCM47XX_PCMCIA_WP 0x01 /* Bit 0 is WP input */
19450 +#define BCM47XX_PCMCIA_STSCHG 0x20 /* Bit 5 is STSCHG input/interrupt */
19451 +#define BCM47XX_PCMCIA_RESET 0x80 /* Bit 7 is RESET */
19452 +
19453 +#define BCM47XX_PCMCIA_IRQ 2
19454 +
19455 +/* The socket driver actually works nicely in interrupt-driven form,
19456 + * so the (relatively infrequent) polling is "just to be sure."
19457 + */
19458 +#define BCM47XX_PCMCIA_POLL_PERIOD (2 * HZ)
19459 +
19460 +#define BCM47XX_PCMCIA_IO_SPEED (255)
19461 +#define BCM47XX_PCMCIA_MEM_SPEED (300)
19462 +
19463 +
19464 +struct pcmcia_state {
19465 + unsigned detect: 1,
19466 + ready: 1,
19467 + bvd1: 1,
19468 + bvd2: 1,
19469 + wrprot: 1,
19470 + vs_3v: 1,
19471 + vs_Xv: 1;
19472 +};
19473 +
19474 +
19475 +struct pcmcia_configure {
19476 + unsigned sock: 8,
19477 + vcc: 8,
19478 + vpp: 8,
19479 + output: 1,
19480 + speaker: 1,
19481 + reset: 1;
19482 +};
19483 +
19484 +struct pcmcia_irq_info {
19485 + unsigned int sock;
19486 + unsigned int irq;
19487 +};
19488 +
19489 +/* This structure encapsulates per-socket state which we might need to
19490 + * use when responding to a Card Services query of some kind.
19491 + */
19492 +struct bcm47xx_pcmcia_socket {
19493 + socket_state_t cs_state;
19494 + struct pcmcia_state k_state;
19495 + unsigned int irq;
19496 + void (*handler)(void *, unsigned int);
19497 + void *handler_info;
19498 + pccard_io_map io_map[MAX_IO_WIN];
19499 + pccard_mem_map mem_map[MAX_WIN];
19500 + ioaddr_t virt_io, phys_attr, phys_mem;
19501 + unsigned short speed_io, speed_attr, speed_mem;
19502 +};
19503 +
19504 +struct pcmcia_init {
19505 + void (*handler)(int irq, void *dev, struct pt_regs *regs);
19506 +};
19507 +
19508 +struct pcmcia_low_level {
19509 + int (*init)(struct pcmcia_init *);
19510 + int (*shutdown)(void);
19511 + int (*socket_state)(unsigned sock, struct pcmcia_state *);
19512 + int (*get_irq_info)(struct pcmcia_irq_info *);
19513 + int (*configure_socket)(const struct pcmcia_configure *);
19514 +};
19515 +
19516 +extern struct pcmcia_low_level bcm47xx_pcmcia_ops;
19517 +
19518 +/* I/O pins replacing memory pins
19519 + * (PCMCIA System Architecture, 2nd ed., by Don Anderson, p.75)
19520 + *
19521 + * These signals change meaning when going from memory-only to
19522 + * memory-or-I/O interface:
19523 + */
19524 +#define iostschg bvd1
19525 +#define iospkr bvd2
19526 +
19527 +
19528 +/*
19529 + * Declaration for implementation specific low_level operations.
19530 + */
19531 +extern struct pcmcia_low_level bcm4710_pcmcia_ops;
19532 +
19533 +#endif /* !defined(_BCM4710PCMCIA_H) */
19534 diff -Nur linux-2.4.32/drivers/pcmcia/Makefile linux-2.4.32-brcm/drivers/pcmcia/Makefile
19535 --- linux-2.4.32/drivers/pcmcia/Makefile 2004-02-18 14:36:31.000000000 +0100
19536 +++ linux-2.4.32-brcm/drivers/pcmcia/Makefile 2005-12-16 23:39:11.364863000 +0100
19537 @@ -65,6 +65,10 @@
19538 au1000_ss-objs-$(CONFIG_PCMCIA_DB1X00) += au1000_db1x00.o
19539 au1000_ss-objs-$(CONFIG_PCMCIA_XXS1500) += au1000_xxs1500.o
19540
19541 +obj-$(CONFIG_PCMCIA_BCM4710) += bcm4710_ss.o
19542 +bcm4710_ss-objs := bcm4710_generic.o
19543 +bcm4710_ss-objs += bcm4710_pcmcia.o
19544 +
19545 obj-$(CONFIG_PCMCIA_SA1100) += sa1100_cs.o
19546 obj-$(CONFIG_PCMCIA_M8XX) += m8xx_pcmcia.o
19547 obj-$(CONFIG_PCMCIA_SIBYTE) += sibyte_generic.o
19548 @@ -102,5 +106,8 @@
19549 au1x00_ss.o: $(au1000_ss-objs-y)
19550 $(LD) -r -o $@ $(au1000_ss-objs-y)
19551
19552 +bcm4710_ss.o: $(bcm4710_ss-objs)
19553 + $(LD) -r -o $@ $(bcm4710_ss-objs)
19554 +
19555 yenta_socket.o: $(yenta_socket-objs)
19556 $(LD) $(LD_RFLAG) -r -o $@ $(yenta_socket-objs)
19557 diff -Nur linux-2.4.32/include/asm-mips/bootinfo.h linux-2.4.32-brcm/include/asm-mips/bootinfo.h
19558 --- linux-2.4.32/include/asm-mips/bootinfo.h 2004-02-18 14:36:32.000000000 +0100
19559 +++ linux-2.4.32-brcm/include/asm-mips/bootinfo.h 2005-12-16 23:39:11.400865250 +0100
19560 @@ -37,6 +37,7 @@
19561 #define MACH_GROUP_HP_LJ 20 /* Hewlett Packard LaserJet */
19562 #define MACH_GROUP_LASAT 21
19563 #define MACH_GROUP_TITAN 22 /* PMC-Sierra Titan */
19564 +#define MACH_GROUP_BRCM 23 /* Broadcom */
19565
19566 /*
19567 * Valid machtype values for group unknown (low order halfword of mips_machtype)
19568 @@ -194,6 +195,15 @@
19569 #define MACH_TANBAC_TB0229 7 /* TANBAC TB0229 (VR4131DIMM) */
19570
19571 /*
19572 + * Valid machtypes for group Broadcom
19573 + */
19574 +#define MACH_BCM93725 0
19575 +#define MACH_BCM93725_VJ 1
19576 +#define MACH_BCM93730 2
19577 +#define MACH_BCM947XX 3
19578 +#define MACH_BCM933XX 4
19579 +
19580 +/*
19581 * Valid machtype for group TITAN
19582 */
19583 #define MACH_TITAN_YOSEMITE 1 /* PMC-Sierra Yosemite */
19584 diff -Nur linux-2.4.32/include/asm-mips/cpu.h linux-2.4.32-brcm/include/asm-mips/cpu.h
19585 --- linux-2.4.32/include/asm-mips/cpu.h 2005-01-19 15:10:11.000000000 +0100
19586 +++ linux-2.4.32-brcm/include/asm-mips/cpu.h 2005-12-16 23:39:11.412866000 +0100
19587 @@ -22,6 +22,11 @@
19588 spec.
19589 */
19590
19591 +#define PRID_COPT_MASK 0xff000000
19592 +#define PRID_COMP_MASK 0x00ff0000
19593 +#define PRID_IMP_MASK 0x0000ff00
19594 +#define PRID_REV_MASK 0x000000ff
19595 +
19596 #define PRID_COMP_LEGACY 0x000000
19597 #define PRID_COMP_MIPS 0x010000
19598 #define PRID_COMP_BROADCOM 0x020000
19599 @@ -58,6 +63,7 @@
19600 #define PRID_IMP_RM7000 0x2700
19601 #define PRID_IMP_NEVADA 0x2800 /* RM5260 ??? */
19602 #define PRID_IMP_RM9000 0x3400
19603 +#define PRID_IMP_BCM4710 0x4000
19604 #define PRID_IMP_R5432 0x5400
19605 #define PRID_IMP_R5500 0x5500
19606 #define PRID_IMP_4KC 0x8000
19607 @@ -66,10 +72,16 @@
19608 #define PRID_IMP_4KEC 0x8400
19609 #define PRID_IMP_4KSC 0x8600
19610 #define PRID_IMP_25KF 0x8800
19611 +#define PRID_IMP_BCM3302 0x9000
19612 +#define PRID_IMP_BCM3303 0x9100
19613 #define PRID_IMP_24K 0x9300
19614
19615 #define PRID_IMP_UNKNOWN 0xff00
19616
19617 +#define BCM330X(id) \
19618 + (((id & (PRID_COMP_MASK | PRID_IMP_MASK)) == (PRID_COMP_BROADCOM | PRID_IMP_BCM3302)) \
19619 + || ((id & (PRID_COMP_MASK | PRID_IMP_MASK)) == (PRID_COMP_BROADCOM | PRID_IMP_BCM3303)))
19620 +
19621 /*
19622 * These are the PRID's for when 23:16 == PRID_COMP_SIBYTE
19623 */
19624 @@ -174,7 +186,9 @@
19625 #define CPU_AU1550 57
19626 #define CPU_24K 58
19627 #define CPU_AU1200 59
19628 -#define CPU_LAST 59
19629 +#define CPU_BCM4710 60
19630 +#define CPU_BCM3302 61
19631 +#define CPU_LAST 61
19632
19633 /*
19634 * ISA Level encodings
19635 diff -Nur linux-2.4.32/include/asm-mips/r4kcache.h linux-2.4.32-brcm/include/asm-mips/r4kcache.h
19636 --- linux-2.4.32/include/asm-mips/r4kcache.h 2004-02-18 14:36:32.000000000 +0100
19637 +++ linux-2.4.32-brcm/include/asm-mips/r4kcache.h 2005-12-16 23:39:11.416866250 +0100
19638 @@ -567,4 +567,17 @@
19639 cache128_unroll32(addr|ws,Index_Writeback_Inv_SD);
19640 }
19641
19642 +extern inline void fill_icache_line(unsigned long addr)
19643 +{
19644 + __asm__ __volatile__(
19645 + ".set noreorder\n\t"
19646 + ".set mips3\n\t"
19647 + "cache %1, (%0)\n\t"
19648 + ".set mips0\n\t"
19649 + ".set reorder"
19650 + :
19651 + : "r" (addr),
19652 + "i" (Fill));
19653 +}
19654 +
19655 #endif /* __ASM_R4KCACHE_H */
19656 diff -Nur linux-2.4.32/include/asm-mips/serial.h linux-2.4.32-brcm/include/asm-mips/serial.h
19657 --- linux-2.4.32/include/asm-mips/serial.h 2005-01-19 15:10:12.000000000 +0100
19658 +++ linux-2.4.32-brcm/include/asm-mips/serial.h 2005-12-16 23:39:11.428867000 +0100
19659 @@ -223,6 +223,13 @@
19660 #define TXX927_SERIAL_PORT_DEFNS
19661 #endif
19662
19663 +#ifdef CONFIG_BCM947XX
19664 +/* reserve 4 ports to be configured at runtime */
19665 +#define BCM947XX_SERIAL_PORT_DEFNS { 0, }, { 0, }, { 0, }, { 0, },
19666 +#else
19667 +#define BCM947XX_SERIAL_PORT_DEFNS
19668 +#endif
19669 +
19670 #ifdef CONFIG_HAVE_STD_PC_SERIAL_PORT
19671 #define STD_SERIAL_PORT_DEFNS \
19672 /* UART CLK PORT IRQ FLAGS */ \
19673 @@ -470,6 +477,7 @@
19674 #define SERIAL_PORT_DFNS \
19675 ATLAS_SERIAL_PORT_DEFNS \
19676 AU1000_SERIAL_PORT_DEFNS \
19677 + BCM947XX_SERIAL_PORT_DEFNS \
19678 COBALT_SERIAL_PORT_DEFNS \
19679 DDB5477_SERIAL_PORT_DEFNS \
19680 EV96100_SERIAL_PORT_DEFNS \
19681 diff -Nur linux-2.4.32/init/do_mounts.c linux-2.4.32-brcm/init/do_mounts.c
19682 --- linux-2.4.32/init/do_mounts.c 2003-11-28 19:26:21.000000000 +0100
19683 +++ linux-2.4.32-brcm/init/do_mounts.c 2005-12-16 23:39:11.504871750 +0100
19684 @@ -253,7 +253,13 @@
19685 { "ftlb", 0x2c08 },
19686 { "ftlc", 0x2c10 },
19687 { "ftld", 0x2c18 },
19688 +#if defined(CONFIG_MTD_BLOCK) || defined(CONFIG_MTD_BLOCK_RO)
19689 { "mtdblock", 0x1f00 },
19690 + { "mtdblock0",0x1f00 },
19691 + { "mtdblock1",0x1f01 },
19692 + { "mtdblock2",0x1f02 },
19693 + { "mtdblock3",0x1f03 },
19694 +#endif
19695 { "nb", 0x2b00 },
19696 { NULL, 0 }
19697 };