Merge aruba support
[openwrt/svn-archive/archive.git] / openwrt / target / linux / aruba-2.6 / patches / 000-aruba.patch
1 diff -Nur linux-2.6.15/arch/mips/aruba/flash_lock.c linux-2.6.15-openwrt/arch/mips/aruba/flash_lock.c
2 --- linux-2.6.15/arch/mips/aruba/flash_lock.c 1970-01-01 01:00:00.000000000 +0100
3 +++ linux-2.6.15-openwrt/arch/mips/aruba/flash_lock.c 2006-01-10 00:32:32.000000000 +0100
4 @@ -0,0 +1,27 @@
5 +#include <linux/module.h>
6 +#include <linux/types.h>
7 +#include <asm/bootinfo.h>
8 +
9 +#define AP70_PROT_ADDR 0xb8010008
10 +#define AP70_PROT_DATA 0x8
11 +#define AP60_PROT_ADDR 0xB8400000
12 +#define AP60_PROT_DATA 0x04000000
13 +
14 +void unlock_ap60_70_flash(void)
15 +{
16 + volatile __u32 val;
17 + switch (mips_machtype) {
18 + case MACH_ARUBA_AP70:
19 + val = *(volatile __u32 *)AP70_PROT_ADDR;
20 + val &= ~(AP70_PROT_DATA);
21 + *(volatile __u32 *)AP70_PROT_ADDR = val;
22 + break;
23 + case MACH_ARUBA_AP65:
24 + case MACH_ARUBA_AP60:
25 + default:
26 + val = *(volatile __u32 *)AP60_PROT_ADDR;
27 + val &= ~(AP60_PROT_DATA);
28 + *(volatile __u32 *)AP60_PROT_ADDR = val;
29 + break;
30 + }
31 +}
32 diff -Nur linux-2.6.15/arch/mips/aruba/idtIRQ.S linux-2.6.15-openwrt/arch/mips/aruba/idtIRQ.S
33 --- linux-2.6.15/arch/mips/aruba/idtIRQ.S 1970-01-01 01:00:00.000000000 +0100
34 +++ linux-2.6.15-openwrt/arch/mips/aruba/idtIRQ.S 2006-01-10 00:32:32.000000000 +0100
35 @@ -0,0 +1,87 @@
36 +/**************************************************************************
37 + *
38 + * BRIEF MODULE DESCRIPTION
39 + * Intterrupt dispatcher code for IDT boards
40 + *
41 + * Copyright 2004 IDT Inc. (rischelp@idt.com)
42 + *
43 + * This program is free software; you can redistribute it and/or modify it
44 + * under the terms of the GNU General Public License as published by the
45 + * Free Software Foundation; either version 2 of the License, or (at your
46 + * option) any later version.
47 + *
48 + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
49 + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
50 + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
51 + * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
52 + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
53 + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
54 + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
55 + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
56 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
57 + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
58 + *
59 + * You should have received a copy of the GNU General Public License along
60 + * with this program; if not, write to the Free Software Foundation, Inc.,
61 + * 675 Mass Ave, Cambridge, MA 02139, USA.
62 + *
63 + *
64 + **************************************************************************
65 + * May 2004 rkt, neb
66 + *
67 + * Initial Release
68 + *
69 + *
70 + *
71 + **************************************************************************
72 + */
73 +
74 +
75 +#include <asm/asm.h>
76 +#include <asm/mipsregs.h>
77 +#include <asm/regdef.h>
78 +#include <asm/stackframe.h>
79 +
80 + .text
81 + .set noreorder
82 + .set noat
83 + .align 5
84 + NESTED(idtIRQ, PT_SIZE, sp)
85 + .set noat
86 + SAVE_ALL
87 + CLI
88 +
89 + .set at
90 + .set noreorder
91 +
92 + /* Get the pending interrupts */
93 + mfc0 t0, CP0_CAUSE
94 + nop
95 +
96 + /* Isolate the allowed ones by anding the irq mask */
97 + mfc0 t2, CP0_STATUS
98 + move a1, sp /* need a nop here, hence we anticipate */
99 + andi t0, CAUSEF_IP
100 + and t0, t2
101 +
102 + /* check for r4k counter/timer IRQ. */
103 +
104 + andi t1, t0, CAUSEF_IP7
105 + beqz t1, 1f
106 + nop
107 +
108 + jal aruba_timer_interrupt
109 +
110 + li a0, 7
111 +
112 + j ret_from_irq
113 + nop
114 +1:
115 + jal aruba_irqdispatch
116 + move a0, t0
117 + j ret_from_irq
118 + nop
119 +
120 + END(idtIRQ)
121 +
122 +
123 diff -Nur linux-2.6.15/arch/mips/aruba/irq.c linux-2.6.15-openwrt/arch/mips/aruba/irq.c
124 --- linux-2.6.15/arch/mips/aruba/irq.c 1970-01-01 01:00:00.000000000 +0100
125 +++ linux-2.6.15-openwrt/arch/mips/aruba/irq.c 2006-01-10 00:32:32.000000000 +0100
126 @@ -0,0 +1,394 @@
127 +/**************************************************************************
128 + *
129 + * BRIEF MODULE DESCRIPTION
130 + * Interrupt routines for IDT EB434 boards
131 + *
132 + * Copyright 2004 IDT Inc. (rischelp@idt.com)
133 + *
134 + * This program is free software; you can redistribute it and/or modify it
135 + * under the terms of the GNU General Public License as published by the
136 + * Free Software Foundation; either version 2 of the License, or (at your
137 + * option) any later version.
138 + *
139 + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
140 + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
141 + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
142 + * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
143 + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
144 + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
145 + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
146 + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
147 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
148 + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
149 + *
150 + * You should have received a copy of the GNU General Public License along
151 + * with this program; if not, write to the Free Software Foundation, Inc.,
152 + * 675 Mass Ave, Cambridge, MA 02139, USA.
153 + *
154 + *
155 + **************************************************************************
156 + * May 2004 rkt, neb
157 + *
158 + * Initial Release
159 + *
160 + *
161 + *
162 + **************************************************************************
163 + */
164 +
165 +#include <linux/errno.h>
166 +#include <linux/init.h>
167 +#include <linux/kernel_stat.h>
168 +#include <linux/module.h>
169 +#include <linux/signal.h>
170 +#include <linux/sched.h>
171 +#include <linux/types.h>
172 +#include <linux/interrupt.h>
173 +#include <linux/ioport.h>
174 +#include <linux/timex.h>
175 +#include <linux/slab.h>
176 +#include <linux/random.h>
177 +#include <linux/delay.h>
178 +
179 +#include <asm/bitops.h>
180 +#include <asm/bootinfo.h>
181 +#include <asm/io.h>
182 +#include <asm/mipsregs.h>
183 +#include <asm/system.h>
184 +#include <asm/idt-boards/rc32434/rc32434.h>
185 +#include <asm/idt-boards/rc32434/rc32434_gpio.h>
186 +
187 +#include <asm/irq.h>
188 +
189 +#undef DEBUG_IRQ
190 +#ifdef DEBUG_IRQ
191 +/* note: prints function name for you */
192 +#define DPRINTK(fmt, args...) printk("%s: " fmt, __FUNCTION__ , ## args)
193 +#else
194 +#define DPRINTK(fmt, args...)
195 +#endif
196 +
197 +extern asmlinkage void idtIRQ(void);
198 +static unsigned int startup_irq(unsigned int irq);
199 +static void end_irq(unsigned int irq_nr);
200 +static void mask_and_ack_irq(unsigned int irq_nr);
201 +static void aruba_enable_irq(unsigned int irq_nr);
202 +static void aruba_disable_irq(unsigned int irq_nr);
203 +
204 +extern void __init init_generic_irq(void);
205 +
206 +typedef struct {
207 + u32 mask;
208 + volatile u32 *base_addr;
209 +} intr_group_t;
210 +
211 +static const intr_group_t intr_group_merlot[NUM_INTR_GROUPS] = {
212 + {0xffffffff, (u32 *) KSEG1ADDR(IC_GROUP0_PEND + 0)},
213 +};
214 +
215 +#define READ_PEND_MERLOT(base) (*((volatile unsigned long *)(0xbc003010)))
216 +#define READ_MASK_MERLOT(base) (*((volatile unsigned long *)(0xbc003010 + 4)))
217 +#define WRITE_MASK_MERLOT(base, val) ((*((volatile unsigned long *)((0xbc003010) + 4))) = (val))
218 +
219 +static const intr_group_t intr_group_muscat[NUM_INTR_GROUPS] = {
220 + {0x0000efff, (u32 *) KSEG1ADDR(IC_GROUP0_PEND + 0 * IC_GROUP_OFFSET)},
221 + {0x00001fff, (u32 *) KSEG1ADDR(IC_GROUP0_PEND + 1 * IC_GROUP_OFFSET)},
222 + {0x00000007, (u32 *) KSEG1ADDR(IC_GROUP0_PEND + 2 * IC_GROUP_OFFSET)},
223 + {0x0003ffff, (u32 *) KSEG1ADDR(IC_GROUP0_PEND + 3 * IC_GROUP_OFFSET)},
224 + {0xffffffff, (u32 *) KSEG1ADDR(IC_GROUP0_PEND + 4 * IC_GROUP_OFFSET)}
225 +};
226 +
227 +#define READ_PEND_MUSCAT(base) (*(base))
228 +#define READ_MASK_MUSCAT(base) (*(base + 2))
229 +#define WRITE_MASK_MUSCAT(base, val) (*(base + 2) = (val))
230 +
231 +static inline int irq_to_group(unsigned int irq_nr)
232 +{
233 + switch (mips_machtype) {
234 + case MACH_ARUBA_AP70:
235 + return ((irq_nr - GROUP0_IRQ_BASE) >> 5);
236 + case MACH_ARUBA_AP65:
237 + case MACH_ARUBA_AP60:
238 + default:
239 + return 0;
240 + }
241 +}
242 +
243 +static inline int group_to_ip(unsigned int group)
244 +{
245 + switch (mips_machtype) {
246 + case MACH_ARUBA_AP70:
247 + return group + 2;
248 + case MACH_ARUBA_AP65:
249 + case MACH_ARUBA_AP60:
250 + default:
251 + return 6;
252 + }
253 +}
254 +
255 +static inline void enable_local_irq(unsigned int ip)
256 +{
257 + int ipnum = 0x100 << ip;
258 + clear_c0_cause(ipnum);
259 + set_c0_status(ipnum);
260 +}
261 +
262 +static inline void disable_local_irq(unsigned int ip)
263 +{
264 + int ipnum = 0x100 << ip;
265 + clear_c0_status(ipnum);
266 +}
267 +
268 +static inline void ack_local_irq(unsigned int ip)
269 +{
270 + int ipnum = 0x100 << ip;
271 + clear_c0_cause(ipnum);
272 +}
273 +
274 +static void aruba_enable_irq(unsigned int irq_nr)
275 +{
276 + int ip = irq_nr - GROUP0_IRQ_BASE;
277 + unsigned int group, intr_bit;
278 + volatile unsigned int *addr;
279 + if (ip < 0) {
280 + enable_local_irq(irq_nr);
281 + } else {
282 + // calculate group
283 + switch (mips_machtype) {
284 + case MACH_ARUBA_AP70:
285 + group = ip >> 5;
286 + break;
287 + case MACH_ARUBA_AP65:
288 + case MACH_ARUBA_AP60:
289 + default:
290 + group = 0;
291 + break;
292 + }
293 +
294 + // calc interrupt bit within group
295 + ip -= (group << 5);
296 + intr_bit = 1 << ip;
297 +
298 + // first enable the IP mapped to this IRQ
299 + enable_local_irq(group_to_ip(group));
300 +
301 + switch (mips_machtype) {
302 + case MACH_ARUBA_AP70:
303 + addr = intr_group_muscat[group].base_addr;
304 + // unmask intr within group
305 + WRITE_MASK_MUSCAT(addr, READ_MASK_MUSCAT(addr) & ~intr_bit);
306 + break;
307 + case MACH_ARUBA_AP65:
308 + case MACH_ARUBA_AP60:
309 + default:
310 + addr = intr_group_merlot[group].base_addr;
311 + WRITE_MASK_MERLOT(addr, (READ_MASK_MERLOT(addr) | intr_bit));
312 + break;
313 + }
314 + }
315 +}
316 +
317 +static void aruba_disable_irq(unsigned int irq_nr)
318 +{
319 + int ip = irq_nr - GROUP0_IRQ_BASE;
320 + unsigned int group, intr_bit, mask;
321 + volatile unsigned int *addr;
322 +
323 + // calculate group
324 + switch (mips_machtype) {
325 + case MACH_ARUBA_AP70:
326 + group = ip >> 5;
327 + break;
328 + case MACH_ARUBA_AP65:
329 + case MACH_ARUBA_AP60:
330 + default:
331 + group = 0;
332 + break;
333 + }
334 +
335 + // calc interrupt bit within group
336 + ip -= group << 5;
337 + intr_bit = 1 << ip;
338 +
339 + switch (mips_machtype) {
340 + case MACH_ARUBA_AP70:
341 + addr = intr_group_muscat[group].base_addr;
342 + // mask intr within group
343 + mask = READ_MASK_MUSCAT(addr);
344 + mask |= intr_bit;
345 + WRITE_MASK_MUSCAT(addr, mask);
346 +
347 + /*
348 + if there are no more interrupts enabled in this
349 + group, disable corresponding IP
350 + */
351 + if (mask == intr_group_muscat[group].mask)
352 + disable_local_irq(group_to_ip(group));
353 + break;
354 + case MACH_ARUBA_AP65:
355 + case MACH_ARUBA_AP60:
356 + default:
357 + addr = intr_group_merlot[group].base_addr;
358 + addr = intr_group_merlot[group].base_addr;
359 + // mask intr within group
360 + WRITE_MASK_MERLOT(addr, (READ_MASK_MERLOT(addr) & ~intr_bit));
361 + if (READ_MASK_MERLOT(addr))
362 + disable_local_irq(group_to_ip(group));
363 + break;
364 + }
365 +}
366 +
367 +static unsigned int startup_irq(unsigned int irq_nr)
368 +{
369 + aruba_enable_irq(irq_nr);
370 + return 0;
371 +}
372 +
373 +static void shutdown_irq(unsigned int irq_nr)
374 +{
375 + aruba_disable_irq(irq_nr);
376 + return;
377 +}
378 +
379 +static void mask_and_ack_irq(unsigned int irq_nr)
380 +{
381 + aruba_disable_irq(irq_nr);
382 + ack_local_irq(group_to_ip(irq_to_group(irq_nr)));
383 +}
384 +
385 +static void end_irq(unsigned int irq_nr)
386 +{
387 +
388 + int ip = irq_nr - GROUP0_IRQ_BASE;
389 + unsigned int intr_bit, group;
390 + volatile unsigned int *addr;
391 +
392 + if (irq_desc[irq_nr].status & (IRQ_DISABLED | IRQ_INPROGRESS)) {
393 + printk("warning: end_irq %d did not enable (%x)\n",
394 + irq_nr, irq_desc[irq_nr].status);
395 + }
396 +
397 + switch (mips_machtype) {
398 + case MACH_ARUBA_AP70:
399 + if (irq_nr == GROUP4_IRQ_BASE + 9) idt_gpio->gpioistat &= 0xfffffdff;
400 + else if (irq_nr == GROUP4_IRQ_BASE + 10) idt_gpio->gpioistat &= 0xfffffbff;
401 + else if (irq_nr == GROUP4_IRQ_BASE + 11) idt_gpio->gpioistat &= 0xfffff7ff;
402 + else if (irq_nr == GROUP4_IRQ_BASE + 12) idt_gpio->gpioistat &= 0xffffefff;
403 +
404 + group = ip >> 5;
405 +
406 + // calc interrupt bit within group
407 + ip -= (group << 5);
408 + intr_bit = 1 << ip;
409 +
410 + // first enable the IP mapped to this IRQ
411 + enable_local_irq(group_to_ip(group));
412 +
413 + addr = intr_group_muscat[group].base_addr;
414 + // unmask intr within group
415 + WRITE_MASK_MUSCAT(addr, READ_MASK_MUSCAT(addr) & ~intr_bit);
416 + break;
417 + case MACH_ARUBA_AP65:
418 + case MACH_ARUBA_AP60:
419 + group = 0;
420 + // calc interrupt bit within group
421 + intr_bit = 1 << ip;
422 + // first enable the IP mapped to this IRQ
423 + enable_local_irq(group_to_ip(group));
424 + addr = intr_group_merlot[group].base_addr;
425 + // unmask intr within group
426 + WRITE_MASK_MERLOT(addr, (READ_MASK_MERLOT(addr) | intr_bit));
427 + break;
428 + }
429 +}
430 +
431 +static struct hw_interrupt_type aruba_irq_type = {
432 + .typename = "IDT434",
433 + .startup = startup_irq,
434 + .shutdown = shutdown_irq,
435 + .enable = aruba_enable_irq,
436 + .disable = aruba_disable_irq,
437 + .ack = mask_and_ack_irq,
438 + .end = end_irq,
439 +};
440 +
441 +void __init arch_init_irq(void)
442 +{
443 + int i;
444 + printk("Initializing IRQ's: %d out of %d\n", RC32434_NR_IRQS, NR_IRQS);
445 + memset(irq_desc, 0, sizeof(irq_desc));
446 + set_except_vector(0, idtIRQ);
447 +
448 + for (i = 0; i < RC32434_NR_IRQS; i++) {
449 + irq_desc[i].status = IRQ_DISABLED;
450 + irq_desc[i].action = NULL;
451 + irq_desc[i].depth = 1;
452 + irq_desc[i].handler = &aruba_irq_type;
453 + spin_lock_init(&irq_desc[i].lock);
454 + }
455 +
456 + switch (mips_machtype) {
457 + case MACH_ARUBA_AP70:
458 + break;
459 + case MACH_ARUBA_AP65:
460 + case MACH_ARUBA_AP60:
461 + default:
462 + WRITE_MASK_MERLOT(intr_group_merlot[0].base_addr, 0);
463 + *((volatile unsigned long *)0xbc003014) = 0x10;
464 + break;
465 + }
466 +}
467 +
468 +/* Main Interrupt dispatcher */
469 +void aruba_irqdispatch(unsigned long cp0_cause, struct pt_regs *regs)
470 +{
471 + unsigned int pend, group, ip;
472 + volatile unsigned int *addr;
473 + switch (mips_machtype) {
474 + case MACH_ARUBA_AP70:
475 + if ((ip = (cp0_cause & 0x7c00))) {
476 + group = 21 - rc32434_clz(ip);
477 +
478 + addr = intr_group_muscat[group].base_addr;
479 +
480 + pend = READ_PEND_MUSCAT(addr);
481 + pend &= ~READ_MASK_MUSCAT(addr); // only unmasked interrupts
482 + pend = 39 - rc32434_clz(pend);
483 + do_IRQ((group << 5) + pend, regs);
484 + }
485 + break;
486 + case MACH_ARUBA_AP65:
487 + case MACH_ARUBA_AP60:
488 + default:
489 + #define MERLOT_WLAN1_IRQ 2 // bit 10 in CP0_status register
490 + #define MERLOT_ENET_IRQ 3 // bit 11 in CP0_status register
491 + #define MERLOT_WLAN_IRQ 5 // bit 13 in CP0_status register
492 + #define MERLOT_MISC_IRQ 6 // bit 14 in CP0_status register = GROUP 0
493 +
494 + if (cp0_cause & (1 << (8 + MERLOT_MISC_IRQ))) {
495 + // Misc Interrupt
496 + group = 0;
497 + addr = intr_group_merlot[group].base_addr;
498 + pend = READ_PEND_MERLOT(addr);
499 + pend &= READ_MASK_MERLOT(addr); // only unmasked interrupts
500 + /* handle one misc interrupt at a time */
501 + while (pend) {
502 + unsigned int intr_bit, irq_nr;
503 + intr_bit = pend ^ (pend - 1);
504 + irq_nr = ((31 - rc32434_clz(pend)) + GROUP0_IRQ_BASE);
505 + do_IRQ(irq_nr, regs);
506 + do_IRQ(irq_nr, regs);
507 + pend &= ~intr_bit;
508 + }
509 + }
510 +
511 + if (cp0_cause & (1 << (8 + MERLOT_WLAN_IRQ))) {
512 + do_IRQ(MERLOT_WLAN_IRQ, regs);
513 + }
514 +
515 + if (cp0_cause & (1 << (8 + MERLOT_ENET_IRQ))) {
516 + do_IRQ(MERLOT_ENET_IRQ, regs);
517 + }
518 + break;
519 + }
520 +}
521 diff -Nur linux-2.6.15/arch/mips/aruba/Makefile linux-2.6.15-openwrt/arch/mips/aruba/Makefile
522 --- linux-2.6.15/arch/mips/aruba/Makefile 1970-01-01 01:00:00.000000000 +0100
523 +++ linux-2.6.15-openwrt/arch/mips/aruba/Makefile 2006-01-10 00:32:32.000000000 +0100
524 @@ -0,0 +1,49 @@
525 +###############################################################################
526 +#
527 +# BRIEF MODULE DESCRIPTION
528 +# Makefile for IDT EB434 BSP
529 +#
530 +# Copyright 2004 IDT Inc. (rischelp@idt.com)
531 +#
532 +# This program is free software; you can redistribute it and/or modify it
533 +# under the terms of the GNU General Public License as published by the
534 +# Free Software Foundation; either version 2 of the License, or (at your
535 +# option) any later version.
536 +#
537 +# THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
538 +# WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
539 +# MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
540 +# NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
541 +# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
542 +# NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
543 +# USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
544 +# ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
545 +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
546 +# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
547 +#
548 +# You should have received a copy of the GNU General Public License along
549 +# with this program; if not, write to the Free Software Foundation, Inc.,
550 +# 675 Mass Ave, Cambridge, MA 02139, USA.
551 +#
552 +#
553 +###############################################################################
554 +# May 2004 rkt, neb
555 +#
556 +# Initial Release
557 +#
558 +#
559 +#
560 +###############################################################################
561 +
562 +
563 +# .S.s:
564 +# $(CPP) $(CFLAGS) $< -o $*.s
565 +# .S.o:
566 +# $(CC) $(CFLAGS) -c $< -o $*.o
567 +
568 +obj-y := prom.o setup.o idtIRQ.o irq.o time.o flash_lock.o wdt_merlot.o
569 +obj-$(CONFIG_SERIAL_8250) += serial.o
570 +
571 +subdir-y += nvram
572 +obj-y += nvram/built-in.o
573 +
574 diff -Nur linux-2.6.15/arch/mips/aruba/nvram/Makefile linux-2.6.15-openwrt/arch/mips/aruba/nvram/Makefile
575 --- linux-2.6.15/arch/mips/aruba/nvram/Makefile 1970-01-01 01:00:00.000000000 +0100
576 +++ linux-2.6.15-openwrt/arch/mips/aruba/nvram/Makefile 2006-01-10 00:32:32.000000000 +0100
577 @@ -0,0 +1,46 @@
578 +###############################################################################
579 +#
580 +# BRIEF MODULE DESCRIPTION
581 +# Makefile for IDT EB434 nvram access routines
582 +#
583 +# Copyright 2004 IDT Inc. (rischelp@idt.com)
584 +#
585 +# This program is free software; you can redistribute it and/or modify it
586 +# under the terms of the GNU General Public License as published by the
587 +# Free Software Foundation; either version 2 of the License, or (at your
588 +# option) any later version.
589 +#
590 +# THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
591 +# WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
592 +# MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
593 +# NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
594 +# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
595 +# NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
596 +# USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
597 +# ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
598 +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
599 +# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
600 +#
601 +# You should have received a copy of the GNU General Public License along
602 +# with this program; if not, write to the Free Software Foundation, Inc.,
603 +# 675 Mass Ave, Cambridge, MA 02139, USA.
604 +#
605 +#
606 +###############################################################################
607 +# May 2004 rkt, neb
608 +#
609 +# Initial Release
610 +#
611 +#
612 +#
613 +###############################################################################
614 +
615 +obj-y := nvram434.o
616 +obj-m := $(O_TARGET)
617 +
618 +
619 +
620 +
621 +
622 +
623 +
624 diff -Nur linux-2.6.15/arch/mips/aruba/nvram/nvram434.c linux-2.6.15-openwrt/arch/mips/aruba/nvram/nvram434.c
625 --- linux-2.6.15/arch/mips/aruba/nvram/nvram434.c 1970-01-01 01:00:00.000000000 +0100
626 +++ linux-2.6.15-openwrt/arch/mips/aruba/nvram/nvram434.c 2006-01-10 00:32:32.000000000 +0100
627 @@ -0,0 +1,392 @@
628 +/**************************************************************************
629 + *
630 + * BRIEF MODULE DESCRIPTION
631 + * nvram interface routines.
632 + *
633 + * Copyright 2004 IDT Inc. (rischelp@idt.com)
634 + *
635 + * This program is free software; you can redistribute it and/or modify it
636 + * under the terms of the GNU General Public License as published by the
637 + * Free Software Foundation; either version 2 of the License, or (at your
638 + * option) any later version.
639 + *
640 + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
641 + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
642 + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
643 + * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
644 + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
645 + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
646 + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
647 + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
648 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
649 + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
650 + *
651 + * You should have received a copy of the GNU General Public License along
652 + * with this program; if not, write to the Free Software Foundation, Inc.,
653 + * 675 Mass Ave, Cambridge, MA 02139, USA.
654 + *
655 + *
656 + **************************************************************************
657 + * May 2004 rkt, neb
658 + *
659 + * Initial Release
660 + *
661 + *
662 + *
663 + **************************************************************************
664 + */
665 +
666 +#include <linux/ctype.h>
667 +#include <linux/string.h>
668 +
669 +//#include <asm/ds1553rtc.h>
670 +#include "nvram434.h"
671 +#define NVRAM_BASE 0xbfff8000
672 +
673 +extern void setenv (char *e, char *v, int rewrite);
674 +extern void unsetenv (char *e);
675 +extern void mapenv (int (*func)(char *, char *));
676 +extern char *getenv (char *s);
677 +extern void purgeenv(void);
678 +
679 +static void nvram_initenv(void);
680 +
681 +static unsigned char
682 +nvram_getbyte(int offs)
683 +{
684 + return(*((unsigned char*)(NVRAM_BASE + offs)));
685 +}
686 +
687 +static void
688 +nvram_setbyte(int offs, unsigned char val)
689 +{
690 + unsigned char* nvramDataPointer = (unsigned char*)(NVRAM_BASE + offs);
691 +
692 + *nvramDataPointer = val;
693 +}
694 +
695 +/*
696 + * BigEndian!
697 + */
698 +static unsigned short
699 +nvram_getshort(int offs)
700 +{
701 + return((nvram_getbyte(offs) << 8) | nvram_getbyte(offs + 1));
702 +}
703 +
704 +static void
705 +nvram_setshort(int offs, unsigned short val)
706 +{
707 + nvram_setbyte(offs, (unsigned char)((val >> 8) & 0xff));
708 + nvram_setbyte(offs + 1, (unsigned char)(val & 0xff));
709 +}
710 +#if 0
711 +static unsigned int
712 +nvram_getint(int offs)
713 +{
714 + unsigned int val;
715 + val = nvram_getbyte(offs) << 24;
716 + val |= nvram_getbyte(offs + 1) << 16;
717 + val |= nvram_getbyte(offs + 2) << 8;
718 + val |= nvram_getbyte(offs + 3);
719 + return(val);
720 +}
721 +
722 +static void
723 +nvram_setint(int offs, unsigned int val)
724 +{
725 + nvram_setbyte(offs, val >> 24);
726 + nvram_setbyte(offs + 1, val >> 16);
727 + nvram_setbyte(offs + 2, val >> 8);
728 + nvram_setbyte(offs + 3, val);
729 +}
730 +#endif
731 +/*
732 + * calculate NVRAM checksum
733 + */
734 +static unsigned short
735 +nvram_calcsum(void)
736 +{
737 + unsigned short sum = NV_MAGIC;
738 + int i;
739 +
740 + for (i = ENV_BASE; i < ENV_TOP; i += 2)
741 + sum += nvram_getshort(i);
742 + return(sum);
743 +}
744 +
745 +/*
746 + * update the nvram checksum
747 + */
748 +static void
749 +nvram_updatesum (void)
750 +{
751 + nvram_setshort(NVOFF_CSUM, nvram_calcsum());
752 +}
753 +
754 +/*
755 + * test validity of nvram by checksumming it
756 + */
757 +static int
758 +nvram_isvalid(void)
759 +{
760 + static int is_valid;
761 +
762 + if (is_valid)
763 + return(1);
764 +
765 + if (nvram_getshort(NVOFF_MAGIC) != NV_MAGIC) {
766 + printk("nvram_isvalid FAILED\n");
767 + //nvram_initenv();
768 + }
769 + is_valid = 1;
770 + return(1);
771 +}
772 +
773 +/* return nvram address of environment string */
774 +static int
775 +nvram_matchenv(char *s)
776 +{
777 + int envsize, envp, n, i, varsize;
778 + char *var;
779 +
780 + envsize = nvram_getshort(NVOFF_ENVSIZE);
781 +
782 + if (envsize > ENV_AVAIL)
783 + return(0); /* sanity */
784 +
785 + envp = ENV_BASE;
786 +
787 + if ((n = strlen (s)) > 255)
788 + return(0);
789 +
790 + while (envsize > 0) {
791 + varsize = nvram_getbyte(envp);
792 + if (varsize == 0 || (envp + varsize) > ENV_TOP)
793 + return(0); /* sanity */
794 + for (i = envp + 1, var = s; i <= envp + n; i++, var++) {
795 + char c1 = nvram_getbyte(i);
796 + char c2 = *var;
797 + if (islower(c1))
798 + c1 = toupper(c1);
799 + if (islower(c2))
800 + c2 = toupper(c2);
801 + if (c1 != c2)
802 + break;
803 + }
804 + if (i > envp + n) { /* match so far */
805 + if (n == varsize - 1) /* match on boolean */
806 + return(envp);
807 + if (nvram_getbyte(i) == '=') /* exact match on variable */
808 + return(envp);
809 + }
810 + envsize -= varsize;
811 + envp += varsize;
812 + }
813 + return(0);
814 +}
815 +
816 +static void nvram_initenv(void)
817 +{
818 + nvram_setshort(NVOFF_MAGIC, NV_MAGIC);
819 + nvram_setshort(NVOFF_ENVSIZE, 0);
820 +
821 + nvram_updatesum();
822 +}
823 +
824 +static void
825 +nvram_delenv(char *s)
826 +{
827 + int nenvp, envp, envsize, nbytes;
828 +
829 + envp = nvram_matchenv(s);
830 + if (envp == 0)
831 + return;
832 +
833 + nenvp = envp + nvram_getbyte(envp);
834 + envsize = nvram_getshort(NVOFF_ENVSIZE);
835 + nbytes = envsize - (nenvp - ENV_BASE);
836 + nvram_setshort(NVOFF_ENVSIZE, envsize - (nenvp - envp));
837 + while (nbytes--) {
838 + nvram_setbyte(envp, nvram_getbyte(nenvp));
839 + envp++;
840 + nenvp++;
841 + }
842 + nvram_updatesum();
843 +}
844 +
845 +static int
846 +nvram_setenv(char *s, char *v)
847 +{
848 + int ns, nv, total;
849 + int envp;
850 +
851 + if (!nvram_isvalid())
852 + return(-1);
853 +
854 + nvram_delenv(s);
855 + ns = strlen(s);
856 + if (ns == 0)
857 + return (-1);
858 + if (v && *v) {
859 + nv = strlen(v);
860 + total = ns + nv + 2;
861 + }
862 + else {
863 + nv = 0;
864 + total = ns + 1;
865 + }
866 + if (total > 255 || total > ENV_AVAIL - nvram_getshort(NVOFF_ENVSIZE))
867 + return(-1);
868 +
869 + envp = ENV_BASE + nvram_getshort(NVOFF_ENVSIZE);
870 +
871 + nvram_setbyte(envp, (unsigned char) total);
872 + envp++;
873 +
874 + while (ns--) {
875 + nvram_setbyte(envp, *s);
876 + envp++;
877 + s++;
878 + }
879 +
880 + if (nv) {
881 + nvram_setbyte(envp, '=');
882 + envp++;
883 + while (nv--) {
884 + nvram_setbyte(envp, *v);
885 + envp++;
886 + v++;
887 + }
888 + }
889 + nvram_setshort(NVOFF_ENVSIZE, envp-ENV_BASE);
890 + nvram_updatesum();
891 + return 0;
892 +}
893 +
894 +static char *
895 +nvram_getenv(char *s)
896 +{
897 + static char buf[256]; /* FIXME: this cannot be static */
898 + int envp, ns, nbytes, i;
899 +
900 + if (!nvram_isvalid())
901 + return "INVALID NVRAM"; //((char *)0);
902 +
903 + envp = nvram_matchenv(s);
904 + if (envp == 0)
905 + return "NOT FOUND"; //((char *)0);
906 + ns = strlen(s);
907 + if (nvram_getbyte(envp) == ns + 1) /* boolean */
908 + buf[0] = '\0';
909 + else {
910 + nbytes = nvram_getbyte(envp) - (ns + 2);
911 + envp += ns + 2;
912 + for (i = 0; i < nbytes; i++)
913 + buf[i] = nvram_getbyte(envp++);
914 + buf[i] = '\0';
915 + }
916 + return(buf);
917 +}
918 +
919 +static void
920 +nvram_unsetenv(char *s)
921 +{
922 + if (!nvram_isvalid())
923 + return;
924 +
925 + nvram_delenv(s);
926 +}
927 +
928 +/*
929 + * apply func to each string in environment
930 + */
931 +static void
932 +nvram_mapenv(int (*func)(char *, char *))
933 +{
934 + int envsize, envp, n, i, seeneql;
935 + char name[256], value[256];
936 + char c, *s;
937 +
938 + if (!nvram_isvalid())
939 + return;
940 +
941 + envsize = nvram_getshort(NVOFF_ENVSIZE);
942 + envp = ENV_BASE;
943 +
944 + while (envsize > 0) {
945 + value[0] = '\0';
946 + seeneql = 0;
947 + s = name;
948 + n = nvram_getbyte(envp);
949 + for (i = envp + 1; i < envp + n; i++) {
950 + c = nvram_getbyte(i);
951 + if ((c == '=') && !seeneql) {
952 + *s = '\0';
953 + s = value;
954 + seeneql = 1;
955 + continue;
956 + }
957 + *s++ = c;
958 + }
959 + *s = '\0';
960 + (*func)(name, value);
961 + envsize -= n;
962 + envp += n;
963 + }
964 +}
965 +#if 0
966 +static unsigned int
967 +digit(char c)
968 +{
969 + if ('0' <= c && c <= '9')
970 + return (c - '0');
971 + if ('A' <= c && c <= 'Z')
972 + return (10 + c - 'A');
973 + if ('a' <= c && c <= 'z')
974 + return (10 + c - 'a');
975 + return (~0);
976 +}
977 +#endif
978 +/*
979 + * Wrappers to allow 'special' environment variables to get processed
980 + */
981 +void
982 +setenv(char *e, char *v, int rewrite)
983 +{
984 + if (nvram_getenv(e) && !rewrite)
985 + return;
986 +
987 + nvram_setenv(e, v);
988 +}
989 +
990 +char *
991 +getenv(char *e)
992 +{
993 + return(nvram_getenv(e));
994 +}
995 +
996 +void
997 +unsetenv(char *e)
998 +{
999 + nvram_unsetenv(e);
1000 +}
1001 +
1002 +void
1003 +purgeenv()
1004 +{
1005 + int i;
1006 + unsigned char* nvramDataPointer = (unsigned char*)(NVRAM_BASE);
1007 +
1008 + for (i = ENV_BASE; i < ENV_TOP; i++)
1009 + *nvramDataPointer++ = 0;
1010 + nvram_setshort(NVOFF_MAGIC, NV_MAGIC);
1011 + nvram_setshort(NVOFF_ENVSIZE, 0);
1012 + nvram_setshort(NVOFF_CSUM, NV_MAGIC);
1013 +}
1014 +
1015 +void
1016 +mapenv(int (*func)(char *, char *))
1017 +{
1018 + nvram_mapenv(func);
1019 +}
1020 diff -Nur linux-2.6.15/arch/mips/aruba/nvram/nvram434.h linux-2.6.15-openwrt/arch/mips/aruba/nvram/nvram434.h
1021 --- linux-2.6.15/arch/mips/aruba/nvram/nvram434.h 1970-01-01 01:00:00.000000000 +0100
1022 +++ linux-2.6.15-openwrt/arch/mips/aruba/nvram/nvram434.h 2006-01-10 00:32:32.000000000 +0100
1023 @@ -0,0 +1,66 @@
1024 +/**************************************************************************
1025 + *
1026 + * BRIEF MODULE DESCRIPTION
1027 + * nvram definitions.
1028 + *
1029 + * Copyright 2004 IDT Inc. (rischelp@idt.com)
1030 + *
1031 + * This program is free software; you can redistribute it and/or modify it
1032 + * under the terms of the GNU General Public License as published by the
1033 + * Free Software Foundation; either version 2 of the License, or (at your
1034 + * option) any later version.
1035 + *
1036 + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
1037 + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
1038 + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
1039 + * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
1040 + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
1041 + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
1042 + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
1043 + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
1044 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
1045 + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
1046 + *
1047 + * You should have received a copy of the GNU General Public License along
1048 + * with this program; if not, write to the Free Software Foundation, Inc.,
1049 + * 675 Mass Ave, Cambridge, MA 02139, USA.
1050 + *
1051 + *
1052 + **************************************************************************
1053 + * May 2004 rkt, neb
1054 + *
1055 + * Initial Release
1056 + *
1057 + *
1058 + *
1059 + **************************************************************************
1060 + */
1061 +
1062 +
1063 +#ifndef _NVRAM_
1064 +#define _NVRAM_
1065 +#define NVOFFSET 0 /* use all of NVRAM */
1066 +
1067 +/* Offsets to reserved locations */
1068 + /* size description */
1069 +#define NVOFF_MAGIC (NVOFFSET + 0) /* 2 magic value */
1070 +#define NVOFF_CSUM (NVOFFSET + 2) /* 2 NVRAM environment checksum */
1071 +#define NVOFF_ENVSIZE (NVOFFSET + 4) /* 2 size of 'environment' */
1072 +#define NVOFF_TEST (NVOFFSET + 5) /* 1 cold start test byte */
1073 +#define NVOFF_ETHADDR (NVOFFSET + 6) /* 6 decoded ethernet address */
1074 +#define NVOFF_UNUSED (NVOFFSET + 12) /* 0 current end of table */
1075 +
1076 +#define NV_MAGIC 0xdeaf /* nvram magic number */
1077 +#define NV_RESERVED 6 /* number of reserved bytes */
1078 +
1079 +#undef NVOFF_ETHADDR
1080 +#define NVOFF_ETHADDR (NVOFFSET + NV_RESERVED - 6)
1081 +
1082 +/* number of bytes available for environment */
1083 +#define ENV_BASE (NVOFFSET + NV_RESERVED)
1084 +#define ENV_TOP 0x2000
1085 +#define ENV_AVAIL (ENV_TOP - ENV_BASE)
1086 +
1087 +#endif /* _NVRAM_ */
1088 +
1089 +
1090 diff -Nur linux-2.6.15/arch/mips/aruba/prom.c linux-2.6.15-openwrt/arch/mips/aruba/prom.c
1091 --- linux-2.6.15/arch/mips/aruba/prom.c 1970-01-01 01:00:00.000000000 +0100
1092 +++ linux-2.6.15-openwrt/arch/mips/aruba/prom.c 2006-01-10 00:32:32.000000000 +0100
1093 @@ -0,0 +1,111 @@
1094 +/**************************************************************************
1095 + *
1096 + * BRIEF MODULE DESCRIPTION
1097 + * prom interface routines
1098 + *
1099 + * Copyright 2004 IDT Inc. (rischelp@idt.com)
1100 + *
1101 + * This program is free software; you can redistribute it and/or modify it
1102 + * under the terms of the GNU General Public License as published by the
1103 + * Free Software Foundation; either version 2 of the License, or (at your
1104 + * option) any later version.
1105 + *
1106 + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
1107 + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
1108 + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
1109 + * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
1110 + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
1111 + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
1112 + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
1113 + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
1114 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
1115 + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
1116 + *
1117 + * You should have received a copy of the GNU General Public License along
1118 + * with this program; if not, write to the Free Software Foundation, Inc.,
1119 + * 675 Mass Ave, Cambridge, MA 02139, USA.
1120 + *
1121 + *
1122 + **************************************************************************
1123 + * May 2004 rkt, neb
1124 + *
1125 + * Initial Release
1126 + *
1127 + *
1128 + *
1129 + **************************************************************************
1130 + */
1131 +
1132 +#include <linux/config.h>
1133 +#include <linux/init.h>
1134 +#include <linux/mm.h>
1135 +#include <linux/module.h>
1136 +#include <linux/string.h>
1137 +#include <linux/console.h>
1138 +#include <asm/bootinfo.h>
1139 +#include <linux/bootmem.h>
1140 +#include <linux/ioport.h>
1141 +#include <linux/serial.h>
1142 +#include <linux/serialP.h>
1143 +#include <asm/serial.h>
1144 +#include <linux/ioport.h>
1145 +
1146 +unsigned int idt_cpu_freq;
1147 +EXPORT_SYMBOL(idt_cpu_freq);
1148 +
1149 +unsigned int arch_has_pci=0;
1150 +
1151 +/* Kernel Boot parameters */
1152 +static unsigned char bootparm[] = "console=ttyS0,9600 root=/dev/mtdblock1 rootfstype=jffs2";
1153 +
1154 +extern unsigned long mips_machgroup;
1155 +extern unsigned long mips_machtype;
1156 +
1157 +extern void setup_serial_port(void);
1158 +extern char * getenv(char *e);
1159 +
1160 +/* IDT 79EB434 memory map -- we really should be auto sizing it */
1161 +#define RAM_SIZE 32*1024*1024
1162 +
1163 +char *__init prom_getcmdline(void)
1164 +{
1165 + return &(arcs_cmdline[0]);
1166 +}
1167 +
1168 +void __init prom_init(void)
1169 +{
1170 + char *boardname;
1171 + sprintf(arcs_cmdline, "%s", bootparm);
1172 +
1173 + /* set our arch type */
1174 + mips_machgroup = MACH_GROUP_ARUBA;
1175 + mips_machtype = MACH_ARUBA_UNKNOWN;
1176 +
1177 + boardname=getenv("boardname");
1178 +
1179 + if (!strcmp(boardname,"Muscat")) {
1180 + mips_machtype = MACH_ARUBA_AP70;
1181 + idt_cpu_freq = 133000000;
1182 + arch_has_pci=1;
1183 + } else if (!strcmp(boardname,"Mataro")) {
1184 + mips_machtype = MACH_ARUBA_AP65;
1185 + idt_cpu_freq = 110000000;
1186 + } else if (!strcmp(boardname,"Merlot")) {
1187 + mips_machtype = MACH_ARUBA_AP60;
1188 + idt_cpu_freq = 90000000;
1189 + }
1190 +
1191 + /* turn on the console */
1192 + setup_serial_port();
1193 +
1194 + /*
1195 + * give all RAM to boot allocator,
1196 + * except where the kernel was loaded
1197 + */
1198 + add_memory_region(0,RAM_SIZE,BOOT_MEM_RAM);
1199 +}
1200 +
1201 +void prom_free_prom_memory(void)
1202 +{
1203 + printk("stubbed prom_free_prom_memory()\n");
1204 +}
1205 diff -Nur linux-2.6.15/arch/mips/aruba/serial.c linux-2.6.15-openwrt/arch/mips/aruba/serial.c
1206 --- linux-2.6.15/arch/mips/aruba/serial.c 1970-01-01 01:00:00.000000000 +0100
1207 +++ linux-2.6.15-openwrt/arch/mips/aruba/serial.c 2006-01-10 00:32:32.000000000 +0100
1208 @@ -0,0 +1,94 @@
1209 +/**************************************************************************
1210 + *
1211 + * BRIEF MODULE DESCRIPTION
1212 + * Serial port initialisation.
1213 + *
1214 + * Copyright 2004 IDT Inc. (rischelp@idt.com)
1215 + *
1216 + * This program is free software; you can redistribute it and/or modify it
1217 + * under the terms of the GNU General Public License as published by the
1218 + * Free Software Foundation; either version 2 of the License, or (at your
1219 + * option) any later version.
1220 + *
1221 + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
1222 + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
1223 + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
1224 + * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
1225 + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
1226 + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
1227 + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
1228 + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
1229 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
1230 + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
1231 + *
1232 + * You should have received a copy of the GNU General Public License along
1233 + * with this program; if not, write to the Free Software Foundation, Inc.,
1234 + * 675 Mass Ave, Cambridge, MA 02139, USA.
1235 + *
1236 + *
1237 + **************************************************************************
1238 + * May 2004 rkt, neb
1239 + *
1240 + * Initial Release
1241 + *
1242 + *
1243 + *
1244 + **************************************************************************
1245 + */
1246 +
1247 +
1248 +#include <linux/config.h>
1249 +#include <linux/init.h>
1250 +#include <linux/sched.h>
1251 +#include <linux/pci.h>
1252 +#include <linux/interrupt.h>
1253 +#include <linux/tty.h>
1254 +#include <linux/serial.h>
1255 +#include <linux/serial_core.h>
1256 +
1257 +#include <asm/time.h>
1258 +#include <asm/cpu.h>
1259 +#include <asm/bootinfo.h>
1260 +#include <asm/irq.h>
1261 +#include <asm/serial.h>
1262 +
1263 +#include <asm/idt-boards/rc32434/rc32434.h>
1264 +
1265 +extern int __init early_serial_setup(struct uart_port *port);
1266 +
1267 +#define BASE_BAUD (1843200 / 16)
1268 +
1269 +extern unsigned int idt_cpu_freq;
1270 +
1271 +extern int __init setup_serial_port(void)
1272 +{
1273 + static struct uart_port serial_req[2];
1274 +
1275 + memset(serial_req, 0, sizeof(serial_req));
1276 + serial_req[0].type = PORT_16550A;
1277 + serial_req[0].line = 0;
1278 + serial_req[0].flags = STD_COM_FLAGS;
1279 + serial_req[0].iotype = SERIAL_IO_MEM;
1280 + serial_req[0].regshift = 2;
1281 +
1282 + switch (mips_machtype) {
1283 + case MACH_ARUBA_AP70:
1284 + serial_req[0].irq = 104;
1285 + serial_req[0].mapbase = KSEG1ADDR(0x18058003);
1286 + serial_req[0].membase = (char *) KSEG1ADDR(0x18058003);
1287 + serial_req[0].uartclk = idt_cpu_freq;
1288 + break;
1289 + case MACH_ARUBA_AP65:
1290 + case MACH_ARUBA_AP60:
1291 + default:
1292 + serial_req[0].irq = 12;
1293 + serial_req[0].mapbase = KSEG1ADDR(0xbc000003);
1294 + serial_req[0].membase = (char *) KSEG1ADDR(0xbc000003);
1295 + serial_req[0].uartclk = idt_cpu_freq / 2;
1296 + break;
1297 + }
1298 +
1299 + early_serial_setup(&serial_req[0]);
1300 +
1301 + return(0);
1302 +}
1303 diff -Nur linux-2.6.15/arch/mips/aruba/setup.c linux-2.6.15-openwrt/arch/mips/aruba/setup.c
1304 --- linux-2.6.15/arch/mips/aruba/setup.c 1970-01-01 01:00:00.000000000 +0100
1305 +++ linux-2.6.15-openwrt/arch/mips/aruba/setup.c 2006-01-10 00:32:32.000000000 +0100
1306 @@ -0,0 +1,124 @@
1307 +/**************************************************************************
1308 + *
1309 + * BRIEF MODULE DESCRIPTION
1310 + * setup routines for IDT EB434 boards
1311 + *
1312 + * Copyright 2004 IDT Inc. (rischelp@idt.com)
1313 + *
1314 + * This program is free software; you can redistribute it and/or modify it
1315 + * under the terms of the GNU General Public License as published by the
1316 + * Free Software Foundation; either version 2 of the License, or (at your
1317 + * option) any later version.
1318 + *
1319 + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
1320 + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
1321 + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
1322 + * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
1323 + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
1324 + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
1325 + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
1326 + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
1327 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
1328 + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
1329 + *
1330 + * You should have received a copy of the GNU General Public License along
1331 + * with this program; if not, write to the Free Software Foundation, Inc.,
1332 + * 675 Mass Ave, Cambridge, MA 02139, USA.
1333 + *
1334 + *
1335 + **************************************************************************
1336 + * May 2004 rkt, neb
1337 + *
1338 + * Initial Release
1339 + *
1340 + *
1341 + *
1342 + **************************************************************************
1343 + */
1344 +
1345 +#include <linux/init.h>
1346 +#include <linux/mm.h>
1347 +#include <linux/sched.h>
1348 +#include <linux/irq.h>
1349 +#include <asm/bootinfo.h>
1350 +#include <asm/io.h>
1351 +#include <linux/ioport.h>
1352 +#include <asm/mipsregs.h>
1353 +#include <asm/pgtable.h>
1354 +#include <asm/reboot.h>
1355 +#include <asm/addrspace.h> /* for KSEG1ADDR() */
1356 +#include <asm/idt-boards/rc32434/rc32434.h>
1357 +
1358 +extern char *__init prom_getcmdline(void);
1359 +
1360 +extern void (*board_time_init) (void);
1361 +extern void (*board_timer_setup) (struct irqaction * irq);
1362 +extern void aruba_time_init(void);
1363 +extern void aruba_timer_setup(struct irqaction *irq);
1364 +extern void aruba_reset(void);
1365 +
1366 +#define epldMask ((volatile unsigned char *)0xB900000d)
1367 +
1368 +static void aruba_machine_restart(char *command)
1369 +{
1370 + switch (mips_machtype) {
1371 + case MACH_ARUBA_AP70:
1372 + *(volatile u32 *)KSEG1ADDR(0x18008000) = 0x80000001;
1373 + break;
1374 + case MACH_ARUBA_AP65:
1375 + case MACH_ARUBA_AP60:
1376 + default:
1377 + /* Reset*/
1378 + *((volatile u32 *)KSEG1ADDR(0x1c003020)) = 0x00080350; // reset everything in sight
1379 + udelay(100);
1380 + *((volatile u32 *)KSEG1ADDR(0x1c003020)) = 0; // reset everything in sight
1381 + udelay(100);
1382 + *((volatile u32 *)KSEG1ADDR(0x1c003020)) = 0x3; // cold reset the cpu & system
1383 + break;
1384 + }
1385 +}
1386 +
1387 +static void aruba_machine_halt(void)
1388 +{
1389 + for (;;) continue;
1390 +}
1391 +
1392 +extern char * getenv(char *e);
1393 +extern void unlock_ap60_70_flash(void);
1394 +extern void wdt_merlot_disable(void);
1395 +
1396 +void __init plat_setup(void)
1397 +{
1398 + board_time_init = aruba_time_init;
1399 +
1400 + board_timer_setup = aruba_timer_setup;
1401 +
1402 + _machine_restart = aruba_machine_restart;
1403 + _machine_halt = aruba_machine_halt;
1404 + _machine_power_off = aruba_machine_halt;
1405 +
1406 + set_io_port_base(KSEG1);
1407 +
1408 + /* Enable PCI interrupts in EPLD Mask register */
1409 + *epldMask = 0x0;
1410 + *(epldMask + 1) = 0x0;
1411 +
1412 + write_c0_wired(0);
1413 + unlock_ap60_70_flash();
1414 +
1415 + printk("BOARD - %s\n",getenv("boardname"));
1416 +
1417 + wdt_merlot_disable();
1418 +
1419 + return 0;
1420 +}
1421 +
1422 +int page_is_ram(unsigned long pagenr)
1423 +{
1424 + return 1;
1425 +}
1426 +
1427 +const char *get_system_type(void)
1428 +{
1429 + return "MIPS IDT32434 - ARUBA";
1430 +}
1431 diff -Nur linux-2.6.15/arch/mips/aruba/time.c linux-2.6.15-openwrt/arch/mips/aruba/time.c
1432 --- linux-2.6.15/arch/mips/aruba/time.c 1970-01-01 01:00:00.000000000 +0100
1433 +++ linux-2.6.15-openwrt/arch/mips/aruba/time.c 2006-01-10 00:32:32.000000000 +0100
1434 @@ -0,0 +1,108 @@
1435 +/**************************************************************************
1436 + *
1437 + * BRIEF MODULE DESCRIPTION
1438 + * timer routines for IDT EB434 boards
1439 + *
1440 + * Copyright 2004 IDT Inc. (rischelp@idt.com)
1441 + *
1442 + * This program is free software; you can redistribute it and/or modify it
1443 + * under the terms of the GNU General Public License as published by the
1444 + * Free Software Foundation; either version 2 of the License, or (at your
1445 + * option) any later version.
1446 + *
1447 + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
1448 + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
1449 + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
1450 + * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
1451 + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
1452 + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
1453 + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
1454 + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
1455 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
1456 + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
1457 + *
1458 + * You should have received a copy of the GNU General Public License along
1459 + * with this program; if not, write to the Free Software Foundation, Inc.,
1460 + * 675 Mass Ave, Cambridge, MA 02139, USA.
1461 + *
1462 + *
1463 + **************************************************************************
1464 + * May 2004 rkt, neb
1465 + *
1466 + * Initial Release
1467 + *
1468 + *
1469 + *
1470 + **************************************************************************
1471 + */
1472 +
1473 +#include <linux/config.h>
1474 +#include <linux/init.h>
1475 +#include <linux/kernel_stat.h>
1476 +#include <linux/sched.h>
1477 +#include <linux/spinlock.h>
1478 +#include <linux/mc146818rtc.h>
1479 +#include <linux/irq.h>
1480 +#include <linux/timex.h>
1481 +
1482 +#include <linux/param.h>
1483 +#include <asm/mipsregs.h>
1484 +#include <asm/ptrace.h>
1485 +#include <asm/time.h>
1486 +#include <asm/hardirq.h>
1487 +
1488 +#include <asm/mipsregs.h>
1489 +#include <asm/ptrace.h>
1490 +#include <asm/debug.h>
1491 +#include <asm/time.h>
1492 +
1493 +#include <asm/idt-boards/rc32434/rc32434.h>
1494 +
1495 +static unsigned long r4k_offset; /* Amount to incr compare reg each time */
1496 +static unsigned long r4k_cur; /* What counter should be at next timer irq */
1497 +
1498 +extern unsigned int idt_cpu_freq;
1499 +
1500 +static unsigned long __init cal_r4koff(void)
1501 +{
1502 + mips_hpt_frequency = idt_cpu_freq * IDT_CLOCK_MULT / 2;
1503 + return (mips_hpt_frequency / HZ);
1504 +}
1505 +
1506 +void __init aruba_time_init(void)
1507 +{
1508 + unsigned int est_freq, flags;
1509 + local_irq_save(flags);
1510 +
1511 + printk("calculating r4koff... ");
1512 + r4k_offset = cal_r4koff();
1513 + printk("%08lx(%d)\n", r4k_offset, (int)r4k_offset);
1514 +
1515 + est_freq = 2 * r4k_offset * HZ;
1516 + est_freq += 5000; /* round */
1517 + est_freq -= est_freq % 10000;
1518 + printk("CPU frequency %d.%02d MHz\n", est_freq / 1000000,
1519 + (est_freq % 1000000) * 100 / 1000000);
1520 + local_irq_restore(flags);
1521 +
1522 +}
1523 +
1524 +void __init aruba_timer_setup(struct irqaction *irq)
1525 +{
1526 + /* we are using the cpu counter for timer interrupts */
1527 + setup_irq(MIPS_CPU_TIMER_IRQ, irq);
1528 +
1529 + /* to generate the first timer interrupt */
1530 + r4k_cur = (read_c0_count() + r4k_offset);
1531 + write_c0_compare(r4k_cur);
1532 +
1533 +}
1534 +
1535 +asmlinkage void aruba_timer_interrupt(int irq, struct pt_regs *regs)
1536 +{
1537 + irq_enter();
1538 + kstat_this_cpu.irqs[irq]++;
1539 +
1540 + timer_interrupt(irq, NULL, regs);
1541 + irq_exit();
1542 +}
1543 diff -Nur linux-2.6.15/arch/mips/aruba/wdt_merlot.c linux-2.6.15-openwrt/arch/mips/aruba/wdt_merlot.c
1544 --- linux-2.6.15/arch/mips/aruba/wdt_merlot.c 1970-01-01 01:00:00.000000000 +0100
1545 +++ linux-2.6.15-openwrt/arch/mips/aruba/wdt_merlot.c 2006-01-10 00:32:32.000000000 +0100
1546 @@ -0,0 +1,30 @@
1547 +#include <linux/config.h>
1548 +#include <linux/kernel.h>
1549 +#include <asm/bootinfo.h>
1550 +
1551 +void wdt_merlot_disable()
1552 +{
1553 + volatile __u32 *wdt_errcs;
1554 + volatile __u32 *wdt_wtc;
1555 + volatile __u32 *wdt_ctl;
1556 + volatile __u32 val;
1557 +
1558 + switch (mips_machtype) {
1559 + case MACH_ARUBA_AP70:
1560 + wdt_errcs = (__u32 *) 0xb8030030;
1561 + wdt_wtc = (__u32 *) 0xb803003c;
1562 + val = *wdt_errcs;
1563 + val &= ~0x201;
1564 + *wdt_errcs = val;
1565 + val = *wdt_wtc;
1566 + val &= ~0x1;
1567 + *wdt_wtc = val;
1568 + break;
1569 + case MACH_ARUBA_AP65:
1570 + case MACH_ARUBA_AP60:
1571 + default:
1572 + wdt_ctl = (__u32 *) 0xbc003008;
1573 + *wdt_ctl = 0;
1574 + break;
1575 + }
1576 +}
1577 diff -Nur linux-2.6.15/arch/mips/Kconfig linux-2.6.15-openwrt/arch/mips/Kconfig
1578 --- linux-2.6.15/arch/mips/Kconfig 2006-01-03 04:21:10.000000000 +0100
1579 +++ linux-2.6.15-openwrt/arch/mips/Kconfig 2006-01-10 00:32:32.000000000 +0100
1580 @@ -227,6 +227,18 @@
1581 either a NEC Vr5432 or QED RM5231. Say Y here if you wish to build
1582 a kernel for this platform.
1583
1584 +config MACH_ARUBA
1585 + bool "Support for the ARUBA product line"
1586 + select DMA_NONCOHERENT
1587 + select IRQ_CPU
1588 + select CPU_HAS_PREFETCH
1589 + select HW_HAS_PCI
1590 + select SWAP_IO_SPACE
1591 + select SYS_SUPPORTS_32BIT_KERNEL
1592 + select SYS_HAS_CPU_MIPS32_R1
1593 + select SYS_SUPPORTS_BIG_ENDIAN
1594 +
1595 +
1596 config MACH_JAZZ
1597 bool "Support for the Jazz family of machines"
1598 select ARC
1599 diff -Nur linux-2.6.15/arch/mips/Makefile linux-2.6.15-openwrt/arch/mips/Makefile
1600 --- linux-2.6.15/arch/mips/Makefile 2006-01-03 04:21:10.000000000 +0100
1601 +++ linux-2.6.15-openwrt/arch/mips/Makefile 2006-01-10 00:32:32.000000000 +0100
1602 @@ -258,6 +258,14 @@
1603 #
1604
1605 #
1606 +# Aruba
1607 +#
1608 +
1609 +core-$(CONFIG_MACH_ARUBA) += arch/mips/aruba/
1610 +cflags-$(CONFIG_MACH_ARUBA) += -Iinclude/asm-mips/aruba
1611 +load-$(CONFIG_MACH_ARUBA) += 0x80100000
1612 +
1613 +#
1614 # Acer PICA 61, Mips Magnum 4000 and Olivetti M700.
1615 #
1616 core-$(CONFIG_MACH_JAZZ) += arch/mips/jazz/
1617 diff -Nur linux-2.6.15/arch/mips/mm/tlbex.c linux-2.6.15-openwrt/arch/mips/mm/tlbex.c
1618 --- linux-2.6.15/arch/mips/mm/tlbex.c 2006-01-03 04:21:10.000000000 +0100
1619 +++ linux-2.6.15-openwrt/arch/mips/mm/tlbex.c 2006-01-10 00:32:32.000000000 +0100
1620 @@ -852,7 +852,6 @@
1621
1622 case CPU_R10000:
1623 case CPU_R12000:
1624 - case CPU_4KC:
1625 case CPU_SB1:
1626 case CPU_SB1A:
1627 case CPU_4KSC:
1628 @@ -880,6 +879,7 @@
1629 tlbw(p);
1630 break;
1631
1632 + case CPU_4KC:
1633 case CPU_4KEC:
1634 case CPU_24K:
1635 case CPU_34K:
1636 diff -Nur linux-2.6.15/arch/mips/pci/fixup-aruba.c linux-2.6.15-openwrt/arch/mips/pci/fixup-aruba.c
1637 --- linux-2.6.15/arch/mips/pci/fixup-aruba.c 1970-01-01 01:00:00.000000000 +0100
1638 +++ linux-2.6.15-openwrt/arch/mips/pci/fixup-aruba.c 2006-01-10 00:34:41.000000000 +0100
1639 @@ -0,0 +1,115 @@
1640 +/**************************************************************************
1641 + *
1642 + * BRIEF MODULE DESCRIPTION
1643 + * PCI fixups for IDT EB434 board
1644 + *
1645 + * Copyright 2004 IDT Inc. (rischelp@idt.com)
1646 + *
1647 + * This program is free software; you can redistribute it and/or modify it
1648 + * under the terms of the GNU General Public License as published by the
1649 + * Free Software Foundation; either version 2 of the License, or (at your
1650 + * option) any later version.
1651 + *
1652 + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
1653 + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
1654 + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
1655 + * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
1656 + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
1657 + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
1658 + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
1659 + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
1660 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
1661 + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
1662 + *
1663 + * You should have received a copy of the GNU General Public License along
1664 + * with this program; if not, write to the Free Software Foundation, Inc.,
1665 + * 675 Mass Ave, Cambridge, MA 02139, USA.
1666 + *
1667 + *
1668 + **************************************************************************
1669 + * May 2004 rkt, neb
1670 + *
1671 + * Initial Release
1672 + *
1673 + *
1674 + *
1675 + **************************************************************************
1676 + */
1677 +
1678 +#include <linux/config.h>
1679 +#include <linux/types.h>
1680 +#include <linux/pci.h>
1681 +#include <linux/kernel.h>
1682 +#include <linux/init.h>
1683 +#include <asm/idt-boards/rc32434/rc32434.h>
1684 +#include <asm/idt-boards/rc32434/rc32434_pci.h>
1685 +
1686 +int __init pcibios_map_irq(struct pci_dev *dev, u8 slot, u8 pin)
1687 +{
1688 +
1689 + if (dev->bus->number != 0) {
1690 + return 0;
1691 + }
1692 +
1693 + slot = PCI_SLOT(dev->devfn);
1694 + dev->irq = 0;
1695 +
1696 + if (slot > 0 && slot <= 15) {
1697 +#if 1
1698 + if(slot == 10) {
1699 + if(pin == 1) dev->irq = GROUP4_IRQ_BASE + 9; // intA
1700 + } else if(slot == 11) {
1701 + if(pin == 1) dev->irq = GROUP4_IRQ_BASE + 10; // intA
1702 + if(pin == 2) dev->irq = GROUP4_IRQ_BASE + 10; // intA
1703 + if(pin == 3) dev->irq = GROUP4_IRQ_BASE + 10; // intA
1704 + } else if(slot == 12) {
1705 + if(pin == 1) dev->irq = GROUP4_IRQ_BASE + 11; // intA
1706 + if(pin == 2) dev->irq = GROUP4_IRQ_BASE + 12; // intB
1707 + } else if (slot == 13) {
1708 + if(pin == 1) dev->irq = GROUP4_IRQ_BASE + 12; // intA
1709 + if(pin == 2) dev->irq = GROUP4_IRQ_BASE + 11; // intB
1710 + } else {
1711 + dev->irq = GROUP4_IRQ_BASE + 11;
1712 + }
1713 +#else
1714 + switch (pin) {
1715 + case 1: /* INTA*/
1716 + dev->irq = GROUP4_IRQ_BASE + 11;
1717 + break;
1718 + case 2: /* INTB */
1719 + dev->irq = GROUP4_IRQ_BASE + 11;
1720 + break;
1721 + case 3: /* INTC */
1722 + dev->irq = GROUP4_IRQ_BASE + 11;
1723 + break;
1724 + case 4: /* INTD */
1725 + dev->irq = GROUP4_IRQ_BASE + 11;
1726 + break;
1727 + default:
1728 + dev->irq = 0xff;
1729 + break;
1730 + }
1731 +#endif
1732 +#ifdef DEBUG
1733 + printk("irq fixup: slot %d, pin %d, irq %d\n",
1734 + slot, pin, dev->irq);
1735 +#endif
1736 + pci_write_config_byte(dev, PCI_INTERRUPT_LINE,dev->irq);
1737 + }
1738 + return (dev->irq);
1739 +}
1740 +
1741 +struct pci_fixup pcibios_fixups[] = {
1742 + {0}
1743 +};
1744 +
1745 +
1746 +
1747 +
1748 +
1749 +
1750 +
1751 +
1752 +
1753 +
1754 +
1755 diff -Nur linux-2.6.15/arch/mips/pci/Makefile linux-2.6.15-openwrt/arch/mips/pci/Makefile
1756 --- linux-2.6.15/arch/mips/pci/Makefile 2006-01-03 04:21:10.000000000 +0100
1757 +++ linux-2.6.15-openwrt/arch/mips/pci/Makefile 2006-01-10 00:32:32.000000000 +0100
1758 @@ -56,3 +56,4 @@
1759 obj-$(CONFIG_TOSHIBA_RBTX4938) += fixup-tx4938.o ops-tx4938.o
1760 obj-$(CONFIG_VICTOR_MPC30X) += fixup-mpc30x.o
1761 obj-$(CONFIG_ZAO_CAPCELLA) += fixup-capcella.o
1762 +obj-$(CONFIG_MACH_ARUBA) += fixup-aruba.o ops-aruba.o pci-aruba.o
1763 diff -Nur linux-2.6.15/arch/mips/pci/ops-aruba.c linux-2.6.15-openwrt/arch/mips/pci/ops-aruba.c
1764 --- linux-2.6.15/arch/mips/pci/ops-aruba.c 1970-01-01 01:00:00.000000000 +0100
1765 +++ linux-2.6.15-openwrt/arch/mips/pci/ops-aruba.c 2006-01-10 00:32:32.000000000 +0100
1766 @@ -0,0 +1,204 @@
1767 +/**************************************************************************
1768 + *
1769 + * BRIEF MODULE DESCRIPTION
1770 + * pci_ops for IDT EB434 board
1771 + *
1772 + * Copyright 2004 IDT Inc. (rischelp@idt.com)
1773 + *
1774 + * This program is free software; you can redistribute it and/or modify it
1775 + * under the terms of the GNU General Public License as published by the
1776 + * Free Software Foundation; either version 2 of the License, or (at your
1777 + * option) any later version.
1778 + *
1779 + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
1780 + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
1781 + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
1782 + * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
1783 + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
1784 + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
1785 + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
1786 + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
1787 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
1788 + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
1789 + *
1790 + * You should have received a copy of the GNU General Public License along
1791 + * with this program; if not, write to the Free Software Foundation, Inc.,
1792 + * 675 Mass Ave, Cambridge, MA 02139, USA.
1793 + *
1794 + *
1795 + **************************************************************************
1796 + * May 2004 rkt, neb
1797 + *
1798 + * Initial Release
1799 + *
1800 + *
1801 + *
1802 + **************************************************************************
1803 + */
1804 +
1805 +#include <linux/config.h>
1806 +#include <linux/init.h>
1807 +#include <linux/pci.h>
1808 +#include <linux/types.h>
1809 +#include <linux/delay.h>
1810 +
1811 +#include <asm/cpu.h>
1812 +#include <asm/io.h>
1813 +
1814 +#include <asm/idt-boards/rc32434/rc32434.h>
1815 +#include <asm/idt-boards/rc32434/rc32434_pci.h>
1816 +
1817 +#define PCI_ACCESS_READ 0
1818 +#define PCI_ACCESS_WRITE 1
1819 +
1820 +
1821 +#define PCI_CFG_SET(slot,func,off) \
1822 + (rc32434_pci->pcicfga = (0x80000000 | ((slot)<<11) | \
1823 + ((func)<<8) | (off)))
1824 +
1825 +static int config_access(unsigned char access_type, struct pci_bus *bus,
1826 + unsigned int devfn, unsigned char where,
1827 + u32 * data)
1828 +{
1829 + /*
1830 + * config cycles are on 4 byte boundary only
1831 + */
1832 + unsigned int slot = PCI_SLOT(devfn);
1833 + u8 func = PCI_FUNC(devfn);
1834 +
1835 + if (slot < 2 || slot > 15) {
1836 + *data = 0xFFFFFFFF;
1837 + return -1;
1838 + }
1839 + /* Setup address */
1840 + PCI_CFG_SET(slot, func, where);
1841 + rc32434_sync();
1842 +
1843 + if (access_type == PCI_ACCESS_WRITE) {
1844 + rc32434_sync();
1845 + rc32434_pci->pcicfgd = *data;
1846 + } else {
1847 + rc32434_sync();
1848 + *data = rc32434_pci->pcicfgd;
1849 + }
1850 +
1851 + rc32434_sync();
1852 +
1853 + return 0;
1854 +}
1855 +
1856 +
1857 +/*
1858 + * We can't address 8 and 16 bit words directly. Instead we have to
1859 + * read/write a 32bit word and mask/modify the data we actually want.
1860 + */
1861 +static int read_config_byte(struct pci_bus *bus, unsigned int devfn,
1862 + int where, u8 * val)
1863 +{
1864 + u32 data;
1865 + int ret;
1866 +
1867 + ret = config_access(PCI_ACCESS_READ, bus, devfn, where, &data);
1868 + *val = (data >> ((where & 3) << 3)) & 0xff;
1869 + return ret;
1870 +}
1871 +
1872 +static int read_config_word(struct pci_bus *bus, unsigned int devfn,
1873 + int where, u16 * val)
1874 +{
1875 + u32 data;
1876 + int ret;
1877 +
1878 + ret = config_access(PCI_ACCESS_READ, bus, devfn, where, &data);
1879 + *val = (data >> ((where & 3) << 3)) & 0xffff;
1880 + return ret;
1881 +}
1882 +
1883 +static int read_config_dword(struct pci_bus *bus, unsigned int devfn,
1884 + int where, u32 * val)
1885 +{
1886 + int ret;
1887 +
1888 + ret = config_access(PCI_ACCESS_READ, bus, devfn, where, val);
1889 + return ret;
1890 +}
1891 +
1892 +static int
1893 +write_config_byte(struct pci_bus *bus, unsigned int devfn, int where,
1894 + u8 val)
1895 +{
1896 + u32 data = 0;
1897 +
1898 + if (config_access(PCI_ACCESS_READ, bus, devfn, where, &data))
1899 + return -1;
1900 +
1901 + data = (data & ~(0xff << ((where & 3) << 3))) |
1902 + (val << ((where & 3) << 3));
1903 +
1904 + if (config_access(PCI_ACCESS_WRITE, bus, devfn, where, &data))
1905 + return -1;
1906 +
1907 + return PCIBIOS_SUCCESSFUL;
1908 +}
1909 +
1910 +
1911 +static int
1912 +write_config_word(struct pci_bus *bus, unsigned int devfn, int where,
1913 + u16 val)
1914 +{
1915 + u32 data = 0;
1916 +
1917 + if (config_access(PCI_ACCESS_READ, bus, devfn, where, &data))
1918 + return -1;
1919 +
1920 + data = (data & ~(0xffff << ((where & 3) << 3))) |
1921 + (val << ((where & 3) << 3));
1922 +
1923 + if (config_access(PCI_ACCESS_WRITE, bus, devfn, where, &data))
1924 + return -1;
1925 +
1926 +
1927 + return PCIBIOS_SUCCESSFUL;
1928 +}
1929 +
1930 +
1931 +static int
1932 +write_config_dword(struct pci_bus *bus, unsigned int devfn, int where,
1933 + u32 val)
1934 +{
1935 + if (config_access(PCI_ACCESS_WRITE, bus, devfn, where, &val))
1936 + return -1;
1937 +
1938 + return PCIBIOS_SUCCESSFUL;
1939 +}
1940 +
1941 +static int pci_config_read(struct pci_bus *bus, unsigned int devfn,
1942 + int where, int size, u32 * val)
1943 +{
1944 + switch (size) {
1945 + case 1:
1946 + return read_config_byte(bus, devfn, where, (u8 *) val);
1947 + case 2:
1948 + return read_config_word(bus, devfn, where, (u16 *) val);
1949 + default:
1950 + return read_config_dword(bus, devfn, where, val);
1951 + }
1952 +}
1953 +
1954 +static int pci_config_write(struct pci_bus *bus, unsigned int devfn,
1955 + int where, int size, u32 val)
1956 +{
1957 + switch (size) {
1958 + case 1:
1959 + return write_config_byte(bus, devfn, where, (u8) val);
1960 + case 2:
1961 + return write_config_word(bus, devfn, where, (u16) val);
1962 + default:
1963 + return write_config_dword(bus, devfn, where, val);
1964 + }
1965 +}
1966 +
1967 +struct pci_ops rc32434_pci_ops = {
1968 + .read = pci_config_read,
1969 + .write = pci_config_write,
1970 +};
1971 diff -Nur linux-2.6.15/arch/mips/pci/pci-aruba.c linux-2.6.15-openwrt/arch/mips/pci/pci-aruba.c
1972 --- linux-2.6.15/arch/mips/pci/pci-aruba.c 1970-01-01 01:00:00.000000000 +0100
1973 +++ linux-2.6.15-openwrt/arch/mips/pci/pci-aruba.c 2006-01-10 00:32:32.000000000 +0100
1974 @@ -0,0 +1,235 @@
1975 +/**************************************************************************
1976 + *
1977 + * BRIEF MODULE DESCRIPTION
1978 + * PCI initialization for IDT EB434 board
1979 + *
1980 + * Copyright 2004 IDT Inc. (rischelp@idt.com)
1981 + *
1982 + * This program is free software; you can redistribute it and/or modify it
1983 + * under the terms of the GNU General Public License as published by the
1984 + * Free Software Foundation; either version 2 of the License, or (at your
1985 + * option) any later version.
1986 + *
1987 + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
1988 + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
1989 + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
1990 + * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
1991 + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
1992 + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
1993 + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
1994 + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
1995 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
1996 + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
1997 + *
1998 + * You should have received a copy of the GNU General Public License along
1999 + * with this program; if not, write to the Free Software Foundation, Inc.,
2000 + * 675 Mass Ave, Cambridge, MA 02139, USA.
2001 + *
2002 + *
2003 + **************************************************************************
2004 + * May 2004 rkt, neb
2005 + *
2006 + * Initial Release
2007 + *
2008 + *
2009 + *
2010 + **************************************************************************
2011 + */
2012 +
2013 +#include <linux/config.h>
2014 +#include <linux/types.h>
2015 +#include <linux/pci.h>
2016 +#include <linux/kernel.h>
2017 +#include <linux/init.h>
2018 +#include <asm/idt-boards/rc32434/rc32434.h>
2019 +#include <asm/idt-boards/rc32434/rc32434_pci.h>
2020 +
2021 +#define PCI_ACCESS_READ 0
2022 +#define PCI_ACCESS_WRITE 1
2023 +
2024 +#undef DEBUG
2025 +#ifdef DEBUG
2026 +#define DBG(x...) printk(x)
2027 +#else
2028 +#define DBG(x...)
2029 +#endif
2030 +/* define an unsigned array for the PCI registers */
2031 +unsigned int korinaCnfgRegs[25] = {
2032 + KORINA_CNFG1, KORINA_CNFG2, KORINA_CNFG3, KORINA_CNFG4,
2033 + KORINA_CNFG5, KORINA_CNFG6, KORINA_CNFG7, KORINA_CNFG8,
2034 + KORINA_CNFG9, KORINA_CNFG10, KORINA_CNFG11, KORINA_CNFG12,
2035 + KORINA_CNFG13, KORINA_CNFG14, KORINA_CNFG15, KORINA_CNFG16,
2036 + KORINA_CNFG17, KORINA_CNFG18, KORINA_CNFG19, KORINA_CNFG20,
2037 + KORINA_CNFG21, KORINA_CNFG22, KORINA_CNFG23, KORINA_CNFG24
2038 +};
2039 +
2040 +static struct resource rc32434_res_pci_mem2;
2041 +
2042 +static struct resource rc32434_res_pci_mem1 = {
2043 + .name = "PCI MEM1",
2044 + .start = 0x50000000,
2045 + .end = 0x5FFFFFFF,
2046 + .flags = IORESOURCE_MEM,
2047 + .child = &rc32434_res_pci_mem2,
2048 +};
2049 +static struct resource rc32434_res_pci_mem2 = {
2050 + .name = "PCI MEM2",
2051 + .start = 0x60000000,
2052 + .end = 0x6FFFFFFF,
2053 + .flags = IORESOURCE_MEM,
2054 + .parent = &rc32434_res_pci_mem1,
2055 +};
2056 +static struct resource rc32434_res_pci_io1 = {
2057 + .name = "PCI I/O1",
2058 + .start = 0x18800000,
2059 + .end = 0x188FFFFF,
2060 + .flags = IORESOURCE_IO,
2061 +};
2062 +
2063 +extern struct pci_ops rc32434_pci_ops;
2064 +
2065 +struct pci_controller rc32434_controller = {
2066 + .pci_ops = &rc32434_pci_ops,
2067 + .mem_resource = &rc32434_res_pci_mem1,
2068 + .io_resource = &rc32434_res_pci_io1,
2069 + .mem_offset = 0x00000000UL,
2070 + .io_offset = 0x00000000UL,
2071 +};
2072 +
2073 +extern unsigned int arch_has_pci;
2074 +
2075 +static int __init rc32434_pcibridge_init(void)
2076 +{
2077 +
2078 + unsigned int pciConfigAddr = 0;/*used for writing pci config values */
2079 + int loopCount=0 ;/*used for the loop */
2080 +
2081 + unsigned int pcicValue, pcicData=0;
2082 + unsigned int dummyRead, pciCntlVal = 0;
2083 +
2084 + if (!arch_has_pci) return 0;
2085 +
2086 + printk("PCI: Initializing PCI\n");
2087 +
2088 + /* Disable the IP bus error for PCI scaning */
2089 + pciCntlVal=rc32434_pci->pcic;
2090 + pciCntlVal &= 0xFFFFFF7;
2091 + rc32434_pci->pcic = pciCntlVal;
2092 +
2093 + ioport_resource.start = rc32434_res_pci_io1.start;
2094 + ioport_resource.end = rc32434_res_pci_io1.end;
2095 +/*
2096 + iomem_resource.start = rc32434_res_pci_mem1.start;
2097 + iomem_resource.end = rc32434_res_pci_mem1.end;
2098 +*/
2099 +
2100 + pcicValue = rc32434_pci->pcic;
2101 + pcicValue = (pcicValue >> PCIM_SHFT) & PCIM_BIT_LEN;
2102 + if (!((pcicValue == PCIM_H_EA) ||
2103 + (pcicValue == PCIM_H_IA_FIX) ||
2104 + (pcicValue == PCIM_H_IA_RR))) {
2105 + /* Not in Host Mode, return ERROR */
2106 + return -1;
2107 + }
2108 +
2109 + /* Enables the Idle Grant mode, Arbiter Parking */
2110 + pcicData |=(PCIC_igm_m|PCIC_eap_m|PCIC_en_m);
2111 + rc32434_pci->pcic = pcicData; /* Enable the PCI bus Interface */
2112 + /* Zero out the PCI status & PCI Status Mask */
2113 + for(;;) {
2114 + pcicData = rc32434_pci->pcis;
2115 + if (!(pcicData & PCIS_rip_m))
2116 + break;
2117 + }
2118 +
2119 + rc32434_pci->pcis = 0;
2120 + rc32434_pci->pcism = 0xFFFFFFFF;
2121 + /* Zero out the PCI decoupled registers */
2122 + rc32434_pci->pcidac=0; /* disable PCI decoupled accesses at initialization */
2123 + rc32434_pci->pcidas=0; /* clear the status */
2124 + rc32434_pci->pcidasm=0x0000007F; /* Mask all the interrupts */
2125 + /* Mask PCI Messaging Interrupts */
2126 + rc32434_pci_msg->pciiic = 0;
2127 + rc32434_pci_msg->pciiim = 0xFFFFFFFF;
2128 + rc32434_pci_msg->pciioic = 0;
2129 + rc32434_pci_msg->pciioim = 0;
2130 +
2131 + /* Setup PCILB0 as Memory Window */
2132 + rc32434_pci->pcilba[0].a = (unsigned int) (PCI_ADDR_START);
2133 +
2134 + /* setup the PCI map address as same as the local address */
2135 +
2136 + rc32434_pci->pcilba[0].m = (unsigned int) (PCI_ADDR_START);
2137 +
2138 + /* Setup PCILBA1 as MEM */
2139 +#ifdef __MIPSEB__
2140 + rc32434_pci->pcilba[0].c = ( ((SIZE_16MB & 0x1f) << PCILBAC_size_b) | PCILBAC_sb_m);
2141 +#else
2142 + rc32434_pci->pcilba[0].c = ( ((SIZE_16MB & 0x1f) << PCILBAC_size_b));
2143 +#endif
2144 + dummyRead = rc32434_pci->pcilba[0].c; /* flush the CPU write Buffers */
2145 +
2146 + rc32434_pci->pcilba[1].a = 0x60000000;
2147 +
2148 + rc32434_pci->pcilba[1].m = 0x60000000;
2149 + /* setup PCILBA2 as IO Window*/
2150 +#ifdef __MIPSEB__
2151 + rc32434_pci->pcilba[1].c = ( ((SIZE_256MB & 0x1f) << PCILBAC_size_b) | PCILBAC_sb_m);
2152 +#else
2153 + rc32434_pci->pcilba[1].c = ((SIZE_256MB & 0x1f) << PCILBAC_size_b);
2154 +#endif
2155 + dummyRead = rc32434_pci->pcilba[1].c; /* flush the CPU write Buffers */
2156 + rc32434_pci->pcilba[2].a = 0x18C00000;
2157 +
2158 + rc32434_pci->pcilba[2].m = 0x18FFFFFF;
2159 + /* setup PCILBA2 as IO Window*/
2160 +#ifdef __MIPSEB__
2161 + rc32434_pci->pcilba[2].c = ( ((SIZE_4MB & 0x1f) << PCILBAC_size_b) | PCILBAC_sb_m);
2162 +#else
2163 + rc32434_pci->pcilba[2].c = ((SIZE_4MB & 0x1f) << PCILBAC_size_b);
2164 +#endif
2165 +
2166 + dummyRead = rc32434_pci->pcilba[2].c; /* flush the CPU write Buffers */
2167 +
2168 +
2169 + rc32434_pci->pcilba[3].a = 0x18800000;
2170 +
2171 + rc32434_pci->pcilba[3].m = 0x18800000;
2172 + /* Setup PCILBA3 as IO Window */
2173 +
2174 +#ifdef __MIPSEB__
2175 + rc32434_pci->pcilba[3].c = ( (((SIZE_1MB & 0x1ff) << PCILBAC_size_b) | PCILBAC_msi_m) | PCILBAC_sb_m);
2176 +#else
2177 + rc32434_pci->pcilba[3].c = (((SIZE_1MB & 0x1ff) << PCILBAC_size_b) | PCILBAC_msi_m);
2178 +#endif
2179 + dummyRead = rc32434_pci->pcilba[2].c; /* flush the CPU write Buffers */
2180 +
2181 + pciConfigAddr = (unsigned int)(0x80000004);
2182 + for(loopCount = 0; loopCount < 24; loopCount++){
2183 + rc32434_pci->pcicfga = pciConfigAddr;
2184 + dummyRead = rc32434_pci->pcicfga;
2185 + rc32434_pci->pcicfgd = korinaCnfgRegs[loopCount];
2186 + dummyRead=rc32434_pci->pcicfgd;
2187 + pciConfigAddr += 4;
2188 + }
2189 + rc32434_pci->pcitc=(unsigned int)((PCITC_RTIMER_VAL&0xff) << PCITC_rtimer_b) |
2190 + ((PCITC_DTIMER_VAL&0xff)<<PCITC_dtimer_b);
2191 +
2192 + pciCntlVal = rc32434_pci->pcic;
2193 + pciCntlVal &= ~(PCIC_tnr_m);
2194 + rc32434_pci->pcic = pciCntlVal;
2195 + pciCntlVal = rc32434_pci->pcic;
2196 +
2197 + register_pci_controller(&rc32434_controller);
2198 +
2199 + rc32434_sync();
2200 + return 0;
2201 +}
2202 +
2203 +arch_initcall(rc32434_pcibridge_init);
2204 +
2205 +/* Do platform specific device initialization at pci_enable_device() time */
2206 +int pcibios_plat_dev_init(struct pci_dev *dev)
2207 +{
2208 + return 0;
2209 +}
2210 diff -Nur linux-2.6.15/drivers/mtd/chips/cfi_probe.c linux-2.6.15-openwrt/drivers/mtd/chips/cfi_probe.c
2211 --- linux-2.6.15/drivers/mtd/chips/cfi_probe.c 2006-01-03 04:21:10.000000000 +0100
2212 +++ linux-2.6.15-openwrt/drivers/mtd/chips/cfi_probe.c 2006-01-10 00:32:32.000000000 +0100
2213 @@ -26,6 +26,74 @@
2214 static void print_cfi_ident(struct cfi_ident *);
2215 #endif
2216
2217 +#if 1
2218 +
2219 +#define AMD_AUTOSEL_OFF1 0xAAA
2220 +#define AMD_AUTOSEL_OFF2 0x555
2221 +#define AMD_MANUF_ID 0x1
2222 +#define AMD_DEVICE_ID1 0xF6 /* T */
2223 +#define AMD_DEVICE_ID2 0xF9 /* B */
2224 +/* Foll. are definitions for Macronix Flash Part */
2225 +#define MCX_MANUF_ID 0xC2
2226 +#define MCX_DEVICE_ID1 0xA7
2227 +#define MCX_DEVICE_ID2 0xA8
2228 +/* Foll. common to both AMD and Macronix */
2229 +#define FACTORY_LOCKED 0x99
2230 +#define USER_LOCKED 0x19
2231 +
2232 +/* NOTE: AP-70/6x use BYTE mode flash access. Therefore the
2233 + * lowest Addr. pin in the flash is not A0 but A-1 (A minus 1).
2234 + * CPU's A0 is tied to Flash's A-1, A1 to A0 and so on. This
2235 + * gives 4MB of byte-addressable mem. In byte mode, all addr
2236 + * need to be multiplied by 2 (i.e compared to word mode).
2237 + * NOTE: AMD_AUTOSEL_OFF1 and OFF2 are already mult. by 2
2238 + * Just blindly use the addr offsets suggested in the manual
2239 + * for byte mode and you'll be OK. Offs. in Table 6 need to
2240 + * be mult by 2 (for getting autosel params)
2241 + */
2242 +void
2243 +flash_detect(struct map_info *map, __u32 base, struct cfi_private *cfi)
2244 +{
2245 + map_word val[3];
2246 + int osf = cfi->interleave * cfi->device_type; // =2 for AP70/6x
2247 + char *manuf, *part, *lock ;
2248 +
2249 + if (osf != 1) return ;
2250 +
2251 + cfi_send_gen_cmd(0xAA, AMD_AUTOSEL_OFF1, base, map, cfi, cfi->device_type, NULL);
2252 + cfi_send_gen_cmd(0x55, AMD_AUTOSEL_OFF2, base, map, cfi, cfi->device_type, NULL);
2253 + cfi_send_gen_cmd(0x90, AMD_AUTOSEL_OFF1, base, map, cfi, cfi->device_type, NULL);
2254 + val[0] = map_read(map, base) ; // manuf ID
2255 + val[1] = map_read(map, base+2) ; // device ID
2256 + val[2] = map_read(map, base+6) ; // lock indicator
2257 +#if 0
2258 +printk("v1=0x%x v2=0x%x v3=0x%x\n", val[0], val[1], val[2]) ;
2259 +#endif
2260 + if (val[0].x[0] == AMD_MANUF_ID) {
2261 + manuf = "AMD Flash" ;
2262 + if (val[1].x[0] == AMD_DEVICE_ID1)
2263 + part = "AM29LV320D (Top)" ;
2264 + else if (val[1].x[0] == AMD_DEVICE_ID2)
2265 + part = "AM29LV320D (Bot)" ;
2266 + else part = "Unknown" ;
2267 + } else if (val[0].x[0] == MCX_MANUF_ID) {
2268 + manuf = "Macronix Flash" ;
2269 + if (val[1].x[0] == MCX_DEVICE_ID1)
2270 + part = "MX29LV320A (Top)" ;
2271 + else if (val[1].x[0] == MCX_DEVICE_ID2)
2272 + part = "MX29LV320A (Bot)" ;
2273 + else part = "Unknown" ;
2274 + } else
2275 + return ;
2276 + if (val[2].x[0] == FACTORY_LOCKED)
2277 + lock = "Factory Locked" ;
2278 + else if (val[2].x[0] == USER_LOCKED)
2279 + lock = "User Locked" ;
2280 + else lock = "Unknown locking" ;
2281 + printk("%s %s (%s)\n", manuf, part, lock) ;
2282 +}
2283 +#endif
2284 +
2285 static int cfi_probe_chip(struct map_info *map, __u32 base,
2286 unsigned long *chip_map, struct cfi_private *cfi);
2287 static int cfi_chip_setup(struct map_info *map, struct cfi_private *cfi);
2288 @@ -118,6 +186,10 @@
2289 }
2290
2291 xip_disable();
2292 +#if 1
2293 + //cfi_send_gen_cmd(0xF0, 0, base, map, cfi, cfi->device_type, NULL);
2294 + flash_detect(map, base, cfi) ;
2295 +#endif
2296 cfi_send_gen_cmd(0xF0, 0, base, map, cfi, cfi->device_type, NULL);
2297 cfi_send_gen_cmd(0xFF, 0, base, map, cfi, cfi->device_type, NULL);
2298 cfi_send_gen_cmd(0x98, 0x55, base, map, cfi, cfi->device_type, NULL);
2299 diff -Nur linux-2.6.15/drivers/mtd/maps/physmap.c linux-2.6.15-openwrt/drivers/mtd/maps/physmap.c
2300 --- linux-2.6.15/drivers/mtd/maps/physmap.c 2006-01-03 04:21:10.000000000 +0100
2301 +++ linux-2.6.15-openwrt/drivers/mtd/maps/physmap.c 2006-01-10 00:32:32.000000000 +0100
2302 @@ -34,15 +34,31 @@
2303 static struct mtd_partition *mtd_parts;
2304 static int mtd_parts_nb;
2305
2306 -static int num_physmap_partitions;
2307 -static struct mtd_partition *physmap_partitions;
2308 +static int num_physmap_partitions = 3;
2309 +static struct mtd_partition physmap_partitions[] = {
2310 + {
2311 + name: "zImage",
2312 + size: 0x3f0000-0x80000,
2313 + offset: 0x80000,
2314 + },
2315 + {
2316 + name: "JFFS2",
2317 + size: 0x3f0000-0x120000,
2318 + offset: 0x120000,
2319 + },
2320 + {
2321 + name: "NVRAM",
2322 + size: 0x2000,
2323 + offset: 0x3f8000,
2324 + }
2325 +};
2326
2327 static const char *part_probes[] __initdata = {"cmdlinepart", "RedBoot", NULL};
2328
2329 void physmap_set_partitions(struct mtd_partition *parts, int num_parts)
2330 {
2331 - physmap_partitions=parts;
2332 - num_physmap_partitions=num_parts;
2333 +// physmap_partitions=parts;
2334 +// num_physmap_partitions=num_parts;
2335 }
2336 #endif /* CONFIG_MTD_PARTITIONS */
2337
2338 diff -Nur linux-2.6.15/drivers/net/Kconfig linux-2.6.15-openwrt/drivers/net/Kconfig
2339 --- linux-2.6.15/drivers/net/Kconfig 2006-01-03 04:21:10.000000000 +0100
2340 +++ linux-2.6.15-openwrt/drivers/net/Kconfig 2006-01-10 00:32:32.000000000 +0100
2341 @@ -176,6 +176,13 @@
2342
2343 source "drivers/net/arm/Kconfig"
2344
2345 +config IDT_RC32434_ETH
2346 + tristate "IDT RC32434 Local Ethernet support"
2347 + depends on NET_ETHERNET
2348 + help
2349 + IDT RC32434 has one local ethernet port. Say Y here to enable it.
2350 + To compile this driver as a module, choose M here.
2351 +
2352 config MACE
2353 tristate "MACE (Power Mac ethernet) support"
2354 depends on NET_ETHERNET && PPC_PMAC && PPC32
2355 diff -Nur linux-2.6.15/drivers/net/Makefile linux-2.6.15-openwrt/drivers/net/Makefile
2356 --- linux-2.6.15/drivers/net/Makefile 2006-01-03 04:21:10.000000000 +0100
2357 +++ linux-2.6.15-openwrt/drivers/net/Makefile 2006-01-10 00:32:33.000000000 +0100
2358 @@ -190,6 +190,7 @@
2359 obj-$(CONFIG_SMC91X) += smc91x.o
2360 obj-$(CONFIG_DM9000) += dm9000.o
2361 obj-$(CONFIG_FEC_8XX) += fec_8xx/
2362 +obj-$(CONFIG_IDT_RC32434_ETH) += rc32434_eth.o
2363
2364 obj-$(CONFIG_ARM) += arm/
2365 obj-$(CONFIG_DEV_APPLETALK) += appletalk/
2366 diff -Nur linux-2.6.15/drivers/net/rc32434_eth.c linux-2.6.15-openwrt/drivers/net/rc32434_eth.c
2367 --- linux-2.6.15/drivers/net/rc32434_eth.c 1970-01-01 01:00:00.000000000 +0100
2368 +++ linux-2.6.15-openwrt/drivers/net/rc32434_eth.c 2006-01-10 00:32:33.000000000 +0100
2369 @@ -0,0 +1,1268 @@
2370 +/**************************************************************************
2371 + *
2372 + * BRIEF MODULE DESCRIPTION
2373 + * Driver for the IDT RC32434 on-chip ethernet controller.
2374 + *
2375 + * Copyright 2004 IDT Inc. (rischelp@idt.com)
2376 + *
2377 + * This program is free software; you can redistribute it and/or modify it
2378 + * under the terms of the GNU General Public License as published by the
2379 + * Free Software Foundation; either version 2 of the License, or (at your
2380 + * option) any later version.
2381 + *
2382 + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
2383 + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
2384 + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
2385 + * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
2386 + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
2387 + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
2388 + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
2389 + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
2390 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
2391 + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
2392 + *
2393 + * You should have received a copy of the GNU General Public License along
2394 + * with this program; if not, write to the Free Software Foundation, Inc.,
2395 + * 675 Mass Ave, Cambridge, MA 02139, USA.
2396 + *
2397 + *
2398 + **************************************************************************
2399 + * May 2004 rkt, neb
2400 + *
2401 + * Based on the driver developed by B. Maruthanayakam, H. Kou and others.
2402 + *
2403 + * Aug 2004 Sadik
2404 + *
2405 + * Added NAPI
2406 + *
2407 + **************************************************************************
2408 + */
2409 +
2410 +#include <linux/config.h>
2411 +#include <linux/module.h>
2412 +#include <linux/kernel.h>
2413 +#include <linux/moduleparam.h>
2414 +#include <linux/sched.h>
2415 +#include <linux/ctype.h>
2416 +#include <linux/types.h>
2417 +#include <linux/fcntl.h>
2418 +#include <linux/interrupt.h>
2419 +#include <linux/ptrace.h>
2420 +#include <linux/init.h>
2421 +#include <linux/ioport.h>
2422 +#include <linux/proc_fs.h>
2423 +#include <linux/in.h>
2424 +#include <linux/slab.h>
2425 +#include <linux/string.h>
2426 +#include <linux/delay.h>
2427 +#include <linux/netdevice.h>
2428 +#include <linux/etherdevice.h>
2429 +#include <linux/skbuff.h>
2430 +#include <linux/errno.h>
2431 +#include <asm/bootinfo.h>
2432 +#include <asm/system.h>
2433 +#include <asm/bitops.h>
2434 +#include <asm/pgtable.h>
2435 +#include <asm/segment.h>
2436 +#include <asm/io.h>
2437 +#include <asm/dma.h>
2438 +
2439 +#include "rc32434_eth.h"
2440 +
2441 +#define DRIVER_VERSION "(mar2904)"
2442 +
2443 +#define DRIVER_NAME "rc32434 Ethernet driver. " DRIVER_VERSION
2444 +
2445 +
2446 +#define STATION_ADDRESS_HIGH(dev) (((dev)->dev_addr[0] << 8) | \
2447 + ((dev)->dev_addr[1]))
2448 +#define STATION_ADDRESS_LOW(dev) (((dev)->dev_addr[2] << 24) | \
2449 + ((dev)->dev_addr[3] << 16) | \
2450 + ((dev)->dev_addr[4] << 8) | \
2451 + ((dev)->dev_addr[5]))
2452 +
2453 +#define MII_CLOCK 1250000 /* no more than 2.5MHz */
2454 +static char mac0[18] = "08:00:06:05:40:01";
2455 +
2456 +MODULE_PARM(mac0, "c18");
2457 +MODULE_PARM_DESC(mac0, "MAC address for RC32434 ethernet0");
2458 +
2459 +static struct rc32434_if_t {
2460 + char *name;
2461 + struct net_device *dev;
2462 + char* mac_str;
2463 + int weight;
2464 + u32 iobase;
2465 + u32 rxdmabase;
2466 + u32 txdmabase;
2467 + int rx_dma_irq;
2468 + int tx_dma_irq;
2469 + int rx_ovr_irq;
2470 + int tx_und_irq;
2471 +} rc32434_iflist[] =
2472 +{
2473 + {
2474 + "rc32434_eth0", NULL, mac0,
2475 + 64,
2476 + ETH0_PhysicalAddress,
2477 + ETH0_RX_DMA_ADDR,
2478 + ETH0_TX_DMA_ADDR,
2479 + ETH0_DMA_RX_IRQ,
2480 + ETH0_DMA_TX_IRQ,
2481 + ETH0_RX_OVR_IRQ,
2482 + ETH0_TX_UND_IRQ
2483 + }
2484 +};
2485 +
2486 +
2487 +static int parse_mac_addr(struct net_device *dev, char* macstr)
2488 +{
2489 + int i, j;
2490 + unsigned char result, value;
2491 +
2492 + for (i=0; i<6; i++) {
2493 + result = 0;
2494 + if (i != 5 && *(macstr+2) != ':') {
2495 + ERR("invalid mac address format: %d %c\n",
2496 + i, *(macstr+2));
2497 + return -EINVAL;
2498 + }
2499 + for (j=0; j<2; j++) {
2500 + if (isxdigit(*macstr) && (value = isdigit(*macstr) ? *macstr-'0' :
2501 + toupper(*macstr)-'A'+10) < 16) {
2502 + result = result*16 + value;
2503 + macstr++;
2504 + }
2505 + else {
2506 + ERR("invalid mac address "
2507 + "character: %c\n", *macstr);
2508 + return -EINVAL;
2509 + }
2510 + }
2511 +
2512 + macstr++;
2513 + dev->dev_addr[i] = result;
2514 + }
2515 +
2516 + return 0;
2517 +}
2518 +
2519 +
2520 +
2521 +static inline void rc32434_abort_tx(struct net_device *dev)
2522 +{
2523 + struct rc32434_local *lp = (struct rc32434_local *)dev->priv;
2524 + rc32434_abort_dma(dev, lp->tx_dma_regs);
2525 +
2526 +}
2527 +
2528 +static inline void rc32434_abort_rx(struct net_device *dev)
2529 +{
2530 + struct rc32434_local *lp = (struct rc32434_local *)dev->priv;
2531 + rc32434_abort_dma(dev, lp->rx_dma_regs);
2532 +
2533 +}
2534 +
2535 +static inline void rc32434_start_tx(struct rc32434_local *lp, volatile DMAD_t td)
2536 +{
2537 + rc32434_start_dma(lp->tx_dma_regs, CPHYSADDR(td));
2538 +}
2539 +
2540 +static inline void rc32434_start_rx(struct rc32434_local *lp, volatile DMAD_t rd)
2541 +{
2542 + rc32434_start_dma(lp->rx_dma_regs, CPHYSADDR(rd));
2543 +}
2544 +
2545 +static inline void rc32434_chain_tx(struct rc32434_local *lp, volatile DMAD_t td)
2546 +{
2547 + rc32434_chain_dma(lp->tx_dma_regs, CPHYSADDR(td));
2548 +}
2549 +
2550 +static inline void rc32434_chain_rx(struct rc32434_local *lp, volatile DMAD_t rd)
2551 +{
2552 + rc32434_chain_dma(lp->rx_dma_regs, CPHYSADDR(rd));
2553 +}
2554 +
2555 +#ifdef RC32434_PROC_DEBUG
2556 +static int rc32434_read_proc(char *buf, char **start, off_t fpos,
2557 + int length, int *eof, void *data)
2558 +{
2559 + struct net_device *dev = (struct net_device *)data;
2560 + struct rc32434_local *lp = (struct rc32434_local *)dev->priv;
2561 + int len = 0;
2562 +
2563 + /* print out header */
2564 + len += sprintf(buf + len, "\n\tRC32434 Ethernet Debug\n\n");
2565 + len += sprintf (buf + len,
2566 + "DMA halt count = %10d, DMA run count = %10d\n",
2567 + lp->dma_halt_cnt, lp->dma_run_cnt);
2568 +
2569 + if (fpos >= len) {
2570 + *start = buf;
2571 + *eof = 1;
2572 + return 0;
2573 + }
2574 + *start = buf + fpos;
2575 +
2576 + if ((len -= fpos) > length)
2577 + return length;
2578 + *eof = 1;
2579 +
2580 + return len;
2581 +
2582 +}
2583 +#endif
2584 +
2585 +
2586 +/*
2587 + * Restart the RC32434 ethernet controller.
2588 + */
2589 +static int rc32434_restart(struct net_device *dev)
2590 +{
2591 + struct rc32434_local *lp = (struct rc32434_local *)dev->priv;
2592 +
2593 + /*
2594 + * Disable interrupts
2595 + */
2596 + disable_irq(lp->rx_irq);
2597 + disable_irq(lp->tx_irq);
2598 +#ifdef RC32434_REVISION
2599 + disable_irq(lp->ovr_irq);
2600 +#endif
2601 + disable_irq(lp->und_irq);
2602 +
2603 + /* Mask F E bit in Tx DMA */
2604 + rc32434_writel(rc32434_readl(&lp->tx_dma_regs->dmasm) | DMASM_f_m | DMASM_e_m, &lp->tx_dma_regs->dmasm);
2605 + /* Mask D H E bit in Rx DMA */
2606 + rc32434_writel(rc32434_readl(&lp->rx_dma_regs->dmasm) | DMASM_d_m | DMASM_h_m | DMASM_e_m, &lp->rx_dma_regs->dmasm);
2607 +
2608 + rc32434_init(dev);
2609 + rc32434_multicast_list(dev);
2610 +
2611 + enable_irq(lp->und_irq);
2612 +#ifdef RC32434_REVISION
2613 + enable_irq(lp->ovr_irq);
2614 +#endif
2615 + enable_irq(lp->tx_irq);
2616 + enable_irq(lp->rx_irq);
2617 +
2618 + return 0;
2619 +}
2620 +
2621 +int rc32434_init_module(void)
2622 +{
2623 +#ifdef CONFIG_MACH_ARUBA
2624 + if (mips_machtype != MACH_ARUBA_AP70)
2625 + return 1;
2626 +#endif
2627 +
2628 + printk(KERN_INFO DRIVER_NAME " \n");
2629 + return rc32434_probe(0);
2630 +}
2631 +
2632 +static int rc32434_probe(int port_num)
2633 +{
2634 + struct rc32434_if_t *bif = &rc32434_iflist[port_num];
2635 + struct rc32434_local *lp = NULL;
2636 + struct net_device *dev = NULL;
2637 + int i, retval,err;
2638 +
2639 + dev = alloc_etherdev(sizeof(struct rc32434_local));
2640 + if(!dev) {
2641 + ERR("rc32434_eth: alloc_etherdev failed\n");
2642 + return -1;
2643 + }
2644 +
2645 + SET_MODULE_OWNER(dev);
2646 + bif->dev = dev;
2647 +
2648 +#ifdef CONFIG_MACH_ARUBA
2649 + {
2650 + extern char * getenv(char *e);
2651 + memcpy(bif->mac_str, getenv("ethaddr"), 17);
2652 + }
2653 +#endif
2654 +
2655 + printk("mac: %s\n", bif->mac_str);
2656 + if ((retval = parse_mac_addr(dev, bif->mac_str))) {
2657 + ERR("MAC address parse failed\n");
2658 + free_netdev(dev);
2659 + return -1;
2660 + }
2661 +
2662 +
2663 + /* Initialize the device structure. */
2664 + if (dev->priv == NULL) {
2665 + lp = (struct rc32434_local *)kmalloc(sizeof(*lp), GFP_KERNEL);
2666 + memset(lp, 0, sizeof(struct rc32434_local));
2667 + }
2668 + else {
2669 + lp = (struct rc32434_local *)dev->priv;
2670 + }
2671 +
2672 + lp->rx_irq = bif->rx_dma_irq;
2673 + lp->tx_irq = bif->tx_dma_irq;
2674 + lp->ovr_irq = bif->rx_ovr_irq;
2675 + lp->und_irq = bif->tx_und_irq;
2676 +
2677 + lp->eth_regs = ioremap_nocache(bif->iobase, sizeof(*lp->eth_regs));
2678 +
2679 + if (!lp->eth_regs) {
2680 + ERR("Can't remap eth registers\n");
2681 + retval = -ENXIO;
2682 + goto probe_err_out;
2683 + }
2684 +
2685 + lp->rx_dma_regs = ioremap_nocache(bif->rxdmabase, sizeof(struct DMA_Chan_s));
2686 +
2687 + if (!lp->rx_dma_regs) {
2688 + ERR("Can't remap Rx DMA registers\n");
2689 + retval = -ENXIO;
2690 + goto probe_err_out;
2691 + }
2692 + lp->tx_dma_regs = ioremap_nocache(bif->txdmabase,sizeof(struct DMA_Chan_s));
2693 +
2694 + if (!lp->tx_dma_regs) {
2695 + ERR("Can't remap Tx DMA registers\n");
2696 + retval = -ENXIO;
2697 + goto probe_err_out;
2698 + }
2699 +
2700 +#ifdef RC32434_PROC_DEBUG
2701 + lp->ps = create_proc_read_entry (bif->name, 0, proc_net,
2702 + rc32434_read_proc, dev);
2703 +#endif
2704 +
2705 + lp->td_ring = (DMAD_t)kmalloc(TD_RING_SIZE + RD_RING_SIZE, GFP_KERNEL);
2706 + if (!lp->td_ring) {
2707 + ERR("Can't allocate descriptors\n");
2708 + retval = -ENOMEM;
2709 + goto probe_err_out;
2710 + }
2711 +
2712 + dma_cache_inv((unsigned long)(lp->td_ring), TD_RING_SIZE + RD_RING_SIZE);
2713 +
2714 + /* now convert TD_RING pointer to KSEG1 */
2715 + lp->td_ring = (DMAD_t )KSEG1ADDR(lp->td_ring);
2716 + lp->rd_ring = &lp->td_ring[RC32434_NUM_TDS];
2717 +
2718 +
2719 + spin_lock_init(&lp->lock);
2720 +
2721 + dev->base_addr = bif->iobase;
2722 + /* just use the rx dma irq */
2723 + dev->irq = bif->rx_dma_irq;
2724 +
2725 + dev->priv = lp;
2726 +
2727 + dev->open = rc32434_open;
2728 + dev->stop = rc32434_close;
2729 + dev->hard_start_xmit = rc32434_send_packet;
2730 + dev->get_stats = rc32434_get_stats;
2731 + dev->set_multicast_list = &rc32434_multicast_list;
2732 + dev->tx_timeout = rc32434_tx_timeout;
2733 + dev->watchdog_timeo = RC32434_TX_TIMEOUT;
2734 +
2735 +#ifdef CONFIG_IDT_USE_NAPI
2736 + dev->poll = rc32434_poll;
2737 + dev->weight = bif->weight;
2738 + printk("Using NAPI with weight %d\n",dev->weight);
2739 +#else
2740 + lp->rx_tasklet = kmalloc(sizeof(struct tasklet_struct), GFP_KERNEL);
2741 + tasklet_init(lp->rx_tasklet, rc32434_rx_tasklet, (unsigned long)dev);
2742 +#endif
2743 + lp->tx_tasklet = kmalloc(sizeof(struct tasklet_struct), GFP_KERNEL);
2744 + tasklet_init(lp->tx_tasklet, rc32434_tx_tasklet, (unsigned long)dev);
2745 +
2746 + if ((err = register_netdev(dev))) {
2747 + printk(KERN_ERR "rc32434 ethernet. Cannot register net device %d\n", err);
2748 + free_netdev(dev);
2749 + retval = -EINVAL;
2750 + goto probe_err_out;
2751 + }
2752 +
2753 + INFO("Rx IRQ %d, Tx IRQ %d, ", bif->rx_dma_irq, bif->tx_dma_irq);
2754 + for (i = 0; i < 6; i++) {
2755 + printk("%2.2x", dev->dev_addr[i]);
2756 + if (i<5)
2757 + printk(":");
2758 + }
2759 + printk("\n");
2760 +
2761 + return 0;
2762 +
2763 + probe_err_out:
2764 + rc32434_cleanup_module();
2765 + ERR(" failed. Returns %d\n", retval);
2766 + return retval;
2767 +
2768 +}
2769 +
2770 +
2771 +static void rc32434_cleanup_module(void)
2772 +{
2773 + int i;
2774 +
2775 + for (i = 0; rc32434_iflist[i].iobase; i++) {
2776 + struct rc32434_if_t * bif = &rc32434_iflist[i];
2777 + if (bif->dev != NULL) {
2778 + struct rc32434_local *lp = (struct rc32434_local *)bif->dev->priv;
2779 + if (lp != NULL) {
2780 + if (lp->eth_regs)
2781 + iounmap((void*)lp->eth_regs);
2782 + if (lp->rx_dma_regs)
2783 + iounmap((void*)lp->rx_dma_regs);
2784 + if (lp->tx_dma_regs)
2785 + iounmap((void*)lp->tx_dma_regs);
2786 + if (lp->td_ring)
2787 + kfree((void*)KSEG0ADDR(lp->td_ring));
2788 +
2789 +#ifdef RC32434_PROC_DEBUG
2790 + if (lp->ps) {
2791 + remove_proc_entry(bif->name, proc_net);
2792 + }
2793 +#endif
2794 + kfree(lp);
2795 + }
2796 +
2797 + unregister_netdev(bif->dev);
2798 + free_netdev(bif->dev);
2799 + kfree(bif->dev);
2800 + }
2801 + }
2802 +}
2803 +
2804 +
2805 +
2806 +static int rc32434_open(struct net_device *dev)
2807 +{
2808 + struct rc32434_local *lp = (struct rc32434_local *)dev->priv;
2809 +
2810 + /* Initialize */
2811 + if (rc32434_init(dev)) {
2812 + ERR("Error: cannot open the Ethernet device\n");
2813 + return -EAGAIN;
2814 + }
2815 +
2816 + /* Install the interrupt handler that handles the Done Finished Ovr and Und Events */
2817 + if (request_irq(lp->rx_irq, &rc32434_rx_dma_interrupt,
2818 + SA_SHIRQ | SA_INTERRUPT,
2819 + "rc32434 ethernet Rx", dev)) {
2820 + ERR(": unable to get Rx DMA IRQ %d\n",
2821 + lp->rx_irq);
2822 + return -EAGAIN;
2823 + }
2824 + if (request_irq(lp->tx_irq, &rc32434_tx_dma_interrupt,
2825 + SA_SHIRQ | SA_INTERRUPT,
2826 + "rc32434 ethernet Tx", dev)) {
2827 + ERR(": unable to get Tx DMA IRQ %d\n",
2828 + lp->tx_irq);
2829 + free_irq(lp->rx_irq, dev);
2830 + return -EAGAIN;
2831 + }
2832 +
2833 +#ifdef RC32434_REVISION
2834 + /* Install handler for overrun error. */
2835 + if (request_irq(lp->ovr_irq, &rc32434_ovr_interrupt,
2836 + SA_SHIRQ | SA_INTERRUPT,
2837 + "Ethernet Overflow", dev)) {
2838 + ERR(": unable to get OVR IRQ %d\n",
2839 + lp->ovr_irq);
2840 + free_irq(lp->rx_irq, dev);
2841 + free_irq(lp->tx_irq, dev);
2842 + return -EAGAIN;
2843 + }
2844 +#endif
2845 +
2846 + /* Install handler for underflow error. */
2847 + if (request_irq(lp->und_irq, &rc32434_und_interrupt,
2848 + SA_SHIRQ | SA_INTERRUPT,
2849 + "Ethernet Underflow", dev)) {
2850 + ERR(": unable to get UND IRQ %d\n",
2851 + lp->und_irq);
2852 + free_irq(lp->rx_irq, dev);
2853 + free_irq(lp->tx_irq, dev);
2854 +#ifdef RC32434_REVISION
2855 + free_irq(lp->ovr_irq, dev);
2856 +#endif
2857 + return -EAGAIN;
2858 + }
2859 +
2860 +
2861 + return 0;
2862 +}
2863 +
2864 +
2865 +
2866 +
2867 +static int rc32434_close(struct net_device *dev)
2868 +{
2869 + struct rc32434_local *lp = (struct rc32434_local *)dev->priv;
2870 + u32 tmp;
2871 +
2872 + /* Disable interrupts */
2873 + disable_irq(lp->rx_irq);
2874 + disable_irq(lp->tx_irq);
2875 +#ifdef RC32434_REVISION
2876 + disable_irq(lp->ovr_irq);
2877 +#endif
2878 + disable_irq(lp->und_irq);
2879 +
2880 + tmp = rc32434_readl(&lp->tx_dma_regs->dmasm);
2881 + tmp = tmp | DMASM_f_m | DMASM_e_m;
2882 + rc32434_writel(tmp, &lp->tx_dma_regs->dmasm);
2883 +
2884 + tmp = rc32434_readl(&lp->rx_dma_regs->dmasm);
2885 + tmp = tmp | DMASM_d_m | DMASM_h_m | DMASM_e_m;
2886 + rc32434_writel(tmp, &lp->rx_dma_regs->dmasm);
2887 +
2888 + free_irq(lp->rx_irq, dev);
2889 + free_irq(lp->tx_irq, dev);
2890 +#ifdef RC32434_REVISION
2891 + free_irq(lp->ovr_irq, dev);
2892 +#endif
2893 + free_irq(lp->und_irq, dev);
2894 + return 0;
2895 +}
2896 +
2897 +
2898 +/* transmit packet */
2899 +static int rc32434_send_packet(struct sk_buff *skb, struct net_device *dev)
2900 +{
2901 + struct rc32434_local *lp = (struct rc32434_local *)dev->priv;
2902 + unsigned long flags;
2903 + u32 length;
2904 + DMAD_t td;
2905 +
2906 +
2907 + spin_lock_irqsave(&lp->lock, flags);
2908 +
2909 + td = &lp->td_ring[lp->tx_chain_tail];
2910 +
2911 + /* stop queue when full, drop pkts if queue already full */
2912 + if(lp->tx_count >= (RC32434_NUM_TDS - 2)) {
2913 + lp->tx_full = 1;
2914 +
2915 + if(lp->tx_count == (RC32434_NUM_TDS - 2)) {
2916 + netif_stop_queue(dev);
2917 + }
2918 + else {
2919 + lp->stats.tx_dropped++;
2920 + dev_kfree_skb_any(skb);
2921 + spin_unlock_irqrestore(&lp->lock, flags);
2922 + return 1;
2923 + }
2924 + }
2925 +
2926 + lp->tx_count ++;
2927 +
2928 + lp->tx_skb[lp->tx_chain_tail] = skb;
2929 +
2930 + length = skb->len;
2931 +
2932 + /* Setup the transmit descriptor. */
2933 + td->ca = CPHYSADDR(skb->data);
2934 +
2935 + if(rc32434_readl(&(lp->tx_dma_regs->dmandptr)) == 0) {
2936 + if( lp->tx_chain_status == empty ) {
2937 + td->control = DMA_COUNT(length) |DMAD_cof_m |DMAD_iof_m; /* Update tail */
2938 + lp->tx_chain_tail = (lp->tx_chain_tail + 1) & RC32434_TDS_MASK; /* Move tail */
2939 + rc32434_writel(CPHYSADDR(&lp->td_ring[lp->tx_chain_head]), &(lp->tx_dma_regs->dmandptr)); /* Write to NDPTR */
2940 + lp->tx_chain_head = lp->tx_chain_tail; /* Move head to tail */
2941 + }
2942 + else {
2943 + td->control = DMA_COUNT(length) |DMAD_cof_m|DMAD_iof_m; /* Update tail */
2944 + lp->td_ring[(lp->tx_chain_tail-1)& RC32434_TDS_MASK].control &= ~(DMAD_cof_m); /* Link to prev */
2945 + lp->td_ring[(lp->tx_chain_tail-1)& RC32434_TDS_MASK].link = CPHYSADDR(td); /* Link to prev */
2946 + lp->tx_chain_tail = (lp->tx_chain_tail + 1) & RC32434_TDS_MASK; /* Move tail */
2947 + rc32434_writel(CPHYSADDR(&lp->td_ring[lp->tx_chain_head]), &(lp->tx_dma_regs->dmandptr)); /* Write to NDPTR */
2948 + lp->tx_chain_head = lp->tx_chain_tail; /* Move head to tail */
2949 + lp->tx_chain_status = empty;
2950 + }
2951 + }
2952 + else {
2953 + if( lp->tx_chain_status == empty ) {
2954 + td->control = DMA_COUNT(length) |DMAD_cof_m |DMAD_iof_m; /* Update tail */
2955 + lp->tx_chain_tail = (lp->tx_chain_tail + 1) & RC32434_TDS_MASK; /* Move tail */
2956 + lp->tx_chain_status = filled;
2957 + }
2958 + else {
2959 + td->control = DMA_COUNT(length) |DMAD_cof_m |DMAD_iof_m; /* Update tail */
2960 + lp->td_ring[(lp->tx_chain_tail-1)& RC32434_TDS_MASK].control &= ~(DMAD_cof_m); /* Link to prev */
2961 + lp->td_ring[(lp->tx_chain_tail-1)& RC32434_TDS_MASK].link = CPHYSADDR(td); /* Link to prev */
2962 + lp->tx_chain_tail = (lp->tx_chain_tail + 1) & RC32434_TDS_MASK; /* Move tail */
2963 + }
2964 + }
2965 +
2966 + dev->trans_start = jiffies;
2967 +
2968 + spin_unlock_irqrestore(&lp->lock, flags);
2969 +
2970 + return 0;
2971 +}
2972 +
2973 +
2974 +/* Ethernet MII-PHY Handler */
2975 +static void rc32434_mii_handler(unsigned long data)
2976 +{
2977 + struct net_device *dev = (struct net_device *)data;
2978 + struct rc32434_local *lp = (struct rc32434_local *)dev->priv;
2979 + unsigned long flags;
2980 + unsigned long duplex_status;
2981 + int port_addr = (lp->rx_irq == 0x2c? 1:0) << 8;
2982 +
2983 + spin_lock_irqsave(&lp->lock, flags);
2984 +
2985 + /* Two ports are using the same MII, the difference is the PHY address */
2986 + rc32434_writel(0, &rc32434_eth0_regs->miimcfg);
2987 + rc32434_writel(0, &rc32434_eth0_regs->miimcmd);
2988 + rc32434_writel(port_addr |0x05, &rc32434_eth0_regs->miimaddr);
2989 + rc32434_writel(MIIMCMD_scn_m, &rc32434_eth0_regs->miimcmd);
2990 + while(rc32434_readl(&rc32434_eth0_regs->miimind) & MIIMIND_nv_m);
2991 +
2992 + ERR("irq:%x port_addr:%x RDD:%x\n",
2993 + lp->rx_irq, port_addr, rc32434_readl(&rc32434_eth0_regs->miimrdd));
2994 + duplex_status = (rc32434_readl(&rc32434_eth0_regs->miimrdd) & 0x140)? ETHMAC2_fd_m: 0;
2995 + if(duplex_status != lp->duplex_mode) {
2996 + ERR("The MII-PHY is Auto-negotiated to %s-Duplex mode for Eth-%x\n", duplex_status? "Full":"Half", lp->rx_irq == 0x2c? 1:0);
2997 + lp->duplex_mode = duplex_status;
2998 + rc32434_restart(dev);
2999 + }
3000 +
3001 + lp->mii_phy_timer.expires = jiffies + 10 * HZ;
3002 + add_timer(&lp->mii_phy_timer);
3003 +
3004 + spin_unlock_irqrestore(&lp->lock, flags);
3005 +
3006 +}
3007 +
3008 +#ifdef RC32434_REVISION
3009 +/* Ethernet Rx Overflow interrupt */
3010 +static irqreturn_t
3011 +rc32434_ovr_interrupt(int irq, void *dev_id, struct pt_regs * regs)
3012 +{
3013 + struct net_device *dev = (struct net_device *)dev_id;
3014 + struct rc32434_local *lp;
3015 + unsigned int ovr;
3016 + irqreturn_t retval = IRQ_NONE;
3017 +
3018 + ASSERT(dev != NULL);
3019 +
3020 + lp = (struct rc32434_local *)dev->priv;
3021 + spin_lock(&lp->lock);
3022 + ovr = rc32434_readl(&lp->eth_regs->ethintfc);
3023 +
3024 + if(ovr & ETHINTFC_ovr_m) {
3025 + netif_stop_queue(dev);
3026 +
3027 + /* clear OVR bit */
3028 + rc32434_writel((ovr & ~ETHINTFC_ovr_m), &lp->eth_regs->ethintfc);
3029 +
3030 + /* Restart interface */
3031 + rc32434_restart(dev);
3032 + retval = IRQ_HANDLED;
3033 + }
3034 + spin_unlock(&lp->lock);
3035 +
3036 + return retval;
3037 +}
3038 +
3039 +#endif
3040 +
3041 +
3042 +/* Ethernet Tx Underflow interrupt */
3043 +static irqreturn_t
3044 +rc32434_und_interrupt(int irq, void *dev_id, struct pt_regs * regs)
3045 +{
3046 + struct net_device *dev = (struct net_device *)dev_id;
3047 + struct rc32434_local *lp;
3048 + unsigned int und;
3049 + irqreturn_t retval = IRQ_NONE;
3050 +
3051 + ASSERT(dev != NULL);
3052 +
3053 + lp = (struct rc32434_local *)dev->priv;
3054 +
3055 + spin_lock(&lp->lock);
3056 +
3057 + und = rc32434_readl(&lp->eth_regs->ethintfc);
3058 +
3059 + if(und & ETHINTFC_und_m) {
3060 + netif_stop_queue(dev);
3061 +
3062 + rc32434_writel((und & ~ETHINTFC_und_m), &lp->eth_regs->ethintfc);
3063 +
3064 + /* Restart interface */
3065 + rc32434_restart(dev);
3066 + retval = IRQ_HANDLED;
3067 + }
3068 +
3069 + spin_unlock(&lp->lock);
3070 +
3071 + return retval;
3072 +}
3073 +
3074 +
3075 +/* Ethernet Rx DMA interrupt */
3076 +static irqreturn_t
3077 +rc32434_rx_dma_interrupt(int irq, void *dev_id, struct pt_regs * regs)
3078 +{
3079 + struct net_device *dev = (struct net_device *)dev_id;
3080 + struct rc32434_local* lp;
3081 + volatile u32 dmas,dmasm;
3082 + irqreturn_t retval;
3083 +
3084 + ASSERT(dev != NULL);
3085 +
3086 + lp = (struct rc32434_local *)dev->priv;
3087 +
3088 + spin_lock(&lp->lock);
3089 + dmas = rc32434_readl(&lp->rx_dma_regs->dmas);
3090 + if(dmas & (DMAS_d_m|DMAS_h_m|DMAS_e_m)) {
3091 + /* Mask D H E bit in Rx DMA */
3092 + dmasm = rc32434_readl(&lp->rx_dma_regs->dmasm);
3093 + rc32434_writel(dmasm | (DMASM_d_m | DMASM_h_m | DMASM_e_m), &lp->rx_dma_regs->dmasm);
3094 +#ifdef CONFIG_IDT_USE_NAPI
3095 + if(netif_rx_schedule_prep(dev))
3096 + __netif_rx_schedule(dev);
3097 +#else
3098 + tasklet_hi_schedule(lp->rx_tasklet);
3099 +#endif
3100 +
3101 + if (dmas & DMAS_e_m)
3102 + ERR(": DMA error\n");
3103 +
3104 + retval = IRQ_HANDLED;
3105 + }
3106 + else
3107 + retval = IRQ_NONE;
3108 +
3109 + spin_unlock(&lp->lock);
3110 + return retval;
3111 +}
3112 +
3113 +#ifdef CONFIG_IDT_USE_NAPI
3114 +static int rc32434_poll(struct net_device *rx_data_dev, int *budget)
3115 +#else
3116 +static void rc32434_rx_tasklet(unsigned long rx_data_dev)
3117 +#endif
3118 +{
3119 + struct net_device *dev = (struct net_device *)rx_data_dev;
3120 + struct rc32434_local* lp = netdev_priv(dev);
3121 + volatile DMAD_t rd = &lp->rd_ring[lp->rx_next_done];
3122 + struct sk_buff *skb, *skb_new;
3123 + u8* pkt_buf;
3124 + u32 devcs, count, pkt_len, pktuncrc_len;
3125 + volatile u32 dmas;
3126 +#ifdef CONFIG_IDT_USE_NAPI
3127 + u32 received = 0;
3128 + int rx_work_limit = min(*budget,dev->quota);
3129 +#else
3130 + unsigned long flags;
3131 + spin_lock_irqsave(&lp->lock, flags);
3132 +#endif
3133 +
3134 + while ( (count = RC32434_RBSIZE - (u32)DMA_COUNT(rd->control)) != 0) {
3135 +#ifdef CONFIG_IDT_USE_NAPI
3136 + if(--rx_work_limit <0)
3137 + {
3138 + break;
3139 + }
3140 +#endif
3141 + /* init the var. used for the later operations within the while loop */
3142 + skb_new = NULL;
3143 + devcs = rd->devcs;
3144 + pkt_len = RCVPKT_LENGTH(devcs);
3145 + skb = lp->rx_skb[lp->rx_next_done];
3146 +
3147 + if (count < 64) {
3148 + lp->stats.rx_errors++;
3149 + lp->stats.rx_dropped++;
3150 + }
3151 + else if ((devcs & ( ETHRX_ld_m)) != ETHRX_ld_m) {
3152 + /* check that this is a whole packet */
3153 + /* WARNING: DMA_FD bit incorrectly set in Rc32434 (errata ref #077) */
3154 + lp->stats.rx_errors++;
3155 + lp->stats.rx_dropped++;
3156 + }
3157 + else if ( (devcs & ETHRX_rok_m) ) {
3158 +
3159 + {
3160 + /* must be the (first and) last descriptor then */
3161 + pkt_buf = (u8*)lp->rx_skb[lp->rx_next_done]->data;
3162 +
3163 + pktuncrc_len = pkt_len - 4;
3164 + /* invalidate the cache */
3165 + dma_cache_inv((unsigned long)pkt_buf, pktuncrc_len);
3166 +
3167 + /* Malloc up new buffer. */
3168 + skb_new = dev_alloc_skb(RC32434_RBSIZE + 2);
3169 +
3170 + if (skb_new != NULL){
3171 + /* Make room */
3172 + skb_put(skb, pktuncrc_len);
3173 +
3174 + skb->protocol = eth_type_trans(skb, dev);
3175 +
3176 + /* pass the packet to upper layers */
3177 +#ifdef CONFIG_IDT_USE_NAPI
3178 + netif_receive_skb(skb);
3179 +#else
3180 + netif_rx(skb);
3181 +#endif
3182 +
3183 + dev->last_rx = jiffies;
3184 + lp->stats.rx_packets++;
3185 + lp->stats.rx_bytes += pktuncrc_len;
3186 +
3187 + if (IS_RCV_MP(devcs))
3188 + lp->stats.multicast++;
3189 +
3190 + /* 16 bit align */
3191 + skb_reserve(skb_new, 2);
3192 +
3193 + skb_new->dev = dev;
3194 + lp->rx_skb[lp->rx_next_done] = skb_new;
3195 + }
3196 + else {
3197 + ERR("no memory, dropping rx packet.\n");
3198 + lp->stats.rx_errors++;
3199 + lp->stats.rx_dropped++;
3200 + }
3201 + }
3202 +
3203 + }
3204 + else {
3205 + /* This should only happen if we enable accepting broken packets */
3206 + lp->stats.rx_errors++;
3207 + lp->stats.rx_dropped++;
3208 +
3209 + /* add statistics counters */
3210 + if (IS_RCV_CRC_ERR(devcs)) {
3211 + DBG(2, "RX CRC error\n");
3212 + lp->stats.rx_crc_errors++;
3213 + }
3214 + else if (IS_RCV_LOR_ERR(devcs)) {
3215 + DBG(2, "RX LOR error\n");
3216 + lp->stats.rx_length_errors++;
3217 + }
3218 + else if (IS_RCV_LE_ERR(devcs)) {
3219 + DBG(2, "RX LE error\n");
3220 + lp->stats.rx_length_errors++;
3221 + }
3222 + else if (IS_RCV_OVR_ERR(devcs)) {
3223 + lp->stats.rx_over_errors++;
3224 + }
3225 + else if (IS_RCV_CV_ERR(devcs)) {
3226 + /* code violation */
3227 + DBG(2, "RX CV error\n");
3228 + lp->stats.rx_frame_errors++;
3229 + }
3230 + else if (IS_RCV_CES_ERR(devcs)) {
3231 + DBG(2, "RX Preamble error\n");
3232 + }
3233 + }
3234 +
3235 + rd->devcs = 0;
3236 +
3237 + /* restore descriptor's curr_addr */
3238 + if(skb_new)
3239 + rd->ca = CPHYSADDR(skb_new->data);
3240 + else
3241 + rd->ca = CPHYSADDR(skb->data);
3242 +
3243 + rd->control = DMA_COUNT(RC32434_RBSIZE) |DMAD_cod_m |DMAD_iod_m;
3244 + lp->rd_ring[(lp->rx_next_done-1)& RC32434_RDS_MASK].control &= ~(DMAD_cod_m);
3245 +
3246 + lp->rx_next_done = (lp->rx_next_done + 1) & RC32434_RDS_MASK;
3247 + rd = &lp->rd_ring[lp->rx_next_done];
3248 + rc32434_writel( ~DMAS_d_m, &lp->rx_dma_regs->dmas);
3249 + }
3250 +#ifdef CONFIG_IDT_USE_NAPI
3251 + dev->quota -= received;
3252 + *budget =- received;
3253 + if(rx_work_limit < 0)
3254 + goto not_done;
3255 +#endif
3256 +
3257 + dmas = rc32434_readl(&lp->rx_dma_regs->dmas);
3258 +
3259 + if(dmas & DMAS_h_m) {
3260 + rc32434_writel( ~(DMAS_h_m | DMAS_e_m), &lp->rx_dma_regs->dmas);
3261 +#ifdef RC32434_PROC_DEBUG
3262 + lp->dma_halt_cnt++;
3263 +#endif
3264 + rd->devcs = 0;
3265 + skb = lp->rx_skb[lp->rx_next_done];
3266 + rd->ca = CPHYSADDR(skb->data);
3267 + rc32434_chain_rx(lp,rd);
3268 + }
3269 +
3270 +#ifdef CONFIG_IDT_USE_NAPI
3271 + netif_rx_complete(dev);
3272 +#endif
3273 + /* Enable D H E bit in Rx DMA */
3274 + rc32434_writel(rc32434_readl(&lp->rx_dma_regs->dmasm) & ~(DMASM_d_m | DMASM_h_m |DMASM_e_m), &lp->rx_dma_regs->dmasm);
3275 +#ifdef CONFIG_IDT_USE_NAPI
3276 + return 0;
3277 + not_done:
3278 + return 1;
3279 +#else
3280 + spin_unlock_irqrestore(&lp->lock, flags);
3281 + return;
3282 +#endif
3283 +
3284 +
3285 +}
3286 +
3287 +
3288 +
3289 +/* Ethernet Tx DMA interrupt */
3290 +static irqreturn_t
3291 +rc32434_tx_dma_interrupt(int irq, void *dev_id, struct pt_regs * regs)
3292 +{
3293 + struct net_device *dev = (struct net_device *)dev_id;
3294 + struct rc32434_local *lp;
3295 + volatile u32 dmas,dmasm;
3296 + irqreturn_t retval;
3297 +
3298 + ASSERT(dev != NULL);
3299 +
3300 + lp = (struct rc32434_local *)dev->priv;
3301 +
3302 + spin_lock(&lp->lock);
3303 +
3304 + dmas = rc32434_readl(&lp->tx_dma_regs->dmas);
3305 +
3306 + if (dmas & (DMAS_f_m | DMAS_e_m)) {
3307 + dmasm = rc32434_readl(&lp->tx_dma_regs->dmasm);
3308 + /* Mask F E bit in Tx DMA */
3309 + rc32434_writel(dmasm | (DMASM_f_m | DMASM_e_m), &lp->tx_dma_regs->dmasm);
3310 +
3311 + tasklet_hi_schedule(lp->tx_tasklet);
3312 +
3313 + if(lp->tx_chain_status == filled && (rc32434_readl(&(lp->tx_dma_regs->dmandptr)) == 0)) {
3314 + rc32434_writel(CPHYSADDR(&lp->td_ring[lp->tx_chain_head]), &(lp->tx_dma_regs->dmandptr));
3315 + lp->tx_chain_status = empty;
3316 + lp->tx_chain_head = lp->tx_chain_tail;
3317 + dev->trans_start = jiffies;
3318 + }
3319 +
3320 + if (dmas & DMAS_e_m)
3321 + ERR(": DMA error\n");
3322 +
3323 + retval = IRQ_HANDLED;
3324 + }
3325 + else
3326 + retval = IRQ_NONE;
3327 +
3328 + spin_unlock(&lp->lock);
3329 +
3330 + return retval;
3331 +}
3332 +
3333 +
3334 +static void rc32434_tx_tasklet(unsigned long tx_data_dev)
3335 +{
3336 + struct net_device *dev = (struct net_device *)tx_data_dev;
3337 + struct rc32434_local* lp = (struct rc32434_local *)dev->priv;
3338 + volatile DMAD_t td = &lp->td_ring[lp->tx_next_done];
3339 + u32 devcs;
3340 + unsigned long flags;
3341 + volatile u32 dmas;
3342 +
3343 + spin_lock_irqsave(&lp->lock, flags);
3344 +
3345 + /* process all desc that are done */
3346 + while(IS_DMA_FINISHED(td->control)) {
3347 + if(lp->tx_full == 1) {
3348 + netif_wake_queue(dev);
3349 + lp->tx_full = 0;
3350 + }
3351 +
3352 + devcs = lp->td_ring[lp->tx_next_done].devcs;
3353 + if ((devcs & (ETHTX_fd_m | ETHTX_ld_m)) != (ETHTX_fd_m | ETHTX_ld_m)) {
3354 + lp->stats.tx_errors++;
3355 + lp->stats.tx_dropped++;
3356 +
3357 + /* should never happen */
3358 + DBG(1, __FUNCTION__ ": split tx ignored\n");
3359 + }
3360 + else if (IS_TX_TOK(devcs)) {
3361 + lp->stats.tx_packets++;
3362 + }
3363 + else {
3364 + lp->stats.tx_errors++;
3365 + lp->stats.tx_dropped++;
3366 +
3367 + /* underflow */
3368 + if (IS_TX_UND_ERR(devcs))
3369 + lp->stats.tx_fifo_errors++;
3370 +
3371 + /* oversized frame */
3372 + if (IS_TX_OF_ERR(devcs))
3373 + lp->stats.tx_aborted_errors++;
3374 +
3375 + /* excessive deferrals */
3376 + if (IS_TX_ED_ERR(devcs))
3377 + lp->stats.tx_carrier_errors++;
3378 +
3379 + /* collisions: medium busy */
3380 + if (IS_TX_EC_ERR(devcs))
3381 + lp->stats.collisions++;
3382 +
3383 + /* late collision */
3384 + if (IS_TX_LC_ERR(devcs))
3385 + lp->stats.tx_window_errors++;
3386 +
3387 + }
3388 +
3389 + /* We must always free the original skb */
3390 + if (lp->tx_skb[lp->tx_next_done] != NULL) {
3391 + dev_kfree_skb_any(lp->tx_skb[lp->tx_next_done]);
3392 + lp->tx_skb[lp->tx_next_done] = NULL;
3393 + }
3394 +
3395 + lp->td_ring[lp->tx_next_done].control = DMAD_iof_m;
3396 + lp->td_ring[lp->tx_next_done].devcs = ETHTX_fd_m | ETHTX_ld_m;
3397 + lp->td_ring[lp->tx_next_done].link = 0;
3398 + lp->td_ring[lp->tx_next_done].ca = 0;
3399 + lp->tx_count --;
3400 +
3401 + /* go on to next transmission */
3402 + lp->tx_next_done = (lp->tx_next_done + 1) & RC32434_TDS_MASK;
3403 + td = &lp->td_ring[lp->tx_next_done];
3404 +
3405 + }
3406 +
3407 + dmas = rc32434_readl(&lp->tx_dma_regs->dmas);
3408 + rc32434_writel( ~dmas, &lp->tx_dma_regs->dmas);
3409 +
3410 + /* Enable F E bit in Tx DMA */
3411 + rc32434_writel(rc32434_readl(&lp->tx_dma_regs->dmasm) & ~(DMASM_f_m | DMASM_e_m), &lp->tx_dma_regs->dmasm);
3412 + spin_unlock_irqrestore(&lp->lock, flags);
3413 +
3414 +}
3415 +
3416 +
3417 +static struct net_device_stats * rc32434_get_stats(struct net_device *dev)
3418 +{
3419 + struct rc32434_local *lp = (struct rc32434_local *)dev->priv;
3420 + return &lp->stats;
3421 +}
3422 +
3423 +
3424 +/*
3425 + * Set or clear the multicast filter for this adaptor.
3426 + */
3427 +static void rc32434_multicast_list(struct net_device *dev)
3428 +{
3429 + /* listen to broadcasts always and to treat */
3430 + /* IFF bits independantly */
3431 + struct rc32434_local *lp = (struct rc32434_local *)dev->priv;
3432 + unsigned long flags;
3433 + u32 recognise = ETHARC_ab_m; /* always accept broadcasts */
3434 +
3435 + if (dev->flags & IFF_PROMISC) /* set promiscuous mode */
3436 + recognise |= ETHARC_pro_m;
3437 +
3438 + if ((dev->flags & IFF_ALLMULTI) || (dev->mc_count > 15))
3439 + recognise |= ETHARC_am_m; /* all multicast & bcast */
3440 + else if (dev->mc_count > 0) {
3441 + DBG(2, __FUNCTION__ ": mc_count %d\n", dev->mc_count);
3442 + recognise |= ETHARC_am_m; /* for the time being */
3443 + }
3444 +
3445 + spin_lock_irqsave(&lp->lock, flags);
3446 + rc32434_writel(recognise, &lp->eth_regs->etharc);
3447 + spin_unlock_irqrestore(&lp->lock, flags);
3448 +}
3449 +
3450 +
3451 +static void rc32434_tx_timeout(struct net_device *dev)
3452 +{
3453 + struct rc32434_local *lp = (struct rc32434_local *)dev->priv;
3454 + unsigned long flags;
3455 +
3456 + spin_lock_irqsave(&lp->lock, flags);
3457 + rc32434_restart(dev);
3458 + spin_unlock_irqrestore(&lp->lock, flags);
3459 +
3460 +}
3461 +
3462 +
3463 +/*
3464 + * Initialize the RC32434 ethernet controller.
3465 + */
3466 +static int rc32434_init(struct net_device *dev)
3467 +{
3468 + struct rc32434_local *lp = (struct rc32434_local *)dev->priv;
3469 + int i, j;
3470 +
3471 + /* Disable DMA */
3472 + rc32434_abort_tx(dev);
3473 + rc32434_abort_rx(dev);
3474 +
3475 + /* reset ethernet logic */
3476 + rc32434_writel(0, &lp->eth_regs->ethintfc);
3477 + while((rc32434_readl(&lp->eth_regs->ethintfc) & ETHINTFC_rip_m))
3478 + dev->trans_start = jiffies;
3479 +
3480 + /* Enable Ethernet Interface */
3481 + rc32434_writel(ETHINTFC_en_m, &lp->eth_regs->ethintfc);
3482 +
3483 +#ifndef CONFIG_IDT_USE_NAPI
3484 + tasklet_disable(lp->rx_tasklet);
3485 +#endif
3486 + tasklet_disable(lp->tx_tasklet);
3487 +
3488 + /* Initialize the transmit Descriptors */
3489 + for (i = 0; i < RC32434_NUM_TDS; i++) {
3490 + lp->td_ring[i].control = DMAD_iof_m;
3491 + lp->td_ring[i].devcs = ETHTX_fd_m | ETHTX_ld_m;
3492 + lp->td_ring[i].ca = 0;
3493 + lp->td_ring[i].link = 0;
3494 + if (lp->tx_skb[i] != NULL) {
3495 + dev_kfree_skb_any(lp->tx_skb[i]);
3496 + lp->tx_skb[i] = NULL;
3497 + }
3498 + }
3499 + lp->tx_next_done = lp->tx_chain_head = lp->tx_chain_tail = lp->tx_full = lp->tx_count = 0;
3500 + lp-> tx_chain_status = empty;
3501 +
3502 + /*
3503 + * Initialize the receive descriptors so that they
3504 + * become a circular linked list, ie. let the last
3505 + * descriptor point to the first again.
3506 + */
3507 + for (i=0; i<RC32434_NUM_RDS; i++) {
3508 + struct sk_buff *skb = lp->rx_skb[i];
3509 +
3510 + if (lp->rx_skb[i] == NULL) {
3511 + skb = dev_alloc_skb(RC32434_RBSIZE + 2);
3512 + if (skb == NULL) {
3513 + ERR("No memory in the system\n");
3514 + for (j = 0; j < RC32434_NUM_RDS; j ++)
3515 + if (lp->rx_skb[j] != NULL)
3516 + dev_kfree_skb_any(lp->rx_skb[j]);
3517 +
3518 + return 1;
3519 + }
3520 + else {