clean up brcm-2.4 system code
[openwrt.git] / 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  };