source: clfs-embedded/patches/linux-2.6.19-bcm947xx.patch@ 21e0fdf

Last change on this file since 21e0fdf was 21e0fdf, checked in by Maarten Lankhorst <m.b.lankhorst@…>, 18 years ago

Add required patches

  • Property mode set to 100644
File size: 226.7 KB
RevLine 
[21e0fdf]1diff -Nru linux-2.6.19.ori/arch/mips/Kconfig linux-2.6.19/arch/mips/Kconfig
2--- linux-2.6.19.ori/arch/mips/Kconfig 2006-12-02 18:55:37.000000000 +0100
3+++ linux-2.6.19/arch/mips/Kconfig 2006-12-02 21:58:30.000000000 +0100
4@@ -4,6 +4,10 @@
5 # Horrible source of confusion. Die, die, die ...
6 select EMBEDDED
7
8+config CFE
9+ bool
10+ # Common Firmware Environment
11+
12 mainmenu "Linux/MIPS Kernel Configuration"
13
14 menu "Machine selection"
15@@ -222,6 +226,22 @@
16 Members include the Acer PICA, MIPS Magnum 4000, MIPS Millenium and
17 Olivetti M700-10 workstations.
18
19+config BCM947XX
20+ bool "Support for BCM947xx based boards"
21+ select DMA_NONCOHERENT
22+ select HW_HAS_PCI
23+ select IRQ_CPU
24+ select SYS_HAS_CPU_MIPS32_R1
25+ select SYS_SUPPORTS_32BIT_KERNEL
26+ select SYS_SUPPORTS_LITTLE_ENDIAN
27+ select MIPS_CPU_SCACHE
28+ select SSB
29+ select SSB_DRIVER_MIPS
30+ select SSB_DRIVER_EXTIF
31+ select CFE
32+ help
33+ Support for BCM947xx based boards
34+
35 config LASAT
36 bool "LASAT Networks platforms"
37 select DMA_NONCOHERENT
38diff -Nru linux-2.6.19.ori/arch/mips/Makefile linux-2.6.19/arch/mips/Makefile
39--- linux-2.6.19.ori/arch/mips/Makefile 2006-12-02 18:55:37.000000000 +0100
40+++ linux-2.6.19/arch/mips/Makefile 2006-12-02 19:14:34.000000000 +0100
41@@ -571,6 +571,18 @@
42 load-$(CONFIG_SIBYTE_BIGSUR) := 0xffffffff80100000
43
44 #
45+# Broadcom BCM47XX boards
46+#
47+core-$(CONFIG_BCM947XX) += arch/mips/bcm947xx/
48+cflags-$(CONFIG_BCM947XX) += -Iarch/mips/bcm947xx/include -Iinclude/asm-mips/mach-bcm947xx
49+load-$(CONFIG_BCM947XX) := 0xffffffff80001000
50+
51+#
52+# Common Firmware Environment
53+#
54+core-$(CONFIG_CFE) += arch/mips/cfe/
55+
56+#
57 # SNI RM200 PCI
58 #
59 core-$(CONFIG_SNI_RM200_PCI) += arch/mips/sni/
60diff -Nru linux-2.6.19.ori/arch/mips/bcm947xx/Makefile linux-2.6.19/arch/mips/bcm947xx/Makefile
61--- linux-2.6.19.ori/arch/mips/bcm947xx/Makefile 1970-01-01 01:00:00.000000000 +0100
62+++ linux-2.6.19/arch/mips/bcm947xx/Makefile 2006-12-02 23:22:31.000000000 +0100
63@@ -0,0 +1,8 @@
64+#
65+# Makefile for the BCM47xx specific kernel interface routines
66+# under Linux.
67+#
68+
69+obj-y := irq.o prom.o setup.o time.o
70+obj-y += nvram.o cfe_env.o
71+#obj-y += pci.o
72diff -Nru linux-2.6.19.ori/arch/mips/bcm947xx/cfe_env.c linux-2.6.19/arch/mips/bcm947xx/cfe_env.c
73--- linux-2.6.19.ori/arch/mips/bcm947xx/cfe_env.c 1970-01-01 01:00:00.000000000 +0100
74+++ linux-2.6.19/arch/mips/bcm947xx/cfe_env.c 2006-12-02 20:57:51.000000000 +0100
75@@ -0,0 +1,232 @@
76+/*
77+ * CFE environment varialble access
78+ *
79+ * Copyright 2006, Felix Fietkau <nbd@openwrt.org>
80+ *
81+ * This program is free software; you can redistribute it and/or modify it
82+ * under the terms of the GNU General Public License as published by the
83+ * Free Software Foundation; either version 2 of the License, or (at your
84+ * option) any later version.
85+ *
86+ * Copyright 2001-2003, Broadcom Corporation
87+ *
88+ * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY
89+ * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM
90+ * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS
91+ * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE.
92+ */
93+
94+#include <linux/init.h>
95+#include <linux/module.h>
96+#include <linux/kernel.h>
97+#include <linux/string.h>
98+#include <asm/io.h>
99+#include <asm/uaccess.h>
100+
101+#define NVRAM_SIZE (0x1ff0)
102+static char _nvdata[NVRAM_SIZE] __initdata;
103+static char _valuestr[256] __initdata;
104+
105+/*
106+ * TLV types. These codes are used in the "type-length-value"
107+ * encoding of the items stored in the NVRAM device (flash or EEPROM)
108+ *
109+ * The layout of the flash/nvram is as follows:
110+ *
111+ * <type> <length> <data ...> <type> <length> <data ...> <type_end>
112+ *
113+ * The type code of "ENV_TLV_TYPE_END" marks the end of the list.
114+ * The "length" field marks the length of the data section, not
115+ * including the type and length fields.
116+ *
117+ * Environment variables are stored as follows:
118+ *
119+ * <type_env> <length> <flags> <name> = <value>
120+ *
121+ * If bit 0 (low bit) is set, the length is an 8-bit value.
122+ * If bit 0 (low bit) is clear, the length is a 16-bit value
123+ *
124+ * Bit 7 set indicates "user" TLVs. In this case, bit 0 still
125+ * indicates the size of the length field.
126+ *
127+ * Flags are from the constants below:
128+ *
129+ */
130+#define ENV_LENGTH_16BITS 0x00 /* for low bit */
131+#define ENV_LENGTH_8BITS 0x01
132+
133+#define ENV_TYPE_USER 0x80
134+
135+#define ENV_CODE_SYS(n,l) (((n)<<1)|(l))
136+#define ENV_CODE_USER(n,l) ((((n)<<1)|(l)) | ENV_TYPE_USER)
137+
138+/*
139+ * The actual TLV types we support
140+ */
141+
142+#define ENV_TLV_TYPE_END 0x00
143+#define ENV_TLV_TYPE_ENV ENV_CODE_SYS(0,ENV_LENGTH_8BITS)
144+
145+/*
146+ * Environment variable flags
147+ */
148+
149+#define ENV_FLG_NORMAL 0x00 /* normal read/write */
150+#define ENV_FLG_BUILTIN 0x01 /* builtin - not stored in flash */
151+#define ENV_FLG_READONLY 0x02 /* read-only - cannot be changed */
152+
153+#define ENV_FLG_MASK 0xFF /* mask of attributes we keep */
154+#define ENV_FLG_ADMIN 0x100 /* lets us internally override permissions */
155+
156+
157+/* *********************************************************************
158+ * _nvram_read(buffer,offset,length)
159+ *
160+ * Read data from the NVRAM device
161+ *
162+ * Input parameters:
163+ * buffer - destination buffer
164+ * offset - offset of data to read
165+ * length - number of bytes to read
166+ *
167+ * Return value:
168+ * number of bytes read, or <0 if error occured
169+ ********************************************************************* */
170+static int
171+_nvram_read(unsigned char *nv_buf, unsigned char *buffer, int offset, int length)
172+{
173+ int i;
174+ if (offset > NVRAM_SIZE)
175+ return -1;
176+
177+ for ( i = 0; i < length; i++) {
178+ buffer[i] = ((volatile unsigned char*)nv_buf)[offset + i];
179+ }
180+ return length;
181+}
182+
183+
184+static char*
185+_strnchr(const char *dest,int c,size_t cnt)
186+{
187+ while (*dest && (cnt > 0)) {
188+ if (*dest == c) return (char *) dest;
189+ dest++;
190+ cnt--;
191+ }
192+ return NULL;
193+}
194+
195+
196+
197+/*
198+ * Core support API: Externally visible.
199+ */
200+
201+/*
202+ * Get the value of an NVRAM variable
203+ * @param name name of variable to get
204+ * @return value of variable or NULL if undefined
205+ */
206+
207+char*
208+cfe_env_get(unsigned char *nv_buf, char* name)
209+{
210+ int size;
211+ unsigned char *buffer;
212+ unsigned char *ptr;
213+ unsigned char *envval;
214+ unsigned int reclen;
215+ unsigned int rectype;
216+ int offset;
217+ int flg;
218+
219+ size = NVRAM_SIZE;
220+ buffer = &_nvdata[0];
221+
222+ ptr = buffer;
223+ offset = 0;
224+
225+ /* Read the record type and length */
226+ if (_nvram_read(nv_buf, ptr,offset,1) != 1) {
227+ goto error;
228+ }
229+
230+ while ((*ptr != ENV_TLV_TYPE_END) && (size > 1)) {
231+
232+ /* Adjust pointer for TLV type */
233+ rectype = *(ptr);
234+ offset++;
235+ size--;
236+
237+ /*
238+ * Read the length. It can be either 1 or 2 bytes
239+ * depending on the code
240+ */
241+ if (rectype & ENV_LENGTH_8BITS) {
242+ /* Read the record type and length - 8 bits */
243+ if (_nvram_read(nv_buf, ptr,offset,1) != 1) {
244+ goto error;
245+ }
246+ reclen = *(ptr);
247+ size--;
248+ offset++;
249+ }
250+ else {
251+ /* Read the record type and length - 16 bits, MSB first */
252+ if (_nvram_read(nv_buf, ptr,offset,2) != 2) {
253+ goto error;
254+ }
255+ reclen = (((unsigned int) *(ptr)) << 8) + (unsigned int) *(ptr+1);
256+ size -= 2;
257+ offset += 2;
258+ }
259+
260+ if (reclen > size)
261+ break; /* should not happen, bad NVRAM */
262+
263+ switch (rectype) {
264+ case ENV_TLV_TYPE_ENV:
265+ /* Read the TLV data */
266+ if (_nvram_read(nv_buf, ptr,offset,reclen) != reclen)
267+ goto error;
268+ flg = *ptr++;
269+ envval = (unsigned char *) _strnchr(ptr,'=',(reclen-1));
270+ if (envval) {
271+ *envval++ = '\0';
272+ memcpy(_valuestr,envval,(reclen-1)-(envval-ptr));
273+ _valuestr[(reclen-1)-(envval-ptr)] = '\0';
274+#if 0
275+ printk(KERN_INFO "NVRAM:%s=%s\n", ptr, _valuestr);
276+#endif
277+ if(!strcmp(ptr, name)){
278+ return _valuestr;
279+ }
280+ if((strlen(ptr) > 1) && !strcmp(&ptr[1], name))
281+ return _valuestr;
282+ }
283+ break;
284+
285+ default:
286+ /* Unknown TLV type, skip it. */
287+ break;
288+ }
289+
290+ /*
291+ * Advance to next TLV
292+ */
293+
294+ size -= (int)reclen;
295+ offset += reclen;
296+
297+ /* Read the next record type */
298+ ptr = buffer;
299+ if (_nvram_read(nv_buf, ptr,offset,1) != 1)
300+ goto error;
301+ }
302+
303+error:
304+ return NULL;
305+
306+}
307+
308diff -Nru linux-2.6.19.ori/arch/mips/bcm947xx/include/nvram.h linux-2.6.19/arch/mips/bcm947xx/include/nvram.h
309--- linux-2.6.19.ori/arch/mips/bcm947xx/include/nvram.h 1970-01-01 01:00:00.000000000 +0100
310+++ linux-2.6.19/arch/mips/bcm947xx/include/nvram.h 2006-12-02 19:14:34.000000000 +0100
311@@ -0,0 +1,37 @@
312+/*
313+ * Copyright (C) 2006 Felix Fietkau <nbd@openwrt.org>
314+ *
315+ * This program is free software; you can redistribute it and/or modify it
316+ * under the terms of the GNU General Public License as published by the
317+ * Free Software Foundation; either version 2 of the License, or (at your
318+ * option) any later version.
319+ */
320+
321+#ifndef __NVRAM_H
322+#define __NVRAM_H
323+
324+struct nvram_header {
325+ u32 magic;
326+ u32 len;
327+ u32 crc_ver_init; /* 0:7 crc, 8:15 ver, 16:31 sdram_init */
328+ u32 config_refresh; /* 0:15 sdram_config, 16:31 sdram_refresh */
329+ u32 config_ncdl; /* ncdl values for memc */
330+};
331+
332+struct nvram_tuple {
333+ char *name;
334+ char *value;
335+ struct nvram_tuple *next;
336+};
337+
338+#define NVRAM_HEADER 0x48534C46 /* 'FLSH' */
339+#define NVRAM_VERSION 1
340+#define NVRAM_HEADER_SIZE 20
341+#define NVRAM_SPACE 0x8000
342+
343+#define NVRAM_MAX_VALUE_LEN 255
344+#define NVRAM_MAX_PARAM_LEN 64
345+
346+char *nvram_get(const char *name);
347+
348+#endif
349diff -Nru linux-2.6.19.ori/arch/mips/bcm947xx/irq.c linux-2.6.19/arch/mips/bcm947xx/irq.c
350--- linux-2.6.19.ori/arch/mips/bcm947xx/irq.c 1970-01-01 01:00:00.000000000 +0100
351+++ linux-2.6.19/arch/mips/bcm947xx/irq.c 2006-12-02 20:57:15.000000000 +0100
352@@ -0,0 +1,63 @@
353+/*
354+ * Copyright (C) 2004 Florian Schirmer (jolt@tuxbox.org)
355+ *
356+ * This program is free software; you can redistribute it and/or modify it
357+ * under the terms of the GNU General Public License as published by the
358+ * Free Software Foundation; either version 2 of the License, or (at your
359+ * option) any later version.
360+ *
361+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
362+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
363+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
364+ * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
365+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
366+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
367+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
368+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
369+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
370+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
371+ *
372+ * You should have received a copy of the GNU General Public License along
373+ * with this program; if not, write to the Free Software Foundation, Inc.,
374+ * 675 Mass Ave, Cambridge, MA 02139, USA.
375+ */
376+
377+#include <linux/errno.h>
378+#include <linux/init.h>
379+#include <linux/interrupt.h>
380+#include <linux/irq.h>
381+#include <linux/module.h>
382+#include <linux/smp.h>
383+#include <linux/types.h>
384+
385+#include <asm/cpu.h>
386+#include <asm/io.h>
387+#include <asm/irq.h>
388+#include <asm/irq_cpu.h>
389+
390+void plat_irq_dispatch(void)
391+{
392+ u32 cause;
393+
394+ cause = read_c0_cause() & read_c0_status() & CAUSEF_IP;
395+
396+ clear_c0_status(cause);
397+
398+ if (cause & CAUSEF_IP7)
399+ do_IRQ(7);
400+ if (cause & CAUSEF_IP2)
401+ do_IRQ(2);
402+ if (cause & CAUSEF_IP3)
403+ do_IRQ(3);
404+ if (cause & CAUSEF_IP4)
405+ do_IRQ(4);
406+ if (cause & CAUSEF_IP5)
407+ do_IRQ(5);
408+ if (cause & CAUSEF_IP6)
409+ do_IRQ(6);
410+}
411+
412+void __init arch_init_irq(void)
413+{
414+ mips_cpu_irq_init(0);
415+}
416diff -Nru linux-2.6.19.ori/arch/mips/bcm947xx/nvram.c linux-2.6.19/arch/mips/bcm947xx/nvram.c
417--- linux-2.6.19.ori/arch/mips/bcm947xx/nvram.c 1970-01-01 01:00:00.000000000 +0100
418+++ linux-2.6.19/arch/mips/bcm947xx/nvram.c 2006-12-02 20:56:05.000000000 +0100
419@@ -0,0 +1,131 @@
420+/*
421+ * BCM947xx nvram variable access
422+ *
423+ * Copyright 2006, Felix Fietkau <nbd@openwrt.org>
424+ *
425+ * This program is free software; you can redistribute it and/or modify it
426+ * under the terms of the GNU General Public License as published by the
427+ * Free Software Foundation; either version 2 of the License, or (at your
428+ * option) any later version.
429+ *
430+ *
431+ * Copyright 2005, Broadcom Corporation
432+ *
433+ * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY
434+ * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM
435+ * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS
436+ * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE.
437+ *
438+ */
439+
440+#include <linux/init.h>
441+#include <linux/module.h>
442+#include <linux/ssb.h>
443+#include <linux/kernel.h>
444+#include <linux/string.h>
445+#include <linux/interrupt.h>
446+#include <linux/spinlock.h>
447+#include <linux/slab.h>
448+#include <asm/byteorder.h>
449+#include <asm/bootinfo.h>
450+#include <asm/addrspace.h>
451+#include <asm/io.h>
452+#include <asm/uaccess.h>
453+
454+#include <nvram.h>
455+
456+#define MB * 1048576
457+extern struct ssb_bus ssb;
458+
459+static char nvram_buf[NVRAM_SPACE];
460+static int cfe_env;
461+extern char *cfe_env_get(char *nv_buf, const char *name);
462+
463+/* Probe for NVRAM header */
464+static void __init early_nvram_init(void)
465+{
466+ struct ssb_mipscore *mcore = &ssb.mipscore;
467+ struct nvram_header *header;
468+ int i;
469+ u32 base, lim, off;
470+ u32 *src, *dst;
471+
472+ base = mcore->flash_window;
473+ lim = mcore->flash_window_size;
474+ cfe_env = 0;
475+
476+
477+ /* XXX: hack for supporting the CFE environment stuff on WGT634U */
478+ if (lim >= 8 MB) {
479+ src = (u32 *) KSEG1ADDR(base + 8 MB - 0x2000);
480+ dst = (u32 *) nvram_buf;
481+
482+ if ((*src & 0xff00ff) == 0x000001) {
483+ printk("early_nvram_init: WGT634U NVRAM found.\n");
484+
485+ for (i = 0; i < 0x1ff0; i++) {
486+ if (*src == 0xFFFFFFFF)
487+ break;
488+ *dst++ = *src++;
489+ }
490+ cfe_env = 1;
491+ return;
492+ }
493+ }
494+
495+ off = 0x20000;
496+ while (off <= lim) {
497+ /* Windowed flash access */
498+ header = (struct nvram_header *) KSEG1ADDR(base + off - NVRAM_SPACE);
499+ if (header->magic == NVRAM_HEADER)
500+ goto found;
501+ off <<= 1;
502+ }
503+
504+ /* Try embedded NVRAM at 4 KB and 1 KB as last resorts */
505+ header = (struct nvram_header *) KSEG1ADDR(base + 4096);
506+ if (header->magic == NVRAM_HEADER)
507+ goto found;
508+
509+ header = (struct nvram_header *) KSEG1ADDR(base + 1024);
510+ if (header->magic == NVRAM_HEADER)
511+ goto found;
512+
513+ return;
514+
515+found:
516+ src = (u32 *) header;
517+ dst = (u32 *) nvram_buf;
518+ for (i = 0; i < sizeof(struct nvram_header); i += 4)
519+ *dst++ = *src++;
520+ for (; i < header->len && i < NVRAM_SPACE; i += 4)
521+ *dst++ = le32_to_cpu(*src++);
522+}
523+
524+char *nvram_get(const char *name)
525+{
526+ char *var, *value, *end, *eq;
527+
528+ if (!name)
529+ return NULL;
530+
531+ if (!nvram_buf[0])
532+ early_nvram_init();
533+
534+ if (cfe_env)
535+ return cfe_env_get(nvram_buf, name);
536+
537+ /* Look for name=value and return value */
538+ var = &nvram_buf[sizeof(struct nvram_header)];
539+ end = nvram_buf + sizeof(nvram_buf) - 2;
540+ end[0] = end[1] = '\0';
541+ for (; *var; var = value + strlen(value) + 1) {
542+ if (!(eq = strchr(var, '=')))
543+ break;
544+ value = eq + 1;
545+ if ((eq - var) == strlen(name) && strncmp(var, name, (eq - var)) == 0)
546+ return value;
547+ }
548+
549+ return NULL;
550+}
551diff -Nru linux-2.6.19.ori/arch/mips/bcm947xx/pci.c linux-2.6.19/arch/mips/bcm947xx/pci.c
552--- linux-2.6.19.ori/arch/mips/bcm947xx/pci.c 1970-01-01 01:00:00.000000000 +0100
553+++ linux-2.6.19/arch/mips/bcm947xx/pci.c 2006-12-02 20:56:05.000000000 +0100
554@@ -0,0 +1,227 @@
555+#include <linux/kernel.h>
556+#include <linux/init.h>
557+#include <linux/pci.h>
558+#include <linux/types.h>
559+
560+#include <asm/cpu.h>
561+#include <asm/io.h>
562+
563+#include <typedefs.h>
564+#include <osl.h>
565+#include <sbutils.h>
566+#include <sbmips.h>
567+#include <sbconfig.h>
568+#include <sbpci.h>
569+#include <bcmdevs.h>
570+#include <pcicfg.h>
571+
572+extern sb_t *sbh;
573+extern spinlock_t sbh_lock;
574+
575+
576+static int
577+sb_pci_read_config(struct pci_bus *bus, unsigned int devfn,
578+ int reg, int size, u32 *val)
579+{
580+ int ret;
581+ unsigned long flags;
582+
583+ spin_lock_irqsave(&sbh_lock, flags);
584+ ret = sbpci_read_config(sbh, bus->number, PCI_SLOT(devfn), PCI_FUNC(devfn), reg, val, size);
585+ spin_unlock_irqrestore(&sbh_lock, flags);
586+
587+ return ret ? PCIBIOS_DEVICE_NOT_FOUND : PCIBIOS_SUCCESSFUL;
588+}
589+
590+static int
591+sb_pci_write_config(struct pci_bus *bus, unsigned int devfn,
592+ int reg, int size, u32 val)
593+{
594+ int ret;
595+ unsigned long flags;
596+
597+ spin_lock_irqsave(&sbh_lock, flags);
598+ ret = sbpci_write_config(sbh, bus->number, PCI_SLOT(devfn), PCI_FUNC(devfn), reg, &val, size);
599+ spin_unlock_irqrestore(&sbh_lock, flags);
600+
601+ return ret ? PCIBIOS_DEVICE_NOT_FOUND : PCIBIOS_SUCCESSFUL;
602+}
603+
604+
605+static struct pci_ops sb_pci_ops = {
606+ .read = sb_pci_read_config,
607+ .write = sb_pci_write_config,
608+};
609+
610+static struct resource sb_pci_mem_resource = {
611+ .name = "SB PCI Memory resources",
612+ .start = SB_ENUM_BASE,
613+ .end = SB_ENUM_LIM - 1,
614+ .flags = IORESOURCE_MEM,
615+};
616+
617+static struct resource sb_pci_io_resource = {
618+ .name = "SB PCI I/O resources",
619+ .start = 0x000,
620+ .end = 0x0FF,
621+ .flags = IORESOURCE_IO,
622+};
623+
624+static struct pci_controller bcm47xx_sb_pci_controller = {
625+ .pci_ops = &sb_pci_ops,
626+ .mem_resource = &sb_pci_mem_resource,
627+ .io_resource = &sb_pci_io_resource,
628+};
629+
630+static struct resource ext_pci_mem_resource = {
631+ .name = "Ext PCI Memory resources",
632+ .start = 0x40000000,
633+ .end = 0x7fffffff,
634+ .flags = IORESOURCE_MEM,
635+};
636+
637+static struct resource ext_pci_io_resource = {
638+ .name = "Ext PCI I/O resources",
639+ .start = 0x100,
640+ .end = 0x7FF,
641+ .flags = IORESOURCE_IO,
642+};
643+
644+static struct pci_controller bcm47xx_ext_pci_controller = {
645+ .pci_ops = &sb_pci_ops,
646+ .io_resource = &ext_pci_io_resource,
647+ .mem_resource = &ext_pci_mem_resource,
648+ .mem_offset = 0x24000000,
649+};
650+
651+void bcm47xx_pci_init(void)
652+{
653+ unsigned long flags;
654+
655+ spin_lock_irqsave(&sbh_lock, flags);
656+ sbpci_init(sbh);
657+ spin_unlock_irqrestore(&sbh_lock, flags);
658+
659+ set_io_port_base((unsigned long) ioremap_nocache(SB_PCI_MEM, 0x04000000));
660+
661+ register_pci_controller(&bcm47xx_sb_pci_controller);
662+ register_pci_controller(&bcm47xx_ext_pci_controller);
663+}
664+
665+int __init pcibios_map_irq(struct pci_dev *dev, u8 slot, u8 pin)
666+{
667+ unsigned long flags;
668+ u8 irq;
669+ uint idx;
670+
671+ /* external: use the irq of the pci core */
672+ if (dev->bus->number >= 1) {
673+ spin_lock_irqsave(&sbh_lock, flags);
674+ idx = sb_coreidx(sbh);
675+ sb_setcore(sbh, SB_PCI, 0);
676+ irq = sb_irq(sbh);
677+ sb_setcoreidx(sbh, idx);
678+ spin_unlock_irqrestore(&sbh_lock, flags);
679+
680+ return irq + 2;
681+ }
682+
683+ /* internal */
684+ pci_read_config_byte(dev, PCI_INTERRUPT_LINE, &irq);
685+ return irq + 2;
686+}
687+
688+u32 pci_iobase = 0x100;
689+u32 pci_membase = SB_PCI_DMA;
690+
691+static void bcm47xx_fixup_device(struct pci_dev *d)
692+{
693+ struct resource *res;
694+ int pos, size;
695+ u32 *base;
696+
697+ if (d->bus->number == 0)
698+ return;
699+
700+ printk("PCI: Fixing up device %s\n", pci_name(d));
701+
702+ /* Fix up resource bases */
703+ for (pos = 0; pos < 6; pos++) {
704+ res = &d->resource[pos];
705+ base = ((res->flags & IORESOURCE_IO) ? &pci_iobase : &pci_membase);
706+ if (res->end) {
707+ size = res->end - res->start + 1;
708+ if (*base & (size - 1))
709+ *base = (*base + size) & ~(size - 1);
710+ res->start = *base;
711+ res->end = res->start + size - 1;
712+ *base += size;
713+ pci_write_config_dword(d, PCI_BASE_ADDRESS_0 + (pos << 2), res->start);
714+ }
715+ /* Fix up PCI bridge BAR0 only */
716+ if (d->bus->number == 1 && PCI_SLOT(d->devfn) == 0)
717+ break;
718+ }
719+ /* Fix up interrupt lines */
720+ if (pci_find_device(VENDOR_BROADCOM, SB_PCI, NULL))
721+ d->irq = (pci_find_device(VENDOR_BROADCOM, SB_PCI, NULL))->irq;
722+ pci_write_config_byte(d, PCI_INTERRUPT_LINE, d->irq);
723+}
724+
725+
726+static void bcm47xx_fixup_bridge(struct pci_dev *dev)
727+{
728+ if (dev->bus->number != 1 || PCI_SLOT(dev->devfn) != 0)
729+ return;
730+
731+ printk("PCI: fixing up bridge\n");
732+
733+ /* Enable PCI bridge bus mastering and memory space */
734+ pci_set_master(dev);
735+ pcibios_enable_device(dev, ~0);
736+
737+ /* Enable PCI bridge BAR1 prefetch and burst */
738+ pci_write_config_dword(dev, PCI_BAR1_CONTROL, 3);
739+}
740+
741+/* Do platform specific device initialization at pci_enable_device() time */
742+int pcibios_plat_dev_init(struct pci_dev *dev)
743+{
744+ uint coreidx;
745+ unsigned long flags;
746+
747+ bcm47xx_fixup_device(dev);
748+
749+ /* These cores come out of reset enabled */
750+ if ((dev->bus->number != 0) ||
751+ (dev->device == SB_MIPS) ||
752+ (dev->device == SB_MIPS33) ||
753+ (dev->device == SB_EXTIF) ||
754+ (dev->device == SB_CC))
755+ return 0;
756+
757+ /* Do a core reset */
758+ spin_lock_irqsave(&sbh_lock, flags);
759+ coreidx = sb_coreidx(sbh);
760+ if (sb_setcoreidx(sbh, PCI_SLOT(dev->devfn)) && (sb_coreid(sbh) == SB_USB)) {
761+ /*
762+ * The USB core requires a special bit to be set during core
763+ * reset to enable host (OHCI) mode. Resetting the SB core in
764+ * pcibios_enable_device() is a hack for compatibility with
765+ * vanilla usb-ohci so that it does not have to know about
766+ * SB. A driver that wants to use the USB core in device mode
767+ * should know about SB and should reset the bit back to 0
768+ * after calling pcibios_enable_device().
769+ */
770+ sb_core_disable(sbh, sb_coreflags(sbh, 0, 0));
771+ sb_core_reset(sbh, 1 << 29);
772+ } else {
773+ sb_core_reset(sbh, 0);
774+ }
775+ sb_setcoreidx(sbh, coreidx);
776+ spin_unlock_irqrestore(&sbh_lock, flags);
777+
778+ return 0;
779+}
780+
781+DECLARE_PCI_FIXUP_EARLY(PCI_ANY_ID, PCI_ANY_ID, bcm47xx_fixup_bridge);
782diff -Nru linux-2.6.19.ori/arch/mips/bcm947xx/prom.c linux-2.6.19/arch/mips/bcm947xx/prom.c
783--- linux-2.6.19.ori/arch/mips/bcm947xx/prom.c 1970-01-01 01:00:00.000000000 +0100
784+++ linux-2.6.19/arch/mips/bcm947xx/prom.c 2006-12-02 20:56:05.000000000 +0100
785@@ -0,0 +1,59 @@
786+/*
787+ * Copyright (C) 2004 Florian Schirmer (jolt@tuxbox.org)
788+ *
789+ * This program is free software; you can redistribute it and/or modify it
790+ * under the terms of the GNU General Public License as published by the
791+ * Free Software Foundation; either version 2 of the License, or (at your
792+ * option) any later version.
793+ *
794+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
795+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
796+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
797+ * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
798+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
799+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
800+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
801+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
802+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
803+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
804+ *
805+ * You should have received a copy of the GNU General Public License along
806+ * with this program; if not, write to the Free Software Foundation, Inc.,
807+ * 675 Mass Ave, Cambridge, MA 02139, USA.
808+ */
809+
810+#include <linux/init.h>
811+#include <linux/mm.h>
812+#include <linux/sched.h>
813+#include <linux/bootmem.h>
814+
815+#include <asm/addrspace.h>
816+#include <asm/bootinfo.h>
817+#include <asm/pmon.h>
818+
819+const char *get_system_type(void)
820+{
821+ return "Broadcom BCM47xx";
822+}
823+
824+void __init prom_init(void)
825+{
826+ unsigned long mem;
827+
828+ mips_machgroup = MACH_GROUP_BRCM;
829+ mips_machtype = MACH_BCM47XX;
830+
831+ /* Figure out memory size by finding aliases */
832+ for (mem = (1 << 20); mem < (128 << 20); mem += (1 << 20)) {
833+ if (*(unsigned long *)((unsigned long)(prom_init) + mem) ==
834+ *(unsigned long *)(prom_init))
835+ break;
836+ }
837+
838+ add_memory_region(0, mem, BOOT_MEM_RAM);
839+}
840+
841+unsigned long __init prom_free_prom_memory(void)
842+{
843+ return 0;
844+}
845diff -Nru linux-2.6.19.ori/arch/mips/bcm947xx/setup.c linux-2.6.19/arch/mips/bcm947xx/setup.c
846--- linux-2.6.19.ori/arch/mips/bcm947xx/setup.c 1970-01-01 01:00:00.000000000 +0100
847+++ linux-2.6.19/arch/mips/bcm947xx/setup.c 2006-12-02 21:07:00.000000000 +0100
848@@ -0,0 +1,161 @@
849+/*
850+ * Copyright (C) 2004 Florian Schirmer (jolt@tuxbox.org)
851+ * Copyright (C) 2005 Waldemar Brodkorb <wbx@openwrt.org>
852+ * Copyright (C) 2006 Felix Fietkau <nbd@openwrt.org>
853+ * Copyright (C) 2006 Michael Buesch
854+ *
855+ * This program is free software; you can redistribute it and/or modify it
856+ * under the terms of the GNU General Public License as published by the
857+ * Free Software Foundation; either version 2 of the License, or (at your
858+ * option) any later version.
859+ *
860+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
861+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
862+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
863+ * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
864+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
865+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
866+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
867+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
868+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
869+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
870+ *
871+ * You should have received a copy of the GNU General Public License along
872+ * with this program; if not, write to the Free Software Foundation, Inc.,
873+ * 675 Mass Ave, Cambridge, MA 02139, USA.
874+ */
875+
876+#include <linux/init.h>
877+#include <linux/types.h>
878+#include <linux/tty.h>
879+#include <linux/serial.h>
880+#include <linux/serial_core.h>
881+#include <linux/serial_reg.h>
882+#include <asm/bootinfo.h>
883+#include <asm/time.h>
884+#include <asm/reboot.h>
885+#include <asm/cfe.h>
886+#include <linux/pm.h>
887+#include <linux/ssb.h>
888+
889+#include <nvram.h>
890+
891+extern void bcm47xx_pci_init(void);
892+extern void bcm47xx_time_init(void);
893+
894+struct ssb_bus ssb;
895+
896+static void bcm47xx_machine_restart(char *command)
897+{
898+ printk(KERN_ALERT "Please stand by while rebooting the system...\n");
899+ local_irq_disable();
900+ /* CFE has a reboot callback, but that does not work.
901+ * Oopses with: Reserved instruction in kernel code.
902+ */
903+
904+ /* Set the watchdog timer to reset immediately */
905+//TODO sb_watchdog(sbh, 1);
906+ while (1)
907+ cpu_relax();
908+}
909+
910+static void bcm47xx_machine_halt(void)
911+{
912+ /* Disable interrupts and watchdog and spin forever */
913+ local_irq_disable();
914+//TODO sb_watchdog(sbh, 0);
915+ while (1)
916+ cpu_relax();
917+}
918+
919+static void e_aton(char *str, char *dest)
920+{
921+ int i = 0;
922+
923+ if (str == NULL) {
924+ memset(dest, 0, 6);
925+ return;
926+ }
927+
928+ for (;;) {
929+ dest[i++] = (char) simple_strtoul(str, NULL, 16);
930+ str += 2;
931+ if (!*str++ || i == 6)
932+ break;
933+ }
934+}
935+
936+static void bcm47xx_fill_sprom(struct ssb_sprom *sprom)
937+{
938+ // TODO
939+}
940+
941+static void bcm47xx_fill_sprom_nvram(struct ssb_sprom *sprom)
942+{
943+ char *s;
944+
945+ memset(sprom, 0, sizeof(struct ssb_sprom));
946+
947+ sprom->revision = 3;
948+ if ((s = nvram_get("et0macaddr")))
949+ e_aton(s, sprom->r1.et0mac);
950+ if ((s = nvram_get("et1macaddr")))
951+ e_aton(s, sprom->r1.et1mac);
952+ if ((s = nvram_get("et0phyaddr")))
953+ sprom->r1.et0phyaddr = simple_strtoul(s, NULL, 10);
954+ if ((s = nvram_get("et1phyaddr")))
955+ sprom->r1.et1phyaddr = simple_strtoul(s, NULL, 10);
956+}
957+
958+void __init plat_mem_setup(void)
959+{
960+ int i, err;
961+ char *s;
962+ struct ssb_mipscore *mcore;
963+
964+ err = ssb_bus_ssbbus_register(&ssb, SSB_ENUM_BASE, bcm47xx_fill_sprom);
965+ if (err) {
966+ const char *msg = "Failed to initialize SSB bus (err %d)\n";
967+ cfe_printk(msg, err); /* Make sure the message gets out of the box. */
968+ panic(msg, err);
969+ }
970+ mcore = &ssb.mipscore;
971+
972+ /* FIXME: the nvram init depends on the ssb being fully initializes,
973+ * can't use the fill_sprom callback yet! */
974+ bcm47xx_fill_sprom_nvram(&ssb.sprom);
975+
976+ s = nvram_get("kernel_args");
977+ if (s && !strncmp(s, "console=ttyS1", 13) && (mcore->nr_serial_ports >= 2)) {
978+ struct ssb_serial_port port;
979+
980+ /* swap serial ports */
981+ memcpy(&port, &mcore->serial_ports[0], sizeof(port));
982+ memcpy(&mcore->serial_ports[0], &mcore->serial_ports[1], sizeof(port));
983+ memcpy(&mcore->serial_ports[1], &port, sizeof(port));
984+ }
985+
986+ for (i = 0; i < mcore->nr_serial_ports; i++) {
987+ struct ssb_serial_port *port = &(mcore->serial_ports[i]);
988+ struct uart_port s;
989+
990+ memset(&s, 0, sizeof(s));
991+ s.line = i;
992+ s.membase = port->regs;
993+ s.irq = port->irq + 2;//FIXME?
994+ s.uartclk = port->baud_base;
995+ s.flags = ASYNC_BOOT_AUTOCONF;
996+ s.iotype = SERIAL_IO_MEM;
997+ s.regshift = port->reg_shift;
998+
999+ early_serial_setup(&s);
1000+ }
1001+ cfe_printk("Serial init done.\n");
1002+
1003+ _machine_restart = bcm47xx_machine_restart;
1004+ _machine_halt = bcm47xx_machine_halt;
1005+ pm_power_off = bcm47xx_machine_halt;
1006+
1007+ board_time_init = bcm47xx_time_init;//FIXME move into ssb
1008+}
1009+
1010diff -Nru linux-2.6.19.ori/arch/mips/bcm947xx/time.c linux-2.6.19/arch/mips/bcm947xx/time.c
1011--- linux-2.6.19.ori/arch/mips/bcm947xx/time.c 1970-01-01 01:00:00.000000000 +0100
1012+++ linux-2.6.19/arch/mips/bcm947xx/time.c 2006-12-02 21:07:42.000000000 +0100
1013@@ -0,0 +1,62 @@
1014+/*
1015+ * Copyright (C) 2004 Florian Schirmer (jolt@tuxbox.org)
1016+ *
1017+ * This program is free software; you can redistribute it and/or modify it
1018+ * under the terms of the GNU General Public License as published by the
1019+ * Free Software Foundation; either version 2 of the License, or (at your
1020+ * option) any later version.
1021+ *
1022+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
1023+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
1024+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
1025+ * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
1026+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
1027+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
1028+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
1029+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
1030+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
1031+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
1032+ *
1033+ * You should have received a copy of the GNU General Public License along
1034+ * with this program; if not, write to the Free Software Foundation, Inc.,
1035+ * 675 Mass Ave, Cambridge, MA 02139, USA.
1036+ */
1037+
1038+#include <linux/init.h>
1039+#include <linux/kernel.h>
1040+#include <linux/sched.h>
1041+#include <linux/serial_reg.h>
1042+#include <linux/interrupt.h>
1043+#include <linux/ssb.h>
1044+#include <asm/addrspace.h>
1045+#include <asm/io.h>
1046+#include <asm/time.h>
1047+
1048+extern struct ssb_bus ssb;
1049+
1050+void __init
1051+bcm47xx_time_init(void)
1052+{
1053+ unsigned long hz;
1054+
1055+ /*
1056+ * Use deterministic values for initial counter interrupt
1057+ * so that calibrate delay avoids encountering a counter wrap.
1058+ */
1059+ write_c0_count(0);
1060+ write_c0_compare(0xffff);
1061+
1062+ hz = ssb_clockspeed(&ssb);
1063+ if (!hz)
1064+ hz = 100000000;
1065+
1066+ /* Set MIPS counter frequency for fixed_rate_gettimeoffset() */
1067+ mips_hpt_frequency = hz;
1068+}
1069+
1070+void __init
1071+plat_timer_setup(struct irqaction *irq)
1072+{
1073+ /* Enable the timer interrupt */
1074+ setup_irq(7, irq);
1075+}
1076diff -Nru linux-2.6.19.ori/arch/mips/cfe/Makefile linux-2.6.19/arch/mips/cfe/Makefile
1077--- linux-2.6.19.ori/arch/mips/cfe/Makefile 1970-01-01 01:00:00.000000000 +0100
1078+++ linux-2.6.19/arch/mips/cfe/Makefile 2006-12-02 19:14:34.000000000 +0100
1079@@ -0,0 +1,5 @@
1080+#
1081+# Makefile for the Broadcom Common Firmware Environment support
1082+#
1083+
1084+obj-y += cfe.o
1085diff -Nru linux-2.6.19.ori/arch/mips/cfe/cfe.c linux-2.6.19/arch/mips/cfe/cfe.c
1086--- linux-2.6.19.ori/arch/mips/cfe/cfe.c 1970-01-01 01:00:00.000000000 +0100
1087+++ linux-2.6.19/arch/mips/cfe/cfe.c 2006-12-02 19:14:34.000000000 +0100
1088@@ -0,0 +1,533 @@
1089+/*
1090+ * Broadcom Common Firmware Environment (CFE) support
1091+ *
1092+ * Copyright 2000, 2001, 2002
1093+ * Broadcom Corporation. All rights reserved.
1094+ *
1095+ * Copyright (C) 2006 Michael Buesch
1096+ *
1097+ * Original Authors: Mitch Lichtenberg, Chris Demetriou
1098+ *
1099+ * This software is furnished under license and may be used and copied only
1100+ * in accordance with the following terms and conditions. Subject to these
1101+ * conditions, you may download, copy, install, use, modify and distribute
1102+ * modified or unmodified copies of this software in source and/or binary
1103+ * form. No title or ownership is transferred hereby.
1104+ *
1105+ * 1) Any source code used, modified or distributed must reproduce and
1106+ * retain this copyright notice and list of conditions as they appear in
1107+ * the source file.
1108+ *
1109+ * 2) No right is granted to use any trade name, trademark, or logo of
1110+ * Broadcom Corporation. The "Broadcom Corporation" name may not be
1111+ * used to endorse or promote products derived from this software
1112+ * without the prior written permission of Broadcom Corporation.
1113+ *
1114+ * 3) THIS SOFTWARE IS PROVIDED "AS-IS" AND ANY EXPRESS OR IMPLIED
1115+ * WARRANTIES, INCLUDING BUT NOT LIMITED TO, ANY IMPLIED WARRANTIES OF
1116+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, OR
1117+ * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL BROADCOM BE LIABLE
1118+ * FOR ANY DAMAGES WHATSOEVER, AND IN PARTICULAR, BROADCOM SHALL NOT BE
1119+ * LIABLE FOR DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
1120+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
1121+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
1122+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
1123+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
1124+ * OR OTHERWISE), EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
1125+ */
1126+
1127+#include <linux/init.h>
1128+#include <linux/string.h>
1129+#include <linux/errno.h>
1130+#include <linux/spinlock.h>
1131+#include <asm/cfe.h>
1132+
1133+#include "cfe_private.h"
1134+
1135+
1136+static cfe_uint_t cfe_handle;
1137+static int (*cfe_trampoline)(long handle, long iocb);
1138+
1139+
1140+#include <linux/kernel.h>
1141+
1142+void __init cfe_setup(unsigned long fwarg0, unsigned long fwarg1,
1143+ unsigned long fwarg2, unsigned long fwarg3)
1144+{
1145+ if (fwarg3 == 0x80300000) {
1146+ /* WRT54G workaround */
1147+ fwarg3 = CFE_EPTSEAL;
1148+ fwarg2 = 0xBFC00500;
1149+ }
1150+ if (fwarg3 != CFE_EPTSEAL) {
1151+ /* We are not booted from CFE */
1152+ return;
1153+ }
1154+ if (fwarg1 == 0) {
1155+ /* We are on the boot CPU */
1156+ cfe_handle = (cfe_uint_t)fwarg0;
1157+ cfe_trampoline = CFE_TO_PTR(fwarg2);
1158+ }
1159+}
1160+
1161+int cfe_vprintk(const char *fmt, va_list args)
1162+{
1163+ static char buffer[1024];
1164+ static DEFINE_SPINLOCK(lock);
1165+ static const char pfx[] = "CFE-console: ";
1166+ static const size_t pfx_len = sizeof(pfx) - 1;
1167+ unsigned long flags;
1168+ int len, cnt, pos;
1169+ int handle;
1170+ int res;
1171+
1172+ if (!cfe_present())
1173+ return -ENODEV;
1174+
1175+ spin_lock_irqsave(&lock, flags);
1176+ handle = cfe_getstdhandle(CFE_STDHANDLE_CONSOLE);
1177+ if (CFE_ISERR(handle)) {
1178+ len = -EIO;
1179+ goto out;
1180+ }
1181+ strcpy(buffer, pfx);
1182+ len = vscnprintf(buffer + pfx_len,
1183+ sizeof(buffer) - pfx_len - 2,
1184+ fmt, args);
1185+ len += pfx_len;
1186+ /* The CFE console requires CR-LF line-ends.
1187+ * Add a CR, if we only terminate lines with a LF.
1188+ * This does only fix CR-LF at the end of the string.
1189+ * So for multiple lines, use multiple cfe_vprintk calls.
1190+ */
1191+ if (len > 1 &&
1192+ buffer[len - 1] == '\n' && buffer[len - 2] != '\r') {
1193+ buffer[len - 1] = '\r';
1194+ buffer[len] = '\n';
1195+ len += 1;
1196+ }
1197+ cnt = len;
1198+ pos = 0;
1199+ while (cnt > 0) {
1200+ res = cfe_write(handle, buffer + pos, len - pos);
1201+ if (CFE_ISERR(res)) {
1202+ len = -EIO;
1203+ goto out;
1204+ }
1205+ cnt -= res;
1206+ pos += res;
1207+ }
1208+out:
1209+ spin_unlock_irqrestore(&lock, flags);
1210+
1211+ return len;
1212+}
1213+
1214+int cfe_printk(const char *fmt, ...)
1215+{
1216+ va_list args;
1217+ int res;
1218+
1219+ va_start(args, fmt);
1220+ res = cfe_vprintk(fmt, args);
1221+ va_end(args);
1222+
1223+ return res;
1224+}
1225+
1226+static int cfe_iocb_dispatch(struct cfe_iocb *iocb)
1227+{
1228+ if (!cfe_present())
1229+ return CFE_ERR_UNSUPPORTED;
1230+ return cfe_trampoline((long)cfe_handle, (long)iocb);
1231+}
1232+
1233+int cfe_present(void)
1234+{
1235+ return (cfe_trampoline != NULL);
1236+}
1237+
1238+int cfe_close(int handle)
1239+{
1240+ struct cfe_iocb iocb;
1241+ int err;
1242+
1243+ memset(&iocb, 0, sizeof(iocb));
1244+ iocb.fcode = CFE_CMD_DEV_CLOSE;
1245+ iocb.handle = handle;
1246+
1247+ err = cfe_iocb_dispatch(&iocb);
1248+
1249+ return (CFE_ISERR(err)) ? err : iocb.status;
1250+}
1251+
1252+int cfe_cpu_start(int cpu, void (*fn)(void), long sp, long gp, long a1)
1253+{
1254+ struct cfe_iocb iocb;
1255+ int err;
1256+
1257+ memset(&iocb, 0, sizeof(iocb));
1258+ iocb.fcode = CFE_CMD_FW_CPUCTL;
1259+ iocb.psize = sizeof(struct cfe_iocb_cpuctl);
1260+ iocb.cpuctl.number = cpu;
1261+ iocb.cpuctl.command = CFE_CPU_CMD_START;
1262+ iocb.cpuctl.gp = gp;
1263+ iocb.cpuctl.sp = sp;
1264+ iocb.cpuctl.a1 = a1;
1265+ iocb.cpuctl.start_addr = (long)fn;
1266+
1267+ err = cfe_iocb_dispatch(&iocb);
1268+
1269+ return (CFE_ISERR(err)) ? err : iocb.status;
1270+}
1271+
1272+int cfe_cpu_stop(int cpu)
1273+{
1274+ struct cfe_iocb iocb;
1275+ int err;
1276+
1277+ memset(&iocb, 0, sizeof(iocb));
1278+ iocb.fcode = CFE_CMD_FW_CPUCTL;
1279+ iocb.psize = sizeof(struct cfe_iocb_cpuctl);
1280+ iocb.cpuctl.number = cpu;
1281+ iocb.cpuctl.command = CFE_CPU_CMD_STOP;
1282+
1283+ err = cfe_iocb_dispatch(&iocb);
1284+
1285+ return (CFE_ISERR(err)) ? err : iocb.status;
1286+}
1287+
1288+int cfe_enumenv(int idx, char *name, int namelen, char *val, int vallen)
1289+{
1290+ struct cfe_iocb iocb;
1291+ int err;
1292+
1293+ memset(&iocb, 0, sizeof(iocb));
1294+ iocb.fcode = CFE_CMD_ENV_ENUM;
1295+ iocb.psize = sizeof(struct cfe_iocb_envbuf);
1296+ iocb.envbuf.index = idx;
1297+ iocb.envbuf.name = PTR_TO_CFE(name);
1298+ iocb.envbuf.name_len = namelen;
1299+ iocb.envbuf.val = PTR_TO_CFE(val);
1300+ iocb.envbuf.val_len = vallen;
1301+
1302+ err = cfe_iocb_dispatch(&iocb);
1303+
1304+ return (CFE_ISERR(err)) ? err : iocb.status;
1305+}
1306+
1307+int cfe_enumdev(int idx, char *name, int namelen)
1308+{
1309+ struct cfe_iocb iocb;
1310+ int err;
1311+
1312+ memset(&iocb, 0, sizeof(iocb));
1313+
1314+ iocb.fcode = CFE_CMD_DEV_ENUM;
1315+ iocb.psize = sizeof(struct cfe_iocb_envbuf);
1316+ iocb.envbuf.index = idx;
1317+ iocb.envbuf.name = PTR_TO_CFE(name);
1318+ iocb.envbuf.name_len = namelen;
1319+
1320+ err = cfe_iocb_dispatch(&iocb);
1321+
1322+ return (CFE_ISERR(err)) ? err : iocb.status;
1323+}
1324+
1325+int cfe_enummem(int idx, int flags, u64 *start, u64 *length,
1326+ u64 *type)
1327+{
1328+ struct cfe_iocb iocb;
1329+ int err;
1330+
1331+ memset(&iocb, 0, sizeof(iocb));
1332+
1333+ iocb.fcode = CFE_CMD_FW_MEMENUM;
1334+ iocb.flags = flags;
1335+ iocb.psize = sizeof(struct cfe_iocb_meminfo);
1336+ iocb.meminfo.index = idx;
1337+
1338+ err = cfe_iocb_dispatch(&iocb);
1339+ if (CFE_ISERR(err))
1340+ return err;
1341+ if (!CFE_ISERR(iocb.status)) {
1342+ *start = iocb.meminfo.addr;
1343+ *length = iocb.meminfo.size;
1344+ *type = iocb.meminfo.type;
1345+ }
1346+
1347+ return iocb.status;
1348+}
1349+
1350+int cfe_exit(int warm, int status)
1351+{
1352+ struct cfe_iocb iocb;
1353+ int err;
1354+
1355+printk("CFE REBOOT\n");
1356+ memset(&iocb, 0, sizeof(iocb));
1357+ iocb.fcode = CFE_CMD_FW_RESTART;
1358+ if (warm)
1359+ iocb.flags = CFE_FLG_WARMSTART;
1360+ iocb.psize = sizeof(struct cfe_iocb_exitstat);
1361+ iocb.exitstat.status = status;
1362+
1363+printk("CALL\n");
1364+ err = cfe_iocb_dispatch(&iocb);
1365+printk("DONE\n");
1366+
1367+ return (CFE_ISERR(err)) ? err : iocb.status;
1368+}
1369+
1370+int cfe_flushcache(int flags)
1371+{
1372+ struct cfe_iocb iocb;
1373+ int err;
1374+
1375+ memset(&iocb, 0, sizeof(iocb));
1376+ iocb.fcode = CFE_CMD_FW_FLUSHCACHE;
1377+ iocb.flags = flags;
1378+
1379+ err = cfe_iocb_dispatch(&iocb);
1380+
1381+ return (CFE_ISERR(err)) ? err : iocb.status;
1382+}
1383+
1384+int cfe_getdevinfo(char *name)
1385+{
1386+ struct cfe_iocb iocb;
1387+ int err;
1388+
1389+ memset(&iocb, 0, sizeof(iocb));
1390+ iocb.fcode = CFE_CMD_DEV_GETINFO;
1391+ iocb.psize = sizeof(struct cfe_iocb_buf);
1392+ iocb.buffer.ptr = PTR_TO_CFE(name);
1393+ iocb.buffer.length = strlen(name);
1394+
1395+ err = cfe_iocb_dispatch(&iocb);
1396+ if (CFE_ISERR(err))
1397+ return err;
1398+ if (CFE_ISERR(iocb.status))
1399+ return iocb.status;
1400+
1401+ return iocb.buffer.devflags;
1402+}
1403+
1404+int cfe_getenv(char *name, char *dest, int destlen)
1405+{
1406+ struct cfe_iocb iocb;
1407+ int err;
1408+
1409+ dest[0] = '\0';
1410+ memset(&iocb, 0, sizeof(iocb));
1411+ iocb.fcode = CFE_CMD_ENV_GET;
1412+ iocb.psize = sizeof(struct cfe_iocb_envbuf);
1413+ iocb.envbuf.name = PTR_TO_CFE(name);
1414+ iocb.envbuf.name_len = strlen(name);
1415+ iocb.envbuf.val = PTR_TO_CFE(dest);
1416+ iocb.envbuf.val_len = destlen;
1417+
1418+ err = cfe_iocb_dispatch(&iocb);
1419+
1420+ return (CFE_ISERR(err)) ? err : iocb.status;
1421+}
1422+
1423+int cfe_getfwinfo(struct cfe_fwinfo *info)
1424+{
1425+ struct cfe_iocb iocb;
1426+ int err;
1427+
1428+ memset(&iocb, 0, sizeof(iocb));
1429+ iocb.fcode = CFE_CMD_FW_GETINFO;
1430+ iocb.psize = sizeof(struct cfe_iocb_fwinfo);
1431+
1432+ err = cfe_iocb_dispatch(&iocb);
1433+ if (CFE_ISERR(err))
1434+ return err;
1435+ if (CFE_ISERR(iocb.status))
1436+ return err;
1437+
1438+ info->version = iocb.fwinfo.version;
1439+ info->totalmem = iocb.fwinfo.totalmem;
1440+ info->flags = iocb.fwinfo.flags;
1441+ info->boardid = iocb.fwinfo.boardid;
1442+ info->bootarea_va = iocb.fwinfo.bootarea_va;
1443+ info->bootarea_pa = iocb.fwinfo.bootarea_pa;
1444+ info->bootarea_size = iocb.fwinfo.bootarea_size;
1445+
1446+ return iocb.status;
1447+}
1448+
1449+int cfe_getstdhandle(int handletype)
1450+{
1451+ struct cfe_iocb iocb;
1452+ int err;
1453+
1454+ memset(&iocb, 0, sizeof(iocb));
1455+ iocb.fcode = CFE_CMD_DEV_GETHANDLE;
1456+ iocb.flags = handletype;
1457+
1458+ err = cfe_iocb_dispatch(&iocb);
1459+ if (CFE_ISERR(err))
1460+ return err;
1461+ if (CFE_ISERR(iocb.status))
1462+ return iocb.status;
1463+
1464+ return iocb.handle;
1465+}
1466+
1467+int cfe_getticks(s64 *ticks)
1468+{
1469+ struct cfe_iocb iocb;
1470+ int err;
1471+
1472+ memset(&iocb, 0, sizeof(iocb));
1473+ iocb.fcode = CFE_CMD_FW_GETTIME;
1474+ iocb.psize = sizeof(struct cfe_iocb_time);
1475+
1476+ err = cfe_iocb_dispatch(&iocb);
1477+ if (CFE_ISERR(err))
1478+ return err;
1479+ if (!CFE_ISERR(iocb.status))
1480+ *ticks = iocb.time.ticks;
1481+
1482+ return iocb.status;
1483+}
1484+
1485+int cfe_inpstat(int handle)
1486+{
1487+ struct cfe_iocb iocb;
1488+ int err;
1489+
1490+ memset(&iocb, 0, sizeof(iocb));
1491+ iocb.fcode = CFE_CMD_DEV_INPSTAT;
1492+ iocb.handle = handle;
1493+ iocb.psize = sizeof(struct cfe_iocb_inpstat);
1494+
1495+ err = cfe_iocb_dispatch(&iocb);
1496+ if (CFE_ISERR(err))
1497+ return err;
1498+ if (CFE_ISERR(iocb.status))
1499+ return iocb.status;
1500+
1501+ return iocb.inpstat.status;
1502+}
1503+
1504+int cfe_ioctl(int handle, unsigned int ioctlnum,
1505+ unsigned char *buffer, int length,
1506+ int *retlen, u64 offset)
1507+{
1508+ struct cfe_iocb iocb;
1509+ int err;
1510+
1511+ memset(&iocb, 0, sizeof(iocb));
1512+ iocb.fcode = CFE_CMD_DEV_IOCTL;
1513+ iocb.handle = handle;
1514+ iocb.psize = sizeof(struct cfe_iocb_buf);
1515+ iocb.buffer.offset = offset;
1516+ iocb.buffer.ioctlcmd = ioctlnum;
1517+ iocb.buffer.ptr = PTR_TO_CFE(buffer);
1518+ iocb.buffer.length = length;
1519+
1520+ err = cfe_iocb_dispatch(&iocb);
1521+ if (CFE_ISERR(err))
1522+ return err;
1523+ if (CFE_ISERR(iocb.status))
1524+ return iocb.status;
1525+ if (retlen)
1526+ *retlen = iocb.buffer.retlen;
1527+
1528+ return iocb.status;
1529+}
1530+
1531+int cfe_open(char *name)
1532+{
1533+ struct cfe_iocb iocb;
1534+ int err;
1535+
1536+ memset(&iocb, 0, sizeof(iocb));
1537+ iocb.fcode = CFE_CMD_DEV_OPEN;
1538+ iocb.psize = sizeof(struct cfe_iocb_buf);
1539+ iocb.buffer.ptr = PTR_TO_CFE(name);
1540+ iocb.buffer.length = strlen(name);
1541+
1542+ err = cfe_iocb_dispatch(&iocb);
1543+ if (CFE_ISERR(err))
1544+ return err;
1545+ if (CFE_ISERR(iocb.status))
1546+ return iocb.status;
1547+
1548+ return iocb.handle;
1549+}
1550+
1551+int cfe_read(int handle, unsigned char *buffer, int length)
1552+{
1553+ return cfe_readblk(handle, 0, buffer, length);
1554+}
1555+
1556+int cfe_readblk(int handle, s64 offset, unsigned char *buffer, int length)
1557+{
1558+ struct cfe_iocb iocb;
1559+ int err;
1560+
1561+ memset(&iocb, 0, sizeof(iocb));
1562+ iocb.fcode = CFE_CMD_DEV_READ;
1563+ iocb.handle = handle;
1564+ iocb.psize = sizeof(struct cfe_iocb_buf);
1565+ iocb.buffer.offset = offset;
1566+ iocb.buffer.ptr = PTR_TO_CFE(buffer);
1567+ iocb.buffer.length = length;
1568+
1569+ err = cfe_iocb_dispatch(&iocb);
1570+ if (CFE_ISERR(err))
1571+ return err;
1572+ if (CFE_ISERR(iocb.status))
1573+ return iocb.status;
1574+
1575+ return iocb.buffer.retlen;
1576+}
1577+
1578+int cfe_setenv(char *name, char *val)
1579+{
1580+ struct cfe_iocb iocb;
1581+ int err;
1582+
1583+ memset(&iocb, 0, sizeof(iocb));
1584+ iocb.fcode = CFE_CMD_ENV_SET;
1585+ iocb.psize = sizeof(struct cfe_iocb_envbuf);
1586+ iocb.envbuf.name = PTR_TO_CFE(name);
1587+ iocb.envbuf.name_len = strlen(name);
1588+ iocb.envbuf.val = PTR_TO_CFE(val);
1589+ iocb.envbuf.val_len = strlen(val);
1590+
1591+ err = cfe_iocb_dispatch(&iocb);
1592+
1593+ return (CFE_ISERR(err)) ? err : iocb.status;
1594+}
1595+
1596+int cfe_write(int handle, unsigned char *buffer, int length)
1597+{
1598+ return cfe_writeblk(handle, 0, buffer, length);
1599+}
1600+
1601+int cfe_writeblk(int handle, s64 offset, unsigned char *buffer, int length)
1602+{
1603+ struct cfe_iocb iocb;
1604+ int err;
1605+
1606+ memset(&iocb, 0, sizeof(iocb));
1607+ iocb.fcode = CFE_CMD_DEV_WRITE;
1608+ iocb.handle = handle;
1609+ iocb.psize = sizeof(struct cfe_iocb_buf);
1610+ iocb.buffer.offset = offset;
1611+ iocb.buffer.ptr = PTR_TO_CFE(buffer);
1612+ iocb.buffer.length = length;
1613+
1614+ err = cfe_iocb_dispatch(&iocb);
1615+ if (CFE_ISERR(err))
1616+ return err;
1617+ if (CFE_ISERR(iocb.status))
1618+ return iocb.status;
1619+
1620+ return iocb.buffer.retlen;
1621+}
1622diff -Nru linux-2.6.19.ori/arch/mips/cfe/cfe_private.h linux-2.6.19/arch/mips/cfe/cfe_private.h
1623--- linux-2.6.19.ori/arch/mips/cfe/cfe_private.h 1970-01-01 01:00:00.000000000 +0100
1624+++ linux-2.6.19/arch/mips/cfe/cfe_private.h 2006-12-02 19:14:34.000000000 +0100
1625@@ -0,0 +1,176 @@
1626+/*
1627+ * Broadcom Common Firmware Environment (CFE) support
1628+ *
1629+ * Copyright 2000, 2001, 2002
1630+ * Broadcom Corporation. All rights reserved.
1631+ *
1632+ * Copyright (C) 2006 Michael Buesch
1633+ *
1634+ * Original Authors: Mitch Lichtenberg, Chris Demetriou
1635+ *
1636+ * This software is furnished under license and may be used and copied only
1637+ * in accordance with the following terms and conditions. Subject to these
1638+ * conditions, you may download, copy, install, use, modify and distribute
1639+ * modified or unmodified copies of this software in source and/or binary
1640+ * form. No title or ownership is transferred hereby.
1641+ *
1642+ * 1) Any source code used, modified or distributed must reproduce and
1643+ * retain this copyright notice and list of conditions as they appear in
1644+ * the source file.
1645+ *
1646+ * 2) No right is granted to use any trade name, trademark, or logo of
1647+ * Broadcom Corporation. The "Broadcom Corporation" name may not be
1648+ * used to endorse or promote products derived from this software
1649+ * without the prior written permission of Broadcom Corporation.
1650+ *
1651+ * 3) THIS SOFTWARE IS PROVIDED "AS-IS" AND ANY EXPRESS OR IMPLIED
1652+ * WARRANTIES, INCLUDING BUT NOT LIMITED TO, ANY IMPLIED WARRANTIES OF
1653+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, OR
1654+ * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL BROADCOM BE LIABLE
1655+ * FOR ANY DAMAGES WHATSOEVER, AND IN PARTICULAR, BROADCOM SHALL NOT BE
1656+ * LIABLE FOR DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
1657+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
1658+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
1659+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
1660+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
1661+ * OR OTHERWISE), EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
1662+ */
1663+
1664+#ifndef LINUX_CFE_PRIVATE_H_
1665+#define LINUX_CFE_PRIVATE_H_
1666+
1667+#ifndef __ASSEMBLY__
1668+
1669+/* Seal indicating CFE's presence, passed to the kernel. */
1670+#define CFE_EPTSEAL 0x43464531
1671+
1672+#define CFE_CMD_FW_GETINFO 0
1673+#define CFE_CMD_FW_RESTART 1
1674+#define CFE_CMD_FW_BOOT 2
1675+#define CFE_CMD_FW_CPUCTL 3
1676+#define CFE_CMD_FW_GETTIME 4
1677+#define CFE_CMD_FW_MEMENUM 5
1678+#define CFE_CMD_FW_FLUSHCACHE 6
1679+
1680+#define CFE_CMD_DEV_GETHANDLE 9
1681+#define CFE_CMD_DEV_ENUM 10
1682+#define CFE_CMD_DEV_OPEN 11
1683+#define CFE_CMD_DEV_INPSTAT 12
1684+#define CFE_CMD_DEV_READ 13
1685+#define CFE_CMD_DEV_WRITE 14
1686+#define CFE_CMD_DEV_IOCTL 15
1687+#define CFE_CMD_DEV_CLOSE 16
1688+#define CFE_CMD_DEV_GETINFO 17
1689+
1690+#define CFE_CMD_ENV_ENUM 20
1691+#define CFE_CMD_ENV_GET 22
1692+#define CFE_CMD_ENV_SET 23
1693+#define CFE_CMD_ENV_DEL 24
1694+
1695+#define CFE_CMD_MAX 32
1696+
1697+#define CFE_CMD_VENDOR_USE 0x8000 /* codes above this are for customer use */
1698+
1699+typedef u64 cfe_uint_t;
1700+typedef s64 cfe_int_t;
1701+typedef s64 cfe_ptr_t;
1702+
1703+/* Cast a pointer from native to CFE-API pointer and back */
1704+#define CFE_TO_PTR(p) ((void *)(unsigned long)(p))
1705+#define PTR_TO_CFE(p) ((cfe_ptr_t)(unsigned long)(p))
1706+
1707+struct cfe_iocb_buf {
1708+ cfe_uint_t offset; /* offset on device (bytes) */
1709+ cfe_ptr_t ptr; /* pointer to a buffer */
1710+ cfe_uint_t length; /* length of this buffer */
1711+ cfe_uint_t retlen; /* returned length (for read ops) */
1712+ union {
1713+ cfe_uint_t ioctlcmd; /* IOCTL command (used only for IOCTLs) */
1714+ cfe_uint_t devflags; /* Returned device info flags */
1715+ };
1716+};
1717+
1718+struct cfe_iocb_inpstat {
1719+ cfe_uint_t status; /* 1 means input available */
1720+};
1721+
1722+struct cfe_iocb_envbuf {
1723+ cfe_int_t index; /* 0-based enumeration index */
1724+ cfe_ptr_t name; /* name string buffer */
1725+ cfe_int_t name_len; /* size of name buffer */
1726+ cfe_ptr_t val; /* value string buffer */
1727+ cfe_int_t val_len; /* size of value string buffer */
1728+};
1729+
1730+struct cfe_iocb_cpuctl {
1731+ cfe_uint_t number; /* cpu number to control */
1732+ cfe_uint_t command; /* command to issue to CPU */
1733+ cfe_uint_t start_addr; /* CPU start address */
1734+ cfe_uint_t gp; /* starting GP value */
1735+ cfe_uint_t sp; /* starting SP value */
1736+ cfe_uint_t a1; /* starting A1 value */
1737+};
1738+
1739+struct cfe_iocb_time {
1740+ cfe_int_t ticks; /* current time in ticks */
1741+};
1742+
1743+struct cfe_iocb_exitstat {
1744+ cfe_int_t status;
1745+};
1746+
1747+struct cfe_iocb_meminfo {
1748+ cfe_int_t index; /* 0-based enumeration index */
1749+ cfe_int_t type; /* type of memory block */
1750+ cfe_uint_t addr; /* physical start address */
1751+ cfe_uint_t size; /* block size */
1752+};
1753+
1754+struct cfe_iocb_fwinfo {
1755+ cfe_int_t version; /* major, minor, eco version */
1756+ cfe_int_t totalmem; /* total installed mem */
1757+ cfe_int_t flags; /* various flags */
1758+ cfe_int_t boardid; /* board ID */
1759+ cfe_int_t bootarea_va; /* VA of boot area */
1760+ cfe_int_t bootarea_pa; /* PA of boot area */
1761+ cfe_int_t bootarea_size; /* size of boot area */
1762+ cfe_int_t reserved1;
1763+ cfe_int_t reserved2;
1764+ cfe_int_t reserved3;
1765+};
1766+
1767+/* CFE I/O Control Block */
1768+struct cfe_iocb {
1769+ cfe_uint_t fcode; /* IOCB function code */
1770+ cfe_int_t status; /* return status */
1771+ cfe_int_t handle; /* file/device handle */
1772+ cfe_uint_t flags; /* flags for this IOCB */
1773+ cfe_uint_t psize; /* size of parameter list */
1774+ union {
1775+ struct cfe_iocb_buf buffer; /* buffer parameters */
1776+ struct cfe_iocb_inpstat inpstat; /* input status parameters */
1777+ struct cfe_iocb_envbuf envbuf; /* environment function parameters */
1778+ struct cfe_iocb_cpuctl cpuctl; /* CPU control parameters */
1779+ struct cfe_iocb_time time; /* timer parameters */
1780+ struct cfe_iocb_meminfo meminfo; /* memory arena info parameters */
1781+ struct cfe_iocb_fwinfo fwinfo; /* firmware information */
1782+ struct cfe_iocb_exitstat exitstat; /* Exit Status */
1783+ };
1784+};
1785+
1786+
1787+#include <linux/init.h>
1788+
1789+void __init cfe_setup(unsigned long fwarg0, unsigned long fwarg1,
1790+ unsigned long fwarg2, unsigned long fwarg3);
1791+
1792+#else /* __ASSEMBLY__ */
1793+
1794+ .macro cfe_early_init
1795+#ifdef CONFIG_CFE
1796+ jal cfe_setup
1797+#endif
1798+ .endm
1799+
1800+#endif /* __ASSEMBLY__ */
1801+#endif /* LINUX_CFE_PRIVATE_H_ */
1802diff -Nru linux-2.6.19.ori/arch/mips/kernel/cpu-probe.c linux-2.6.19/arch/mips/kernel/cpu-probe.c
1803--- linux-2.6.19.ori/arch/mips/kernel/cpu-probe.c 2006-12-02 18:55:37.000000000 +0100
1804+++ linux-2.6.19/arch/mips/kernel/cpu-probe.c 2006-12-02 19:14:34.000000000 +0100
1805@@ -723,6 +723,28 @@
1806 }
1807
1808
1809+static inline void cpu_probe_broadcom(struct cpuinfo_mips *c)
1810+{
1811+ decode_config1(c);
1812+ switch (c->processor_id & 0xff00) {
1813+ case PRID_IMP_BCM3302:
1814+ c->cputype = CPU_BCM3302;
1815+ c->isa_level = MIPS_CPU_ISA_M32R1;
1816+ c->options = MIPS_CPU_TLB | MIPS_CPU_4KEX |
1817+ MIPS_CPU_4K_CACHE | MIPS_CPU_COUNTER;
1818+ break;
1819+ case PRID_IMP_BCM4710:
1820+ c->cputype = CPU_BCM4710;
1821+ c->isa_level = MIPS_CPU_ISA_M32R1;
1822+ c->options = MIPS_CPU_TLB | MIPS_CPU_4KEX |
1823+ MIPS_CPU_4K_CACHE | MIPS_CPU_COUNTER;
1824+ break;
1825+ default:
1826+ c->cputype = CPU_UNKNOWN;
1827+ break;
1828+ }
1829+}
1830+
1831 __init void cpu_probe(void)
1832 {
1833 struct cpuinfo_mips *c = &current_cpu_data;
1834@@ -745,6 +767,9 @@
1835 case PRID_COMP_SIBYTE:
1836 cpu_probe_sibyte(c);
1837 break;
1838+ case PRID_COMP_BROADCOM:
1839+ cpu_probe_broadcom(c);
1840+ break;
1841 case PRID_COMP_SANDCRAFT:
1842 cpu_probe_sandcraft(c);
1843 break;
1844diff -Nru linux-2.6.19.ori/arch/mips/kernel/head.S linux-2.6.19/arch/mips/kernel/head.S
1845--- linux-2.6.19.ori/arch/mips/kernel/head.S 2006-12-02 18:55:37.000000000 +0100
1846+++ linux-2.6.19/arch/mips/kernel/head.S 2006-12-02 23:36:23.000000000 +0100
1847@@ -129,6 +129,9 @@
1848 #endif
1849 .endm
1850
1851+ j kernel_entry
1852+ nop
1853+
1854 /*
1855 * Reserved space for exception handlers.
1856 * Necessary for machines which link their kernels at KSEG0.
1857diff -Nru linux-2.6.19.ori/arch/mips/kernel/proc.c linux-2.6.19/arch/mips/kernel/proc.c
1858--- linux-2.6.19.ori/arch/mips/kernel/proc.c 2006-12-02 18:55:37.000000000 +0100
1859+++ linux-2.6.19/arch/mips/kernel/proc.c 2006-12-02 19:14:34.000000000 +0100
1860@@ -83,6 +83,8 @@
1861 [CPU_VR4181] = "NEC VR4181",
1862 [CPU_VR4181A] = "NEC VR4181A",
1863 [CPU_SR71000] = "Sandcraft SR71000",
1864+ [CPU_BCM3302] = "Broadcom BCM3302",
1865+ [CPU_BCM4710] = "Broadcom BCM4710",
1866 [CPU_PR4450] = "Philips PR4450",
1867 };
1868
1869diff -Nru linux-2.6.19.ori/arch/mips/mm/tlbex.c linux-2.6.19/arch/mips/mm/tlbex.c
1870--- linux-2.6.19.ori/arch/mips/mm/tlbex.c 2006-12-02 18:55:37.000000000 +0100
1871+++ linux-2.6.19/arch/mips/mm/tlbex.c 2006-12-02 23:53:07.000000000 +0100
1872@@ -880,6 +880,8 @@
1873 case CPU_4KSC:
1874 case CPU_20KC:
1875 case CPU_25KF:
1876+ case CPU_BCM3302:
1877+ case CPU_BCM4710:
1878 tlbw(p);
1879 break;
1880
1881diff -Nru linux-2.6.19.ori/drivers/Kconfig linux-2.6.19/drivers/Kconfig
1882--- linux-2.6.19.ori/drivers/Kconfig 2006-12-02 18:55:37.000000000 +0100
1883+++ linux-2.6.19/drivers/Kconfig 2006-12-02 19:14:34.000000000 +0100
1884@@ -56,6 +56,8 @@
1885
1886 source "drivers/hwmon/Kconfig"
1887
1888+source "drivers/ssb/Kconfig"
1889+
1890 source "drivers/mfd/Kconfig"
1891
1892 source "drivers/media/Kconfig"
1893diff -Nru linux-2.6.19.ori/drivers/Makefile linux-2.6.19/drivers/Makefile
1894--- linux-2.6.19.ori/drivers/Makefile 2006-12-02 18:55:37.000000000 +0100
1895+++ linux-2.6.19/drivers/Makefile 2006-12-02 19:15:08.000000000 +0100
1896@@ -77,3 +77,4 @@
1897 obj-$(CONFIG_SUPERH) += sh/
1898 obj-$(CONFIG_GENERIC_TIME) += clocksource/
1899 obj-$(CONFIG_DMA_ENGINE) += dma/
1900+obj-$(CONFIG_SSB) += ssb/
1901diff -Nru linux-2.6.19.ori/drivers/mtd/chips/cfi_cmdset_0002.c linux-2.6.19/drivers/mtd/chips/cfi_cmdset_0002.c
1902--- linux-2.6.19.ori/drivers/mtd/chips/cfi_cmdset_0002.c 2006-12-02 18:55:38.000000000 +0100
1903+++ linux-2.6.19/drivers/mtd/chips/cfi_cmdset_0002.c 2006-12-03 00:06:13.000000000 +0100
1904@@ -296,9 +296,6 @@
1905 printk(KERN_ERR " Unknown Amd/Fujitsu Extended Query "
1906 "version %c.%c.\n", extp->MajorVersion,
1907 extp->MinorVersion);
1908- kfree(extp);
1909- kfree(mtd);
1910- return NULL;
1911 }
1912
1913 /* Install our own private info structure */
1914diff -Nru linux-2.6.19.ori/drivers/mtd/maps/Kconfig linux-2.6.19/drivers/mtd/maps/Kconfig
1915--- linux-2.6.19.ori/drivers/mtd/maps/Kconfig 2006-12-02 18:55:38.000000000 +0100
1916+++ linux-2.6.19/drivers/mtd/maps/Kconfig 2006-12-02 19:14:34.000000000 +0100
1917@@ -299,6 +299,12 @@
1918 Mapping for the Flaga digital module. If you don't have one, ignore
1919 this setting.
1920
1921+config MTD_BCM47XX
1922+ tristate "BCM47xx flash device"
1923+ depends on MIPS && MTD_CFI && BCM947XX
1924+ help
1925+ Support for the flash chips on the BCM947xx board.
1926+
1927 config MTD_BEECH
1928 tristate "CFI Flash device mapped on IBM 405LP Beech"
1929 depends on MTD_CFI && BEECH
1930diff -Nru linux-2.6.19.ori/drivers/mtd/maps/Makefile linux-2.6.19/drivers/mtd/maps/Makefile
1931--- linux-2.6.19.ori/drivers/mtd/maps/Makefile 2006-12-02 18:55:38.000000000 +0100
1932+++ linux-2.6.19/drivers/mtd/maps/Makefile 2006-12-02 19:14:34.000000000 +0100
1933@@ -29,6 +29,7 @@
1934 obj-$(CONFIG_MTD_PCMCIA) += pcmciamtd.o
1935 obj-$(CONFIG_MTD_RPXLITE) += rpxlite.o
1936 obj-$(CONFIG_MTD_TQM8XXL) += tqm8xxl.o
1937+obj-$(CONFIG_MTD_BCM47XX) += bcm47xx-flash.o
1938 obj-$(CONFIG_MTD_SA1100) += sa1100-flash.o
1939 obj-$(CONFIG_MTD_IPAQ) += ipaq-flash.o
1940 obj-$(CONFIG_MTD_SBC_GXX) += sbc_gxx.o
1941diff -Nru linux-2.6.19.ori/drivers/mtd/maps/bcm47xx-flash.c linux-2.6.19/drivers/mtd/maps/bcm47xx-flash.c
1942--- linux-2.6.19.ori/drivers/mtd/maps/bcm47xx-flash.c 1970-01-01 01:00:00.000000000 +0100
1943+++ linux-2.6.19/drivers/mtd/maps/bcm47xx-flash.c 2006-12-02 21:04:34.000000000 +0100
1944@@ -0,0 +1,471 @@
1945+/*
1946+ * Copyright (C) 2006 Felix Fietkau <nbd@openwrt.org>
1947+ * Copyright (C) 2005 Waldemar Brodkorb <wbx@openwrt.org>
1948+ * Copyright (C) 2004 Florian Schirmer (jolt@tuxbox.org)
1949+ *
1950+ * original functions for finding root filesystem from Mike Baker
1951+ *
1952+ * This program is free software; you can redistribute it and/or modify it
1953+ * under the terms of the GNU General Public License as published by the
1954+ * Free Software Foundation; either version 2 of the License, or (at your
1955+ * option) any later version.
1956+ *
1957+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
1958+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
1959+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
1960+ * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
1961+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
1962+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
1963+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
1964+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
1965+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
1966+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
1967+ *
1968+ * You should have received a copy of the GNU General Public License along
1969+ * with this program; if not, write to the Free Software Foundation, Inc.,
1970+ * 675 Mass Ave, Cambridge, MA 02139, USA.
1971+ *
1972+ * Copyright 2001-2003, Broadcom Corporation
1973+ * All Rights Reserved.
1974+ *
1975+ * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY
1976+ * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM
1977+ * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS
1978+ * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE.
1979+ *
1980+ * Flash mapping for BCM947XX boards
1981+ */
1982+
1983+#include <linux/init.h>
1984+#include <linux/module.h>
1985+#include <linux/types.h>
1986+#include <linux/kernel.h>
1987+#include <linux/wait.h>
1988+#include <linux/mtd/mtd.h>
1989+#include <linux/mtd/map.h>
1990+#ifdef CONFIG_MTD_PARTITIONS
1991+#include <linux/mtd/partitions.h>
1992+#endif
1993+#include <linux/squashfs_fs.h>
1994+#include <linux/jffs2.h>
1995+#include <linux/crc32.h>
1996+#include <linux/ssb.h>
1997+#include <asm/io.h>
1998+
1999+
2000+#define TRX_MAGIC 0x30524448 /* "HDR0" */
2001+#define TRX_VERSION 1
2002+#define TRX_MAX_LEN 0x3A0000
2003+#define TRX_NO_HEADER 1 /* Do not write TRX header */
2004+#define TRX_GZ_FILES 0x2 /* Contains up to TRX_MAX_OFFSET individual gzip files */
2005+#define TRX_MAX_OFFSET 3
2006+
2007+struct trx_header {
2008+ u32 magic; /* "HDR0" */
2009+ u32 len; /* Length of file including header */
2010+ u32 crc32; /* 32-bit CRC from flag_version to end of file */
2011+ u32 flag_version; /* 0:15 flags, 16:31 version */
2012+ u32 offsets[TRX_MAX_OFFSET]; /* Offsets of partitions from start of header */
2013+};
2014+
2015+#define ROUNDUP(x, y) ((((x)+((y)-1))/(y))*(y))
2016+#define NVRAM_SPACE 0x8000
2017+#define WINDOW_ADDR 0x1fc00000
2018+#define WINDOW_SIZE 0x400000
2019+#define BUSWIDTH 2
2020+
2021+extern struct ssb_bus ssb;
2022+static struct mtd_info *bcm947xx_mtd;
2023+
2024+static void bcm947xx_map_copy_from(struct map_info *map, void *to, unsigned long from, ssize_t len)
2025+{
2026+#define MIPS_MEMCPY_ALIGN 4
2027+ map_word ret;
2028+ ssize_t transfer;
2029+ ssize_t done = 0;
2030+ if ((len >= MIPS_MEMCPY_ALIGN) && (!(from & (MIPS_MEMCPY_ALIGN - 1))) && (!(((unsigned int)to & (MIPS_MEMCPY_ALIGN - 1))))) {
2031+ done = len & ~(MIPS_MEMCPY_ALIGN - 1);
2032+ memcpy_fromio(to, map->virt + from, done);
2033+ }
2034+ while (done < len) {
2035+ ret = map->read(map, from + done);
2036+ transfer = len - done;
2037+ if (transfer > map->bankwidth)
2038+ transfer = map->bankwidth;
2039+ memcpy((void *)((unsigned long)to + done), &ret.x[0], transfer);
2040+ done += transfer;
2041+ }
2042+}
2043+
2044+static struct map_info bcm947xx_map = {
2045+ name: "Physically mapped flash",
2046+ size: WINDOW_SIZE,
2047+ bankwidth: BUSWIDTH,
2048+ phys: WINDOW_ADDR,
2049+};
2050+
2051+#ifdef CONFIG_MTD_PARTITIONS
2052+
2053+static struct mtd_partition bcm947xx_parts[] = {
2054+ { name: "cfe", offset: 0, size: 0, mask_flags: MTD_WRITEABLE, },
2055+ { name: "linux", offset: 0, size: 0, },
2056+ { name: "rootfs", offset: 0, size: 0, },
2057+ { name: "nvram", offset: 0, size: 0, },
2058+ { name: "OpenWrt", offset: 0, size: 0, },
2059+ { name: NULL, },
2060+};
2061+
2062+static int __init
2063+find_cfe_size(struct mtd_info *mtd, size_t size)
2064+{
2065+ struct trx_header *trx;
2066+ unsigned char buf[512];
2067+ int off;
2068+ size_t len;
2069+ int blocksize;
2070+
2071+ trx = (struct trx_header *) buf;
2072+
2073+ blocksize = mtd->erasesize;
2074+ if (blocksize < 0x10000)
2075+ blocksize = 0x10000;
2076+
2077+ for (off = (128*1024); off < size; off += blocksize) {
2078+ memset(buf, 0xe5, sizeof(buf));
2079+
2080+ /*
2081+ * Read into buffer
2082+ */
2083+ if (mtd->read(mtd, off, sizeof(buf), &len, buf) ||
2084+ len != sizeof(buf))
2085+ continue;
2086+
2087+ /* found a TRX header */
2088+ if (le32_to_cpu(trx->magic) == TRX_MAGIC) {
2089+ goto found;
2090+ }
2091+ }
2092+
2093+ printk(KERN_NOTICE
2094+ "%s: Couldn't find bootloader size\n",
2095+ mtd->name);
2096+ return -1;
2097+
2098+ found:
2099+ printk(KERN_NOTICE "bootloader size: %d\n", off);
2100+ return off;
2101+
2102+}
2103+
2104+/*
2105+ * Copied from mtdblock.c
2106+ *
2107+ * Cache stuff...
2108+ *
2109+ * Since typical flash erasable sectors are much larger than what Linux's
2110+ * buffer cache can handle, we must implement read-modify-write on flash
2111+ * sectors for each block write requests. To avoid over-erasing flash sectors
2112+ * and to speed things up, we locally cache a whole flash sector while it is
2113+ * being written to until a different sector is required.
2114+ */
2115+
2116+static void erase_callback(struct erase_info *done)
2117+{
2118+ wait_queue_head_t *wait_q = (wait_queue_head_t *)done->priv;
2119+ wake_up(wait_q);
2120+}
2121+
2122+static int erase_write (struct mtd_info *mtd, unsigned long pos,
2123+ int len, const char *buf)
2124+{
2125+ struct erase_info erase;
2126+ DECLARE_WAITQUEUE(wait, current);
2127+ wait_queue_head_t wait_q;
2128+ size_t retlen;
2129+ int ret;
2130+
2131+ /*
2132+ * First, let's erase the flash block.
2133+ */
2134+
2135+ init_waitqueue_head(&wait_q);
2136+ erase.mtd = mtd;
2137+ erase.callback = erase_callback;
2138+ erase.addr = pos;
2139+ erase.len = len;
2140+ erase.priv = (u_long)&wait_q;
2141+
2142+ set_current_state(TASK_INTERRUPTIBLE);
2143+ add_wait_queue(&wait_q, &wait);
2144+
2145+ ret = mtd->erase(mtd, &erase);
2146+ if (ret) {
2147+ set_current_state(TASK_RUNNING);
2148+ remove_wait_queue(&wait_q, &wait);
2149+ printk (KERN_WARNING "erase of region [0x%lx, 0x%x] "
2150+ "on \"%s\" failed\n",
2151+ pos, len, mtd->name);
2152+ return ret;
2153+ }
2154+
2155+ schedule(); /* Wait for erase to finish. */
2156+ remove_wait_queue(&wait_q, &wait);
2157+
2158+ /*
2159+ * Next, writhe data to flash.
2160+ */
2161+
2162+ ret = mtd->write (mtd, pos, len, &retlen, buf);
2163+ if (ret)
2164+ return ret;
2165+ if (retlen != len)
2166+ return -EIO;
2167+ return 0;
2168+}
2169+
2170+
2171+
2172+
2173+static int __init
2174+find_root(struct mtd_info *mtd, size_t size, struct mtd_partition *part)
2175+{
2176+ struct trx_header trx, *trx2;
2177+ unsigned char buf[512], *block;
2178+ int off, blocksize;
2179+ u32 i, crc = ~0;
2180+ size_t len;
2181+ struct squashfs_super_block *sb = (struct squashfs_super_block *) buf;
2182+
2183+ blocksize = mtd->erasesize;
2184+ if (blocksize < 0x10000)
2185+ blocksize = 0x10000;
2186+
2187+ for (off = (128*1024); off < size; off += blocksize) {
2188+ memset(&trx, 0xe5, sizeof(trx));
2189+
2190+ /*
2191+ * Read into buffer
2192+ */
2193+ if (mtd->read(mtd, off, sizeof(trx), &len, (char *) &trx) ||
2194+ len != sizeof(trx))
2195+ continue;
2196+
2197+ /* found a TRX header */
2198+ if (le32_to_cpu(trx.magic) == TRX_MAGIC) {
2199+ part->offset = le32_to_cpu(trx.offsets[2]) ? :
2200+ le32_to_cpu(trx.offsets[1]);
2201+ part->size = le32_to_cpu(trx.len);
2202+
2203+ part->size -= part->offset;
2204+ part->offset += off;
2205+
2206+ goto found;
2207+ }
2208+ }
2209+
2210+ printk(KERN_NOTICE
2211+ "%s: Couldn't find root filesystem\n",
2212+ mtd->name);
2213+ return -1;
2214+
2215+ found:
2216+ if (part->size == 0)
2217+ return 0;
2218+
2219+ if (mtd->read(mtd, part->offset, sizeof(buf), &len, buf) || len != sizeof(buf))
2220+ return 0;
2221+
2222+ if (*((__u32 *) buf) == SQUASHFS_MAGIC) {
2223+ printk(KERN_INFO "%s: Filesystem type: squashfs, size=0x%x\n", mtd->name, (u32) sb->bytes_used);
2224+
2225+ /* Update the squashfs partition size based on the superblock info */
2226+ part->size = sb->bytes_used;
2227+ len = part->offset + part->size;
2228+ len += (mtd->erasesize - 1);
2229+ len &= ~(mtd->erasesize - 1);
2230+ part->size = len - part->offset;
2231+ } else if (*((__u16 *) buf) == JFFS2_MAGIC_BITMASK) {
2232+ printk(KERN_INFO "%s: Filesystem type: jffs2\n", mtd->name);
2233+
2234+ /* Move the squashfs outside of the trx */
2235+ part->size = 0;
2236+ } else {
2237+ printk(KERN_INFO "%s: Filesystem type: unknown\n", mtd->name);
2238+ return 0;
2239+ }
2240+
2241+ if (trx.len != part->offset + part->size - off) {
2242+ /* Update the trx offsets and length */
2243+ trx.len = part->offset + part->size - off;
2244+
2245+ /* Update the trx crc32 */
2246+ for (i = (u32) &(((struct trx_header *)NULL)->flag_version); i <= trx.len; i += sizeof(buf)) {
2247+ if (mtd->read(mtd, off + i, sizeof(buf), &len, buf) || len != sizeof(buf))
2248+ return 0;
2249+ crc = crc32_le(crc, buf, min(sizeof(buf), trx.len - i));
2250+ }
2251+ trx.crc32 = crc;
2252+
2253+ /* read first eraseblock from the trx */
2254+ block = kmalloc(mtd->erasesize, GFP_KERNEL);
2255+ trx2 = (struct trx_header *) block;
2256+ if (mtd->read(mtd, off, mtd->erasesize, &len, block) || len != mtd->erasesize) {
2257+ printk("Error accessing the first trx eraseblock\n");
2258+ return 0;
2259+ }
2260+
2261+ printk("Updating TRX offsets and length:\n");
2262+ printk("old trx = [0x%08x, 0x%08x, 0x%08x], len=0x%08x crc32=0x%08x\n", trx2->offsets[0], trx2->offsets[1], trx2->offsets[2], trx2->len, trx2->crc32);
2263+ printk("new trx = [0x%08x, 0x%08x, 0x%08x], len=0x%08x crc32=0x%08x\n", trx.offsets[0], trx.offsets[1], trx.offsets[2], trx.len, trx.crc32);
2264+
2265+ /* Write updated trx header to the flash */
2266+ memcpy(block, &trx, sizeof(trx));
2267+ if (mtd->unlock)
2268+ mtd->unlock(mtd, off, mtd->erasesize);
2269+ erase_write(mtd, off, mtd->erasesize, block);
2270+ if (mtd->sync)
2271+ mtd->sync(mtd);
2272+ kfree(block);
2273+ printk("Done\n");
2274+ }
2275+
2276+ return part->size;
2277+}
2278+
2279+struct mtd_partition * __init
2280+init_mtd_partitions(struct mtd_info *mtd, size_t size)
2281+{
2282+ int cfe_size;
2283+
2284+ if ((cfe_size = find_cfe_size(mtd,size)) < 0)
2285+ return NULL;
2286+
2287+ /* boot loader */
2288+ bcm947xx_parts[0].offset = 0;
2289+ bcm947xx_parts[0].size = cfe_size;
2290+
2291+ /* nvram */
2292+ if (cfe_size != 384 * 1024) {
2293+ bcm947xx_parts[3].offset = size - ROUNDUP(NVRAM_SPACE, mtd->erasesize);
2294+ bcm947xx_parts[3].size = ROUNDUP(NVRAM_SPACE, mtd->erasesize);
2295+ } else {
2296+ /* nvram (old 128kb config partition on netgear wgt634u) */
2297+ bcm947xx_parts[3].offset = bcm947xx_parts[0].size;
2298+ bcm947xx_parts[3].size = ROUNDUP(NVRAM_SPACE, mtd->erasesize);
2299+ }
2300+
2301+ /* linux (kernel and rootfs) */
2302+ if (cfe_size != 384 * 1024) {
2303+ bcm947xx_parts[1].offset = bcm947xx_parts[0].size;
2304+ bcm947xx_parts[1].size = bcm947xx_parts[3].offset -
2305+ bcm947xx_parts[1].offset;
2306+ } else {
2307+ /* do not count the elf loader, which is on one block */
2308+ bcm947xx_parts[1].offset = bcm947xx_parts[0].size +
2309+ bcm947xx_parts[3].size + mtd->erasesize;
2310+ bcm947xx_parts[1].size = size -
2311+ bcm947xx_parts[0].size -
2312+ (2*bcm947xx_parts[3].size) -
2313+ mtd->erasesize;
2314+ }
2315+
2316+ /* find and size rootfs */
2317+ if (find_root(mtd,size,&bcm947xx_parts[2])==0) {
2318+ /* entirely jffs2 */
2319+ bcm947xx_parts[4].name = NULL;
2320+ bcm947xx_parts[2].size = size - bcm947xx_parts[2].offset -
2321+ bcm947xx_parts[3].size;
2322+ } else {
2323+ /* legacy setup */
2324+ /* calculate leftover flash, and assign it to the jffs2 partition */
2325+ if (cfe_size != 384 * 1024) {
2326+ bcm947xx_parts[4].offset = bcm947xx_parts[2].offset +
2327+ bcm947xx_parts[2].size;
2328+ if ((bcm947xx_parts[4].offset % mtd->erasesize) > 0) {
2329+ bcm947xx_parts[4].offset += mtd->erasesize -
2330+ (bcm947xx_parts[4].offset % mtd->erasesize);
2331+ }
2332+ bcm947xx_parts[4].size = bcm947xx_parts[3].offset -
2333+ bcm947xx_parts[4].offset;
2334+ } else {
2335+ bcm947xx_parts[4].offset = bcm947xx_parts[2].offset +
2336+ bcm947xx_parts[2].size;
2337+ if ((bcm947xx_parts[4].offset % mtd->erasesize) > 0) {
2338+ bcm947xx_parts[4].offset += mtd->erasesize -
2339+ (bcm947xx_parts[4].offset % mtd->erasesize);
2340+ }
2341+ bcm947xx_parts[4].size = size - bcm947xx_parts[3].size -
2342+ bcm947xx_parts[4].offset;
2343+ }
2344+ }
2345+
2346+ return bcm947xx_parts;
2347+}
2348+#endif
2349+
2350+int __init init_bcm947xx_map(void)
2351+{
2352+ struct ssb_mipscore *mcore = &ssb.mipscore;
2353+ size_t size;
2354+ int ret = 0;
2355+#ifdef CONFIG_MTD_PARTITIONS
2356+ struct mtd_partition *parts;
2357+ int i;
2358+#endif
2359+ u32 window = mcore->flash_window;
2360+ u32 window_size = mcore->flash_window_size;
2361+
2362+ printk("flash init: 0x%08x 0x%08x\n", window, window_size);
2363+ bcm947xx_map.virt = ioremap(window, window_size);
2364+
2365+ if (!bcm947xx_map.virt) {
2366+ printk("Failed to ioremap\n");
2367+ return -EIO;
2368+ }
2369+ simple_map_init(&bcm947xx_map);
2370+
2371+ bcm947xx_map.copy_from = bcm947xx_map_copy_from;
2372+
2373+ if (!(bcm947xx_mtd = do_map_probe("cfi_probe", &bcm947xx_map))) {
2374+ printk("Failed to do_map_probe\n");
2375+ iounmap((void *)bcm947xx_map.virt);
2376+ return -ENXIO;
2377+ }
2378+
2379+ bcm947xx_mtd->owner = THIS_MODULE;
2380+
2381+ size = bcm947xx_mtd->size;
2382+
2383+ printk(KERN_NOTICE "Flash device: 0x%x at 0x%x\n", size, WINDOW_ADDR);
2384+
2385+#ifdef CONFIG_MTD_PARTITIONS
2386+ parts = init_mtd_partitions(bcm947xx_mtd, size);
2387+ for (i = 0; parts[i].name; i++);
2388+ ret = add_mtd_partitions(bcm947xx_mtd, parts, i);
2389+ if (ret) {
2390+ printk(KERN_ERR "Flash: add_mtd_partitions failed\n");
2391+ goto fail;
2392+ }
2393+#endif
2394+ return 0;
2395+
2396+ fail:
2397+ if (bcm947xx_mtd)
2398+ map_destroy(bcm947xx_mtd);
2399+ if (bcm947xx_map.virt)
2400+ iounmap((void *)bcm947xx_map.virt);
2401+ bcm947xx_map.virt = 0;
2402+ return ret;
2403+}
2404+
2405+void __exit cleanup_bcm947xx_map(void)
2406+{
2407+#ifdef CONFIG_MTD_PARTITIONS
2408+ del_mtd_partitions(bcm947xx_mtd);
2409+#endif
2410+ map_destroy(bcm947xx_mtd);
2411+ iounmap((void *)bcm947xx_map.virt);
2412+}
2413+
2414+module_init(init_bcm947xx_map);
2415+module_exit(cleanup_bcm947xx_map);
2416diff -Nru linux-2.6.19.ori/drivers/net/Kconfig linux-2.6.19/drivers/net/Kconfig
2417--- linux-2.6.19.ori/drivers/net/Kconfig 2006-12-02 18:55:38.000000000 +0100
2418+++ linux-2.6.19/drivers/net/Kconfig 2006-12-02 19:15:41.000000000 +0100
2419@@ -1394,7 +1394,7 @@
2420
2421 config B44
2422 tristate "Broadcom 4400 ethernet support"
2423- depends on NET_PCI && PCI
2424+ depends on SSB && EXPERIMENTAL
2425 select MII
2426 help
2427 If you have a network (Ethernet) controller of this type, say Y and
2428diff -Nru linux-2.6.19.ori/drivers/net/b44.c linux-2.6.19/drivers/net/b44.c
2429--- linux-2.6.19.ori/drivers/net/b44.c 2006-12-02 18:55:38.000000000 +0100
2430+++ linux-2.6.19/drivers/net/b44.c 2006-12-02 21:21:11.000000000 +0100
2431@@ -1,7 +1,9 @@
2432-/* b44.c: Broadcom 4400 device driver.
2433+/* b44.c: Broadcom 4400/47xx device driver.
2434 *
2435 * Copyright (C) 2002 David S. Miller (davem@redhat.com)
2436- * Fixed by Pekka Pietikainen (pp@ee.oulu.fi)
2437+ * Copyright (C) 2004 Pekka Pietikainen (pp@ee.oulu.fi)
2438+ * Copyright (C) 2004 Florian Schirmer (jolt@tuxbox.org)
2439+ * Copyright (C) 2006 Felix Fietkau (nbd@openwrt.org)
2440 * Copyright (C) 2006 Broadcom Corporation.
2441 *
2442 * Distribute under GPL.
2443@@ -20,11 +22,13 @@
2444 #include <linux/delay.h>
2445 #include <linux/init.h>
2446 #include <linux/dma-mapping.h>
2447+#include <linux/ssb.h>
2448
2449 #include <asm/uaccess.h>
2450 #include <asm/io.h>
2451 #include <asm/irq.h>
2452
2453+
2454 #include "b44.h"
2455
2456 #define DRV_MODULE_NAME "b44"
2457@@ -87,8 +91,8 @@
2458 static char version[] __devinitdata =
2459 DRV_MODULE_NAME ".c:v" DRV_MODULE_VERSION " (" DRV_MODULE_RELDATE ")\n";
2460
2461-MODULE_AUTHOR("Florian Schirmer, Pekka Pietikainen, David S. Miller");
2462-MODULE_DESCRIPTION("Broadcom 4400 10/100 PCI ethernet driver");
2463+MODULE_AUTHOR("Felix Fietkau, Florian Schirmer, Pekka Pietikainen, David S. Miller");
2464+MODULE_DESCRIPTION("Broadcom 4400/47xx 10/100 PCI ethernet driver");
2465 MODULE_LICENSE("GPL");
2466 MODULE_VERSION(DRV_MODULE_VERSION);
2467
2468@@ -96,24 +100,18 @@
2469 module_param(b44_debug, int, 0);
2470 MODULE_PARM_DESC(b44_debug, "B44 bitmapped debugging message enable value");
2471
2472-static struct pci_device_id b44_pci_tbl[] = {
2473- { PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_BCM4401,
2474- PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0UL },
2475- { PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_BCM4401B0,
2476- PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0UL },
2477- { PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_BCM4401B1,
2478- PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0UL },
2479- { } /* terminate list with empty entry */
2480+static struct ssb_device_id b44_ssb_tbl[] = {
2481+ SSB_DEVICE(SSB_VENDOR_BROADCOM, SSB_DEV_ETHERNET, SSB_ANY_REV),
2482+ SSB_DEVTABLE_END
2483 };
2484
2485-MODULE_DEVICE_TABLE(pci, b44_pci_tbl);
2486-
2487 static void b44_halt(struct b44 *);
2488 static void b44_init_rings(struct b44 *);
2489 static void b44_init_hw(struct b44 *, int);
2490
2491 static int dma_desc_align_mask;
2492 static int dma_desc_sync_size;
2493+static int instance;
2494
2495 static const char b44_gstrings[][ETH_GSTRING_LEN] = {
2496 #define _B44(x...) # x,
2497@@ -121,35 +119,24 @@
2498 #undef _B44
2499 };
2500
2501-static inline void b44_sync_dma_desc_for_device(struct pci_dev *pdev,
2502- dma_addr_t dma_base,
2503- unsigned long offset,
2504- enum dma_data_direction dir)
2505-{
2506- dma_sync_single_range_for_device(&pdev->dev, dma_base,
2507- offset & dma_desc_align_mask,
2508- dma_desc_sync_size, dir);
2509-}
2510-
2511-static inline void b44_sync_dma_desc_for_cpu(struct pci_dev *pdev,
2512- dma_addr_t dma_base,
2513- unsigned long offset,
2514- enum dma_data_direction dir)
2515-{
2516- dma_sync_single_range_for_cpu(&pdev->dev, dma_base,
2517- offset & dma_desc_align_mask,
2518- dma_desc_sync_size, dir);
2519-}
2520-
2521-static inline unsigned long br32(const struct b44 *bp, unsigned long reg)
2522-{
2523- return readl(bp->regs + reg);
2524-}
2525-
2526-static inline void bw32(const struct b44 *bp,
2527- unsigned long reg, unsigned long val)
2528-{
2529- writel(val, bp->regs + reg);
2530+static inline void b44_sync_dma_desc_for_device(struct ssb_device *sdev,
2531+ dma_addr_t dma_base,
2532+ unsigned long offset,
2533+ enum dma_data_direction dir)
2534+{
2535+ dma_sync_single_range_for_device(&sdev->dev, dma_base,
2536+ offset & dma_desc_align_mask,
2537+ dma_desc_sync_size, dir);
2538+}
2539+
2540+static inline void b44_sync_dma_desc_for_cpu(struct ssb_device *sdev,
2541+ dma_addr_t dma_base,
2542+ unsigned long offset,
2543+ enum dma_data_direction dir)
2544+{
2545+ dma_sync_single_range_for_cpu(&sdev->dev, dma_base,
2546+ offset & dma_desc_align_mask,
2547+ dma_desc_sync_size, dir);
2548 }
2549
2550 static int b44_wait_bit(struct b44 *bp, unsigned long reg,
2551@@ -177,117 +164,29 @@
2552 return 0;
2553 }
2554
2555-/* Sonics SiliconBackplane support routines. ROFL, you should see all the
2556- * buzz words used on this company's website :-)
2557- *
2558- * All of these routines must be invoked with bp->lock held and
2559- * interrupts disabled.
2560- */
2561-
2562-#define SB_PCI_DMA 0x40000000 /* Client Mode PCI memory access space (1 GB) */
2563-#define BCM4400_PCI_CORE_ADDR 0x18002000 /* Address of PCI core on BCM4400 cards */
2564-
2565-static u32 ssb_get_core_rev(struct b44 *bp)
2566-{
2567- return (br32(bp, B44_SBIDHIGH) & SBIDHIGH_RC_MASK);
2568-}
2569-
2570-static u32 ssb_pci_setup(struct b44 *bp, u32 cores)
2571-{
2572- u32 bar_orig, pci_rev, val;
2573-
2574- pci_read_config_dword(bp->pdev, SSB_BAR0_WIN, &bar_orig);
2575- pci_write_config_dword(bp->pdev, SSB_BAR0_WIN, BCM4400_PCI_CORE_ADDR);
2576- pci_rev = ssb_get_core_rev(bp);
2577-
2578- val = br32(bp, B44_SBINTVEC);
2579- val |= cores;
2580- bw32(bp, B44_SBINTVEC, val);
2581-
2582- val = br32(bp, SSB_PCI_TRANS_2);
2583- val |= SSB_PCI_PREF | SSB_PCI_BURST;
2584- bw32(bp, SSB_PCI_TRANS_2, val);
2585-
2586- pci_write_config_dword(bp->pdev, SSB_BAR0_WIN, bar_orig);
2587-
2588- return pci_rev;
2589-}
2590-
2591-static void ssb_core_disable(struct b44 *bp)
2592-{
2593- if (br32(bp, B44_SBTMSLOW) & SBTMSLOW_RESET)
2594- return;
2595-
2596- bw32(bp, B44_SBTMSLOW, (SBTMSLOW_REJECT | SBTMSLOW_CLOCK));
2597- b44_wait_bit(bp, B44_SBTMSLOW, SBTMSLOW_REJECT, 100000, 0);
2598- b44_wait_bit(bp, B44_SBTMSHIGH, SBTMSHIGH_BUSY, 100000, 1);
2599- bw32(bp, B44_SBTMSLOW, (SBTMSLOW_FGC | SBTMSLOW_CLOCK |
2600- SBTMSLOW_REJECT | SBTMSLOW_RESET));
2601- br32(bp, B44_SBTMSLOW);
2602- udelay(1);
2603- bw32(bp, B44_SBTMSLOW, (SBTMSLOW_REJECT | SBTMSLOW_RESET));
2604- br32(bp, B44_SBTMSLOW);
2605- udelay(1);
2606-}
2607-
2608-static void ssb_core_reset(struct b44 *bp)
2609+static inline void __b44_cam_read(struct b44 *bp, unsigned char *data, int index)
2610 {
2611 u32 val;
2612
2613- ssb_core_disable(bp);
2614- bw32(bp, B44_SBTMSLOW, (SBTMSLOW_RESET | SBTMSLOW_CLOCK | SBTMSLOW_FGC));
2615- br32(bp, B44_SBTMSLOW);
2616- udelay(1);
2617-
2618- /* Clear SERR if set, this is a hw bug workaround. */
2619- if (br32(bp, B44_SBTMSHIGH) & SBTMSHIGH_SERR)
2620- bw32(bp, B44_SBTMSHIGH, 0);
2621-
2622- val = br32(bp, B44_SBIMSTATE);
2623- if (val & (SBIMSTATE_IBE | SBIMSTATE_TO))
2624- bw32(bp, B44_SBIMSTATE, val & ~(SBIMSTATE_IBE | SBIMSTATE_TO));
2625-
2626- bw32(bp, B44_SBTMSLOW, (SBTMSLOW_CLOCK | SBTMSLOW_FGC));
2627- br32(bp, B44_SBTMSLOW);
2628- udelay(1);
2629-
2630- bw32(bp, B44_SBTMSLOW, (SBTMSLOW_CLOCK));
2631- br32(bp, B44_SBTMSLOW);
2632- udelay(1);
2633-}
2634+ bw32(bp, B44_CAM_CTRL, (CAM_CTRL_READ |
2635+ (index << CAM_CTRL_INDEX_SHIFT)));
2636
2637-static int ssb_core_unit(struct b44 *bp)
2638-{
2639-#if 0
2640- u32 val = br32(bp, B44_SBADMATCH0);
2641- u32 base;
2642+ b44_wait_bit(bp, B44_CAM_CTRL, CAM_CTRL_BUSY, 100, 1);
2643
2644- type = val & SBADMATCH0_TYPE_MASK;
2645- switch (type) {
2646- case 0:
2647- base = val & SBADMATCH0_BS0_MASK;
2648- break;
2649+ val = br32(bp, B44_CAM_DATA_LO);
2650
2651- case 1:
2652- base = val & SBADMATCH0_BS1_MASK;
2653- break;
2654+ data[2] = (val >> 24) & 0xFF;
2655+ data[3] = (val >> 16) & 0xFF;
2656+ data[4] = (val >> 8) & 0xFF;
2657+ data[5] = (val >> 0) & 0xFF;
2658
2659- case 2:
2660- default:
2661- base = val & SBADMATCH0_BS2_MASK;
2662- break;
2663- };
2664-#endif
2665- return 0;
2666-}
2667+ val = br32(bp, B44_CAM_DATA_HI);
2668
2669-static int ssb_is_core_up(struct b44 *bp)
2670-{
2671- return ((br32(bp, B44_SBTMSLOW) & (SBTMSLOW_RESET | SBTMSLOW_REJECT | SBTMSLOW_CLOCK))
2672- == SBTMSLOW_CLOCK);
2673+ data[0] = (val >> 8) & 0xFF;
2674+ data[1] = (val >> 0) & 0xFF;
2675 }
2676
2677-static void __b44_cam_write(struct b44 *bp, unsigned char *data, int index)
2678+static inline void __b44_cam_write(struct b44 *bp, unsigned char *data, int index)
2679 {
2680 u32 val;
2681
2682@@ -323,14 +222,14 @@
2683 bw32(bp, B44_IMASK, bp->imask);
2684 }
2685
2686-static int b44_readphy(struct b44 *bp, int reg, u32 *val)
2687+static int __b44_readphy(struct b44 *bp, int phy_addr, int reg, u32 *val)
2688 {
2689 int err;
2690
2691 bw32(bp, B44_EMAC_ISTAT, EMAC_INT_MII);
2692 bw32(bp, B44_MDIO_DATA, (MDIO_DATA_SB_START |
2693 (MDIO_OP_READ << MDIO_DATA_OP_SHIFT) |
2694- (bp->phy_addr << MDIO_DATA_PMD_SHIFT) |
2695+ (phy_addr << MDIO_DATA_PMD_SHIFT) |
2696 (reg << MDIO_DATA_RA_SHIFT) |
2697 (MDIO_TA_VALID << MDIO_DATA_TA_SHIFT)));
2698 err = b44_wait_bit(bp, B44_EMAC_ISTAT, EMAC_INT_MII, 100, 0);
2699@@ -339,18 +238,34 @@
2700 return err;
2701 }
2702
2703-static int b44_writephy(struct b44 *bp, int reg, u32 val)
2704+static int __b44_writephy(struct b44 *bp, int phy_addr, int reg, u32 val)
2705 {
2706 bw32(bp, B44_EMAC_ISTAT, EMAC_INT_MII);
2707 bw32(bp, B44_MDIO_DATA, (MDIO_DATA_SB_START |
2708 (MDIO_OP_WRITE << MDIO_DATA_OP_SHIFT) |
2709- (bp->phy_addr << MDIO_DATA_PMD_SHIFT) |
2710+ (phy_addr << MDIO_DATA_PMD_SHIFT) |
2711 (reg << MDIO_DATA_RA_SHIFT) |
2712 (MDIO_TA_VALID << MDIO_DATA_TA_SHIFT) |
2713 (val & MDIO_DATA_DATA)));
2714 return b44_wait_bit(bp, B44_EMAC_ISTAT, EMAC_INT_MII, 100, 0);
2715 }
2716
2717+static inline int b44_readphy(struct b44 *bp, int reg, u32 *val)
2718+{
2719+ if (bp->phy_addr == B44_PHY_ADDR_NO_PHY)
2720+ return 0;
2721+
2722+ return __b44_readphy(bp, bp->phy_addr, reg, val);
2723+}
2724+
2725+static inline int b44_writephy(struct b44 *bp, int reg, u32 val)
2726+{
2727+ if (bp->phy_addr == B44_PHY_ADDR_NO_PHY)
2728+ return 0;
2729+
2730+ return __b44_writephy(bp, bp->phy_addr, reg, val);
2731+}
2732+
2733 /* miilib interface */
2734 /* FIXME FIXME: phy_id is ignored, bp->phy_addr use is unconditional
2735 * due to code existing before miilib use was added to this driver.
2736@@ -379,6 +294,8 @@
2737 u32 val;
2738 int err;
2739
2740+ if (bp->phy_addr == B44_PHY_ADDR_NO_PHY)
2741+ return 0;
2742 err = b44_writephy(bp, MII_BMCR, BMCR_RESET);
2743 if (err)
2744 return err;
2745@@ -437,11 +354,27 @@
2746 __b44_set_flow_ctrl(bp, pause_enab);
2747 }
2748
2749+
2750+extern char *nvram_get(char *name); //FIXME: move elsewhere
2751 static int b44_setup_phy(struct b44 *bp)
2752 {
2753 u32 val;
2754 int err;
2755
2756+ /*
2757+ * workaround for bad hardware design in Linksys WAP54G v1.0
2758+ * see https://dev.openwrt.org/ticket/146
2759+ * check and reset bit "isolate"
2760+ */
2761+ if ((atoi(nvram_get("boardnum")) == 2) &&
2762+ (__b44_readphy(bp, 0, MII_BMCR, &val) == 0) &&
2763+ (val & BMCR_ISOLATE) &&
2764+ (__b44_writephy(bp, 0, MII_BMCR, val & ~BMCR_ISOLATE) != 0)) {
2765+ printk(KERN_WARNING PFX "PHY: cannot reset MII transceiver isolate bit.\n");
2766+ }
2767+
2768+ if (bp->phy_addr == B44_PHY_ADDR_NO_PHY)
2769+ return 0;
2770 if ((err = b44_readphy(bp, B44_MII_ALEDCTRL, &val)) != 0)
2771 goto out;
2772 if ((err = b44_writephy(bp, B44_MII_ALEDCTRL,
2773@@ -537,6 +470,19 @@
2774 {
2775 u32 bmsr, aux;
2776
2777+ if (bp->phy_addr == B44_PHY_ADDR_NO_PHY) {
2778+ bp->flags |= B44_FLAG_100_BASE_T;
2779+ bp->flags |= B44_FLAG_FULL_DUPLEX;
2780+ if (!netif_carrier_ok(bp->dev)) {
2781+ u32 val = br32(bp, B44_TX_CTRL);
2782+ val |= TX_CTRL_DUPLEX;
2783+ bw32(bp, B44_TX_CTRL, val);
2784+ netif_carrier_on(bp->dev);
2785+ b44_link_report(bp);
2786+ }
2787+ return;
2788+ }
2789+
2790 if (!b44_readphy(bp, MII_BMSR, &bmsr) &&
2791 !b44_readphy(bp, B44_MII_AUXCTRL, &aux) &&
2792 (bmsr != 0xffff)) {
2793@@ -613,10 +559,10 @@
2794
2795 BUG_ON(skb == NULL);
2796
2797- pci_unmap_single(bp->pdev,
2798+ dma_unmap_single(&bp->sdev->dev,
2799 pci_unmap_addr(rp, mapping),
2800 skb->len,
2801- PCI_DMA_TODEVICE);
2802+ DMA_TO_DEVICE);
2803 rp->skb = NULL;
2804 dev_kfree_skb_irq(skb);
2805 }
2806@@ -652,10 +598,10 @@
2807 skb = dev_alloc_skb(RX_PKT_BUF_SZ);
2808 if (skb == NULL)
2809 return -ENOMEM;
2810-
2811- mapping = pci_map_single(bp->pdev, skb->data,
2812+
2813+ mapping = dma_map_single(&bp->sdev->dev, skb->data,
2814 RX_PKT_BUF_SZ,
2815- PCI_DMA_FROMDEVICE);
2816+ DMA_FROM_DEVICE);
2817
2818 /* Hardware bug work-around, the chip is unable to do PCI DMA
2819 to/from anything above 1GB :-( */
2820@@ -663,18 +609,18 @@
2821 mapping + RX_PKT_BUF_SZ > B44_DMA_MASK) {
2822 /* Sigh... */
2823 if (!dma_mapping_error(mapping))
2824- pci_unmap_single(bp->pdev, mapping, RX_PKT_BUF_SZ,PCI_DMA_FROMDEVICE);
2825+ dma_unmap_single(&bp->sdev->dev, mapping, RX_PKT_BUF_SZ,DMA_FROM_DEVICE);
2826 dev_kfree_skb_any(skb);
2827 skb = __dev_alloc_skb(RX_PKT_BUF_SZ,GFP_DMA);
2828 if (skb == NULL)
2829 return -ENOMEM;
2830- mapping = pci_map_single(bp->pdev, skb->data,
2831+ mapping = dma_map_single(&bp->sdev->dev, skb->data,
2832 RX_PKT_BUF_SZ,
2833- PCI_DMA_FROMDEVICE);
2834+ DMA_FROM_DEVICE);
2835 if (dma_mapping_error(mapping) ||
2836 mapping + RX_PKT_BUF_SZ > B44_DMA_MASK) {
2837 if (!dma_mapping_error(mapping))
2838- pci_unmap_single(bp->pdev, mapping, RX_PKT_BUF_SZ,PCI_DMA_FROMDEVICE);
2839+ dma_unmap_single(&bp->sdev->dev, mapping, RX_PKT_BUF_SZ,DMA_FROM_DEVICE);
2840 dev_kfree_skb_any(skb);
2841 return -ENOMEM;
2842 }
2843@@ -703,9 +649,9 @@
2844 dp->addr = cpu_to_le32((u32) mapping + bp->rx_offset + bp->dma_offset);
2845
2846 if (bp->flags & B44_FLAG_RX_RING_HACK)
2847- b44_sync_dma_desc_for_device(bp->pdev, bp->rx_ring_dma,
2848- dest_idx * sizeof(dp),
2849- DMA_BIDIRECTIONAL);
2850+ b44_sync_dma_desc_for_device(bp->sdev, bp->rx_ring_dma,
2851+ dest_idx * sizeof(dp),
2852+ DMA_BIDIRECTIONAL);
2853
2854 return RX_PKT_BUF_SZ;
2855 }
2856@@ -732,9 +678,9 @@
2857 pci_unmap_addr(src_map, mapping));
2858
2859 if (bp->flags & B44_FLAG_RX_RING_HACK)
2860- b44_sync_dma_desc_for_cpu(bp->pdev, bp->rx_ring_dma,
2861- src_idx * sizeof(src_desc),
2862- DMA_BIDIRECTIONAL);
2863+ b44_sync_dma_desc_for_cpu(bp->sdev, bp->rx_ring_dma,
2864+ src_idx * sizeof(src_desc),
2865+ DMA_BIDIRECTIONAL);
2866
2867 ctrl = src_desc->ctrl;
2868 if (dest_idx == (B44_RX_RING_SIZE - 1))
2869@@ -748,13 +694,13 @@
2870 src_map->skb = NULL;
2871
2872 if (bp->flags & B44_FLAG_RX_RING_HACK)
2873- b44_sync_dma_desc_for_device(bp->pdev, bp->rx_ring_dma,
2874- dest_idx * sizeof(dest_desc),
2875- DMA_BIDIRECTIONAL);
2876+ b44_sync_dma_desc_for_device(bp->sdev, bp->rx_ring_dma,
2877+ dest_idx * sizeof(dest_desc),
2878+ DMA_BIDIRECTIONAL);
2879
2880- pci_dma_sync_single_for_device(bp->pdev, src_desc->addr,
2881+ dma_sync_single_for_device(&bp->sdev->dev, src_desc->addr,
2882 RX_PKT_BUF_SZ,
2883- PCI_DMA_FROMDEVICE);
2884+ DMA_FROM_DEVICE);
2885 }
2886
2887 static int b44_rx(struct b44 *bp, int budget)
2888@@ -774,9 +720,9 @@
2889 struct rx_header *rh;
2890 u16 len;
2891
2892- pci_dma_sync_single_for_cpu(bp->pdev, map,
2893+ dma_sync_single_for_cpu(&bp->sdev->dev, map,
2894 RX_PKT_BUF_SZ,
2895- PCI_DMA_FROMDEVICE);
2896+ DMA_FROM_DEVICE);
2897 rh = (struct rx_header *) skb->data;
2898 len = cpu_to_le16(rh->len);
2899 if ((len > (RX_PKT_BUF_SZ - bp->rx_offset)) ||
2900@@ -808,11 +754,11 @@
2901 skb_size = b44_alloc_rx_skb(bp, cons, bp->rx_prod);
2902 if (skb_size < 0)
2903 goto drop_it;
2904- pci_unmap_single(bp->pdev, map,
2905- skb_size, PCI_DMA_FROMDEVICE);
2906+ dma_unmap_single(&bp->sdev->dev, map,
2907+ skb_size, DMA_FROM_DEVICE);
2908 /* Leave out rx_header */
2909- skb_put(skb, len+bp->rx_offset);
2910- skb_pull(skb,bp->rx_offset);
2911+ skb_put(skb, len+bp->rx_offset);
2912+ skb_pull(skb,bp->rx_offset);
2913 } else {
2914 struct sk_buff *copy_skb;
2915
2916@@ -980,23 +926,23 @@
2917 goto err_out;
2918 }
2919
2920- mapping = pci_map_single(bp->pdev, skb->data, len, PCI_DMA_TODEVICE);
2921+ mapping = dma_map_single(&bp->sdev->dev, skb->data, len, DMA_TO_DEVICE);
2922 if (dma_mapping_error(mapping) || mapping + len > B44_DMA_MASK) {
2923 /* Chip can't handle DMA to/from >1GB, use bounce buffer */
2924 if (!dma_mapping_error(mapping))
2925- pci_unmap_single(bp->pdev, mapping, len, PCI_DMA_TODEVICE);
2926+ dma_unmap_single(&bp->sdev->dev, mapping, len, DMA_TO_DEVICE);
2927
2928 bounce_skb = __dev_alloc_skb(TX_PKT_BUF_SZ,
2929 GFP_ATOMIC|GFP_DMA);
2930 if (!bounce_skb)
2931 goto err_out;
2932
2933- mapping = pci_map_single(bp->pdev, bounce_skb->data,
2934- len, PCI_DMA_TODEVICE);
2935+ mapping = dma_map_single(&bp->sdev->dev, bounce_skb->data,
2936+ len, DMA_TO_DEVICE);
2937 if (dma_mapping_error(mapping) || mapping + len > B44_DMA_MASK) {
2938 if (!dma_mapping_error(mapping))
2939- pci_unmap_single(bp->pdev, mapping,
2940- len, PCI_DMA_TODEVICE);
2941+ dma_unmap_single(&bp->sdev->dev, mapping,
2942+ len, DMA_TO_DEVICE);
2943 dev_kfree_skb_any(bounce_skb);
2944 goto err_out;
2945 }
2946@@ -1019,9 +965,9 @@
2947 bp->tx_ring[entry].addr = cpu_to_le32((u32) mapping+bp->dma_offset);
2948
2949 if (bp->flags & B44_FLAG_TX_RING_HACK)
2950- b44_sync_dma_desc_for_device(bp->pdev, bp->tx_ring_dma,
2951- entry * sizeof(bp->tx_ring[0]),
2952- DMA_TO_DEVICE);
2953+ b44_sync_dma_desc_for_device(bp->sdev, bp->tx_ring_dma,
2954+ entry * sizeof(bp->tx_ring[0]),
2955+ DMA_TO_DEVICE);
2956
2957 entry = NEXT_TX(entry);
2958
2959@@ -1094,10 +1040,10 @@
2960
2961 if (rp->skb == NULL)
2962 continue;
2963- pci_unmap_single(bp->pdev,
2964+ dma_unmap_single(&bp->sdev->dev,
2965 pci_unmap_addr(rp, mapping),
2966 RX_PKT_BUF_SZ,
2967- PCI_DMA_FROMDEVICE);
2968+ DMA_FROM_DEVICE);
2969 dev_kfree_skb_any(rp->skb);
2970 rp->skb = NULL;
2971 }
2972@@ -1108,10 +1054,10 @@
2973
2974 if (rp->skb == NULL)
2975 continue;
2976- pci_unmap_single(bp->pdev,
2977+ dma_unmap_single(&bp->sdev->dev,
2978 pci_unmap_addr(rp, mapping),
2979 rp->skb->len,
2980- PCI_DMA_TODEVICE);
2981+ DMA_TO_DEVICE);
2982 dev_kfree_skb_any(rp->skb);
2983 rp->skb = NULL;
2984 }
2985@@ -1133,14 +1079,14 @@
2986 memset(bp->tx_ring, 0, B44_TX_RING_BYTES);
2987
2988 if (bp->flags & B44_FLAG_RX_RING_HACK)
2989- dma_sync_single_for_device(&bp->pdev->dev, bp->rx_ring_dma,
2990- DMA_TABLE_BYTES,
2991- PCI_DMA_BIDIRECTIONAL);
2992+ dma_sync_single_for_device(&bp->sdev->dev, bp->rx_ring_dma,
2993+ DMA_TABLE_BYTES,
2994+ DMA_BIDIRECTIONAL);
2995
2996 if (bp->flags & B44_FLAG_TX_RING_HACK)
2997- dma_sync_single_for_device(&bp->pdev->dev, bp->tx_ring_dma,
2998- DMA_TABLE_BYTES,
2999- PCI_DMA_TODEVICE);
3000+ dma_sync_single_for_device(&bp->sdev->dev, bp->tx_ring_dma,
3001+ DMA_TABLE_BYTES,
3002+ DMA_TO_DEVICE);
3003
3004 for (i = 0; i < bp->rx_pending; i++) {
3005 if (b44_alloc_rx_skb(bp, -1, i) < 0)
3006@@ -1160,24 +1106,24 @@
3007 bp->tx_buffers = NULL;
3008 if (bp->rx_ring) {
3009 if (bp->flags & B44_FLAG_RX_RING_HACK) {
3010- dma_unmap_single(&bp->pdev->dev, bp->rx_ring_dma,
3011- DMA_TABLE_BYTES,
3012- DMA_BIDIRECTIONAL);
3013+ dma_unmap_single(&bp->sdev->dev, bp->rx_ring_dma,
3014+ DMA_TABLE_BYTES,
3015+ DMA_BIDIRECTIONAL);
3016 kfree(bp->rx_ring);
3017 } else
3018- pci_free_consistent(bp->pdev, DMA_TABLE_BYTES,
3019+ dma_free_coherent(&bp->sdev->dev, DMA_TABLE_BYTES,
3020 bp->rx_ring, bp->rx_ring_dma);
3021 bp->rx_ring = NULL;
3022 bp->flags &= ~B44_FLAG_RX_RING_HACK;
3023 }
3024 if (bp->tx_ring) {
3025 if (bp->flags & B44_FLAG_TX_RING_HACK) {
3026- dma_unmap_single(&bp->pdev->dev, bp->tx_ring_dma,
3027- DMA_TABLE_BYTES,
3028- DMA_TO_DEVICE);
3029+ dma_unmap_single(&bp->sdev->dev, bp->tx_ring_dma,
3030+ DMA_TABLE_BYTES,
3031+ DMA_TO_DEVICE);
3032 kfree(bp->tx_ring);
3033 } else
3034- pci_free_consistent(bp->pdev, DMA_TABLE_BYTES,
3035+ dma_free_coherent(&bp->sdev->dev, DMA_TABLE_BYTES,
3036 bp->tx_ring, bp->tx_ring_dma);
3037 bp->tx_ring = NULL;
3038 bp->flags &= ~B44_FLAG_TX_RING_HACK;
3039@@ -1203,7 +1149,7 @@
3040 goto out_err;
3041
3042 size = DMA_TABLE_BYTES;
3043- bp->rx_ring = pci_alloc_consistent(bp->pdev, size, &bp->rx_ring_dma);
3044+ bp->rx_ring = dma_alloc_coherent(&bp->sdev->dev, size, &bp->rx_ring_dma, GFP_ATOMIC);
3045 if (!bp->rx_ring) {
3046 /* Allocation may have failed due to pci_alloc_consistent
3047 insisting on use of GFP_DMA, which is more restrictive
3048@@ -1215,9 +1161,9 @@
3049 if (!rx_ring)
3050 goto out_err;
3051
3052- rx_ring_dma = dma_map_single(&bp->pdev->dev, rx_ring,
3053- DMA_TABLE_BYTES,
3054- DMA_BIDIRECTIONAL);
3055+ rx_ring_dma = dma_map_single(&bp->sdev->dev, rx_ring,
3056+ DMA_TABLE_BYTES,
3057+ DMA_BIDIRECTIONAL);
3058
3059 if (dma_mapping_error(rx_ring_dma) ||
3060 rx_ring_dma + size > B44_DMA_MASK) {
3061@@ -1230,9 +1176,9 @@
3062 bp->flags |= B44_FLAG_RX_RING_HACK;
3063 }
3064
3065- bp->tx_ring = pci_alloc_consistent(bp->pdev, size, &bp->tx_ring_dma);
3066+ bp->tx_ring = dma_alloc_coherent(&bp->sdev->dev, size, &bp->tx_ring_dma, GFP_ATOMIC);
3067 if (!bp->tx_ring) {
3068- /* Allocation may have failed due to pci_alloc_consistent
3069+ /* Allocation may have failed due to dma_alloc_coherent
3070 insisting on use of GFP_DMA, which is more restrictive
3071 than necessary... */
3072 struct dma_desc *tx_ring;
3073@@ -1242,9 +1188,9 @@
3074 if (!tx_ring)
3075 goto out_err;
3076
3077- tx_ring_dma = dma_map_single(&bp->pdev->dev, tx_ring,
3078- DMA_TABLE_BYTES,
3079- DMA_TO_DEVICE);
3080+ tx_ring_dma = dma_map_single(&bp->sdev->dev, tx_ring,
3081+ DMA_TABLE_BYTES,
3082+ DMA_TO_DEVICE);
3083
3084 if (dma_mapping_error(tx_ring_dma) ||
3085 tx_ring_dma + size > B44_DMA_MASK) {
3086@@ -1279,7 +1225,9 @@
3087 /* bp->lock is held. */
3088 static void b44_chip_reset(struct b44 *bp)
3089 {
3090- if (ssb_is_core_up(bp)) {
3091+ struct ssb_device *sdev = bp->sdev;
3092+
3093+ if (ssb_core_is_enabled(bp->sdev)) {
3094 bw32(bp, B44_RCV_LAZY, 0);
3095 bw32(bp, B44_ENET_CTRL, ENET_CTRL_DISABLE);
3096 b44_wait_bit(bp, B44_ENET_CTRL, ENET_CTRL_DISABLE, 100, 1);
3097@@ -1291,19 +1239,23 @@
3098 }
3099 bw32(bp, B44_DMARX_CTRL, 0);
3100 bp->rx_prod = bp->rx_cons = 0;
3101- } else {
3102- ssb_pci_setup(bp, (bp->core_unit == 0 ?
3103- SBINTVEC_ENET0 :
3104- SBINTVEC_ENET1));
3105 }
3106
3107- ssb_core_reset(bp);
3108-
3109+ ssb_core_enable(bp->sdev, 0);
3110 b44_clear_stats(bp);
3111
3112- /* Make PHY accessible. */
3113- bw32(bp, B44_MDIO_CTRL, (MDIO_CTRL_PREAMBLE |
3114+ switch (sdev->bus->bustype) {
3115+ case SSB_BUSTYPE_SSB:
3116+ bw32(bp, B44_MDIO_CTRL, (MDIO_CTRL_PREAMBLE |
3117+ (((ssb_clockspeed(sdev->bus) + (B44_MDC_RATIO / 2)) / B44_MDC_RATIO)
3118+ & MDIO_CTRL_MAXF_MASK)));
3119+ break;
3120+ case SSB_BUSTYPE_PCI:
3121+ bw32(bp, B44_MDIO_CTRL, (MDIO_CTRL_PREAMBLE |
3122 (0x0d & MDIO_CTRL_MAXF_MASK)));
3123+ break;
3124+ }
3125+
3126 br32(bp, B44_MDIO_CTRL);
3127
3128 if (!(br32(bp, B44_DEVCTRL) & DEVCTRL_IPP)) {
3129@@ -1346,6 +1298,7 @@
3130 {
3131 struct b44 *bp = netdev_priv(dev);
3132 struct sockaddr *addr = p;
3133+ u32 val;
3134
3135 if (netif_running(dev))
3136 return -EBUSY;
3137@@ -1356,7 +1309,11 @@
3138 memcpy(dev->dev_addr, addr->sa_data, dev->addr_len);
3139
3140 spin_lock_irq(&bp->lock);
3141- __b44_set_mac_addr(bp);
3142+
3143+ val = br32(bp, B44_RXCONFIG);
3144+ if (!(val & RXCONFIG_CAM_ABSENT))
3145+ __b44_set_mac_addr(bp);
3146+
3147 spin_unlock_irq(&bp->lock);
3148
3149 return 0;
3150@@ -1442,18 +1399,6 @@
3151 return err;
3152 }
3153
3154-#if 0
3155-/*static*/ void b44_dump_state(struct b44 *bp)
3156-{
3157- u32 val32, val32_2, val32_3, val32_4, val32_5;
3158- u16 val16;
3159-
3160- pci_read_config_word(bp->pdev, PCI_STATUS, &val16);
3161- printk("DEBUG: PCI status [%04x] \n", val16);
3162-
3163-}
3164-#endif
3165-
3166 #ifdef CONFIG_NET_POLL_CONTROLLER
3167 /*
3168 * Polling receive - used by netconsole and other diagnostic tools
3169@@ -1568,7 +1513,6 @@
3170 static void b44_setup_wol(struct b44 *bp)
3171 {
3172 u32 val;
3173- u16 pmval;
3174
3175 bw32(bp, B44_RXCONFIG, RXCONFIG_ALLMULTI);
3176
3177@@ -1592,13 +1536,6 @@
3178 } else {
3179 b44_setup_pseudo_magicp(bp);
3180 }
3181-
3182- val = br32(bp, B44_SBTMSLOW);
3183- bw32(bp, B44_SBTMSLOW, val | SBTMSLOW_PE);
3184-
3185- pci_read_config_word(bp->pdev, SSB_PMCSR, &pmval);
3186- pci_write_config_word(bp->pdev, SSB_PMCSR, pmval | SSB_PE);
3187-
3188 }
3189
3190 static int b44_close(struct net_device *dev)
3191@@ -1698,7 +1635,7 @@
3192
3193 val = br32(bp, B44_RXCONFIG);
3194 val &= ~(RXCONFIG_PROMISC | RXCONFIG_ALLMULTI);
3195- if (dev->flags & IFF_PROMISC) {
3196+ if ((dev->flags & IFF_PROMISC) || (val & RXCONFIG_CAM_ABSENT)) {
3197 val |= RXCONFIG_PROMISC;
3198 bw32(bp, B44_RXCONFIG, val);
3199 } else {
3200@@ -1745,12 +1682,8 @@
3201
3202 static void b44_get_drvinfo (struct net_device *dev, struct ethtool_drvinfo *info)
3203 {
3204- struct b44 *bp = netdev_priv(dev);
3205- struct pci_dev *pci_dev = bp->pdev;
3206-
3207 strcpy (info->driver, DRV_MODULE_NAME);
3208 strcpy (info->version, DRV_MODULE_VERSION);
3209- strcpy (info->bus_info, pci_name(pci_dev));
3210 }
3211
3212 static int b44_nway_reset(struct net_device *dev)
3213@@ -2034,6 +1967,245 @@
3214 .get_perm_addr = ethtool_op_get_perm_addr,
3215 };
3216
3217+static int b44_ethtool_ioctl (struct net_device *dev, void __user *useraddr)
3218+{
3219+ struct b44 *bp = dev->priv;
3220+ u32 ethcmd;
3221+
3222+ if (copy_from_user (&ethcmd, useraddr, sizeof (ethcmd)))
3223+ return -EFAULT;
3224+
3225+ switch (ethcmd) {
3226+ case ETHTOOL_GDRVINFO: {
3227+ struct ethtool_drvinfo info = { ETHTOOL_GDRVINFO };
3228+ strcpy (info.driver, DRV_MODULE_NAME);
3229+ strcpy (info.version, DRV_MODULE_VERSION);
3230+ memset(&info.fw_version, 0, sizeof(info.fw_version));
3231+ info.eedump_len = 0;
3232+ info.regdump_len = 0;
3233+ if (copy_to_user (useraddr, &info, sizeof (info)))
3234+ return -EFAULT;
3235+ return 0;
3236+ }
3237+
3238+ case ETHTOOL_GSET: {
3239+ struct ethtool_cmd cmd = { ETHTOOL_GSET };
3240+
3241+ if (!(bp->flags & B44_FLAG_INIT_COMPLETE))
3242+ return -EAGAIN;
3243+ cmd.supported = (SUPPORTED_Autoneg);
3244+ cmd.supported |= (SUPPORTED_100baseT_Half |
3245+ SUPPORTED_100baseT_Full |
3246+ SUPPORTED_10baseT_Half |
3247+ SUPPORTED_10baseT_Full |
3248+ SUPPORTED_MII);
3249+
3250+ cmd.advertising = 0;
3251+ if (bp->flags & B44_FLAG_ADV_10HALF)
3252+ cmd.advertising |= ADVERTISE_10HALF;
3253+ if (bp->flags & B44_FLAG_ADV_10FULL)
3254+ cmd.advertising |= ADVERTISE_10FULL;
3255+ if (bp->flags & B44_FLAG_ADV_100HALF)
3256+ cmd.advertising |= ADVERTISE_100HALF;
3257+ if (bp->flags & B44_FLAG_ADV_100FULL)
3258+ cmd.advertising |= ADVERTISE_100FULL;
3259+ cmd.advertising |= ADVERTISE_PAUSE_CAP | ADVERTISE_PAUSE_ASYM;
3260+ cmd.speed = (bp->flags & B44_FLAG_100_BASE_T) ?
3261+ SPEED_100 : SPEED_10;
3262+ cmd.duplex = (bp->flags & B44_FLAG_FULL_DUPLEX) ?
3263+ DUPLEX_FULL : DUPLEX_HALF;
3264+ cmd.port = 0;
3265+ cmd.phy_address = bp->phy_addr;
3266+ cmd.transceiver = (bp->flags & B44_FLAG_INTERNAL_PHY) ?
3267+ XCVR_INTERNAL : XCVR_EXTERNAL;
3268+ cmd.autoneg = (bp->flags & B44_FLAG_FORCE_LINK) ?
3269+ AUTONEG_DISABLE : AUTONEG_ENABLE;
3270+ cmd.maxtxpkt = 0;
3271+ cmd.maxrxpkt = 0;
3272+ if (copy_to_user(useraddr, &cmd, sizeof(cmd)))
3273+ return -EFAULT;
3274+ return 0;
3275+ }
3276+ case ETHTOOL_SSET: {
3277+ struct ethtool_cmd cmd;
3278+
3279+ if (!(bp->flags & B44_FLAG_INIT_COMPLETE))
3280+ return -EAGAIN;
3281+
3282+ if (copy_from_user(&cmd, useraddr, sizeof(cmd)))
3283+ return -EFAULT;
3284+
3285+ /* We do not support gigabit. */
3286+ if (cmd.autoneg == AUTONEG_ENABLE) {
3287+ if (cmd.advertising &
3288+ (ADVERTISED_1000baseT_Half |
3289+ ADVERTISED_1000baseT_Full))
3290+ return -EINVAL;
3291+ } else if ((cmd.speed != SPEED_100 &&
3292+ cmd.speed != SPEED_10) ||
3293+ (cmd.duplex != DUPLEX_HALF &&
3294+ cmd.duplex != DUPLEX_FULL)) {
3295+ return -EINVAL;
3296+ }
3297+
3298+ spin_lock_irq(&bp->lock);
3299+
3300+ if (cmd.autoneg == AUTONEG_ENABLE) {
3301+ bp->flags &= ~B44_FLAG_FORCE_LINK;
3302+ bp->flags &= ~(B44_FLAG_ADV_10HALF |
3303+ B44_FLAG_ADV_10FULL |
3304+ B44_FLAG_ADV_100HALF |
3305+ B44_FLAG_ADV_100FULL);
3306+ if (cmd.advertising & ADVERTISE_10HALF)
3307+ bp->flags |= B44_FLAG_ADV_10HALF;
3308+ if (cmd.advertising & ADVERTISE_10FULL)
3309+ bp->flags |= B44_FLAG_ADV_10FULL;
3310+ if (cmd.advertising & ADVERTISE_100HALF)
3311+ bp->flags |= B44_FLAG_ADV_100HALF;
3312+ if (cmd.advertising & ADVERTISE_100FULL)
3313+ bp->flags |= B44_FLAG_ADV_100FULL;
3314+ } else {
3315+ bp->flags |= B44_FLAG_FORCE_LINK;
3316+ if (cmd.speed == SPEED_100)
3317+ bp->flags |= B44_FLAG_100_BASE_T;
3318+ if (cmd.duplex == DUPLEX_FULL)
3319+ bp->flags |= B44_FLAG_FULL_DUPLEX;
3320+ }
3321+
3322+ b44_setup_phy(bp);
3323+
3324+ spin_unlock_irq(&bp->lock);
3325+
3326+ return 0;
3327+ }
3328+
3329+ case ETHTOOL_GMSGLVL: {
3330+ struct ethtool_value edata = { ETHTOOL_GMSGLVL };
3331+ edata.data = bp->msg_enable;
3332+ if (copy_to_user(useraddr, &edata, sizeof(edata)))
3333+ return -EFAULT;
3334+ return 0;
3335+ }
3336+ case ETHTOOL_SMSGLVL: {
3337+ struct ethtool_value edata;
3338+ if (copy_from_user(&edata, useraddr, sizeof(edata)))
3339+ return -EFAULT;
3340+ bp->msg_enable = edata.data;
3341+ return 0;
3342+ }
3343+ case ETHTOOL_NWAY_RST: {
3344+ u32 bmcr;
3345+ int r;
3346+
3347+ spin_lock_irq(&bp->lock);
3348+ b44_readphy(bp, MII_BMCR, &bmcr);
3349+ b44_readphy(bp, MII_BMCR, &bmcr);
3350+ r = -EINVAL;
3351+ if (bmcr & BMCR_ANENABLE) {
3352+ b44_writephy(bp, MII_BMCR,
3353+ bmcr | BMCR_ANRESTART);
3354+ r = 0;
3355+ }
3356+ spin_unlock_irq(&bp->lock);
3357+
3358+ return r;
3359+ }
3360+ case ETHTOOL_GLINK: {
3361+ struct ethtool_value edata = { ETHTOOL_GLINK };
3362+ edata.data = netif_carrier_ok(bp->dev) ? 1 : 0;
3363+ if (copy_to_user(useraddr, &edata, sizeof(edata)))
3364+ return -EFAULT;
3365+ return 0;
3366+ }
3367+ case ETHTOOL_GRINGPARAM: {
3368+ struct ethtool_ringparam ering = { ETHTOOL_GRINGPARAM };
3369+
3370+ ering.rx_max_pending = B44_RX_RING_SIZE - 1;
3371+ ering.rx_pending = bp->rx_pending;
3372+
3373+ /* XXX ethtool lacks a tx_max_pending, oops... */
3374+
3375+ if (copy_to_user(useraddr, &ering, sizeof(ering)))
3376+ return -EFAULT;
3377+ return 0;
3378+ }
3379+ case ETHTOOL_SRINGPARAM: {
3380+ struct ethtool_ringparam ering;
3381+
3382+ if (copy_from_user(&ering, useraddr, sizeof(ering)))
3383+ return -EFAULT;
3384+
3385+ if ((ering.rx_pending > B44_RX_RING_SIZE - 1) ||
3386+ (ering.rx_mini_pending != 0) ||
3387+ (ering.rx_jumbo_pending != 0) ||
3388+ (ering.tx_pending > B44_TX_RING_SIZE - 1))
3389+ return -EINVAL;
3390+
3391+ spin_lock_irq(&bp->lock);
3392+
3393+ bp->rx_pending = ering.rx_pending;
3394+ bp->tx_pending = ering.tx_pending;
3395+
3396+ b44_halt(bp);
3397+ b44_init_rings(bp);
3398+ b44_init_hw(bp, 1);
3399+ netif_wake_queue(bp->dev);
3400+ spin_unlock_irq(&bp->lock);
3401+
3402+ b44_enable_ints(bp);
3403+
3404+ return 0;
3405+ }
3406+ case ETHTOOL_GPAUSEPARAM: {
3407+ struct ethtool_pauseparam epause = { ETHTOOL_GPAUSEPARAM };
3408+
3409+ epause.autoneg =
3410+ (bp->flags & B44_FLAG_PAUSE_AUTO) != 0;
3411+ epause.rx_pause =
3412+ (bp->flags & B44_FLAG_RX_PAUSE) != 0;
3413+ epause.tx_pause =
3414+ (bp->flags & B44_FLAG_TX_PAUSE) != 0;
3415+ if (copy_to_user(useraddr, &epause, sizeof(epause)))
3416+ return -EFAULT;
3417+ return 0;
3418+ }
3419+ case ETHTOOL_SPAUSEPARAM: {
3420+ struct ethtool_pauseparam epause;
3421+
3422+ if (copy_from_user(&epause, useraddr, sizeof(epause)))
3423+ return -EFAULT;
3424+
3425+ spin_lock_irq(&bp->lock);
3426+ if (epause.autoneg)
3427+ bp->flags |= B44_FLAG_PAUSE_AUTO;
3428+ else
3429+ bp->flags &= ~B44_FLAG_PAUSE_AUTO;
3430+ if (epause.rx_pause)
3431+ bp->flags |= B44_FLAG_RX_PAUSE;
3432+ else
3433+ bp->flags &= ~B44_FLAG_RX_PAUSE;
3434+ if (epause.tx_pause)
3435+ bp->flags |= B44_FLAG_TX_PAUSE;
3436+ else
3437+ bp->flags &= ~B44_FLAG_TX_PAUSE;
3438+ if (bp->flags & B44_FLAG_PAUSE_AUTO) {
3439+ b44_halt(bp);
3440+ b44_init_rings(bp);
3441+ b44_init_hw(bp, 1);
3442+ } else {
3443+ __b44_set_flow_ctrl(bp, bp->flags);
3444+ }
3445+ spin_unlock_irq(&bp->lock);
3446+
3447+ b44_enable_ints(bp);
3448+
3449+ return 0;
3450+ }
3451+ };
3452+
3453+ return -EOPNOTSUPP;
3454+}
3455+
3456 static int b44_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
3457 {
3458 struct mii_ioctl_data *data = if_mii(ifr);
3459@@ -2043,40 +2215,64 @@
3460 if (!netif_running(dev))
3461 goto out;
3462
3463- spin_lock_irq(&bp->lock);
3464- err = generic_mii_ioctl(&bp->mii_if, data, cmd, NULL);
3465- spin_unlock_irq(&bp->lock);
3466-out:
3467- return err;
3468-}
3469+ switch (cmd) {
3470+ case SIOCETHTOOL:
3471+ return b44_ethtool_ioctl(dev, (void __user*) ifr->ifr_data);
3472
3473-/* Read 128-bytes of EEPROM. */
3474-static int b44_read_eeprom(struct b44 *bp, u8 *data)
3475-{
3476- long i;
3477- u16 *ptr = (u16 *) data;
3478+ case SIOCGMIIPHY:
3479+ data->phy_id = bp->phy_addr;
3480
3481- for (i = 0; i < 128; i += 2)
3482- ptr[i / 2] = cpu_to_le16(readw(bp->regs + 4096 + i));
3483+ /* fallthru */
3484+ case SIOCGMIIREG: {
3485+ u32 mii_regval;
3486+ spin_lock_irq(&bp->lock);
3487+ err = __b44_readphy(bp, data->phy_id & 0x1f, data->reg_num & 0x1f, &mii_regval);
3488+ spin_unlock_irq(&bp->lock);
3489
3490- return 0;
3491+ data->val_out = mii_regval;
3492+
3493+ return err;
3494+ }
3495+
3496+ case SIOCSMIIREG:
3497+ if (!capable(CAP_NET_ADMIN))
3498+ return -EPERM;
3499+
3500+ spin_lock_irq(&bp->lock);
3501+ err = __b44_writephy(bp, data->phy_id & 0x1f, data->reg_num & 0x1f, data->val_in);
3502+ spin_unlock_irq(&bp->lock);
3503+
3504+ return err;
3505+
3506+ default:
3507+ break;
3508+ };
3509+ return -EOPNOTSUPP;
3510+
3511+out:
3512+ return err;
3513 }
3514
3515 static int __devinit b44_get_invariants(struct b44 *bp)
3516 {
3517- u8 eeprom[128];
3518- int err;
3519+ struct ssb_device *sdev = bp->sdev;
3520+ int err = 0;
3521+ u8 *addr;
3522
3523- err = b44_read_eeprom(bp, &eeprom[0]);
3524- if (err)
3525- goto out;
3526+ bp->dma_offset = ssb_dma_offset(sdev);
3527
3528- bp->dev->dev_addr[0] = eeprom[79];
3529- bp->dev->dev_addr[1] = eeprom[78];
3530- bp->dev->dev_addr[2] = eeprom[81];
3531- bp->dev->dev_addr[3] = eeprom[80];
3532- bp->dev->dev_addr[4] = eeprom[83];
3533- bp->dev->dev_addr[5] = eeprom[82];
3534+ switch (instance) {
3535+ case 1:
3536+ addr = sdev->bus->sprom.r1.et0mac;
3537+ bp->phy_addr = sdev->bus->sprom.r1.et0phyaddr;
3538+ break;
3539+ default:
3540+ addr = sdev->bus->sprom.r1.et1mac;
3541+ bp->phy_addr = sdev->bus->sprom.r1.et1phyaddr;
3542+ break;
3543+ }
3544+
3545+ memcpy(bp->dev->dev_addr, addr, 6);
3546
3547 if (!is_valid_ether_addr(&bp->dev->dev_addr[0])){
3548 printk(KERN_ERR PFX "Invalid MAC address found in EEPROM\n");
3549@@ -2085,108 +2281,52 @@
3550
3551 memcpy(bp->dev->perm_addr, bp->dev->dev_addr, bp->dev->addr_len);
3552
3553- bp->phy_addr = eeprom[90] & 0x1f;
3554-
3555 /* With this, plus the rx_header prepended to the data by the
3556 * hardware, we'll land the ethernet header on a 2-byte boundary.
3557 */
3558 bp->rx_offset = 30;
3559-
3560 bp->imask = IMASK_DEF;
3561-
3562- bp->core_unit = ssb_core_unit(bp);
3563- bp->dma_offset = SB_PCI_DMA;
3564-
3565 /* XXX - really required?
3566 bp->flags |= B44_FLAG_BUGGY_TXPTR;
3567- */
3568+ */
3569
3570- if (ssb_get_core_rev(bp) >= 7)
3571- bp->flags |= B44_FLAG_B0_ANDLATER;
3572-
3573-out:
3574 return err;
3575 }
3576
3577-static int __devinit b44_init_one(struct pci_dev *pdev,
3578- const struct pci_device_id *ent)
3579+static int __devinit b44_init_one(struct ssb_device *sdev,
3580+ const struct ssb_device_id *ent)
3581 {
3582 static int b44_version_printed = 0;
3583- unsigned long b44reg_base, b44reg_len;
3584 struct net_device *dev;
3585 struct b44 *bp;
3586 int err, i;
3587
3588+ instance++;
3589+
3590 if (b44_version_printed++ == 0)
3591 printk(KERN_INFO "%s", version);
3592
3593- err = pci_enable_device(pdev);
3594- if (err) {
3595- dev_err(&pdev->dev, "Cannot enable PCI device, "
3596- "aborting.\n");
3597- return err;
3598- }
3599-
3600- if (!(pci_resource_flags(pdev, 0) & IORESOURCE_MEM)) {
3601- dev_err(&pdev->dev,
3602- "Cannot find proper PCI device "
3603- "base address, aborting.\n");
3604- err = -ENODEV;
3605- goto err_out_disable_pdev;
3606- }
3607-
3608- err = pci_request_regions(pdev, DRV_MODULE_NAME);
3609- if (err) {
3610- dev_err(&pdev->dev,
3611- "Cannot obtain PCI resources, aborting.\n");
3612- goto err_out_disable_pdev;
3613- }
3614-
3615- pci_set_master(pdev);
3616-
3617- err = pci_set_dma_mask(pdev, (u64) B44_DMA_MASK);
3618- if (err) {
3619- dev_err(&pdev->dev, "No usable DMA configuration, aborting.\n");
3620- goto err_out_free_res;
3621- }
3622-
3623- err = pci_set_consistent_dma_mask(pdev, (u64) B44_DMA_MASK);
3624- if (err) {
3625- dev_err(&pdev->dev, "No usable DMA configuration, aborting.\n");
3626- goto err_out_free_res;
3627- }
3628-
3629- b44reg_base = pci_resource_start(pdev, 0);
3630- b44reg_len = pci_resource_len(pdev, 0);
3631-
3632 dev = alloc_etherdev(sizeof(*bp));
3633 if (!dev) {
3634- dev_err(&pdev->dev, "Etherdev alloc failed, aborting.\n");
3635+ dev_err(&sdev->dev, "Etherdev alloc failed, aborting.\n");
3636 err = -ENOMEM;
3637- goto err_out_free_res;
3638+ goto out;
3639 }
3640
3641 SET_MODULE_OWNER(dev);
3642- SET_NETDEV_DEV(dev,&pdev->dev);
3643+ SET_NETDEV_DEV(dev,&sdev->dev);
3644
3645 /* No interesting netdevice features in this card... */
3646 dev->features |= 0;
3647
3648 bp = netdev_priv(dev);
3649- bp->pdev = pdev;
3650+ bp->sdev = sdev;
3651 bp->dev = dev;
3652
3653 bp->msg_enable = netif_msg_init(b44_debug, B44_DEF_MSG_ENABLE);
3654
3655 spin_lock_init(&bp->lock);
3656
3657- bp->regs = ioremap(b44reg_base, b44reg_len);
3658- if (bp->regs == 0UL) {
3659- dev_err(&pdev->dev, "Cannot map device registers, aborting.\n");
3660- err = -ENOMEM;
3661- goto err_out_free_dev;
3662- }
3663-
3664 bp->rx_pending = B44_DEF_RX_RING_PENDING;
3665 bp->tx_pending = B44_DEF_TX_RING_PENDING;
3666
3667@@ -2205,16 +2345,16 @@
3668 dev->poll_controller = b44_poll_controller;
3669 #endif
3670 dev->change_mtu = b44_change_mtu;
3671- dev->irq = pdev->irq;
3672+ dev->irq = sdev->irq;
3673 SET_ETHTOOL_OPS(dev, &b44_ethtool_ops);
3674
3675 netif_carrier_off(dev);
3676
3677 err = b44_get_invariants(bp);
3678 if (err) {
3679- dev_err(&pdev->dev,
3680+ dev_err(&sdev->dev,
3681 "Problem fetching invariants of chip, aborting.\n");
3682- goto err_out_iounmap;
3683+ goto err_out_free_dev;
3684 }
3685
3686 bp->mii_if.dev = dev;
3687@@ -2233,61 +2373,52 @@
3688
3689 err = register_netdev(dev);
3690 if (err) {
3691- dev_err(&pdev->dev, "Cannot register net device, aborting.\n");
3692- goto err_out_iounmap;
3693+ dev_err(&sdev->dev, "Cannot register net device, aborting.\n");
3694+ goto out;
3695 }
3696
3697- pci_set_drvdata(pdev, dev);
3698-
3699- pci_save_state(bp->pdev);
3700+ ssb_set_drvdata(sdev, dev);
3701
3702 /* Chip reset provides power to the b44 MAC & PCI cores, which
3703 * is necessary for MAC register access.
3704 */
3705 b44_chip_reset(bp);
3706
3707- printk(KERN_INFO "%s: Broadcom 4400 10/100BaseT Ethernet ", dev->name);
3708+ printk(KERN_INFO "%s: Broadcom 10/100BaseT Ethernet ", dev->name);
3709 for (i = 0; i < 6; i++)
3710 printk("%2.2x%c", dev->dev_addr[i],
3711 i == 5 ? '\n' : ':');
3712
3713- return 0;
3714+ /* Initialize phy */
3715+ spin_lock_irq(&bp->lock);
3716+ b44_chip_reset(bp);
3717+ spin_unlock_irq(&bp->lock);
3718
3719-err_out_iounmap:
3720- iounmap(bp->regs);
3721+ return 0;
3722
3723 err_out_free_dev:
3724 free_netdev(dev);
3725
3726-err_out_free_res:
3727- pci_release_regions(pdev);
3728-
3729-err_out_disable_pdev:
3730- pci_disable_device(pdev);
3731- pci_set_drvdata(pdev, NULL);
3732+out:
3733 return err;
3734 }
3735
3736-static void __devexit b44_remove_one(struct pci_dev *pdev)
3737+static void __devexit b44_remove_one(struct ssb_device *pdev)
3738 {
3739- struct net_device *dev = pci_get_drvdata(pdev);
3740- struct b44 *bp = netdev_priv(dev);
3741+ struct net_device *dev = ssb_get_drvdata(pdev);
3742
3743 unregister_netdev(dev);
3744- iounmap(bp->regs);
3745 free_netdev(dev);
3746- pci_release_regions(pdev);
3747- pci_disable_device(pdev);
3748- pci_set_drvdata(pdev, NULL);
3749+ ssb_set_drvdata(pdev, NULL);
3750 }
3751
3752-static int b44_suspend(struct pci_dev *pdev, pm_message_t state)
3753+static int b44_suspend(struct ssb_device *pdev, pm_message_t state)
3754 {
3755- struct net_device *dev = pci_get_drvdata(pdev);
3756+ struct net_device *dev = ssb_get_drvdata(pdev);
3757 struct b44 *bp = netdev_priv(dev);
3758
3759 if (!netif_running(dev))
3760- return 0;
3761+ return 0;
3762
3763 del_timer_sync(&bp->timer);
3764
3765@@ -2305,19 +2436,15 @@
3766 b44_init_hw(bp, 0);
3767 b44_setup_wol(bp);
3768 }
3769- pci_disable_device(pdev);
3770+
3771 return 0;
3772 }
3773
3774-static int b44_resume(struct pci_dev *pdev)
3775+static int b44_resume(struct ssb_device *pdev)
3776 {
3777- struct net_device *dev = pci_get_drvdata(pdev);
3778+ struct net_device *dev = ssb_get_drvdata(pdev);
3779 struct b44 *bp = netdev_priv(dev);
3780
3781- pci_restore_state(pdev);
3782- pci_enable_device(pdev);
3783- pci_set_master(pdev);
3784-
3785 if (!netif_running(dev))
3786 return 0;
3787
3788@@ -2339,29 +2466,31 @@
3789 return 0;
3790 }
3791
3792-static struct pci_driver b44_driver = {
3793+static struct ssb_driver b44_driver = {
3794 .name = DRV_MODULE_NAME,
3795- .id_table = b44_pci_tbl,
3796+ .id_table = b44_ssb_tbl,
3797 .probe = b44_init_one,
3798 .remove = __devexit_p(b44_remove_one),
3799- .suspend = b44_suspend,
3800- .resume = b44_resume,
3801+ .suspend = b44_suspend,
3802+ .resume = b44_resume,
3803 };
3804
3805 static int __init b44_init(void)
3806 {
3807 unsigned int dma_desc_align_size = dma_get_cache_alignment();
3808
3809+ instance = 0;
3810+
3811 /* Setup paramaters for syncing RX/TX DMA descriptors */
3812 dma_desc_align_mask = ~(dma_desc_align_size - 1);
3813 dma_desc_sync_size = max_t(unsigned int, dma_desc_align_size, sizeof(struct dma_desc));
3814
3815- return pci_register_driver(&b44_driver);
3816+ return ssb_driver_register(&b44_driver);
3817 }
3818
3819 static void __exit b44_cleanup(void)
3820 {
3821- pci_unregister_driver(&b44_driver);
3822+ ssb_driver_unregister(&b44_driver);
3823 }
3824
3825 module_init(b44_init);
3826diff -Nru linux-2.6.19.ori/drivers/net/b44.h linux-2.6.19/drivers/net/b44.h
3827--- linux-2.6.19.ori/drivers/net/b44.h 2006-12-02 18:55:38.000000000 +0100
3828+++ linux-2.6.19/drivers/net/b44.h 2006-12-02 19:21:40.000000000 +0100
3829@@ -129,6 +129,7 @@
3830 #define RXCONFIG_FLOW 0x00000020 /* Flow Control Enable */
3831 #define RXCONFIG_FLOW_ACCEPT 0x00000040 /* Accept Unicast Flow Control Frame */
3832 #define RXCONFIG_RFILT 0x00000080 /* Reject Filter */
3833+#define RXCONFIG_CAM_ABSENT 0x00000100 /* CAM Absent */
3834 #define B44_RXMAXLEN 0x0404UL /* EMAC RX Max Packet Length */
3835 #define B44_TXMAXLEN 0x0408UL /* EMAC TX Max Packet Length */
3836 #define B44_MDIO_CTRL 0x0410UL /* EMAC MDIO Control */
3837@@ -227,75 +228,9 @@
3838 #define B44_RX_PAUSE 0x05D4UL /* MIB RX Pause Packets */
3839 #define B44_RX_NPAUSE 0x05D8UL /* MIB RX Non-Pause Packets */
3840
3841-/* Silicon backplane register definitions */
3842-#define B44_SBIMSTATE 0x0F90UL /* SB Initiator Agent State */
3843-#define SBIMSTATE_PC 0x0000000f /* Pipe Count */
3844-#define SBIMSTATE_AP_MASK 0x00000030 /* Arbitration Priority */
3845-#define SBIMSTATE_AP_BOTH 0x00000000 /* Use both timeslices and token */
3846-#define SBIMSTATE_AP_TS 0x00000010 /* Use timeslices only */
3847-#define SBIMSTATE_AP_TK 0x00000020 /* Use token only */
3848-#define SBIMSTATE_AP_RSV 0x00000030 /* Reserved */
3849-#define SBIMSTATE_IBE 0x00020000 /* In Band Error */
3850-#define SBIMSTATE_TO 0x00040000 /* Timeout */
3851-#define B44_SBINTVEC 0x0F94UL /* SB Interrupt Mask */
3852-#define SBINTVEC_PCI 0x00000001 /* Enable interrupts for PCI */
3853-#define SBINTVEC_ENET0 0x00000002 /* Enable interrupts for enet 0 */
3854-#define SBINTVEC_ILINE20 0x00000004 /* Enable interrupts for iline20 */
3855-#define SBINTVEC_CODEC 0x00000008 /* Enable interrupts for v90 codec */
3856-#define SBINTVEC_USB 0x00000010 /* Enable interrupts for usb */
3857-#define SBINTVEC_EXTIF 0x00000020 /* Enable interrupts for external i/f */
3858-#define SBINTVEC_ENET1 0x00000040 /* Enable interrupts for enet 1 */
3859-#define B44_SBTMSLOW 0x0F98UL /* SB Target State Low */
3860-#define SBTMSLOW_RESET 0x00000001 /* Reset */
3861-#define SBTMSLOW_REJECT 0x00000002 /* Reject */
3862-#define SBTMSLOW_CLOCK 0x00010000 /* Clock Enable */
3863-#define SBTMSLOW_FGC 0x00020000 /* Force Gated Clocks On */
3864-#define SBTMSLOW_PE 0x40000000 /* Power Management Enable */
3865-#define SBTMSLOW_BE 0x80000000 /* BIST Enable */
3866-#define B44_SBTMSHIGH 0x0F9CUL /* SB Target State High */
3867-#define SBTMSHIGH_SERR 0x00000001 /* S-error */
3868-#define SBTMSHIGH_INT 0x00000002 /* Interrupt */
3869-#define SBTMSHIGH_BUSY 0x00000004 /* Busy */
3870-#define SBTMSHIGH_GCR 0x20000000 /* Gated Clock Request */
3871-#define SBTMSHIGH_BISTF 0x40000000 /* BIST Failed */
3872-#define SBTMSHIGH_BISTD 0x80000000 /* BIST Done */
3873-#define B44_SBIDHIGH 0x0FFCUL /* SB Identification High */
3874-#define SBIDHIGH_RC_MASK 0x0000000f /* Revision Code */
3875-#define SBIDHIGH_CC_MASK 0x0000fff0 /* Core Code */
3876-#define SBIDHIGH_CC_SHIFT 4
3877-#define SBIDHIGH_VC_MASK 0xffff0000 /* Vendor Code */
3878-#define SBIDHIGH_VC_SHIFT 16
3879-
3880-/* SSB PCI config space registers. */
3881-#define SSB_PMCSR 0x44
3882-#define SSB_PE 0x100
3883-#define SSB_BAR0_WIN 0x80
3884-#define SSB_BAR1_WIN 0x84
3885-#define SSB_SPROM_CONTROL 0x88
3886-#define SSB_BAR1_CONTROL 0x8c
3887-
3888-/* SSB core and host control registers. */
3889-#define SSB_CONTROL 0x0000UL
3890-#define SSB_ARBCONTROL 0x0010UL
3891-#define SSB_ISTAT 0x0020UL
3892-#define SSB_IMASK 0x0024UL
3893-#define SSB_MBOX 0x0028UL
3894-#define SSB_BCAST_ADDR 0x0050UL
3895-#define SSB_BCAST_DATA 0x0054UL
3896-#define SSB_PCI_TRANS_0 0x0100UL
3897-#define SSB_PCI_TRANS_1 0x0104UL
3898-#define SSB_PCI_TRANS_2 0x0108UL
3899-#define SSB_SPROM 0x0800UL
3900-
3901-#define SSB_PCI_MEM 0x00000000
3902-#define SSB_PCI_IO 0x00000001
3903-#define SSB_PCI_CFG0 0x00000002
3904-#define SSB_PCI_CFG1 0x00000003
3905-#define SSB_PCI_PREF 0x00000004
3906-#define SSB_PCI_BURST 0x00000008
3907-#define SSB_PCI_MASK0 0xfc000000
3908-#define SSB_PCI_MASK1 0xfc000000
3909-#define SSB_PCI_MASK2 0xc0000000
3910+#define br32(bp, REG) ssb_read32((bp)->sdev, (REG))
3911+#define bw32(bp, REG, VAL) ssb_write32((bp)->sdev, (REG), (VAL))
3912+#define atoi(str) simple_strtoul(((str != NULL) ? str : ""), NULL, 0)
3913
3914 /* 4400 PHY registers */
3915 #define B44_MII_AUXCTRL 24 /* Auxiliary Control */
3916@@ -346,10 +281,12 @@
3917
3918 struct ring_info {
3919 struct sk_buff *skb;
3920- DECLARE_PCI_UNMAP_ADDR(mapping);
3921+ dma_addr_t mapping;
3922 };
3923
3924 #define B44_MCAST_TABLE_SIZE 32
3925+#define B44_PHY_ADDR_NO_PHY 30
3926+#define B44_MDC_RATIO 5000000
3927
3928 #define B44_STAT_REG_DECLARE \
3929 _B44(tx_good_octets) \
3930@@ -425,9 +362,10 @@
3931
3932 u32 dma_offset;
3933 u32 flags;
3934-#define B44_FLAG_B0_ANDLATER 0x00000001
3935+#define B44_FLAG_INIT_COMPLETE 0x00000001
3936 #define B44_FLAG_BUGGY_TXPTR 0x00000002
3937 #define B44_FLAG_REORDER_BUG 0x00000004
3938+#define B44_FLAG_B0_ANDLATER 0x00000008
3939 #define B44_FLAG_PAUSE_AUTO 0x00008000
3940 #define B44_FLAG_FULL_DUPLEX 0x00010000
3941 #define B44_FLAG_100_BASE_T 0x00020000
3942@@ -452,8 +390,7 @@
3943 struct net_device_stats stats;
3944 struct b44_hw_stats hw_stats;
3945
3946- void __iomem *regs;
3947- struct pci_dev *pdev;
3948+ struct ssb_device *sdev;
3949 struct net_device *dev;
3950
3951 dma_addr_t rx_ring_dma, tx_ring_dma;
3952diff -Nru linux-2.6.19.ori/drivers/ssb/Kconfig linux-2.6.19/drivers/ssb/Kconfig
3953--- linux-2.6.19.ori/drivers/ssb/Kconfig 1970-01-01 01:00:00.000000000 +0100
3954+++ linux-2.6.19/drivers/ssb/Kconfig 2006-12-02 19:14:34.000000000 +0100
3955@@ -0,0 +1,59 @@
3956+menu "Sonics Silicon Backplane"
3957+
3958+config SSB
3959+ tristate "Sonics Silicon Backplane support"
3960+ depends on PCI
3961+ help
3962+ Support for the Sonics Silicon Backplane bus
3963+
3964+ The module will be called ssb
3965+
3966+ If unsure, say m
3967+
3968+config SSB_SILENT
3969+ bool "No SSB kernel messages"
3970+ depends on SSB
3971+ help
3972+ This option turns off all Sonics Silicon Backplane printks.
3973+ Note that you won't be able to identify problems, once
3974+ messages are turned off.
3975+ This might only be desired for production kernels on
3976+ embedded devices.
3977+
3978+ Say n
3979+
3980+config SSB_DEBUG
3981+ bool "SSB debugging"
3982+ depends on SSB && !SSB_SILENT
3983+ # TODO: Default y for now, but change to n later
3984+ default y
3985+ help
3986+ This turns on additional runtime checks and debugging
3987+ messages. Turn this on for SSB troubleshooting.
3988+
3989+ If unsure, say n
3990+
3991+config SSB_SERIAL
3992+ bool
3993+ depends on SSB
3994+ # ChipCommon and ExtIf serial support routines.
3995+
3996+config SSB_DRIVER_EXTIF
3997+ bool "SSB Broadcom EXTIF core driver"
3998+ help
3999+ Driver for the Sonics Silicon Backplane attached
4000+ Broadcom EXTIF core
4001+
4002+ If unsure, say n
4003+
4004+config SSB_DRIVER_MIPS
4005+ bool "SSB Broadcom MIPS core driver"
4006+ depends on SSB
4007+ select SSB_SERIAL
4008+ help
4009+ Driver for the Sonics Silicon Backplane attached
4010+ Broadcom MIPS core
4011+
4012+ If unsure, say n
4013+
4014+endmenu
4015diff -Nru linux-2.6.19.ori/drivers/ssb/Makefile linux-2.6.19/drivers/ssb/Makefile
4016--- linux-2.6.19.ori/drivers/ssb/Makefile 1970-01-01 01:00:00.000000000 +0100
4017+++ linux-2.6.19/drivers/ssb/Makefile 2006-12-02 19:14:34.000000000 +0100
4018@@ -0,0 +1,6 @@
4019+ssb-drivers-y += driver_chipcommon/
4020+ssb-drivers-$(CONFIG_SSB_DRIVER_MIPS) += driver_mips/
4021+
4022+obj-y += ssb.o $(ssb-drivers-y)
4023+
4024+ssb-objs := core.o pci.o scan.o
4025diff -Nru linux-2.6.19.ori/drivers/ssb/core.c linux-2.6.19/drivers/ssb/core.c
4026--- linux-2.6.19.ori/drivers/ssb/core.c 1970-01-01 01:00:00.000000000 +0100
4027+++ linux-2.6.19/drivers/ssb/core.c 2006-12-02 19:14:34.000000000 +0100
4028@@ -0,0 +1,596 @@
4029+#include "ssb_private.h"
4030+
4031+#include <linux/delay.h>
4032+#include <linux/pci.h>
4033+#include <linux/ssb.h>
4034+#include <linux/ssb_regs.h>
4035+
4036+
4037+static LIST_HEAD(attach_queue);
4038+static LIST_HEAD(buses);
4039+static int nr_buses;
4040+static DEFINE_SPINLOCK(buses_lock);
4041+
4042+
4043+static struct ssb_device * ssb_device_get(struct ssb_device *dev)
4044+{
4045+ if (dev)
4046+ get_device(&dev->dev);
4047+ return dev;
4048+}
4049+
4050+static void ssb_device_put(struct ssb_device *dev)
4051+{
4052+ if (dev)
4053+ put_device(&dev->dev);
4054+}
4055+
4056+static int ssb_device_resume(struct device *dev)
4057+{//TODO
4058+ return 0;
4059+}
4060+
4061+static int ssb_device_suspend(struct device *dev, pm_message_t state)
4062+{//TODO
4063+ return 0;
4064+}
4065+
4066+static void ssb_device_shutdown(struct device *dev)
4067+{//TODO
4068+}
4069+
4070+static int ssb_device_remove(struct device *dev)
4071+{
4072+ struct ssb_device *ssb_dev = dev_to_ssb_dev(dev);
4073+ struct ssb_driver *ssb_drv = drv_to_ssb_drv(dev->driver);
4074+
4075+ if (ssb_drv && ssb_drv->remove)
4076+ ssb_drv->remove(ssb_dev);
4077+ ssb_device_put(ssb_dev);
4078+
4079+ return 0;
4080+}
4081+
4082+static int ssb_device_probe(struct device *dev)
4083+{
4084+ struct ssb_device *ssb_dev = dev_to_ssb_dev(dev);
4085+ struct ssb_driver *ssb_drv = drv_to_ssb_drv(dev->driver);
4086+ int err = 0;
4087+
4088+ ssb_device_get(ssb_dev);
4089+ if (ssb_drv && ssb_drv->probe)
4090+ err = ssb_drv->probe(ssb_dev, &ssb_dev->id);
4091+ if (!err)
4092+ ssb_device_put(ssb_dev);
4093+
4094+ return err;
4095+}
4096+
4097+static int ssb_match_devid(const struct ssb_device_id *tabid,
4098+ const struct ssb_device_id *devid)
4099+{
4100+ if ((tabid->vendor != devid->vendor) &&
4101+ tabid->vendor != SSB_ANY_VENDOR)
4102+ return 0;
4103+ if ((tabid->coreid != devid->coreid) &&
4104+ tabid->coreid != SSB_ANY_ID)
4105+ return 0;
4106+ if ((tabid->revision != devid->revision) &&
4107+ tabid->revision != SSB_ANY_REV)
4108+ return 0;
4109+ return 1;
4110+}
4111+
4112+static int ssb_bus_match(struct device *dev, struct device_driver *drv)
4113+{
4114+ struct ssb_device *ssb_dev = dev_to_ssb_dev(dev);
4115+ struct ssb_driver *ssb_drv = drv_to_ssb_drv(drv);
4116+ const struct ssb_device_id *id;
4117+
4118+ for (id = ssb_drv->id_table;
4119+ id->vendor || id->coreid || id->revision;
4120+ id++) {
4121+ if (ssb_match_devid(id, &ssb_dev->id))
4122+ return 1; /* found */
4123+ }
4124+
4125+ return 0;
4126+}
4127+
4128+struct bus_type ssb_bustype = {
4129+ .name = NULL, /* Intentionally NULL to indicate early boot */
4130+ .match = ssb_bus_match,
4131+ .probe = ssb_device_probe,
4132+ .remove = ssb_device_remove,
4133+ .shutdown = ssb_device_shutdown,
4134+ .suspend = ssb_device_suspend,
4135+ .resume = ssb_device_resume,
4136+};
4137+
4138+#define is_early_boot() (ssb_bustype.name == NULL)
4139+
4140+void ssb_bus_unregister(struct ssb_bus *bus)
4141+{//FIXME?
4142+ spin_lock(&buses_lock);
4143+ list_del(&bus->list);
4144+ spin_unlock(&buses_lock);
4145+
4146+//TODO chipcommon exit
4147+ /* Free MMIO */
4148+ bus->mapped_device = NULL;
4149+ if (bus->bustype == SSB_BUSTYPE_SSB)
4150+ iounmap(bus->mmio);
4151+ else
4152+ pci_iounmap(bus->host_pci, bus->mmio);
4153+ bus->mmio = NULL;
4154+}
4155+EXPORT_SYMBOL_GPL(ssb_bus_unregister);
4156+
4157+/* Needs buses_lock locked */
4158+static int ssb_attach_queued_buses(void)
4159+{
4160+ struct ssb_bus *bus, *n;
4161+ struct ssb_device *dev;
4162+ int i, err;
4163+
4164+ssb_printk("BUSINIT\n");
4165+ list_for_each_entry_safe(bus, n, &attach_queue, list) {
4166+ for (i = 0; i < bus->nr_devices; i++) {
4167+ dev = &(bus->devices[i]);
4168+
4169+ err = device_register(&dev->dev);
4170+ if (err) {
4171+ ssb_printk("Could not register %s\n",
4172+ dev->dev.bus_id);
4173+ }
4174+ }
4175+ list_move_tail(&bus->list, &buses);
4176+ }
4177+ssb_printk("BUS init second stage completed\n");
4178+//FIXME dynamic clock somewhere?
4179+ return 0;
4180+}
4181+
4182+static int ssb_bus_register(struct ssb_bus *bus,
4183+ unsigned long baseaddr)
4184+{
4185+ int err;
4186+
4187+ ssb_printk("Sonics Silicon Backplane bus found at:\n");
4188+ if (bus->bustype == SSB_BUSTYPE_PCI)
4189+ ssb_printk("PCI device %s\n", bus->host_pci->dev.bus_id);
4190+ else
4191+ ssb_printk("Address 0x%08lX\n", baseaddr);
4192+
4193+ spin_lock(&buses_lock);
4194+
4195+ spin_lock_init(&bus->bar_lock);
4196+ INIT_LIST_HEAD(&bus->list);
4197+ bus->busnumber = nr_buses;
4198+
4199+ /* Powerup the bus */
4200+ err = ssb_pci_xtal(bus, SSB_GPIO_XTAL | SSB_GPIO_PLL, 1);
4201+ if (err)
4202+ goto out;
4203+ /* Scan for devices (cores) */
4204+ err = ssb_bus_scan(bus, baseaddr);
4205+ if (err)
4206+ goto err_disable_xtal;
4207+
4208+ /* Initialize basic system devices (if available) */
4209+ ssb_chipcommon_init(&bus->chipco);
4210+ ssb_mipscore_init(&bus->mipscore);
4211+ //TODO also register drivers for the basic system stuff later?
4212+ // I think the only purpose would be to show them in sysfs.
4213+
4214+ /* Queue it for attach */
4215+ list_add_tail(&bus->list, &attach_queue);
4216+ if (!is_early_boot()) {
4217+ /* This is not early boot, so we must attach the bus now */
4218+ err = ssb_attach_queued_buses();
4219+ if (err)
4220+ goto err_dequeue;
4221+ }
4222+
4223+ nr_buses++;
4224+out:
4225+ spin_unlock(&buses_lock);
4226+
4227+ssb_printk("busregister %d\n", err);
4228+ return err;
4229+err_dequeue:
4230+ list_del(&bus->list);
4231+err_disable_xtal:
4232+ ssb_pci_xtal(bus, SSB_GPIO_XTAL | SSB_GPIO_PLL, 0);
4233+ goto out;
4234+}
4235+
4236+int ssb_bus_pcibus_register(struct ssb_bus *bus,
4237+ struct pci_dev *host_pci)
4238+{
4239+ int err;
4240+
4241+ bus->bustype = SSB_BUSTYPE_PCI;
4242+ bus->host_pci = host_pci;
4243+
4244+ err = ssb_pci_sprom_get(bus);
4245+ if (!err)
4246+ err = ssb_bus_register(bus, 0);
4247+
4248+ return err;
4249+}
4250+EXPORT_SYMBOL_GPL(ssb_bus_pcibus_register);
4251+
4252+int ssb_bus_ssbbus_register(struct ssb_bus *bus,
4253+ unsigned long baseaddr,
4254+ void (*fill_sprom)(struct ssb_sprom *sprom))
4255+{
4256+ int err;
4257+
4258+ bus->bustype = SSB_BUSTYPE_SSB;
4259+ fill_sprom(&bus->sprom);
4260+ err = ssb_bus_register(bus, baseaddr);
4261+
4262+ return err;
4263+}
4264+
4265+static inline
4266+int do_select_core(struct ssb_bus *bus,
4267+ struct ssb_device *dev,
4268+ u16 *offset)
4269+{
4270+ int err = 0;
4271+
4272+ switch (bus->bustype) {
4273+ case SSB_BUSTYPE_PCI:
4274+ if (unlikely(dev != bus->mapped_device))
4275+ err = ssb_pci_switch_core(bus, dev);
4276+ break;
4277+ case SSB_BUSTYPE_SSB:
4278+ *offset += dev->core_index * SSB_CORE_SIZE;
4279+ break;
4280+ }
4281+
4282+ return err;
4283+}
4284+
4285+u16 ssb_read16(struct ssb_device *dev, u16 offset)
4286+{
4287+ struct ssb_bus *bus = dev->bus;
4288+
4289+ if (unlikely(do_select_core(bus, dev, &offset)))
4290+ return 0xFFFF;
4291+ return ssb_raw_read16(bus, offset);
4292+}
4293+EXPORT_SYMBOL_GPL(ssb_read16);
4294+
4295+u32 ssb_read32(struct ssb_device *dev, u16 offset)
4296+{
4297+ struct ssb_bus *bus = dev->bus;
4298+
4299+ if (unlikely(do_select_core(bus, dev, &offset)))
4300+ return 0xFFFFFFFF;
4301+ return ssb_raw_read32(bus, offset);
4302+}
4303+EXPORT_SYMBOL_GPL(ssb_read32);
4304+
4305+void ssb_write16(struct ssb_device *dev, u16 offset, u16 value)
4306+{
4307+ struct ssb_bus *bus = dev->bus;
4308+
4309+ if (unlikely(do_select_core(bus, dev, &offset)))
4310+ return;
4311+ ssb_raw_write16(bus, offset, value);
4312+}
4313+EXPORT_SYMBOL_GPL(ssb_write16);
4314+
4315+void ssb_write32(struct ssb_device *dev, u16 offset, u32 value)
4316+{
4317+ struct ssb_bus *bus = dev->bus;
4318+
4319+ if (unlikely(do_select_core(bus, dev, &offset)))
4320+ return;
4321+ ssb_raw_write32(bus, offset, value);
4322+}
4323+EXPORT_SYMBOL_GPL(ssb_write32);
4324+
4325+int __ssb_driver_register(struct ssb_driver *drv, struct module *owner)
4326+{
4327+ drv->drv.name = drv->name;
4328+ drv->drv.bus = &ssb_bustype;
4329+ drv->drv.owner = owner;
4330+
4331+ return driver_register(&drv->drv);
4332+}
4333+EXPORT_SYMBOL_GPL(__ssb_driver_register);
4334+
4335+void ssb_driver_unregister(struct ssb_driver *drv)
4336+{
4337+ driver_unregister(&drv->drv);
4338+}
4339+EXPORT_SYMBOL_GPL(ssb_driver_unregister);
4340+
4341+static u32 clkfactor_f6_resolve(u32 v)
4342+{
4343+ /* map the magic values */
4344+ switch (v) {
4345+ case SSB_CHIPCO_CLK_F6_2:
4346+ return 2;
4347+ case SSB_CHIPCO_CLK_F6_3:
4348+ return 3;
4349+ case SSB_CHIPCO_CLK_F6_4:
4350+ return 4;
4351+ case SSB_CHIPCO_CLK_F6_5:
4352+ return 5;
4353+ case SSB_CHIPCO_CLK_F6_6:
4354+ return 6;
4355+ case SSB_CHIPCO_CLK_F6_7:
4356+ return 7;
4357+ }
4358+ return 0;
4359+}
4360+
4361+/* Calculate the speed the backplane would run at a given set of clockcontrol values */
4362+u32 ssb_calc_clock_rate(u32 plltype, u32 n, u32 m)
4363+{
4364+ u32 n1, n2, clock, m1, m2, m3, mc;
4365+
4366+ n1 = (n & SSB_CHIPCO_CLK_N1);
4367+ n2 = ((n & SSB_CHIPCO_CLK_N2) >> SSB_CHIPCO_CLK_N2_SHIFT);
4368+
4369+ switch (plltype) {
4370+ case SSB_PLLTYPE_6: /* 100/200 or 120/240 only */
4371+ if (m & SSB_CHIPCO_CLK_T6_MMASK)
4372+ return SSB_CHIPCO_CLK_T6_M0;
4373+ return SSB_CHIPCO_CLK_T6_M1;
4374+ case SSB_PLLTYPE_1: /* 48Mhz base, 3 dividers */
4375+ case SSB_PLLTYPE_3: /* 25Mhz, 2 dividers */
4376+ case SSB_PLLTYPE_4: /* 48Mhz, 4 dividers */
4377+ case SSB_PLLTYPE_7: /* 25Mhz, 4 dividers */
4378+ n1 = clkfactor_f6_resolve(n1);
4379+ n2 += SSB_CHIPCO_CLK_F5_BIAS;
4380+ break;
4381+ case SSB_PLLTYPE_2: /* 48Mhz, 4 dividers */
4382+ n1 += SSB_CHIPCO_CLK_T2_BIAS;
4383+ n2 += SSB_CHIPCO_CLK_T2_BIAS;
4384+ assert((n1 >= 2) && (n1 <= 7));
4385+ assert((n2 >= 5) && (n2 <= 23));
4386+ break;
4387+ case SSB_PLLTYPE_5: /* 25Mhz, 4 dividers */
4388+ return 100000000;
4389+ default:
4390+ assert(0);
4391+ }
4392+
4393+ switch (plltype) {
4394+ case SSB_PLLTYPE_3: /* 25Mhz, 2 dividers */
4395+ case SSB_PLLTYPE_7: /* 25Mhz, 4 dividers */
4396+ clock = SSB_CHIPCO_CLK_BASE2 * n1 * n2;
4397+ break;
4398+ default:
4399+ clock = SSB_CHIPCO_CLK_BASE1 * n1 * n2;
4400+ }
4401+ if (!clock)
4402+ return 0;
4403+
4404+ m1 = (m & SSB_CHIPCO_CLK_M1);
4405+ m2 = ((m & SSB_CHIPCO_CLK_M2) >> SSB_CHIPCO_CLK_M2_SHIFT);
4406+ m3 = ((m & SSB_CHIPCO_CLK_M3) >> SSB_CHIPCO_CLK_M3_SHIFT);
4407+ mc = ((m & SSB_CHIPCO_CLK_MC) >> SSB_CHIPCO_CLK_MC_SHIFT);
4408+
4409+ switch (plltype) {
4410+ case SSB_PLLTYPE_1: /* 48Mhz base, 3 dividers */
4411+ case SSB_PLLTYPE_3: /* 25Mhz, 2 dividers */
4412+ case SSB_PLLTYPE_4: /* 48Mhz, 4 dividers */
4413+ case SSB_PLLTYPE_7: /* 25Mhz, 4 dividers */
4414+ m1 = clkfactor_f6_resolve(m1);
4415+ if ((plltype == SSB_PLLTYPE_1) ||
4416+ (plltype == SSB_PLLTYPE_3))
4417+ m2 += SSB_CHIPCO_CLK_F5_BIAS;
4418+ else
4419+ m2 = clkfactor_f6_resolve(m2);
4420+ m3 = clkfactor_f6_resolve(m3);
4421+
4422+ switch (mc) {
4423+ case SSB_CHIPCO_CLK_MC_BYPASS:
4424+ return clock;
4425+ case SSB_CHIPCO_CLK_MC_M1:
4426+ return (clock / m1);
4427+ case SSB_CHIPCO_CLK_MC_M1M2:
4428+ return (clock / (m1 * m2));
4429+ case SSB_CHIPCO_CLK_MC_M1M2M3:
4430+ return (clock / (m1 * m2 * m3));
4431+ case SSB_CHIPCO_CLK_MC_M1M3:
4432+ return (clock / (m1 * m3));
4433+ }
4434+ return 0;
4435+ case SSB_PLLTYPE_2:
4436+ m1 += SSB_CHIPCO_CLK_T2_BIAS;
4437+ m2 += SSB_CHIPCO_CLK_T2M2_BIAS;
4438+ m3 += SSB_CHIPCO_CLK_T2_BIAS;
4439+ assert((m1 >= 2) && (m1 <= 7));
4440+ assert((m2 >= 3) && (m2 <= 10));
4441+ assert((m3 >= 2) && (m3 <= 7));
4442+
4443+ if (!(mc & SSB_CHIPCO_CLK_T2MC_M1BYP))
4444+ clock /= m1;
4445+ if (!(mc & SSB_CHIPCO_CLK_T2MC_M2BYP))
4446+ clock /= m2;
4447+ if (!(mc & SSB_CHIPCO_CLK_T2MC_M3BYP))
4448+ clock /= m3;
4449+ return clock;
4450+ default:
4451+ assert(0);
4452+ }
4453+ return 0;
4454+}
4455+
4456+/* Get the current speed the backplane is running at */
4457+u32 ssb_clockspeed(struct ssb_bus *bus)
4458+{
4459+ u32 rate;
4460+ u32 plltype;
4461+ u32 clkctl_n, clkctl_m;
4462+
4463+ //TODO if EXTIF: PLLTYPE == 1, read n from clockcontrol_n, m from clockcontrol_sb
4464+
4465+ if (bus->chipco.dev) {
4466+ ssb_chipco_get_clockcontrol(&bus->chipco, &plltype,
4467+ &clkctl_n, &clkctl_m);
4468+ } else
4469+ return 0;
4470+
4471+ if (bus->chip_id == 0x5365) {
4472+ rate = 100000000;
4473+ } else {
4474+ rate = ssb_calc_clock_rate(plltype, clkctl_n, clkctl_m);
4475+ if (plltype == SSB_PLLTYPE_3) /* 25Mhz, 2 dividers */
4476+ rate /= 2;
4477+ }
4478+
4479+ return rate;
4480+}
4481+
4482+int ssb_core_is_enabled(struct ssb_device *dev)
4483+{
4484+ u32 val;
4485+
4486+ val = ssb_read32(dev, SSB_TMSLOW);
4487+ val &= SSB_TMSLOW_CLOCK | SSB_TMSLOW_RESET | SSB_TMSLOW_REJECT;
4488+
4489+ return (val == SSB_TMSLOW_CLOCK);
4490+}
4491+EXPORT_SYMBOL(ssb_core_is_enabled);
4492+
4493+void ssb_core_enable(struct ssb_device *dev, u32 core_specific_flags)
4494+{
4495+ u32 val;
4496+
4497+ ssb_core_disable(dev, core_specific_flags);
4498+ ssb_write32(dev, SSB_TMSLOW,
4499+ SSB_TMSLOW_RESET | SSB_TMSLOW_CLOCK |
4500+ SSB_TMSLOW_FGC | core_specific_flags);
4501+ /* flush */
4502+ ssb_read32(dev, SSB_TMSLOW);
4503+ udelay(1);
4504+
4505+ /* Clear SERR if set. This is a hw bug workaround. */
4506+ if (ssb_read32(dev, SSB_TMSHIGH) & SSB_TMSHIGH_SERR)
4507+ ssb_write32(dev, SSB_TMSHIGH, 0);
4508+
4509+ val = ssb_read32(dev, SSB_IMSTATE);
4510+ if (val & (SSB_IMSTATE_IBE | SSB_IMSTATE_TO)) {
4511+ val &= ~(SSB_IMSTATE_IBE | SSB_IMSTATE_TO);
4512+ ssb_write32(dev, SSB_IMSTATE, val);
4513+ }
4514+
4515+ ssb_write32(dev, SSB_TMSLOW,
4516+ SSB_TMSLOW_CLOCK | SSB_TMSLOW_FGC |
4517+ core_specific_flags);
4518+ /* flush */
4519+ ssb_read32(dev, SSB_TMSLOW);
4520+ udelay(1);
4521+
4522+ ssb_write32(dev, SSB_TMSLOW, SSB_TMSLOW_CLOCK |
4523+ core_specific_flags);
4524+ /* flush */
4525+ ssb_read32(dev, SSB_TMSLOW);
4526+ udelay(1);
4527+}
4528+EXPORT_SYMBOL(ssb_core_enable);
4529+
4530+static int ssb_wait_bit(struct ssb_device *dev, u16 reg, u32 bitmask,
4531+ int timeout, int set)
4532+{
4533+ int i;
4534+ u32 val;
4535+
4536+ for (i = 0; i < timeout; i++) {
4537+ val = ssb_read32(dev, reg);
4538+ if (set) {
4539+ if (val & bitmask)
4540+ return 0;
4541+ } else {
4542+ if (!(val & bitmask))
4543+ return 0;
4544+ }
4545+ udelay(10);
4546+ }
4547+ printk(KERN_ERR PFX "Timeout waiting for bitmask %08X on "
4548+ "register %04X to %s.\n",
4549+ bitmask, reg, (set ? "set" : "clear"));
4550+
4551+ return -ETIMEDOUT;
4552+}
4553+
4554+void ssb_core_disable(struct ssb_device *dev, u32 core_specific_flags)
4555+{
4556+ if (ssb_read32(dev, SSB_TMSLOW) & SSB_TMSLOW_RESET)
4557+ return;
4558+
4559+ ssb_write32(dev, SSB_TMSLOW, SSB_TMSLOW_REJECT | SSB_TMSLOW_CLOCK);
4560+ ssb_wait_bit(dev, SSB_TMSLOW, SSB_TMSLOW_REJECT, 1000, 1);
4561+ ssb_wait_bit(dev, SSB_TMSHIGH, SSB_TMSHIGH_BUSY, 1000, 0);
4562+ ssb_write32(dev, SSB_TMSLOW,
4563+ SSB_TMSLOW_FGC | SSB_TMSLOW_CLOCK |
4564+ SSB_TMSLOW_REJECT | SSB_TMSLOW_RESET |
4565+ core_specific_flags);
4566+ /* flush */
4567+ ssb_read32(dev, SSB_TMSLOW);
4568+ udelay(1);
4569+
4570+ ssb_write32(dev, SSB_TMSLOW,
4571+ SSB_TMSLOW_REJECT | SSB_TMSLOW_RESET |
4572+ core_specific_flags);
4573+ /* flush */
4574+ ssb_read32(dev, SSB_TMSLOW);
4575+ udelay(1);
4576+}
4577+EXPORT_SYMBOL(ssb_core_disable);
4578+
4579+int __ssb_printk(const char *fmt, ...)
4580+{
4581+ va_list args;
4582+ int res;
4583+
4584+ va_start(args, fmt);
4585+#ifdef CONFIG_CFE
4586+ if (is_early_boot() && cfe_present()) {
4587+ res = cfe_vprintk(fmt, args);
4588+ } else
4589+#endif
4590+ {
4591+ printk(KERN_INFO);
4592+ res = vprintk(fmt, args);
4593+ }
4594+ va_end(args);
4595+
4596+ return res;
4597+}
4598+
4599+
4600+static int ssb_modinit(void)
4601+{
4602+ int err;
4603+
4604+ ssb_bustype.name = "ssb";
4605+ err = bus_register(&ssb_bustype);
4606+ if (err)
4607+ return err;
4608+
4609+ /* Maybe we already registered some buses at early boot.
4610+ * Check for this and attach them
4611+ */
4612+ spin_lock(&buses_lock);
4613+ err = ssb_attach_queued_buses();
4614+ spin_unlock(&buses_lock);
4615+
4616+ return err;
4617+}
4618+subsys_initcall(ssb_modinit);
4619+
4620+static void __exit ssb_modexit(void)
4621+{
4622+ bus_unregister(&ssb_bustype);
4623+}
4624+module_exit(ssb_modexit)
4625diff -Nru linux-2.6.19.ori/drivers/ssb/driver_chipcommon/Makefile linux-2.6.19/drivers/ssb/driver_chipcommon/Makefile
4626--- linux-2.6.19.ori/drivers/ssb/driver_chipcommon/Makefile 1970-01-01 01:00:00.000000000 +0100
4627+++ linux-2.6.19/drivers/ssb/driver_chipcommon/Makefile 2006-12-02 19:14:34.000000000 +0100
4628@@ -0,0 +1 @@
4629+obj-y += chipcommon.o
4630diff -Nru linux-2.6.19.ori/drivers/ssb/driver_chipcommon/chipcommon.c linux-2.6.19/drivers/ssb/driver_chipcommon/chipcommon.c
4631--- linux-2.6.19.ori/drivers/ssb/driver_chipcommon/chipcommon.c 1970-01-01 01:00:00.000000000 +0100
4632+++ linux-2.6.19/drivers/ssb/driver_chipcommon/chipcommon.c 2006-12-02 19:14:34.000000000 +0100
4633@@ -0,0 +1,217 @@
4634+#include <linux/ssb.h>
4635+#include <linux/ssb_regs.h>
4636+
4637+#include "../ssb_private.h"
4638+
4639+
4640+static inline u32 chipco_read32(struct ssb_chipcommon *cc,
4641+ u16 offset)
4642+{
4643+ return ssb_read32(cc->dev, offset);
4644+}
4645+
4646+static inline void chipco_write32(struct ssb_chipcommon *cc,
4647+ u16 offset,
4648+ u32 value)
4649+{
4650+ ssb_write32(cc->dev, offset, value);
4651+}
4652+
4653+static void ssb_clock(struct ssb_chipcommon *cc, enum ssb_clkmode mode)
4654+{
4655+ struct ssb_device *ccdev = cc->dev;
4656+ struct ssb_bus *bus;
4657+ u32 tmp;
4658+
4659+ if (!ccdev)
4660+ return;
4661+ bus = ccdev->bus;
4662+ /* chipcommon cores prior to rev6 don't support dynamic clock control */
4663+ if (ccdev->id.revision < 6)
4664+ return;
4665+ /* chipcommon cores rev10 are a whole new ball game */
4666+ if (ccdev->id.revision >= 10)
4667+ return;
4668+ if (!(cc->capabilities & SSB_CHIPCO_CAP_PCTL))
4669+ return;
4670+
4671+ switch (mode) {
4672+ case SSB_CLKMODE_SLOW:
4673+ tmp = chipco_read32(cc, SSB_CHIPCO_SLOWCLKCTL);
4674+ tmp |= SSB_CHIPCO_SLOWCLKCTL_FSLOW;
4675+ chipco_write32(cc, SSB_CHIPCO_SLOWCLKCTL, tmp);
4676+ break;
4677+ case SSB_CLKMODE_FAST:
4678+ ssb_pci_xtal(bus, SSB_GPIO_XTAL, 1); /* Force crystal on */
4679+ tmp = chipco_read32(cc, SSB_CHIPCO_SLOWCLKCTL);
4680+ tmp &= ~SSB_CHIPCO_SLOWCLKCTL_FSLOW;
4681+ tmp |= SSB_CHIPCO_SLOWCLKCTL_IPLL;
4682+ chipco_write32(cc, SSB_CHIPCO_SLOWCLKCTL, tmp);
4683+ break;
4684+ case SSB_CLKMODE_DYNAMIC:
4685+ tmp = chipco_read32(cc, SSB_CHIPCO_SLOWCLKCTL);
4686+ tmp &= ~SSB_CHIPCO_SLOWCLKCTL_FSLOW;
4687+ tmp &= ~SSB_CHIPCO_SLOWCLKCTL_IPLL;
4688+ tmp &= ~SSB_CHIPCO_SLOWCLKCTL_ENXTAL;
4689+ if ((tmp & SSB_CHIPCO_SLOWCLKCTL_SRC) != SSB_CHIPCO_SLOWCLKCTL_SRC_XTAL)
4690+ tmp |= SSB_CHIPCO_SLOWCLKCTL_ENXTAL;
4691+ chipco_write32(cc, SSB_CHIPCO_SLOWCLKCTL, tmp);
4692+
4693+ /* for dynamic control, we have to release our xtal_pu "force on" */
4694+ if (tmp & SSB_CHIPCO_SLOWCLKCTL_ENXTAL)
4695+ ssb_pci_xtal(bus, SSB_GPIO_XTAL, 0);
4696+ break;
4697+ default:
4698+ assert(0);
4699+ }
4700+}
4701+
4702+void ssb_chipcommon_init(struct ssb_chipcommon *cc)
4703+{
4704+ if (!cc->dev)
4705+ return; /* We don't have a ChipCommon */
4706+ ssb_dprintk("Initializing Chipcommon...\n");
4707+ ssb_clock(cc, SSB_CLKMODE_FAST);
4708+}
4709+
4710+void ssb_chipcommon_exit(struct ssb_chipcommon *cc)
4711+{
4712+ //TODO
4713+}
4714+
4715+void ssb_chipco_get_clockcontrol(struct ssb_chipcommon *cc,
4716+ u32 *plltype, u32 *n, u32 *m)
4717+{
4718+ *n = chipco_read32(cc, SSB_CHIPCO_CLOCK_N);
4719+ *plltype = (cc->capabilities & SSB_CHIPCO_CAP_PLLT);
4720+ switch (*plltype) {
4721+ case SSB_PLLTYPE_6: /* 100/200 or 120/240 only */
4722+ *m = chipco_read32(cc, SSB_CHIPCO_CLOCK_MIPS);
4723+ break;
4724+ case SSB_PLLTYPE_3: /* 25Mhz, 2 dividers */
4725+ if (cc->dev->bus->chip_id != 0x5365) {
4726+ *m = chipco_read32(cc, SSB_CHIPCO_CLOCK_M2);
4727+ break;
4728+ }
4729+ /* Fallthough */
4730+ default:
4731+ *m = chipco_read32(cc, SSB_CHIPCO_CLOCK_SB);
4732+ }
4733+}
4734+
4735+void ssb_chipco_timing_init(struct ssb_chipcommon *cc,
4736+ unsigned long ns)
4737+{
4738+ struct ssb_device *dev = cc->dev;
4739+ struct ssb_bus *bus = dev->bus;
4740+ u32 tmp;
4741+
4742+ /* set register for external IO to control LED. */
4743+ chipco_write32(cc, SSB_CHIPCO_PROG_CFG, 0x11);
4744+ tmp = ceildiv(10, ns) << SSB_PROG_WCNT_3_SHIFT; /* Waitcount-3 = 10ns */
4745+ tmp |= ceildiv(40, ns) << SSB_PROG_WCNT_1_SHIFT; /* Waitcount-1 = 40ns */
4746+ tmp |= ceildiv(240, ns); /* Waitcount-0 = 240ns */
4747+ chipco_write32(cc, SSB_CHIPCO_PROG_WAITCNT, tmp); /* 0x01020a0c for a 100Mhz clock */
4748+
4749+ /* Set timing for the flash */
4750+ tmp = ceildiv(10, ns) << SSB_FLASH_WCNT_3_SHIFT; /* Waitcount-3 = 10nS */
4751+ tmp |= ceildiv(10, ns) << SSB_FLASH_WCNT_1_SHIFT; /* Waitcount-1 = 10nS */
4752+ tmp |= ceildiv(120, ns); /* Waitcount-0 = 120nS */
4753+ if ((bus->chip_id == 0x5365) ||
4754+ (dev->id.revision < 9))
4755+ chipco_write32(cc, SSB_CHIPCO_FLASH_WAITCNT, tmp);
4756+ if ((bus->chip_id == 0x5365) ||
4757+ (dev->id.revision < 9) ||
4758+ ((bus->chip_id == 0x5350) && (bus->chip_rev == 0)))
4759+ chipco_write32(cc, SSB_CHIPCO_PCMCIA_MEMWAIT, tmp);
4760+
4761+ if (bus->chip_id == 0x5350) {
4762+ /* Enable EXTIF */
4763+ tmp = ceildiv(10, ns) << SSB_PROG_WCNT_3_SHIFT; /* Waitcount-3 = 10ns */
4764+ tmp |= ceildiv(20, ns) << SSB_PROG_WCNT_2_SHIFT; /* Waitcount-2 = 20ns */
4765+ tmp |= ceildiv(100, ns) << SSB_PROG_WCNT_1_SHIFT; /* Waitcount-1 = 100ns */
4766+ tmp |= ceildiv(120, ns); /* Waitcount-0 = 120ns */
4767+ chipco_write32(cc, SSB_CHIPCO_PROG_WAITCNT, tmp); /* 0x01020a0c for a 100Mhz clock */
4768+ }
4769+}
4770+
4771+
4772+#ifdef CONFIG_SSB_SERIAL
4773+int ssb_chipco_serial_init(struct ssb_chipcommon *cc,
4774+ struct ssb_serial_port *ports)
4775+{
4776+ struct ssb_bus *bus = cc->dev->bus;
4777+ int nr_ports = 0;
4778+ u32 plltype;
4779+ unsigned int irq;
4780+ u32 baud_base, div;
4781+ u32 i, n;
4782+
4783+ plltype = (cc->capabilities & SSB_CHIPCO_CAP_PLLT);
4784+ irq = ssb_mips_irq(cc->dev);
4785+
4786+ if (plltype == SSB_PLLTYPE_1) {
4787+ /* PLL clock */
4788+ baud_base = ssb_calc_clock_rate(plltype,
4789+ chipco_read32(cc, SSB_CHIPCO_CLOCK_N),
4790+ chipco_read32(cc, SSB_CHIPCO_CLOCK_M2));
4791+ div = 1;
4792+ } else {
4793+ if (cc->dev->id.revision >= 11) {
4794+ /* Fixed ALP clock */
4795+ baud_base = 20000000;
4796+ div = 1;
4797+ /* Set the override bit so we don't divide it */
4798+ chipco_write32(cc, SSB_CHIPCO_CORECTL,
4799+ SSB_CHIPCO_CORECTL_UARTCLK0);
4800+ } else if (cc->dev->id.revision >= 3) {
4801+ /* Internal backplane clock */
4802+ baud_base = ssb_clockspeed(bus);
4803+ div = 2; /* Minimum divisor */
4804+ chipco_write32(cc, SSB_CHIPCO_CLKDIV,
4805+ (chipco_read32(cc, SSB_CHIPCO_CLKDIV)
4806+ & ~SSB_CHIPCO_CLKDIV_UART) | div);
4807+ } else {
4808+ /* Fixed internal backplane clock */
4809+ baud_base = 88000000;
4810+ div = 48;
4811+ }
4812+
4813+ /* Clock source depends on strapping if UartClkOverride is unset */
4814+ if ((cc->dev->id.revision > 0) &&
4815+ !(chipco_read32(cc, SSB_CHIPCO_CORECTL) & SSB_CHIPCO_CORECTL_UARTCLK0)) {
4816+ if ((cc->capabilities & SSB_CHIPCO_CAP_UARTCLK) ==
4817+ SSB_CHIPCO_CAP_UARTCLK_INT) {
4818+ /* Internal divided backplane clock */
4819+ baud_base /= div;
4820+ } else {
4821+ /* Assume external clock of 1.8432 MHz */
4822+ baud_base = 1843200;
4823+ }
4824+ }
4825+ }
4826+
4827+ /* Determine the registers of the UARTs */
4828+ n = (cc->capabilities & SSB_CHIPCO_CAP_NRUART);
4829+ for (i = 0; i < n; i++) {
4830+ void __iomem *cc_mmio;
4831+ void __iomem *uart_regs;
4832+
4833+ cc_mmio = cc->dev->bus->mmio + (cc->dev->core_index * SSB_CORE_SIZE);
4834+ uart_regs = cc_mmio + SSB_CHIPCO_UART0_DATA;
4835+ /* Offset changed at after rev 0 */
4836+ if (cc->dev->id.revision == 0)
4837+ uart_regs += (i * 8);
4838+ else
4839+ uart_regs += (i * 256);
4840+
4841+ nr_ports++;
4842+ ports[i].regs = uart_regs;
4843+ ports[i].irq = irq;
4844+ ports[i].baud_base = baud_base;
4845+ ports[i].reg_shift = 0;
4846+ }
4847+
4848+ return nr_ports;
4849+}
4850+#endif /* CONFIG_SSB_SERIAL */
4851diff -Nru linux-2.6.19.ori/drivers/ssb/driver_mips/Makefile linux-2.6.19/drivers/ssb/driver_mips/Makefile
4852--- linux-2.6.19.ori/drivers/ssb/driver_mips/Makefile 1970-01-01 01:00:00.000000000 +0100
4853+++ linux-2.6.19/drivers/ssb/driver_mips/Makefile 2006-12-02 19:14:34.000000000 +0100
4854@@ -0,0 +1 @@
4855+obj-y += mips.o
4856diff -Nru linux-2.6.19.ori/drivers/ssb/driver_mips/mips.c linux-2.6.19/drivers/ssb/driver_mips/mips.c
4857--- linux-2.6.19.ori/drivers/ssb/driver_mips/mips.c 1970-01-01 01:00:00.000000000 +0100
4858+++ linux-2.6.19/drivers/ssb/driver_mips/mips.c 2006-12-02 19:14:34.000000000 +0100
4859@@ -0,0 +1,233 @@
4860+#include <linux/ssb.h>
4861+
4862+#include <linux/serial.h>
4863+#include <linux/serial_core.h>
4864+#include <linux/serial_reg.h>
4865+#include <asm/time.h>
4866+
4867+#include "../ssb_private.h"
4868+
4869+
4870+static inline u32 mips_read32(struct ssb_mipscore *mcore,
4871+ u16 offset)
4872+{
4873+ return ssb_read32(mcore->dev, offset);
4874+}
4875+
4876+static inline void mips_write32(struct ssb_mipscore *mcore,
4877+ u16 offset,
4878+ u32 value)
4879+{
4880+ ssb_write32(mcore->dev, offset, value);
4881+}
4882+
4883+static const u32 ipsflag_irq_mask[] = {
4884+ 0,
4885+ SSB_IPSFLAG_IRQ1,
4886+ SSB_IPSFLAG_IRQ2,
4887+ SSB_IPSFLAG_IRQ3,
4888+ SSB_IPSFLAG_IRQ4,
4889+};
4890+
4891+static const u32 ipsflag_irq_shift[] = {
4892+ 0,
4893+ SSB_IPSFLAG_IRQ1_SHIFT,
4894+ SSB_IPSFLAG_IRQ2_SHIFT,
4895+ SSB_IPSFLAG_IRQ3_SHIFT,
4896+ SSB_IPSFLAG_IRQ4_SHIFT,
4897+};
4898+
4899+static inline u32 ssb_irqflag(struct ssb_device *dev)
4900+{
4901+ return ssb_read32(dev, SSB_TPSFLAG) & SSB_TPSFLAG_BPFLAG;
4902+}
4903+
4904+/* Get the MIPS IRQ assignment for a specified device.
4905+ * If unassigned, 0 is returned.
4906+ */
4907+unsigned int ssb_mips_irq(struct ssb_device *dev)
4908+{
4909+ struct ssb_bus *bus = dev->bus;
4910+ u32 irqflag;
4911+ u32 ipsflag;
4912+ u32 tmp;
4913+ unsigned int irq;
4914+
4915+ irqflag = ssb_irqflag(dev);
4916+ ipsflag = ssb_read32(bus->mipscore.dev, SSB_IPSFLAG);
4917+ for (irq = 1; irq <= 4; irq++) {
4918+ tmp = ((ipsflag & ipsflag_irq_mask[irq]) >> ipsflag_irq_shift[irq]);
4919+ if (tmp == irqflag)
4920+ break;
4921+ }
4922+ if (irq == 5)
4923+ irq = 0;
4924+
4925+ return irq;
4926+}
4927+
4928+static void clear_irq(struct ssb_bus *bus, unsigned int irq)
4929+{
4930+ struct ssb_device *dev = bus->mipscore.dev;
4931+
4932+ /* Clear the IRQ in the MIPScore backplane registers */
4933+ if (irq == 0) {
4934+ ssb_write32(dev, SSB_INTVEC, 0);
4935+ } else {
4936+ ssb_write32(dev, SSB_IPSFLAG,
4937+ ssb_read32(dev, SSB_IPSFLAG) |
4938+ ipsflag_irq_mask[irq]);
4939+ }
4940+}
4941+
4942+static void set_irq(struct ssb_device *dev, unsigned int irq)
4943+{
4944+ unsigned int oldirq = ssb_mips_irq(dev);
4945+ struct ssb_bus *bus = dev->bus;
4946+ struct ssb_device *mdev = bus->mipscore.dev;
4947+ u32 irqflag = ssb_irqflag(dev);
4948+
4949+ dev->irq = irq + 2;
4950+
4951+ ssb_dprintk("set_irq: core 0x%04x, irq %d => %d\n", dev->id.coreid, oldirq, irq);
4952+ /* clear the old irq */
4953+ if (oldirq == 0)
4954+ ssb_write32(mdev, SSB_INTVEC, (~(1 << irqflag) & ssb_read32(mdev, SSB_INTVEC)));
4955+ else
4956+ clear_irq(bus, oldirq);
4957+
4958+ /* assign the new one */
4959+ if (irq == 0)
4960+ ssb_write32(mdev, SSB_INTVEC, ((1 << irqflag) & ssb_read32(mdev, SSB_INTVEC)));
4961+
4962+ irqflag <<= ipsflag_irq_shift[irq];
4963+ irqflag |= (ssb_read32(mdev, SSB_IPSFLAG) & ~ipsflag_irq_mask[irq]);
4964+ ssb_write32(mdev, SSB_IPSFLAG, irqflag);
4965+}
4966+
4967+
4968+static void ssb_mips_serial_init(struct ssb_mipscore *mcore)
4969+{
4970+ struct ssb_bus *bus = mcore->dev->bus;
4971+
4972+ //TODO if (EXTIF available
4973+#if 0
4974+ extifregs_t *eir = (extifregs_t *) regs;
4975+ sbconfig_t *sb;
4976+
4977+ /* Determine external UART register base */
4978+ sb = (sbconfig_t *)((ulong) eir + SBCONFIGOFF);
4979+ base = EXTIF_CFGIF_BASE(sb_base(R_REG(&sb->sbadmatch1)));
4980+
4981+ /* Determine IRQ */
4982+ irq = sb_irq(sbh);
4983+
4984+ /* Disable GPIO interrupt initially */
4985+ W_REG(&eir->gpiointpolarity, 0);
4986+ W_REG(&eir->gpiointmask, 0);
4987+
4988+ /* Search for external UARTs */
4989+ n = 2;
4990+ for (i = 0; i < 2; i++) {
4991+ regs = (void *) REG_MAP(base + (i * 8), 8);
4992+ if (BCMINIT(serial_exists)(regs)) {
4993+ /* Set GPIO 1 to be the external UART IRQ */
4994+ W_REG(&eir->gpiointmask, 2);
4995+ if (add)
4996+ add(regs, irq, 13500000, 0);
4997+ }
4998+ }
4999+
5000+ /* Add internal UART if enabled */
5001+ if (R_REG(&eir->corecontrol) & CC_UE)
5002+ if (add)
5003+ add((void *) &eir->uartdata, irq, sb_clock(sbh), 2);
5004+
5005+#endif
5006+ if (bus->chipco.dev)
5007+ mcore->nr_serial_ports = ssb_chipco_serial_init(&bus->chipco, mcore->serial_ports);
5008+ else
5009+ mcore->nr_serial_ports = 0;
5010+}
5011+
5012+static void ssb_mips_flash_detect(struct ssb_mipscore *mcore)
5013+{
5014+ struct ssb_bus *bus = mcore->dev->bus;
5015+
5016+ if (bus->chipco.dev) {
5017+ mcore->flash_window = 0x1c000000;
5018+ mcore->flash_window_size = 0x800000;
5019+ } else {
5020+ mcore->flash_window = 0x1fc00000;
5021+ mcore->flash_window_size = 0x400000;
5022+ }
5023+}
5024+
5025+void ssb_mipscore_init(struct ssb_mipscore *mcore)
5026+{
5027+ struct ssb_bus *bus = mcore->dev->bus;
5028+ struct ssb_device *dev;
5029+ unsigned long hz, ns;
5030+ unsigned int irq, i;
5031+
5032+ if (!mcore->dev)
5033+ return; /* We don't have a MIPS core */
5034+
5035+ ssb_dprintk("Initializing MIPS core...\n");
5036+
5037+ hz = ssb_clockspeed(bus);
5038+ if (!hz)
5039+ hz = 100000000;
5040+ ns = 1000000000 / hz;
5041+
5042+//TODO
5043+#if 0
5044+ if (have EXTIF) {
5045+ /* Initialize extif so we can get to the LEDs and external UART */
5046+ W_REG(&eir->prog_config, CF_EN);
5047+
5048+ /* Set timing for the flash */
5049+ tmp = CEIL(10, ns) << FW_W3_SHIFT; /* W3 = 10nS */
5050+ tmp = tmp | (CEIL(40, ns) << FW_W1_SHIFT); /* W1 = 40nS */
5051+ tmp = tmp | CEIL(120, ns); /* W0 = 120nS */
5052+ W_REG(&eir->prog_waitcount, tmp); /* 0x01020a0c for a 100Mhz clock */
5053+
5054+ /* Set programmable interface timing for external uart */
5055+ tmp = CEIL(10, ns) << FW_W3_SHIFT; /* W3 = 10nS */
5056+ tmp = tmp | (CEIL(20, ns) << FW_W2_SHIFT); /* W2 = 20nS */
5057+ tmp = tmp | (CEIL(100, ns) << FW_W1_SHIFT); /* W1 = 100nS */
5058+ tmp = tmp | CEIL(120, ns); /* W0 = 120nS */
5059+ W_REG(&eir->prog_waitcount, tmp);
5060+ }
5061+ else... chipcommon
5062+#endif
5063+ if (bus->chipco.dev)
5064+ ssb_chipco_timing_init(&bus->chipco, ns);
5065+
5066+ /* Assign IRQs to all cores on the bus, start with irq line 2, because serial usually takes 1 */
5067+ for (irq = 2, i = 0; i < bus->nr_devices; i++) {
5068+ dev = &(bus->devices[i]);
5069+ dev->irq = ssb_mips_irq(dev) + 2;
5070+ switch(dev->id.coreid) {
5071+ case SSB_DEV_USB11_HOST:
5072+ /* shouldn't need a separate irq line for non-4710, most of them have a proper
5073+ * external usb controller on the pci */
5074+ if ((bus->chip_id == 0x4710) && (irq <= 4)) {
5075+ set_irq(dev, irq++);
5076+ break;
5077+ }
5078+ case SSB_DEV_PCI:
5079+ case SSB_DEV_ETHERNET:
5080+ case SSB_DEV_80211:
5081+ case SSB_DEV_USB20_HOST:
5082+ /* These devices get their own IRQ line if available, the rest goes on IRQ0 */
5083+ if (irq <= 4) {
5084+ set_irq(dev, irq++);
5085+ break;
5086+ }
5087+ }
5088+ }
5089+
5090+ ssb_mips_serial_init(mcore);
5091+ ssb_mips_flash_detect(mcore);
5092+}
5093diff -Nru linux-2.6.19.ori/drivers/ssb/pci.c linux-2.6.19/drivers/ssb/pci.c
5094--- linux-2.6.19.ori/drivers/ssb/pci.c 1970-01-01 01:00:00.000000000 +0100
5095+++ linux-2.6.19/drivers/ssb/pci.c 2006-12-02 19:14:34.000000000 +0100
5096@@ -0,0 +1,399 @@
5097+/*
5098+ * Sonics Silicon Backplane PCI-Hostbus related functions.
5099+ *
5100+ * Copyright (C) 2005-2006 Michael Buesch <mb@bu3sch.de>
5101+ * Copyright (C) 2005 Martin Langer <martin-langer@gmx.de>
5102+ * Copyright (C) 2005 Stefano Brivio <st3@riseup.net>
5103+ * Copyright (C) 2005 Danny van Dyk <kugelfang@gentoo.org>
5104+ * Copyright (C) 2005 Andreas Jaggi <andreas.jaggi@waterwave.ch>
5105+ *
5106+ * Derived from the Broadcom 4400 device driver.
5107+ * Copyright (C) 2002 David S. Miller (davem@redhat.com)
5108+ * Fixed by Pekka Pietikainen (pp@ee.oulu.fi)
5109+ * Copyright (C) 2006 Broadcom Corporation.
5110+ *
5111+ * Licensed under the GNU/GPL. See COPYING for details.
5112+ */
5113+
5114+#include <linux/ssb.h>
5115+#include <linux/ssb_regs.h>
5116+#include <linux/pci.h>
5117+#include <linux/delay.h>
5118+
5119+#include "ssb_private.h"
5120+
5121+
5122+int ssb_pci_switch_coreidx(struct ssb_bus *bus, u8 coreidx)
5123+{
5124+ int err;
5125+ int attempts = 0;
5126+ u32 cur_core;
5127+
5128+ while (1) {
5129+ err = pci_write_config_dword(bus->host_pci, SSB_BAR0_WIN,
5130+ (coreidx * SSB_CORE_SIZE)
5131+ + SSB_ENUM_BASE);
5132+ if (err)
5133+ goto error;
5134+ err = pci_read_config_dword(bus->host_pci, SSB_BAR0_WIN,
5135+ &cur_core);
5136+ if (err)
5137+ goto error;
5138+ cur_core = (cur_core - SSB_ENUM_BASE)
5139+ / SSB_CORE_SIZE;
5140+ if (cur_core == coreidx)
5141+ break;
5142+
5143+ if (attempts++ > SSB_BAR0_MAX_RETRIES)
5144+ goto error;
5145+ udelay(10);
5146+ }
5147+ return 0;
5148+error:
5149+ printk(KERN_ERR PFX "Failed to switch to core %u\n", coreidx);
5150+ return -ENODEV;
5151+}
5152+
5153+int ssb_pci_switch_core(struct ssb_bus *bus,
5154+ struct ssb_device *dev)
5155+{
5156+ int err;
5157+ unsigned long flags;
5158+
5159+ ssb_dprintk("Switching to core %d\n",
5160+ dev->core_index);
5161+
5162+ spin_lock_irqsave(&bus->bar_lock, flags);
5163+ err = ssb_pci_switch_coreidx(bus, dev->core_index);
5164+ if (!err)
5165+ bus->mapped_device = dev;
5166+ spin_unlock_irqrestore(&bus->bar_lock, flags);
5167+
5168+ return err;
5169+}
5170+
5171+int ssb_pci_xtal(struct ssb_bus *bus, u32 what, int turn_on)
5172+{
5173+ int err;
5174+ u32 in, out, outenable;
5175+
5176+ if (bus->bustype != SSB_BUSTYPE_PCI)
5177+ return 0;
5178+
5179+ err = pci_read_config_dword(bus->host_pci, SSB_GPIO_IN, &in);
5180+ if (err)
5181+ goto err_pci;
5182+ err = pci_read_config_dword(bus->host_pci, SSB_GPIO_OUT, &out);
5183+ if (err)
5184+ goto err_pci;
5185+ err = pci_read_config_dword(bus->host_pci, SSB_GPIO_OUT_ENABLE, &outenable);
5186+ if (err)
5187+ goto err_pci;
5188+
5189+ outenable |= what;
5190+
5191+ if (turn_on) {
5192+ /* Avoid glitching the clock if GPRS is already using it.
5193+ * We can't actually read the state of the PLLPD so we infer it
5194+ * by the value of XTAL_PU which *is* readable via gpioin.
5195+ */
5196+ if (in & SSB_GPIO_XTAL)
5197+ return 0;
5198+
5199+ if (what & SSB_GPIO_XTAL) {
5200+ /* Turn the crystal on */
5201+ out |= SSB_GPIO_XTAL;
5202+ if (what & SSB_GPIO_PLL)
5203+ out |= SSB_GPIO_PLL;
5204+ err = pci_write_config_dword(bus->host_pci, SSB_GPIO_OUT, out);
5205+ if (err)
5206+ goto err_pci;
5207+ err = pci_write_config_dword(bus->host_pci, SSB_GPIO_OUT_ENABLE,
5208+ outenable);
5209+ if (err)
5210+ goto err_pci;
5211+ msleep(1);
5212+ }
5213+ if (what & SSB_GPIO_PLL) {
5214+ /* Turn the PLL on */
5215+ out &= ~SSB_GPIO_PLL;
5216+ err = pci_write_config_dword(bus->host_pci, SSB_GPIO_OUT, out);
5217+ if (err)
5218+ goto err_pci;
5219+ msleep(2);
5220+ }
5221+ } else {
5222+ if (what & SSB_GPIO_XTAL) {
5223+ /* Turn the crystal off */
5224+ out &= ~SSB_GPIO_XTAL;
5225+ }
5226+ if (what & SSB_GPIO_PLL) {
5227+ /* Turn the PLL off */
5228+ out |= SSB_GPIO_PLL;
5229+ }
5230+ err = pci_write_config_dword(bus->host_pci, SSB_GPIO_OUT, out);
5231+ if (err)
5232+ goto err_pci;
5233+ err = pci_write_config_dword(bus->host_pci, SSB_GPIO_OUT_ENABLE, outenable);
5234+ if (err)
5235+ goto err_pci;
5236+ }
5237+
5238+out:
5239+ return err;
5240+
5241+err_pci:
5242+ printk(KERN_ERR PFX "Error: pctl_set_clock() could not access PCI config space!\n");
5243+ err = -EBUSY;
5244+ goto out;
5245+}
5246+
5247+#define SPOFF(offset) (((offset) - SSB_SPROM_BASE) / sizeof(u16))
5248+#define SPEX(_outvar, _offset, _mask, _shift) \
5249+ out->_outvar = ((in[SPOFF(_offset)] & (_mask)) >> (_shift))
5250+
5251+static inline u8 ssb_crc8(u8 crc, u8 data)
5252+{
5253+ /* Polynomial: x^8 + x^7 + x^6 + x^4 + x^2 + 1 */
5254+ static const u8 t[] = {
5255+ 0x00, 0xF7, 0xB9, 0x4E, 0x25, 0xD2, 0x9C, 0x6B,
5256+ 0x4A, 0xBD, 0xF3, 0x04, 0x6F, 0x98, 0xD6, 0x21,
5257+ 0x94, 0x63, 0x2D, 0xDA, 0xB1, 0x46, 0x08, 0xFF,
5258+ 0xDE, 0x29, 0x67, 0x90, 0xFB, 0x0C, 0x42, 0xB5,
5259+ 0x7F, 0x88, 0xC6, 0x31, 0x5A, 0xAD, 0xE3, 0x14,
5260+ 0x35, 0xC2, 0x8C, 0x7B, 0x10, 0xE7, 0xA9, 0x5E,
5261+ 0xEB, 0x1C, 0x52, 0xA5, 0xCE, 0x39, 0x77, 0x80,
5262+ 0xA1, 0x56, 0x18, 0xEF, 0x84, 0x73, 0x3D, 0xCA,
5263+ 0xFE, 0x09, 0x47, 0xB0, 0xDB, 0x2C, 0x62, 0x95,
5264+ 0xB4, 0x43, 0x0D, 0xFA, 0x91, 0x66, 0x28, 0xDF,
5265+ 0x6A, 0x9D, 0xD3, 0x24, 0x4F, 0xB8, 0xF6, 0x01,
5266+ 0x20, 0xD7, 0x99, 0x6E, 0x05, 0xF2, 0xBC, 0x4B,
5267+ 0x81, 0x76, 0x38, 0xCF, 0xA4, 0x53, 0x1D, 0xEA,
5268+ 0xCB, 0x3C, 0x72, 0x85, 0xEE, 0x19, 0x57, 0xA0,
5269+ 0x15, 0xE2, 0xAC, 0x5B, 0x30, 0xC7, 0x89, 0x7E,
5270+ 0x5F, 0xA8, 0xE6, 0x11, 0x7A, 0x8D, 0xC3, 0x34,
5271+ 0xAB, 0x5C, 0x12, 0xE5, 0x8E, 0x79, 0x37, 0xC0,
5272+ 0xE1, 0x16, 0x58, 0xAF, 0xC4, 0x33, 0x7D, 0x8A,
5273+ 0x3F, 0xC8, 0x86, 0x71, 0x1A, 0xED, 0xA3, 0x54,
5274+ 0x75, 0x82, 0xCC, 0x3B, 0x50, 0xA7, 0xE9, 0x1E,
5275+ 0xD4, 0x23, 0x6D, 0x9A, 0xF1, 0x06, 0x48, 0xBF,
5276+ 0x9E, 0x69, 0x27, 0xD0, 0xBB, 0x4C, 0x02, 0xF5,
5277+ 0x40, 0xB7, 0xF9, 0x0E, 0x65, 0x92, 0xDC, 0x2B,
5278+ 0x0A, 0xFD, 0xB3, 0x44, 0x2F, 0xD8, 0x96, 0x61,
5279+ 0x55, 0xA2, 0xEC, 0x1B, 0x70, 0x87, 0xC9, 0x3E,
5280+ 0x1F, 0xE8, 0xA6, 0x51, 0x3A, 0xCD, 0x83, 0x74,
5281+ 0xC1, 0x36, 0x78, 0x8F, 0xE4, 0x13, 0x5D, 0xAA,
5282+ 0x8B, 0x7C, 0x32, 0xC5, 0xAE, 0x59, 0x17, 0xE0,
5283+ 0x2A, 0xDD, 0x93, 0x64, 0x0F, 0xF8, 0xB6, 0x41,
5284+ 0x60, 0x97, 0xD9, 0x2E, 0x45, 0xB2, 0xFC, 0x0B,
5285+ 0xBE, 0x49, 0x07, 0xF0, 0x9B, 0x6C, 0x22, 0xD5,
5286+ 0xF4, 0x03, 0x4D, 0xBA, 0xD1, 0x26, 0x68, 0x9F,
5287+ };
5288+ return t[crc ^ data];
5289+}
5290+
5291+static u8 ssb_sprom_crc(const u16 *sprom)
5292+{
5293+ int word;
5294+ u8 crc = 0xFF;
5295+
5296+ for (word = 0; word < SSB_SPROMSIZE_WORDS - 1; word++) {
5297+ crc = ssb_crc8(crc, sprom[word] & 0x00FF);
5298+ crc = ssb_crc8(crc, (sprom[word] & 0xFF00) >> 8);
5299+ }
5300+ crc = ssb_crc8(crc, sprom[SPOFF(SSB_SPROM_REVISION)] & 0x00FF);
5301+ crc ^= 0xFF;
5302+
5303+ return crc;
5304+}
5305+
5306+static int sprom_check_crc(const u16 *sprom)
5307+{
5308+ u8 crc;
5309+ u8 expected_crc;
5310+ u16 tmp;
5311+
5312+ crc = ssb_sprom_crc(sprom);
5313+ tmp = sprom[SPOFF(SSB_SPROM_REVISION)] & SSB_SPROM_REVISION_CRC;
5314+ expected_crc = tmp >> SSB_SPROM_REVISION_CRC_SHIFT;
5315+ if (crc != expected_crc)
5316+ return -EPROTO;
5317+
5318+ return 0;
5319+}
5320+
5321+static void sprom_do_read(struct ssb_bus *bus, u16 *sprom)
5322+{
5323+ int i;
5324+
5325+ for (i = 0; i < SSB_SPROMSIZE_WORDS; i++)
5326+ sprom[i] = ssb_raw_read16(bus, SSB_SPROM_BASE + (i * 2));
5327+}
5328+
5329+static void sprom_extract_r1(struct ssb_sprom_r1 *out, const u16 *in)
5330+{
5331+ int i;
5332+ u16 v;
5333+
5334+ SPEX(pci_spid, SSB_SPROM1_SPID, 0xFFFF, 0);
5335+ SPEX(pci_svid, SSB_SPROM1_SVID, 0xFFFF, 0);
5336+ SPEX(pci_pid, SSB_SPROM1_PID, 0xFFFF, 0);
5337+ for (i = 0; i < 3; i++) {
5338+ v = in[SPOFF(SSB_SPROM1_IL0MAC) + i];
5339+ *(((u16 *)out->il0mac) + i) = cpu_to_be16(v);
5340+ }
5341+ for (i = 0; i < 3; i++) {
5342+ v = in[SPOFF(SSB_SPROM1_ET0MAC) + i];
5343+ *(((u16 *)out->et0mac) + i) = cpu_to_be16(v);
5344+ }
5345+ for (i = 0; i < 3; i++) {
5346+ v = in[SPOFF(SSB_SPROM1_ET1MAC) + i];
5347+ *(((u16 *)out->et1mac) + i) = cpu_to_be16(v);
5348+ }
5349+ SPEX(et0phyaddr, SSB_SPROM1_ETHPHY, SSB_SPROM1_ETHPHY_ET0A, 0);
5350+ SPEX(et1phyaddr, SSB_SPROM1_ETHPHY, SSB_SPROM1_ETHPHY_ET1A,
5351+ SSB_SPROM1_ETHPHY_ET1A_SHIFT);
5352+ SPEX(et0mdcport, SSB_SPROM1_ETHPHY, SSB_SPROM1_ETHPHY_ET0M, 14);
5353+ SPEX(et1mdcport, SSB_SPROM1_ETHPHY, SSB_SPROM1_ETHPHY_ET1M, 15);
5354+ SPEX(board_rev, SSB_SPROM1_BINF, SSB_SPROM1_BINF_BREV, 0);
5355+ SPEX(country_code, SSB_SPROM1_BINF, SSB_SPROM1_BINF_CCODE,
5356+ SSB_SPROM1_BINF_CCODE_SHIFT);
5357+ SPEX(antenna_a, SSB_SPROM1_BINF, SSB_SPROM1_BINF_ANTA,
5358+ SSB_SPROM1_BINF_ANTA_SHIFT);
5359+ SPEX(antenna_bg, SSB_SPROM1_BINF, SSB_SPROM1_BINF_ANTBG,
5360+ SSB_SPROM1_BINF_ANTBG_SHIFT);
5361+ SPEX(pa0b0, SSB_SPROM1_PA0B0, 0xFFFF, 0);
5362+ SPEX(pa0b1, SSB_SPROM1_PA0B1, 0xFFFF, 0);
5363+ SPEX(pa0b2, SSB_SPROM1_PA0B2, 0xFFFF, 0);
5364+ SPEX(pa1b0, SSB_SPROM1_PA1B0, 0xFFFF, 0);
5365+ SPEX(pa1b1, SSB_SPROM1_PA1B1, 0xFFFF, 0);
5366+ SPEX(pa1b2, SSB_SPROM1_PA1B2, 0xFFFF, 0);
5367+ SPEX(gpio0, SSB_SPROM1_GPIOA, SSB_SPROM1_GPIOA_P0, 0);
5368+ SPEX(gpio1, SSB_SPROM1_GPIOA, SSB_SPROM1_GPIOA_P1,
5369+ SSB_SPROM1_GPIOA_P1_SHIFT);
5370+ SPEX(gpio2, SSB_SPROM1_GPIOB, SSB_SPROM1_GPIOB_P2, 0);
5371+ SPEX(gpio3, SSB_SPROM1_GPIOB, SSB_SPROM1_GPIOB_P3,
5372+ SSB_SPROM1_GPIOB_P3_SHIFT);
5373+ SPEX(maxpwr_a, SSB_SPROM1_MAXPWR, SSB_SPROM1_MAXPWR_A, 0);
5374+ SPEX(maxpwr_bg, SSB_SPROM1_MAXPWR, SSB_SPROM1_MAXPWR_BG,
5375+ SSB_SPROM1_MAXPWR_BG_SHIFT);
5376+ SPEX(itssi_a, SSB_SPROM1_ITSSI, SSB_SPROM1_ITSSI_A, 0);
5377+ SPEX(itssi_bg, SSB_SPROM1_ITSSI, SSB_SPROM1_ITSSI_BG,
5378+ SSB_SPROM1_ITSSI_BG_SHIFT);
5379+ SPEX(boardflags_lo, SSB_SPROM1_BFLLO, 0xFFFF, 0);
5380+ SPEX(antenna_gain_a, SSB_SPROM1_AGAIN, SSB_SPROM1_AGAIN_A, 0);
5381+ SPEX(antenna_gain_bg, SSB_SPROM1_AGAIN, SSB_SPROM1_AGAIN_BG,
5382+ SSB_SPROM1_AGAIN_BG_SHIFT);
5383+ for (i = 0; i < 4; i++) {
5384+ v = in[SPOFF(SSB_SPROM1_OEM) + i];
5385+ *(((u16 *)out->oem) + i) = cpu_to_le16(v);
5386+ }
5387+}
5388+
5389+static void sprom_extract_r2(struct ssb_sprom_r2 *out, const u16 *in)
5390+{
5391+ int i;
5392+ u16 v;
5393+
5394+ SPEX(boardflags_hi, SSB_SPROM2_BFLHI, 0xFFFF, 0);
5395+ SPEX(maxpwr_a_hi, SSB_SPROM2_MAXP_A, SSB_SPROM2_MAXP_A_HI, 0);
5396+ SPEX(maxpwr_a_lo, SSB_SPROM2_MAXP_A, SSB_SPROM2_MAXP_A_LO,
5397+ SSB_SPROM2_MAXP_A_LO_SHIFT);
5398+ SPEX(pa1lob0, SSB_SPROM2_PA1LOB0, 0xFFFF, 0);
5399+ SPEX(pa1lob1, SSB_SPROM2_PA1LOB1, 0xFFFF, 0);
5400+ SPEX(pa1lob2, SSB_SPROM2_PA1LOB2, 0xFFFF, 0);
5401+ SPEX(pa1hib0, SSB_SPROM2_PA1HIB0, 0xFFFF, 0);
5402+ SPEX(pa1hib1, SSB_SPROM2_PA1HIB1, 0xFFFF, 0);
5403+ SPEX(pa1hib2, SSB_SPROM2_PA1HIB2, 0xFFFF, 0);
5404+ SPEX(ofdm_pwr_off, SSB_SPROM2_OPO, SSB_SPROM2_OPO_VALUE, 0);
5405+ for (i = 0; i < 4; i++) {
5406+ v = in[SPOFF(SSB_SPROM2_CCODE) + i];
5407+ *(((u16 *)out->country_str) + i) = cpu_to_le16(v);
5408+ }
5409+}
5410+
5411+static void sprom_extract_r3(struct ssb_sprom_r3 *out, const u16 *in)
5412+{
5413+ out->ofdmapo = (in[SPOFF(SSB_SPROM3_OFDMAPO) + 0] & 0xFF00) >> 8;
5414+ out->ofdmapo |= (in[SPOFF(SSB_SPROM3_OFDMAPO) + 0] & 0x00FF) << 8;
5415+ out->ofdmapo <<= 16;
5416+ out->ofdmapo |= (in[SPOFF(SSB_SPROM3_OFDMAPO) + 1] & 0xFF00) >> 8;
5417+ out->ofdmapo |= (in[SPOFF(SSB_SPROM3_OFDMAPO) + 1] & 0x00FF) << 8;
5418+
5419+ out->ofdmalpo = (in[SPOFF(SSB_SPROM3_OFDMALPO) + 0] & 0xFF00) >> 8;
5420+ out->ofdmalpo |= (in[SPOFF(SSB_SPROM3_OFDMALPO) + 0] & 0x00FF) << 8;
5421+ out->ofdmalpo <<= 16;
5422+ out->ofdmalpo |= (in[SPOFF(SSB_SPROM3_OFDMALPO) + 1] & 0xFF00) >> 8;
5423+ out->ofdmalpo |= (in[SPOFF(SSB_SPROM3_OFDMALPO) + 1] & 0x00FF) << 8;
5424+
5425+ out->ofdmahpo = (in[SPOFF(SSB_SPROM3_OFDMAHPO) + 0] & 0xFF00) >> 8;
5426+ out->ofdmahpo |= (in[SPOFF(SSB_SPROM3_OFDMAHPO) + 0] & 0x00FF) << 8;
5427+ out->ofdmahpo <<= 16;
5428+ out->ofdmahpo |= (in[SPOFF(SSB_SPROM3_OFDMAHPO) + 1] & 0xFF00) >> 8;
5429+ out->ofdmahpo |= (in[SPOFF(SSB_SPROM3_OFDMAHPO) + 1] & 0x00FF) << 8;
5430+
5431+ SPEX(gpioldc_on_cnt, SSB_SPROM3_GPIOLDC, SSB_SPROM3_GPIOLDC_ON,
5432+ SSB_SPROM3_GPIOLDC_ON_SHIFT);
5433+ SPEX(gpioldc_off_cnt, SSB_SPROM3_GPIOLDC, SSB_SPROM3_GPIOLDC_OFF,
5434+ SSB_SPROM3_GPIOLDC_OFF_SHIFT);
5435+ SPEX(cckpo_1M, SSB_SPROM3_CCKPO, SSB_SPROM3_CCKPO_1M, 0);
5436+ SPEX(cckpo_2M, SSB_SPROM3_CCKPO, SSB_SPROM3_CCKPO_2M,
5437+ SSB_SPROM3_CCKPO_2M_SHIFT);
5438+ SPEX(cckpo_55M, SSB_SPROM3_CCKPO, SSB_SPROM3_CCKPO_55M,
5439+ SSB_SPROM3_CCKPO_55M_SHIFT);
5440+ SPEX(cckpo_11M, SSB_SPROM3_CCKPO, SSB_SPROM3_CCKPO_11M,
5441+ SSB_SPROM3_CCKPO_11M_SHIFT);
5442+
5443+ out->ofdmgpo = (in[SPOFF(SSB_SPROM3_OFDMGPO) + 0] & 0xFF00) >> 8;
5444+ out->ofdmgpo |= (in[SPOFF(SSB_SPROM3_OFDMGPO) + 0] & 0x00FF) << 8;
5445+ out->ofdmgpo <<= 16;
5446+ out->ofdmgpo |= (in[SPOFF(SSB_SPROM3_OFDMGPO) + 1] & 0xFF00) >> 8;
5447+ out->ofdmgpo |= (in[SPOFF(SSB_SPROM3_OFDMGPO) + 1] & 0x00FF) << 8;
5448+}
5449+
5450+static int sprom_extract(struct ssb_sprom *out, const u16 *in)
5451+{
5452+ memset(out, 0, sizeof(*out));
5453+
5454+ SPEX(revision, SSB_SPROM_REVISION, SSB_SPROM_REVISION_REV, 0);
5455+ SPEX(crc, SSB_SPROM_REVISION, SSB_SPROM_REVISION_CRC,
5456+ SSB_SPROM_REVISION_CRC_SHIFT);
5457+
5458+ if (out->revision == 0)
5459+ goto err_unsup;
5460+ if (out->revision >= 1 && out->revision <= 3)
5461+ sprom_extract_r1(&out->r1, in);
5462+ if (out->revision >= 2 && out->revision <= 3)
5463+ sprom_extract_r2(&out->r2, in);
5464+ if (out->revision == 3)
5465+ sprom_extract_r3(&out->r3, in);
5466+ if (out->revision >= 4)
5467+ goto err_unsup;
5468+
5469+ return 0;
5470+err_unsup:
5471+ ssb_printk("ERROR: Unsupported SPROM revision %d\n",
5472+ out->revision);
5473+ return -EOPNOTSUPP;
5474+}
5475+
5476+int ssb_pci_sprom_get(struct ssb_bus *bus)
5477+{
5478+ int err = -ENOMEM;
5479+ u16 *buf;
5480+
5481+ assert(bus->bustype == SSB_BUSTYPE_PCI);
5482+
5483+ buf = kcalloc(SSB_SPROMSIZE_WORDS, sizeof(u16), GFP_KERNEL);
5484+ if (!buf)
5485+ goto out;
5486+ sprom_do_read(bus, buf);
5487+ err = sprom_check_crc(buf);
5488+ if (err)
5489+ ssb_printk("WARNING: Invalid SPROM CRC (corrupt SPROM)\n");
5490+ err = sprom_extract(&bus->sprom, buf);
5491+
5492+ kfree(buf);
5493+out:
5494+ return err;
5495+}
5496diff -Nru linux-2.6.19.ori/drivers/ssb/scan.c linux-2.6.19/drivers/ssb/scan.c
5497--- linux-2.6.19.ori/drivers/ssb/scan.c 1970-01-01 01:00:00.000000000 +0100
5498+++ linux-2.6.19/drivers/ssb/scan.c 2006-12-02 19:14:34.000000000 +0100
5499@@ -0,0 +1,284 @@
5500+#include <linux/ssb.h>
5501+#include <linux/ssb_regs.h>
5502+#include <linux/pci.h>
5503+#include <asm/io.h>
5504+
5505+#include "ssb_private.h"
5506+
5507+
5508+static const char * ssb_core_name(u16 coreid)
5509+{
5510+ switch (coreid) {
5511+ case SSB_DEV_CHIPCOMMON:
5512+ return "ChipCommon";
5513+ case SSB_DEV_ILINE20:
5514+ return "ILine 20";
5515+ case SSB_DEV_SDRAM:
5516+ return "SDRAM";
5517+ case SSB_DEV_PCI:
5518+ return "PCI";
5519+ case SSB_DEV_MIPS:
5520+ return "MIPS";
5521+ case SSB_DEV_ETHERNET:
5522+ return "Fast Ethernet";
5523+ case SSB_DEV_V90:
5524+ return "V90";
5525+ case SSB_DEV_USB11_HOSTDEV:
5526+ return "USB 1.1 Hostdev";
5527+ case SSB_DEV_ADSL:
5528+ return "ADSL";
5529+ case SSB_DEV_ILINE100:
5530+ return "ILine 100";
5531+ case SSB_DEV_IPSEC:
5532+ return "IPSEC";
5533+ case SSB_DEV_PCMCIA:
5534+ return "PCMCIA";
5535+ case SSB_DEV_INTERNAL_MEM:
5536+ return "Internal Memory";
5537+ case SSB_DEV_MEMC_SDRAM:
5538+ return "MEMC SDRAM";
5539+ case SSB_DEV_EXTIF:
5540+ return "EXTIF";
5541+ case SSB_DEV_80211:
5542+ return "IEEE 802.11";
5543+ case SSB_DEV_MIPS_3302:
5544+ return "MIPS 3302";
5545+ case SSB_DEV_USB11_HOST:
5546+ return "USB 1.1 Host";
5547+ case SSB_DEV_USB11_DEV:
5548+ return "USB 1.1 Device";
5549+ case SSB_DEV_USB20_HOST:
5550+ return "USB 2.0 Host";
5551+ case SSB_DEV_USB20_DEV:
5552+ return "USB 2.0 Device";
5553+ case SSB_DEV_SDIO_HOST:
5554+ return "SDIO Host";
5555+ case SSB_DEV_ROBOSWITCH:
5556+ return "Roboswitch";
5557+ case SSB_DEV_PARA_ATA:
5558+ return "PATA";
5559+ case SSB_DEV_SATA_XORDMA:
5560+ return "SATA XOR-DMA";
5561+ case SSB_DEV_ETHERNET_GBIT:
5562+ return "GBit Ethernet";
5563+ case SSB_DEV_PCIE:
5564+ return "PCI-E";
5565+ case SSB_DEV_MIMO_PHY:
5566+ return "MIMO PHY";
5567+ case SSB_DEV_SRAM_CTRLR:
5568+ return "SRAM Controller";
5569+ case SSB_DEV_MINI_MACPHY:
5570+ return "Mini MACPHY";
5571+ case SSB_DEV_ARM_1176:
5572+ return "ARM 1176";
5573+ case SSB_DEV_ARM_7TDMI:
5574+ return "ARM 7TDMI";
5575+ }
5576+ return "Unknown CoreID";
5577+}
5578+
5579+static u16 pcidev_to_chipid(struct pci_dev *pci_dev)
5580+{
5581+ u16 chipid_fallback = 0;
5582+
5583+ switch (pci_dev->device) {
5584+ case 0x4301:
5585+ chipid_fallback = 0x4301;
5586+ break;
5587+ case 0x4305 ... 0x4307:
5588+ chipid_fallback = 0x4307;
5589+ break;
5590+ case 0x4402 ... 0x4403:
5591+ chipid_fallback = 0x4402;
5592+ break;
5593+ case 0x4610 ... 0x4615:
5594+ chipid_fallback = 0x4610;
5595+ break;
5596+ case 0x4710 ... 0x4715:
5597+ chipid_fallback = 0x4710;
5598+ break;
5599+ case 0x4320 ... 0x4325:
5600+ chipid_fallback = 0x4309;
5601+ break;
5602+ default:
5603+ ssb_printk("PCI-ID not in fallback list\n");
5604+ }
5605+
5606+ return chipid_fallback;
5607+}
5608+
5609+static u8 chipid_to_nrcores(u16 chipid)
5610+{
5611+ switch (chipid) {
5612+ case 0x5365:
5613+ return 7;
5614+ case 0x4306:
5615+ return 6;
5616+ case 0x4310:
5617+ return 8;
5618+ case 0x4307:
5619+ case 0x4301:
5620+ return 5;
5621+ case 0x4402:
5622+ return 3;
5623+ case 0x4710:
5624+ case 0x4610:
5625+ case 0x4704:
5626+ return 9;
5627+ default:
5628+ ssb_printk("CHIPID not found in nrcores fallback list\n");
5629+ }
5630+ return 1;
5631+}
5632+
5633+static u32 scan_read32(struct ssb_bus *bus, u8 current_coreidx,
5634+ u16 offset)
5635+{
5636+ if (bus->bustype == SSB_BUSTYPE_SSB)
5637+ offset += current_coreidx * SSB_CORE_SIZE;
5638+ return ssb_raw_read32(bus, offset);
5639+}
5640+
5641+static int scan_switchcore(struct ssb_bus *bus, u8 coreidx)
5642+{
5643+ switch (bus->bustype) {
5644+ case SSB_BUSTYPE_SSB:
5645+ break;
5646+ case SSB_BUSTYPE_PCI:
5647+ return ssb_pci_switch_coreidx(bus, coreidx);
5648+ default:
5649+ assert(0);
5650+ }
5651+ return 0;
5652+}
5653+
5654+int ssb_bus_scan(struct ssb_bus *bus,
5655+ unsigned long baseaddr)
5656+{
5657+ int err = -ENOMEM;
5658+ void __iomem *mmio;
5659+ u32 idhi, cc, rev, tmp;
5660+ int i;
5661+ struct ssb_device *dev;
5662+
5663+ if (bus->bustype == SSB_BUSTYPE_SSB) {
5664+ /* Only map the first core for now. */
5665+ mmio = ioremap(baseaddr, SSB_CORE_SIZE);
5666+ } else {
5667+ assert(bus->host_pci);
5668+ mmio = pci_iomap(bus->host_pci, 0, ~0UL);
5669+ }
5670+ if (!mmio)
5671+ goto out;
5672+ bus->mmio = mmio;
5673+
5674+ err = scan_switchcore(bus, 0); /* Switch to first core */
5675+ if (err)
5676+ goto err_unmap;
5677+
5678+ idhi = scan_read32(bus, 0, SSB_IDHIGH);
5679+ cc = (idhi & SSB_IDHIGH_CC) >> SSB_IDHIGH_CC_SHIFT;
5680+ rev = (idhi & SSB_IDHIGH_RCLO);
5681+ rev |= (idhi & SSB_IDHIGH_RCHI) >> SSB_IDHIGH_RCHI_SHIFT;
5682+
5683+ bus->nr_devices = 0;
5684+ if (cc == SSB_DEV_CHIPCOMMON) {
5685+ tmp = scan_read32(bus, 0, SSB_CHIPCO_CHIPID);
5686+
5687+ bus->chip_id = (tmp & SSB_CHIPCO_IDMASK);
5688+ bus->chip_rev = (tmp & SSB_CHIPCO_REVMASK) >>
5689+ SSB_CHIPCO_REVSHIFT;
5690+ bus->chip_package = (tmp & SSB_CHIPCO_PACKMASK) >>
5691+ SSB_CHIPCO_PACKSHIFT;
5692+ if (rev >= 4) {
5693+ bus->nr_devices = (tmp & SSB_CHIPCO_NRCORESMASK) >>
5694+ SSB_CHIPCO_NRCORESSHIFT;
5695+ }
5696+ tmp = scan_read32(bus, 0, SSB_CHIPCO_CAP);
5697+ bus->chipco.capabilities = tmp;
5698+ } else {
5699+ if (bus->bustype == SSB_BUSTYPE_SSB) {
5700+ bus->chip_id = 0x4710;
5701+ bus->chip_rev = 0;
5702+ bus->chip_package = 0;
5703+ } else {
5704+ bus->chip_id = pcidev_to_chipid(bus->host_pci);
5705+ pci_read_config_word(bus->host_pci, PCI_REVISION_ID,
5706+ &bus->chip_rev);
5707+ bus->chip_package = 0;
5708+ }
5709+ }
5710+ if (!bus->nr_devices)
5711+ bus->nr_devices = chipid_to_nrcores(bus->chip_id);
5712+ if (bus->nr_devices > ARRAY_SIZE(bus->devices)) {
5713+ ssb_printk("ERR: More than %d ssb cores found (%d)\n",
5714+ SSB_MAX_NR_CORES, bus->nr_devices);
5715+ goto err_unmap;
5716+ }
5717+ if (bus->bustype == SSB_BUSTYPE_SSB) {
5718+ /* Now that we know the number of cores,
5719+ * remap the whole IO space for all cores.
5720+ */
5721+ err = -ENOMEM;
5722+ iounmap(mmio);
5723+ mmio = ioremap(baseaddr, SSB_CORE_SIZE * bus->nr_devices);
5724+ if (!mmio)
5725+ goto out;
5726+ bus->mmio = mmio;
5727+ }
5728+
5729+ /* Fetch basic information about each core/device */
5730+ for (i = 0; i < bus->nr_devices; i++) {
5731+ err = scan_switchcore(bus, i);
5732+ if (err)
5733+ goto err_unmap;
5734+ dev = &(bus->devices[i]);
5735+
5736+ idhi = scan_read32(bus, i, SSB_IDHIGH);
5737+ dev->id.coreid = (idhi & SSB_IDHIGH_CC) >> SSB_IDHIGH_CC_SHIFT;
5738+ dev->id.revision = (idhi & SSB_IDHIGH_RCLO);
5739+ dev->id.revision |= (idhi & SSB_IDHIGH_RCHI) >> SSB_IDHIGH_RCHI_SHIFT;
5740+ dev->id.vendor = (idhi & SSB_IDHIGH_VC) >> SSB_IDHIGH_VC_SHIFT;
5741+ dev->core_index = i;
5742+ dev->bus = bus;
5743+ if ((dev->bus->bustype == SSB_BUSTYPE_PCI) && (bus->host_pci))
5744+ dev->irq = bus->host_pci->irq;
5745+
5746+ ssb_printk("Core %d found: %s "
5747+ "(cc 0x%03X, rev 0x%02X, vendor 0x%04X)\n",
5748+ i, ssb_core_name(dev->id.coreid),
5749+ dev->id.coreid, dev->id.revision, dev->id.vendor);
5750+
5751+ dev->dev.bus = &ssb_bustype;
5752+ snprintf(dev->dev.bus_id, sizeof(dev->dev.bus_id),
5753+ "ssb%02x:%02x", bus->busnumber, i);
5754+
5755+ switch (dev->id.coreid) {
5756+ case SSB_DEV_CHIPCOMMON:
5757+ if (bus->chipco.dev) {
5758+ ssb_printk("WARNING: Multiple Chipcommon found\n");
5759+ break;
5760+ }
5761+ bus->chipco.dev = dev;
5762+ break;
5763+ case SSB_DEV_MIPS:
5764+ case SSB_DEV_MIPS_3302:
5765+ if (bus->mipscore.dev) {
5766+ ssb_printk("WARNING: Multiple MIPS cores found\n");
5767+ break;
5768+ }
5769+ bus->mipscore.dev = dev;
5770+ default:
5771+ break;
5772+ }
5773+ }
5774+ err = 0;
5775+out:
5776+ return err;
5777+err_unmap:
5778+ if (bus->bustype == SSB_BUSTYPE_SSB)
5779+ iounmap(mmio);
5780+ else
5781+ pci_iounmap(bus->host_pci, mmio);
5782+ goto out;
5783+}
5784diff -Nru linux-2.6.19.ori/drivers/ssb/sprom.c linux-2.6.19/drivers/ssb/sprom.c
5785--- linux-2.6.19.ori/drivers/ssb/sprom.c 1970-01-01 01:00:00.000000000 +0100
5786+++ linux-2.6.19/drivers/ssb/sprom.c 2006-12-02 19:14:34.000000000 +0100
5787@@ -0,0 +1 @@
5788+
5789diff -Nru linux-2.6.19.ori/drivers/ssb/ssb_private.h linux-2.6.19/drivers/ssb/ssb_private.h
5790--- linux-2.6.19.ori/drivers/ssb/ssb_private.h 1970-01-01 01:00:00.000000000 +0100
5791+++ linux-2.6.19/drivers/ssb/ssb_private.h 2006-12-02 19:14:34.000000000 +0100
5792@@ -0,0 +1,106 @@
5793+#ifndef LINUX_SSB_PRIVATE_H_
5794+#define LINUX_SSB_PRIVATE_H_
5795+
5796+#include <linux/ssb.h>
5797+#include <linux/types.h>
5798+#include <asm/io.h>
5799+
5800+#ifdef CONFIG_CFE
5801+# include <asm/cfe.h>
5802+#endif
5803+
5804+
5805+#define PFX "ssb: "
5806+
5807+#ifdef CONFIG_SSB_SILENT
5808+# define ssb_printk(fmt, x...) do { /* nothing */ } while (0)
5809+#else
5810+/* SSB specific printk. If CFE is available, this can be used in early boot.
5811+ * But it does not harm otherwise. It just does not print anything.
5812+ */
5813+int __ssb_printk(const char *fmt, ...) __attribute__((format(printf, 1, 2)));
5814+# define ssb_printk(fmt, x...) __ssb_printk(PFX fmt ,##x)
5815+#endif /* CONFIG_SSB_SILENT */
5816+
5817+/* dprintk: Debugging printk; vanishes for non-debug compilation */
5818+#ifdef CONFIG_SSB_DEBUG
5819+# define ssb_dprintk(fmt, x...) ssb_printk(fmt ,##x)
5820+#else
5821+# define ssb_dprintk(fmt, x...) do { /* nothing */ } while (0)
5822+#endif
5823+
5824+/* printkl: Rate limited printk */
5825+#define ssb_printkl(fmt, x...) do { \
5826+ if (printk_ratelimit()) \
5827+ ssb_printk(fmt ,##x); \
5828+ } while (0)
5829+
5830+/* dprintkl: Rate limited debugging printk */
5831+#ifdef CONFIG_SSB_DEBUG
5832+# define ssb_dprintkl ssb_printkl
5833+#else
5834+# define ssb_dprintkl(fmt, x...) do { /* nothing */ } while (0)
5835+#endif
5836+
5837+#define assert(cond) do { \
5838+ if (unlikely(!(cond))) { \
5839+ ssb_dprintk(KERN_ERR PFX "BUG: Assertion failed (%s) " \
5840+ "at: %s:%d:%s()\n", \
5841+ #cond, __FILE__, __LINE__, __func__); \
5842+ } \
5843+ } while (0)
5844+
5845+
5846+extern struct bus_type ssb_bustype;
5847+
5848+/* pci.c */
5849+extern int ssb_pci_switch_core(struct ssb_bus *bus,
5850+ struct ssb_device *dev);
5851+extern int ssb_pci_switch_coreidx(struct ssb_bus *bus,
5852+ u8 coreidx);
5853+extern int ssb_pci_xtal(struct ssb_bus *bus, u32 what,
5854+ int turn_on);
5855+extern int ssb_pci_sprom_get(struct ssb_bus *bus);
5856+
5857+
5858+/* scan.c */
5859+extern int ssb_bus_scan(struct ssb_bus *bus,
5860+ unsigned long baseaddr);
5861+
5862+
5863+/* core.c */
5864+extern u32 ssb_calc_clock_rate(u32 plltype, u32 n, u32 m);
5865+
5866+static inline
5867+u16 ssb_raw_read16(struct ssb_bus *bus, u16 offset)
5868+{
5869+ return readw(bus->mmio + offset);
5870+}
5871+
5872+static inline
5873+u32 ssb_raw_read32(struct ssb_bus *bus, u16 offset)
5874+{
5875+ return readl(bus->mmio + offset);
5876+}
5877+
5878+static inline
5879+void ssb_raw_write16(struct ssb_bus *bus, u16 offset, u16 value)
5880+{
5881+ writew(value, bus->mmio + offset);
5882+}
5883+
5884+static inline
5885+void ssb_raw_write32(struct ssb_bus *bus, u16 offset, u32 value)
5886+{
5887+ writel(value, bus->mmio + offset);
5888+}
5889+
5890+
5891+static inline
5892+unsigned long ceildiv(unsigned long x, unsigned long y)
5893+{
5894+ return ((x + (y - 1)) / y);
5895+}
5896+
5897+
5898+#endif /* LINUX_SSB_PRIVATE_H_ */
5899diff -Nru linux-2.6.19.ori/include/asm-mips/asm-offsets.h linux-2.6.19/include/asm-mips/asm-offsets.h
5900--- linux-2.6.19.ori/include/asm-mips/asm-offsets.h 1970-01-01 01:00:00.000000000 +0100
5901+++ linux-2.6.19/include/asm-mips/asm-offsets.h 2006-12-02 23:16:42.000000000 +0100
5902@@ -0,0 +1,214 @@
5903+#ifndef __ASM_OFFSETS_H__
5904+#define __ASM_OFFSETS_H__
5905+/*
5906+ * DO NOT MODIFY.
5907+ *
5908+ * This file was generated by Kbuild
5909+ *
5910+ */
5911+
5912+/* MIPS pt_regs offsets. */
5913+#define PT_R0 24
5914+#define PT_R1 28
5915+#define PT_R2 32
5916+#define PT_R3 36
5917+#define PT_R4 40
5918+#define PT_R5 44
5919+#define PT_R6 48
5920+#define PT_R7 52
5921+#define PT_R8 56
5922+#define PT_R9 60
5923+#define PT_R10 64
5924+#define PT_R11 68
5925+#define PT_R12 72
5926+#define PT_R13 76
5927+#define PT_R14 80
5928+#define PT_R15 84
5929+#define PT_R16 88
5930+#define PT_R17 92
5931+#define PT_R18 96
5932+#define PT_R19 100
5933+#define PT_R20 104
5934+#define PT_R21 108
5935+#define PT_R22 112
5936+#define PT_R23 116
5937+#define PT_R24 120
5938+#define PT_R25 124
5939+#define PT_R26 128
5940+#define PT_R27 132
5941+#define PT_R28 136
5942+#define PT_R29 140
5943+#define PT_R30 144
5944+#define PT_R31 148
5945+#define PT_LO 160
5946+#define PT_HI 156
5947+#define PT_EPC 172
5948+#define PT_BVADDR 164
5949+#define PT_STATUS 152
5950+#define PT_CAUSE 168
5951+#define PT_SIZE 176
5952+
5953+/* MIPS task_struct offsets. */
5954+#define TASK_STATE 0
5955+#define TASK_THREAD_INFO 4
5956+#define TASK_FLAGS 12
5957+#define TASK_MM 132
5958+#define TASK_PID 168
5959+#define TASK_STRUCT_SIZE 1048
5960+
5961+/* MIPS thread_info offsets. */
5962+#define TI_TASK 0
5963+#define TI_EXEC_DOMAIN 4
5964+#define TI_FLAGS 8
5965+#define TI_TP_VALUE 12
5966+#define TI_CPU 16
5967+#define TI_PRE_COUNT 20
5968+#define TI_ADDR_LIMIT 24
5969+#define TI_RESTART_BLOCK 28
5970+#define TI_REGS 48
5971+#define _THREAD_SIZE_ORDER 0x1
5972+#define _THREAD_SIZE 0x2000
5973+#define _THREAD_MASK 0x1fff
5974+
5975+/* MIPS specific thread_struct offsets. */
5976+#define THREAD_REG16 432
5977+#define THREAD_REG17 436
5978+#define THREAD_REG18 440
5979+#define THREAD_REG19 444
5980+#define THREAD_REG20 448
5981+#define THREAD_REG21 452
5982+#define THREAD_REG22 456
5983+#define THREAD_REG23 460
5984+#define THREAD_REG29 464
5985+#define THREAD_REG30 468
5986+#define THREAD_REG31 472
5987+#define THREAD_STATUS 476
5988+#define THREAD_FPU 480
5989+#define THREAD_BVADDR 772
5990+#define THREAD_BUADDR 776
5991+#define THREAD_ECODE 780
5992+#define THREAD_TRAPNO 784
5993+#define THREAD_MFLAGS 788
5994+#define THREAD_TRAMP 792
5995+#define THREAD_OLDCTX 796
5996+
5997+#define THREAD_FPR0 480
5998+#define THREAD_FPR1 488
5999+#define THREAD_FPR2 496
6000+#define THREAD_FPR3 504
6001+#define THREAD_FPR4 512
6002+#define THREAD_FPR5 520
6003+#define THREAD_FPR6 528
6004+#define THREAD_FPR7 536
6005+#define THREAD_FPR8 544
6006+#define THREAD_FPR9 552
6007+#define THREAD_FPR10 560
6008+#define THREAD_FPR11 568
6009+#define THREAD_FPR12 576
6010+#define THREAD_FPR13 584
6011+#define THREAD_FPR14 592
6012+#define THREAD_FPR15 600
6013+#define THREAD_FPR16 608
6014+#define THREAD_FPR17 616
6015+#define THREAD_FPR18 624
6016+#define THREAD_FPR19 632
6017+#define THREAD_FPR20 640
6018+#define THREAD_FPR21 648
6019+#define THREAD_FPR22 656
6020+#define THREAD_FPR23 664
6021+#define THREAD_FPR24 672
6022+#define THREAD_FPR25 680
6023+#define THREAD_FPR26 688
6024+#define THREAD_FPR27 696
6025+#define THREAD_FPR28 704
6026+#define THREAD_FPR29 712
6027+#define THREAD_FPR30 720
6028+#define THREAD_FPR31 728
6029+#define THREAD_FCR31 736
6030+
6031+/* Linux sigcontext offsets. */
6032+#define SC_REGS 16
6033+#define SC_FPREGS 272
6034+#define SC_MDHI 552
6035+#define SC_MDLO 560
6036+#define SC_PC 8
6037+#define SC_STATUS 4
6038+#define SC_FPC_CSR 532
6039+#define SC_FPC_EIR 536
6040+#define SC_HI1 568
6041+#define SC_LO1 572
6042+#define SC_HI2 576
6043+#define SC_LO2 580
6044+#define SC_HI3 584
6045+#define SC_LO3 588
6046+
6047+/* Linux signal numbers. */
6048+#define _SIGHUP 0x1
6049+#define _SIGINT 0x2
6050+#define _SIGQUIT 0x3
6051+#define _SIGILL 0x4
6052+#define _SIGTRAP 0x5
6053+#define _SIGIOT 0x6
6054+#define _SIGABRT 0x6
6055+#define _SIGEMT 0x7
6056+#define _SIGFPE 0x8
6057+#define _SIGKILL 0x9
6058+#define _SIGBUS 0xa
6059+#define _SIGSEGV 0xb
6060+#define _SIGSYS 0xc
6061+#define _SIGPIPE 0xd
6062+#define _SIGALRM 0xe
6063+#define _SIGTERM 0xf
6064+#define _SIGUSR1 0x10
6065+#define _SIGUSR2 0x11
6066+#define _SIGCHLD 0x12
6067+#define _SIGPWR 0x13
6068+#define _SIGWINCH 0x14
6069+#define _SIGURG 0x15
6070+#define _SIGIO 0x16
6071+#define _SIGSTOP 0x17
6072+#define _SIGTSTP 0x18
6073+#define _SIGCONT 0x19
6074+#define _SIGTTIN 0x1a
6075+#define _SIGTTOU 0x1b
6076+#define _SIGVTALRM 0x1c
6077+#define _SIGPROF 0x1d
6078+#define _SIGXCPU 0x1e
6079+#define _SIGXFSZ 0x1f
6080+
6081+/* Linux irq_cpustat_t offsets. */
6082+#define IC_SOFTIRQ_PENDING 0
6083+#define IC_IRQ_CPUSTAT_T 32
6084+
6085+/* Size of struct page */
6086+#define STRUCT_PAGE_SIZE 32
6087+
6088+/* Linux mm_struct offsets. */
6089+#define MM_USERS 40
6090+#define MM_PGD 36
6091+#define MM_CONTEXT 348
6092+
6093+#define _PAGE_SIZE 0x1000
6094+#define _PAGE_SHIFT 0xc
6095+
6096+#define _PGD_T_SIZE 0x4
6097+#define _PMD_T_SIZE 0x4
6098+#define _PTE_T_SIZE 0x4
6099+
6100+#define _PGD_T_LOG2 $2
6101+#define _PMD_T_LOG2 $2
6102+#define _PTE_T_LOG2 $2
6103+
6104+#define _PMD_SHIFT 0x16
6105+#define _PGDIR_SHIFT 0x16
6106+
6107+#define _PGD_ORDER 0x0
6108+#define _PMD_ORDER 0x1
6109+#define _PTE_ORDER 0x0
6110+
6111+#define _PTRS_PER_PGD 0x400
6112+#define _PTRS_PER_PMD 0x1
6113+#define _PTRS_PER_PTE 0x400
6114+
6115+
6116+#endif
6117diff -Nru linux-2.6.19.ori/include/asm-mips/bootinfo.h linux-2.6.19/include/asm-mips/bootinfo.h
6118--- linux-2.6.19.ori/include/asm-mips/bootinfo.h 2006-12-02 18:55:39.000000000 +0100
6119+++ linux-2.6.19/include/asm-mips/bootinfo.h 2006-12-02 19:14:34.000000000 +0100
6120@@ -212,6 +212,12 @@
6121 #define MACH_GROUP_NEC_EMMA2RH 25 /* NEC EMMA2RH (was 23) */
6122 #define MACH_NEC_MARKEINS 0 /* NEC EMMA2RH Mark-eins */
6123
6124+/*
6125+ * Valid machtype for group Broadcom
6126+ */
6127+#define MACH_GROUP_BRCM 23 /* Broadcom */
6128+#define MACH_BCM47XX 1 /* Broadcom BCM47xx */
6129+
6130 #define CL_SIZE COMMAND_LINE_SIZE
6131
6132 const char *get_system_type(void);
6133diff -Nru linux-2.6.19.ori/include/asm-mips/cfe.h linux-2.6.19/include/asm-mips/cfe.h
6134--- linux-2.6.19.ori/include/asm-mips/cfe.h 1970-01-01 01:00:00.000000000 +0100
6135+++ linux-2.6.19/include/asm-mips/cfe.h 2006-12-02 19:14:34.000000000 +0100
6136@@ -0,0 +1,189 @@
6137+/*
6138+ * Broadcom Common Firmware Environment (CFE) support
6139+ *
6140+ * Copyright 2000, 2001, 2002
6141+ * Broadcom Corporation. All rights reserved.
6142+ *
6143+ * Copyright (C) 2006 Michael Buesch
6144+ *
6145+ * Original Authors: Mitch Lichtenberg, Chris Demetriou
6146+ *
6147+ * This software is furnished under license and may be used and copied only
6148+ * in accordance with the following terms and conditions. Subject to these
6149+ * conditions, you may download, copy, install, use, modify and distribute
6150+ * modified or unmodified copies of this software in source and/or binary
6151+ * form. No title or ownership is transferred hereby.
6152+ *
6153+ * 1) Any source code used, modified or distributed must reproduce and
6154+ * retain this copyright notice and list of conditions as they appear in
6155+ * the source file.
6156+ *
6157+ * 2) No right is granted to use any trade name, trademark, or logo of
6158+ * Broadcom Corporation. The "Broadcom Corporation" name may not be
6159+ * used to endorse or promote products derived from this software
6160+ * without the prior written permission of Broadcom Corporation.
6161+ *
6162+ * 3) THIS SOFTWARE IS PROVIDED "AS-IS" AND ANY EXPRESS OR IMPLIED
6163+ * WARRANTIES, INCLUDING BUT NOT LIMITED TO, ANY IMPLIED WARRANTIES OF
6164+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, OR
6165+ * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL BROADCOM BE LIABLE
6166+ * FOR ANY DAMAGES WHATSOEVER, AND IN PARTICULAR, BROADCOM SHALL NOT BE
6167+ * LIABLE FOR DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
6168+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
6169+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
6170+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
6171+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
6172+ * OR OTHERWISE), EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
6173+ */
6174+
6175+#ifndef LINUX_CFE_API_H_
6176+#define LINUX_CFE_API_H_
6177+
6178+#include <linux/types.h>
6179+
6180+
6181+#define CFE_MI_RESERVED 0 /* memory is reserved, do not use */
6182+#define CFE_MI_AVAILABLE 1 /* memory is available */
6183+
6184+#define CFE_FLG_WARMSTART 0x00000001
6185+#define CFE_FLG_FULL_ARENA 0x00000001
6186+#define CFE_FLG_ENV_PERMANENT 0x00000001
6187+
6188+#define CFE_CPU_CMD_START 1
6189+#define CFE_CPU_CMD_STOP 0
6190+
6191+#define CFE_STDHANDLE_CONSOLE 0
6192+
6193+#define CFE_DEV_NETWORK 1
6194+#define CFE_DEV_DISK 2
6195+#define CFE_DEV_FLASH 3
6196+#define CFE_DEV_SERIAL 4
6197+#define CFE_DEV_CPU 5
6198+#define CFE_DEV_NVRAM 6
6199+#define CFE_DEV_CLOCK 7
6200+#define CFE_DEV_OTHER 8
6201+#define CFE_DEV_MASK 0x0F
6202+
6203+#define CFE_CACHE_FLUSH_D 1
6204+#define CFE_CACHE_INVAL_I 2
6205+#define CFE_CACHE_INVAL_D 4
6206+#define CFE_CACHE_INVAL_L2 8
6207+
6208+#define CFE_FWI_64BIT 0x00000001
6209+#define CFE_FWI_32BIT 0x00000002
6210+#define CFE_FWI_RELOC 0x00000004
6211+#define CFE_FWI_UNCACHED 0x00000008
6212+#define CFE_FWI_MULTICPU 0x00000010
6213+#define CFE_FWI_FUNCSIM 0x00000020
6214+#define CFE_FWI_RTLSIM 0x00000040
6215+
6216+struct cfe_fwinfo {
6217+ s64 version; /* major, minor, eco version */
6218+ s64 totalmem; /* total installed mem */
6219+ s64 flags; /* various flags */
6220+ s64 boardid; /* board ID */
6221+ s64 bootarea_va; /* VA of boot area */
6222+ s64 bootarea_pa; /* PA of boot area */
6223+ s64 bootarea_size; /* size of boot area */
6224+};
6225+
6226+
6227+/* The public CFE API */
6228+
6229+int cfe_present(void); /* Check if we booted from CFE. Returns bool */
6230+
6231+int cfe_getticks(s64 *ticks);
6232+int cfe_close(int handle);
6233+int cfe_cpu_start(int cpu, void (*fn)(void), long sp, long gp, long a1);
6234+int cfe_cpu_stop(int cpu);
6235+int cfe_enumenv(int idx, char *name, int namelen, char *val, int vallen);
6236+int cfe_enumdev(int idx, char *name, int namelen);
6237+int cfe_enummem(int idx, int flags, u64 *start, u64 *length,
6238+ u64 *type);
6239+int cfe_exit(int warm, int status);
6240+int cfe_flushcache(int flags);
6241+int cfe_getdevinfo(char *name);
6242+int cfe_getenv(char *name, char *dest, int destlen);
6243+int cfe_getfwinfo(struct cfe_fwinfo *info);
6244+int cfe_getstdhandle(int handletype);
6245+int cfe_inpstat(int handle);
6246+int cfe_ioctl(int handle, unsigned int ioctlnum, unsigned char *buffer,
6247+ int length, int *retlen, u64 offset);
6248+int cfe_open(char *name);
6249+int cfe_read(int handle, unsigned char *buffer, int length);
6250+int cfe_readblk(int handle, s64 offset, unsigned char *buffer, int length);
6251+int cfe_setenv(char *name, char *val);
6252+int cfe_write(int handle, unsigned char *buffer, int length);
6253+int cfe_writeblk(int handle, s64 offset, unsigned char *buffer,
6254+ int length);
6255+
6256+
6257+/* High level API */
6258+
6259+/* Print some information to CFE's console (most likely serial line) */
6260+int cfe_printk(const char *fmt, ...) __attribute__((format(printf, 1, 2)));
6261+int cfe_vprintk(const char *fmt, va_list args);
6262+
6263+
6264+
6265+/* Error codes returned by the low API functions */
6266+
6267+#define CFE_ISERR(errcode) (errcode < 0)
6268+
6269+#define CFE_OK 0
6270+#define CFE_ERR -1 /* generic error */
6271+#define CFE_ERR_INV_COMMAND -2
6272+#define CFE_ERR_EOF -3
6273+#define CFE_ERR_IOERR -4
6274+#define CFE_ERR_NOMEM -5
6275+#define CFE_ERR_DEVNOTFOUND -6
6276+#define CFE_ERR_DEVOPEN -7
6277+#define CFE_ERR_INV_PARAM -8
6278+#define CFE_ERR_ENVNOTFOUND -9
6279+#define CFE_ERR_ENVREADONLY -10
6280+
6281+#define CFE_ERR_NOTELF -11
6282+#define CFE_ERR_NOT32BIT -12
6283+#define CFE_ERR_WRONGENDIAN -13
6284+#define CFE_ERR_BADELFVERS -14
6285+#define CFE_ERR_NOTMIPS -15
6286+#define CFE_ERR_BADELFFMT -16
6287+#define CFE_ERR_BADADDR -17
6288+
6289+#define CFE_ERR_FILENOTFOUND -18
6290+#define CFE_ERR_UNSUPPORTED -19
6291+
6292+#define CFE_ERR_HOSTUNKNOWN -20
6293+
6294+#define CFE_ERR_TIMEOUT -21
6295+
6296+#define CFE_ERR_PROTOCOLERR -22
6297+
6298+#define CFE_ERR_NETDOWN -23
6299+#define CFE_ERR_NONAMESERVER -24
6300+
6301+#define CFE_ERR_NOHANDLES -25
6302+#define CFE_ERR_ALREADYBOUND -26
6303+
6304+#define CFE_ERR_CANNOTSET -27
6305+#define CFE_ERR_NOMORE -28
6306+#define CFE_ERR_BADFILESYS -29
6307+#define CFE_ERR_FSNOTAVAIL -30
6308+
6309+#define CFE_ERR_INVBOOTBLOCK -31
6310+#define CFE_ERR_WRONGDEVTYPE -32
6311+#define CFE_ERR_BBCHECKSUM -33
6312+#define CFE_ERR_BOOTPROGCHKSUM -34
6313+
6314+#define CFE_ERR_LDRNOTAVAIL -35
6315+
6316+#define CFE_ERR_NOTREADY -36
6317+
6318+#define CFE_ERR_GETMEM -37
6319+#define CFE_ERR_SETMEM -38
6320+
6321+#define CFE_ERR_NOTCONN -39
6322+#define CFE_ERR_ADDRINUSE -40
6323+
6324+
6325+#endif /* LINUX_CFE_API_H_ */
6326diff -Nru linux-2.6.19.ori/include/asm-mips/cpu.h linux-2.6.19/include/asm-mips/cpu.h
6327--- linux-2.6.19.ori/include/asm-mips/cpu.h 2006-12-02 18:55:39.000000000 +0100
6328+++ linux-2.6.19/include/asm-mips/cpu.h 2006-12-02 19:14:34.000000000 +0100
6329@@ -104,6 +104,13 @@
6330 #define PRID_IMP_SR71000 0x0400
6331
6332 /*
6333+ * These are the PRID's for when 23:16 == PRID_COMP_BROADCOM
6334+ */
6335+
6336+#define PRID_IMP_BCM4710 0x4000
6337+#define PRID_IMP_BCM3302 0x9000
6338+
6339+/*
6340 * Definitions for 7:0 on legacy processors
6341 */
6342
6343@@ -200,7 +207,9 @@
6344 #define CPU_SB1A 62
6345 #define CPU_74K 63
6346 #define CPU_R14000 64
6347-#define CPU_LAST 64
6348+#define CPU_BCM3302 65
6349+#define CPU_BCM4710 66
6350+#define CPU_LAST 66
6351
6352 /*
6353 * ISA Level encodings
6354diff -Nru linux-2.6.19.ori/include/asm-mips/mach-bcm947xx/kernel-entry-init.h linux-2.6.19/include/asm-mips/mach-bcm947xx/kernel-entry-init.h
6355--- linux-2.6.19.ori/include/asm-mips/mach-bcm947xx/kernel-entry-init.h 1970-01-01 01:00:00.000000000 +0100
6356+++ linux-2.6.19/include/asm-mips/mach-bcm947xx/kernel-entry-init.h 2006-12-02 19:14:34.000000000 +0100
6357@@ -0,0 +1,26 @@
6358+/*
6359+ * This file is subject to the terms and conditions of the GNU General Public
6360+ * License. See the file "COPYING" in the main directory of this archive
6361+ * for more details.
6362+ *
6363+ * Copyright (C) 2005 Embedded Alley Solutions, Inc
6364+ * Copyright (C) 2005 Ralf Baechle (ralf@linux-mips.org)
6365+ * Copyright (C) 2006 Michael Buesch
6366+ */
6367+#ifndef __ASM_MACH_GENERIC_KERNEL_ENTRY_H
6368+#define __ASM_MACH_GENERIC_KERNEL_ENTRY_H
6369+
6370+/* Intentionally empty macro, used in head.S. Override in
6371+ * arch/mips/mach-xxx/kernel-entry-init.h when necessary.
6372+ */
6373+ .macro kernel_entry_setup
6374+ .endm
6375+
6376+/*
6377+ * Do SMP slave processor setup necessary before we can savely execute C code.
6378+ */
6379+ .macro smp_slave_setup
6380+ .endm
6381+
6382+
6383+#endif /* __ASM_MACH_GENERIC_KERNEL_ENTRY_H */
6384diff -Nru linux-2.6.19.ori/include/linux/pci_ids.h linux-2.6.19/include/linux/pci_ids.h
6385--- linux-2.6.19.ori/include/linux/pci_ids.h 2006-12-02 18:55:39.000000000 +0100
6386+++ linux-2.6.19/include/linux/pci_ids.h 2006-12-02 19:14:34.000000000 +0100
6387@@ -1953,6 +1953,7 @@
6388 #define PCI_DEVICE_ID_TIGON3_5906M 0x1713
6389 #define PCI_DEVICE_ID_BCM4401 0x4401
6390 #define PCI_DEVICE_ID_BCM4401B0 0x4402
6391+#define PCI_DEVICE_ID_BCM4713 0x4713
6392
6393 #define PCI_VENDOR_ID_TOPIC 0x151f
6394 #define PCI_DEVICE_ID_TOPIC_TP560 0x0000
6395diff -Nru linux-2.6.19.ori/include/linux/ssb.h linux-2.6.19/include/linux/ssb.h
6396--- linux-2.6.19.ori/include/linux/ssb.h 1970-01-01 01:00:00.000000000 +0100
6397+++ linux-2.6.19/include/linux/ssb.h 2006-12-02 19:14:34.000000000 +0100
6398@@ -0,0 +1,263 @@
6399+#ifndef LINUX_SSB_H_
6400+#define LINUX_SSB_H_
6401+#ifdef __KERNEL__
6402+
6403+#include <linux/device.h>
6404+#include <linux/list.h>
6405+#include <linux/types.h>
6406+#include <linux/spinlock.h>
6407+
6408+#include <linux/ssb_regs.h>
6409+
6410+
6411+struct ssb_bus;
6412+struct ssb_driver;
6413+
6414+
6415+struct ssb_sprom_r1 {
6416+ u16 pci_spid; /* Subsystem Product ID for PCI */
6417+ u16 pci_svid; /* Subsystem Vendor ID for PCI */
6418+ u16 pci_pid; /* Product ID for PCI */
6419+ u8 il0mac[6]; /* MAC address for 802.11b/g */
6420+ u8 et0mac[6]; /* MAC address for Ethernet */
6421+ u8 et1mac[6]; /* MAC address for 802.11a */
6422+ u8 et0phyaddr:5; /* MII address for enet0 */
6423+ u8 et1phyaddr:5; /* MII address for enet1 */
6424+ u8 et0mdcport:1; /* MDIO for enet0 */
6425+ u8 et1mdcport:1; /* MDIO for enet1 */
6426+ u8 board_rev; /* Board revision */
6427+ u8 country_code:4; /* Country Code */
6428+ u8 antenna_a:2; /* Antenna 0/1 available for A-PHY */
6429+ u8 antenna_bg:2; /* Antenna 0/1 available for B-PHY and G-PHY */
6430+ u16 pa0b0;
6431+ u16 pa0b1;
6432+ u16 pa0b2;
6433+ u16 pa1b0;
6434+ u16 pa1b1;
6435+ u16 pa1b2;
6436+ u8 gpio0; /* GPIO pin 0 */
6437+ u8 gpio1; /* GPIO pin 1 */
6438+ u8 gpio2; /* GPIO pin 2 */
6439+ u8 gpio3; /* GPIO pin 3 */
6440+ u16 maxpwr_a; /* A-PHY Power Amplifier Max Power (in dBm Q5.2) */
6441+ u16 maxpwr_bg; /* B/G-PHY Power Amplifier Max Power (in dBm Q5.2) */
6442+ u8 itssi_a; /* Idle TSSI Target for A-PHY */
6443+ u8 itssi_bg; /* Idle TSSI Target for B/G-PHY */
6444+ u16 boardflags_lo; /* Boardflags (low 16 bits) */
6445+ u8 antenna_gain_a; /* A-PHY Antenna gain (in dBm Q5.2) */
6446+ u8 antenna_gain_bg; /* B/G-PHY Antenna gain (in dBm Q5.2) */
6447+ u8 oem[8]; /* OEM string (rev 1 only) */
6448+};
6449+
6450+struct ssb_sprom_r2 {
6451+ u16 boardflags_hi; /* Boardflags (high 16 bits) */
6452+ u8 maxpwr_a_lo; /* A-PHY Max Power Low */
6453+ u8 maxpwr_a_hi; /* A-PHY Max Power High */
6454+ u16 pa1lob0; /* A-PHY PA Low Settings */
6455+ u16 pa1lob1; /* A-PHY PA Low Settings */
6456+ u16 pa1lob2; /* A-PHY PA Low Settings */
6457+ u16 pa1hib0; /* A-PHY PA High Settings */
6458+ u16 pa1hib1; /* A-PHY PA High Settings */
6459+ u16 pa1hib2; /* A-PHY PA High Settings */
6460+ u8 ofdm_pwr_off; /* OFDM Power Offset from CCK Level */
6461+ u8 country_str[2]; /* Two char Country Code */
6462+};
6463+
6464+struct ssb_sprom_r3 {
6465+ u32 ofdmapo; /* A-PHY OFDM Mid Power Offset */
6466+ u32 ofdmalpo; /* A-PHY OFDM Low Power Offset */
6467+ u32 ofdmahpo; /* A-PHY OFDM High Power Offset */
6468+ u8 gpioldc_on_cnt; /* GPIO LED Powersave Duty Cycle ON count */
6469+ u8 gpioldc_off_cnt; /* GPIO LED Powersave Duty Cycle OFF count */
6470+ u8 cckpo_1M:4; /* CCK Power Offset for Rate 1M */
6471+ u8 cckpo_2M:4; /* CCK Power Offset for Rate 2M */
6472+ u8 cckpo_55M:4; /* CCK Power Offset for Rate 5.5M */
6473+ u8 cckpo_11M:4; /* CCK Power Offset for Rate 11M */
6474+ u32 ofdmgpo; /* G-PHY OFDM Power Offset */
6475+};
6476+
6477+struct ssb_sprom_r4 {
6478+ /* TODO */
6479+};
6480+
6481+struct ssb_sprom {
6482+ u8 revision;
6483+ u8 crc;
6484+ /* The valid r# fields are selected by the "revision".
6485+ * Revision 3 and lower inherit from lower revisions.
6486+ */
6487+ union {
6488+ struct {
6489+ struct ssb_sprom_r1 r1;
6490+ struct ssb_sprom_r2 r2;
6491+ struct ssb_sprom_r3 r3;
6492+ };
6493+ struct ssb_sprom_r4 r4;
6494+ };
6495+};
6496+
6497+
6498+/* Core-ID values. */
6499+#define SSB_DEV_CHIPCOMMON 0x800
6500+#define SSB_DEV_ILINE20 0x801
6501+#define SSB_DEV_SDRAM 0x803
6502+#define SSB_DEV_PCI 0x804
6503+#define SSB_DEV_MIPS 0x805
6504+#define SSB_DEV_ETHERNET 0x806
6505+#define SSB_DEV_V90 0x807
6506+#define SSB_DEV_USB11_HOSTDEV 0x808
6507+#define SSB_DEV_ADSL 0x809
6508+#define SSB_DEV_ILINE100 0x80A
6509+#define SSB_DEV_IPSEC 0x80B
6510+#define SSB_DEV_PCMCIA 0x80D
6511+#define SSB_DEV_INTERNAL_MEM 0x80E
6512+#define SSB_DEV_MEMC_SDRAM 0x80F
6513+#define SSB_DEV_EXTIF 0x811
6514+#define SSB_DEV_80211 0x812
6515+#define SSB_DEV_MIPS_3302 0x816
6516+#define SSB_DEV_USB11_HOST 0x817
6517+#define SSB_DEV_USB11_DEV 0x818
6518+#define SSB_DEV_USB20_HOST 0x819
6519+#define SSB_DEV_USB20_DEV 0x81A
6520+#define SSB_DEV_SDIO_HOST 0x81B
6521+#define SSB_DEV_ROBOSWITCH 0x81C
6522+#define SSB_DEV_PARA_ATA 0x81D
6523+#define SSB_DEV_SATA_XORDMA 0x81E
6524+#define SSB_DEV_ETHERNET_GBIT 0x81F
6525+#define SSB_DEV_PCIE 0x820
6526+#define SSB_DEV_MIMO_PHY 0x821
6527+#define SSB_DEV_SRAM_CTRLR 0x822
6528+#define SSB_DEV_MINI_MACPHY 0x823
6529+#define SSB_DEV_ARM_1176 0x824
6530+#define SSB_DEV_ARM_7TDMI 0x825
6531+
6532+/* Vendor-ID values */
6533+#define SSB_VENDOR_BROADCOM 0x4243
6534+
6535+struct ssb_device_id {
6536+ u16 vendor;
6537+ u16 coreid;
6538+ u8 revision;
6539+};
6540+#define SSB_DEVICE(_vendor, _coreid, _revision) \
6541+ { .vendor = _vendor, .coreid = _coreid, .revision = _revision, }
6542+#define SSB_DEVTABLE_END \
6543+ { 0, },
6544+
6545+#define SSB_ANY_VENDOR 0xFFFF
6546+#define SSB_ANY_ID 0xFFFF
6547+#define SSB_ANY_REV 0xFF
6548+
6549+
6550+struct ssb_device {
6551+ struct device dev;
6552+ struct ssb_bus *bus;
6553+ struct ssb_device_id id;
6554+
6555+ u8 core_index;
6556+ u32 dma_routing; //FIXME assign this! move to bus? Use helper function?
6557+ unsigned int irq;
6558+ void *drvdata;
6559+};
6560+#define dev_to_ssb_dev(_dev) container_of(_dev, struct ssb_device, dev)
6561+
6562+static inline
6563+void ssb_set_drvdata(struct ssb_device *dev, void *data)
6564+{
6565+ dev->drvdata = data;
6566+}
6567+static inline
6568+void * ssb_get_drvdata(struct ssb_device *dev)
6569+{
6570+ return dev->drvdata;
6571+}
6572+
6573+u16 ssb_read16(struct ssb_device *dev, u16 offset);
6574+u32 ssb_read32(struct ssb_device *dev, u16 offset);
6575+void ssb_write16(struct ssb_device *dev, u16 offset, u16 value);
6576+void ssb_write32(struct ssb_device *dev, u16 offset, u32 value);
6577+
6578+
6579+struct ssb_driver {
6580+ const char *name;
6581+ const struct ssb_device_id *id_table;
6582+
6583+ int (*probe)(struct ssb_device *dev, const struct ssb_device_id *id);
6584+ void (*remove)(struct ssb_device *dev);
6585+ int (*suspend)(struct ssb_device *dev, pm_message_t state);
6586+ int (*resume)(struct ssb_device *dev);
6587+ void (*shutdown)(struct ssb_device *dev);
6588+
6589+ struct device_driver drv;
6590+};
6591+#define drv_to_ssb_drv(_drv) container_of(_drv, struct ssb_driver, drv)
6592+
6593+extern int __ssb_driver_register(struct ssb_driver *drv, struct module *owner);
6594+static inline int ssb_driver_register(struct ssb_driver *drv)
6595+{
6596+ return __ssb_driver_register(drv, THIS_MODULE);
6597+}
6598+extern void ssb_driver_unregister(struct ssb_driver *drv);
6599+
6600+
6601+
6602+
6603+enum ssb_bustype {
6604+ SSB_BUSTYPE_SSB, /* This SSB bus is the system bus */
6605+ SSB_BUSTYPE_PCI, /* SSB is connected to PCI bus */
6606+ //FIXME JTAG?
6607+};
6608+
6609+#include <linux/ssb_driver_chipcommon.h>
6610+#include <linux/ssb_driver_mips.h>
6611+#include <linux/ssb_driver_extif.h>
6612+
6613+struct ssb_bus {
6614+ enum ssb_bustype bustype;
6615+ struct pci_dev *host_pci;
6616+ void __iomem *mmio;
6617+
6618+ u16 chip_id;
6619+ u16 chip_rev;
6620+ u8 chip_package;
6621+ struct ssb_sprom sprom;
6622+
6623+ spinlock_t bar_lock;
6624+ struct ssb_device *mapped_device;
6625+ int nr_devices;
6626+ struct ssb_device devices[SSB_MAX_NR_CORES]; /* cores */
6627+
6628+ struct ssb_chipcommon chipco;
6629+ struct ssb_mipscore mipscore;
6630+
6631+ int busnumber;
6632+ struct list_head list;
6633+};
6634+
6635+extern int ssb_bus_ssbbus_register(struct ssb_bus *bus,
6636+ unsigned long baseaddr,
6637+ void (*fill_sprom)(struct ssb_sprom *sprom));
6638+extern int ssb_bus_pcibus_register(struct ssb_bus *bus,
6639+ struct pci_dev *host_pci);
6640+extern void ssb_bus_unregister(struct ssb_bus *bus);
6641+extern u32 ssb_clockspeed(struct ssb_bus *bus);
6642+
6643+int ssb_core_is_enabled(struct ssb_device *dev);
6644+void ssb_core_enable(struct ssb_device *dev, u32 core_specific_flags);
6645+void ssb_core_disable(struct ssb_device *dev, u32 core_specific_flags);
6646+
6647+static inline dma_addr_t ssb_dma_offset(struct ssb_device *dev)
6648+{
6649+ switch(dev->bus->bustype) {
6650+ case SSB_BUSTYPE_SSB:
6651+ return 0;
6652+ case SSB_BUSTYPE_PCI:
6653+ return SSB_PCI_DMA;
6654+ }
6655+ return 0;
6656+}
6657+
6658+
6659+
6660+#endif /* __KERNEL__ */
6661+#endif /* LINUX_SSB_H_ */
6662diff -Nru linux-2.6.19.ori/include/linux/ssb_driver_chipcommon.h linux-2.6.19/include/linux/ssb_driver_chipcommon.h
6663--- linux-2.6.19.ori/include/linux/ssb_driver_chipcommon.h 1970-01-01 01:00:00.000000000 +0100
6664+++ linux-2.6.19/include/linux/ssb_driver_chipcommon.h 2006-12-02 19:14:34.000000000 +0100
6665@@ -0,0 +1,379 @@
6666+#ifndef LINUX_SSB_CHIPCO_H_
6667+#define LINUX_SSB_CHIPCO_H_
6668+
6669+/* SonicsSiliconBackplane CHIPCOMMON core hardware definitions
6670+ *
6671+ * The chipcommon core provides chip identification, SB control,
6672+ * jtag, 0/1/2 uarts, clock frequency control, a watchdog interrupt timer,
6673+ * gpio interface, extbus, and support for serial and parallel flashes.
6674+ *
6675+ * Copyright 2005, Broadcom Corporation
6676+ * Copyright 2006, Michael Buesch <mb@bu3sch.de>
6677+ *
6678+ * Licensed under the GPL version 2. See COPYING for details.
6679+ */
6680+#ifdef __KERNEL__
6681+
6682+/** ChipCommon core registers. **/
6683+
6684+#define SSB_CHIPCO_CHIPID 0x0000
6685+#define SSB_CHIPCO_IDMASK 0x0000FFFF
6686+#define SSB_CHIPCO_REVMASK 0x000F0000
6687+#define SSB_CHIPCO_REVSHIFT 16
6688+#define SSB_CHIPCO_PACKMASK 0x00F00000
6689+#define SSB_CHIPCO_PACKSHIFT 20
6690+#define SSB_CHIPCO_NRCORESMASK 0x0F000000
6691+#define SSB_CHIPCO_NRCORESSHIFT 24
6692+#define SSB_CHIPCO_CAP 0x0004 /* Capabilities */
6693+#define SSB_CHIPCO_CAP_NRUART 0x00000003 /* # of UARTs */
6694+#define SSB_CHIPCO_CAP_MIPSEB 0x00000004 /* MIPS in BigEndian Mode */
6695+#define SSB_CHIPCO_CAP_UARTCLK 0x00000018 /* UART clock select */
6696+#define SSB_CHIPCO_CAP_UARTCLK_INT 0x00000008 /* UARTs are driven by internal divided clock */
6697+#define SSB_CHIPCO_CAP_UARTGPIO 0x00000020 /* UARTs on GPIO 15-12 */
6698+#define SSB_CHIPCO_CAP_EXTBUS 0x000000C0 /* External buses present */
6699+#define SSB_CHIPCO_CAP_FLASHT 0x00000700 /* Flash Type */
6700+#define SSB_CHIPCO_FLASHT_NONE 0x00000000 /* No flash */
6701+#define SSB_CHIPCO_FLASHT_STSER 0x00000100 /* ST serial flash */
6702+#define SSB_CHIPCO_FLASHT_ATSER 0x00000200 /* Atmel serial flash */
6703+#define SSB_CHIPCO_FLASHT_PARA 0x00000700 /* Parallel flash */
6704+#define SSB_CHIPCO_CAP_PLLT 0x00038000 /* PLL Type */
6705+#define SSB_PLLTYPE_NONE 0x00000000
6706+#define SSB_PLLTYPE_1 0x00010000 /* 48Mhz base, 3 dividers */
6707+#define SSB_PLLTYPE_2 0x00020000 /* 48Mhz, 4 dividers */
6708+#define SSB_PLLTYPE_3 0x00030000 /* 25Mhz, 2 dividers */
6709+#define SSB_PLLTYPE_4 0x00008000 /* 48Mhz, 4 dividers */
6710+#define SSB_PLLTYPE_5 0x00018000 /* 25Mhz, 4 dividers */
6711+#define SSB_PLLTYPE_6 0x00028000 /* 100/200 or 120/240 only */
6712+#define SSB_PLLTYPE_7 0x00038000 /* 25Mhz, 4 dividers */
6713+#define SSB_CHIPCO_CAP_PCTL 0x00040000 /* Power Control */
6714+#define SSB_CHIPCO_CAP_OTPS 0x00380000 /* OTP size */
6715+#define SSB_CHIPCO_CAP_OTPS_SHIFT 19
6716+#define SSB_CHIPCO_CAP_OTPS_BASE 5
6717+#define SSB_CHIPCO_CAP_JTAGM 0x00400000 /* JTAG master present */
6718+#define SSB_CHIPCO_CAP_BROM 0x00800000 /* Internal boot ROM active */
6719+#define SSB_CHIPCO_CAP_64BIT 0x08000000 /* 64-bit Backplane */
6720+#define SSB_CHIPCO_CORECTL 0x0008
6721+#define SSB_CHIPCO_CORECTL_UARTCLK0 0x00000001 /* Drive UART with internal clock */
6722+#define SSB_CHIPCO_CORECTL_SE 0x00000002 /* sync clk out enable (corerev >= 3) */
6723+#define SSB_CHIPCO_BIST 0x000C
6724+#define SSB_CHIPCO_OTPS 0x0010 /* OTP status */
6725+#define SSB_CHIPCO_OTPS_PROGFAIL 0x80000000
6726+#define SSB_CHIPCO_OTPS_PROTECT 0x00000007
6727+#define SSB_CHIPCO_OTPS_HW_PROTECT 0x00000001
6728+#define SSB_CHIPCO_OTPS_SW_PROTECT 0x00000002
6729+#define SSB_CHIPCO_OTPS_CID_PROTECT 0x00000004
6730+#define SSB_CHIPCO_OTPC 0x0014 /* OTP control */
6731+#define SSB_CHIPCO_OTPC_RECWAIT 0xFF000000
6732+#define SSB_CHIPCO_OTPC_PROGWAIT 0x00FFFF00
6733+#define SSB_CHIPCO_OTPC_PRW_SHIFT 8
6734+#define SSB_CHIPCO_OTPC_MAXFAIL 0x00000038
6735+#define SSB_CHIPCO_OTPC_VSEL 0x00000006
6736+#define SSB_CHIPCO_OTPC_SELVL 0x00000001
6737+#define SSB_CHIPCO_OTPP 0x0018 /* OTP prog */
6738+#define SSB_CHIPCO_OTPP_COL 0x000000FF
6739+#define SSB_CHIPCO_OTPP_ROW 0x0000FF00
6740+#define SSB_CHIPCO_OTPP_ROW_SHIFT 8
6741+#define SSB_CHIPCO_OTPP_READERR 0x10000000
6742+#define SSB_CHIPCO_OTPP_VALUE 0x20000000
6743+#define SSB_CHIPCO_OTPP_READ 0x40000000
6744+#define SSB_CHIPCO_OTPP_START 0x80000000
6745+#define SSB_CHIPCO_OTPP_BUSY 0x80000000
6746+#define SSB_CHIPCO_IRQSTAT 0x0020
6747+#define SSB_CHIPCO_IRQMASK 0x0024
6748+#define SSB_CHIPCO_IRQ_GPIO 0x00000001 /* gpio intr */
6749+#define SSB_CHIPCO_IRQ_EXT 0x00000002 /* ro: ext intr pin (corerev >= 3) */
6750+#define SSB_CHIPCO_IRQ_WDRESET 0x80000000 /* watchdog reset occurred */
6751+#define SSB_CHIPCO_CHIPCTL 0x0028 /* Rev >= 11 only */
6752+#define SSB_CHIPCO_CHIPSTAT 0x002C /* Rev >= 11 only */
6753+#define SSB_CHIPCO_JCMD 0x0030 /* Rev >= 10 only */
6754+#define SSB_CHIPCO_JCMD_START 0x80000000
6755+#define SSB_CHIPCO_JCMD_BUSY 0x80000000
6756+#define SSB_CHIPCO_JCMD_PAUSE 0x40000000
6757+#define SSB_CHIPCO_JCMD0_ACC_MASK 0x0000F000
6758+#define SSB_CHIPCO_JCMD0_ACC_IRDR 0x00000000
6759+#define SSB_CHIPCO_JCMD0_ACC_DR 0x00001000
6760+#define SSB_CHIPCO_JCMD0_ACC_IR 0x00002000
6761+#define SSB_CHIPCO_JCMD0_ACC_RESET 0x00003000
6762+#define SSB_CHIPCO_JCMD0_ACC_IRPDR 0x00004000
6763+#define SSB_CHIPCO_JCMD0_ACC_PDR 0x00005000
6764+#define SSB_CHIPCO_JCMD0_IRW_MASK 0x00000F00
6765+#define SSB_CHIPCO_JCMD_ACC_MASK 0x000F0000 /* Changes for corerev 11 */
6766+#define SSB_CHIPCO_JCMD_ACC_IRDR 0x00000000
6767+#define SSB_CHIPCO_JCMD_ACC_DR 0x00010000
6768+#define SSB_CHIPCO_JCMD_ACC_IR 0x00020000
6769+#define SSB_CHIPCO_JCMD_ACC_RESET 0x00030000
6770+#define SSB_CHIPCO_JCMD_ACC_IRPDR 0x00040000
6771+#define SSB_CHIPCO_JCMD_ACC_PDR 0x00050000
6772+#define SSB_CHIPCO_JCMD_IRW_MASK 0x00001F00
6773+#define SSB_CHIPCO_JCMD_IRW_SHIFT 8
6774+#define SSB_CHIPCO_JCMD_DRW_MASK 0x0000003F
6775+#define SSB_CHIPCO_JIR 0x0034 /* Rev >= 10 only */
6776+#define SSB_CHIPCO_JDR 0x0038 /* Rev >= 10 only */
6777+#define SSB_CHIPCO_JCTL 0x003C /* Rev >= 10 only */
6778+#define SSB_CHIPCO_JCTL_FORCE_CLK 4 /* Force clock */
6779+#define SSB_CHIPCO_JCTL_EXT_EN 2 /* Enable external targets */
6780+#define SSB_CHIPCO_JCTL_EN 1 /* Enable Jtag master */
6781+#define SSB_CHIPCO_FLASHCTL 0x0040
6782+#define SSB_CHIPCO_FLASHCTL_START 0x80000000
6783+#define SSB_CHIPCO_FLASHCTL_BUSY SSB_CHIPCO_FLASHCTL_START
6784+#define SSB_CHIPCO_FLASHADDR 0x0044
6785+#define SSB_CHIPCO_FLASHDATA 0x0048
6786+#define SSB_CHIPCO_BCAST_ADDR 0x0050
6787+#define SSB_CHIPCO_BCAST_DATA 0x0054
6788+#define SSB_CHIPCO_GPIOIN 0x0060
6789+#define SSB_CHIPCO_GPIOOUT 0x0064
6790+#define SSB_CHIPCO_GPIOOUTEN 0x0068
6791+#define SSB_CHIPCO_GPIOCTL 0x006C
6792+#define SSB_CHIPCO_GPIOPOL 0x0070
6793+#define SSB_CHIPCO_GPIOIRQ 0x0074
6794+#define SSB_CHIPCO_WATCHDOG 0x0080
6795+#define SSB_CHIPCO_GPIOTIMER 0x0088 /* LED powersave (corerev >= 16) */
6796+#define SSB_CHIPCO_GPIOTIMER_ONTIME_SHIFT 16
6797+#define SSB_CHIPCO_GPIOTOUTM 0x008C /* LED powersave (corerev >= 16) */
6798+#define SSB_CHIPCO_CLOCK_N 0x0090
6799+#define SSB_CHIPCO_CLOCK_SB 0x0094
6800+#define SSB_CHIPCO_CLOCK_PCI 0x0098
6801+#define SSB_CHIPCO_CLOCK_M2 0x009C
6802+#define SSB_CHIPCO_CLOCK_MIPS 0x00A0
6803+#define SSB_CHIPCO_CLKDIV 0x00A4 /* Rev >= 3 only */
6804+#define SSB_CHIPCO_CLKDIV_SFLASH 0x0F000000
6805+#define SSB_CHIPCO_CLKDIV_SFLASH_SHIFT 24
6806+#define SSB_CHIPCO_CLKDIV_OTP 0x000F0000
6807+#define SSB_CHIPCO_CLKDIV_OTP_SHIFT 16
6808+#define SSB_CHIPCO_CLKDIV_JTAG 0x00000F00
6809+#define SSB_CHIPCO_CLKDIV_JTAG_SHIFT 8
6810+#define SSB_CHIPCO_CLKDIV_UART 0x000000FF
6811+#define SSB_CHIPCO_PLLONDELAY 0x00B0 /* Rev >= 4 only */
6812+#define SSB_CHIPCO_FREFSELDELAY 0x00B4 /* Rev >= 4 only */
6813+#define SSB_CHIPCO_SLOWCLKCTL 0x00B8 /* 6 <= Rev <= 9 only */
6814+#define SSB_CHIPCO_SLOWCLKCTL_SRC 0x00000007 /* slow clock source mask */
6815+#define SSB_CHIPCO_SLOWCLKCTL_SRC_LPO 0x00000000 /* source of slow clock is LPO */
6816+#define SSB_CHIPCO_SLOWCLKCTL_SRC_XTAL 0x00000001 /* source of slow clock is crystal */
6817+#define SSB_CHIPCO_SLOECLKCTL_SRC_PCI 0x00000002 /* source of slow clock is PCI */
6818+#define SSB_CHIPCO_SLOWCLKCTL_LPOFREQ 0x00000200 /* LPOFreqSel, 1: 160Khz, 0: 32KHz */
6819+#define SSB_CHIPCO_SLOWCLKCTL_LPOPD 0x00000400 /* LPOPowerDown, 1: LPO is disabled, 0: LPO is enabled */
6820+#define SSB_CHIPCO_SLOWCLKCTL_FSLOW 0x00000800 /* ForceSlowClk, 1: sb/cores running on slow clock, 0: power logic control */
6821+#define SSB_CHIPCO_SLOWCLKCTL_IPLL 0x00001000 /* IgnorePllOffReq, 1/0: power logic ignores/honors PLL clock disable requests from core */
6822+#define SSB_CHIPCO_SLOWCLKCTL_ENXTAL 0x00002000 /* XtalControlEn, 1/0: power logic does/doesn't disable crystal when appropriate */
6823+#define SSB_CHIPCO_SLOWCLKCTL_XTALPU 0x00004000 /* XtalPU (RO), 1/0: crystal running/disabled */
6824+#define SSB_CHIPCO_SLOWCLKCTL_CLKDIV 0xFFFF0000 /* ClockDivider (SlowClk = 1/(4+divisor)) */
6825+#define SSB_CHIPCO_SLOWCLKCTL_CLKDIV_SHIFT 16
6826+#define SSB_CHIPCO_SYSCLKCTL 0x00C0 /* Rev >= 3 only */
6827+#define SSB_CHIPCO_SYSCLKCTL_IDLPEN 0x00000001 /* ILPen: Enable Idle Low Power */
6828+#define SSB_CHIPCO_SYSCLKCTL_ALPEN 0x00000002 /* ALPen: Enable Active Low Power */
6829+#define SSB_CHIPCO_SYSCLKCTL_PLLEN 0x00000004 /* ForcePLLOn */
6830+#define SSB_CHIPCO_SYSCLKCTL_FORCEALP 0x00000008 /* Force ALP (or HT if ALPen is not set */
6831+#define SSB_CHIPCO_SYSCLKCTL_FORCEHT 0x00000010 /* Force HT */
6832+#define SSB_CHIPCO_SYSCLKCTL_CLKDIV 0xFFFF0000 /* ClkDiv (ILP = 1/(4+divisor)) */
6833+#define SSB_CHIPCO_SYSCLKCTL_CLKDIV_SHIFT 16
6834+#define SSB_CHIPCO_CLKSTSTR 0x00C4 /* Rev >= 3 only */
6835+#define SSB_CHIPCO_PCMCIA_CFG 0x0100
6836+#define SSB_CHIPCO_PCMCIA_MEMWAIT 0x0104
6837+#define SSB_CHIPCO_PCMCIA_ATTRWAIT 0x0108
6838+#define SSB_CHIPCO_PCMCIA_IOWAIT 0x010C
6839+#define SSB_CHIPCO_IDE_CFG 0x0110
6840+#define SSB_CHIPCO_IDE_MEMWAIT 0x0114
6841+#define SSB_CHIPCO_IDE_ATTRWAIT 0x0118
6842+#define SSB_CHIPCO_IDE_IOWAIT 0x011C
6843+#define SSB_CHIPCO_PROG_CFG 0x0120
6844+#define SSB_CHIPCO_PROG_WAITCNT 0x0124
6845+#define SSB_CHIPCO_FLASH_CFG 0x0128
6846+#define SSB_CHIPCO_FLASH_WAITCNT 0x012C
6847+#define SSB_CHIPCO_UART0_DATA 0x0300
6848+#define SSB_CHIPCO_UART0_IMR 0x0304
6849+#define SSB_CHIPCO_UART0_FCR 0x0308
6850+#define SSB_CHIPCO_UART0_LCR 0x030C
6851+#define SSB_CHIPCO_UART0_MCR 0x0310
6852+#define SSB_CHIPCO_UART0_LSR 0x0314
6853+#define SSB_CHIPCO_UART0_MSR 0x0318
6854+#define SSB_CHIPCO_UART0_SCRATCH 0x031C
6855+#define SSB_CHIPCO_UART1_DATA 0x0400
6856+#define SSB_CHIPCO_UART1_IMR 0x0404
6857+#define SSB_CHIPCO_UART1_FCR 0x0408
6858+#define SSB_CHIPCO_UART1_LCR 0x040C
6859+#define SSB_CHIPCO_UART1_MCR 0x0410
6860+#define SSB_CHIPCO_UART1_LSR 0x0414
6861+#define SSB_CHIPCO_UART1_MSR 0x0418
6862+#define SSB_CHIPCO_UART1_SCRATCH 0x041C
6863+
6864+
6865+
6866+/** Clockcontrol masks and values **/
6867+
6868+/* SSB_CHIPCO_CLOCK_N */
6869+#define SSB_CHIPCO_CLK_N1 0x0000003F /* n1 control */
6870+#define SSB_CHIPCO_CLK_N2 0x00003F00 /* n2 control */
6871+#define SSB_CHIPCO_CLK_N2_SHIFT 8
6872+#define SSB_CHIPCO_CLK_PLLC 0x000F0000 /* pll control */
6873+#define SSB_CHIPCO_CLK_PLLC_SHIFT 16
6874+
6875+/* SSB_CHIPCO_CLOCK_SB/PCI/UART */
6876+#define SSB_CHIPCO_CLK_M1 0x0000003F /* m1 control */
6877+#define SSB_CHIPCO_CLK_M2 0x00003F00 /* m2 control */
6878+#define SSB_CHIPCO_CLK_M2_SHIFT 8
6879+#define SSB_CHIPCO_CLK_M3 0x003F0000 /* m3 control */
6880+#define SSB_CHIPCO_CLK_M3_SHIFT 16
6881+#define SSB_CHIPCO_CLK_MC 0x1F000000 /* mux control */
6882+#define SSB_CHIPCO_CLK_MC_SHIFT 24
6883+
6884+/* N3M Clock control magic field values */
6885+#define SSB_CHIPCO_CLK_F6_2 0x02 /* A factor of 2 in */
6886+#define SSB_CHIPCO_CLK_F6_3 0x03 /* 6-bit fields like */
6887+#define SSB_CHIPCO_CLK_F6_4 0x05 /* N1, M1 or M3 */
6888+#define SSB_CHIPCO_CLK_F6_5 0x09
6889+#define SSB_CHIPCO_CLK_F6_6 0x11
6890+#define SSB_CHIPCO_CLK_F6_7 0x21
6891+
6892+#define SSB_CHIPCO_CLK_F5_BIAS 5 /* 5-bit fields get this added */
6893+
6894+#define SSB_CHIPCO_CLK_MC_BYPASS 0x08
6895+#define SSB_CHIPCO_CLK_MC_M1 0x04
6896+#define SSB_CHIPCO_CLK_MC_M1M2 0x02
6897+#define SSB_CHIPCO_CLK_MC_M1M2M3 0x01
6898+#define SSB_CHIPCO_CLK_MC_M1M3 0x11
6899+
6900+/* Type 2 Clock control magic field values */
6901+#define SSB_CHIPCO_CLK_T2_BIAS 2 /* n1, n2, m1 & m3 bias */
6902+#define SSB_CHIPCO_CLK_T2M2_BIAS 3 /* m2 bias */
6903+
6904+#define SSB_CHIPCO_CLK_T2MC_M1BYP 1
6905+#define SSB_CHIPCO_CLK_T2MC_M2BYP 2
6906+#define SSB_CHIPCO_CLK_T2MC_M3BYP 4
6907+
6908+/* Type 6 Clock control magic field values */
6909+#define SSB_CHIPCO_CLK_T6_MMASK 1 /* bits of interest in m */
6910+#define SSB_CHIPCO_CLK_T6_M0 120000000 /* sb clock for m = 0 */
6911+#define SSB_CHIPCO_CLK_T6_M1 100000000 /* sb clock for m = 1 */
6912+#define SSB_CHIPCO_CLK_SB2MIPS_T6(sb) (2 * (sb))
6913+
6914+/* Common clock base */
6915+#define SSB_CHIPCO_CLK_BASE1 24000000 /* Half the clock freq */
6916+#define SSB_CHIPCO_CLK_BASE2 12500000 /* Alternate crystal on some PLL's */
6917+
6918+/* Clock control values for 200Mhz in 5350 */
6919+#define SSB_CHIPCO_CLK_5350_N 0x0311
6920+#define SSB_CHIPCO_CLK_5350_M 0x04020009
6921+
6922+
6923+/** Bits in the config registers **/
6924+
6925+#define SSB_CHIPCO_CFG_EN 0x0001 /* Enable */
6926+#define SSB_CHIPCO_CFG_EXTM 0x000E /* Extif Mode */
6927+#define SSB_CHIPCO_CFG_EXTM_ASYNC 0x0002 /* Async/Parallel flash */
6928+#define SSB_CHIPCO_CFG_EXTM_SYNC 0x0004 /* Synchronous */
6929+#define SSB_CHIPCO_CFG_EXTM_PCMCIA 0x0008 /* PCMCIA */
6930+#define SSB_CHIPCO_CFG_EXTM_IDE 0x000A /* IDE */
6931+#define SSB_CHIPCO_CFG_DS16 0x0010 /* Data size, 0=8bit, 1=16bit */
6932+#define SSB_CHIPCO_CFG_CLKDIV 0x0060 /* Sync: Clock divisor */
6933+#define SSB_CHIPCO_CFG_CLKEN 0x0080 /* Sync: Clock enable */
6934+#define SSB_CHIPCO_CFG_BSTRO 0x0100 /* Sync: Size/Bytestrobe */
6935+
6936+
6937+/** Flash-specific control/status values */
6938+
6939+/* flashcontrol opcodes for ST flashes */
6940+#define SSB_CHIPCO_FLASHCTL_ST_WREN 0x0006 /* Write Enable */
6941+#define SSB_CHIPCO_FLASHCTL_ST_WRDIS 0x0004 /* Write Disable */
6942+#define SSB_CHIPCO_FLASHCTL_ST_RDSR 0x0105 /* Read Status Register */
6943+#define SSB_CHIPCO_FLASHCTL_ST_WRSR 0x0101 /* Write Status Register */
6944+#define SSB_CHIPCO_FLASHCTL_ST_READ 0x0303 /* Read Data Bytes */
6945+#define SSB_CHIPCO_FLASHCTL_ST_PP 0x0302 /* Page Program */
6946+#define SSB_CHIPCO_FLASHCTL_ST_SE 0x02D8 /* Sector Erase */
6947+#define SSB_CHIPCO_FLASHCTL_ST_BE 0x00C7 /* Bulk Erase */
6948+#define SSB_CHIPCO_FLASHCTL_ST_DP 0x00B9 /* Deep Power-down */
6949+#define SSB_CHIPCO_FLASHCTL_ST_RSIG 0x03AB /* Read Electronic Signature */
6950+
6951+/* Status register bits for ST flashes */
6952+#define SSB_CHIPCO_FLASHSTA_ST_WIP 0x01 /* Write In Progress */
6953+#define SSB_CHIPCO_FLASHSTA_ST_WEL 0x02 /* Write Enable Latch */
6954+#define SSB_CHIPCO_FLASHSTA_ST_BP 0x1C /* Block Protect */
6955+#define SSB_CHIPCO_FLASHSTA_ST_BP_SHIFT 2
6956+#define SSB_CHIPCO_FLASHSTA_ST_SRWD 0x80 /* Status Register Write Disable */
6957+
6958+/* flashcontrol opcodes for Atmel flashes */
6959+#define SSB_CHIPCO_FLASHCTL_AT_READ 0x07E8
6960+#define SSB_CHIPCO_FLASHCTL_AT_PAGE_READ 0x07D2
6961+#define SSB_CHIPCO_FLASHCTL_AT_BUF1_READ /* FIXME */
6962+#define SSB_CHIPCO_FLASHCTL_AT_BUF2_READ /* FIXME */
6963+#define SSB_CHIPCO_FLASHCTL_AT_STATUS 0x01D7
6964+#define SSB_CHIPCO_FLASHCTL_AT_BUF1_WRITE 0x0384
6965+#define SSB_CHIPCO_FLASHCTL_AT_BUF2_WRITE 0x0387
6966+#define SSB_CHIPCO_FLASHCTL_AT_BUF1_ERASE_PRGM 0x0283 /* Erase program */
6967+#define SSB_CHIPCO_FLASHCTL_AT_BUF2_ERASE_PRGM 0x0286 /* Erase program */
6968+#define SSB_CHIPCO_FLASHCTL_AT_BUF1_PROGRAM 0x0288
6969+#define SSB_CHIPCO_FLASHCTL_AT_BUF2_PROGRAM 0x0289
6970+#define SSB_CHIPCO_FLASHCTL_AT_PAGE_ERASE 0x0281
6971+#define SSB_CHIPCO_FLASHCTL_AT_BLOCK_ERASE 0x0250
6972+#define SSB_CHIPCO_FLASHCTL_AT_BUF1_WRER_PRGM 0x0382 /* Write erase program */
6973+#define SSB_CHIPCO_FLASHCTL_AT_BUF2_WRER_PRGM 0x0385 /* Write erase program */
6974+#define SSB_CHIPCO_FLASHCTL_AT_BUF1_LOAD 0x0253
6975+#define SSB_CHIPCO_FLASHCTL_AT_BUF2_LOAD 0x0255
6976+#define SSB_CHIPCO_FLASHCTL_AT_BUF1_COMPARE 0x0260
6977+#define SSB_CHIPCO_FLASHCTL_AT_BUF2_COMPARE 0x0261
6978+#define SSB_CHIPCO_FLASHCTL_AT_BUF1_REPROGRAM 0x0258
6979+#define SSB_CHIPCO_FLASHCTL_AT_BUF2_REPROGRAM 0x0259
6980+
6981+/* Status register bits for Atmel flashes */
6982+#define SSB_CHIPCO_FLASHSTA_AT_READY 0x80
6983+#define SSB_CHIPCO_FLASHSTA_AT_MISMATCH 0x40
6984+#define SSB_CHIPCO_FLASHSTA_AT_ID 0x38
6985+#define SSB_CHIPCO_FLASHSTA_AT_ID_SHIFT 3
6986+
6987+
6988+/** OTP **/
6989+
6990+/* OTP regions */
6991+#define SSB_CHIPCO_OTP_HW_REGION SSB_CHIPCO_OTPS_HW_PROTECT
6992+#define SSB_CHIPCO_OTP_SW_REGION SSB_CHIPCO_OTPS_SW_PROTECT
6993+#define SSB_CHIPCO_OTP_CID_REGION SSB_CHIPCO_OTPS_CID_PROTECT
6994+
6995+/* OTP regions (Byte offsets from otp size) */
6996+#define SSB_CHIPCO_OTP_SWLIM_OFF (-8)
6997+#define SSB_CHIPCO_OTP_CIDBASE_OFF 0
6998+#define SSB_CHIPCO_OTP_CIDLIM_OFF 8
6999+
7000+/* Predefined OTP words (Word offset from otp size) */
7001+#define SSB_CHIPCO_OTP_BOUNDARY_OFF (-4)
7002+#define SSB_CHIPCO_OTP_HWSIGN_OFF (-3)
7003+#define SSB_CHIPCO_OTP_SWSIGN_OFF (-2)
7004+#define SSB_CHIPCO_OTP_CIDSIGN_OFF (-1)
7005+
7006+#define SSB_CHIPCO_OTP_CID_OFF 0
7007+#define SSB_CHIPCO_OTP_PKG_OFF 1
7008+#define SSB_CHIPCO_OTP_FID_OFF 2
7009+#define SSB_CHIPCO_OTP_RSV_OFF 3
7010+#define SSB_CHIPCO_OTP_LIM_OFF 4
7011+
7012+#define SSB_CHIPCO_OTP_SIGNATURE 0x578A
7013+#define SSB_CHIPCO_OTP_MAGIC 0x4E56
7014+
7015+
7016+struct ssb_device;
7017+struct ssb_serial_port;
7018+
7019+struct ssb_chipcommon {
7020+ struct ssb_device *dev;
7021+ u32 capabilities;
7022+};
7023+
7024+enum ssb_clkmode {
7025+ SSB_CLKMODE_SLOW,
7026+ SSB_CLKMODE_FAST,
7027+ SSB_CLKMODE_DYNAMIC,
7028+};
7029+
7030+extern void ssb_chipcommon_init(struct ssb_chipcommon *cc);
7031+extern void ssb_chipcommon_exit(struct ssb_chipcommon *cc);
7032+
7033+extern void ssb_chipco_get_clockcontrol(struct ssb_chipcommon *cc,
7034+ u32 *plltype, u32 *n, u32 *m);
7035+extern void ssb_chipco_timing_init(struct ssb_chipcommon *cc,
7036+ unsigned long ns_per_cycle);
7037+
7038+#ifdef CONFIG_SSB_SERIAL
7039+extern int ssb_chipco_serial_init(struct ssb_chipcommon *cc,
7040+ struct ssb_serial_port *ports);
7041+#endif /* CONFIG_SSB_SERIAL */
7042+
7043+#endif /* __KERNEL__ */
7044+#endif /* LINUX_SSB_CHIPCO_H_ */
7045diff -Nru linux-2.6.19.ori/include/linux/ssb_driver_extif.h linux-2.6.19/include/linux/ssb_driver_extif.h
7046--- linux-2.6.19.ori/include/linux/ssb_driver_extif.h 1970-01-01 01:00:00.000000000 +0100
7047+++ linux-2.6.19/include/linux/ssb_driver_extif.h 2006-12-02 19:14:34.000000000 +0100
7048@@ -0,0 +1,159 @@
7049+/*
7050+ * Hardware-specific External Interface I/O core definitions
7051+ * for the BCM47xx family of SiliconBackplane-based chips.
7052+ *
7053+ * The External Interface core supports a total of three external chip selects
7054+ * supporting external interfaces. One of the external chip selects is
7055+ * used for Flash, one is used for PCMCIA, and the other may be
7056+ * programmed to support either a synchronous interface or an
7057+ * asynchronous interface. The asynchronous interface can be used to
7058+ * support external devices such as UARTs and the BCM2019 Bluetooth
7059+ * baseband processor.
7060+ * The external interface core also contains 2 on-chip 16550 UARTs, clock
7061+ * frequency control, a watchdog interrupt timer, and a GPIO interface.
7062+ *
7063+ * Copyright 2005, Broadcom Corporation
7064+ * Copyright 2006, Michael Buesch
7065+ *
7066+ * Licensed under the GPL version 2. See COPYING for details.
7067+ */
7068+#ifndef LINUX_SSB_EXTIFCORE_H_
7069+#define LINUX_SSB_EXTIFCORE_H_
7070+
7071+#ifdef __KERNEL__
7072+
7073+/* external interface address space */
7074+#define SSB_EXTIF_PCMCIA_MEMBASE(x) (x)
7075+#define SSB_EXTIF_PCMCIA_IOBASE(x) ((x) + 0x100000)
7076+#define SSB_EXTIF_PCMCIA_CFGBASE(x) ((x) + 0x200000)
7077+#define SSB_EXTIF_CFGIF_BASE(x) ((x) + 0x800000)
7078+#define SSB_EXTIF_FLASH_BASE(x) ((x) + 0xc00000)
7079+
7080+#define SSB_EXTIF_NR_GPIOOUT 5
7081+/* GPIO NOTE:
7082+ * The multiple instances of output and output enable registers
7083+ * are present to allow driver software for multiple cores to control
7084+ * gpio outputs without needing to share a single register pair.
7085+ * Use the following helper macro to get a register offset value.
7086+ */
7087+#define SSB_EXTIF_GPIO_OUT(index) ({ \
7088+ BUILD_BUG_ON(index >= SSB_EXTIF_NR_GPIOOUT); \
7089+ SSB_EXTIF_GPIO_OUT_BASE + ((index) * 8); \
7090+ })
7091+#define SSB_EXTIF_GPIO_OUTEN(index) ({ \
7092+ BUILD_BUG_ON(index >= SSB_EXTIF_NR_GPIOOUT); \
7093+ SSB_EXTIF_GPIO_OUTEN_BASE + ((index) * 8); \
7094+ })
7095+
7096+/** EXTIF core registers **/
7097+
7098+#define SSB_EXTIF_CTL 0x0000
7099+#define SSB_EXTIF_CTL_UARTEN (1 << 0) /* UART enable */
7100+#define SSB_EXTIF_EXTSTAT 0x0004
7101+#define SSB_EXTIF_EXTSTAT_EMODE (1 << 0) /* Endian mode (ro) */
7102+#define SSB_EXTIF_EXTSTAT_EIRQPIN (1 << 1) /* External interrupt pin (ro) */
7103+#define SSB_EXTIF_EXTSTAT_GPIOIRQPIN (1 << 2) /* GPIO interrupt pin (ro) */
7104+#define SSB_EXTIF_PCMCIA_CFG 0x0010
7105+#define SSB_EXTIF_PCMCIA_MEMWAIT 0x0014
7106+#define SSB_EXTIF_PCMCIA_ATTRWAIT 0x0018
7107+#define SSB_EXTIF_PCMCIA_IOWAIT 0x001C
7108+#define SSB_EXTIF_PROG_CFG 0x0020
7109+#define SSB_EXTIF_PROG_WAITCNT 0x0024
7110+#define SSB_EXTIF_FLASH_CFG 0x0028
7111+#define SSB_EXTIF_FLASH_WAITCNT 0x002C
7112+#define SSB_EXTIF_WATCHDOG 0x0040
7113+#define SSB_EXTIF_CLOCK_N 0x0044
7114+#define SSB_EXTIF_CLOCK_SB 0x0048
7115+#define SSB_EXTIF_CLOCK_PCI 0x004C
7116+#define SSB_EXTIF_CLOCK_MII 0x0050
7117+#define SSB_EXTIF_GPIO_IN 0x0060
7118+#define SSB_EXTIF_GPIO_OUT_BASE 0x0064
7119+#define SSB_EXTIF_GPIO_OUTEN_BASE 0x0068
7120+#define SSB_EXTIF_EJTAG_OUTEN 0x0090
7121+#define SSB_EXTIF_GPIO_INTPOL 0x0094
7122+#define SSB_EXTIF_GPIO_INTMASK 0x0098
7123+#define SSB_EXTIF_UART_DATA 0x0300
7124+#define SSB_EXTIF_UART_TIMER 0x0310
7125+#define SSB_EXTIF_UART_FCR 0x0320
7126+#define SSB_EXTIF_UART_LCR 0x0330
7127+#define SSB_EXTIF_UART_MCR 0x0340
7128+#define SSB_EXTIF_UART_LSR 0x0350
7129+#define SSB_EXTIF_UART_MSR 0x0360
7130+#define SSB_EXTIF_UART_SCRATCH 0x0370
7131+
7132+
7133+
7134+
7135+/* pcmcia/prog/flash_config */
7136+#define SSB_EXTCFG_EN (1 << 0) /* enable */
7137+#define SSB_EXTCFG_MODE 0xE /* mode */
7138+#define SSB_EXTCFG_MODE_SHIFT 1
7139+#define SSB_EXTCFG_MODE_FLASH 0x0 /* flash/asynchronous mode */
7140+#define SSB_EXTCFG_MODE_SYNC 0x2 /* synchronous mode */
7141+#define SSB_EXTCFG_MODE_PCMCIA 0x4 /* pcmcia mode */
7142+#define SSB_EXTCFG_DS16 (1 << 4) /* destsize: 0=8bit, 1=16bit */
7143+#define SSB_EXTCFG_BSWAP (1 << 5) /* byteswap */
7144+#define SSB_EXTCFG_CLKDIV 0xC0 /* clock divider */
7145+#define SSB_EXTCFG_CLKDIV_SHIFT 6
7146+#define SSB_EXTCFG_CLKDIV_2 0x0 /* backplane/2 */
7147+#define SSB_EXTCFG_CLKDIV_3 0x40 /* backplane/3 */
7148+#define SSB_EXTCFG_CLKDIV_4 0x80 /* backplane/4 */
7149+#define SSB_EXTCFG_CLKEN (1 << 8) /* clock enable */
7150+#define SSB_EXTCFG_STROBE (1 << 9) /* size/bytestrobe (synch only) */
7151+
7152+/* pcmcia_memwait */
7153+#define SSB_PCMCIA_MEMW_0 0x0000003F /* waitcount0 */
7154+#define SSB_PCMCIA_MEMW_1 0x00001F00 /* waitcount1 */
7155+#define SSB_PCMCIA_MEMW_1_SHIFT 8
7156+#define SSB_PCMCIA_MEMW_2 0x001F0000 /* waitcount2 */
7157+#define SSB_PCMCIA_MEMW_2_SHIFT 16
7158+#define SSB_PCMCIA_MEMW_3 0x1F000000 /* waitcount3 */
7159+#define SSB_PCMCIA_MEMW_3_SHIFT 24
7160+
7161+/* pcmcia_attrwait */
7162+#define SSB_PCMCIA_ATTW_0 0x0000003F /* waitcount0 */
7163+#define SSB_PCMCIA_ATTW_1 0x00001F00 /* waitcount1 */
7164+#define SSB_PCMCIA_ATTW_1_SHIFT 8
7165+#define SSB_PCMCIA_ATTW_2 0x001F0000 /* waitcount2 */
7166+#define SSB_PCMCIA_ATTW_2_SHIFT 16
7167+#define SSB_PCMCIA_ATTW_3 0x1F000000 /* waitcount3 */
7168+#define SSB_PCMCIA_ATTW_3_SHIFT 24
7169+
7170+/* pcmcia_iowait */
7171+#define SSB_PCMCIA_IOW_0 0x0000003F /* waitcount0 */
7172+#define SSB_PCMCIA_IOW_1 0x00001F00 /* waitcount1 */
7173+#define SSB_PCMCIA_IOW_1_SHIFT 8
7174+#define SSB_PCMCIA_IOW_2 0x001F0000 /* waitcount2 */
7175+#define SSB_PCMCIA_IOW_2_SHIFT 16
7176+#define SSB_PCMCIA_IOW_3 0x1F000000 /* waitcount3 */
7177+#define SSB_PCMCIA_IOW_3_SHIFT 24
7178+
7179+/* prog_waitcount */
7180+#define SSB_PROG_WCNT_0 0x0000001F /* waitcount0 */
7181+#define SSB_PROG_WCNT_1 0x00001F00 /* waitcount1 */
7182+#define SSB_PROG_WCNT_1_SHIFT 8
7183+#define SSB_PROG_WCNT_2 0x001F0000 /* waitcount2 */
7184+#define SSB_PROG_WCNT_2_SHIFT 16
7185+#define SSB_PROG_WCNT_3 0x1F000000 /* waitcount3 */
7186+#define SSB_PROG_WCNT_3_SHIFT 24
7187+
7188+#define SSB_PROG_W0 0x0000000C
7189+#define SSB_PROG_W1 0x00000A00
7190+#define SSB_PROG_W2 0x00020000
7191+#define SSB_PROG_W3 0x01000000
7192+
7193+/* flash_waitcount */
7194+#define SSB_FLASH_WCNT_0 0x0000001F /* waitcount0 */
7195+#define SSB_FLASH_WCNT_1 0x00001F00 /* waitcount1 */
7196+#define SSB_FLASH_WCNT_1_SHIFT 8
7197+#define SSB_FLASH_WCNT_2 0x001F0000 /* waitcount2 */
7198+#define SSB_FLASH_WCNT_2_SHIFT 16
7199+#define SSB_FLASH_WCNT_3 0x1F000000 /* waitcount3 */
7200+#define SSB_FLASH_WCNT_3_SHIFT 24
7201+
7202+/* watchdog */
7203+#define SSB_EXTIF_WATCHDOG_CLK 48000000 /* Hz */
7204+
7205+
7206+#endif /* __KERNEL__ */
7207+#endif /* LINUX_SSB_EXTIFCORE_H_ */
7208diff -Nru linux-2.6.19.ori/include/linux/ssb_driver_mips.h linux-2.6.19/include/linux/ssb_driver_mips.h
7209--- linux-2.6.19.ori/include/linux/ssb_driver_mips.h 1970-01-01 01:00:00.000000000 +0100
7210+++ linux-2.6.19/include/linux/ssb_driver_mips.h 2006-12-02 19:14:34.000000000 +0100
7211@@ -0,0 +1,46 @@
7212+#ifndef LINUX_SSB_MIPSCORE_H_
7213+#define LINUX_SSB_MIPSCORE_H_
7214+
7215+#ifdef __KERNEL__
7216+
7217+#ifdef CONFIG_SSB_DRIVER_MIPS
7218+
7219+struct ssb_device;
7220+
7221+struct ssb_serial_port {
7222+ void *regs;
7223+ unsigned int irq;
7224+ unsigned int baud_base;
7225+ unsigned int reg_shift;
7226+};
7227+
7228+
7229+struct ssb_mipscore {
7230+ struct ssb_device *dev;
7231+
7232+ int nr_serial_ports;
7233+ struct ssb_serial_port serial_ports[4];
7234+
7235+ u32 flash_window;
7236+ u32 flash_window_size;
7237+};
7238+
7239+extern void ssb_mipscore_init(struct ssb_mipscore *mcore);
7240+
7241+extern unsigned int ssb_mips_irq(struct ssb_device *dev);
7242+
7243+
7244+#else /* CONFIG_SSB_DRIVER_MIPS */
7245+
7246+struct ssb_mipscore {
7247+};
7248+
7249+static inline
7250+void ssb_mipscore_init(struct ssb_mipscore *mcore)
7251+{
7252+}
7253+
7254+#endif /* CONFIG_SSB_DRIVER_MIPS */
7255+
7256+#endif /* __KERNEL__ */
7257+#endif /* LINUX_SSB_MIPSCORE_H_ */
7258diff -Nru linux-2.6.19.ori/include/linux/ssb_driver_pci.h linux-2.6.19/include/linux/ssb_driver_pci.h
7259--- linux-2.6.19.ori/include/linux/ssb_driver_pci.h 1970-01-01 01:00:00.000000000 +0100
7260+++ linux-2.6.19/include/linux/ssb_driver_pci.h 2006-12-02 19:14:34.000000000 +0100
7261@@ -0,0 +1,35 @@
7262+#ifndef LINUX_SSB_PCICORE_H_
7263+#define LINUX_SSB_PCICORE_H_
7264+#ifndef __KERNEL__
7265+
7266+
7267+/* PCI core registers. */
7268+#define SSB_PCICORE_CTL 0x0000 /* PCI Control */
7269+#define SSB_PCICORE_ARBCTL 0x0010 /* PCI Arbiter Control */
7270+#define SSB_PCICORE_ISTAT 0x0020 /* Interrupt status */
7271+#define SSB_PCICORE_IMASK 0x0024 /* Interrupt mask */
7272+#define SSB_PCICORE_MBOX 0x0028 /* Backplane to PCI Mailbox */
7273+#define SSB_PCICORE_BCAST_ADDR 0x0050 /* Backplane Broadcast Address */
7274+#define SSB_PCICORE_BCAST_DATA 0x0054 /* Backplane Broadcast Data */
7275+#define SSB_PCICORE_GPIO_IN 0x0060 /* rev >= 2 only */
7276+#define SSB_PCICORE_GPIO_OUT 0x0064 /* rev >= 2 only */
7277+#define SSB_PCICORE_GPIO_ENABLE 0x0068 /* rev >= 2 only */
7278+#define SSB_PCICORE_GPIO_CTL 0x006C /* rev >= 2 only */
7279+#define SSB_PCICORE_TRANS0 0x0100 /* Backplane to PCI translation 0 (sbtopci0) */
7280+#define SSB_PCICORE_TRANS1 0x0104 /* Backplane to PCI translation 1 (sbtopci1) */
7281+#define SSB_PCICORE_TRANS2 0x0108 /* Backplane to PCI translation 2 (dbtopci2) */
7282+#define SSB_PCICORE_TRANS2_MEM 0x00000000
7283+#define SSB_PCICORE_TRANS2_IO 0x00000001
7284+#define SSB_PCICORE_TRANS2_CFG0 0x00000002
7285+#define SSB_PCICORE_TRANS2_CFG1 0x00000003
7286+#define SSB_PCICORE_TRANS2_PREF 0x00000004 /* Prefetch enable */
7287+#define SSB_PCICORE_TRANS2_BURST 0x00000008 /* Burst enable */
7288+#define SSB_PCICORE_TRANS2_MRM 0x00000020 /* Memory Read Multiple */
7289+#define SSB_PCICORE_TRANS2_MASK0 0xfc000000
7290+#define SSB_PCICORE_TRANS2_MASK1 0xfc000000
7291+#define SSB_PCICORE_TRANS2_MASK2 0xc0000000
7292+
7293+
7294+
7295+#endif /* __KERNEL__ */
7296+#endif /* LINUX_SSB_PCICORE_H_ */
7297diff -Nru linux-2.6.19.ori/include/linux/ssb_regs.h linux-2.6.19/include/linux/ssb_regs.h
7298--- linux-2.6.19.ori/include/linux/ssb_regs.h 1970-01-01 01:00:00.000000000 +0100
7299+++ linux-2.6.19/include/linux/ssb_regs.h 2006-12-02 19:14:34.000000000 +0100
7300@@ -0,0 +1,267 @@
7301+#ifndef LINUX_SSB_REGS_H_
7302+#define LINUX_SSB_REGS_H_
7303+#ifdef __KERNEL__
7304+
7305+
7306+/* SiliconBackplane Address Map.
7307+ * All regions may not exist on all chips.
7308+ */
7309+#define SSB_SDRAM_BASE 0x00000000 /* Physical SDRAM */
7310+#define SSB_PCI_MEM 0x08000000 /* Host Mode sb2pcitranslation0 (64 MB) */
7311+#define SSB_PCI_CFG 0x0c000000 /* Host Mode sb2pcitranslation1 (64 MB) */
7312+#define SSB_SDRAM_SWAPPED 0x10000000 /* Byteswapped Physical SDRAM */
7313+#define SSB_ENUM_BASE 0x18000000 /* Enumeration space base */
7314+#define SSB_ENUM_LIMIT 0x18010000 /* Enumeration space limit */
7315+
7316+#define SSB_FLASH2 0x1c000000 /* Flash Region 2 (region 1 shadowed here) */
7317+#define SSB_FLASH2_SZ 0x02000000 /* Size of Flash Region 2 */
7318+
7319+#define SSB_EXTIF_BASE 0x1f000000 /* External Interface region base address */
7320+#define SSB_FLASH1 0x1fc00000 /* Flash Region 1 */
7321+#define SSB_FLASH1_SZ 0x00400000 /* Size of Flash Region 1 */
7322+
7323+#define SSB_PCI_DMA 0x40000000 /* Client Mode sb2pcitranslation2 (1 GB) */
7324+#define SSB_PCI_DMA_SZ 0x40000000 /* Client Mode sb2pcitranslation2 size in bytes */
7325+#define SSB_PCIE_DMA_L32 0x00000000 /* PCIE Client Mode sb2pcitranslation2 (2 ZettaBytes), low 32 bits */
7326+#define SSB_PCIE_DMA_H32 0x80000000 /* PCIE Client Mode sb2pcitranslation2 (2 ZettaBytes), high 32 bits */
7327+#define SSB_EUART (SB_EXTIF_BASE + 0x00800000)
7328+#define SSB_LED (SB_EXTIF_BASE + 0x00900000)
7329+
7330+
7331+/* Enumeration space constants */
7332+#define SSB_CORE_SIZE 0x1000 /* Size of a core MMIO area */
7333+#define SSB_MAX_NR_CORES ((SSB_ENUM_LIMIT - SSB_ENUM_BASE) / SSB_CORE_SIZE)
7334+
7335+
7336+/* mips address */
7337+#define SSB_EJTAG 0xff200000 /* MIPS EJTAG space (2M) */
7338+
7339+
7340+/* SSB PCI config space registers. */
7341+#define SSB_BAR0_WIN 0x80 /* Backplane address space 0 */
7342+#define SSB_BAR1_WIN 0x84 /* Backplane address space 1 */
7343+#define SSB_SPROMCTL 0x88 /* SPROM control */
7344+#define SSB_SPROMCTL_WE 0x10 /* SPROM write enable */
7345+#define SSB_BAR1_CONTROL 0x8c /* Address space 1 burst control */
7346+#define SSB_PCI_IRQS 0x90 /* PCI interrupts */
7347+#define SSB_PCI_IRQMASK 0x94 /* PCI IRQ control and mask (pcirev >= 6 only) */
7348+#define SSB_BACKPLANE_IRQS 0x98 /* Backplane Interrupts */
7349+#define SSB_GPIO_IN 0xB0 /* GPIO Input (pcirev >= 3 only) */
7350+#define SSB_GPIO_OUT 0xB4 /* GPIO Output (pcirev >= 3 only) */
7351+#define SSB_GPIO_OUT_ENABLE 0xB8 /* GPIO Output Enable/Disable (pcirev >= 3 only) */
7352+#define SSB_GPIO_SCS 0x10 /* PCI config space bit 4 for 4306c0 slow clock source */
7353+#define SSB_GPIO_HWRAD 0x20 /* PCI config space GPIO 13 for hw radio disable */
7354+#define SSB_GPIO_XTAL 0x40 /* PCI config space GPIO 14 for Xtal powerup */
7355+#define SSB_GPIO_PLL 0x80 /* PCI config space GPIO 15 for PLL powerdown */
7356+
7357+
7358+#define SSB_BAR0_MAX_RETRIES 50
7359+
7360+/* Silicon backplane configuration register definitions */
7361+#define SSB_IPSFLAG 0x0F08
7362+#define SSB_IPSFLAG_IRQ1 0x0000003F /* which sbflags get routed to mips interrupt 1 */
7363+#define SSB_IPSFLAG_IRQ1_SHIFT 0
7364+#define SSB_IPSFLAG_IRQ2 0x00003F00 /* which sbflags get routed to mips interrupt 2 */
7365+#define SSB_IPSFLAG_IRQ2_SHIFT 8
7366+#define SSB_IPSFLAG_IRQ3 0x003F0000 /* which sbflags get routed to mips interrupt 3 */
7367+#define SSB_IPSFLAG_IRQ3_SHIFT 16
7368+#define SSB_IPSFLAG_IRQ4 0x3F000000 /* which sbflags get routed to mips interrupt 4 */
7369+#define SSB_IPSFLAG_IRQ4_SHIFT 24
7370+#define SSB_TPSFLAG 0x0F18
7371+#define SSB_TPSFLAG_BPFLAG 0x0000003F /* Backplane flag # */
7372+#define SSB_TPSFLAG_ALWAYSIRQ 0x00000040 /* IRQ is always sent on the Backplane */
7373+#define SSB_TMERRLOGA 0x0F48
7374+#define SSB_TMERRLOG 0x0F50
7375+#define SSB_ADMATCH3 0x0F60
7376+#define SSB_ADMATCH2 0x0F68
7377+#define SSB_ADMATCH1 0x0F70
7378+#define SSB_IMSTATE 0x0F90 /* SB Initiator Agent State */
7379+#define SSB_IMSTATE_PC 0x0000000f /* Pipe Count */
7380+#define SSB_IMSTATE_AP_MASK 0x00000030 /* Arbitration Priority */
7381+#define SSB_IMSTATE_AP_BOTH 0x00000000 /* Use both timeslices and token */
7382+#define SSB_IMSTATE_AP_TS 0x00000010 /* Use timeslices only */
7383+#define SSB_IMSTATE_AP_TK 0x00000020 /* Use token only */
7384+#define SSB_IMSTATE_AP_RSV 0x00000030 /* Reserved */
7385+#define SSB_IMSTATE_IBE 0x00020000 /* In Band Error */
7386+#define SSB_IMSTATE_TO 0x00040000 /* Timeout */
7387+#define SSB_INTVEC 0x0F94 /* SB Interrupt Mask */
7388+#define SSB_INTVEC_PCI 0x00000001 /* Enable interrupts for PCI */
7389+#define SSB_INTVEC_ENET0 0x00000002 /* Enable interrupts for enet 0 */
7390+#define SSB_INTVEC_ILINE20 0x00000004 /* Enable interrupts for iline20 */
7391+#define SSB_INTVEC_CODEC 0x00000008 /* Enable interrupts for v90 codec */
7392+#define SSB_INTVEC_USB 0x00000010 /* Enable interrupts for usb */
7393+#define SSB_INTVEC_EXTIF 0x00000020 /* Enable interrupts for external i/f */
7394+#define SSB_INTVEC_ENET1 0x00000040 /* Enable interrupts for enet 1 */
7395+#define SSB_TMSLOW 0x0F98 /* SB Target State Low */
7396+#define SSB_TMSLOW_RESET 0x00000001 /* Reset */
7397+#define SSB_TMSLOW_REJECT 0x00000002 /* Reject */
7398+#define SSB_TMSLOW_CLOCK 0x00010000 /* Clock Enable */
7399+#define SSB_TMSLOW_FGC 0x00020000 /* Force Gated Clocks On */
7400+#define SSB_TMSLOW_PE 0x40000000 /* Power Management Enable */
7401+#define SSB_TMSLOW_BE 0x80000000 /* BIST Enable */
7402+#define SSB_TMSHIGH 0x0F9C /* SB Target State High */
7403+#define SSB_TMSHIGH_SERR 0x00000001 /* S-error */
7404+#define SSB_TMSHIGH_INT 0x00000002 /* Interrupt */
7405+#define SSB_TMSHIGH_BUSY 0x00000004 /* Busy */
7406+#define SSB_TMSHIGH_TO 0x00000020 /* Timeout. Backplane rev >= 2.3 only */
7407+#define SSB_TMSHIGH_COREFL 0x1FFF0000 /* Core specific flags */
7408+#define SSB_TMSHIGH_COREFL_SHIFT 16
7409+#define SSB_TMSHIGH_DMA64 0x10000000 /* 64bit DMA supported */
7410+#define SSB_TMSHIGH_GCR 0x20000000 /* Gated Clock Request */
7411+#define SSB_TMSHIGH_BISTF 0x40000000 /* BIST Failed */
7412+#define SSB_TMSHIGH_BISTD 0x80000000 /* BIST Done */
7413+#define SSB_BWA0 0x0FA0
7414+#define SSB_IMCFGLO 0x0FA8
7415+#define SSB_IMCFGLO_SERTO 0x00000007 /* Service timeout */
7416+#define SSB_IMCFGLO_REQTO 0x00000070 /* Request timeout */
7417+#define SSB_IMCFGLO_REQTO_SHIFT 4
7418+#define SSB_IMCFGLO_CONNID 0x00FF0000 /* Connection ID */
7419+#define SSB_IMCFGLO_CONNID_SHIFT 16
7420+#define SSB_IMCFGHI 0x0FAC
7421+#define SSB_BCONFIG 0x0FC0
7422+#define SSB_BSTATE 0x0FC8
7423+#define SSB_ACTCFG 0x0FD8
7424+#define SSB_FLAGST 0x0FE8
7425+#define SSB_IDLOW 0x0FF8
7426+#define SSB_IDLOW_CFGSP 0x00000003 /* Config Space */
7427+#define SSB_IDLOW_ADDRNGE 0x00000038 /* Address Ranges supported */
7428+#define SSB_IDLOW_ADDRNGE_SHIFT 3
7429+#define SSB_IDLOW_SYNC 0x00000040
7430+#define SSB_IDLOW_INITIATOR 0x00000080
7431+#define SSB_IDLOW_MIBL 0x00000F00 /* Minimum Backplane latency */
7432+#define SSB_IDLOW_MIBL_SHIFT 8
7433+#define SSB_IDLOW_MABL 0x0000F000 /* Maximum Backplane latency */
7434+#define SSB_IDLOW_MABL_SHIFT 12
7435+#define SSB_IDLOW_TIF 0x00010000 /* This Initiator is first */
7436+#define SSB_IDLOW_CCW 0x000C0000 /* Cycle counter width */
7437+#define SSB_IDLOW_CCW_SHIFT 18
7438+#define SSB_IDLOW_TPT 0x00F00000 /* Target ports */
7439+#define SSB_IDLOW_TPT_SHIFT 20
7440+#define SSB_IDLOW_INITP 0x0F000000 /* Initiator ports */
7441+#define SSB_IDLOW_INITP_SHIFT 24
7442+#define SSB_IDLOW_SSBREV 0xF0000000 /* Sonics Backplane Revision code */
7443+#define SSB_IDLOW_SSBREV_22 0x00000000 /* <= 2.2 */
7444+#define SSB_IDLOW_SSBREV_23 0x10000000 /* 2.3 */
7445+#define SSB_IDHIGH 0x0FFC /* SB Identification High */
7446+#define SSB_IDHIGH_RCLO 0x0000000F /* Revision Code (low part) */
7447+#define SSB_IDHIGH_CC 0x00008FF0 /* Core Code */
7448+#define SSB_IDHIGH_CC_SHIFT 4
7449+#define SSB_IDHIGH_RCHI 0x00007000 /* Revision Code (high part) */
7450+#define SSB_IDHIGH_RCHI_SHIFT 8 /* yes, shift 8 is right */
7451+#define SSB_IDHIGH_VC 0xFFFF0000 /* Vendor Code */
7452+#define SSB_IDHIGH_VC_SHIFT 16
7453+
7454+/* SPROM shadow area. If not otherwise noted, fields are
7455+ * two bytes wide. Note that the SPROM can _only_ be read
7456+ * in two-byte quantinies.
7457+ */
7458+#define SSB_SPROMSIZE_WORDS 64
7459+#define SSB_SPROMSIZE_BYTES (SSB_SPROMSIZE_WORDS * sizeof(u16))
7460+#define SSB_SPROM_BASE 0x1000
7461+#define SSB_SPROM_REVISION 0x107E
7462+#define SSB_SPROM_REVISION_REV 0x00FF /* SPROM Revision number */
7463+#define SSB_SPROM_REVISION_CRC 0xFF00 /* SPROM CRC8 value */
7464+#define SSB_SPROM_REVISION_CRC_SHIFT 8
7465+/* SPROM Revision 1 */
7466+#define SSB_SPROM1_SPID 0x1004 /* Subsystem Product ID for PCI */
7467+#define SSB_SPROM1_SVID 0x1006 /* Subsystem Vendor ID for PCI */
7468+#define SSB_SPROM1_PID 0x1008 /* Product ID for PCI */
7469+#define SSB_SPROM1_IL0MAC 0x1048 /* 6 bytes MAC address for 802.11b/g */
7470+#define SSB_SPROM1_ET0MAC 0x104E /* 6 bytes MAC address for Ethernet */
7471+#define SSB_SPROM1_ET1MAC 0x1054 /* 6 bytes MAC address for 802.11a */
7472+#define SSB_SPROM1_ETHPHY 0x105A /* Ethernet PHY settings */
7473+#define SSB_SPROM1_ETHPHY_ET0A 0x001F /* MII Address for enet0 */
7474+#define SSB_SPROM1_ETHPHY_ET1A 0x03E0 /* MII Address for enet1 */
7475+#define SSB_SPROM1_ETHPHY_ET1A_SHIFT 5
7476+#define SSB_SPROM1_ETHPHY_ET0M (1<<14) /* MDIO for enet0 */
7477+#define SSB_SPROM1_ETHPHY_ET1M (1<<15) /* MDIO for enet1 */
7478+#define SSB_SPROM1_BINF 0x105C /* Board info */
7479+#define SSB_SPROM1_BINF_BREV 0x00FF /* Board Revision */
7480+#define SSB_SPROM1_BINF_CCODE 0x0F00 /* Country Code */
7481+#define SSB_SPROM1_BINF_CCODE_SHIFT 8
7482+#define SSB_SPROM1_BINF_ANTA 0x3000 /* Available A-PHY antennas */
7483+#define SSB_SPROM1_BINF_ANTA_SHIFT 12
7484+#define SSB_SPROM1_BINF_ANTBG 0xC000 /* Available B-PHY antennas */
7485+#define SSB_SPROM1_BINF_ANTBG_SHIFT 14
7486+#define SSB_SPROM1_PA0B0 0x105E
7487+#define SSB_SPROM1_PA0B1 0x1060
7488+#define SSB_SPROM1_PA0B2 0x1062
7489+#define SSB_SPROM1_GPIOA 0x1064 /* General Purpose IO pins 0 and 1 */
7490+#define SSB_SPROM1_GPIOA_P0 0x00FF /* Pin 0 */
7491+#define SSB_SPROM1_GPIOA_P1 0xFF00 /* Pin 1 */
7492+#define SSB_SPROM1_GPIOA_P1_SHIFT 8
7493+#define SSB_SPROM1_GPIOB 0x1066 /* General Purpuse IO pins 2 and 3 */
7494+#define SSB_SPROM1_GPIOB_P2 0x00FF /* Pin 2 */
7495+#define SSB_SPROM1_GPIOB_P3 0xFF00 /* Pin 3 */
7496+#define SSB_SPROM1_GPIOB_P3_SHIFT 8
7497+#define SSB_SPROM1_MAXPWR 0x1068 /* Power Amplifier Max Power */
7498+#define SSB_SPROM1_MAXPWR_A 0x00FF /* A-PHY (in dBm Q5.2) */
7499+#define SSB_SPROM1_MAXPWR_BG 0xFF00 /* B-PHY and G-PHY (in dBm Q5.2) */
7500+#define SSB_SPROM1_MAXPWR_BG_SHIFT 8
7501+#define SSB_SPROM1_PA1B0 0x106A
7502+#define SSB_SPROM1_PA1B1 0x106C
7503+#define SSB_SPROM1_PA1B2 0x106E
7504+#define SSB_SPROM1_ITSSI 0x1070 /* Idle TSSI Target */
7505+#define SSB_SPROM1_ITSSI_A 0x00FF /* A-PHY */
7506+#define SSB_SPROM1_ITSSI_BG 0xFF00 /* B-PHY and G-PHY */
7507+#define SSB_SPROM1_ITSSI_BG_SHIFT 8
7508+#define SSB_SPROM1_BFLLO 0x1072 /* Boardflags (low 16 bits) */
7509+#define SSB_SPROM1_AGAIN 0x1074 /* Antenna Gain (in dBm Q5.2) */
7510+#define SSB_SPROM1_AGAIN_A 0x00FF /* A-PHY */
7511+#define SSB_SPROM1_AGAIN_BG 0xFF00 /* B-PHY and G-PHY */
7512+#define SSB_SPROM1_AGAIN_BG_SHIFT 8
7513+#define SSB_SPROM1_OEM 0x1076 /* 8 bytes OEM string (rev 1 only) */
7514+/* SPROM Revision 2 (inherits from rev 1) */
7515+#define SSB_SPROM2_BFLHI 0x1038 /* Boardflags (high 16 bits) */
7516+#define SSB_SPROM2_MAXP_A 0x103A /* A-PHY Max Power */
7517+#define SSB_SPROM2_MAXP_A_HI 0x00FF /* Max Power High */
7518+#define SSB_SPROM2_MAXP_A_LO 0xFF00 /* Max Power Low */
7519+#define SSB_SPROM2_MAXP_A_LO_SHIFT 8
7520+#define SSB_SPROM2_PA1LOB0 0x103C /* A-PHY PowerAmplifier Low Settings */
7521+#define SSB_SPROM2_PA1LOB1 0x103E /* A-PHY PowerAmplifier Low Settings */
7522+#define SSB_SPROM2_PA1LOB2 0x1040 /* A-PHY PowerAmplifier Low Settings */
7523+#define SSB_SPROM2_PA1HIB0 0x1042 /* A-PHY PowerAmplifier High Settings */
7524+#define SSB_SPROM2_PA1HIB1 0x1044 /* A-PHY PowerAmplifier High Settings */
7525+#define SSB_SPROM2_PA1HIB2 0x1046 /* A-PHY PowerAmplifier High Settings */
7526+#define SSB_SPROM2_OPO 0x1078 /* OFDM Power Offset from CCK Level */
7527+#define SSB_SPROM2_OPO_VALUE 0x00FF
7528+#define SSB_SPROM2_OPO_UNUSED 0xFF00
7529+#define SSB_SPROM2_CCODE 0x107C /* Two char Country Code */
7530+/* SPROM Revision 3 (inherits from rev 2) */
7531+#define SSB_SPROM3_OFDMAPO 0x102C /* A-PHY OFDM Mid Power Offset (4 bytes, BigEndian) */
7532+#define SSB_SPROM3_OFDMALPO 0x1030 /* A-PHY OFDM Low Power Offset (4 bytes, BigEndian) */
7533+#define SSB_SPROM3_OFDMAHPO 0x1034 /* A-PHY OFDM High Power Offset (4 bytes, BigEndian) */
7534+#define SSB_SPROM3_GPIOLDC 0x1042 /* GPIO LED Powersave Duty Cycle (4 bytes, BigEndian) */
7535+#define SSB_SPROM3_GPIOLDC_OFF 0x0000FF00 /* Off Count */
7536+#define SSB_SPROM3_GPIOLDC_OFF_SHIFT 8
7537+#define SSB_SPROM3_GPIOLDC_ON 0x00FF0000 /* On Count */
7538+#define SSB_SPROM3_GPIOLDC_ON_SHIFT 16
7539+#define SSB_SPROM3_CCKPO 0x1078 /* CCK Power Offset */
7540+#define SSB_SPROM3_CCKPO_1M 0x000F /* 1M Rate PO */
7541+#define SSB_SPROM3_CCKPO_2M 0x00F0 /* 2M Rate PO */
7542+#define SSB_SPROM3_CCKPO_2M_SHIFT 4
7543+#define SSB_SPROM3_CCKPO_55M 0x0F00 /* 5.5M Rate PO */
7544+#define SSB_SPROM3_CCKPO_55M_SHIFT 8
7545+#define SSB_SPROM3_CCKPO_11M 0xF000 /* 11M Rate PO */
7546+#define SSB_SPROM3_CCKPO_11M_SHIFT 12
7547+#define SSB_SPROM3_OFDMGPO 0x107A /* G-PHY OFDM Power Offset (4 bytes, BigEndian) */
7548+
7549+/* Values for SSB_SPROM1_BINF_CCODE */
7550+enum {
7551+ SSB_SPROM1CCODE_WORLD = 0,
7552+ SSB_SPROM1CCODE_THAILAND,
7553+ SSB_SPROM1CCODE_ISRAEL,
7554+ SSB_SPROM1CCODE_JORDAN,
7555+ SSB_SPROM1CCODE_CHINA,
7556+ SSB_SPROM1CCODE_JAPAN,
7557+ SSB_SPROM1CCODE_USA_CANADA_ANZ,
7558+ SSB_SPROM1CCODE_EUROPE,
7559+ SSB_SPROM1CCODE_USA_LOW,
7560+ SSB_SPROM1CCODE_JAPAN_HIGH,
7561+ SSB_SPROM1CCODE_ALL,
7562+ SSB_SPROM1CCODE_NONE,
7563+};
7564+
7565+
7566+#endif /* __KERNEL__ */
7567+#endif /* LINUX_SSB_REGS_H_ */
Note: See TracBrowser for help on using the repository browser.