finally move buildroot-ng to trunk
[openwrt.git] / target / linux / ar531x-2.4 / patches / 000-atheros-support.patch
1 diff -urN linux-mips/arch/mips/ar531x/ar531xdbg_io.c mips-linux-2.4.25/arch/mips/ar531x/ar531xdbg_io.c
2 --- linux-mips/arch/mips/ar531x/ar531xdbg_io.c  1970-01-01 01:00:00.000000000 +0100
3 +++ mips-linux-2.4.25/arch/mips/ar531x/ar531xdbg_io.c   2005-12-30 17:26:30.606883840 +0000
4 @@ -0,0 +1,234 @@
5 +/*
6 + * This file is subject to the terms and conditions of the GNU General Public
7 + * License.  See the file "COPYING" in the main directory of this archive
8 + * for more details.
9 + *
10 + * Copyright MontaVista Software Inc
11 + * Copyright © 2003 Atheros Communications, Inc.,  All Rights Reserved.
12 + */
13 +
14 +/*
15 + * Basic support for polled character input/output
16 + * using the AR531X's serial port.
17 + */
18 +
19 +#include <linux/config.h>
20 +#include <linux/init.h>
21 +#include <linux/delay.h>
22 +#include <linux/irq.h>
23 +#include <linux/interrupt.h>
24 +#include <linux/serial.h>
25 +#include <linux/types.h>
26 +#include <linux/string.h>
27 +
28 +#include <asm/reboot.h>
29 +#include <asm/io.h>
30 +#include <asm/time.h>
31 +#include <asm/pgtable.h>
32 +#include <asm/processor.h>
33 +#include <asm/reboot.h>
34 +#include <asm/system.h>
35 +#include <asm/serial.h>
36 +#include <asm/gdb-stub.h>
37 +
38 +#include "ar531xlnx.h"
39 +
40 +#if CONFIG_EARLY_PRINTK_HACK || CONFIG_KGDB
41 +/* base addr of uart and clock timing */
42 +#if CONFIG_AR5315
43 +#define         BASE                    AR5315_UART0 
44 +#else
45 +#define         BASE                    AR531X_UART0
46 +#endif
47 +
48 +/* distance in bytes between two serial registers */
49 +#define         REG_OFFSET              4
50 +
51 +/*
52 + * 0 - we need to do serial init
53 + * 1 - skip serial init
54 + */
55 +static int serialPortInitialized = 0;
56 +
57 +/*
58 + *  * the default baud rate *if* we do serial init
59 + *   */
60 +#define         BAUD_DEFAULT            UART16550_BAUD_9600
61 +
62 +/* === END OF CONFIG === */
63 +
64 +#define         UART16550_BAUD_2400             2400
65 +#define         UART16550_BAUD_4800             4800
66 +#define         UART16550_BAUD_9600             9600
67 +#define         UART16550_BAUD_19200            19200
68 +#define         UART16550_BAUD_38400            38400
69 +#define         UART16550_BAUD_57600            57600
70 +#define         UART16550_BAUD_115200           115200
71 +
72 +#define         UART16550_PARITY_NONE           0
73 +#define         UART16550_PARITY_ODD            0x08
74 +#define         UART16550_PARITY_EVEN           0x18
75 +#define         UART16550_PARITY_MARK           0x28
76 +#define         UART16550_PARITY_SPACE          0x38
77 +
78 +#define         UART16550_DATA_5BIT             0x0
79 +#define         UART16550_DATA_6BIT             0x1
80 +#define         UART16550_DATA_7BIT             0x2
81 +#define         UART16550_DATA_8BIT             0x3
82 +
83 +#define         UART16550_STOP_1BIT             0x0
84 +#define         UART16550_STOP_2BIT             0x4
85 +
86 +/* register offset */
87 +#define         OFS_RCV_BUFFER          (0*REG_OFFSET)
88 +#define         OFS_TRANS_HOLD          (0*REG_OFFSET)
89 +#define         OFS_SEND_BUFFER         (0*REG_OFFSET)
90 +#define         OFS_INTR_ENABLE         (1*REG_OFFSET)
91 +#define         OFS_INTR_ID             (2*REG_OFFSET)
92 +#define         OFS_DATA_FORMAT         (3*REG_OFFSET)
93 +#define         OFS_LINE_CONTROL        (3*REG_OFFSET)
94 +#define         OFS_MODEM_CONTROL       (4*REG_OFFSET)
95 +#define         OFS_RS232_OUTPUT        (4*REG_OFFSET)
96 +#define         OFS_LINE_STATUS         (5*REG_OFFSET)
97 +#define         OFS_MODEM_STATUS        (6*REG_OFFSET)
98 +#define         OFS_RS232_INPUT         (6*REG_OFFSET)
99 +#define         OFS_SCRATCH_PAD         (7*REG_OFFSET)
100 +
101 +#define         OFS_DIVISOR_LSB         (0*REG_OFFSET)
102 +#define         OFS_DIVISOR_MSB         (1*REG_OFFSET)
103 +
104 +
105 +/* memory-mapped read/write of the port */
106 +#define         UART16550_READ(y)    (*((volatile u8*)(BASE + y)))
107 +#define         UART16550_WRITE(y, z)  ((*((volatile u8*)(BASE + y))) = z)
108 +
109 +void
110 +debugPortInit(u32 baud, u8 data, u8 parity, u8 stop)
111 +{
112 +       /* Pull UART out of reset */
113 +#if CONFIG_AR5315
114 +       sysRegWrite(AR5315_RESET,
115 +               sysRegRead(AR5315_RESET) & ~(RESET_UART0));
116 +#else
117 +       sysRegWrite(AR531X_RESET,
118 +               sysRegRead(AR531X_RESET) & ~(AR531X_RESET_UART0));
119 +#endif
120 +
121 +       /* disable interrupts */
122 +        UART16550_WRITE(OFS_LINE_CONTROL, 0x0);
123 +       UART16550_WRITE(OFS_INTR_ENABLE, 0);
124 +
125 +       /* set up buad rate */
126 +       { 
127 +               u32 divisor;
128 +#if CONFIG_AR5315 
129 +               u32 uart_clock_rate = ar531x_apb_frequency();
130 +#else
131 +               u32 uart_clock_rate = ar531x_cpu_frequency() / 4;
132 +#endif
133 +               u32 base_baud = uart_clock_rate / 16;
134 +       
135 +               /* set DIAB bit */
136 +               UART16550_WRITE(OFS_LINE_CONTROL, 0x80);
137 +        
138 +               /* set divisor */
139 +               divisor = base_baud / baud;
140 +               UART16550_WRITE(OFS_DIVISOR_LSB, divisor & 0xff);
141 +               UART16550_WRITE(OFS_DIVISOR_MSB, (divisor & 0xff00)>>8);
142 +
143 +               /* clear DIAB bit */
144 +               UART16550_WRITE(OFS_LINE_CONTROL, 0x0);
145 +       }
146 +
147 +       /* set data format */
148 +       UART16550_WRITE(OFS_DATA_FORMAT, data | parity | stop);
149 +}
150 +
151 +u8
152 +getDebugChar(void)
153 +{
154 +        if (!serialPortInitialized) {
155 +                serialPortInitialized = 1;
156 +                debugPortInit(BAUD_DEFAULT,
157 +                              UART16550_DATA_8BIT,
158 +                              UART16550_PARITY_NONE, UART16550_STOP_1BIT);
159 +        }
160 +
161 +       while((UART16550_READ(OFS_LINE_STATUS) & 0x1) == 0);
162 +       return UART16550_READ(OFS_RCV_BUFFER);
163 +}
164 +
165 +#if CONFIG_KGDB
166 +/*
167 + * Peek at the most recently received character.
168 + * Don't wait for a new character to be received.
169 + */
170 +u8
171 +peekDebugChar(void)
172 +{
173 +       return UART16550_READ(OFS_RCV_BUFFER);
174 +}
175 +
176 +static int kgdbInitialized = 0;
177 +
178 +void
179 +kgdbInit(void)
180 +{
181 +#if CONFIG_AR5315
182 +    sysRegWrite(AR5315_WDC, WDC_IGNORE_EXPIRATION);
183 +#else
184 +    sysRegWrite(AR531X_WD_CTRL, AR531X_WD_CTRL_IGNORE_EXPIRATION);
185 +#endif
186 +
187 +    if (!kgdbInitialized) {
188 +        printk("Setting debug traps - please connect the remote debugger.\n");
189 +        set_debug_traps();
190 +        kgdbInitialized = 1;
191 +    }
192 +    breakpoint();
193 +}
194 +
195 +int
196 +kgdbEnabled(void)
197 +{
198 +    return kgdbInitialized;
199 +}
200 +
201 +#define DEBUG_CHAR '\001';
202 +
203 +int
204 +kgdbInterrupt(void)
205 +{
206 +    if (!kgdbInitialized) {
207 +        return 0;
208 +    }
209 +
210 +    /* 
211 +     * Try to avoid swallowing too much input: Only consume
212 +     * a character if nothing new has arrived.  Yes, there's
213 +     * still a small hole here, and we may lose an input
214 +     * character now and then.
215 +     */
216 +    if (UART16550_READ(OFS_LINE_STATUS) & 1) {
217 +        return 0;
218 +    } else {
219 +        return UART16550_READ(OFS_RCV_BUFFER) == DEBUG_CHAR;
220 +    }
221 +}
222 +#endif
223 +
224 +
225 +void
226 +putDebugChar(char byte)
227 +{
228 +        if (!serialPortInitialized) {
229 +                serialPortInitialized = 1;
230 +                debugPortInit(BAUD_DEFAULT,
231 +                              UART16550_DATA_8BIT,
232 +                              UART16550_PARITY_NONE, UART16550_STOP_1BIT);
233 +        }
234 +
235 +       while ((UART16550_READ(OFS_LINE_STATUS) &0x20) == 0);
236 +       UART16550_WRITE(OFS_SEND_BUFFER, byte);
237 + }
238 +#endif /* CONFIG_EARLY_PRINTK_HACK || CONFIG_KGDB */
239 diff -urN linux-mips/arch/mips/ar531x/ar531xgpio.c mips-linux-2.4.25/arch/mips/ar531x/ar531xgpio.c
240 --- linux-mips/arch/mips/ar531x/ar531xgpio.c    1970-01-01 01:00:00.000000000 +0100
241 +++ mips-linux-2.4.25/arch/mips/ar531x/ar531xgpio.c     2005-12-30 17:26:30.606883840 +0000
242 @@ -0,0 +1,147 @@
243 +/*
244 + * This file is subject to the terms and conditions of the GNU General Public
245 + * License.  See the file "COPYING" in the main directory of this archive
246 + * for more details.
247 + *
248 + * Copyright © 2003 Atheros Communications, Inc.,  All Rights Reserved.
249 + */
250 +
251 +/*
252 + * Support for GPIO -- General Purpose Input/Output Pins
253 + */
254 +
255 +#include <linux/config.h>
256 +#include <linux/kernel.h>
257 +#include <linux/signal.h>
258 +#include <linux/interrupt.h>
259 +#include <linux/irq.h>
260 +
261 +#include "ar531xlnx.h"
262 +
263 +/* GPIO Interrupt Support */
264 +
265 +/* Turn on the specified AR531X_GPIO_IRQ interrupt */
266 +static unsigned int
267 +ar531x_gpio_intr_startup(unsigned int irq)
268 +{
269 +       ar531x_gpio_intr_enable(irq);
270 +       return 0;
271 +}
272 +
273 +/* Turn off the specified AR531X_GPIO_IRQ interrupt */
274 +static void
275 +ar531x_gpio_intr_shutdown(unsigned int irq)
276 +{
277 +       ar531x_gpio_intr_disable(irq);
278 +}
279 +
280 +u32 gpioIntMask = 0;
281 +
282 +/* Enable the specified AR531X_GPIO_IRQ interrupt */
283 +void
284 +ar531x_gpio_intr_enable(unsigned int irq)
285 +{
286 +    u32 reg;
287 +    int gpio;
288 +
289 +#ifndef CONFIG_AR5315
290 +    gpio = irq - AR531X_GPIO_IRQ_BASE;
291 +    gpioIntMask |= gpio;
292 +
293 +    reg = sysRegRead(AR531X_GPIO_CR);
294 +    reg &= ~(GPIO_CR_M(gpio) | GPIO_CR_UART(gpio) | GPIO_CR_INT(gpio));
295 +    reg |= GPIO_CR_I(gpio);
296 +    reg |= GPIO_CR_INT(gpio);
297 +
298 +    sysRegWrite(AR531X_GPIO_CR, reg);
299 +    (void)sysRegRead(AR531X_GPIO_CR); /* flush to hardware */
300 +#endif
301 +}
302 +
303 +/* Disable the specified AR531X_GPIO_IRQ interrupt */
304 +void
305 +ar531x_gpio_intr_disable(unsigned int irq)
306 +{
307 +    u32 reg;
308 +    int gpio;
309 +
310 +#ifndef CONFIG_AR5315
311 +    gpio = irq - AR531X_GPIO_IRQ_BASE;
312 +    reg = sysRegRead(AR531X_GPIO_CR);
313 +    reg &= ~(GPIO_CR_M(gpio) | GPIO_CR_UART(gpio) | GPIO_CR_INT(gpio));
314 +    reg |= GPIO_CR_I(gpio);
315 +    /* No GPIO_CR_INT bit */
316 +
317 +    sysRegWrite(AR531X_GPIO_CR, reg);
318 +    (void)sysRegRead(AR531X_GPIO_CR); /* flush to hardware */
319 +
320 +    gpioIntMask &= ~gpio;
321 +#endif
322 +}
323 +
324 +static void
325 +ar531x_gpio_intr_ack(unsigned int irq)
326 +{
327 +       ar531x_gpio_intr_disable(irq);
328 +}
329 +
330 +static void
331 +ar531x_gpio_intr_end(unsigned int irq)
332 +{
333 +       if (!(irq_desc[irq].status & (IRQ_DISABLED | IRQ_INPROGRESS)))
334 +               ar531x_gpio_intr_enable(irq);
335 +}
336 +
337 +static void
338 +ar531x_gpio_intr_set_affinity(unsigned int irq, unsigned long mask)
339 +{
340 +       /* Only 1 CPU; ignore affinity request */
341 +}
342 +
343 +int ar531x_gpio_irq_base;
344 +
345 +struct hw_interrupt_type ar531x_gpio_intr_controller = {
346 +       "AR531X GPIO",
347 +       ar531x_gpio_intr_startup,
348 +       ar531x_gpio_intr_shutdown,
349 +       ar531x_gpio_intr_enable,
350 +       ar531x_gpio_intr_disable,
351 +       ar531x_gpio_intr_ack,
352 +       ar531x_gpio_intr_end,
353 +       ar531x_gpio_intr_set_affinity,
354 +};
355 +
356 +void
357 +ar531x_gpio_intr_init(int irq_base)
358 +{
359 +       int i;
360 +
361 +       for (i = irq_base; i < irq_base + AR531X_GPIO_IRQ_COUNT; i++) {
362 +               irq_desc[i].status = IRQ_DISABLED;
363 +               irq_desc[i].action = NULL;
364 +               irq_desc[i].depth = 1;
365 +               irq_desc[i].handler = &ar531x_gpio_intr_controller;
366 +       }
367 +
368 +       ar531x_gpio_irq_base = irq_base;
369 +}
370 +
371 +/* ARGSUSED */
372 +void
373 +spurious_gpio_handler(int cpl, void *dev_id, struct pt_regs *regs)
374 +{
375 +    u32 gpioDataIn;
376 +#if CONFIG_AR5315
377 +    gpioDataIn = sysRegRead(AR5315_GPIO_DI) & gpioIntMask;
378 +#else
379 +    gpioDataIn = sysRegRead(AR531X_GPIO_DI) & gpioIntMask;
380 +#endif
381 +
382 +    printk("spurious_gpio_handler: 0x%x di=0x%8.8x gpioIntMask=0x%8.8x\n",
383 +           cpl, gpioDataIn, gpioIntMask);
384 +}
385 +
386 +struct irqaction spurious_gpio =
387 +       {spurious_gpio_handler, SA_INTERRUPT, 0, "spurious_gpio",
388 +            NULL, NULL};
389 +
390 diff -urN linux-mips/arch/mips/ar531x/ar531x.h mips-linux-2.4.25/arch/mips/ar531x/ar531x.h
391 --- linux-mips/arch/mips/ar531x/ar531x.h        1970-01-01 01:00:00.000000000 +0100
392 +++ mips-linux-2.4.25/arch/mips/ar531x/ar531x.h 2005-12-30 17:26:30.605883992 +0000
393 @@ -0,0 +1,1018 @@
394 +/*
395 + * This file is subject to the terms and conditions of the GNU General Public
396 + * License.  See the file "COPYING" in the main directory of this archive
397 + * for more details.
398 + *
399 + * Copyright © 2003 Atheros Communications, Inc.,  All Rights Reserved.
400 + */
401 +
402 +#ifndef AR531X_H
403 +#define AR531X_H 1
404 +
405 +#ifndef CONFIG_AR5315
406 +
407 +#include <asm/addrspace.h>
408 +
409 +/* Address Map */
410 +#define AR531X_WLAN0            0x18000000
411 +#define AR531X_WLAN1            0x18500000
412 +#define AR531X_ENET0            0x18100000
413 +#define AR531X_ENET1            0x18200000
414 +#define AR531X_SDRAMCTL         0x18300000
415 +#define AR531X_FLASHCTL         0x18400000
416 +#define AR531X_APBBASE         0x1c000000
417 +#define AR531X_FLASH            0x1e000000
418 +#define AR531X_UART0            0xbc000003      /* UART MMR */
419 +
420 +/*
421 + * AR531X_NUM_ENET_MAC defines the number of ethernet MACs that
422 + * should be considered available.  The AR5312 supports 2 enet MACS,
423 + * even though many reference boards only actually use 1 of them
424 + * (i.e. Only MAC 0 is actually connected to an enet PHY or PHY switch.
425 + * The AR2312 supports 1 enet MAC.
426 + */
427 +#define AR531X_NUM_ENET_MAC             2
428 +
429 +/*
430 + * Need these defines to determine true number of ethernet MACs
431 + */
432 +#define AR5212_AR5312_REV2      0x0052          /* AR5312 WMAC (AP31) */
433 +#define AR5212_AR5312_REV7      0x0057          /* AR5312 WMAC (AP30-040) */
434 +#define AR5212_AR2313_REV8      0x0058          /* AR2313 WMAC (AP43-030) */
435 +#define AR531X_RADIO_MASK_OFF  0xc8
436 +#define AR531X_RADIO0_MASK     0x0003
437 +#define AR531X_RADIO1_MASK     0x000c
438 +#define AR531X_RADIO1_S        2 
439 +
440 +/*
441 + * AR531X_NUM_WMAC defines the number of Wireless MACs that\
442 + * should be considered available.
443 + */
444 +#define AR531X_NUM_WMAC                 2
445 +
446 +/* Reset/Timer Block Address Map */
447 +#define AR531X_RESETTMR                (AR531X_APBBASE  + 0x3000)
448 +#define AR531X_TIMER           (AR531X_RESETTMR + 0x0000) /* countdown timer */
449 +#define AR531X_WD_CTRL          (AR531X_RESETTMR + 0x0008) /* watchdog cntrl */
450 +#define AR531X_WD_TIMER         (AR531X_RESETTMR + 0x000c) /* watchdog timer */
451 +#define AR531X_ISR             (AR531X_RESETTMR + 0x0010) /* Intr Status Reg */
452 +#define AR531X_IMR             (AR531X_RESETTMR + 0x0014) /* Intr Mask Reg */
453 +#define AR531X_RESET           (AR531X_RESETTMR + 0x0020)
454 +#define AR5312_CLOCKCTL1       (AR531X_RESETTMR + 0x0064)
455 +#define AR5312_SCRATCH         (AR531X_RESETTMR + 0x006c)
456 +#define AR531X_PROCADDR                (AR531X_RESETTMR + 0x0070)
457 +#define AR531X_PROC1           (AR531X_RESETTMR + 0x0074)
458 +#define AR531X_DMAADDR         (AR531X_RESETTMR + 0x0078)
459 +#define AR531X_DMA1            (AR531X_RESETTMR + 0x007c)
460 +#define AR531X_ENABLE           (AR531X_RESETTMR + 0x0080) /* interface enb */
461 +#define AR531X_REV             (AR531X_RESETTMR + 0x0090) /* revision */
462 +
463 +/* AR531X_WD_CTRL register bit field definitions */
464 +#define AR531X_WD_CTRL_IGNORE_EXPIRATION 0x0000
465 +#define AR531X_WD_CTRL_NMI               0x0001
466 +#define AR531X_WD_CTRL_RESET             0x0002
467 +
468 +/* AR531X_ISR register bit field definitions */
469 +#define AR531X_ISR_NONE                0x0000
470 +#define AR531X_ISR_TIMER       0x0001
471 +#define AR531X_ISR_AHBPROC     0x0002
472 +#define AR531X_ISR_AHBDMA      0x0004
473 +#define AR531X_ISR_GPIO                0x0008
474 +#define AR531X_ISR_UART0       0x0010
475 +#define AR531X_ISR_UART0DMA    0x0020
476 +#define AR531X_ISR_WD          0x0040
477 +#define AR531X_ISR_LOCAL       0x0080
478 +
479 +/* AR531X_RESET register bit field definitions */
480 +#define AR531X_RESET_SYSTEM     0x00000001  /* cold reset full system */
481 +#define AR531X_RESET_PROC       0x00000002  /* cold reset MIPS core */
482 +#define AR531X_RESET_WLAN0      0x00000004  /* cold reset WLAN MAC and BB */
483 +#define AR531X_RESET_EPHY0      0x00000008  /* cold reset ENET0 phy */
484 +#define AR531X_RESET_EPHY1      0x00000010  /* cold reset ENET1 phy */
485 +#define AR531X_RESET_ENET0      0x00000020  /* cold reset ENET0 mac */
486 +#define AR531X_RESET_ENET1      0x00000040  /* cold reset ENET1 mac */
487 +#define AR531X_RESET_UART0      0x00000100  /* cold reset UART0 (high speed) */
488 +#define AR531X_RESET_WLAN1      0x00000200  /* cold reset WLAN MAC/BB */
489 +#define AR531X_RESET_APB        0x00000400  /* cold reset APB (ar5312) */
490 +#define AR531X_RESET_WARM_PROC  0x00001000  /* warm reset MIPS core */
491 +#define AR531X_RESET_WARM_WLAN0_MAC 0x00002000  /* warm reset WLAN0 MAC */
492 +#define AR531X_RESET_WARM_WLAN0_BB  0x00004000  /* warm reset WLAN0 BaseBand */
493 +#define AR531X_RESET_NMI        0x00010000  /* send an NMI to the processor */
494 +#define AR531X_RESET_WARM_WLAN1_MAC 0x00020000  /* warm reset WLAN1 mac */
495 +#define AR531X_RESET_WARM_WLAN1_BB  0x00040000  /* warm reset WLAN1 baseband */
496 +#define AR531X_RESET_LOCAL_BUS  0x00080000  /* reset local bus */
497 +#define AR531X_RESET_WDOG       0x00100000  /* last reset was a watchdog */
498 +
499 +#define AR531X_RESET_WMAC0_BITS \
500 +        AR531X_RESET_WLAN0 |\
501 +        AR531X_RESET_WARM_WLAN0_MAC |\
502 +        AR531X_RESET_WARM_WLAN0_BB
503 +
504 +#define AR531X_RESERT_WMAC1_BITS \
505 +        AR531X_RESET_WLAN1 |\
506 +        AR531X_RESET_WARM_WLAN1_MAC |\
507 +        AR531X_RESET_WARM_WLAN1_BB
508 +
509 +/* AR5312_CLOCKCTL1 register bit field definitions */
510 +#define AR5312_CLOCKCTL1_PREDIVIDE_MASK    0x00000030
511 +#define AR5312_CLOCKCTL1_PREDIVIDE_SHIFT            4
512 +#define AR5312_CLOCKCTL1_MULTIPLIER_MASK   0x00001f00
513 +#define AR5312_CLOCKCTL1_MULTIPLIER_SHIFT           8
514 +#define AR5312_CLOCKCTL1_DOUBLER_MASK      0x00010000
515 +
516 +/* Valid for AR5312 and AR2312 */
517 +#define AR5312_CLOCKCTL1_PREDIVIDE_MASK    0x00000030
518 +#define AR5312_CLOCKCTL1_PREDIVIDE_SHIFT            4
519 +#define AR5312_CLOCKCTL1_MULTIPLIER_MASK   0x00001f00
520 +#define AR5312_CLOCKCTL1_MULTIPLIER_SHIFT           8
521 +#define AR5312_CLOCKCTL1_DOUBLER_MASK      0x00010000
522 +
523 +/* Valid for AR2313 */
524 +#define AR2313_CLOCKCTL1_PREDIVIDE_MASK    0x00003000
525 +#define AR2313_CLOCKCTL1_PREDIVIDE_SHIFT           12
526 +#define AR2313_CLOCKCTL1_MULTIPLIER_MASK   0x001f0000
527 +#define AR2313_CLOCKCTL1_MULTIPLIER_SHIFT          16
528 +#define AR2313_CLOCKCTL1_DOUBLER_MASK      0x00000000
529 +
530 +
531 +/* AR531X_ENABLE register bit field definitions */
532 +#define AR531X_ENABLE_WLAN0              0x0001
533 +#define AR531X_ENABLE_ENET0              0x0002
534 +#define AR531X_ENABLE_ENET1              0x0004
535 +#define AR531X_ENABLE_UART_AND_WLAN1_PIO 0x0008   /* UART, and WLAN1 PIOs */
536 +#define AR531X_ENABLE_WLAN1_DMA          0x0010   /* WLAN1 DMAs */
537 +#define AR531X_ENABLE_WLAN1 \
538 +            (AR531X_ENABLE_UART_AND_WLAN1_PIO | AR531X_ENABLE_WLAN1_DMA)
539 +
540 +/* AR531X_REV register bit field definitions */
541 +#define AR531X_REV_WMAC_MAJ    0xf000
542 +#define AR531X_REV_WMAC_MAJ_S  12
543 +#define AR531X_REV_WMAC_MIN    0x0f00
544 +#define AR531X_REV_WMAC_MIN_S  8
545 +#define AR531X_REV_MAJ         0x00f0
546 +#define AR531X_REV_MAJ_S       4
547 +#define AR531X_REV_MIN         0x000f
548 +#define AR531X_REV_MIN_S       0
549 +#define AR531X_REV_CHIP        (REV_MAJ|REV_MIN)
550 +
551 +/* Major revision numbers, bits 7..4 of Revision ID register */
552 +#define AR531X_REV_MAJ_AR5312          0x4
553 +#define AR531X_REV_MAJ_AR2313          0x5
554 +
555 +/* Minor revision numbers, bits 3..0 of Revision ID register */
556 +#define AR5312_REV_MIN_DUAL     0x0     /* Dual WLAN version */
557 +#define AR5312_REV_MIN_SINGLE   0x1     /* Single WLAN version */
558 +
559 +/* AR531X_FLASHCTL register bit field definitions */
560 +#define FLASHCTL_IDCY   0x0000000f      /* Idle cycle turn around time */
561 +#define FLASHCTL_IDCY_S 0
562 +#define FLASHCTL_WST1   0x000003e0      /* Wait state 1 */
563 +#define FLASHCTL_WST1_S 5
564 +#define FLASHCTL_RBLE   0x00000400      /* Read byte lane enable */
565 +#define FLASHCTL_WST2   0x0000f800      /* Wait state 2 */
566 +#define FLASHCTL_WST2_S 11
567 +#define FLASHCTL_AC     0x00070000      /* Flash address check (added) */
568 +#define FLASHCTL_AC_S   16
569 +#define FLASHCTL_AC_128K 0x00000000
570 +#define FLASHCTL_AC_256K 0x00010000
571 +#define FLASHCTL_AC_512K 0x00020000
572 +#define FLASHCTL_AC_1M   0x00030000
573 +#define FLASHCTL_AC_2M   0x00040000
574 +#define FLASHCTL_AC_4M   0x00050000
575 +#define FLASHCTL_AC_8M   0x00060000
576 +#define FLASHCTL_AC_RES  0x00070000     /* 16MB is not supported */
577 +#define FLASHCTL_E      0x00080000      /* Flash bank enable (added) */
578 +#define FLASHCTL_BUSERR 0x01000000      /* Bus transfer error status flag */
579 +#define FLASHCTL_WPERR  0x02000000      /* Write protect error status flag */
580 +#define FLASHCTL_WP     0x04000000      /* Write protect */
581 +#define FLASHCTL_BM     0x08000000      /* Burst mode */
582 +#define FLASHCTL_MW     0x30000000      /* Memory width */
583 +#define FLASHCTL_MWx8   0x00000000      /* Memory width x8 */
584 +#define FLASHCTL_MWx16  0x10000000      /* Memory width x16 */
585 +#define FLASHCTL_MWx32  0x20000000      /* Memory width x32 (not supported) */
586 +#define FLASHCTL_ATNR   0x00000000      /* Access type == no retry */
587 +#define FLASHCTL_ATR    0x80000000      /* Access type == retry every */
588 +#define FLASHCTL_ATR4   0xc0000000      /* Access type == retry every 4 */
589 +
590 +/* ARM Flash Controller -- 3 flash banks with either x8 or x16 devices.  */
591 +#define AR531X_FLASHCTL0        (AR531X_FLASHCTL + 0x00)
592 +#define AR531X_FLASHCTL1        (AR531X_FLASHCTL + 0x04)
593 +#define AR531X_FLASHCTL2        (AR531X_FLASHCTL + 0x08)
594 +
595 +/* ARM SDRAM Controller -- just enough to determine memory size */
596 +#define AR531X_MEM_CFG1 (AR531X_SDRAMCTL + 0x04)
597 +#define MEM_CFG1_AC0    0x00000700      /* bank 0: SDRAM addr check (added) */
598 +#define MEM_CFG1_AC0_S  8
599 +#define MEM_CFG1_AC1    0x00007000      /* bank 1: SDRAM addr check (added) */
600 +#define MEM_CFG1_AC1_S  12
601 +
602 +/* GPIO Address Map */
603 +#define AR531X_GPIO         (AR531X_APBBASE  + 0x2000)
604 +#define AR531X_GPIO_DO      (AR531X_GPIO + 0x00)        /* output register */
605 +#define AR531X_GPIO_DI      (AR531X_GPIO + 0x04)        /* intput register */
606 +#define AR531X_GPIO_CR      (AR531X_GPIO + 0x08)        /* control register */
607 +
608 +/* GPIO Control Register bit field definitions */
609 +#define GPIO_CR_M(x)    (1 << (x))                      /* mask for i/o */
610 +#define GPIO_CR_O(x)    (0 << (x))                      /* mask for output */
611 +#define GPIO_CR_I(x)    (1 << (x))                      /* mask for input */
612 +#define GPIO_CR_INT(x)  (1 << ((x)+8))                  /* mask for interrupt */
613 +#define GPIO_CR_UART(x) (1 << ((x)+16))                 /* uart multiplex */
614 +
615 +
616 +typedef unsigned int AR531X_REG;
617 +
618 +#define sysRegRead(phys)       \
619 +       (*(volatile AR531X_REG *)PHYS_TO_K1(phys))
620 +
621 +#define sysRegWrite(phys, val) \
622 +       ((*(volatile AR531X_REG *)PHYS_TO_K1(phys)) = (val))
623 +
624 +
625 +/*
626 + * This is board-specific data that is stored in a "fixed" location in flash.
627 + * It is shared across operating systems, so it should not be changed lightly.
628 + * The main reason we need it is in order to extract the ethernet MAC
629 + * address(es).
630 + */
631 +struct ar531x_boarddata {
632 +    u32 magic;                       /* board data is valid */
633 +#define AR531X_BD_MAGIC 0x35333131   /* "5311", for all 531x platforms */
634 +    u16 cksum;                       /* checksum (starting with BD_REV 2) */
635 +    u16 rev;                         /* revision of this struct */
636 +#define BD_REV  4
637 +    char   boardName[64];            /* Name of board */
638 +    u16 major;                       /* Board major number */
639 +    u16 minor;                       /* Board minor number */
640 +    u32 config;                      /* Board configuration */
641 +#define BD_ENET0        0x00000001   /* ENET0 is stuffed */
642 +#define BD_ENET1        0x00000002   /* ENET1 is stuffed */
643 +#define BD_UART1        0x00000004   /* UART1 is stuffed */
644 +#define BD_UART0        0x00000008   /* UART0 is stuffed (dma) */
645 +#define BD_RSTFACTORY   0x00000010   /* Reset factory defaults stuffed */
646 +#define BD_SYSLED       0x00000020   /* System LED stuffed */
647 +#define BD_EXTUARTCLK   0x00000040   /* External UART clock */
648 +#define BD_CPUFREQ      0x00000080   /* cpu freq is valid in nvram */
649 +#define BD_SYSFREQ      0x00000100   /* sys freq is set in nvram */
650 +#define BD_WLAN0        0x00000200   /* Enable WLAN0 */
651 +#define BD_MEMCAP       0x00000400   /* CAP SDRAM @ memCap for testing */
652 +#define BD_DISWATCHDOG  0x00000800   /* disable system watchdog */
653 +#define BD_WLAN1        0x00001000   /* Enable WLAN1 (ar5212) */
654 +#define BD_ISCASPER     0x00002000   /* FLAG for AR2312 */
655 +#define BD_WLAN0_2G_EN  0x00004000   /* FLAG for radio0_2G */
656 +#define BD_WLAN0_5G_EN  0x00008000   /* FLAG for radio0_2G */
657 +#define BD_WLAN1_2G_EN  0x00020000   /* FLAG for radio0_2G */
658 +#define BD_WLAN1_5G_EN  0x00040000   /* FLAG for radio0_2G */
659 +    u16 resetConfigGpio;             /* Reset factory GPIO pin */
660 +    u16 sysLedGpio;                  /* System LED GPIO pin */
661 +
662 +    u32 cpuFreq;                     /* CPU core frequency in Hz */
663 +    u32 sysFreq;                     /* System frequency in Hz */
664 +    u32 cntFreq;                     /* Calculated C0_COUNT frequency */
665 +
666 +    u8  wlan0Mac[6];
667 +    u8  enet0Mac[6];
668 +    u8  enet1Mac[6];
669 +
670 +    u16 pciId;                       /* Pseudo PCIID for common code */
671 +    u16 memCap;                      /* cap bank1 in MB */
672 +
673 +    /* version 3 */
674 +    u8  wlan1Mac[6];                 /* (ar5212) */
675 +};
676 +
677 +#else
678 +
679 +/*
680 + * Address map
681 + */
682 +#define AR5315_SDRAM0           0x00000000      /* DRAM */
683 +#define AR5315_SPI_READ         0x08000000      /* SPI FLASH */
684 +#define AR5315_WLAN0            0xB0000000      /* Wireless MMR */
685 +#define AR5315_PCI              0xB0100000      /* PCI MMR */
686 +#define AR5315_SDRAMCTL         0xB0300000      /* SDRAM MMR */
687 +#define AR5315_LOCAL            0xB0400000      /* LOCAL BUS MMR */
688 +#define AR5315_ENET0            0xB0500000      /* ETHERNET MMR */
689 +#define AR5315_DSLBASE          0xB1000000      /* RESET CONTROL MMR */
690 +#define AR5315_UART0            0xB1100003      /* UART MMR */
691 +#define AR5315_SPI              0xB1300000      /* SPI FLASH MMR */
692 +#define AR5315_FLASHBT          0xBfc00000      /* ro boot alias to FLASH */
693 +#define AR5315_RAM1             0x40000000      /* ram alias */
694 +#define AR5315_PCIEXT           0x80000000      /* pci external */
695 +#define AR5315_RAM2             0xc0000000      /* ram alias */
696 +#define AR5315_RAM3             0xe0000000      /* ram alias */
697 +
698 +/*
699 + * Reset Register
700 + */
701 +#define AR5315_COLD_RESET       (AR5315_DSLBASE + 0x0000)
702 +
703 +/* Cold Reset */
704 +#define RESET_COLD_AHB              0x00000001
705 +#define RESET_COLD_APB              0x00000002
706 +#define RESET_COLD_CPU              0x00000004
707 +#define RESET_COLD_CPUWARM          0x00000008
708 +#define RESET_SYSTEM                (RESET_COLD_CPU | RESET_COLD_APB | RESET_COLD_AHB)      /* full system */
709 +
710 +/* Warm Reset */
711 +
712 +#define AR5315_RESET            (AR5315_DSLBASE + 0x0004)
713 +
714 +#define RESET_WARM_WLAN0_MAC        0x00000001      /* warm reset WLAN0 MAC */
715 +#define RESET_WARM_WLAN0_BB         0x00000002      /* warm reset WLAN0 BaseBand */
716 +#define RESET_MPEGTS_RSVD           0x00000004      /* warm reset MPEG-TS */
717 +#define RESET_PCIDMA                0x00000008      /* warm reset PCI ahb/dma */
718 +#define RESET_MEMCTL                0x00000010      /* warm reset memory controller */
719 +#define RESET_LOCAL                 0x00000020      /* warm reset local bus */
720 +#define RESET_I2C_RSVD              0x00000040      /* warm reset I2C bus */
721 +#define RESET_SPI                   0x00000080      /* warm reset SPI interface */
722 +#define RESET_UART0                 0x00000100      /* warm reset UART0 */
723 +#define RESET_IR_RSVD               0x00000200      /* warm reset IR interface */
724 +#define RESET_EPHY0                 0x00000400      /* cold reset ENET0 phy */
725 +#define RESET_ENET0                 0x00000800      /* cold reset ENET0 mac */
726 +
727 +/*
728 + * AHB master arbitration control
729 + */
730 +#define AR5315_AHB_ARB_CTL      (AR5315_DSLBASE + 0x0008)
731 +
732 +#define ARB_CPU                     0x00000001      /* CPU, default */
733 +#define ARB_WLAN                    0x00000002      /* WLAN */
734 +#define ARB_MPEGTS_RSVD             0x00000004      /* MPEG-TS */
735 +#define ARB_LOCAL                   0x00000008      /* LOCAL */
736 +#define ARB_PCI                     0x00000010      /* PCI */
737 +#define ARB_ETHERNET                0x00000020      /* Ethernet */
738 +#define ARB_RETRY                   0x00000100      /* retry policy, debug only */
739 +
740 +/*
741 + * Config Register
742 + */
743 +#define AR5315_ENDIAN_CTL       (AR5315_DSLBASE + 0x000c)
744 +
745 +#define CONFIG_AHB                  0x00000001      /* EC - AHB bridge endianess */
746 +#define CONFIG_WLAN                 0x00000002      /* WLAN byteswap */
747 +#define CONFIG_MPEGTS_RSVD          0x00000004      /* MPEG-TS byteswap */
748 +#define CONFIG_PCI                  0x00000008      /* PCI byteswap */
749 +#define CONFIG_MEMCTL               0x00000010      /* Memory controller endianess */
750 +#define CONFIG_LOCAL                0x00000020      /* Local bus byteswap */
751 +#define CONFIG_ETHERNET             0x00000040      /* Ethernet byteswap */
752 +
753 +#define CONFIG_MERGE                0x00000200      /* CPU write buffer merge */
754 +#define CONFIG_CPU                  0x00000400      /* CPU big endian */
755 +#define CONFIG_PCIAHB               0x00000800
756 +#define CONFIG_PCIAHB_BRIDGE        0x00001000
757 +#define CONFIG_SPI                  0x00008000      /* SPI byteswap */
758 +#define CONFIG_CPU_DRAM             0x00010000
759 +#define CONFIG_CPU_PCI              0x00020000
760 +#define CONFIG_CPU_MMR              0x00040000
761 +#define CONFIG_BIG                  0x00000400      
762 +
763 +
764 +/*
765 + * NMI control
766 + */
767 +#define AR5315_NMI_CTL          (AR5315_DSLBASE + 0x0010)
768 +
769 +#define NMI_EN  1
770 +
771 +/*
772 + * Revision Register - Initial value is 0x3010 (WMAC 3.0, AR531X 1.0).
773 + */
774 +#define AR5315_SREV             (AR5315_DSLBASE + 0x0014)
775 +
776 +#define REV_MAJ                     0x00f0
777 +#define REV_MAJ_S                   4
778 +#define REV_MIN                     0x000f
779 +#define REV_MIN_S                   0
780 +#define REV_CHIP                    (REV_MAJ|REV_MIN)
781 +
782 +/*
783 + * Interface Enable
784 + */
785 +#define AR5315_IF_CTL           (AR5315_DSLBASE + 0x0018)
786 +
787 +#define IF_MASK                     0x00000007
788 +#define IF_DISABLED                 0
789 +#define IF_PCI                      1
790 +#define IF_TS_LOCAL                 2
791 +#define IF_ALL                      3   /* only for emulation with separate pins */
792 +#define IF_LOCAL_HOST               0x00000008
793 +#define IF_PCI_HOST                 0x00000010
794 +#define IF_PCI_INTR                 0x00000020
795 +#define IF_PCI_CLK_MASK             0x00030000
796 +#define IF_PCI_CLK_INPUT            0 
797 +#define IF_PCI_CLK_OUTPUT_LOW       1
798 +#define IF_PCI_CLK_OUTPUT_CLK       2
799 +#define IF_PCI_CLK_OUTPUT_HIGH      3
800 +#define IF_PCI_CLK_SHIFT            16 
801
802 +                
803 +/* Major revision numbers, bits 7..4 of Revision ID register */
804 +#define REV_MAJ_AR5311              0x01
805 +#define REV_MAJ_AR5312              0x04
806 +#define REV_MAJ_AR5315              0x0B
807 +
808 +/*
809 + * APB Interrupt control
810 + */
811 +
812 +#define AR5315_ISR              (AR5315_DSLBASE + 0x0020)
813 +#define AR5315_IMR              (AR5315_DSLBASE + 0x0024)
814 +#define AR5315_GISR             (AR5315_DSLBASE + 0x0028)
815 +
816 +#define ISR_UART0                   0x0001           /* high speed UART */
817 +#define ISR_I2C_RSVD                0x0002           /* I2C bus */
818 +#define ISR_SPI                     0x0004           /* SPI bus */
819 +#define ISR_AHB                     0x0008           /* AHB error */
820 +#define ISR_APB                     0x0010           /* APB error */
821 +#define ISR_TIMER                   0x0020           /* timer */
822 +#define ISR_GPIO                    0x0040           /* GPIO */
823 +#define ISR_WD                      0x0080           /* watchdog */
824 +#define ISR_IR_RSVD                 0x0100           /* IR */
825 +                                
826 +#define IMR_UART0                   ISR_UART0
827 +#define IMR_I2C_RSVD                ISR_I2C_RSVD
828 +#define IMR_SPI                     ISR_SPI
829 +#define IMR_AHB                     ISR_AHB
830 +#define IMR_APB                     ISR_APB
831 +#define IMR_TIMER                   ISR_TIMER
832 +#define IMR_GPIO                    ISR_GPIO
833 +#define IMR_WD                      ISR_WD
834 +#define IMR_IR_RSVD                 ISR_IR_RSVD
835 +
836 +#define GISR_MISC                   0x0001
837 +#define GISR_WLAN0                  0x0002
838 +#define GISR_MPEGTS_RSVD            0x0004
839 +#define GISR_LOCALPCI               0x0008
840 +#define GISR_WMACPOLL               0x0010
841 +#define GISR_TIMER                  0x0020
842 +#define GISR_ETHERNET               0x0040
843 +
844 +/*
845 + * Interrupt routing from IO to the processor IP bits
846 + * Define our inter mask and level
847 + */
848 +#define AR5315_INTR_MISCIO      SR_IBIT3
849 +#define AR5315_INTR_WLAN0       SR_IBIT4
850 +#define AR5315_INTR_ENET0       SR_IBIT5
851 +#define AR5315_INTR_LOCALPCI    SR_IBIT6
852 +#define AR5315_INTR_WMACPOLL    SR_IBIT7
853 +#define AR5315_INTR_COMPARE     SR_IBIT8
854 +
855 +/*
856 + * Timers
857 + */
858 +#define AR5315_TIMER            (AR5315_DSLBASE + 0x0030)
859 +#define AR5315_RELOAD           (AR5315_DSLBASE + 0x0034)
860 +#define AR5315_WD               (AR5315_DSLBASE + 0x0038)
861 +#define AR5315_WDC              (AR5315_DSLBASE + 0x003c)
862 +
863 +#define WDC_RESET                   0x00000002               /* reset on watchdog */
864 +#define WDC_NMI                     0x00000001               /* NMI on watchdog */
865 +#define WDC_IGNORE_EXPIRATION       0x00000000
866 +
867 +/*
868 + * Interface Debug
869 + */
870 +#define AR531X_FLASHDBG             (AR531X_RESETTMR + 0x0040)
871 +#define AR531X_MIIDBG               (AR531X_RESETTMR + 0x0044)
872 +
873 +
874 +/*
875 + * CPU Performance Counters
876 + */
877 +#define AR5315_PERFCNT0         (AR5315_DSLBASE + 0x0048)
878 +#define AR5315_PERFCNT1         (AR5315_DSLBASE + 0x004c)
879 +
880 +#define PERF_DATAHIT                0x0001  /* Count Data Cache Hits */
881 +#define PERF_DATAMISS               0x0002  /* Count Data Cache Misses */
882 +#define PERF_INSTHIT                0x0004  /* Count Instruction Cache Hits */
883 +#define PERF_INSTMISS               0x0008  /* Count Instruction Cache Misses */
884 +#define PERF_ACTIVE                 0x0010  /* Count Active Processor Cycles */
885 +#define PERF_WBHIT                  0x0020  /* Count CPU Write Buffer Hits */
886 +#define PERF_WBMISS                 0x0040  /* Count CPU Write Buffer Misses */
887 +                                
888 +#define PERF_EB_ARDY                0x0001  /* Count EB_ARdy signal */
889 +#define PERF_EB_AVALID              0x0002  /* Count EB_AValid signal */
890 +#define PERF_EB_WDRDY               0x0004  /* Count EB_WDRdy signal */
891 +#define PERF_EB_RDVAL               0x0008  /* Count EB_RdVal signal */
892 +#define PERF_VRADDR                 0x0010  /* Count valid read address cycles */
893 +#define PERF_VWADDR                 0x0020  /* Count valid write address cycles */
894 +#define PERF_VWDATA                 0x0040  /* Count valid write data cycles */
895 +
896 +/*
897 + * AHB Error Reporting.
898 + */
899 +#define AR5315_AHB_ERR0         (AR5315_DSLBASE + 0x0050)  /* error  */
900 +#define AR5315_AHB_ERR1         (AR5315_DSLBASE + 0x0054)  /* haddr  */
901 +#define AR5315_AHB_ERR2         (AR5315_DSLBASE + 0x0058)  /* hwdata */
902 +#define AR5315_AHB_ERR3         (AR5315_DSLBASE + 0x005c)  /* hrdata */
903 +#define AR5315_AHB_ERR4         (AR5315_DSLBASE + 0x0060)  /* status */
904 +
905 +#define AHB_ERROR_DET               1   /* AHB Error has been detected,          */
906 +                                        /* write 1 to clear all bits in ERR0     */
907 +#define AHB_ERROR_OVR               2   /* AHB Error overflow has been detected  */
908 +#define AHB_ERROR_WDT               4   /* AHB Error due to wdt instead of hresp */
909 +
910 +#define PROCERR_HMAST               0x0000000f
911 +#define PROCERR_HMAST_DFLT          0
912 +#define PROCERR_HMAST_WMAC          1
913 +#define PROCERR_HMAST_ENET          2
914 +#define PROCERR_HMAST_PCIENDPT      3
915 +#define PROCERR_HMAST_LOCAL         4
916 +#define PROCERR_HMAST_CPU           5
917 +#define PROCERR_HMAST_PCITGT        6
918 +                                    
919 +#define PROCERR_HMAST_S             0
920 +#define PROCERR_HWRITE              0x00000010
921 +#define PROCERR_HSIZE               0x00000060
922 +#define PROCERR_HSIZE_S             5
923 +#define PROCERR_HTRANS              0x00000180
924 +#define PROCERR_HTRANS_S            7
925 +#define PROCERR_HBURST              0x00000e00
926 +#define PROCERR_HBURST_S            9
927 +
928 +
929 +
930 +/*
931 + * Clock Control
932 + */
933 +#define AR5315_PLLC_CTL         (AR5315_DSLBASE + 0x0064)
934 +#define AR5315_PLLV_CTL         (AR5315_DSLBASE + 0x0068)
935 +#define AR5315_CPUCLK           (AR5315_DSLBASE + 0x006c)
936 +#define AR5315_AMBACLK          (AR5315_DSLBASE + 0x0070)
937 +#define AR5315_SYNCCLK          (AR5315_DSLBASE + 0x0074)
938 +#define AR5315_DSL_SLEEP_CTL    (AR5315_DSLBASE + 0x0080)
939 +#define AR5315_DSL_SLEEP_DUR    (AR5315_DSLBASE + 0x0084)
940 +
941 +/* PLLc Control fields */
942 +#define PLLC_REF_DIV_M              0x00000003
943 +#define PLLC_REF_DIV_S              0
944 +#define PLLC_FDBACK_DIV_M           0x0000007C
945 +#define PLLC_FDBACK_DIV_S           2
946 +#define PLLC_ADD_FDBACK_DIV_M       0x00000080
947 +#define PLLC_ADD_FDBACK_DIV_S       7
948 +#define PLLC_CLKC_DIV_M             0x0001c000
949 +#define PLLC_CLKC_DIV_S             14
950 +#define PLLC_CLKM_DIV_M             0x00700000
951 +#define PLLC_CLKM_DIV_S             20
952 +
953 +/* CPU CLK Control fields */
954 +#define CPUCLK_CLK_SEL_M            0x00000003
955 +#define CPUCLK_CLK_SEL_S            0
956 +#define CPUCLK_CLK_DIV_M            0x0000000c
957 +#define CPUCLK_CLK_DIV_S            2
958 +
959 +/* AMBA CLK Control fields */
960 +#define AMBACLK_CLK_SEL_M           0x00000003
961 +#define AMBACLK_CLK_SEL_S           0
962 +#define AMBACLK_CLK_DIV_M           0x0000000c
963 +#define AMBACLK_CLK_DIV_S           2
964 +
965 +#if defined(COBRA_EMUL)
966 +#define AR5315_AMBA_CLOCK_RATE  20000000
967 +#define AR5315_CPU_CLOCK_RATE   40000000
968 +#else
969 +#if defined(DEFAULT_PLL)
970 +#define AR5315_AMBA_CLOCK_RATE  40000000
971 +#define AR5315_CPU_CLOCK_RATE   40000000
972 +#else
973 +#define AR5315_AMBA_CLOCK_RATE  92000000
974 +#define AR5315_CPU_CLOCK_RATE   184000000
975 +#endif /* ! DEFAULT_PLL */
976 +#endif /* ! COBRA_EMUL */
977 +
978 +#define AR5315_UART_CLOCK_RATE  AR5315_AMBA_CLOCK_RATE
979 +#define AR5315_SDRAM_CLOCK_RATE AR5315_AMBA_CLOCK_RATE
980 +
981 +/*
982 + * The UART computes baud rate as:
983 + *   baud = clock / (16 * divisor)
984 + * where divisor is specified as a High Byte (DLM) and a Low Byte (DLL).
985 + */
986 +#define DESIRED_BAUD_RATE           38400
987 +
988 +/*
989 + * The WATCHDOG value is computed as
990 + *  10 seconds * AR531X_WATCHDOG_CLOCK_RATE
991 + */
992 +#define DESIRED_WATCHDOG_SECONDS    10
993 +#define AR531X_WATCHDOG_TIME \
994 +        (DESIRED_WATCHDOG_SECONDS * AR531X_WATCHDOG_CLOCK_RATE)
995 +
996 +
997 +#define CLOCKCTL_UART0  0x0010  /* enable UART0 external clock */
998 +
999 +
1000 + /*
1001 + * Applicable "PCICFG" bits for WLAN(s).  Assoc status and LED mode.
1002 + */
1003 +#define AR531X_PCICFG               (AR531X_RESETTMR + 0x00b0)
1004 +#define ASSOC_STATUS_M              0x00000003
1005 +#define ASSOC_STATUS_NONE           0
1006 +#define ASSOC_STATUS_PENDING        1   
1007 +#define ASSOC_STATUS_ASSOCIATED     2
1008 +#define LED_MODE_M                  0x0000001c
1009 +#define LED_BLINK_THRESHOLD_M       0x000000e0
1010 +#define LED_SLOW_BLINK_MODE         0x00000100
1011 +
1012 +/*
1013 + * GPIO
1014 + */
1015 +
1016 +#define AR5315_GPIO_DI          (AR5315_DSLBASE + 0x0088)
1017 +#define AR5315_GPIO_DO          (AR5315_DSLBASE + 0x0090)
1018 +#define AR5315_GPIO_CR          (AR5315_DSLBASE + 0x0098)
1019 +#define AR5315_GPIO_INT         (AR5315_DSLBASE + 0x00a0)
1020 +
1021 +#define GPIO_CR_M(x)                (1 << (x))                  /* mask for i/o */
1022 +#define GPIO_CR_O(x)                (1 << (x))                  /* output */
1023 +#define GPIO_CR_I(x)                (0 << (x))                  /* input */
1024 +
1025 +#define GPIO_INT(x,Y)               ((x) << (8 * (Y)))          /* interrupt enable */
1026 +#define GPIO_INT_M(Y)               ((0x3F) << (8 * (Y)))       /* mask for int */
1027 +#define GPIO_INT_LVL(x,Y)           ((x) << (8 * (Y) + 6))      /* interrupt level */
1028 +#define GPIO_INT_LVL_M(Y)           ((0x3) << (8 * (Y) + 6))    /* mask for int level */
1029 +
1030 +#define AR5315_RESET_GPIO       5
1031 +#define AR5315_NUM_GPIO         22
1032 +
1033 +    
1034 +/* 
1035 + *  PCI Clock Control
1036 + */     
1037
1038 +#define AR5315_PCICLK           (AR5315_DSLBASE + 0x00a4)
1039 +
1040 +#define PCICLK_INPUT_M              0x3
1041 +#define PCICLK_INPUT_S              0
1042 +                         
1043 +#define PCICLK_PLLC_CLKM            0
1044 +#define PCICLK_PLLC_CLKM1           1
1045 +#define PCICLK_PLLC_CLKC            2
1046 +#define PCICLK_REF_CLK              3 
1047 +
1048 +#define PCICLK_DIV_M                0xc
1049 +#define PCICLK_DIV_S                2
1050 +                         
1051 +#define PCICLK_IN_FREQ              0
1052 +#define PCICLK_IN_FREQ_DIV_6        1
1053 +#define PCICLK_IN_FREQ_DIV_8        2
1054 +#define PCICLK_IN_FREQ_DIV_10       3 
1055 +
1056 +/*
1057 + * Observation Control Register
1058 + */
1059 +#define AR5315_OCR              (AR5315_DSLBASE + 0x00b0)
1060 +#define OCR_GPIO0_IRIN              0x0040
1061 +#define OCR_GPIO1_IROUT             0x0080
1062 +#define OCR_GPIO3_RXCLR             0x0200
1063 +
1064 +/* 
1065 + *  General Clock Control
1066 + */     
1067
1068 +#define AR5315_MISCCLK          (AR5315_DSLBASE + 0x00b4)
1069 +#define MISCCLK_PLLBYPASS_EN        0x00000001
1070 +#define MISCCLK_PROCREFCLK          0x00000002
1071 +
1072 +/*
1073 + * SDRAM Controller
1074 + *   - No read or write buffers are included.
1075 + */
1076 +#define AR5315_MEM_CFG          (AR5315_SDRAMCTL + 0x00)
1077 +#define AR5315_MEM_CTRL         (AR5315_SDRAMCTL + 0x0c)
1078 +#define AR5315_MEM_REF          (AR5315_SDRAMCTL + 0x10)
1079 +
1080 +#define SDRAM_DATA_WIDTH_M          0x00006000
1081 +#define SDRAM_DATA_WIDTH_S          13
1082 +
1083 +#define SDRAM_COL_WIDTH_M           0x00001E00
1084 +#define SDRAM_COL_WIDTH_S           9
1085 +
1086 +#define SDRAM_ROW_WIDTH_M           0x000001E0
1087 +#define SDRAM_ROW_WIDTH_S           5
1088 +
1089 +#define SDRAM_BANKADDR_BITS_M       0x00000018
1090 +#define SDRAM_BANKADDR_BITS_S       3
1091 +
1092 +
1093 +/*
1094 + * SDRAM Memory Refresh (MEM_REF) value is computed as:
1095 + * MEMCTL_SREFR = (Tr * hclk_freq) / R
1096 + * where Tr is max. time of refresh of any single row
1097 + * R is number of rows in the DRAM
1098 + * For most 133MHz SDRAM parts, Tr=64ms, R=4096 or 8192
1099 + */
1100 +#if defined(COBRA_EMUL)
1101 +#define AR5315_SDRAM_MEMORY_REFRESH_VALUE  0x96
1102 +#else 
1103 +#if defined(DEFAULT_PLL)
1104 +#define AR5315_SDRAM_MEMORY_REFRESH_VALUE  0x200
1105 +#else
1106 +#define AR5315_SDRAM_MEMORY_REFRESH_VALUE  0x61a
1107 +#endif /* ! DEFAULT_PLL */
1108 +#endif 
1109 +
1110 +#if defined(AR5315)
1111 +
1112 +#define AR5315_SDRAM_DDR_SDRAM      0   /* Not DDR SDRAM */
1113 +#define AR5315_SDRAM_DATA_WIDTH     16  /* bits */   
1114 +#define AR5315_SDRAM_COL_WIDTH      8
1115 +#define AR5315_SDRAM_ROW_WIDTH      12
1116 +
1117 +#else
1118 +
1119 +#define AR5315_SDRAM_DDR_SDRAM      0   /* Not DDR SDRAM */
1120 +#define AR5315_SDRAM_DATA_WIDTH     16
1121 +#define AR5315_SDRAM_COL_WIDTH      8
1122 +#define AR5315_SDRAM_ROW_WIDTH      12
1123 +
1124 +#endif /* ! AR5315 */
1125 +
1126 +/*
1127 + * SPI Flash Interface Registers
1128 + */
1129 +
1130 +#define AR5315_SPI_CTL      (AR5315_SPI + 0x00)
1131 +#define AR5315_SPI_OPCODE   (AR5315_SPI + 0x04)
1132 +#define AR5315_SPI_DATA     (AR5315_SPI + 0x08)
1133 +
1134 +#define SPI_CTL_START           0x00000100
1135 +#define SPI_CTL_BUSY            0x00010000
1136 +#define SPI_CTL_TXCNT_MASK      0x0000000f
1137 +#define SPI_CTL_RXCNT_MASK      0x000000f0
1138 +#define SPI_CTL_TX_RX_CNT_MASK  0x000000ff
1139 +#define SPI_CTL_SIZE_MASK       0x00060000
1140 +
1141 +#define SPI_CTL_CLK_SEL_MASK    0x03000000
1142 +#define SPI_OPCODE_MASK         0x000000ff
1143 +
1144 +/* 
1145 + * PCI-MAC Configuration registers 
1146 + */
1147 +#define PCI_MAC_RC              (AR5315_PCI + 0x4000) 
1148 +#define PCI_MAC_SCR             (AR5315_PCI + 0x4004)
1149 +#define PCI_MAC_INTPEND         (AR5315_PCI + 0x4008)
1150 +#define PCI_MAC_SFR             (AR5315_PCI + 0x400C)
1151 +#define PCI_MAC_PCICFG          (AR5315_PCI + 0x4010)
1152 +#define PCI_MAC_SREV            (AR5315_PCI + 0x4020)
1153 +
1154 +#define PCI_MAC_RC_MAC          0x00000001
1155 +#define PCI_MAC_RC_BB           0x00000002
1156 +
1157 +#define PCI_MAC_SCR_SLMODE_M    0x00030000
1158 +#define PCI_MAC_SCR_SLMODE_S    16        
1159 +#define PCI_MAC_SCR_SLM_FWAKE   0         
1160 +#define PCI_MAC_SCR_SLM_FSLEEP  1         
1161 +#define PCI_MAC_SCR_SLM_NORMAL  2         
1162 +
1163 +#define PCI_MAC_SFR_SLEEP       0x00000001
1164 +
1165 +#define PCI_MAC_PCICFG_SPWR_DN  0x00010000
1166 +
1167
1168 +
1169 +
1170 +/*
1171 + * PCI Bus Interface Registers
1172 + */
1173 +#define AR5315_PCI_1MS_REG      (AR5315_PCI + 0x0008)
1174 +#define AR5315_PCI_1MS_MASK     0x3FFFF         /* # of AHB clk cycles in 1ms */
1175 +
1176 +#define AR5315_PCI_MISC_CONFIG  (AR5315_PCI + 0x000c)
1177 +#define AR5315_PCIMISC_TXD_EN   0x00000001      /* Enable TXD for fragments */
1178 +#define AR5315_PCIMISC_CFG_SEL  0x00000002      /* mem or config cycles */
1179 +#define AR5315_PCIMISC_GIG_MASK 0x0000000C      /* bits 31-30 for pci req */
1180 +#define AR5315_PCIMISC_RST_MODE 0x00000030
1181 +#define AR5315_PCIRST_INPUT     0x00000000      /* 4:5=0 rst is input */
1182 +#define AR5315_PCIRST_LOW       0x00000010      /* 4:5=1 rst to GND */
1183 +#define AR5315_PCIRST_HIGH      0x00000020      /* 4:5=2 rst to VDD */
1184 +#define AR5315_PCIGRANT_EN      0x00000000      /* 6:7=0 early grant en */
1185 +#define AR5315_PCIGRANT_FRAME   0x00000040      /* 6:7=1 grant waits 4 frame */
1186 +#define AR5315_PCIGRANT_IDLE    0x00000080      /* 6:7=2 grant waits 4 idle */
1187 +#define AR5315_PCIGRANT_GAP     0x00000000      /* 6:7=2 grant waits 4 idle */
1188 +#define AR5315_PCICACHE_DIS     0x00001000      /* PCI external access cache disable */
1189 +
1190 +#define AR5315_PCI_OUT_TSTAMP   (AR5315_PCI + 0x0010)
1191 +
1192 +#define AR5315_PCI_UNCACHE_CFG  (AR5315_PCI + 0x0014)
1193 +
1194 +#define AR5315_PCI_IN_EN        (AR5315_PCI + 0x0100)
1195 +#define AR5315_PCI_IN_EN0       0x01            /* Enable chain 0 */
1196 +#define AR5315_PCI_IN_EN1       0x02            /* Enable chain 1 */
1197 +#define AR5315_PCI_IN_EN2       0x04            /* Enable chain 2 */
1198 +#define AR5315_PCI_IN_EN3       0x08            /* Enable chain 3 */
1199 +
1200 +#define AR5315_PCI_IN_DIS       (AR5315_PCI + 0x0104)
1201 +#define AR5315_PCI_IN_DIS0      0x01            /* Disable chain 0 */
1202 +#define AR5315_PCI_IN_DIS1      0x02            /* Disable chain 1 */
1203 +#define AR5315_PCI_IN_DIS2      0x04            /* Disable chain 2 */
1204 +#define AR5315_PCI_IN_DIS3      0x08            /* Disable chain 3 */
1205 +
1206 +#define AR5315_PCI_IN_PTR       (AR5315_PCI + 0x0200)
1207 +
1208 +#define AR5315_PCI_OUT_EN       (AR5315_PCI + 0x0400)
1209 +#define AR5315_PCI_OUT_EN0      0x01            /* Enable chain 0 */
1210 +
1211 +#define AR5315_PCI_OUT_DIS      (AR5315_PCI + 0x0404)
1212 +#define AR5315_PCI_OUT_DIS0     0x01            /* Disable chain 0 */
1213 +
1214 +#define AR5315_PCI_OUT_PTR      (AR5315_PCI + 0x0408)
1215 +
1216 +#define AR5315_PCI_INT_STATUS   (AR5315_PCI + 0x0500)   /* write one to clr */
1217 +#define AR5315_PCI_TXINT        0x00000001      /* Desc In Completed */
1218 +#define AR5315_PCI_TXOK         0x00000002      /* Desc In OK */
1219 +#define AR5315_PCI_TXERR        0x00000004      /* Desc In ERR */
1220 +#define AR5315_PCI_TXEOL        0x00000008      /* Desc In End-of-List */
1221 +#define AR5315_PCI_RXINT        0x00000010      /* Desc Out Completed */
1222 +#define AR5315_PCI_RXOK         0x00000020      /* Desc Out OK */
1223 +#define AR5315_PCI_RXERR        0x00000040      /* Desc Out ERR */
1224 +#define AR5315_PCI_RXEOL        0x00000080      /* Desc Out EOL */
1225 +#define AR5315_PCI_TXOOD        0x00000200      /* Desc In Out-of-Desc */
1226 +#define AR5315_PCI_MASK         0x0000FFFF      /* Desc Mask */
1227 +#define AR5315_PCI_EXT_INT      0x02000000      
1228 +#define AR5315_PCI_ABORT_INT    0x04000000      
1229 +
1230 +#define AR5315_PCI_INT_MASK     (AR5315_PCI + 0x0504)   /* same as INT_STATUS */
1231 +
1232 +#define AR5315_PCI_INTEN_REG    (AR5315_PCI + 0x0508)
1233 +#define AR5315_PCI_INT_DISABLE  0x00            /* disable pci interrupts */
1234 +#define AR5315_PCI_INT_ENABLE   0x01            /* enable pci interrupts */
1235 +
1236 +#define AR5315_PCI_HOST_IN_EN   (AR5315_PCI + 0x0800)
1237 +#define AR5315_PCI_HOST_IN_DIS  (AR5315_PCI + 0x0804)
1238 +#define AR5315_PCI_HOST_IN_PTR  (AR5315_PCI + 0x0810)
1239 +#define AR5315_PCI_HOST_OUT_EN  (AR5315_PCI + 0x0900)
1240 +#define AR5315_PCI_HOST_OUT_DIS (AR5315_PCI + 0x0904)
1241 +#define AR5315_PCI_HOST_OUT_PTR (AR5315_PCI + 0x0908)
1242 +
1243 +
1244 +/*
1245 + * Local Bus Interface Registers
1246 + */
1247 +#define AR5315_LB_CONFIG        (AR5315_LOCAL + 0x0000)
1248 +#define AR5315_LBCONF_OE        0x00000001      /* =1 OE is low-true */
1249 +#define AR5315_LBCONF_CS0       0x00000002      /* =1 first CS is low-true */
1250 +#define AR5315_LBCONF_CS1       0x00000004      /* =1 2nd CS is low-true */
1251 +#define AR5315_LBCONF_RDY       0x00000008      /* =1 RDY is low-true */
1252 +#define AR5315_LBCONF_WE        0x00000010      /* =1 Write En is low-true */
1253 +#define AR5315_LBCONF_WAIT      0x00000020      /* =1 WAIT is low-true */
1254 +#define AR5315_LBCONF_ADS       0x00000040      /* =1 Adr Strobe is low-true */
1255 +#define AR5315_LBCONF_MOT       0x00000080      /* =0 Intel, =1 Motorola */
1256 +#define AR5315_LBCONF_8CS       0x00000100      /* =1 8 bits CS, 0= 16bits */
1257 +#define AR5315_LBCONF_8DS       0x00000200      /* =1 8 bits Data S, 0=16bits */
1258 +#define AR5315_LBCONF_ADS_EN    0x00000400      /* =1 Enable ADS */
1259 +#define AR5315_LBCONF_ADR_OE    0x00000800      /* =1 Adr cap on OE, WE or DS */
1260 +#define AR5315_LBCONF_ADDT_MUX  0x00001000      /* =1 Adr and Data share bus */
1261 +#define AR5315_LBCONF_DATA_OE   0x00002000      /* =1 Data cap on OE, WE, DS */
1262 +#define AR5315_LBCONF_16DATA    0x00004000      /* =1 Data is 16 bits wide */
1263 +#define AR5315_LBCONF_SWAPDT    0x00008000      /* =1 Byte swap data */
1264 +#define AR5315_LBCONF_SYNC      0x00010000      /* =1 Bus synchronous to clk */
1265 +#define AR5315_LBCONF_INT       0x00020000      /* =1 Intr is low true */
1266 +#define AR5315_LBCONF_INT_CTR0  0x00000000      /* GND high-Z, Vdd is high-Z */
1267 +#define AR5315_LBCONF_INT_CTR1  0x00040000      /* GND drive, Vdd is high-Z */
1268 +#define AR5315_LBCONF_INT_CTR2  0x00080000      /* GND high-Z, Vdd drive */
1269 +#define AR5315_LBCONF_INT_CTR3  0x000C0000      /* GND drive, Vdd drive */
1270 +#define AR5315_LBCONF_RDY_WAIT  0x00100000      /* =1 RDY is negative of WAIT */
1271 +#define AR5315_LBCONF_INT_PULSE 0x00200000      /* =1 Interrupt is a pulse */
1272 +#define AR5315_LBCONF_ENABLE    0x00400000      /* =1 Falcon respond to LB */
1273 +
1274 +#define AR5315_LB_CLKSEL        (AR5315_LOCAL + 0x0004)
1275 +#define AR5315_LBCLK_EXT        0x0001          /* use external clk for lb */
1276 +
1277 +#define AR5315_LB_1MS           (AR5315_LOCAL + 0x0008)
1278 +#define AR5315_LB1MS_MASK       0x3FFFF         /* # of AHB clk cycles in 1ms */
1279 +
1280 +#define AR5315_LB_MISCCFG       (AR5315_LOCAL + 0x000C)
1281 +#define AR5315_LBM_TXD_EN       0x00000001      /* Enable TXD for fragments */
1282 +#define AR5315_LBM_RX_INTEN     0x00000002      /* Enable LB ints on RX ready */
1283 +#define AR5315_LBM_MBOXWR_INTEN 0x00000004      /* Enable LB ints on mbox wr */
1284 +#define AR5315_LBM_MBOXRD_INTEN 0x00000008      /* Enable LB ints on mbox rd */
1285 +#define AR5315_LMB_DESCSWAP_EN  0x00000010      /* Byte swap desc enable */
1286 +#define AR5315_LBM_TIMEOUT_MASK 0x00FFFF80
1287 +#define AR5315_LBM_TIMEOUT_SHFT 7
1288 +#define AR5315_LBM_PORTMUX      0x07000000
1289 +
1290 +
1291 +#define AR5315_LB_RXTSOFF       (AR5315_LOCAL + 0x0010)
1292 +
1293 +#define AR5315_LB_TX_CHAIN_EN   (AR5315_LOCAL + 0x0100)
1294 +#define AR5315_LB_TXEN_0        0x01
1295 +#define AR5315_LB_TXEN_1        0x02
1296 +#define AR5315_LB_TXEN_2        0x04
1297 +#define AR5315_LB_TXEN_3        0x08
1298 +
1299 +#define AR5315_LB_TX_CHAIN_DIS  (AR5315_LOCAL + 0x0104)
1300 +#define AR5315_LB_TX_DESC_PTR   (AR5315_LOCAL + 0x0200)
1301 +
1302 +#define AR5315_LB_RX_CHAIN_EN   (AR5315_LOCAL + 0x0400)
1303 +#define AR5315_LB_RXEN          0x01
1304 +
1305 +#define AR5315_LB_RX_CHAIN_DIS  (AR5315_LOCAL + 0x0404)
1306 +#define AR5315_LB_RX_DESC_PTR   (AR5315_LOCAL + 0x0408)
1307 +
1308 +#define AR5315_LB_INT_STATUS    (AR5315_LOCAL + 0x0500)
1309 +#define AR5315_INT_TX_DESC      0x0001
1310 +#define AR5315_INT_TX_OK        0x0002
1311 +#define AR5315_INT_TX_ERR       0x0004
1312 +#define AR5315_INT_TX_EOF       0x0008
1313 +#define AR5315_INT_RX_DESC      0x0010
1314 +#define AR5315_INT_RX_OK        0x0020
1315 +#define AR5315_INT_RX_ERR       0x0040
1316 +#define AR5315_INT_RX_EOF       0x0080
1317 +#define AR5315_INT_TX_TRUNC     0x0100
1318 +#define AR5315_INT_TX_STARVE    0x0200
1319 +#define AR5315_INT_LB_TIMEOUT   0x0400
1320 +#define AR5315_INT_LB_ERR       0x0800
1321 +#define AR5315_INT_MBOX_WR      0x1000
1322 +#define AR5315_INT_MBOX_RD      0x2000
1323 +
1324 +/* Bit definitions for INT MASK are the same as INT_STATUS */
1325 +#define AR5315_LB_INT_MASK      (AR5315_LOCAL + 0x0504)
1326 +
1327 +#define AR5315_LB_INT_EN        (AR5315_LOCAL + 0x0508)
1328 +#define AR5315_LB_MBOX          (AR5315_LOCAL + 0x0600)
1329 +
1330 +
1331 +
1332 +/*
1333 + * IR Interface Registers
1334 + */
1335 +#define AR5315_IR_PKTDATA                   (AR5315_IR + 0x0000)
1336 +
1337 +#define AR5315_IR_PKTLEN                    (AR5315_IR + 0x07fc) /* 0 - 63 */
1338 +
1339 +#define AR5315_IR_CONTROL                   (AR5315_IR + 0x0800)
1340 +#define AR5315_IRCTL_TX                     0x00000000  /* use as tranmitter */
1341 +#define AR5315_IRCTL_RX                     0x00000001  /* use as receiver   */
1342 +#define AR5315_IRCTL_SAMPLECLK_MASK         0x00003ffe  /* Sample clk divisor mask */
1343 +#define AR5315_IRCTL_SAMPLECLK_SHFT                  1
1344 +#define AR5315_IRCTL_OUTPUTCLK_MASK         0x03ffc000  /* Output clk divisor mask */
1345 +#define AR5315_IRCTL_OUTPUTCLK_SHFT                 14
1346 +
1347 +#define AR5315_IR_STATUS                    (AR5315_IR + 0x0804)
1348 +#define AR5315_IRSTS_RX                     0x00000001  /* receive in progress */
1349 +#define AR5315_IRSTS_TX                     0x00000002  /* transmit in progress */
1350 +
1351 +#define AR5315_IR_CONFIG                    (AR5315_IR + 0x0808)
1352 +#define AR5315_IRCFG_INVIN                  0x00000001  /* invert input polarity */
1353 +#define AR5315_IRCFG_INVOUT                 0x00000002  /* invert output polarity */
1354 +#define AR5315_IRCFG_SEQ_START_WIN_SEL      0x00000004  /* 1 => 28, 0 => 7 */
1355 +#define AR5315_IRCFG_SEQ_START_THRESH       0x000000f0  /*  */
1356 +#define AR5315_IRCFG_SEQ_END_UNIT_SEL       0x00000100  /*  */
1357 +#define AR5315_IRCFG_SEQ_END_UNIT_THRESH    0x00007e00  /*  */
1358 +#define AR5315_IRCFG_SEQ_END_WIN_SEL        0x00008000  /*  */
1359 +#define AR5315_IRCFG_SEQ_END_WIN_THRESH     0x001f0000  /*  */
1360 +#define AR5315_IRCFG_NUM_BACKOFF_WORDS      0x01e00000  /*  */
1361 +
1362 +/*
1363 + * PCI memory constants: Memory area 1 and 2 are the same size -
1364 + * (twice the PCI_TLB_PAGE_SIZE). The definition of
1365 + * CPU_TO_PCI_MEM_SIZE is coupled with the TLB setup routine
1366 + * sysLib.c/sysTlbInit(), in that it assumes that 2 pages of size
1367 + * PCI_TLB_PAGE_SIZE are set up in the TLB for each PCI memory space.
1368 + */
1369
1370 +#define CPU_TO_PCI_MEM_BASE1    0xE0000000
1371 +#define CPU_TO_PCI_MEM_SIZE1    (2*PCI_TLB_PAGE_SIZE)
1372
1373 +
1374 +/* TLB attributes for PCI transactions */
1375 +
1376 +#define PCI_MMU_PAGEMASK        0x00003FFF
1377 +#define MMU_PAGE_UNCACHED       0x00000010
1378 +#define MMU_PAGE_DIRTY          0x00000004
1379 +#define MMU_PAGE_VALID          0x00000002
1380 +#define MMU_PAGE_GLOBAL         0x00000001
1381 +#define PCI_MMU_PAGEATTRIB      (MMU_PAGE_UNCACHED|MMU_PAGE_DIRTY|\
1382 +                                 MMU_PAGE_VALID|MMU_PAGE_GLOBAL)
1383 +#define PCI_MEMORY_SPACE1_VIRT  0xE0000000      /* Used for non-prefet  mem   */
1384 +#define PCI_MEMORY_SPACE1_PHYS  0x80000000
1385 +#define PCI_TLB_PAGE_SIZE       0x01000000
1386 +#define TLB_HI_MASK             0xFFFFE000
1387 +#define TLB_LO_MASK             0x3FFFFFFF
1388 +#define PAGEMASK_SHIFT          11
1389 +#define TLB_LO_SHIFT            6
1390 +
1391 +#define PCI_MAX_LATENCY         0xFFF           /* Max PCI latency            */
1392 +
1393 +#define HOST_PCI_DEV_ID         3
1394 +#define HOST_PCI_MBAR0          0x10000000
1395 +#define HOST_PCI_MBAR1          0x20000000
1396 +#define HOST_PCI_MBAR2          0x30000000
1397 +
1398 +#define HOST_PCI_SDRAM_BASEADDR HOST_PCI_MBAR1
1399 +#define PCI_DEVICE_MEM_SPACE    0x800000
1400 +
1401 +
1402 +typedef unsigned int AR531X_REG;
1403 +
1404 +#define sysRegRead(phys)       \
1405 +       (*(volatile AR531X_REG *)PHYS_TO_K1(phys))
1406 +
1407 +#define sysRegWrite(phys, val) \
1408 +       ((*(volatile AR531X_REG *)PHYS_TO_K1(phys)) = (val))
1409 +#endif
1410 +
1411 +#endif
1412 diff -urN linux-mips/arch/mips/ar531x/ar531xintr.S mips-linux-2.4.25/arch/mips/ar531x/ar531xintr.S
1413 --- linux-mips/arch/mips/ar531x/ar531xintr.S    1970-01-01 01:00:00.000000000 +0100
1414 +++ mips-linux-2.4.25/arch/mips/ar531x/ar531xintr.S     2005-12-30 17:26:31.000823952 +0000
1415 @@ -0,0 +1,30 @@
1416 +/*
1417 + * This file is subject to the terms and conditions of the GNU General Public
1418 + * License.  See the file "COPYING" in the main directory of this archive
1419 + * for more details.
1420 + *
1421 + * Copyright © 2003 Atheros Communications, Inc.,  All Rights Reserved.
1422 + */
1423 +
1424 +#include <asm/asm.h>
1425 +#include <asm/mipsregs.h>
1426 +#include <asm/regdef.h>
1427 +#include <asm/stackframe.h>
1428 +
1429 +/*
1430 + * Glue code to save registers and get us to the interrupt dispatcher
1431 + */
1432 +       .text
1433 +       .set    noat
1434 +       .align  5
1435 +NESTED(ar531x_interrupt_receive, PT_SIZE, sp)
1436 +       SAVE_ALL
1437 +       CLI
1438 +       .set    at
1439 +
1440 +       move    a0, sp
1441 +       jal     ar531x_irq_dispatch
1442 +
1443 +       j       ret_from_irq
1444 +
1445 +       END(ar531x_interrupt_receive)
1446 diff -urN linux-mips/arch/mips/ar531x/ar531xirq.c mips-linux-2.4.25/arch/mips/ar531x/ar531xirq.c
1447 --- linux-mips/arch/mips/ar531x/ar531xirq.c     1970-01-01 01:00:00.000000000 +0100
1448 +++ mips-linux-2.4.25/arch/mips/ar531x/ar531xirq.c      2005-12-30 17:26:31.000823952 +0000
1449 @@ -0,0 +1,442 @@
1450 +/*
1451 + * This file is subject to the terms and conditions of the GNU General Public
1452 + * License.  See the file "COPYING" in the main directory of this archive
1453 + * for more details.
1454 + *
1455 + * Copyright © 2003 Atheros Communications, Inc.,  All Rights Reserved.
1456 + */
1457 +
1458 +/*
1459 + * Interrupt support for AR531X WiSOC.
1460 + */
1461 +
1462 +#include <linux/config.h>
1463 +#include <linux/init.h>
1464 +#include <linux/kernel_stat.h>
1465 +#include <linux/signal.h>
1466 +#include <linux/sched.h>
1467 +#include <linux/interrupt.h>
1468 +#include <linux/slab.h>
1469 +#include <linux/random.h>
1470 +#include <linux/pm.h>
1471 +#include <linux/delay.h>
1472 +#include <linux/reboot.h>
1473 +
1474 +#include <asm/irq.h>
1475 +#include <asm/mipsregs.h>
1476 +#include <asm/gdb-stub.h>
1477 +
1478 +#include "ar531xlnx.h"
1479 +#include <asm/irq_cpu.h>
1480 +
1481 +extern int setup_irq(unsigned int irq, struct irqaction *irqaction);
1482 +
1483 +static void ar531x_misc_intr_enable(unsigned int irq);
1484 +static void ar531x_misc_intr_disable(unsigned int irq);
1485 +
1486 +/* Turn on the specified AR531X_MISC_IRQ interrupt */
1487 +static unsigned int
1488 +ar531x_misc_intr_startup(unsigned int irq)
1489 +{
1490 +       ar531x_misc_intr_enable(irq);
1491 +       return 0;
1492 +}
1493 +
1494 +/* Turn off the specified AR531X_MISC_IRQ interrupt */
1495 +static void
1496 +ar531x_misc_intr_shutdown(unsigned int irq)
1497 +{
1498 +       ar531x_misc_intr_disable(irq);
1499 +}
1500 +
1501 +/* Enable the specified AR531X_MISC_IRQ interrupt */
1502 +static void
1503 +ar531x_misc_intr_enable(unsigned int irq)
1504 +{
1505 +       unsigned int imr;
1506 +
1507 +#if CONFIG_AR5315
1508 +       imr = sysRegRead(AR5315_IMR);
1509 +        switch(irq)
1510 +        {
1511 +           case AR531X_MISC_IRQ_TIMER:
1512 +             imr |= IMR_TIMER;
1513 +            break;
1514 +
1515 +          case AR531X_MISC_IRQ_AHB_PROC:
1516 +             imr |= IMR_AHB;
1517 +            break;
1518 +
1519 +           case AR531X_MISC_IRQ_AHB_DMA:
1520 +             imr |= 0/* ?? */;
1521 +            break;
1522 +            /*
1523 +          case AR531X_ISR_GPIO:
1524 +             imr |= IMR_GPIO;
1525 +             break;
1526 +             */
1527 +
1528 +          case AR531X_MISC_IRQ_UART0:
1529 +             imr |= IMR_UART0;
1530 +             break;
1531 +
1532 +
1533 +           case        AR531X_MISC_IRQ_WATCHDOG:
1534 +             imr |= IMR_WD;
1535 +             break;
1536 +
1537 +          case AR531X_MISC_IRQ_LOCAL:
1538 +             imr |= 0/* ?? */;
1539 +             break;
1540 +
1541 +        }
1542 +       sysRegWrite(AR5315_IMR, imr);
1543 +       imr=sysRegRead(AR5315_IMR); /* flush write buffer */
1544 +        //printk("enable Interrupt irq 0x%x imr 0x%x \n",irq,imr);
1545 +
1546 +#else
1547 +       imr = sysRegRead(AR531X_IMR);
1548 +       imr |= (1 << (irq - AR531X_MISC_IRQ_BASE - 1));
1549 +       sysRegWrite(AR531X_IMR, imr);
1550 +       sysRegRead(AR531X_IMR); /* flush write buffer */
1551 +#endif
1552 +}
1553 +
1554 +/* Disable the specified AR531X_MISC_IRQ interrupt */
1555 +static void
1556 +ar531x_misc_intr_disable(unsigned int irq)
1557 +{
1558 +       unsigned int imr;
1559 +
1560 +#if CONFIG_AR5315
1561 +       imr = sysRegRead(AR5315_IMR);
1562 +        switch(irq)
1563 +        {
1564 +           case AR531X_MISC_IRQ_TIMER:
1565 +             imr &= (~IMR_TIMER);
1566 +            break;
1567 +
1568 +          case AR531X_MISC_IRQ_AHB_PROC:
1569 +             imr &= (~IMR_AHB);
1570 +            break;
1571 +
1572 +           case AR531X_MISC_IRQ_AHB_DMA:
1573 +             imr &= 0/* ?? */;
1574 +            break;
1575 +            /*
1576 +          case AR531X_ISR_GPIO:
1577 +             imr &= ~IMR_GPIO;
1578 +             break;
1579 +             */
1580 +
1581 +          case AR531X_MISC_IRQ_UART0:
1582 +             imr &= (~IMR_UART0);
1583 +             break;
1584 +
1585 +           case        AR531X_MISC_IRQ_WATCHDOG:
1586 +             imr &= (~IMR_WD);
1587 +             break;
1588 +
1589 +          case AR531X_MISC_IRQ_LOCAL:
1590 +             imr &= ~0/* ?? */;
1591 +             break;
1592 +
1593 +        }
1594 +       sysRegWrite(AR5315_IMR, imr);
1595 +       sysRegRead(AR5315_IMR); /* flush write buffer */
1596 +#else
1597 +       imr = sysRegRead(AR531X_IMR);
1598 +       imr &= ~(1 << (irq - AR531X_MISC_IRQ_BASE - 1));
1599 +       sysRegWrite(AR531X_IMR, imr);
1600 +       sysRegRead(AR531X_IMR); /* flush write buffer */
1601 +#endif
1602 +}
1603 +
1604 +static void
1605 +ar531x_misc_intr_ack(unsigned int irq)
1606 +{
1607 +       ar531x_misc_intr_disable(irq);
1608 +}
1609 +
1610 +static void
1611 +ar531x_misc_intr_end(unsigned int irq)
1612 +{
1613 +       if (!(irq_desc[irq].status & (IRQ_DISABLED | IRQ_INPROGRESS)))
1614 +               ar531x_misc_intr_enable(irq);
1615 +}
1616 +
1617 +static void
1618 +ar531x_misc_intr_set_affinity(unsigned int irq, unsigned long mask)
1619 +{
1620 +       /* Only 1 CPU; ignore affinity request */
1621 +}
1622 +
1623 +struct hw_interrupt_type ar531x_misc_intr_controller = {
1624 +       "AR531X MISC",
1625 +       ar531x_misc_intr_startup,
1626 +       ar531x_misc_intr_shutdown,
1627 +       ar531x_misc_intr_enable,
1628 +       ar531x_misc_intr_disable,
1629 +       ar531x_misc_intr_ack,
1630 +       ar531x_misc_intr_end,
1631 +       ar531x_misc_intr_set_affinity,
1632 +};
1633 +
1634 +int ar531x_misc_irq_base;
1635 +
1636 +/*
1637 + * Determine interrupt source among interrupts that use IP6
1638 + */
1639 +void
1640 +ar531x_misc_intr_init(int irq_base)
1641 +{
1642 +       int i;
1643 +
1644 +       for (i = irq_base; i < irq_base + AR531X_MISC_IRQ_COUNT; i++) {
1645 +               irq_desc[i].status = IRQ_DISABLED;
1646 +               irq_desc[i].action = NULL;
1647 +               irq_desc[i].depth = 1;
1648 +               irq_desc[i].handler = &ar531x_misc_intr_controller;
1649 +       }
1650 +
1651 +       ar531x_misc_irq_base = irq_base;
1652 +}
1653 +
1654 +/* ARGSUSED */
1655 +void
1656 +spurious_irq_handler(int cpl, void *dev_id, struct pt_regs *regs)
1657 +{
1658 +    /* 
1659 +    printk("spurious_irq_handler: %d  cause=0x%8.8x  status=0x%8.8x\n",
1660 +           cpl, cause_intrs, status_intrs); 
1661 +    */
1662 +}
1663 +
1664 +/* ARGSUSED */
1665 +void
1666 +spurious_misc_handler(int cpl, void *dev_id, struct pt_regs *regs)
1667 +{
1668 +    /*
1669 +    printk("spurious_misc_handler: 0x%x isr=0x%8.8x imr=0x%8.8x\n",
1670 +           cpl, ar531x_isr, ar531x_imr);
1671 +    */
1672 +}
1673 +
1674 +void
1675 +ar531x_timer_handler(int cpl, void *dev_id, struct pt_regs *regs)
1676 +{
1677 +#if CONFIG_AR5315
1678 +       (void)sysRegRead(AR5315_TIMER); /* clear interrupt */
1679 +#else
1680 +       (void)sysRegRead(AR531X_TIMER); /* clear interrupt */
1681 +#endif
1682 +}
1683 +
1684 +void
1685 +ar531x_ahb_proc_handler(int cpl, void *dev_id, struct pt_regs *regs)
1686 +{
1687 +    u32 procAddr;
1688 +    u32 proc1;
1689 +    u32 dmaAddr;
1690 +    u32 dma1;
1691 +#if CONFIG_AR5315
1692 +    sysRegWrite(AR5315_AHB_ERR0,AHB_ERROR_DET);
1693 +    sysRegRead(AR5315_AHB_ERR1);
1694 +#else
1695 +    proc1 = sysRegRead(AR531X_PROC1);
1696 +    procAddr = sysRegRead(AR531X_PROCADDR); /* clears error state */
1697 +    dma1 = sysRegRead(AR531X_DMA1);
1698 +    dmaAddr = sysRegRead(AR531X_DMAADDR);   /* clears error state */
1699 +#endif
1700 +
1701 +    printk("AHB interrupt: PROCADDR=0x%8.8x  PROC1=0x%8.8x  DMAADDR=0x%8.8x  DMA1=0x%8.8x\n",
1702 +        procAddr, proc1, dmaAddr, dma1);
1703 +        
1704 +    machine_restart("AHB error"); /* Catastrophic failure */
1705 +}
1706 +
1707 +static struct irqaction cascade  =
1708 +       {no_action, SA_INTERRUPT, 0, "cascade",
1709 +            NULL, NULL};
1710 +
1711 +static struct irqaction spurious_irq =
1712 +       {spurious_irq_handler, SA_INTERRUPT, 0, "spurious_irq",
1713 +            NULL, NULL};
1714 +
1715 +static struct irqaction spurious_misc =
1716 +       {spurious_misc_handler, SA_INTERRUPT, 0, "spurious_misc",
1717 +            NULL, NULL};
1718 +
1719 +static struct irqaction ar531x_timer_interrupt =
1720 +       {ar531x_timer_handler, SA_INTERRUPT, 0, "ar531x_timer_interrupt",
1721 +            NULL, NULL};
1722 +
1723 +static struct irqaction ar531x_ahb_proc_interrupt =
1724 +       {ar531x_ahb_proc_handler, SA_INTERRUPT, 0, "ar531x_ahb_proc_interrupt",
1725 +            NULL, NULL};
1726 +
1727 +extern asmlinkage void ar531x_interrupt_receive(void);
1728 +
1729 +/*
1730 + * Called when an interrupt is received, this function
1731 + * determines exactly which interrupt it was, and it
1732 + * invokes the appropriate handler.
1733 + *
1734 + * Implicitly, we also define interrupt priority by
1735 + * choosing which to dispatch first.
1736 + */
1737 +extern void dump_uart(void *);
1738 +
1739 +#if CONFIG_AR5315
1740 +
1741 +void
1742 +ar531x_irq_dispatch(struct pt_regs *regs)
1743 +{
1744 +       int cause_intrs = regs->cp0_cause;
1745 +       int status_intrs = regs->cp0_status;
1746 +       int pending = cause_intrs & status_intrs;
1747 +
1748 +       if (pending & CAUSEF_IP3) {
1749 +               do_IRQ(AR531X_IRQ_WLAN0_INTRS, regs);
1750 +       }               
1751 +       else if (pending & CAUSEF_IP4) {
1752 +               do_IRQ(AR531X_IRQ_ENET0_INTRS, regs);
1753 +       }
1754 +       else if (pending & CAUSEF_IP2) {
1755 +               AR531X_REG ar531x_isr = sysRegRead(AR5315_ISR);
1756 +               AR531X_REG ar531x_imr = sysRegRead(AR5315_IMR);
1757 +               unsigned int ar531x_misc_intrs = ar531x_isr & ar531x_imr;
1758 +
1759 +               if (ar531x_misc_intrs & ISR_TIMER)
1760 +                                         do_IRQ(AR531X_MISC_IRQ_TIMER, regs);
1761 +               else if (ar531x_misc_intrs & ISR_AHB)
1762 +                                         do_IRQ(AR531X_MISC_IRQ_AHB_PROC, regs);
1763 +               else if (ar531x_misc_intrs & ISR_GPIO)
1764 +                {
1765 +                    int i;
1766 +                    u32 gpioIntPending;
1767 +
1768 +                    gpioIntPending = sysRegRead(AR5315_GPIO_DI) & gpioIntMask;
1769 +                    for (i=0; i<AR531X_GPIO_IRQ_COUNT; i++) {
1770 +                        if (gpioIntPending & (1 << i))
1771 +                                             do_IRQ(AR531X_GPIO_IRQ(i), regs);
1772 +                    }
1773 +                }
1774 +               else if (ar531x_misc_intrs & ISR_UART0) {
1775 +                               do_IRQ(AR531X_MISC_IRQ_UART0, regs);
1776 +#if CONFIG_KGDB
1777 +                        if (kgdbInterrupt()) {
1778 +                                if (!user_mode(regs))
1779 +                                   set_async_breakpoint((unsigned long *)&regs->cp0_epc);
1780 +                        }
1781 +#endif         /* CONFIG_KGDB */
1782 +                }
1783 +               else if (ar531x_misc_intrs & ISR_WD)
1784 +                       do_IRQ(AR531X_MISC_IRQ_WATCHDOG, regs);
1785 +               else
1786 +                       do_IRQ(AR531X_MISC_IRQ_NONE, regs);
1787 +       } else if (pending & CAUSEF_IP7) {
1788 +               do_IRQ(AR531X_IRQ_CPU_CLOCK, regs);
1789 +        }
1790 +       else {
1791 +               do_IRQ(AR531X_IRQ_NONE, regs);
1792 +        }
1793 +}
1794 +
1795 +#else
1796 +
1797 +void
1798 +ar531x_irq_dispatch(struct pt_regs *regs)
1799 +{
1800 +       int cause_intrs = regs->cp0_cause;
1801 +       int status_intrs = regs->cp0_status;
1802 +       int pending = cause_intrs & status_intrs;
1803 +
1804 +       if (pending & CAUSEF_IP2) {
1805 +               do_IRQ(AR531X_IRQ_WLAN0_INTRS, regs);
1806 +       }               
1807 +       else if (pending & CAUSEF_IP3) {
1808 +               do_IRQ(AR531X_IRQ_ENET0_INTRS, regs);
1809 +       }
1810 +       else if (pending & CAUSEF_IP4) {
1811 +               do_IRQ(AR531X_IRQ_ENET1_INTRS, regs);
1812 +       }
1813 +       else if (pending & CAUSEF_IP5) {
1814 +               do_IRQ(AR531X_IRQ_WLAN1_INTRS, regs);
1815 +       }
1816 +       else if (pending & CAUSEF_IP6) {
1817 +               AR531X_REG ar531x_isr = sysRegRead(AR531X_ISR);
1818 +               AR531X_REG ar531x_imr = sysRegRead(AR531X_IMR);
1819 +               unsigned int ar531x_misc_intrs = ar531x_isr & ar531x_imr;
1820 +
1821 +               if (ar531x_misc_intrs & AR531X_ISR_TIMER)
1822 +                       do_IRQ(AR531X_MISC_IRQ_TIMER, regs);
1823 +               else if (ar531x_misc_intrs & AR531X_ISR_AHBPROC)
1824 +                       do_IRQ(AR531X_MISC_IRQ_AHB_PROC, regs);
1825 +               else if (ar531x_misc_intrs & AR531X_ISR_AHBDMA)
1826 +                       do_IRQ(AR531X_MISC_IRQ_AHB_DMA, regs);
1827 +               else if (ar531x_misc_intrs & AR531X_ISR_GPIO)
1828 +                {
1829 +                    int i;
1830 +                    u32 gpioIntPending;
1831 +
1832 +                    gpioIntPending = sysRegRead(AR531X_GPIO_DI) & gpioIntMask;
1833 +                    for (i=0; i<AR531X_GPIO_IRQ_COUNT; i++) {
1834 +                        if (gpioIntPending & (1 << i))
1835 +                            do_IRQ(AR531X_GPIO_IRQ(i), regs);
1836 +                    }
1837 +                }
1838 +               else if ((ar531x_misc_intrs & AR531X_ISR_UART0) ||
1839 +                        (ar531x_misc_intrs & AR531X_ISR_UART0DMA)) {
1840 +                       do_IRQ(AR531X_MISC_IRQ_UART0, regs);
1841 +#if CONFIG_KGDB
1842 +                        if (kgdbInterrupt()) {
1843 +                                if (!user_mode(regs))
1844 +                                   set_async_breakpoint((unsigned long *)&regs->cp0_epc);
1845 +                        }
1846 +#endif         /* CONFIG_KGDB */
1847 +                }
1848 +               else if (ar531x_misc_intrs & AR531X_ISR_WD)
1849 +                       do_IRQ(AR531X_MISC_IRQ_WATCHDOG, regs);
1850 +               else if (ar531x_misc_intrs & AR531X_ISR_LOCAL)
1851 +                       do_IRQ(AR531X_MISC_IRQ_LOCAL, regs);
1852 +               else
1853 +                       do_IRQ(AR531X_MISC_IRQ_NONE, regs);
1854 +       } else if (pending & CAUSEF_IP7) {
1855 +               do_IRQ(AR531X_IRQ_CPU_CLOCK, regs);
1856 +       } else
1857 +               do_IRQ(AR531X_IRQ_NONE, regs);
1858 +}
1859 +
1860 +#endif
1861 +
1862 +void __init init_IRQ(void)
1863 +{
1864 +       init_generic_irq();
1865 +       set_except_vector(0, ar531x_interrupt_receive);
1866 +
1867 +       /* Initialize interrupt controllers */
1868 +       mips_cpu_irq_init(MIPS_CPU_IRQ_BASE);
1869 +       ar531x_misc_intr_init(AR531X_MISC_IRQ_BASE);
1870 +        ar531x_gpio_intr_init(AR531X_GPIO_IRQ_BASE);
1871 +       setup_irq(AR531X_IRQ_MISC_INTRS, &cascade);
1872 +       /*
1873 +         * AR531X_IRQ_CPU_CLOCK is setup by ar531x_timer_setup.
1874 +         */
1875 +
1876 +       /* Default "spurious interrupt" handlers */
1877 +       setup_irq(AR531X_IRQ_NONE, &spurious_irq);
1878 +       setup_irq(AR531X_MISC_IRQ_NONE, &spurious_misc);
1879 +       setup_irq(AR531X_GPIO_IRQ_NONE, &spurious_gpio);
1880 +#ifndef CONFIG_AR5315
1881 +       setup_irq(AR531X_MISC_IRQ_TIMER, &ar531x_timer_interrupt);
1882 +#endif
1883 +       setup_irq(AR531X_MISC_IRQ_AHB_PROC, &ar531x_ahb_proc_interrupt);
1884 +        setup_irq(AR531X_MISC_IRQ_GPIO, &cascade);
1885 +
1886 +#ifdef CONFIG_KGDB
1887 +#if CONFIG_EARLY_STOP
1888 +        kgdbInit();
1889 +#endif
1890 +#endif
1891 +}
1892 diff -urN linux-mips/arch/mips/ar531x/ar531xksyms.c mips-linux-2.4.25/arch/mips/ar531x/ar531xksyms.c
1893 --- linux-mips/arch/mips/ar531x/ar531xksyms.c   1970-01-01 01:00:00.000000000 +0100
1894 +++ mips-linux-2.4.25/arch/mips/ar531x/ar531xksyms.c    2005-12-30 17:26:31.001823800 +0000
1895 @@ -0,0 +1,17 @@
1896 +/*
1897 + * This file is subject to the terms and conditions of the GNU General Public
1898 + * License.  See the file "COPYING" in the main directory of this archive
1899 + * for more details.
1900 + *
1901 + * Copyright © 2003 Atheros Communications, Inc.,  All Rights Reserved.
1902 + */
1903 +
1904 +#include <linux/module.h>
1905 +#include "asm/atheros/ar531xbsp.h"
1906 +
1907 +#ifdef CONFIG_KGDB
1908 +EXPORT_SYMBOL(kgdbInit);
1909 +EXPORT_SYMBOL(kgdbEnabled);
1910 +#endif
1911 +EXPORT_SYMBOL(ar531x_sys_frequency);
1912 +EXPORT_SYMBOL(get_system_type);
1913 diff -urN linux-mips/arch/mips/ar531x/ar531xlnx.h mips-linux-2.4.25/arch/mips/ar531x/ar531xlnx.h
1914 --- linux-mips/arch/mips/ar531x/ar531xlnx.h     1970-01-01 01:00:00.000000000 +0100
1915 +++ mips-linux-2.4.25/arch/mips/ar531x/ar531xlnx.h      2005-12-30 17:26:31.001823800 +0000
1916 @@ -0,0 +1,135 @@
1917 +/*
1918 + * This file is subject to the terms and conditions of the GNU General Public
1919 + * License.  See the file "COPYING" in the main directory of this archive
1920 + * for more details.
1921 + *
1922 + * Copyright © 2003 Atheros Communications, Inc.,  All Rights Reserved.
1923 + */
1924 +
1925 +/*
1926 + * This file contains definitions needed in order to compile
1927 + * AR531X products for linux.  Definitions that are largely
1928 + * AR531X-specific and independent of operating system belong
1929 + * in ar531x.h rather than this file.
1930 + */
1931 +#include "ar531x.h"
1932 +
1933 +#define MIPS_CPU_IRQ_BASE              0x00
1934 +#define AR531X_HIGH_PRIO                0x10
1935 +#define AR531X_MISC_IRQ_BASE           0x20
1936 +#define AR531X_GPIO_IRQ_BASE            0x30
1937 +
1938 +/* Software's idea of interrupts handled by "CPU Interrupt Controller" */
1939 +#if CONFIG_AR5315
1940 +#define AR531X_IRQ_NONE                MIPS_CPU_IRQ_BASE+0
1941 +#define AR531X_IRQ_MISC_INTRS  MIPS_CPU_IRQ_BASE+2 /* C0_CAUSE: 0x0400 */
1942 +#define AR531X_IRQ_WLAN0_INTRS MIPS_CPU_IRQ_BASE+3 /* C0_CAUSE: 0x0800 */
1943 +#define AR531X_IRQ_ENET0_INTRS MIPS_CPU_IRQ_BASE+4 /* C0_CAUSE: 0x1000 */
1944 +#define AR531X_IRQ_LCBUS_PCI   MIPS_CPU_IRQ_BASE+6 /* C0_CAUSE: 0x4000 */
1945 +#define AR531X_IRQ_WLAN0_POLL  MIPS_CPU_IRQ_BASE+6 /* C0_CAUSE: 0x4000 */
1946 +#define AR531X_IRQ_CPU_CLOCK   MIPS_CPU_IRQ_BASE+7 /* C0_CAUSE: 0x8000 */
1947 +#else
1948 +#define AR531X_IRQ_NONE                MIPS_CPU_IRQ_BASE+0
1949 +#define AR531X_IRQ_WLAN0_INTRS MIPS_CPU_IRQ_BASE+2 /* C0_CAUSE: 0x0400 */
1950 +#define AR531X_IRQ_ENET0_INTRS MIPS_CPU_IRQ_BASE+3 /* C0_CAUSE: 0x0800 */
1951 +#define AR531X_IRQ_ENET1_INTRS MIPS_CPU_IRQ_BASE+4 /* C0_CAUSE: 0x1000 */
1952 +#define AR531X_IRQ_WLAN1_INTRS MIPS_CPU_IRQ_BASE+5 /* C0_CAUSE: 0x2000 */
1953 +#define AR531X_IRQ_MISC_INTRS  MIPS_CPU_IRQ_BASE+6 /* C0_CAUSE: 0x4000 */
1954 +#define AR531X_IRQ_CPU_CLOCK   MIPS_CPU_IRQ_BASE+7 /* C0_CAUSE: 0x8000 */
1955 +#endif
1956 +/* Miscellaneous interrupts, which share IP6 */
1957 +#define AR531X_MISC_IRQ_NONE           AR531X_MISC_IRQ_BASE+0
1958 +#define AR531X_MISC_IRQ_TIMER          AR531X_MISC_IRQ_BASE+1
1959 +#define AR531X_MISC_IRQ_AHB_PROC       AR531X_MISC_IRQ_BASE+2
1960 +#define AR531X_MISC_IRQ_AHB_DMA                AR531X_MISC_IRQ_BASE+3
1961 +#define AR531X_MISC_IRQ_GPIO           AR531X_MISC_IRQ_BASE+4
1962 +#define AR531X_MISC_IRQ_UART0          AR531X_MISC_IRQ_BASE+5
1963 +#define AR531X_MISC_IRQ_UART0_DMA      AR531X_MISC_IRQ_BASE+6
1964 +#define AR531X_MISC_IRQ_WATCHDOG       AR531X_MISC_IRQ_BASE+7
1965 +#define AR531X_MISC_IRQ_LOCAL          AR531X_MISC_IRQ_BASE+8
1966 +#define AR531X_MISC_IRQ_COUNT          9
1967 +
1968 +/* GPIO Interrupts [0..7], share AR531X_MISC_IRQ_GPIO */
1969 +#define AR531X_GPIO_IRQ_NONE            AR531X_MISC_IRQ_BASE+0
1970 +#define AR531X_GPIO_IRQ(n)              AR531X_MISC_IRQ_BASE+(n)+1
1971 +#ifdef CONFIG_AR5315
1972 +#define AR531X_GPIO_IRQ_COUNT           2
1973 +#else
1974 +#define AR531X_GPIO_IRQ_COUNT           9
1975 +#endif
1976 +
1977 +#define PHYS_TO_K1(physaddr) KSEG1ADDR(physaddr)
1978 +#define PHYS_TO_K0(physaddr) KSEG0ADDR(physaddr)
1979 +#define UNMAPPED_TO_PHYS(vaddr)  PHYSADDR(vaddr)
1980 +#define IS_UNMAPPED_VADDR(vaddr) \
1981 +    ((KSEGX(vaddr) == KSEG0) || (KSEGX(vaddr) == KSEG1))
1982 +
1983 +/* IOCTL commands for /proc/ar531x */
1984 +#define AR531X_CTRL_DO_BREAKPOINT       1
1985 +#define AR531X_CTRL_DO_MADWIFI          2
1986 +
1987 +/*
1988 + * Definitions for operating system portability.
1989 + * These are vxWorks-->Linux translations.
1990 + */
1991 +#define LOCAL static
1992 +#define BOOL int
1993 +#define TRUE 1
1994 +#define FALSE 0
1995 +#define UINT8 u8
1996 +#define UINT16 u16
1997 +#define UINT32 u32
1998 +#define PRINTF printk
1999 +#if /* DEBUG */ 1
2000 +#define DEBUG_PRINTF printk
2001 +#define INLINE
2002 +#else
2003 +DEBUG_PRINTF while (0) printk
2004 +#define INLINE inline
2005 +#endif
2006 +#define sysUDelay(usecs) udelay(usecs)
2007 +#define sysMsDelay(msecs) mdelay(msecs)
2008 +typedef volatile UINT8 *VIRT_ADDR;
2009 +#define MALLOC(sz) kmalloc(sz, GFP_KERNEL)
2010 +#define MALLOC_NOSLEEP(sz) kmalloc(sz, GFP_ATOMIC)
2011 +#define FREE(ptr) kfree((void *)ptr)
2012 +#define BSP_BUG() do { printk("kernel BSP BUG at %s:%d!\n", __FILE__, __LINE__); *(int *)0=0; } while (0)
2013 +#define BSP_BUG_ON(condition) do { if (unlikely((condition)!=0)) BSP_BUG(); } while(0)
2014 +#define ASSERT(x) BSP_BUG_ON(!(x))
2015 +
2016 +extern struct ar531x_boarddata *ar531x_board_configuration;
2017 +extern char *ar531x_radio_configuration;
2018 +extern char *enet_mac_address_get(int MACUnit);
2019 +
2020 +extern void kgdbInit(void);
2021 +extern int kgdbEnabled(void);
2022 +extern void breakpoint(void);
2023 +extern int kgdbInterrupt(void);
2024 +extern unsigned int ar531x_cpu_frequency(void);
2025 +extern unsigned int ar531x_sys_frequency(void);
2026 +
2027 +/* GPIO support */
2028 +extern struct irqaction spurious_gpio;
2029 +extern unsigned int gpioIntMask;
2030 +extern void ar531x_gpio_intr_init(int irq_base);
2031 +extern void ar531x_gpio_ctrl_output(int gpio);
2032 +extern void ar531x_gpio_ctrl_input(int gpio);
2033 +extern void ar531x_gpio_set(int gpio, int val);
2034 +extern int  ar531x_gpio_get(int gpio);
2035 +extern void ar531x_gpio_intr_enable(unsigned int irq);
2036 +extern void ar531x_gpio_intr_disable(unsigned int irq);
2037 +
2038 +/* Watchdog Timer support */
2039 +extern int watchdog_start(unsigned int milliseconds);
2040 +extern int watchdog_stop(void);
2041 +extern int watchdog_is_enabled(void);
2042 +extern unsigned int watchdog_min_timer_reached(void);
2043 +extern void watchdog_notify_alive(void);
2044 +
2045 +#define A_DATA_CACHE_INVAL(start, length) \
2046 +        dma_cache_inv((UINT32)(start),(length))
2047 +
2048 +#define sysWbFlush() mb()
2049 +
2050 +#define intDisable(x) cli()
2051 +#define intEnable(x) sti()
2052 diff -urN linux-mips/arch/mips/ar531x/ar531xprom.c mips-linux-2.4.25/arch/mips/ar531x/ar531xprom.c
2053 --- linux-mips/arch/mips/ar531x/ar531xprom.c    1970-01-01 01:00:00.000000000 +0100
2054 +++ mips-linux-2.4.25/arch/mips/ar531x/ar531xprom.c     2005-12-30 17:26:31.001823800 +0000
2055 @@ -0,0 +1,88 @@
2056 +/*
2057 + * This file is subject to the terms and conditions of the GNU General Public
2058 + * License.  See the file "COPYING" in the main directory of this archive
2059 + * for more details.
2060 + *
2061 + * Copyright MontaVista Software Inc
2062 + * Copyright © 2003 Atheros Communications, Inc.,  All Rights Reserved.
2063 + */
2064 +
2065 +/*
2066 + * Prom setup file for ar531x
2067 + */
2068 +
2069 +#include <linux/init.h>
2070 +#include <linux/config.h>
2071 +#include <linux/kernel.h>
2072 +#include <linux/string.h>
2073 +#include <linux/mm.h>
2074 +#include <linux/bootmem.h>
2075 +
2076 +#include <asm/bootinfo.h>
2077 +#include <asm/addrspace.h>
2078 +
2079 +#include "ar531xlnx.h"
2080 +
2081 +#define COMMAND_LINE_SIZE 512
2082 +
2083 +char arcs_cmdline[COMMAND_LINE_SIZE];
2084 +
2085 +void __init prom_init(int argc, char *argv[])
2086 +{
2087 +    int i;
2088 +    unsigned int memcfg1;
2089 +    int bank0AC, bank1AC;
2090 +    int memsz_in_mb;
2091 +    strcpy(arcs_cmdline, "console=ttyS0,9600");
2092 +    for (i=0; i<argc; i++) {
2093 +        strcat(arcs_cmdline, " ");
2094 +        strcat(arcs_cmdline, argv[i]);
2095 +    }
2096 +
2097 +    mips_machgroup = MACH_GROUP_AR531X;
2098 +#ifdef CONFIG_APUNUSED
2099 +    mips_machtype = MACH_ATHEROS_UNUSED;
2100 +#endif
2101 +#ifdef CONFIG_AP30
2102 +    mips_machtype = MACH_ATHEROS_AP30;
2103 +#endif
2104 +#ifdef CONFIG_AP33
2105 +    mips_machtype = MACH_ATHEROS_AP33;
2106 +#endif
2107 +#ifdef CONFIG_AP38
2108 +    mips_machtype = MACH_ATHEROS_AP38;
2109 +#endif
2110 +#ifdef CONFIG_AP43
2111 +    mips_machtype = MACH_ATHEROS_AP43;
2112 +#endif
2113 +#ifdef CONFIG_AP48
2114 +    mips_machtype = MACH_ATHEROS_AP48;
2115 +#endif
2116 +#ifdef CONFIG_PB32
2117 +    mips_machtype = MACH_ATHEROS_PB32;
2118 +#endif
2119 +
2120 +
2121 +    /* Determine SDRAM size based on Address Checks done at startup */
2122 +#if CONFIG_AR5315
2123 +    /* TO-DO : compute the SDRAM size */
2124 +    memsz_in_mb=8;
2125 +#else
2126 +    memcfg1 = sysRegRead(AR531X_MEM_CFG1);
2127 +    bank0AC = (memcfg1 & MEM_CFG1_AC0) >> MEM_CFG1_AC0_S;
2128 +    bank1AC = (memcfg1 & MEM_CFG1_AC1) >> MEM_CFG1_AC1_S;
2129 +    memsz_in_mb = (bank0AC ? (1 << (bank0AC+1)) : 0)
2130 +                + (bank1AC ? (1 << (bank1AC+1)) : 0);
2131 +#endif
2132 +
2133 +    /*
2134 +     * By default, use all available memory.  You can override this
2135 +     * to use, say, 8MB by specifying "mem=8M" as an argument on the
2136 +     * linux bootup command line.
2137 +     */
2138 +    add_memory_region(0, memsz_in_mb << 20, BOOT_MEM_RAM);
2139 +}
2140 +
2141 +void __init prom_free_prom_memory(void)
2142 +{
2143 +}
2144 diff -urN linux-mips/arch/mips/ar531x/ar531xsetup.c mips-linux-2.4.25/arch/mips/ar531x/ar531xsetup.c
2145 --- linux-mips/arch/mips/ar531x/ar531xsetup.c   1970-01-01 01:00:00.000000000 +0100
2146 +++ mips-linux-2.4.25/arch/mips/ar531x/ar531xsetup.c    2005-12-30 17:26:31.002823648 +0000
2147 @@ -0,0 +1,406 @@
2148 +/*
2149 + * This file is subject to the terms and conditions of the GNU General Public
2150 + * License.  See the file "COPYING" in the main directory of this archive
2151 + * for more details.
2152 + *
2153 + * Copyright © 2003 Atheros Communications, Inc.,  All Rights Reserved.
2154 + */
2155 +
2156 +/*
2157 + * Initialization for ar531x SOC.
2158 + */
2159 +
2160 +#include <linux/config.h>
2161 +#include <linux/init.h>
2162 +#include <linux/delay.h>
2163 +#include <linux/irq.h>
2164 +#include <linux/interrupt.h>
2165 +#include <linux/serial.h>
2166 +#include <linux/types.h>
2167 +#include <linux/string.h>
2168 +
2169 +#include <asm/reboot.h>
2170 +#include <asm/io.h>
2171 +#include <asm/time.h>
2172 +#include <asm/pgtable.h>
2173 +#include <asm/processor.h>
2174 +#include <asm/reboot.h>
2175 +#include <asm/system.h>
2176 +#include <asm/serial.h>
2177 +
2178 +#include "ar531xlnx.h"
2179 +
2180 +void
2181 +ar531x_restart(char *command)
2182 +{
2183 +    for(;;) {
2184 +#if CONFIG_AR5315
2185 +    /* 
2186 +    ** Cold reset does not work,work around is to use the GPIO reset bit.  
2187 +    */
2188 +    unsigned int reg;
2189 +    reg = sysRegRead(AR5315_GPIO_DO);
2190 +    reg &= ~(1 << AR5315_RESET_GPIO);
2191 +    sysRegWrite(AR5315_GPIO_DO, reg);
2192 +    (void)sysRegRead(AR5315_GPIO_DO); /* flush write to hardware */
2193 +      
2194 +#else
2195 +        sysRegWrite(AR531X_RESET, AR531X_RESET_SYSTEM);
2196 +#endif
2197 +    }
2198 +}
2199 +
2200 +void
2201 +ar531x_halt(void)
2202 +{
2203 +        printk(KERN_NOTICE "\n** You can safely turn off the power\n");
2204 +        while (1);
2205 +}
2206 +
2207 +void
2208 +ar531x_power_off(void)
2209 +{
2210 +        ar531x_halt();
2211 +}
2212 +
2213 +const char *
2214 +get_system_type(void)
2215 +{
2216 +#if CONFIG_AR5315
2217 +       return "Atheros AR5315";
2218 +#else
2219 +       return "Atheros AR531X";
2220 +#endif
2221 +}
2222 +
2223 +/*
2224 + * This table is indexed by bits 5..4 of the CLOCKCTL1 register
2225 + * to determine the predevisor value.
2226 + */
2227 +static int CLOCKCTL1_PREDIVIDE_TABLE[4] = {
2228 +    1,
2229 +    2,
2230 +    4,
2231 +    5
2232 +};
2233 +
2234 +#if CONFIG_AR5315
2235 +static int PLLC_DIVIDE_TABLE[5] = {
2236 +    2,
2237 +    3,
2238 +    4,
2239 +    6,
2240 +    3
2241 +};
2242 +
2243 +unsigned int
2244 +ar531x_cpu_frequency(void)
2245 +{
2246 +    static unsigned int ar531x_calculated_cpu_freq=0;
2247 +    unsigned int clockCtl,pllcCtrl,cpuDiv;
2248 +    unsigned int pllcOut,refdiv,fdiv,divby2;
2249 +
2250 +    if(ar531x_calculated_cpu_freq) 
2251 +         return ar531x_calculated_cpu_freq; 
2252 +
2253 +    
2254 +    pllcCtrl = sysRegRead(AR5315_PLLC_CTL);
2255 +    refdiv = (pllcCtrl & PLLC_REF_DIV_M) >> PLLC_REF_DIV_S;
2256 +    refdiv = CLOCKCTL1_PREDIVIDE_TABLE[refdiv];
2257 +    fdiv = (pllcCtrl & PLLC_FDBACK_DIV_M) >> PLLC_FDBACK_DIV_S;
2258 +    divby2 = (pllcCtrl & PLLC_ADD_FDBACK_DIV_M) >> PLLC_ADD_FDBACK_DIV_S;
2259 +    divby2 += 1;
2260 +    pllcOut = (40000000/refdiv)*(2*divby2)*fdiv;
2261 +
2262 +    clockCtl = sysRegRead(AR5315_CPUCLK);
2263 +
2264 +    /* clkm input selected */
2265 +    if((clockCtl & CPUCLK_CLK_SEL_M) == 0  || (clockCtl & CPUCLK_CLK_SEL_M) == 1 ) {
2266 +       unsigned int clkMdiv;
2267 +       clkMdiv = (pllcCtrl & PLLC_CLKM_DIV_M) >> PLLC_CLKM_DIV_S;
2268 +       clkMdiv = PLLC_DIVIDE_TABLE[clkMdiv];
2269 +
2270 +       cpuDiv = (clockCtl & CPUCLK_CLK_DIV_M) >> CPUCLK_CLK_DIV_S;  
2271 +       if(cpuDiv)  cpuDiv *= 2;
2272 +       else cpuDiv=1;
2273 +
2274 +       ar531x_calculated_cpu_freq= (pllcOut/(clkMdiv * cpuDiv)) ;
2275 +        
2276 +       return ar531x_calculated_cpu_freq; 
2277 +    } 
2278 +    
2279 +    /* clkc input selected */
2280 +    if((clockCtl & CPUCLK_CLK_SEL_M) == 2 ) {
2281 +       unsigned int clkCdiv;
2282 +       clkCdiv = (pllcCtrl & PLLC_CLKC_DIV_M) >> PLLC_CLKC_DIV_S;
2283 +       clkCdiv = PLLC_DIVIDE_TABLE[clkCdiv];
2284 +
2285 +       cpuDiv = (clockCtl & CPUCLK_CLK_DIV_M) >> CPUCLK_CLK_DIV_S;  
2286 +       if(cpuDiv)  cpuDiv *= 2;
2287 +       else cpuDiv=1;
2288 +
2289 +       ar531x_calculated_cpu_freq= (pllcOut/(clkCdiv * cpuDiv)) ;
2290 +        
2291 +       return ar531x_calculated_cpu_freq; 
2292 +    } else {   /* ref_clk  selected */
2293 +
2294 +       cpuDiv = (clockCtl & CPUCLK_CLK_DIV_M) >> CPUCLK_CLK_DIV_S;  
2295 +       if(cpuDiv)  cpuDiv *= 2;
2296 +       else cpuDiv=1;
2297 +
2298 +       ar531x_calculated_cpu_freq= (40000000/(cpuDiv)) ;
2299 +       return ar531x_calculated_cpu_freq; 
2300 +    }
2301 +}
2302 +
2303 +unsigned int
2304 +ar531x_apb_frequency(void)
2305 +{
2306 +    static unsigned int ar531x_calculated_cpu_freq=0;
2307 +    unsigned int clockCtl,pllcCtrl,cpuDiv;
2308 +    unsigned int pllcOut,refdiv,fdiv,divby2;
2309 +
2310 +    if(ar531x_calculated_cpu_freq) 
2311 +         return ar531x_calculated_cpu_freq; 
2312 +
2313 +    
2314 +    pllcCtrl = sysRegRead(AR5315_PLLC_CTL);
2315 +    refdiv = (pllcCtrl & PLLC_REF_DIV_M) >> PLLC_REF_DIV_S;
2316 +    refdiv = CLOCKCTL1_PREDIVIDE_TABLE[refdiv];
2317 +    fdiv = (pllcCtrl & PLLC_FDBACK_DIV_M) >> PLLC_FDBACK_DIV_S;
2318 +    divby2 = (pllcCtrl & PLLC_ADD_FDBACK_DIV_M) >> PLLC_ADD_FDBACK_DIV_S;
2319 +    divby2 += 1;
2320 +    pllcOut = (40000000/refdiv)*(2*divby2)*fdiv;
2321 +
2322 +    clockCtl = sysRegRead(AR5315_AMBACLK);
2323 +
2324 +    /* clkm input selected */
2325 +    if((clockCtl & CPUCLK_CLK_SEL_M) == 0  || (clockCtl & CPUCLK_CLK_SEL_M) == 1 ) {
2326 +       unsigned int clkMdiv;
2327 +       clkMdiv = (pllcCtrl & PLLC_CLKM_DIV_M) >> PLLC_CLKM_DIV_S;
2328 +       clkMdiv = PLLC_DIVIDE_TABLE[clkMdiv];
2329 +
2330 +       cpuDiv = (clockCtl & CPUCLK_CLK_DIV_M) >> CPUCLK_CLK_DIV_S;  
2331 +       if(cpuDiv)  cpuDiv *= 2;
2332 +       else cpuDiv=1;
2333 +
2334 +       ar531x_calculated_cpu_freq= (pllcOut/(clkMdiv * cpuDiv)) ;
2335 +        
2336 +       return ar531x_calculated_cpu_freq; 
2337 +    } 
2338 +    
2339 +    /* clkc input selected */
2340 +    if((clockCtl & CPUCLK_CLK_SEL_M) == 2 ) {
2341 +       unsigned int clkCdiv;
2342 +       clkCdiv = (pllcCtrl & PLLC_CLKC_DIV_M) >> PLLC_CLKC_DIV_S;
2343 +       clkCdiv = PLLC_DIVIDE_TABLE[clkCdiv];
2344 +
2345 +       cpuDiv = (clockCtl & CPUCLK_CLK_DIV_M) >> CPUCLK_CLK_DIV_S;  
2346 +       if(cpuDiv)  cpuDiv *= 2;
2347 +       else cpuDiv=1;
2348 +
2349 +       ar531x_calculated_cpu_freq= (pllcOut/(clkCdiv * cpuDiv)) ;
2350 +        
2351 +       return ar531x_calculated_cpu_freq; 
2352 +    } else {   /* ref_clk  selected */
2353 +
2354 +       cpuDiv = (clockCtl & CPUCLK_CLK_DIV_M) >> CPUCLK_CLK_DIV_S;  
2355 +       if(cpuDiv)  cpuDiv *= 2;
2356 +       else cpuDiv=1;
2357 +
2358 +       ar531x_calculated_cpu_freq= (40000000/(cpuDiv)) ;
2359 +       return ar531x_calculated_cpu_freq; 
2360 +    }
2361 +}
2362 +
2363 +#else
2364 +unsigned int
2365 +ar531x_cpu_frequency(void)
2366 +{
2367 +       static unsigned int ar531x_calculated_cpu_freq;
2368 +        unsigned int clockctl1_predivide_mask;
2369 +        unsigned int clockctl1_predivide_shift;
2370 +        unsigned int clockctl1_multiplier_mask;
2371 +        unsigned int clockctl1_multiplier_shift;
2372 +        unsigned int clockctl1_doubler_mask;
2373 +        int wisoc_revision;
2374 +
2375 +        /*
2376 +         * Trust the bootrom's idea of cpu frequency.
2377 +         */
2378 +        ar531x_calculated_cpu_freq = sysRegRead(AR5312_SCRATCH);
2379 +        if (ar531x_calculated_cpu_freq)
2380 +           return ar531x_calculated_cpu_freq;
2381 +
2382 +        wisoc_revision = (sysRegRead(AR531X_REV) & AR531X_REV_MAJ) >> AR531X_REV_MAJ_S;
2383 +
2384 +        if (wisoc_revision == AR531X_REV_MAJ_AR2313) {
2385 +            clockctl1_predivide_mask = AR2313_CLOCKCTL1_PREDIVIDE_MASK;
2386 +            clockctl1_predivide_shift = AR2313_CLOCKCTL1_PREDIVIDE_SHIFT;
2387 +            clockctl1_multiplier_mask = AR2313_CLOCKCTL1_MULTIPLIER_MASK;
2388 +            clockctl1_multiplier_shift = AR2313_CLOCKCTL1_MULTIPLIER_SHIFT;
2389 +            clockctl1_doubler_mask = AR2313_CLOCKCTL1_DOUBLER_MASK;
2390 +        } else { /* AR5312 and AR2312 */
2391 +            clockctl1_predivide_mask = AR5312_CLOCKCTL1_PREDIVIDE_MASK;
2392 +            clockctl1_predivide_shift = AR5312_CLOCKCTL1_PREDIVIDE_SHIFT;
2393 +            clockctl1_multiplier_mask = AR5312_CLOCKCTL1_MULTIPLIER_MASK;
2394 +            clockctl1_multiplier_shift = AR5312_CLOCKCTL1_MULTIPLIER_SHIFT;
2395 +            clockctl1_doubler_mask = AR5312_CLOCKCTL1_DOUBLER_MASK;
2396 +        }
2397 +
2398 +        /*
2399 +         * Clocking is derived from a fixed 40MHz input clock.
2400 +         *  cpuFreq = InputClock * MULT (where MULT is PLL multiplier)
2401 +         *
2402 +         *  sysFreq = cpuFreq / 4       (used for APB clock, serial,
2403 +         *                               flash, Timer, Watchdog Timer)
2404 +         *
2405 +         *  cntFreq = cpuFreq / 2       (use for CPU count/compare)
2406 +         *
2407 +         * So, for example, with a PLL multiplier of 5, we have
2408 +         *  cpuFrez = 200MHz
2409 +         *  sysFreq = 50MHz
2410 +         *  cntFreq = 100MHz
2411 +         *
2412 +         * We compute the CPU frequency, based on PLL settings.
2413 +         */
2414 +       if (ar531x_calculated_cpu_freq == 0) {
2415 +            unsigned int clockCtl1 = sysRegRead(AR5312_CLOCKCTL1);
2416 +
2417 +            int preDivideSelect = (clockCtl1 & clockctl1_predivide_mask) >>
2418 +                                   clockctl1_predivide_shift;
2419 +
2420 +            int preDivisor = CLOCKCTL1_PREDIVIDE_TABLE[preDivideSelect];
2421 +
2422 +            int multiplier = (clockCtl1 & clockctl1_multiplier_mask) >>
2423 +                              clockctl1_multiplier_shift;
2424 +
2425 +            if (clockCtl1 & clockctl1_doubler_mask) {
2426 +                multiplier = multiplier << 1;
2427 +            }
2428 +
2429 +            ar531x_calculated_cpu_freq = (40000000 / preDivisor) * multiplier;
2430 +        }
2431 +
2432 +       return ar531x_calculated_cpu_freq;
2433 +}
2434 +#endif
2435 +
2436 +unsigned int
2437 +ar531x_sys_frequency(void)
2438 +{
2439 +       static unsigned int ar531x_calculated_sys_freq = 0;
2440 +
2441 +       if (ar531x_calculated_sys_freq == 0) {
2442 +               ar531x_calculated_sys_freq = ar531x_cpu_frequency() / 4;
2443 +       }
2444 +
2445 +       return ar531x_calculated_sys_freq;
2446 +}
2447 +
2448 +static void __init
2449 +flash_setup(void)
2450 +{
2451 +    UINT32 flash_ctl;
2452 +#ifndef CONFIG_AR5315
2453 +    /* Configure flash bank 0 */
2454 +    flash_ctl = FLASHCTL_E |
2455 +                FLASHCTL_AC_8M |
2456 +                FLASHCTL_RBLE |
2457 +                (0x01 << FLASHCTL_IDCY_S) |
2458 +                (0x07 << FLASHCTL_WST1_S) |
2459 +                (0x07 << FLASHCTL_WST2_S) |
2460 +                (sysRegRead(AR531X_FLASHCTL0) & FLASHCTL_MW);
2461 +
2462 +    sysRegWrite(AR531X_FLASHCTL0, flash_ctl);
2463 +
2464 +    /* Disable other flash banks */
2465 +    sysRegWrite(AR531X_FLASHCTL1,
2466 +                sysRegRead(AR531X_FLASHCTL1) & ~(FLASHCTL_E | FLASHCTL_AC));
2467 +
2468 +    sysRegWrite(AR531X_FLASHCTL2,
2469 +                sysRegRead(AR531X_FLASHCTL2) & ~(FLASHCTL_E | FLASHCTL_AC));
2470 +#endif
2471 +}
2472 +
2473 +
2474 +
2475 +void __init
2476 +serial_setup(void)
2477 +{
2478 +       struct serial_struct s;
2479 +
2480 +       memset(&s, 0, sizeof(s));
2481 +
2482 +       s.flags = STD_COM_FLAGS;
2483 +       s.io_type = SERIAL_IO_MEM;
2484 +#if CONFIG_AR5315
2485 +       s.baud_base = ar531x_apb_frequency()/16;
2486 +#else
2487 +       s.baud_base = ar531x_sys_frequency()/16;
2488 +#endif
2489 +       s.irq = AR531X_MISC_IRQ_UART0;
2490 +       s.iomem_reg_shift = 2;
2491 +#if CONFIG_AR5315
2492 +       s.iomem_base = (u8 *)AR5315_UART0;
2493 +#else
2494 +       s.iomem_base = (u8 *)AR531X_UART0;
2495 +#endif
2496 +
2497 +       if (early_serial_setup(&s) != 0)
2498 +               printk(KERN_ERR "early_serial_setup failed\n");
2499 +}
2500 +
2501 +extern int setup_irq(unsigned int irq, struct irqaction *irqaction);
2502 +static void __init
2503 +ar531x_timer_setup(struct irqaction *irq)
2504 +{
2505 +        unsigned int count;
2506 +
2507 +       /* Usually irq is timer_irqaction (timer_interrupt) */
2508 +       setup_irq(AR531X_IRQ_CPU_CLOCK, irq);
2509 +
2510 +        /* to generate the first CPU timer interrupt */
2511 +        count = read_c0_count();
2512 +        write_c0_compare(count + 1000);
2513 +}
2514 +
2515 +extern void (*board_time_init)(void);
2516 +
2517 +static void __init
2518 +ar531x_time_init(void)
2519 +{
2520 +       mips_hpt_frequency = ar531x_cpu_frequency() / 2;
2521 +}
2522 +
2523 +void __init
2524 +ar531x_setup(void)
2525 +{
2526 +       /* Clear any lingering AHB errors */
2527 +#if CONFIG_AR5315
2528 +       unsigned int config = read_c0_config();
2529 +       write_c0_config(config & ~0x3);
2530 +       sysRegWrite(AR5315_AHB_ERR0,AHB_ERROR_DET);
2531 +       sysRegRead(AR5315_AHB_ERR1);
2532 +       sysRegWrite(AR5315_WDC, WDC_IGNORE_EXPIRATION);
2533 +#else
2534 +       sysRegRead(AR531X_PROCADDR);
2535 +       sysRegRead(AR531X_DMAADDR);
2536 +
2537 +       sysRegWrite(AR531X_WD_CTRL, AR531X_WD_CTRL_IGNORE_EXPIRATION);
2538 +
2539 +#endif
2540 +
2541 +        /* Disable data watchpoints */
2542 +        write_c0_watchlo0(0);
2543 +
2544 +       board_time_init = ar531x_time_init;
2545 +        board_timer_setup = ar531x_timer_setup;
2546 +
2547 +        _machine_restart = ar531x_restart;
2548 +        _machine_halt = ar531x_halt;
2549 +        _machine_power_off = ar531x_power_off;
2550 +
2551 +        flash_setup();
2552 +        serial_setup();
2553 +}
2554 diff -urN linux-mips/arch/mips/ar531x/Makefile mips-linux-2.4.25/arch/mips/ar531x/Makefile
2555 --- linux-mips/arch/mips/ar531x/Makefile        1970-01-01 01:00:00.000000000 +0100
2556 +++ mips-linux-2.4.25/arch/mips/ar531x/Makefile 2005-12-30 17:26:29.912989328 +0000
2557 @@ -0,0 +1,33 @@
2558 +#
2559 +# This file is subject to the terms and conditions of the GNU General Public
2560 +# License.  See the file "COPYING" in the main directory of this archive
2561 +# for more details.
2562 +#
2563 +# Copyright © 2003 Atheros Communications, Inc.,  All Rights Reserved.
2564 +#
2565 +
2566 +# Makefile for Atheros ar531x boards
2567 +#
2568 +# Note! Dependencies are done automagically by 'make dep', which also
2569 +# removes any old dependencies. DON'T put your own dependencies here
2570 +# unless it's something special (ie not a .c file).
2571 +#
2572 +
2573 +.S.s:
2574 +       $(CPP) $(CFLAGS) $< -o $*.s
2575 +.S.o:
2576 +       $(CC) $(CFLAGS) -D__ASSEMBLY__ -c $< -o $*.o
2577 +
2578 +O_TARGET:= ar531x.o
2579 +
2580 +export-objs = ar531xksyms.o
2581 +
2582 +obj-y    := ar531xdbg_io.o     \
2583 +       ar531xsetup.o   \
2584 +       ar531xprom.o    \
2585 +       ar531xirq.o     \
2586 +       ar531xintr.o    \
2587 +       ar531xgpio.o    \
2588 +       ar531xksyms.o
2589 +
2590 +include $(TOPDIR)/Rules.make
2591 diff -urN linux-mips/arch/mips/ar531x/README mips-linux-2.4.25/arch/mips/ar531x/README
2592 --- linux-mips/arch/mips/ar531x/README  1970-01-01 01:00:00.000000000 +0100
2593 +++ mips-linux-2.4.25/arch/mips/ar531x/README   2005-12-30 17:26:30.478903296 +0000
2594 @@ -0,0 +1,68 @@
2595 +Basic information for the AR531X Board Support Package
2596 +
2597 +This directory contains the "LBSP" -- Linux Board Support Package --
2598 +for Linux on the Atheros AR531X Wireless System-On-a-Chip.  It is intended
2599 +primarily as a building block for wireless products.  At this time, the
2600 +AR531X Linux BSP is experimental code, and is actively UNDER CONSTRUCTION.
2601 +
2602 +Some components that are supported by this LBSP along with a standard 2.4
2603 +Linux MIPS kernel include
2604 +  R4Kc CPU
2605 +  instruction and data caches
2606 +  SDRAM
2607 +  flash (Macronix, AMD, STS, etc.)
2608 +  16550 serial port
2609 +  ethernet MACs
2610 +  ethernet PHY or PHY Switch (RealTek, Kendin, Marvell)
2611 +  General-Purpose I/O pins
2612 +  kernel debugging with kgdb
2613 +
2614 +This LBSP code does NOT include drivers for the wireless components of the
2615 +chip/boards!  Drivers for those components may be distributed separately.
2616 +In particular, the MADWiFi project under SourceForge supports (not yet!)
2617 +wireless functions on the AR531X chipset.  See
2618 +   http://www.sourceforge.net/projects/madwifi
2619 +
2620 +Files included in this BSP:
2621 +ae531xlnx.c      - Linux-specific portions of the ethernet driver
2622 +ae531xmac.c      - OS-independent AR531X ethernet MAC code
2623 +ae531xmac.h      - OS-independent AR531X ethernet MAC software definitions
2624 +ae531xreg.h      - OS-independent AR531X ethernet MAC hardware definitions
2625 +ar531x.h         - OS-independent AR531X system hardware definitions
2626 +ar531xlnx.h      - Linux-specific AR531X system definitions and externs
2627 +defconfig-ar531x - Default Linux configuration file
2628 +intr_recv.S      - Linux interrupt "glue" code
2629 +ar531xirq.c      - Linux Interrupt Request management
2630 +Makefile         - Linux makefile
2631 +mvPhy.c          - OS-independent ethernet PHY code for Marvell Switch
2632 +mvPhy.h          - OS-independent ethernet PHY definitions for Marvell Switch
2633 +ar531xprom.c     - Linux prom "glue" code
2634 +ar531xsetup.c    - Linux startup code
2635 +ar531xdbg_io.c   - Support for kgdb-based debugging and for EARLY_PRINTK_HACK
2636 +ar531xproc.c     - Pseudo-device driver for /proc/ar531x device
2637 +ar531xgpio.c     - Support for General Purpose I/O pins
2638 +ar531xwmacsl.c   - Wireless MAC Support Layer
2639 +
2640 +Additional files, distributed with the BSP:
2641 +README           - This file
2642 +README.BUILD     - Instructions for building a linux kernel from source
2643 +README.EXECUTE   - Instructions for testing your linux kernel
2644 +README.RAMDISK   - Instructions for building a root ramdisk image
2645 +
2646 +ramdisk.gz       - A binary ramdisk image, suitable for use with AR531X.
2647 +DIFFS            - Directory that contains "patch" files (See README.BUILD)
2648 +
2649 +
2650 +There are several ways to boot a vmlinux image on an AR531X board:
2651 +  -You can boot in over ethernet from the vxWorks bootrom, which is preloaded
2652 +   on all Atheros boards
2653 +  -You can use an ICE (e.g. VisionICE) to load the vmlinux image.  You will
2654 +   need appropriate register initialization (e.g. AP30.ini file)
2655 +  -You can use the eCos RedBoot bootrom loader.  This is a full-featured
2656 +   bootrom which as been ported to AR531x.  It can boot vmlinux over ethernet
2657 +   or from flash.  Source code is available from Atheros.
2658 +
2659 +Please send comments, corrections, complaints, criticisms, suggestions,
2660 +enhancements, requests, or any other reasonable communications regarding
2661 +this effort, to "linux@atheros.com".  Your email will be received by a
2662 +couple of engineers, and redirected as appropriate.
2663 diff -urN linux-mips/arch/mips/ar531x/README.BUILD mips-linux-2.4.25/arch/mips/ar531x/README.BUILD
2664 --- linux-mips/arch/mips/ar531x/README.BUILD    1970-01-01 01:00:00.000000000 +0100
2665 +++ mips-linux-2.4.25/arch/mips/ar531x/README.BUILD     2005-12-30 17:26:30.478903296 +0000
2666 @@ -0,0 +1,47 @@
2667 +       How to BUILD a linux kernel for an AR531X system
2668 +
2669 +It is expected that you will build Linux on an existing Linux system, which 
2670 +has all of the standard Linux tools.
2671 +
2672 +01) Obtain a MIPS BigEndian ELF gcc-compatible toolchain.  For example,
2673 +    if you're cross-compiling on a x86 Linux system, you could use:
2674 +    ftp://ftp.mips.com/pub/tools/software/sde-for-linux/sdelinux-5.01-4eb.i386.rpm
2675 +
2676 +02) Obtain the latest working MIPS Linux kernel
2677 +    cvs -d :pserver:cvs@ftp.linux-mips.org:/home/cvs login    (password "cvs")
2678 +    cvs -d :pserver:cvs@ftp.linux-mips.org:/home/cvs co -r linux_2_4 linux
2679 +
2680 +    Now "cd linux".  The remainder of these instructions assume
2681 +    that you are in the linux directory.
2682 +
2683 +03) Place the contents of this directory at arch/mips/ar531x.
2684 +
2685 +04) Use the patch command to patch generic linux files according
2686 +    to the DIFFS directory
2687 +    for i in arch/mips/ar531x/DIFFS/*.diff
2688 +    do
2689 +       patch -p1 < $i
2690 +    done
2691 +    NOTE: This version of the AR531X Linux BSP was tested with
2692 +    MIPS Linux 2.4.22 as of 11/14/03.  If you use a different
2693 +    (e.g. more recent) version of Linux source, you may need to
2694 +    resolve some minor patch and compilation issues.
2695 +
2696 +05) Set up a RAMDISK image.
2697 +    See the instructions in README.RAMDISK.
2698 +
2699 +06) Set up a linux configuration using ar531x/defconfig-ar531x.
2700 +    cp arch/mips/ar531x/defconfig-ar531x .config
2701 +    make oldconfig       (answer all questions that are asked)
2702 +    NOTE: For development/debug purposes, you may want to
2703 +    enable CONFIG_RUNTIME_DEBUG and CONFIG_KGDB.
2704 +
2705 +07) Make dependencies.
2706 +    make dep
2707 +
2708 +08) Build the linux kernel
2709 +    make
2710 +
2711 +09) The linux image you just built is in vmlinux.
2712 +    See instructions in README.EXECUTE to run your vmlinux
2713 +    image on an AP531X-based board.
2714 diff -urN linux-mips/arch/mips/ar531x/README.EXECUTE mips-linux-2.4.25/arch/mips/ar531x/README.EXECUTE
2715 --- linux-mips/arch/mips/ar531x/README.EXECUTE  1970-01-01 01:00:00.000000000 +0100
2716 +++ mips-linux-2.4.25/arch/mips/ar531x/README.EXECUTE   2005-12-30 17:26:30.479903144 +0000
2717 @@ -0,0 +1,23 @@
2718 +      How to EXECUTE a linux image on an AR531X system
2719 +
2720 +There are currently three ways to run you vmlinux image:
2721 +  1) Load it using the vxWorks bootrom that is supplied with the board.
2722 +     You can load it over ethernet or from the TFFS file system, if you
2723 +     have sufficient flash to store the image.
2724 +  2) Load it using an ICE (e.g. VisionICE).
2725 +  3) Use a bootrom loader, such as eCos RedBoot.
2726 +
2727 +After you have booted linux:
2728 +  By default, the root filesystem on ramdisk is read-only.
2729 +  To make it writable, use "mount -o remount w /".
2730 +
2731 +  The user-level commands are slightly non-standard, as they
2732 +  are based on "busybox".
2733 +
2734 +  The "wget" command is included.  You can use wget to fetch
2735 +  files from any ftp server.  So, for instance, you can fetch
2736 +  a kernel module and then "insmod" it.
2737 +
2738 +Note that the standard source-level kernel debugger, kgdb, works well
2739 +over the serial line with this port.  We use kgdb and the kgdb_demux perl
2740 +script -- available over the www -- for debugging.
2741 diff -urN linux-mips/arch/mips/ar531x/README.VERSION mips-linux-2.4.25/arch/mips/ar531x/README.VERSION
2742 --- linux-mips/arch/mips/ar531x/README.VERSION  1970-01-01 01:00:00.000000000 +0100
2743 +++ mips-linux-2.4.25/arch/mips/ar531x/README.VERSION   2005-12-30 17:26:30.479903144 +0000
2744 @@ -0,0 +1 @@
2745 +Source release last modified: 12/16/03
2746 diff -urN linux-mips/arch/mips/config-shared.in mips-linux-2.4.25/arch/mips/config-shared.in
2747 --- linux-mips/arch/mips/config-shared.in       2005-12-24 15:11:15.963885864 +0000
2748 +++ mips-linux-2.4.25/arch/mips/config-shared.in        2005-12-30 17:26:31.611731080 +0000
2749 @@ -34,6 +34,7 @@
2750  dep_bool 'Support for Alchemy PB1550 board' CONFIG_MIPS_PB1550 $CONFIG_MIPS32
2751  dep_bool 'Support for Alchemy PB1200 board' CONFIG_MIPS_PB1200 $CONFIG_MIPS32
2752  dep_bool 'Support for Alchemy Hydrogen3 board' CONFIG_MIPS_HYDROGEN3 $CONFIG_MIPS32
2753 +dep_bool 'Support for Atheros AR5312/AR2312 WiSoC (EXPERIMENTAL)' CONFIG_AR531X $CONFIG_AR531X $CONFIG_EXPERIMENTAL
2754  dep_bool 'Support for MyCable XXS1500 board' CONFIG_MIPS_XXS1500 $CONFIG_MIPS32
2755  dep_bool 'Support for 4G Systems MTX-1 board' CONFIG_MIPS_MTX1 $CONFIG_MIPS32
2756  dep_bool 'Support for Cogent CSB250 board' CONFIG_COGENT_CSB250 $CONFIG_MIPS32
2757 @@ -238,6 +239,63 @@
2758     define_bool CONFIG_PC_KEYB y
2759     define_bool CONFIG_OLD_TIME_C y
2760  fi
2761 +if [ "$CONFIG_AR531X" = "y" ]; then
2762 +   define_bool CONFIG_IRQ_CPU y
2763 +   define_bool CONFIG_CPU_R4X00 y
2764 +   define_bool CONFIG_SERIAL y
2765 +   define_bool CONFIG_NEW_IRQ y
2766 +   define_bool CONFIG_NEW_TIME_C y
2767 +   define_bool CONFIG_AR5312
2768 +   define_bool CONFIG_NONCOHERENT_IO y
2769 +   bool 'Enable early printk hack' CONFIG_EARLY_PRINTK_HACK
2770 +   define_bool CONFIG_SCSI n
2771 +   mainmenu_option next_comment
2772 +   comment 'Board selection'
2773 +      choice 'Board type' \
2774 +         "UNKNOWN CONFIG_APUNKNOWN \
2775 +         AP30 CONFIG_AP30 \
2776 +          AP31 CONFIG_AP31 \
2777 +         AP33 CONFIG_AP33 \
2778 +         AP38 CONFIG_AP38 \
2779 +         AP43 CONFIG_AP43 \
2780 +         AP48 CONFIG_AP48 \
2781 +         AP51 CONFIG_AP51 \
2782 +          AP30-ASK CONFIG_AP30ASK" AP30
2783 +   if [ "$CONFIG_AP30" = "y" -o "$CONFIG_AP30ASK" = "y" ]; then
2784 +       define_int CONFIG_MTD_PHYSMAP_BUSWIDTH 2
2785 +   fi
2786 +   if [ "$CONFIG_AP33" = "y" ]; then
2787 +       define_int CONFIG_MTD_PHYSMAP_BUSWIDTH 1
2788 +   fi
2789 +   if [ "$CONFIG_AP38" = "y" ]; then
2790 +       define_int CONFIG_MTD_PHYSMAP_BUSWIDTH 1
2791 +   fi
2792 +   if [ "$CONFIG_AP43" = "y" ]; then
2793 +       define_int CONFIG_MTD_PHYSMAP_BUSWIDTH 1
2794 +   fi
2795 +   if [ "$CONFIG_AP48" = "y" ]; then
2796 +       define_int CONFIG_MTD_PHYSMAP_BUSWIDTH 1
2797 +   fi
2798 +   if [ "$CONFIG_AP51" = "y" ]; then
2799 +       define_int CONFIG_MTD_PHYSMAP_BUSWIDTH 1
2800 +       define_bool CONFIG_MTD_REDBOOT_PARTS y
2801 +       define_bool CONFIG_AR5315 y
2802 +       define_bool CONFIG_MTD_SPIFLASH y
2803 +       define_bool CONFIG_MTD_CFI n
2804 +       define_bool CONFIG_MTD_JEDECPROBE n
2805 +       define_bool CONFIG_MTD_CFI_INTELEXT n
2806 +       define_bool CONFIG_MTD_CFI_AMDSTD n
2807 +       define_bool CONFIG_MTD_OBSOLETE_CHIPS n
2808 +       define_bool CONFIG_MTD_AMDSTD n
2809 +       define_bool CONFIG_MTD_JEDEC n
2810 +       define_bool CONFIG_MTD_PHYSMAP n
2811 +   fi
2812 +   mainmenu_option next_comment
2813 +   comment 'Flash Selection'
2814 +      choice 'Flash Size' \
2815 +         "2MB  CONFIG_FLASH_2MB \
2816 +          4MB  CONFIG_FLASH_4MB" 2MB
2817 +fi
2818  if [ "$CONFIG_CASIO_E55" = "y" ]; then
2819     define_bool CONFIG_IRQ_CPU y
2820     define_bool CONFIG_NEW_TIME_C y
2821
2822 diff -urN linux-mips/arch/mips/kernel/setup.c mips-linux-2.4.25/arch/mips/kernel/setup.c
2823 --- linux-mips/arch/mips/kernel/setup.c 2005-12-24 15:11:16.188851664 +0000
2824 +++ mips-linux-2.4.25/arch/mips/kernel/setup.c  2005-12-30 17:26:33.536438480 +0000
2825 @@ -496,6 +496,7 @@
2826         void hp_setup(void);
2827         void au1x00_setup(void);
2828         void frame_info_init(void);
2829 +       void ar531x_setup(void);
2830  
2831         frame_info_init();
2832  #if defined(CONFIG_BLK_DEV_FD) || defined(CONFIG_BLK_DEV_FD_MODULE)
2833 @@ -693,6 +694,12 @@
2834                  pmc_yosemite_setup();
2835                  break;
2836  #endif
2837 +
2838 +#ifdef CONFIG_AR531X
2839 +       case MACH_GROUP_AR531X:
2840 +               ar531x_setup();
2841 +               break;
2842 +#endif
2843         default:
2844                 panic("Unsupported architecture");
2845         }
2846 diff -urN linux-mips/arch/mips/Makefile mips-linux-2.4.25/arch/mips/Makefile
2847 --- linux-mips/arch/mips/Makefile       2005-12-24 15:11:15.903894984 +0000
2848 +++ mips-linux-2.4.25/arch/mips/Makefile        2005-12-30 17:26:29.911989480 +0000
2849 @@ -701,6 +701,17 @@
2850  LOADADDR      += 0x80020000
2851  endif
2852  
2853 +ifdef CONFIG_AR531X
2854 +SUBDIRS       += arch/mips/ar531x
2855 +LIBS          += arch/mips/ar531x/ar531x.o
2856 +ifdef CONFIG_AP51
2857 +LOADADDR      += 0x80041000
2858 +else
2859 +LOADADDR      += 0x80002000
2860 +endif
2861 +
2862 +endif
2863 +
2864  #
2865  # Choosing incompatible machines durings configuration will result in
2866  # error messages during linking.  Select a default linkscript if
2867 diff -urN linux-mips/ath_version.mk mips-linux-2.4.25/ath_version.mk
2868 --- linux-mips/ath_version.mk   1970-01-01 01:00:00.000000000 +0100
2869 +++ mips-linux-2.4.25/ath_version.mk    2005-12-30 17:27:00.579327336 +0000
2870 @@ -0,0 +1 @@
2871 +EXTRAVERSION=-LSDK-5.0.0-RC5
2872 diff -urN linux-mips/drivers/char/serial.c mips-linux-2.4.25/drivers/char/serial.c
2873 --- linux-mips/drivers/char/serial.c    2005-12-24 15:11:21.796999096 +0000
2874 +++ mips-linux-2.4.25/drivers/char/serial.c     2005-12-30 17:27:10.815771160 +0000
2875 @@ -3441,7 +3441,7 @@
2876  
2877  static _INLINE_ void show_serial_version(void)
2878  {
2879 -       printk(KERN_INFO "%s version %s%s (%s) with%s", serial_name,
2880 +       printk(KERN_INFO "%s version %s%s (%s) with%s\n", serial_name,
2881                serial_version, LOCAL_VERSTRING, serial_revdate,
2882                serial_options);
2883  }
2884 @@ -5567,7 +5567,7 @@
2885                         printk(KERN_INFO"ttyS%02d%s at 0x%p (irq = %d) is a %s\n",
2886                                state->line + SERIAL_DEV_OFFSET,
2887                                (state->flags & ASYNC_FOURPORT) ? " FourPort" : "",
2888 -                              state->iomem_base, state->irq,
2889 +                              (void *)state->iomem_base, state->irq,
2890                                uart_config[state->type].name);
2891                 }
2892                 else {
2893 diff -urN linux-mips/drivers/mtd/chips/cfi_cmdset_0002.c mips-linux-2.4.25/drivers/mtd/chips/cfi_cmdset_0002.c
2894 --- linux-mips/drivers/mtd/chips/cfi_cmdset_0002.c      2005-12-24 15:11:25.102496584 +0000
2895 +++ mips-linux-2.4.25/drivers/mtd/chips/cfi_cmdset_0002.c       2005-12-30 17:27:21.333172272 +0000
2896 @@ -511,7 +511,7 @@
2897            or tells us why it failed. */        
2898         dq6 = CMD(1<<6);
2899         dq5 = CMD(1<<5);
2900 -       timeo = jiffies + (HZ/1000); /* setting timeout to 1ms for now */
2901 +       timeo = jiffies + (HZ/1000) + 1; /* setting timeout to 1ms for now */
2902                 
2903         oldstatus = cfi_read(map, adr);
2904         status = cfi_read(map, adr);
2905 @@ -536,16 +536,18 @@
2906                 if( (status & dq5) == dq5 ) {
2907                         /* When DQ5 raises, we must check once again
2908                            if DQ6 is toggling.  If not, the erase has been
2909 -                          completed OK.  If not, reset chip. */
2910 +                          completed OK.  But if so, reset chip. */
2911                         oldstatus = cfi_read(map, adr);
2912                         status = cfi_read(map, adr);
2913                     
2914                         if ( (oldstatus & 0x00FF) == (status & 0x00FF) ) {
2915 +#if 0
2916                                 printk(KERN_WARNING "Warning: DQ5 raised while program operation was in progress, however operation completed OK\n" );
2917 +#endif 
2918                         } else { 
2919                                 /* DQ5 is active so we can do a reset and stop the erase */
2920                                 cfi_write(map, CMD(0xF0), chip->start);
2921 -                               printk(KERN_WARNING "Internal flash device timeout occurred or write operation was performed while flash was programming.\n" );
2922 +                               printk(KERN_WARNING "Internal flash device timeout pt A occurred or write operation was performed while flash was programming.  timeout=%d\n",chip->word_write_time );
2923                         }
2924                 } else {
2925                         printk(KERN_WARNING "Waiting for write to complete timed out in do_write_oneword.");        
2926 @@ -959,7 +961,7 @@
2927              {
2928                             /* DQ5 is active so we can do a reset and stop the erase */
2929                                 cfi_write(map, CMD(0xF0), chip->start);
2930 -                printk( KERN_WARNING "Internal flash device timeout occured or write operation was performed while flash was erasing\n" );
2931 +                printk( KERN_WARNING "Internal flash device timeout pt B occured or write operation was performed while flash was erasing\n" );
2932                         }
2933                 }
2934          else
2935 diff -urN linux-mips/drivers/mtd/chips/cfi_probe.c mips-linux-2.4.25/drivers/mtd/chips/cfi_probe.c
2936 --- linux-mips/drivers/mtd/chips/cfi_probe.c    2005-12-24 15:11:25.103496432 +0000
2937 +++ mips-linux-2.4.25/drivers/mtd/chips/cfi_probe.c     2005-12-30 17:27:21.507145824 +0000
2938 @@ -51,7 +51,7 @@
2939                           struct flchip *chips, struct cfi_private *cfi)
2940  {
2941         int i;
2942 -       
2943 +
2944         if ((base + 0) >= map->size) {
2945                 printk(KERN_NOTICE
2946                         "Probe at base[0x00](0x%08lx) past the end of the map(0x%08lx)\n",
2947 @@ -221,12 +221,10 @@
2948  
2949  static void print_cfi_ident(struct cfi_ident *cfip)
2950  {
2951 -#if 0
2952         if (cfip->qry[0] != 'Q' || cfip->qry[1] != 'R' || cfip->qry[2] != 'Y') {
2953                 printk("Invalid CFI ident structure.\n");
2954                 return;
2955         }       
2956 -#endif         
2957         printk("Primary Vendor Command Set: %4.4X (%s)\n", cfip->P_ID, vendorname(cfip->P_ID));
2958         if (cfip->P_ADR)
2959                 printk("Primary Algorithm Table at %4.4X\n", cfip->P_ADR);
2960 diff -urN linux-mips/drivers/mtd/chips/jedec_probe.c mips-linux-2.4.25/drivers/mtd/chips/jedec_probe.c
2961 --- linux-mips/drivers/mtd/chips/jedec_probe.c  2005-12-24 15:11:25.126492936 +0000
2962 +++ mips-linux-2.4.25/drivers/mtd/chips/jedec_probe.c   2005-12-30 17:27:21.532142024 +0000
2963 @@ -104,6 +104,7 @@
2964  #define SST29LE512     0x003d
2965  #define SST39LF800     0x2781
2966  #define SST39LF160     0x2782
2967 +#define SST39LF1601    0x234b
2968  #define SST39LF512     0x00D4
2969  #define SST39LF010     0x00D5
2970  #define SST39LF020     0x00D6
2971 @@ -113,6 +114,8 @@
2972  #define SST49LF030A    0x001C
2973  #define SST49LF040A    0x0051
2974  #define SST49LF080A    0x005B
2975 +#define SST39VF3201     0x235B
2976 +#define SST39VF3202     0x235A
2977  
2978  /* Toshiba */
2979  #define TC58FVT160     0x00C2
2980 @@ -900,7 +903,43 @@
2981                 NumEraseRegions: 1,
2982                 regions: {ERASEINFO(0x01000,256),
2983                 }
2984 -       } 
2985 +       }, {
2986 +               mfr_id: MANUFACTURER_SST,
2987 +               dev_id: SST39LF160,
2988 +               name: "SST 39LF160",
2989 +               DevSize: SIZE_2MiB,
2990 +               CmdSet: P_ID_AMD_STD,
2991 +               NumEraseRegions: 1,
2992 +               regions: {ERASEINFO(0x01000,512),
2993 +               }
2994 +        }, {
2995 +               mfr_id: MANUFACTURER_SST,
2996 +               dev_id: SST39LF1601,
2997 +               name: "SST 39LF1601",
2998 +               DevSize: SIZE_2MiB,
2999 +               CmdSet: P_ID_AMD_STD,
3000 +               NumEraseRegions: 1,
3001 +               regions: {ERASEINFO(0x01000,512),
3002 +               }
3003 +        }, {
3004 +               mfr_id: MANUFACTURER_SST,
3005 +               dev_id: SST39VF3201,
3006 +               name: "SST 39VF3201",
3007 +               DevSize: SIZE_4MiB,
3008 +               CmdSet: P_ID_AMD_STD,
3009 +               NumEraseRegions: 1,
3010 +               regions: {ERASEINFO(0x01000,1024),
3011 +               }
3012 +        }, {
3013 +               mfr_id: MANUFACTURER_SST,
3014 +               dev_id: SST39VF3202,
3015 +               name: "SST 39VF3202",
3016 +               DevSize: SIZE_4MiB,
3017 +               CmdSet: P_ID_AMD_STD,
3018 +               NumEraseRegions: 1,
3019 +               regions: {ERASEINFO(0x01000,1024),
3020 +               }
3021 +        }
3022  };
3023  
3024  
3025 @@ -967,6 +1006,35 @@
3026         p_cfi->cfiq->DevSize = jedec_table[index].DevSize;
3027         p_cfi->cfi_mode = CFI_MODE_JEDEC;
3028  
3029 +       /*
3030 +        * Add the following code to set the flash timing parameters.
3031 +        * Maybe this is done in a table somwehere else? I can't find it.
3032 +        */
3033 +          
3034 +          
3035 +       switch(jedec_table[index].dev_id) {
3036 +       case SST39VF3201:
3037 +       case SST39VF3202:
3038 +               p_cfi->cfiq->WordWriteTimeoutTyp = 3;  /* 8 us */
3039 +               p_cfi->cfiq->WordWriteTimeoutMax = 4;  /* 16 us */
3040 +               p_cfi->cfiq->BlockEraseTimeoutTyp = 15; /* Actually 18ms, max 25 */
3041 +               p_cfi->cfiq->BlockEraseTimeoutMax =  15;  /*  Actually 25ms */ 
3042 +               p_cfi->cfiq->ChipEraseTimeoutTyp = 16;  /* Max is 50ms, typical is 40ms */
3043 +               p_cfi->cfiq->ChipEraseTimeoutMax = 16;
3044 +               break;
3045 +       case SST39LF160:
3046 +       case SST39LF1601:
3047 +               p_cfi->cfiq->WordWriteTimeoutTyp = 4;  /* 14 us */
3048 +               p_cfi->cfiq->WordWriteTimeoutMax = 5;  /* 20 us */
3049 +               p_cfi->cfiq->BlockEraseTimeoutTyp = 15; /* Actually 18ms, max 25 */
3050 +               p_cfi->cfiq->BlockEraseTimeoutMax =  15;  /*  Actually 25ms */ 
3051 +               p_cfi->cfiq->ChipEraseTimeoutTyp = 17;  /* Max is 70ms, typical is 40ms */
3052 +               p_cfi->cfiq->ChipEraseTimeoutMax = 17;
3053 +               break;
3054 +       }
3055 +
3056 +
3057 +
3058         for (i=0; i<num_erase_regions; i++){
3059                 p_cfi->cfiq->EraseRegionInfo[i] = jedec_table[index].regions[i];
3060         }
3061 diff -urN linux-mips/drivers/mtd/Config.in mips-linux-2.4.25/drivers/mtd/Config.in
3062 --- linux-mips/drivers/mtd/Config.in    2005-12-24 15:11:25.091498256 +0000
3063 +++ mips-linux-2.4.25/drivers/mtd/Config.in     2005-12-30 17:27:21.182195224 +0000
3064 @@ -14,6 +14,9 @@
3065     dep_tristate '  MTD partitioning support' CONFIG_MTD_PARTITIONS $CONFIG_MTD
3066     dep_tristate '  MTD concatenating support' CONFIG_MTD_CONCAT $CONFIG_MTD
3067     dep_tristate '  RedBoot partition table parsing' CONFIG_MTD_REDBOOT_PARTS $CONFIG_MTD_PARTITIONS
3068 +   if [ "$CONFIG_MTD_END_RESERVED" != "" ]; then
3069 +      define_int CONFIG_MTD_END_RESERVED $CONFIG_MTD_END_RESERVED
3070 +   fi
3071     dep_tristate '  Command line partition table parsing' CONFIG_MTD_CMDLINE_PARTS $CONFIG_MTD_PARTITIONS
3072     if [ "$CONFIG_ARM" = "y" ]; then
3073        dep_tristate '  ARM Firmware Suite partition parsing' CONFIG_MTD_AFS_PARTS $CONFIG_MTD_PARTITIONS
3074 diff -urN linux-mips/drivers/mtd/devices/Makefile mips-linux-2.4.25/drivers/mtd/devices/Makefile
3075 --- linux-mips/drivers/mtd/devices/Makefile     2005-12-24 15:11:25.128492632 +0000
3076 +++ mips-linux-2.4.25/drivers/mtd/devices/Makefile      2005-12-30 17:27:21.561137616 +0000
3077 @@ -22,5 +22,6 @@
3078  obj-$(CONFIG_MTD_MTDRAM)       += mtdram.o
3079  obj-$(CONFIG_MTD_LART)         += lart.o
3080  obj-$(CONFIG_MTD_BLKMTD)       += blkmtd.o
3081 +obj-$(CONFIG_MTD_SPIFLASH)      += spiflash.o
3082  
3083  include $(TOPDIR)/Rules.make
3084 diff -urN linux-mips/drivers/mtd/devices/spiflash.c mips-linux-2.4.25/drivers/mtd/devices/spiflash.c
3085 --- linux-mips/drivers/mtd/devices/spiflash.c   1970-01-01 01:00:00.000000000 +0100
3086 +++ mips-linux-2.4.25/drivers/mtd/devices/spiflash.c    2005-12-30 17:27:21.652123784 +0000
3087 @@ -0,0 +1,506 @@
3088 +
3089 +/*
3090 + * MTD driver for the SPI Flash Memory support.
3091 + *
3092 + * $Id: //depot/sw/releases/linuxsrc/src/kernels/mips-linux-2.4.25/drivers/mtd/devices/spiflash.c#3 $
3093 + *
3094 + *
3095 + * Copyright (c) 2005-2006 Atheros Communications Inc.
3096 + *
3097 + * This code is free software; you can redistribute it and/or modify
3098 + * it under the terms of the GNU General Public License version 2 as
3099 + * published by the Free Software Foundation.
3100 + *
3101 + */
3102 +
3103 +/*===========================================================================
3104 +** !!!!  VERY IMPORTANT NOTICE !!!!  FLASH DATA STORED IN LITTLE ENDIAN FORMAT
3105 +**
3106 +** This module contains the Serial Flash access routines for the Atheros SOC.
3107 +** The Atheros SOC integrates a SPI flash controller that is used to access
3108 +** serial flash parts. The SPI flash controller executes in "Little Endian"
3109 +** mode. THEREFORE, all WRITES and READS from the MIPS CPU must be
3110 +** BYTESWAPPED! The SPI Flash controller hardware by default performs READ
3111 +** ONLY byteswapping when accessed via the SPI Flash Alias memory region
3112 +** (Physical Address 0x0800_0000 - 0x0fff_ffff). The data stored in the
3113 +** flash sectors is stored in "Little Endian" format.
3114 +**
3115 +** The spiflash_write() routine performs byteswapping on all write
3116 +** operations.
3117 +**===========================================================================*/
3118 +
3119 +#include <linux/kernel.h>
3120 +#include <linux/module.h>
3121 +#include <linux/types.h>
3122 +#include <linux/version.h>
3123 +#include <linux/errno.h>
3124 +#include <linux/slab.h>
3125 +#include <linux/mtd/mtd.h>
3126 +#include <linux/mtd/partitions.h>
3127 +#include <asm/delay.h>
3128 +#include <asm/io.h>
3129 +#include "spiflash.h"
3130 +
3131 +/* debugging */
3132 +/* #define SPIFLASH_DEBUG */
3133 +
3134 +#ifndef __BIG_ENDIAN
3135 +#error This driver currently only works with big endian CPU.
3136 +#endif
3137 +
3138 +static char module_name[] = "spiflash";
3139 +
3140 +#define MIN(a,b)        ((a) < (b) ? (a) : (b))
3141 +#define FALSE  0
3142 +#define TRUE   1
3143 +
3144 +#define ROOTFS_NAME    "rootfs"
3145 +
3146 +static __u32 spiflash_regread32(int reg);
3147 +static void spiflash_regwrite32(int reg, __u32 data);
3148 +static __u32 spiflash_sendcmd (int op);
3149 +
3150 +int __init spiflash_init (void);
3151 +void __exit spiflash_exit (void);
3152 +static int spiflash_probe (void);
3153 +static int spiflash_erase (struct mtd_info *mtd,struct erase_info *instr);
3154 +static int spiflash_read (struct mtd_info *mtd, loff_t from,size_t len,size_t *retlen,u_char *buf);
3155 +static int spiflash_write (struct mtd_info *mtd,loff_t to,size_t len,size_t *retlen,const u_char *buf);
3156 +
3157 +/* Flash configuration table */
3158 +struct flashconfig {
3159 +    __u32 byte_cnt;
3160 +    __u32 sector_cnt;
3161 +    __u32 sector_size;
3162 +    __u32 cs_addrmask;
3163 +} flashconfig_tbl[MAX_FLASH] =
3164 +    {
3165 +        { 0, 0, 0, 0},
3166 +        { STM_1MB_BYTE_COUNT, STM_1MB_SECTOR_COUNT, STM_1MB_SECTOR_SIZE, 0x0},
3167 +        { STM_2MB_BYTE_COUNT, STM_2MB_SECTOR_COUNT, STM_2MB_SECTOR_SIZE, 0x0},
3168 +        { STM_4MB_BYTE_COUNT, STM_4MB_SECTOR_COUNT, STM_4MB_SECTOR_SIZE, 0x0}
3169 +    };
3170 +
3171 +/* Mapping of generic opcodes to STM serial flash opcodes */
3172 +struct opcodes {
3173 +    __u16 code;
3174 +    __s8 tx_cnt;
3175 +    __s8 rx_cnt;
3176 +} stm_opcodes[] = {
3177 +        {STM_OP_WR_ENABLE, 1, 0},
3178 +        {STM_OP_WR_DISABLE, 1, 0},
3179 +        {STM_OP_RD_STATUS, 1, 1},
3180 +        {STM_OP_WR_STATUS, 1, 0},
3181 +        {STM_OP_RD_DATA, 4, 4},
3182 +        {STM_OP_FAST_RD_DATA, 1, 0},
3183 +        {STM_OP_PAGE_PGRM, 8, 0},
3184 +        {STM_OP_SECTOR_ERASE, 4, 0},
3185 +        {STM_OP_BULK_ERASE, 1, 0},
3186 +        {STM_OP_DEEP_PWRDOWN, 1, 0},
3187 +        {STM_OP_RD_SIG, 4, 1}
3188 +};
3189 +
3190 +/* Driver private data structure */
3191 +struct spiflash_data {
3192 +       struct  mtd_info       *mtd;    
3193 +       struct  mtd_partition  *parsed_parts;     /* parsed partitions */
3194 +       void    *spiflash_readaddr; /* memory mapped data for read  */
3195 +       void    *spiflash_mmraddr;  /* memory mapped register space */
3196 +};
3197 +
3198 +static struct spiflash_data *spidata;
3199 +
3200 +extern int parse_redboot_partitions(struct mtd_info *master, struct mtd_partition **pparts);
3201 +
3202 +/***************************************************************************************************/
3203 +
3204 +static __u32
3205 +spiflash_regread32(int reg)
3206 +{
3207 +       volatile __u32 *data = (__u32 *)(spidata->spiflash_mmraddr + reg);
3208 +
3209 +       return (*data);
3210 +}
3211 +
3212 +static void 
3213 +spiflash_regwrite32(int reg, __u32 data)
3214 +{
3215 +       volatile __u32 *addr = (__u32 *)(spidata->spiflash_mmraddr + reg);
3216 +
3217 +       *addr = data;
3218 +       return;
3219 +}
3220 +
3221 +static __u32 
3222 +spiflash_sendcmd (int op)
3223 +{
3224 +        __u32 reg;
3225 +        __u32 mask;
3226 +       struct opcodes *ptr_opcode;
3227 +
3228 +       ptr_opcode = &stm_opcodes[op];
3229 +
3230 +       do {
3231 +               reg = spiflash_regread32(SPI_FLASH_CTL);
3232 +       } while (reg & SPI_CTL_BUSY);
3233 +
3234 +       spiflash_regwrite32(SPI_FLASH_OPCODE, ptr_opcode->code);
3235 +
3236 +       reg = (reg & ~SPI_CTL_TX_RX_CNT_MASK) | ptr_opcode->tx_cnt |
3237 +               (ptr_opcode->rx_cnt << 4) | SPI_CTL_START;
3238 +
3239 +       spiflash_regwrite32(SPI_FLASH_CTL, reg);
3240
3241 +       if (ptr_opcode->rx_cnt > 0) {
3242 +               do {
3243 +                       reg = spiflash_regread32(SPI_FLASH_CTL);
3244 +               } while (reg & SPI_CTL_BUSY);
3245 +
3246 +               reg = (__u32) spiflash_regread32(SPI_FLASH_DATA);
3247 +
3248 +               switch (ptr_opcode->rx_cnt) {
3249 +               case 1:
3250 +                       mask = 0x000000ff;
3251 +                       break;
3252 +               case 2:
3253 +                       mask = 0x0000ffff;
3254 +                       break;
3255 +               case 3:
3256 +                       mask = 0x00ffffff;
3257 +                       break;
3258 +               default:
3259 +                       mask = 0xffffffff;
3260 +                       break;
3261 +               }
3262 +
3263 +               reg &= mask;
3264 +       }
3265 +       else {
3266 +                       reg = 0;
3267 +       }
3268 +
3269 +       return reg;
3270 +}
3271 +
3272 +/* Probe SPI flash device
3273 + * Function returns 0 for failure.
3274 + * and flashconfig_tbl array index for success.
3275 + */
3276 +static int 
3277 +spiflash_probe (void)
3278 +{
3279 +       __u32 sig;
3280 +       int flash_size;
3281 +
3282 +       /* Read the signature on the flash device */
3283 +       sig = spiflash_sendcmd(SPI_RD_SIG);
3284 +
3285 +       switch (sig) {
3286 +       case STM_8MBIT_SIGNATURE:
3287 +               flash_size = FLASH_1MB;
3288 +               break;
3289 +        case STM_16MBIT_SIGNATURE:
3290 +               flash_size = FLASH_2MB;
3291 +               break;
3292 +        case STM_32MBIT_SIGNATURE:
3293 +               flash_size = FLASH_4MB;
3294 +               break;
3295 +        default:
3296 +               printk (KERN_WARNING "%s: Read of flash device signature failed!\n", module_name);
3297 +               return (0);
3298 +       }
3299 +
3300 +       return (flash_size);
3301 +}
3302 +
3303 +
3304 +static int 
3305 +spiflash_erase (struct mtd_info *mtd,struct erase_info *instr)
3306 +{
3307 +       struct opcodes *ptr_opcode;
3308 +       __u32 temp, reg;
3309 +       int finished = FALSE;
3310 +
3311 +#ifdef SPIFLASH_DEBUG
3312 +       printk (KERN_DEBUG "%s(addr = 0x%.8x, len = %d)\n",__FUNCTION__,instr->addr,instr->len);
3313 +#endif
3314 +
3315 +       /* sanity checks */
3316 +       if (instr->addr + instr->len > mtd->size) return (-EINVAL);
3317 +
3318 +       ptr_opcode = &stm_opcodes[SPI_SECTOR_ERASE];
3319 +
3320 +       temp = ((__u32)instr->addr << 8) | (__u32)(ptr_opcode->code);
3321 +       spiflash_sendcmd(SPI_WRITE_ENABLE);
3322 +       do {
3323 +               reg = spiflash_regread32(SPI_FLASH_CTL);
3324 +       } while (reg & SPI_CTL_BUSY);
3325 +
3326 +       spiflash_regwrite32(SPI_FLASH_OPCODE, temp);
3327 +
3328 +       reg = (reg & ~SPI_CTL_TX_RX_CNT_MASK) | ptr_opcode->tx_cnt | SPI_CTL_START;
3329 +       spiflash_regwrite32(SPI_FLASH_CTL, reg);
3330 +
3331 +       do {
3332 +               reg = spiflash_sendcmd(SPI_RD_STATUS);
3333 +               if (!(reg & SPI_STATUS_WIP)) {
3334 +                       finished = TRUE;
3335 +               }
3336 +       } while (!finished);
3337 +
3338 +       instr->state = MTD_ERASE_DONE;
3339 +       if (instr->callback) instr->callback (instr);
3340 +
3341 +#ifdef SPIFLASH_DEBUG
3342 +       printk (KERN_DEBUG "%s return\n",__FUNCTION__);
3343 +#endif
3344 +       return (0);
3345 +}
3346 +
3347 +static int 
3348 +spiflash_read (struct mtd_info *mtd, loff_t from,size_t len,size_t *retlen,u_char *buf)
3349 +{
3350 +       u_char  *read_addr;
3351 +
3352 +#ifdef SPIFLASH_DEBUG
3353 +       printk (KERN_DEBUG "%s(from = 0x%.8x, len = %d)\n",__FUNCTION__,(__u32) from,(int)len);  
3354 +#endif
3355 +
3356 +       /* sanity checks */
3357 +       if (!len) return (0);
3358 +       if (from + len > mtd->size) return (-EINVAL);
3359 +       
3360 +
3361 +       /* we always read len bytes */
3362 +       *retlen = len;
3363 +
3364 +       read_addr = (u_char *)(spidata->spiflash_readaddr + from);
3365 +       memcpy(buf, read_addr, len);
3366 +
3367 +       return (0);
3368 +}
3369 +
3370 +static int 
3371 +spiflash_write (struct mtd_info *mtd,loff_t to,size_t len,size_t *retlen,const u_char *buf)
3372 +{
3373 +       int done = FALSE, page_offset, bytes_left, finished;
3374 +       __u32 xact_len, spi_data = 0, opcode, reg;
3375 +
3376 +#ifdef SPIFLASH_DEBUG
3377 +       printk (KERN_DEBUG "%s(to = 0x%.8x, len = %d)\n",__FUNCTION__,(__u32) to,len); 
3378 +#endif
3379 +
3380 +       *retlen = 0;
3381 +       
3382 +       /* sanity checks */
3383 +       if (!len) return (0);
3384 +       if (to + len > mtd->size) return (-EINVAL);
3385 +       
3386 +       opcode = stm_opcodes[SPI_PAGE_PROGRAM].code;
3387 +       bytes_left = len;
3388 +       
3389 +       while (done == FALSE) {
3390 +               xact_len = MIN(bytes_left, sizeof(__u32));
3391 +
3392 +               /* 32-bit writes cannot span across a page boundary
3393 +                * (256 bytes). This types of writes require two page
3394 +                * program operations to handle it correctly. The STM part
3395 +                * will write the overflow data to the beginning of the
3396 +                * current page as opposed to the subsequent page.
3397 +                */
3398 +               page_offset = (to & (STM_PAGE_SIZE - 1)) + xact_len;
3399 +
3400 +               if (page_offset > STM_PAGE_SIZE) {
3401 +                       xact_len -= (page_offset - STM_PAGE_SIZE);
3402 +               }
3403 +
3404 +               spiflash_sendcmd(SPI_WRITE_ENABLE);
3405 +
3406 +               do {
3407 +                       reg = spiflash_regread32(SPI_FLASH_CTL);
3408 +               } while (reg & SPI_CTL_BUSY);
3409 +       
3410 +               switch (xact_len) {
3411 +                       case 1:
3412 +                               (__u8)spi_data = *buf;
3413 +                               break;
3414 +                       case 2:
3415 +                               spi_data = (buf[1] << 8) | buf[0];
3416 +                               break;
3417 +                       case 3:
3418 +                               spi_data = (buf[2] << 16) | (buf[1] << 8) | buf[0];
3419 +                               break;
3420 +                       case 4:
3421 +                               spi_data = (buf[3] << 24) | (buf[2] << 16) | 
3422 +                                                       (buf[1] << 8) | buf[0];
3423 +                               break;
3424 +                       default:
3425 +                               printk("spiflash_write: default case\n");
3426 +                               break;
3427 +               }
3428 +
3429 +               spiflash_regwrite32(SPI_FLASH_DATA, spi_data);
3430 +               opcode = (opcode & SPI_OPCODE_MASK) | ((__u32)to << 8);
3431 +               spiflash_regwrite32(SPI_FLASH_OPCODE, opcode);
3432 +
3433 +               reg = (reg & ~SPI_CTL_TX_RX_CNT_MASK) | (xact_len + 4) | SPI_CTL_START;
3434 +               spiflash_regwrite32(SPI_FLASH_CTL, reg);
3435 +               finished = FALSE;
3436 +               
3437 +               do {
3438 +                       udelay(1);
3439 +                       reg = spiflash_sendcmd(SPI_RD_STATUS);
3440 +                       if (!(reg & SPI_STATUS_WIP)) {
3441 +                               finished = TRUE;
3442 +                       }
3443 +               } while (!finished);
3444 +
3445 +               bytes_left -= xact_len;
3446 +               to += xact_len;
3447 +               buf += xact_len;
3448 +
3449 +               *retlen += xact_len;
3450 +
3451 +               if (bytes_left == 0) {
3452 +                       done = TRUE;
3453 +               }
3454 +       }
3455 +
3456 +       return (0);
3457 +}
3458 +
3459 +
3460 +int __init 
3461 +spiflash_init (void)
3462 +{
3463 +       int result, i;
3464 +       int index, num_parts;
3465 +       struct mtd_info *mtd;
3466 +       struct  mtd_partition  *mtd_parts;
3467 +
3468 +       spidata = kmalloc(sizeof(struct spiflash_data), GFP_KERNEL);
3469 +       if (!spidata)
3470 +               return (-ENXIO);
3471 +
3472 +       spidata->spiflash_mmraddr = ioremap_nocache(SPI_FLASH_MMR, SPI_FLASH_MMR_SIZE);
3473 +       if (!spidata->spiflash_mmraddr) {
3474 +                       printk (KERN_WARNING "%s: Failed to map flash device\n", module_name);
3475 +               kfree(spidata);
3476 +                       return (-ENXIO);
3477 +       }
3478 +
3479 +       mtd = kmalloc(sizeof(struct mtd_info), GFP_KERNEL);
3480 +       if (!mtd) {
3481 +               kfree(spidata);
3482 +               return (-ENXIO);
3483 +       }
3484 +       
3485 +       memset (mtd,0,sizeof (*mtd));
3486 +       
3487 +       printk ("MTD driver for SPI flash.\n");
3488 +       printk ("%s: Probing for Serial flash ...\n", module_name);
3489 +       if (!(index = spiflash_probe ())) {
3490 +                       printk (KERN_WARNING "%s: Found no serial flash device\n", module_name);
3491 +               kfree(mtd);
3492 +               kfree(spidata);
3493 +                       return (-ENXIO);
3494 +       }
3495 +       printk ("%s: Found SPI serial Flash.\n", module_name);
3496 +       printk ("%d: size\n", flashconfig_tbl[index].byte_cnt);
3497 +
3498 +       spidata->spiflash_readaddr = ioremap_nocache(SPI_FLASH_READ, flashconfig_tbl[index].byte_cnt);
3499 +       if (!spidata->spiflash_readaddr) {
3500 +                       printk (KERN_WARNING "%s: Failed to map flash device\n", module_name);
3501 +               kfree(mtd);
3502 +               kfree(spidata);
3503 +                       return (-ENXIO);
3504 +       }
3505 +
3506 +       mtd->name = module_name;
3507 +       mtd->type = MTD_NORFLASH;
3508 +       mtd->flags = (MTD_CAP_NORFLASH|MTD_WRITEABLE);
3509 +       mtd->size = flashconfig_tbl[index].byte_cnt;
3510 +       mtd->erasesize = flashconfig_tbl[index].sector_size;
3511 +       mtd->numeraseregions = 0;
3512 +       mtd->eraseregions = NULL;
3513 +       mtd->module = THIS_MODULE;
3514 +       mtd->erase = spiflash_erase;
3515 +       mtd->read = spiflash_read;
3516 +       mtd->write = spiflash_write;
3517 +       
3518 +#ifdef SPIFLASH_DEBUG
3519 +       printk (KERN_DEBUG
3520 +                  "mtd->name = %s\n"
3521 +                  "mtd->size = 0x%.8x (%uM)\n"
3522 +                  "mtd->erasesize = 0x%.8x (%uK)\n"
3523 +                  "mtd->numeraseregions = %d\n",
3524 +                  mtd->name,
3525 +                  mtd->size, mtd->size / (1024*1024),
3526 +                  mtd->erasesize, mtd->erasesize / 1024,
3527 +                  mtd->numeraseregions);
3528 +
3529 +       if (mtd->numeraseregions) {
3530 +               for (result = 0; result < mtd->numeraseregions; result++) {
3531 +                       printk (KERN_DEBUG
3532 +                          "\n\n"
3533 +                          "mtd->eraseregions[%d].offset = 0x%.8x\n"
3534 +                          "mtd->eraseregions[%d].erasesize = 0x%.8x (%uK)\n"
3535 +                          "mtd->eraseregions[%d].numblocks = %d\n",
3536 +                          result,mtd->eraseregions[result].offset,
3537 +                          result,mtd->eraseregions[result].erasesize,mtd->eraseregions[result].erasesize / 1024,
3538 +                          result,mtd->eraseregions[result].numblocks);
3539 +               }
3540 +       }
3541 +#endif
3542 +
3543 +#ifndef CONFIG_BLK_DEV_INITRD
3544 +       /* parse redboot partitions */
3545 +       num_parts = parse_redboot_partitions(mtd, &spidata->parsed_parts);
3546 +
3547 +#ifdef SPIFLASH_DEBUG
3548 +       printk (KERN_DEBUG "Found %d redboot partitions\n", num_parts);
3549 +#endif
3550 +
3551 +       if (num_parts) {
3552 +               result = add_mtd_partitions(mtd, spidata->parsed_parts, num_parts);
3553 +               /* Find root partition */
3554 +               mtd_parts = spidata->parsed_parts;
3555 +               for (i=0; i < num_parts; i++) {
3556 +                       if (!strcmp(mtd_parts[i].name, ROOTFS_NAME)) {
3557 +                               /* Create root device */
3558 +                               ROOT_DEV = MKDEV(MTD_BLOCK_MAJOR, i);
3559 +                               break;
3560 +                       }
3561 +               }
3562 +       } else {
3563 +#ifdef SPIFLASH_DEBUG
3564 +       printk (KERN_DEBUG "Did not find any redboot partitions\n");
3565 +#endif
3566 +               kfree(mtd);
3567 +               kfree(spidata);
3568 +                       return (-ENXIO);
3569 +       }
3570 +#endif
3571 +
3572 +       spidata->mtd = mtd;
3573 +
3574 +       return (result);
3575 +}
3576 +
3577 +void __exit 
3578 +spiflash_exit (void)
3579 +{
3580 +       if (spidata && spidata->parsed_parts) {
3581 +               del_mtd_partitions (spidata->mtd);
3582 +               kfree(spidata->mtd);
3583 +               kfree(spidata);
3584 +       }
3585 +}
3586 +
3587 +module_init (spiflash_init);
3588 +module_exit (spiflash_exit);
3589 +
3590 +MODULE_LICENSE("GPL");
3591 +MODULE_AUTHOR("Atheros Communications Inc");
3592 +MODULE_DESCRIPTION("MTD driver for SPI Flash on Atheros SOC");
3593 +
3594 diff -urN linux-mips/drivers/mtd/devices/spiflash.h mips-linux-2.4.25/drivers/mtd/devices/spiflash.h
3595 --- linux-mips/drivers/mtd/devices/spiflash.h   1970-01-01 01:00:00.000000000 +0100
3596 +++ mips-linux-2.4.25/drivers/mtd/devices/spiflash.h    2005-12-30 17:27:21.652123784 +0000
3597 @@ -0,0 +1,113 @@
3598 +/*
3599 + * SPI Flash Memory support header file.
3600 + *
3601 + * $Id: //depot/sw/releases/linuxsrc/src/kernels/mips-linux-2.4.25/drivers/mtd/devices/spiflash.h#3 $
3602 + *
3603 + *
3604 + * Copyright (c) 2005, Atheros Communications Inc.
3605 + *
3606 + * This code is free software; you can redistribute it and/or modify
3607 + * it under the terms of the GNU General Public License version 2 as
3608 + * published by the Free Software Foundation.
3609 + *
3610 + */
3611 +#define FLASH_1MB  1
3612 +#define FLASH_2MB  2
3613 +#define FLASH_4MB  3
3614 +#define MAX_FLASH  4
3615 +
3616 +#define STM_PAGE_SIZE           256
3617 +
3618 +#define STM_8MBIT_SIGNATURE     0x13
3619 +#define STM_M25P80_BYTE_COUNT   1048576
3620 +#define STM_M25P80_SECTOR_COUNT 16
3621 +#define STM_M25P80_SECTOR_SIZE  0x10000
3622 +
3623 +#define STM_16MBIT_SIGNATURE    0x14
3624 +#define STM_M25P16_BYTE_COUNT   2097152
3625 +#define STM_M25P16_SECTOR_COUNT 32
3626 +#define STM_M25P16_SECTOR_SIZE  0x10000
3627 +
3628 +#define STM_32MBIT_SIGNATURE    0x15
3629 +#define STM_M25P32_BYTE_COUNT   4194304
3630 +#define STM_M25P32_SECTOR_COUNT 64
3631 +#define STM_M25P32_SECTOR_SIZE  0x10000
3632 +
3633 +#define STM_1MB_BYTE_COUNT   STM_M25P80_BYTE_COUNT
3634 +#define STM_1MB_SECTOR_COUNT STM_M25P80_SECTOR_COUNT
3635 +#define STM_1MB_SECTOR_SIZE  STM_M25P80_SECTOR_SIZE
3636 +#define STM_2MB_BYTE_COUNT   STM_M25P16_BYTE_COUNT
3637 +#define STM_2MB_SECTOR_COUNT STM_M25P16_SECTOR_COUNT
3638 +#define STM_2MB_SECTOR_SIZE  STM_M25P16_SECTOR_SIZE
3639 +#define STM_4MB_BYTE_COUNT   STM_M25P32_BYTE_COUNT
3640 +#define STM_4MB_SECTOR_COUNT STM_M25P32_SECTOR_COUNT
3641 +#define STM_4MB_SECTOR_SIZE  STM_M25P32_SECTOR_SIZE
3642 +
3643 +#define SPI_WRITE_ENABLE    0
3644 +#define SPI_WRITE_DISABLE   1
3645 +#define SPI_RD_STATUS       2
3646 +#define SPI_WR_STATUS       3
3647 +#define SPI_RD_DATA         4
3648 +#define SPI_FAST_RD_DATA    5
3649 +#define SPI_PAGE_PROGRAM    6
3650 +#define SPI_SECTOR_ERASE    7
3651 +#define SPI_BULK_ERASE      8
3652 +#define SPI_DEEP_PWRDOWN    9
3653 +#define SPI_RD_SIG          10
3654 +#define SPI_MAX_OPCODES     11
3655 +
3656 +#define SFI_WRITE_BUFFER_SIZE   4
3657 +#define SFI_FLASH_ADDR_MASK     0x00ffffff
3658 +
3659 +/*
3660 + * ST Microelectronics Opcodes for Serial Flash
3661 + */
3662 +
3663 +#define STM_OP_WR_ENABLE       0x06     /* Write Enable */
3664 +#define STM_OP_WR_DISABLE      0x04     /* Write Disable */
3665 +#define STM_OP_RD_STATUS       0x05     /* Read Status */
3666 +#define STM_OP_WR_STATUS       0x01     /* Write Status */
3667 +#define STM_OP_RD_DATA         0x03     /* Read Data */
3668 +#define STM_OP_FAST_RD_DATA    0x0b     /* Fast Read Data */
3669 +#define STM_OP_PAGE_PGRM       0x02     /* Page Program */
3670 +#define STM_OP_SECTOR_ERASE    0xd8     /* Sector Erase */
3671 +#define STM_OP_BULK_ERASE      0xc7     /* Bulk Erase */
3672 +#define STM_OP_DEEP_PWRDOWN    0xb9     /* Deep Power-Down Mode */
3673 +#define STM_OP_RD_SIG          0xab     /* Read Electronic Signature */
3674 +
3675 +#define STM_STATUS_WIP       0x01       /* Write-In-Progress */
3676 +#define STM_STATUS_WEL       0x02       /* Write Enable Latch */
3677 +#define STM_STATUS_BP0       0x04       /* Block Protect 0 */
3678 +#define STM_STATUS_BP1       0x08       /* Block Protect 1 */
3679 +#define STM_STATUS_BP2       0x10       /* Block Protect 2 */
3680 +#define STM_STATUS_SRWD      0x80       /* Status Register Write Disable */
3681 +
3682 +/*
3683 + * SPI Flash Interface Registers
3684 + */
3685 +#define AR531XPLUS_SPI_READ     0x1fc00000
3686 +#define AR531XPLUS_SPI_MMR      0x11300000
3687 +#define AR531XPLUS_SPI_MMR_SIZE 12
3688 +
3689 +#define AR531XPLUS_SPI_CTL      0x00
3690 +#define AR531XPLUS_SPI_OPCODE   0x04
3691 +#define AR531XPLUS_SPI_DATA     0x08
3692 +
3693 +#define SPI_FLASH_READ          AR531XPLUS_SPI_READ
3694 +#define SPI_FLASH_MMR           AR531XPLUS_SPI_MMR
3695 +#define SPI_FLASH_MMR_SIZE      AR531XPLUS_SPI_MMR_SIZE
3696 +#define SPI_FLASH_CTL           AR531XPLUS_SPI_CTL
3697 +#define SPI_FLASH_OPCODE        AR531XPLUS_SPI_OPCODE
3698 +#define SPI_FLASH_DATA          AR531XPLUS_SPI_DATA
3699 +
3700 +#define SPI_CTL_START           0x00000100
3701 +#define SPI_CTL_BUSY            0x00010000
3702 +#define SPI_CTL_TXCNT_MASK      0x0000000f
3703 +#define SPI_CTL_RXCNT_MASK      0x000000f0
3704 +#define SPI_CTL_TX_RX_CNT_MASK  0x000000ff
3705 +#define SPI_CTL_SIZE_MASK       0x00060000
3706 +
3707 +#define SPI_CTL_CLK_SEL_MASK    0x03000000
3708 +#define SPI_OPCODE_MASK         0x000000ff
3709 +
3710 +#define SPI_STATUS_WIP         STM_STATUS_WIP
3711 diff -urN linux-mips/drivers/mtd/maps/Config.in mips-linux-2.4.25/drivers/mtd/maps/Config.in
3712 --- linux-mips/drivers/mtd/maps/Config.in       2005-12-24 15:11:25.158488072 +0000
3713 +++ mips-linux-2.4.25/drivers/mtd/maps/Config.in        2005-12-30 17:27:21.660122568 +0000
3714 @@ -9,7 +9,14 @@
3715  dep_tristate '  CFI Flash device in physical memory map' CONFIG_MTD_PHYSMAP $CONFIG_MTD_GEN_PROBE
3716  if [ "$CONFIG_MTD_PHYSMAP" = "y" -o "$CONFIG_MTD_PHYSMAP" = "m" ]; then
3717     hex '    Physical start address of flash mapping' CONFIG_MTD_PHYSMAP_START 0x8000000
3718 -   hex '    Physical length of flash mapping' CONFIG_MTD_PHYSMAP_LEN 0x4000000
3719 +   if [ "$CONFIG_FLASH_2MB" = "y" ]; then
3720 +       define_hex CONFIG_MTD_PHYSMAP_LEN 200000
3721 +   fi  
3722 +   if [ "$CONFIG_FLASH_4MB" = "y" ]; then
3723 +       define_hex CONFIG_MTD_PHYSMAP_LEN 400000
3724 +   fi  
3725 +
3726 +#   hex '    Physical length of flash mapping' CONFIG_MTD_PHYSMAP_LEN 0x4000000
3727     int '    Bus width in octets' CONFIG_MTD_PHYSMAP_BUSWIDTH 2
3728  fi
3729  
3730 diff -urN linux-mips/drivers/mtd/maps/physmap.c mips-linux-2.4.25/drivers/mtd/maps/physmap.c
3731 --- linux-mips/drivers/mtd/maps/physmap.c       2005-12-24 15:11:25.217479104 +0000
3732 +++ mips-linux-2.4.25/drivers/mtd/maps/physmap.c        2005-12-30 17:27:22.044064200 +0000
3733 @@ -80,12 +80,25 @@
3734  };
3735  
3736  #ifdef CONFIG_MTD_PARTITIONS
3737 -#ifdef CONFIG_MTD_CMDLINE_PARTS
3738 +#if defined(CONFIG_MTD_CMDLINE_PARTS) || defined(CONFIG_MTD_REDBOOT_PARTS)
3739  static struct mtd_partition *mtd_parts = 0;
3740  static int                   mtd_parts_nb = 0;
3741  #else
3742  static struct mtd_partition physmap_partitions[] = {
3743  /* Put your own partition definitions here */
3744 +    {
3745 +        name:   "rootfs",
3746 +#ifdef CONFIG_FLASH_2MB
3747 +        size:   0x000e0000,
3748 +       offset: 0x000f0000,
3749 +#endif
3750 +#ifdef CONFIG_FLASH_4MB
3751 +        size:   0x002dd000,
3752 +        offset: 0x00100000,
3753 +#endif
3754 +
3755 +        /* Allow file system to be mounted for writing */
3756 +    }
3757  #if 0
3758         {
3759                 name:           "bootROM",
3760 @@ -138,6 +151,22 @@
3761  
3762                 add_mtd_device(mymtd);
3763  #ifdef CONFIG_MTD_PARTITIONS
3764 +#ifdef CONFIG_MTD_REDBOOT_PARTS
3765 +                {
3766 +                    extern int parse_redboot_partitions(struct mtd_info *master,
3767 +                                        struct mtd_partition **pparts);
3768 +
3769 +                    struct mtd_partition *rb_parts = 0;
3770 +                    int rb_parts_nb = 0;
3771 +
3772 +                   rb_parts_nb = parse_redboot_partitions(mymtd, &rb_parts);
3773 +                   if (rb_parts_nb > 0) {
3774 +                        printk(KERN_NOTICE
3775 +                               "Using redboot flash partitioning");
3776 +                       add_mtd_partitions (mymtd, rb_parts, rb_parts_nb);
3777 +                   }
3778 +                }
3779 +#endif
3780  #ifdef CONFIG_MTD_CMDLINE_PARTS
3781                 mtd_parts_nb = parse_cmdline_partitions(mymtd, &mtd_parts, 
3782                                                         "phys");
3783 @@ -147,7 +176,8 @@
3784                                "Using command line partition definition\n");
3785                         add_mtd_partitions (mymtd, mtd_parts, mtd_parts_nb);
3786                 }
3787 -#else
3788 +#endif
3789 +#if !defined(CONFIG_MTD_CMDLINE_PARTS) && !defined(CONFIG_MTD_REDBOOT_PARTS)
3790                 if (NUM_PARTITIONS != 0) 
3791                 {
3792                         printk(KERN_NOTICE 
3793 diff -urN linux-mips/drivers/mtd/redboot.c mips-linux-2.4.25/drivers/mtd/redboot.c
3794 --- linux-mips/drivers/mtd/redboot.c    2005-12-24 15:11:25.249474240 +0000
3795 +++ mips-linux-2.4.25/drivers/mtd/redboot.c     2005-12-30 17:27:22.517992152 +0000
3796 @@ -51,8 +51,14 @@
3797                 return -ENOMEM;
3798  
3799         /* Read the start of the last erase block */
3800 -       ret = master->read(master, master->size - master->erasesize,
3801 +        {
3802 +        u_int32_t part_table_start = master->size - master->erasesize;
3803 +#if defined(CONFIG_MTD_END_RESERVED)
3804 +        part_table_start -= CONFIG_MTD_END_RESERVED;
3805 +#endif
3806 +       ret = master->read(master, part_table_start,
3807                            PAGE_SIZE, &retlen, (void *)buf);
3808 +        }
3809  
3810         if (ret)
3811                 goto out;
3812 diff -urN linux-mips/drivers/net/Config.in mips-linux-2.4.25/drivers/net/Config.in
3813 --- linux-mips/drivers/net/Config.in    2005-12-24 15:11:25.725401888 +0000
3814 +++ mips-linux-2.4.25/drivers/net/Config.in     2005-12-30 17:27:22.684966768 +0000
3815 @@ -24,6 +24,18 @@
3816  comment 'Ethernet (10 or 100Mbit)'
3817  bool 'Ethernet (10 or 100Mbit)' CONFIG_NET_ETHERNET
3818  if [ "$CONFIG_NET_ETHERNET" = "y" ]; then
3819 +   define_bool CONFIG_VENETDEV n
3820 +   tristate ' BUILT-IN ATHEROS ENET DRIVER' CONFIG_NET_ATHEROS_ETHER
3821 +   if [ "$CONFIG_AP38" = "y" -o "$CONFIG_AP48" = "y"  ]; then
3822 +      define_bool CONFIG_KENDIN_ENET_PHY y
3823 +   elif [ "$CONFIG_AP30ASK" = "y" ]; then
3824 +      define_bool CONFIG_KENDIN_KS8995XA_ENET_PHY y
3825 +      bool 'Multiple Ethernet address hack ' CONFIG_ASK_MULT_MAC_HACK
3826 +   elif [ "$CONFIG_AP51" = "y" ]; then
3827 +      define_bool CONFIG_ICPLUS_ENET_PHY y
3828 +   else
3829 +      define_bool CONFIG_MARVELL_ENET_PHY y
3830 +   fi
3831     if [ "$CONFIG_ARM" = "y" ]; then  
3832        dep_bool '  ARM EBSA110 AM79C961A support' CONFIG_ARM_AM79C961A $CONFIG_ARCH_EBSA110
3833        tristate '  Cirrus Logic CS8900A support' CONFIG_ARM_CIRRUS
3834 diff -urN linux-mips/drivers/net/Makefile mips-linux-2.4.25/drivers/net/Makefile
3835 --- linux-mips/drivers/net/Makefile     2005-12-24 15:11:25.726401736 +0000
3836 +++ mips-linux-2.4.25/drivers/net/Makefile      2005-12-30 17:27:22.709962968 +0000
3837 @@ -31,6 +31,10 @@
3838    obj-y += e1000/e1000.o
3839  endif
3840  
3841 +ifeq ($(CONFIG_NET_ATHEROS_ETHER),y)
3842 +  obj-y += ath/ae531x.o
3843 +endif
3844 +
3845  ifeq ($(CONFIG_BONDING),y)
3846    obj-y += bonding/bonding.o
3847  endif
3848 @@ -53,8 +57,13 @@
3849  subdir-$(CONFIG_SKFP) += skfp
3850  subdir-$(CONFIG_E100) += e100
3851  subdir-$(CONFIG_E1000) += e1000
3852 +subdir-$(CONFIG_NET_ATHEROS_ETHER) += ath
3853  subdir-$(CONFIG_BONDING) += bonding
3854  
3855 +ifeq ($(CONFIG_ATHAP33),y)
3856 +subdir-$(CONFIG_ATHAP33) += athap33
3857 +endif
3858 +
3859  #
3860  # link order important here
3861  #
3862 @@ -242,6 +251,10 @@
3863  obj-$(CONFIG_R8169) += r8169.o
3864  obj-$(CONFIG_AMD8111_ETH) += amd8111e.o mii.o
3865  
3866 +ifeq ($(CONFIG_ATHAP33),y)
3867 +obj-$(CONFIG_ATHAP33) += athap33/ath_ap_mips.o
3868 +endif
3869 +
3870  # non-drivers/net drivers who want mii lib
3871  obj-$(CONFIG_PCMCIA_SMC91C92) += mii.o
3872  obj-$(CONFIG_USB_USBNET) += mii.o
3873 diff -urN linux-mips/fs/jffs2/nodelist.h mips-linux-2.4.25/fs/jffs2/nodelist.h
3874 --- linux-mips/fs/jffs2/nodelist.h      2005-12-24 15:11:50.407649616 +0000
3875 +++ mips-linux-2.4.25/fs/jffs2/nodelist.h       2005-12-30 17:27:51.289618200 +0000
3876 @@ -31,7 +31,7 @@
3877   * provisions above, a recipient may use your version of this file
3878   * under either the RHEPL or the GPL.
3879   *
3880 - * $Id: nodelist.h,v 1.46.2.5 2003/11/02 13:54:20 dwmw2 Exp $
3881 + * $Id: //depot/sw/releases/linuxsrc/src/kernels/mips-linux-2.4.25/fs/jffs2/nodelist.h#3 $
3882   *
3883   */
3884  
3885 @@ -222,8 +222,8 @@
3886  #define ALLOC_DELETION 1       /* Deletion node. Best to allow it */
3887  #define ALLOC_GC       2       /* Space requested for GC. Give it or die */
3888  
3889 -#define JFFS2_RESERVED_BLOCKS_BASE 3                                           /* Number of free blocks there must be before we... */
3890 -#define JFFS2_RESERVED_BLOCKS_WRITE (JFFS2_RESERVED_BLOCKS_BASE + 2)           /* ... allow a normal filesystem write */
3891 +#define JFFS2_RESERVED_BLOCKS_BASE 2                                           /* Number of free blocks there must be before we... */
3892 +#define JFFS2_RESERVED_BLOCKS_WRITE (JFFS2_RESERVED_BLOCKS_BASE + 1)           /* ... allow a normal filesystem write */
3893  #define JFFS2_RESERVED_BLOCKS_DELETION (JFFS2_RESERVED_BLOCKS_BASE + 1)                /* ... allow a normal filesystem deletion */
3894  #define JFFS2_RESERVED_BLOCKS_GCTRIGGER (JFFS2_RESERVED_BLOCKS_BASE + 3)       /* ... wake up the GC thread */
3895  #define JFFS2_RESERVED_BLOCKS_GCBAD (JFFS2_RESERVED_BLOCKS_BASE + 1)           /* ... pick a block from the bad_list to GC */
3896 diff -urN linux-mips/fs/partitions/Config.in mips-linux-2.4.25/fs/partitions/Config.in
3897 --- linux-mips/fs/partitions/Config.in  2005-12-24 15:11:52.366351848 +0000
3898 +++ mips-linux-2.4.25/fs/partitions/Config.in   2005-12-30 17:27:52.279467720 +0000
3899 @@ -39,7 +39,7 @@
3900     fi
3901     if [ "$CONFIG_AMIGA" != "y" -a "$CONFIG_ATARI" != "y" -a \
3902          "$CONFIG_MAC" != "y" -a "$CONFIG_SGI_IP22" != "y" -a \
3903 -       "$CONFIG_SGI_IP27" != "y" ]; then
3904 +       "$CONFIG_SGI_IP27" != "y" -a "$CONFIG_AR531X" != "y" ]; then
3905        define_bool CONFIG_MSDOS_PARTITION y
3906     fi
3907     if [ "$CONFIG_AMIGA" = "y" -o "$CONFIG_AFFS_FS" = "y" ]; then
3908 diff -urN linux-mips/include/asm-mips/atheros/ar531xbsp.h mips-linux-2.4.25/include/asm-mips/atheros/ar531xbsp.h
3909 --- linux-mips/include/asm-mips/atheros/ar531xbsp.h     1970-01-01 01:00:00.000000000 +0100
3910 +++ mips-linux-2.4.25/include/asm-mips/atheros/ar531xbsp.h      2005-12-30 17:28:01.523062480 +0000
3911 @@ -0,0 +1,17 @@
3912 +#ifndef __ASM_ATHEROS_BSP_SUPPORT_H
3913 +#define __ASM_ATHEROS_BSP_SUPPORT_H
3914 +/*
3915 + * These are definitions and functions provided by the bsp to support the
3916 + * AR5312 WiSoC running LSDK.  For different BSP implementations, different
3917 + * BSP functions will be needed.
3918 + */
3919 +
3920 +extern unsigned int ar531x_sys_frequency(void);
3921 +extern const char* get_system_type(void);
3922 +
3923 +#ifdef CONFIG_KGDB
3924 +extern  void kgdbInit(void);
3925 +extern int kgdbEnabled(void);
3926 +#endif
3927 +
3928 +#endif /* __ASM_ATHEROS_BSP_SUPPORT_H */
3929 diff -urN linux-mips/include/asm-mips/bootinfo.h mips-linux-2.4.25/include/asm-mips/bootinfo.h
3930 --- linux-mips/include/asm-mips/bootinfo.h      2005-12-24 15:12:00.645093288 +0000
3931 +++ mips-linux-2.4.25/include/asm-mips/bootinfo.h       2005-12-30 17:28:01.534060808 +0000
3932 @@ -37,6 +37,7 @@
3933  #define MACH_GROUP_HP_LJ       20 /* Hewlett Packard LaserJet               */
3934  #define MACH_GROUP_LASAT       21
3935  #define MACH_GROUP_TITAN       22 /* PMC-Sierra Titan                      */
3936 +#define MACH_GROUP_AR531X      23 /* Atheros AR531X                         */
3937  
3938  /*
3939   * Valid machtype values for group unknown (low order halfword of mips_machtype)
3940 @@ -198,6 +199,17 @@
3941   */
3942  #define        MACH_TITAN_YOSEMITE     1       /* PMC-Sierra Yosemite */
3943  
3944 +/*
3945 + * Valid machtype for group MACH_GROUP_AR5312
3946 + */
3947 +#define MACH_ATHEROS_UNUSED     0
3948 +#define MACH_ATHEROS_AP30       1       /* AP30 */
3949 +#define MACH_ATHEROS_AP33      2       /* AP33 */
3950 +#define MACH_ATHEROS_AP38       3       /* AP38 */
3951 +#define MACH_ATHEROS_AP43       4       /* AP43 */
3952 +#define MACH_ATHEROS_AP48       5       /* AP48 */
3953 +#define MACH_ATHEROS_PB32       6       /* PB32 */
3954 +
3955  #define CL_SIZE                        (256)
3956  
3957  const char *get_system_type(void);
3958 diff -urN linux-mips/include/asm-mips/page.h mips-linux-2.4.25/include/asm-mips/page.h
3959 --- linux-mips/include/asm-mips/page.h  2005-12-24 15:12:01.097024584 +0000
3960 +++ mips-linux-2.4.25/include/asm-mips/page.h   2005-12-30 17:28:01.898005480 +0000
3961 @@ -13,7 +13,6 @@
3962  #include <linux/config.h>
3963  #include <asm/break.h>
3964  
3965 -#ifdef __KERNEL__
3966  
3967  /*
3968   * PAGE_SHIFT determines the page size
3969 @@ -30,6 +29,7 @@
3970  #define PAGE_SIZE      (1L << PAGE_SHIFT)
3971  #define PAGE_MASK      (~(PAGE_SIZE-1))
3972  
3973 +#ifdef __KERNEL__
3974  #ifndef __ASSEMBLY__
3975  
3976  #include <asm/cacheflush.h>
3977 diff -urN linux-mips/include/asm-mips/serial.h mips-linux-2.4.25/include/asm-mips/serial.h
3978 --- linux-mips/include/asm-mips/serial.h        2005-12-24 15:12:01.130019568 +0000
3979 +++ mips-linux-2.4.25/include/asm-mips/serial.h 2005-12-30 17:28:02.143968088 +0000
3980 @@ -410,6 +410,11 @@
3981  #define DDB5477_SERIAL_PORT_DEFNS
3982  #endif
3983  
3984 +#if defined(CONFIG_AR531X)
3985 +#undef RS_TABLE_SIZE
3986 +#define RS_TABLE_SIZE 1
3987 +#endif
3988 +
3989  #define SERIAL_PORT_DFNS                       \
3990         ATLAS_SERIAL_PORT_DEFNS                 \
3991         AU1000_SERIAL_PORT_DEFNS                \
3992 diff -urN linux-mips/kernel/printk.c mips-linux-2.4.25/kernel/printk.c
3993 --- linux-mips/kernel/printk.c  2005-12-24 15:12:09.361768152 +0000
3994 +++ mips-linux-2.4.25/kernel/printk.c   2005-12-30 17:28:11.943478336 +0000
3995 @@ -383,6 +383,18 @@
3996         _call_console_drivers(start_print, end, msg_level);
3997  }
3998  
3999 +#if CONFIG_EARLY_PRINTK_HACK
4000 +void putDebugChar(char byte);
4001 +static void emit_log_char(char c)
4002 +{
4003 +       if (c == '\n') {
4004 +               putDebugChar('\r');
4005 +               putDebugChar('\n');
4006 +       } else {
4007 +               putDebugChar(c);
4008 +       }
4009 +}
4010 +#else
4011  static void emit_log_char(char c)
4012  {
4013         LOG_BUF(log_end) = c;
4014 @@ -394,6 +406,7 @@
4015         if (logged_chars < LOG_BUF_LEN)
4016                 logged_chars++;
4017  }
4018 +#endif
4019  
4020  /*
4021   * This is printk.  It can be called from any context.  We want it to work.
4022 @@ -696,3 +709,4 @@
4023                 tty->driver.write(tty, 0, msg, strlen(msg));
4024         return;
4025  }
4026 +
4027 diff -urN linux-mips-orig/drivers/net/ath/ae531x.h linux-mips-new/drivers/net/ath/ae531x.h
4028 --- linux-mips-orig/drivers/net/ath/ae531x.h    1970-01-01 01:00:00.000000000 +0100
4029 +++ linux-mips-new/drivers/net/ath/ae531x.h     2005-12-31 12:33:57.672538976 +0000
4030 @@ -0,0 +1,43 @@
4031 +#ifndef __AE531X_H
4032 +#define __AE531X_H
4033 +
4034 +#include <linux/config.h>
4035 +#include <linux/types.h>
4036 +#include <linux/delay.h>
4037 +#include <linux/netdevice.h>
4038 +#include <linux/etherdevice.h>
4039 +#include <linux/init.h>
4040 +#include <linux/skbuff.h>
4041 +#include <asm/io.h>
4042 +
4043 +#include "ar531xlnx.h"
4044 +#include "ae531xreg.h"
4045 +#include "ae531xmac.h"
4046 +
4047 +extern void *ae531x_rxbuf_alloc(ae531x_MAC_t *MACInfo, char **rxBuffp, 
4048 +                               int *rxBuffSizep);
4049 +extern void ae531x_swptr_free(VIRT_ADDR desc);
4050 +extern BOOL ae531x_twisted_enet(void);
4051 +extern void ae531x_MiiWrite(UINT32 phyBase, UINT32 phyAddr, UINT8 reg, 
4052 +                           UINT16 data);
4053 +extern UINT16 ae531x_MiiRead(UINT32 phyBase, UINT32 phyAddr, UINT8 reg);
4054 +extern void ae531x_unitLinkGained(int ethUnit);
4055 +extern void ae531x_unitLinkLost(int ethUnit);
4056 +extern void ae531x_WriteDmaReg(ae531x_MAC_t *MACInfo, UINT32 reg, UINT32 data);
4057 +extern void ae531x_MACReset(ae531x_MAC_t *MACInfo);
4058 +extern void ae531x_DisableComm(ae531x_MAC_t *MACInfo);
4059 +extern void ae531x_FreeQueues(ae531x_MAC_t *MACInfo);
4060 +extern void ae531x_reset(ae531x_MAC_t *MACInfo);
4061 +extern int  ae531x_AllocateQueues(ae531x_MAC_t *MACInfo);
4062 +extern void ae531x_EnableComm(ae531x_MAC_t *MACInfo);
4063 +extern void ae531x_DmaIntEnable(ae531x_MAC_t *MACInfo);
4064 +extern void ae531x_DmaIntDisable(ae531x_MAC_t *MACInfo);
4065 +extern void ae531x_DmaReset(ae531x_MAC_t *MACInfo);
4066 +extern void ae531x_BeginResetMode(ae531x_MAC_t *MACInfo);
4067 +extern void ae531x_AckIntr(ae531x_MAC_t *MACInfo, UINT32 data);
4068 +extern void ae531x_SetDmaReg(ae531x_MAC_t *MACInfo, UINT32 reg, UINT32 val);
4069 +extern BOOL ae531x_IsInResetMode(ae531x_MAC_t *MACInfo);
4070 +extern UINT32 ae531x_ReadDmaReg(ae531x_MAC_t *MACInfo, UINT32 reg);
4071 +extern void ae531x_ClearDmaReg(ae531x_MAC_t *MACInfo, UINT32 reg, UINT32 val);
4072 +
4073 +#endif   /* __AE531X_H */
4074 diff -urN linux-mips-orig/drivers/net/ath/ae531xlnx.c linux-mips-new/drivers/net/ath/ae531xlnx.c
4075 --- linux-mips-orig/drivers/net/ath/ae531xlnx.c 1970-01-01 01:00:00.000000000 +0100
4076 +++ linux-mips-new/drivers/net/ath/ae531xlnx.c  2005-12-31 12:33:57.673538824 +0000
4077 @@ -0,0 +1,1303 @@
4078 +/*
4079 + * This file is subject to the terms and conditions of the GNU General Public
4080 + * License.  See the file "COPYING" in the main directory of this archive
4081 + * for more details.
4082 + *
4083 + * Copyright © 2003 Atheros Communications, Inc.,  All Rights Reserved.
4084 + */
4085 +
4086 +/*
4087 + * Ethernet driver for Atheros' ae531x ethernet MAC.
4088 + * This is a fairly generic driver, but it's intended
4089 + * for use in typical Atheros products.
4090 + */
4091 +
4092 +#include <linux/config.h>
4093 +#include <linux/module.h>
4094 +#include <linux/types.h>
4095 +#include <linux/delay.h>
4096 +#include <linux/netdevice.h>
4097 +#include <linux/etherdevice.h>
4098 +#include <linux/init.h>
4099 +#include <linux/skbuff.h>
4100 +#include <asm/io.h>
4101 +
4102 +#include "ar531xlnx.h"
4103 +#include "ae531xreg.h"
4104 +#include "ae531xmac.h"
4105 +#include "ae531x.h"
4106 +
4107 +#ifndef EXPORT_SYMTAB
4108 +#define EXPORT_SYMTAB
4109 +#endif
4110 +
4111 +#ifdef DEBUG
4112 +void my_mvPhyShow(int ethUnit);
4113 +#endif
4114 +
4115 +static struct ar531x_boarddata *ar531x_boardConfig=NULL;
4116 +
4117 +static char *radioConfig=NULL;
4118 +
4119 +#define AE531X_LAN_PORT 0
4120 +#define AE531X_DEV_PER_MAC 1
4121 +
4122 +/*
4123 + * ae531x_MAC_state contains driver-specific linux-specific per-MAC information.
4124 + * The OSinfo member of ae531x_MAC_t points to one of these.
4125 + */
4126 +typedef struct ae531x_MAC_state {
4127 +    int                         irq;
4128 +    struct tq_struct            restart_task;
4129 +    struct net_device_stats     stats;
4130 +    struct ae531x_dev_sw_state  *dev_sw_state[AE531X_DEV_PER_MAC];
4131 +    int                         primary_dev;
4132 +    ae531x_MAC_t                MACInfo; /* hardware state */
4133 +} ae531x_MAC_state_t;
4134 +
4135 +/*
4136 + * ae531x_dev_sw_state contains driver-specific linux-specific per-device
4137 + * information.  The net_device priv member points to one of these, and
4138 + * this structure contains a pointer to the associated MAC information.
4139 + */
4140 +
4141 +typedef struct ae531x_dev_sw_state {
4142 +    int                     enetUnit;        /* system unit number "eth%d" */
4143 +    int                     unit_on_MAC;     /* MAC-relative unit number */
4144 +    struct net_device       *dev;
4145 +    ae531x_MAC_state_t      *MAC_state;      /* underlying MAC hw/sw state */
4146 +} ae531x_dev_sw_state_t;
4147 +
4148 +/*
4149 + * Driver-independent linux-specific per-ethernet device software information.
4150 + */
4151 +static struct net_device *ae531x_MAC_dev[AR531X_NUM_ENET_MAC * AE531X_DEV_PER_MAC];
4152 +
4153 +/* Driver-dependent per-MAC information */
4154 +static ae531x_MAC_state_t per_MAC_info[AR531X_NUM_ENET_MAC];
4155 +
4156 +/*
4157 + * Receive buffers need enough room to hold the following:
4158 + * 1) a max MTU-sized packet.  
4159 + * 2) space for an ethernet header
4160 + * 3) room at the beginning of the receive buffer in order
4161 + *    to facilitate cooperating drivers that need to PREpend
4162 + *    data.
4163 + * 4) Depending on configuration, we may need some additional
4164 + *    room at the END of the rx buffer for phy-supplied
4165 + *    trailers (if any). (c.f. CONFIG_VENETDEV)
4166 + *
4167 + * The DMA engine insists on 32-bit aligned RX buffers.
4168 + * TBDXXX: With current code, the IP stack ends up looking
4169 + * at misaligned headers with word operations.  The misaligned
4170 + * reads are software-emulated via handle_adel_int.  We'd
4171 + * rather align the buffers on a 16-bit boundary, but the
4172 + * DMA engine doesn't permit it???
4173 + */
4174 +#define ETH_MAX_MTU 1518
4175 +#define AE531X_RX_BUF_SIZE \
4176 +    (((RXBUFF_RESERVE + ETH_HLEN + ETH_MAX_MTU + PHY_TRAILER_SIZE) + 3) & ~3)
4177 +
4178 +/* Forward references to local functions */
4179 +static void ae531x_TxReap(ae531x_MAC_state_t *MAC_state);
4180 +static int ae531x_phy_poll(void *data);
4181 +static int ae531x_MAC_stop(struct net_device *dev);
4182 +static int ae531x_MAC_open(struct net_device *dev);
4183 +
4184 +/*******************************************************************************
4185 +* ae531x_MAC_poll checks for received packets, and sends data
4186 +* up the stack.
4187 +*/
4188 +int
4189 +ae531x_MAC_poll(struct net_device *dev, int *budget)
4190 +{
4191 +    struct sk_buff *skb;
4192 +    struct sk_buff *newskb;
4193 +    char *rxBufp;
4194 +    int unused_length;
4195 +    VIRT_ADDR   rxDesc;
4196 +    int length;
4197 +    ae531x_dev_sw_state_t *dev_sw_state;
4198 +    ae531x_MAC_state_t *MAC_state;
4199 +    ae531x_MAC_t *MACInfo;
4200 +    u32 cmdsts;
4201 +    int rx_limit;
4202 +    int rx_received;
4203 +    int rxDescCount;
4204 +    struct net_device *rxdev;
4205 +    int early_stop;
4206 +    int retval;
4207 +#ifdef DEBUG
4208 +       static int rxDescCountMax = 0;
4209 +#endif
4210 +
4211 +    ARRIVE();
4212 +
4213 +    dev_sw_state = (ae531x_dev_sw_state_t *)dev->priv;
4214 +    MAC_state = dev_sw_state->MAC_state;
4215 +    MACInfo = &MAC_state->MACInfo;
4216 +    rx_limit = MAC_state->dev_sw_state[MAC_state->primary_dev]->dev->quota;
4217 +    rx_received = 0;
4218 +
4219 +    rxDescCount = 0;
4220 +
4221 +    early_stop = 0;
4222 +    do {
4223 +        ae531x_AckIntr(MACInfo, DmaIntRxCompleted);
4224 +
4225 +        for(;!early_stop;) {
4226 +            rxDesc = MACInfo->rxQueue.curDescAddr;
4227 +            cmdsts = AE531X_DESC_STATUS_GET(KSEG1ADDR(rxDesc));
4228 +
4229 +            AE531X_PRINT(AE531X_DEBUG_RX,
4230 +                  ("examine rxDesc %p with cmdsts=0x%x\n",
4231 +                   (void *)rxDesc, cmdsts));
4232 +    
4233 +            if (cmdsts & DescOwnByDma) {
4234 +                /* There's nothing left to process in the RX ring */
4235 +                goto rx_all_done;
4236 +            }
4237 +
4238 +            rxDescCount++;
4239 +
4240 +            AE531X_CONSUME_DESC((&MACInfo->rxQueue));
4241 +    
4242 +            A_DATA_CACHE_INVAL(rxDesc, AE531X_DESC_SIZE);
4243 +
4244 +            /*  Process a packet */
4245 +            length = AE531X_DESC_STATUS_RX_SIZE(cmdsts) - ETH_CRC_LEN;
4246 +            if ( (cmdsts & (DescRxFirst |DescRxLast | DescRxErrors)) ==
4247 +                           (DescRxFirst | DescRxLast) ) {
4248 +                /* Descriptor status indicates "NO errors" */
4249 +                skb = AE531X_DESC_SWPTR_GET(rxDesc);
4250 +    
4251 +                /*
4252 +                 * Allocate a replacement skb.
4253 +                 * We want to get another buffer ready for Rx ASAP.
4254 +                 */
4255 +                newskb = (struct sk_buff *)ae531x_rxbuf_alloc(MACInfo, &rxBufp, &unused_length);
4256 +                if(newskb == NULL ) {
4257 +                    /*
4258 +                     * Give this descriptor back to the DMA engine,
4259 +                     * and drop the received packet.
4260 +                     */
4261 +                    MAC_state->stats.rx_dropped++;
4262 +                    AE531X_PRINT(AE531X_DEBUG_ERROR,
4263 +                              ("Can't allocate new skb\n"));
4264 +                } else {
4265 +                    AE531X_DESC_BUFPTR_SET(rxDesc, virt_to_bus(rxBufp));
4266 +                    AE531X_DESC_SWPTR_SET(rxDesc, newskb);
4267 +                }
4268 +
4269 +                AE531X_DESC_STATUS_SET(rxDesc, DescOwnByDma);
4270 +                rxDesc = NULL; /* sanity -- cannot use rxDesc now */
4271 +                sysWbFlush();
4272 +    
4273 +                if (newskb == NULL) {
4274 +                    retval = 1;
4275 +                    goto rx_no_skbs;
4276 +                } else {
4277 +                    /* Sync data cache w.r.t. DMA */
4278 +                    A_DATA_CACHE_INVAL(skb->data, length);
4279 +        
4280 +                    rxdev = dev_sw_state->dev;
4281 +
4282 +                    if (rxdev == NULL) {
4283 +                        /*
4284 +                         * We received a packet for a virtual enet device
4285 +                         * that is no longer up.  Ignore it.
4286 +                         */
4287 +                        kfree_skb(skb);
4288 +                        continue;
4289 +                    }
4290 +
4291 +                    /* Advance data pointer to show that there's data here */
4292 +                    skb_put(skb, length);
4293 +                    skb->protocol = eth_type_trans(skb, rxdev);
4294 +                    skb->dev = rxdev;
4295 +                    rxdev->last_rx = jiffies;
4296 +                    rxdev->quota--;
4297 +
4298 +                    if (rx_limit-- < 0) {
4299 +                        early_stop=1;
4300 +                        /* We've done enough for now -- more later */
4301 +                        AE531X_PRINT(AE531X_DEBUG_RX_STOP,
4302 +                            ("Enet%d RX early stop.  Quota=%d rxDescCount=%d budget=%d\n",
4303 +                             MACInfo->unit, dev->quota, rxDescCount, *budget));
4304 +                    }
4305 +                    rx_received++;
4306 +        
4307 +                    /* Send the data up the stack */
4308 +                    AE531X_PRINT(AE531X_DEBUG_RX,
4309 +                              ("Send data up stack: skb=%p data=%p length=%d\n",
4310 +                               (void *)skb, (void *)skb->data, length));
4311 +
4312 +                    netif_receive_skb(skb);
4313 +
4314 +                    MAC_state->stats.rx_packets++;
4315 +                    MAC_state->stats.rx_bytes += length;
4316 +                }
4317 +            } else {
4318 +                /* Descriptor status indicates ERRORS */
4319 +                MAC_state->stats.rx_errors++;
4320 +    
4321 +                if (cmdsts & (DescRxRunt | DescRxLateColl)) {
4322 +                    MAC_state->stats.collisions++;
4323 +                }
4324 +    
4325 +                if (cmdsts & DescRxLengthError) {
4326 +                    MAC_state->stats.rx_length_errors++;
4327 +                }
4328 +    
4329 +                if (cmdsts & DescRxCrc) {
4330 +                    MAC_state->stats.rx_crc_errors++;
4331 +                }
4332 +    
4333 +                if (cmdsts & DescRxDribbling) {
4334 +                    MAC_state->stats.rx_frame_errors++;
4335 +                }
4336 +                               
4337 +                               AE531X_DESC_STATUS_SET(rxDesc, DescOwnByDma);
4338 +
4339 +                AE531X_PRINT(AE531X_DEBUG_ERROR,
4340 +                          ("Bad receive.  rxDesc=%p  cmdsts=0x%8.8x\n",
4341 +                           (void *)rxDesc, cmdsts));
4342 +            }
4343 +        }
4344 +    } while ((!early_stop) &&
4345 +             ae531x_ReadDmaReg(MACInfo, DmaStatus) & DmaIntRxCompleted);
4346 +
4347 +rx_all_done:
4348 +    AE531X_PRINT(AE531X_DEBUG_RX, 
4349 +             ("rx done (%d)\n", rxDescCount));
4350 +    *budget -= rxDescCount;
4351 +
4352 +    if (!early_stop) {
4353 +        netif_rx_complete(dev);
4354 +
4355 +        ae531x_SetDmaReg(MACInfo, DmaIntrEnb,
4356 +                     DmaIeRxCompleted | DmaIeRxNoBuffer);
4357 +        ae531x_WriteDmaReg(MACInfo, DmaRxPollDemand, 0);
4358 +    }
4359 +    
4360 +    retval = early_stop;
4361 +
4362 +rx_no_skbs:
4363 +
4364 +    LEAVE();
4365 +
4366 +#ifdef DEBUG
4367 +       if (rxDescCount > rxDescCountMax) {
4368 +               printk("max rx %d\n", rxDescCount);
4369 +               rxDescCountMax = rxDescCount;
4370 +       }
4371 +#endif
4372 +
4373 +    return retval;
4374 +}
4375 +
4376 +/*******************************************************************************
4377 +* ae531x_restart stops all ethernet devices associated with a physical MAC,
4378 +* then shuts down the MAC.  Then it re-opens all devices that were in use.
4379 +* TBDXXX: needs testing!
4380 +*/
4381 +static void
4382 +ae531x_restart(void *data)
4383 +{
4384 +    ae531x_MAC_t *MACInfo = (ae531x_MAC_t *)data;
4385 +    ae531x_MAC_state_t *MAC_state = (ae531x_MAC_state_t *)MACInfo->OSinfo;
4386 +    struct net_device *saved_dev[AE531X_DEV_PER_MAC];
4387 +    int i;
4388 +
4389 +    for (i=0; i<AE531X_DEV_PER_MAC; i++) {
4390 +        if ((saved_dev[i] = MAC_state->dev_sw_state[i]->dev) != NULL) {
4391 +            ae531x_MAC_stop(saved_dev[i]);
4392 +        }
4393 +    }
4394 +
4395 +    for (i=0; i<AE531X_DEV_PER_MAC; i++) {
4396 +        if (saved_dev[i])
4397 +            ae531x_MAC_open(saved_dev[i]);
4398 +    }
4399 +}
4400 +
4401 +/*******************************************************************************
4402 +* ae531x_MAC_intr handle interrupts from an ethernet MAC.
4403 +* It checks MAC status registers, and dispatches as appropriate.
4404 +*/
4405 +void
4406 +ae531x_MAC_intr(int cpl, void *dev_id, struct pt_regs *regs)
4407 +{
4408 +       ae531x_MAC_state_t *MAC_state;
4409 +       ae531x_MAC_t *MACInfo;
4410 +       u32 regIsr;
4411 +       u32 regImr;
4412 +       u32 pendIntrs;
4413 +
4414 +       ARRIVE();
4415 +       MACInfo = (ae531x_MAC_t *)dev_id;
4416 +       MAC_state = (ae531x_MAC_state_t *)MACInfo->OSinfo;
4417 +       for(;;) {
4418 +               /* Clear any unhandled intr causes. */
4419 +               ae531x_WriteDmaReg(MACInfo, DmaStatus, UnhandledIntrMask);
4420 +
4421 +               regIsr = ae531x_ReadDmaReg(MACInfo, DmaStatus);
4422 +               regImr = ae531x_ReadDmaReg(MACInfo, DmaIntrEnb);
4423 +               pendIntrs = regIsr & regImr;
4424 +
4425 +               AE531X_PRINT(AE531X_DEBUG_INT,
4426 +                                        ("ethmac%d: intIsr=0x%8.8x intImr=0x%8.8x pendIntrs=0x%8.8x\n",
4427 +                                         MACInfo->unit, regIsr, regImr, pendIntrs ));
4428 +
4429 +               if ((pendIntrs & DmaAllIntCauseMask) == 0)
4430 +                       break;
4431 +
4432 +               if ((pendIntrs & DmaIntRxCompleted) ||
4433 +                       (pendIntrs & DmaIntRxNoBuffer)) {
4434 +                       if (netif_rx_schedule_prep(MAC_state->dev_sw_state[MAC_state->primary_dev]->dev)) {
4435 +                               ae531x_ClearDmaReg(MACInfo,
4436 +                                                                  DmaIntrEnb,
4437 +                                                                  DmaIeRxCompleted | DmaIeRxNoBuffer);
4438 +                               ae531x_AckIntr(MACInfo,
4439 +                                                          DmaIntRxCompleted | DmaIntRxNoBuffer);
4440 +                               (void)ae531x_ReadDmaReg(MACInfo, DmaIntrEnb);
4441 +                               __netif_rx_schedule(MAC_state->dev_sw_state[MAC_state->primary_dev]->dev);
4442 +                       } else {
4443 +#if 0
4444 +                               AE531X_PRINT(AE531X_DEBUG_ERROR,
4445 +                                                        ("%s: Interrupt (0x%8.8x/0x%8.8x) while in poll.  regs@%p, pc=%p, ra=%p\n",
4446 +                                                         __FILE__,
4447 +                                                         regIsr,
4448 +                                                         ae531x_ReadDmaReg(MACInfo, DmaIntrEnb),
4449 +                                                         (void *)regs,
4450 +                                                         (void *)regs->cp0_epc,
4451 +                                                         (void *)regs->regs[31]));
4452 +#endif
4453 +                               ae531x_AckIntr(MACInfo,
4454 +                                                          DmaIntRxCompleted | DmaIntRxNoBuffer);
4455 +                       }
4456 +               }
4457 +
4458 +               if (pendIntrs &
4459 +                       (DmaIntTxStopped | DmaIntTxJabber | DmaIntTxUnderflow)) {
4460 +                       AE531X_PRINT(AE531X_DEBUG_ERROR,
4461 +                                                ("ethmac%d: TX Error Intr (0x%x)\n",
4462 +                                                 MACInfo->unit, pendIntrs));
4463 +                       ae531x_AckIntr(MACInfo,
4464 +                                                  (DmaIntTxStopped | DmaIntTxJabber | DmaIntTxUnderflow));
4465 +               }
4466 +
4467 +               if (pendIntrs & DmaIntBusError) {
4468 +                       AE531X_PRINT(AE531X_DEBUG_ERROR,
4469 +                                                ("ethmac%d: DMA Bus Error Intr (0x%x)\n",
4470 +                                                 MACInfo->unit, pendIntrs));
4471 +                       ae531x_AckIntr(MACInfo, DmaIntBusError);
4472 +                       /* Reset the chip, if it's not already being done */
4473 +                       if (ae531x_IsInResetMode(MACInfo)) {
4474 +                               goto intr_done;
4475 +                       }
4476 +                       ae531x_BeginResetMode(MACInfo);
4477 +                       schedule_task(&MAC_state->restart_task);
4478 +               }
4479 +
4480 +               if (pendIntrs & DmaIntRxStopped) {
4481 +                       AE531X_PRINT(AE531X_DEBUG_ERROR,
4482 +                                                ("ethmac%d: RX Stopped Intr (0x%x)\n",
4483 +                                                 MACInfo->unit, pendIntrs));
4484 +                       ae531x_AckIntr(MACInfo, DmaIntRxStopped);
4485 +               }
4486 +       }
4487 +
4488 + intr_done:
4489 +       LEAVE();
4490 +}
4491 +
4492 +/*******************************************************************************
4493 +* ae531x_MAC_get_stats returns statistics for a specified device
4494 +*/
4495 +static struct net_device_stats*
4496 +ae531x_MAC_get_stats(struct net_device *dev)
4497 +{
4498 +        ae531x_dev_sw_state_t *dev_sw_state;
4499 +        ae531x_MAC_state_t *MAC_state;
4500 +
4501 +        ARRIVE();
4502 +        dev_sw_state = (ae531x_dev_sw_state_t *)dev->priv;
4503 +        MAC_state = dev_sw_state->MAC_state;
4504 +
4505 +        LEAVE();
4506 +        return &MAC_state->stats;
4507 +}
4508 +
4509 +#define AE531X_PHY_POLL_SECONDS 2
4510 +
4511 +#if CONFIG_AR5315
4512 +
4513 +/*******************************************************************************
4514 +* ae531x_getMACInfo returns the MACInfo  of the interface given by unit 
4515 +*/
4516 +ae531x_MAC_t *ae531x_getMAcInfo(int ethUnit)
4517 +{
4518 +  int i,j;
4519 +  for(i=0;i<AR531X_NUM_ENET_MAC;++i) {
4520 +    if(per_MAC_info[i].dev_sw_state) {
4521 +      for(j=0;j<AE531X_DEV_PER_MAC;++j) {
4522 +        if(per_MAC_info[i].dev_sw_state[j]
4523 +           && per_MAC_info[i].dev_sw_state[j]->enetUnit == ethUnit)
4524 +            return (&(per_MAC_info[i].MACInfo));
4525 +      }
4526 +    }
4527 +  }
4528 +  return NULL;
4529 +}
4530 +    
4531 +
4532 +#endif
4533 +
4534 +/*******************************************************************************
4535 +* ae531x_phy_poll periodically checks for changes in phy status
4536 +* (e.g. dropped link).
4537 +*/
4538 +static int
4539 +ae531x_phy_poll(void *data)
4540 +{
4541 +    ae531x_dev_sw_state_t *dev_sw_state = (ae531x_dev_sw_state_t *)data;
4542 +    ae531x_MAC_t *MACInfo = &dev_sw_state->MAC_state->MACInfo;
4543 +    int unit = dev_sw_state->enetUnit;
4544 +
4545 +    while(dev_sw_state->dev!=NULL) {
4546 +        if (MACInfo->port_is_up) {
4547 +            phyCheckStatusChange(unit);
4548 +        }
4549 +
4550 +        set_current_state(TASK_UNINTERRUPTIBLE);
4551 +        schedule_timeout(AE531X_PHY_POLL_SECONDS * HZ);
4552 +    }
4553 +
4554 +    return 0;
4555 +}
4556 +
4557 +
4558 +static char invalid_enet_MAC_addr[] = {0, 0, 0, 0, 0, 0};
4559 +
4560 +/*
4561 + * Fetch a pointer to an ethernet's MAC address
4562 + * in the Board Configuration data (in flash).
4563 + */
4564 +char *
4565 +ae531x_enet_mac_address_get(int MACUnit)
4566 +{
4567 +       /* XXX: Hack for poorly configured boards.
4568 +        *      Cannot setup bridging properly (brctl) when both enet
4569 +        *      interfaces share the same MAC address.
4570 +        * 
4571 +        */
4572 +
4573 +#ifdef CONFIG_ASK_MULT_MAC_HACK
4574 +    static u8  enet0Mac[6] = {0x00, 0x0d, 0x0b, 0x13, 0x6b, 0x16};
4575 +    static u8  enet1Mac[6] = {0x00, 0x0d, 0x0b, 0x13, 0x6b, 0x17};
4576 +#endif
4577 +
4578 +    if (!ar531x_boardConfig)
4579 +        return invalid_enet_MAC_addr;
4580 +    if (MACUnit == 0) {
4581 +#ifndef CONFIG_ASK_MULT_MAC_HACK
4582 +        return ar531x_boardConfig->enet0Mac;
4583 +#else
4584 +               return enet0Mac;
4585 +#endif
4586 +    }
4587 +    if (MACUnit == 1) {
4588 +#ifndef CONFIG_ASK_MULT_MAC_HACK
4589 +        return ar531x_boardConfig->enet1Mac;
4590 +#else
4591 +               return enet1Mac;
4592 +#endif
4593 +    }
4594 +    printk("Invalid ethernet MAC unit number (%d)!\n", MACUnit);
4595 +    return invalid_enet_MAC_addr;
4596 +}
4597 +
4598 +
4599 +
4600 +/*******************************************************************************
4601 +* ae531x_MAC_open is the standard Linux open function.  It puts
4602 +* hardware into a known good state, allocates queues, starts
4603 +* the phy polling task, and arranges for interrupts to be handled.
4604 +*/
4605 +static int 
4606 +ae531x_MAC_open(struct net_device *dev)
4607 +{
4608 +    ae531x_dev_sw_state_t *dev_sw_state;
4609 +    ae531x_MAC_state_t *MAC_state;
4610 +    ae531x_MAC_t *MACInfo;
4611 +    u8 *MACAddr;
4612 +    int rv;
4613 +    struct tq_struct *restart_task;
4614 +    pid_t phy_poll_pid;
4615 +    ARRIVE();
4616 +
4617 +    dev_sw_state = (ae531x_dev_sw_state_t *)dev->priv;
4618 +    dev_sw_state->dev = dev;
4619 +    MAC_state = dev_sw_state->MAC_state;
4620 +    MACInfo = &MAC_state->MACInfo;
4621 +
4622 +    restart_task = &MAC_state->restart_task;
4623 +    restart_task->routine = ae531x_restart;
4624 +    restart_task->data = (void *)MACInfo;
4625 +
4626 +    AE531X_PRINT(AE531X_DEBUG_RESET,
4627 +              ("ae531x_MAC_open eth%d ethmac%d macBase=0x%x dmaBase=0x%x irq=0x%x\n",
4628 +               dev_sw_state->enetUnit,
4629 +               MACInfo->unit,
4630 +               MACInfo->macBase,
4631 +               MACInfo->dmaBase,
4632 +               MAC_state->irq));
4633 +
4634 +    /* Default MAC address */
4635 +    MACAddr = ae531x_enet_mac_address_get(MACInfo->unit);
4636 +    memcpy(dev->dev_addr, MACAddr, dev->addr_len );
4637
4638 +    if (!MACInfo->port_is_up) {
4639 +        /* Bring MAC and PHY out of reset */
4640 +        ae531x_reset(MACInfo);
4641 +    
4642 +        /* Attach interrupt handler */
4643 +        rv = request_irq(MAC_state->irq, ae531x_MAC_intr, SA_INTERRUPT,
4644 +                    "ae531x_MAC_intr", (void *)MACInfo);
4645 +        if (rv < 0) {
4646 +            AE531X_PRINT(AE531X_DEBUG_ERROR,
4647 +                         ("request_irq(0x%x) failed (%d)\n",
4648 +                          MAC_state->irq, rv));
4649 +            goto open_failure;
4650 +        }
4651 +
4652 +        /* Initialize PHY */
4653 +               AE531X_PRINT(AE531X_DEBUG_RESET, ("\n --- phyBase: %08x\n", MACInfo->phyBase));
4654 +        phySetup(MACInfo->unit, MACInfo->phyBase);
4655 +
4656 +        /* Start thread to poll for phy link status changes */
4657 +        phy_poll_pid = kernel_thread(ae531x_phy_poll, dev_sw_state, 0);
4658 +        if (phy_poll_pid < 0) {
4659 +            AE531X_PRINT(AE531X_DEBUG_ERROR,
4660 +                     ("ethmac%d unable to start Phy Poll thread\n",
4661 +                     MACInfo->unit));
4662 +        }
4663 +
4664 +        /* Allocate RX/TX Queues */
4665 +        if (ae531x_AllocateQueues(MACInfo) < 0) {
4666 +            AE531X_PRINT(AE531X_DEBUG_RESET, ("Queue allocation failed"));
4667 +            free_irq(MAC_state->irq, (void *)MACInfo);
4668 +            goto open_failure;
4669 +        }
4670 +    
4671 +        /* Initialize DMA and descriptors */
4672 +        ae531x_DmaReset(MACInfo);
4673 +
4674 +        /* Initialize MAC */
4675 +        ae531x_MACReset(MACInfo);
4676 +
4677 +        /* Enable Receive/Transmit */
4678 +        ae531x_EnableComm(MACInfo);
4679 +    
4680 +        MAC_state->primary_dev = dev_sw_state->unit_on_MAC;
4681 +        MACInfo->port_is_up = TRUE;
4682 +    }
4683 +
4684 +    dev->trans_start = jiffies;
4685 +    SET_MODULE_OWNER(dev);
4686 +
4687 +    LEAVE();
4688 +    return 0;
4689 +
4690 +open_failure:
4691 +    LEAVE();
4692 +    return -1;
4693 +}
4694 +
4695 +/*
4696 + * Shut down MAC hardware.
4697 + */
4698 +static void
4699 +ae531x_MAC_shutdown(ae531x_MAC_state_t *MAC_state)
4700 +{
4701 +    ae531x_MAC_t *MACInfo;
4702 +
4703 +    MACInfo = &MAC_state->MACInfo;
4704 +    MACInfo->port_is_up = FALSE;
4705 +
4706 +    /* Disable Receive/Transmit */
4707 +    ae531x_DisableComm(MACInfo);
4708 +
4709 +    /* Disable Interrupts */
4710 +    ae531x_DmaIntDisable(MACInfo);
4711 +    sysWbFlush();
4712 +    free_irq(MAC_state->irq, (void *)MACInfo);
4713 +
4714 +    /* Free Transmit & Receive skb's/descriptors */
4715 +    ae531x_TxReap(MAC_state); /* one last time */
4716 +    ae531x_FreeQueues(MACInfo);
4717 +}
4718 +
4719 +/*******************************************************************************
4720 +* ae531x_MAC_stop is the standard Linux stop function.  It undoes
4721 +* everything set up by ae531x_MAC_open.
4722 +*/
4723 +static int
4724 +ae531x_MAC_stop(struct net_device *dev)
4725 +{
4726 +    ae531x_dev_sw_state_t *dev_sw_state;
4727 +    ae531x_MAC_state_t *MAC_state;
4728 +    ae531x_MAC_t *MACInfo;
4729 +    int i;
4730 +
4731 +    ARRIVE();
4732 +
4733 +    dev_sw_state = (ae531x_dev_sw_state_t *)dev->priv;
4734 +    MAC_state = dev_sw_state->MAC_state;
4735 +    MACInfo = &MAC_state->MACInfo;
4736 +
4737 +    for (i=0; i<AE531X_DEV_PER_MAC; i++) {
4738 +        if ((MAC_state->dev_sw_state[i]->dev) &&
4739 +            (MAC_state->dev_sw_state[i]->dev != dev_sw_state->dev)) {
4740 +            break;
4741 +        }
4742 +    }
4743 +
4744 +    if (i < AE531X_DEV_PER_MAC) {
4745 +        /* Physical MAC is still in use */
4746 +        if (MAC_state->primary_dev == dev_sw_state->unit_on_MAC) {
4747 +            /*
4748 +             * If the primary_dev is being stopped
4749 +             * then we need to assign a new one.
4750 +             */
4751 +            MAC_state->primary_dev = i;
4752 +        }
4753 +    } else {
4754 +        /* Physical MAC is no longer in use */
4755 +        ae531x_MAC_shutdown(MAC_state);
4756 +    }
4757 +
4758 +    dev_sw_state->dev = NULL;
4759 +    LEAVE();
4760 +    return 0;
4761 +}
4762 +
4763 +/*******************************************************************************
4764 +* ae531x_rxbuf_alloc - Allocate an skb to be associated with an RX descriptor.
4765 +*
4766 +* RETURNS: A pointer to the skb.  Also returns a pointer to the underlying
4767 +* buffer and the size of that buffer. 
4768 +*/
4769 +void *
4770 +ae531x_rxbuf_alloc(ae531x_MAC_t *MACInfo, char **rxBuffp, int *rxBuffSizep)
4771 +{
4772 +    int buf_size;
4773 +    struct sk_buff *skb;
4774 +    char *rxBuff;
4775 +    int rxBuffSize;
4776 +
4777 +    buf_size = AE531X_RX_BUF_SIZE;
4778 +
4779 +    skb = dev_alloc_skb(buf_size);
4780 +    if (skb) {
4781 +        /* skb->dev = dev; */
4782 +        skb_reserve(skb, RXBUFF_RESERVE);
4783 +
4784 +        rxBuffSize = skb_tailroom(skb);
4785 +        rxBuff = skb->tail;
4786 +
4787 +        *rxBuffp = rxBuff;
4788 +        *rxBuffSizep = rxBuffSize;
4789 +    }
4790 +
4791 +    return skb;
4792 +}
4793 +
4794 +/*******************************************************************************
4795 +* ae531x_swptr_free - Free the skb, if any, associated with a descriptor.
4796 +*/
4797 +void
4798 +ae531x_swptr_free(VIRT_ADDR desc)
4799 +{
4800 +    struct sk_buff *skb;
4801 +
4802 +    skb = (struct sk_buff *)AE531X_DESC_SWPTR_GET(desc);
4803 +    if (skb) {
4804 +        AE531X_DESC_SWPTR_SET(desc, NULL);
4805 +        kfree_skb(skb);
4806 +    }
4807 +}
4808 +
4809 +/*******************************************************************************
4810 +*
4811 +* ae531x_TxReap - the driver Tx completion routine.
4812 +*
4813 +* This routine reaps sk_buffs which have already been transmitted.
4814 +*
4815 +*/
4816 +static void
4817 +ae531x_TxReap(ae531x_MAC_state_t *MAC_state)
4818 +{
4819 +    AE531X_QUEUE      *txq;
4820 +    VIRT_ADDR         txDesc;
4821 +    UINT32            cmdsts;
4822 +    struct            sk_buff *skb;
4823 +    int               reaped;
4824 +    ae531x_MAC_t      *MACInfo;
4825 +    static int        aeUselessReap = 0;
4826 +#ifdef DEBUG
4827 +    static int        aeMaxReap = 0;
4828 +#endif
4829 +    ARRIVE();
4830 +
4831 +    MACInfo = &MAC_state->MACInfo;
4832 +    txq = &MACInfo->txQueue;
4833 +    reaped = 0;
4834 +
4835 +    while (1) {
4836 +
4837 +        txDesc = AE531X_QUEUE_ELE_NEXT_GET(txq, txq->reapDescAddr);
4838 +        if (txDesc == txq->curDescAddr) {
4839 +            break;
4840 +        }
4841 +
4842 +        cmdsts = AE531X_DESC_STATUS_GET(KSEG1ADDR(txDesc));
4843 +        if (cmdsts & DescOwnByDma) {
4844 +            break;
4845 +        }
4846 +
4847 +        /* Release sk_buff associated with completed transmit */
4848 +        skb = (struct sk_buff *)AE531X_DESC_SWPTR_GET(txDesc);
4849 +        if (skb) {
4850 +            kfree_skb(skb);
4851 +            AE531X_DESC_SWPTR_SET(txDesc, NULL);
4852 +        }
4853 +
4854 +        /* Update statistics according to completed transmit desc */
4855 +        if (cmdsts & DescTxErrors) {
4856 +            AE531X_PRINT(AE531X_DEBUG_ERROR,
4857 +                    ("enetmac%d Tx prior error: 0x%8.8x <0x%8.8x> 0x%8.8x\n",
4858 +                    MACInfo->unit,
4859 +                    cmdsts,
4860 +                    DescTxErrors,
4861 +                    (int)txDesc));
4862 +#ifdef DEBUG
4863 +                       //my_mvPhyShow(MACInfo->unit);
4864 +           printk ("ae531xMacControl: 0x%08x\tMacFlowControl: 0x%08x\n",
4865 +                   ae531x_ReadMacReg(MACInfo, MacControl),
4866 +                   ae531x_ReadMacReg(MACInfo, MacFlowControl));
4867 +#endif
4868 +            MAC_state->stats.tx_errors++;
4869 +            if (cmdsts & (DescTxLateCollision | DescTxExcCollisions)) {
4870 +                MAC_state->stats.tx_aborted_errors++;
4871 +            }
4872 +            if (cmdsts & (DescTxLostCarrier | DescTxNoCarrier)) {
4873 +                MAC_state->stats.tx_carrier_errors++;
4874 +            }
4875 +        } else {
4876 +            MAC_state->stats.tx_bytes += AE531X_DESC_STATUS_RX_SIZE(cmdsts);
4877 +            MAC_state->stats.tx_packets++;
4878 +        }
4879 +
4880 +        MAC_state->stats.collisions +=
4881 +            ((cmdsts & DescTxCollMask) >> DescTxCollShift);
4882 +
4883 +        txq->reapDescAddr = txDesc;
4884 +        reaped++;
4885 +    }
4886 +
4887 +    if (reaped > 0) {
4888 +        int i;
4889 +
4890 +#ifdef DEBUG
4891 +               if (reaped > aeMaxReap) {
4892 +                       aeMaxReap = reaped;
4893 +                       printk("max reaped = %d\n", reaped);
4894 +               }
4895 +#endif
4896 +        AE531X_PRINT(AE531X_DEBUG_TX_REAP,
4897 +             ("reaped %d\n", reaped));
4898 +
4899 +        /*
4900 +         * Re-start transmit queues for all ethernet devices
4901 +         * associated with this MAC.
4902 +         */
4903 +        for (i=0; i<AE531X_DEV_PER_MAC; i++) {
4904 +            if (MAC_state->dev_sw_state[i]->dev)
4905 +                netif_start_queue(MAC_state->dev_sw_state[i]->dev);
4906 +        }
4907 +    } else {
4908 +        aeUselessReap++;
4909 +    }
4910 +
4911 +    LEAVE();
4912 +}
4913 +
4914 +
4915 +/*******************************************************************************
4916 +* ae531x_MAC_start_xmit sends a packet.
4917 +*/
4918 +static int
4919 +ae531x_MAC_start_xmit(struct sk_buff *skb, struct net_device *dev)
4920 +{
4921 +    ae531x_dev_sw_state_t *dev_sw_state;
4922 +    ae531x_MAC_state_t *MAC_state;
4923 +    ae531x_MAC_t *MACInfo;
4924 +    u32 buf;
4925 +    u32 ctrlen;
4926 +    u32 length;
4927 +    int mtu;
4928 +    int max_buf_size;
4929 +    VIRT_ADDR txDesc;
4930 +
4931 +    ARRIVE();
4932 +
4933 +    dev_sw_state = (ae531x_dev_sw_state_t *)dev->priv;
4934 +    MAC_state = dev_sw_state->MAC_state;
4935 +    MACInfo = &MAC_state->MACInfo;
4936 +
4937 +    length = skb->len;
4938 +
4939 +    /* Check if this port is up, else toss packet */
4940 +    if (!MACInfo->port_is_up) {
4941 +        buf = virt_to_bus(skb->data);
4942 +        AE531X_PRINT(AE531X_DEBUG_ERROR,
4943 +                  ("eth%d Tx Down, dropping buf=0x%8.8x, length=0x%8.8x, skb=%p\n",
4944 +                   dev_sw_state->enetUnit, buf, length, (void *)skb));
4945 +
4946 +        MAC_state->stats.tx_dropped++;
4947 +        MAC_state->stats.tx_carrier_errors++;
4948 +        goto dropFrame;
4949 +    }
4950 +
4951 +    if (ae531x_IsInResetMode(MACInfo)) {
4952 +        AE531X_PRINT(AE531X_DEBUG_ERROR,
4953 +                  ("eth%d Tx: In Chip reset - drop frame\n",
4954 +                   dev_sw_state->enetUnit));
4955 +
4956 +        MAC_state->stats.tx_dropped++;
4957 +        MAC_state->stats.tx_aborted_errors++;
4958 +        goto dropFrame;
4959 +    }
4960 +
4961 +    /* Check if we can transport this packet */
4962 +    length = max((u32)60, length);  /* total length */
4963 +    mtu = dev->mtu;
4964 +    max_buf_size = mtu + ETH_HLEN;
4965 +    if (length > max_buf_size) {
4966 +        AE531X_PRINT(AE531X_DEBUG_ERROR,
4967 +                  ("eth%d Tx: length %d too long.  mtu=%d, trailer=%d\n",
4968 +                   dev_sw_state->enetUnit, length, mtu, PHY_TRAILER_SIZE));
4969 +
4970 +        MAC_state->stats.tx_errors++;
4971 +        MAC_state->stats.tx_aborted_errors++;
4972 +
4973 +        goto dropFrame;
4974 +    }
4975 +
4976 +       /* Reap any old, completed Tx descriptors */
4977 +       ae531x_TxReap(MAC_state);
4978 +
4979 +    txDesc = MACInfo->txQueue.curDescAddr;
4980 +    if (txDesc == MACInfo->txQueue.reapDescAddr) {
4981 +        int i;
4982 +
4983 +        AE531X_PRINT(AE531X_DEBUG_ERROR,
4984 +                  ("eth%d Tx: cannot get txDesc\n",
4985 +                   dev_sw_state->enetUnit));
4986 +
4987 +        MAC_state->stats.tx_dropped++;
4988 +        MAC_state->stats.tx_fifo_errors++;
4989 +
4990 +        /*
4991 +         * Stop transmit queues for any ethernet devices
4992 +         * associated with this MAC.
4993 +         */
4994 +#if 0 /* XXX: no way to recover from queue stop until ae531x_MAC_tx_timeout()
4995 +          *      is rewritten to avoid calls to shedule().
4996 +          */
4997 +        for (i=0; i<AE531X_DEV_PER_MAC; i++) {
4998 +            if (MAC_state->dev_sw_state[i]->dev)
4999 +                netif_stop_queue(MAC_state->dev_sw_state[i]->dev);
5000 +        }
5001 +#endif
5002 +        goto dropFrame;
5003 +    }
5004 +
5005 +    /* We won't fail now; so consume this descriptor */
5006 +    AE531X_CONSUME_DESC((&MACInfo->txQueue));
5007 +
5008 +    /* Update the descriptor */
5009 +    buf = virt_to_bus(skb->data);
5010 +    AE531X_DESC_BUFPTR_SET(txDesc, buf);
5011 +    AE531X_DESC_SWPTR_SET(txDesc, skb);
5012 +    ctrlen = AE531X_DESC_CTRLEN_GET(txDesc);
5013 +    ctrlen = (ctrlen & (DescEndOfRing)) |
5014 +                            DescTxFirst |
5015 +                             DescTxLast |
5016 +                        DescTxIntEnable;
5017 +
5018 +    ctrlen |= ((length << DescSize1Shift) & DescSize1Mask);
5019 +
5020 +    AE531X_DESC_CTRLEN_SET(txDesc, ctrlen);
5021 +    AE531X_DESC_STATUS_SET(txDesc, DescOwnByDma);
5022 +
5023 +    /* Alert DMA engine to resume Tx */
5024 +    ae531x_WriteDmaReg(MACInfo, DmaTxPollDemand, 0);
5025 +    sysWbFlush();
5026 +
5027 +    AE531X_PRINT(AE531X_DEBUG_TX,
5028 +              ("eth%d Tx: Desc=0x%8.8x, L=0x%8.8x, D=0x%8.8x, d=0x%8.8x, length=0x%8.8x\n",
5029 +               dev_sw_state->enetUnit,
5030 +               (UINT32)txDesc,
5031 +               AE531X_DESC_CTRLEN_GET(txDesc),
5032 +               buf,
5033 +               AE531X_DESC_LNKBUF_GET(txDesc),
5034 +               length));
5035 +
5036 +    /* Tell upper layers to keep it coming */
5037 +    dev->trans_start = jiffies;
5038 +
5039 +    LEAVE();
5040 +
5041 +    return 0;
5042 +
5043 +dropFrame:
5044 +    kfree_skb(skb);
5045 +    LEAVE();
5046 +    return 0;
5047 +}
5048 +
5049 +
5050 +/*******************************************************************************
5051 +* ae531x_MAC_tx_timeout handles transmit timeouts
5052 +*/
5053 +static void
5054 +ae531x_MAC_tx_timeout(struct net_device *dev)
5055 +{
5056 +    ae531x_dev_sw_state_t *dev_sw_state;
5057 +    ae531x_MAC_state_t *MAC_state;
5058 +    ae531x_MAC_t *MACInfo;
5059 +
5060 +    ARRIVE();
5061 +
5062 +    dev_sw_state = (ae531x_dev_sw_state_t *)dev->priv;
5063 +    MAC_state = dev_sw_state->MAC_state;
5064 +    MACInfo = &MAC_state->MACInfo;
5065 +
5066 +    AE531X_PRINT(AE531X_DEBUG_ERROR,
5067 +             ("enet%d: Tx timeout\n", dev_sw_state->enetUnit));
5068 +
5069 +    ae531x_restart(MACInfo);
5070 +
5071 +    LEAVE();
5072 +}
5073 +
5074 +
5075 +/*******************************************************************************
5076 +* ae531x_MAC_do_ioctl is a placeholder for future ioctls.
5077 +*/
5078 +static int
5079 +ae531x_MAC_do_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
5080 +{
5081 +        int rv;
5082 +        ae531x_MAC_t *MACInfo;
5083 +        struct ioctl_data {
5084 +                u32 unit;
5085 +                u32 addr;
5086 +                u32 data;
5087 +        } *req;
5088 +        ae531x_dev_sw_state_t *dev_sw_state;
5089 +        ae531x_MAC_state_t *MAC_state;
5090 +
5091 +        ARRIVE();
5092 +
5093 +        dev_sw_state = (ae531x_dev_sw_state_t *)dev->priv;
5094 +        MAC_state = dev_sw_state->MAC_state;
5095 +        MACInfo = &MAC_state->MACInfo;
5096 +
5097 +        req = (struct ioctl_data *)ifr->ifr_data;
5098 +
5099 +        switch( cmd ) {
5100 +        default:
5101 +            AE531X_PRINT(AE531X_DEBUG_ERROR,
5102 +                     ("Unsupported ioctl: 0x%x\n", cmd));
5103 +            rv = -EOPNOTSUPP;
5104 +        }
5105 +
5106 +        LEAVE();
5107 +        return rv;
5108 +}
5109 +
5110 +static void
5111 +ae531x_MAC_setup_fntable(struct net_device *dev)
5112 +{
5113 +    ARRIVE();
5114 +
5115 +    dev->get_stats       = ae531x_MAC_get_stats;
5116 +    dev->open            = ae531x_MAC_open;
5117 +    dev->stop            = ae531x_MAC_stop;
5118 +    dev->hard_start_xmit = ae531x_MAC_start_xmit;
5119 +    dev->do_ioctl        = ae531x_MAC_do_ioctl;
5120 +    dev->poll            = ae531x_MAC_poll;
5121 +    dev->weight          = 16;
5122 +#if 0 /* XXX: currently, ae531x_MAC_tx_timeout() will call functions
5123 +          *      that in turn call schedule(). this is BAD, since the
5124 +          *      timeout call runs at interrupt time. until ae531x_MAC_tx_timeout
5125 +          *      is rewritten to avoid schedule() calls, we do not use it.
5126 +          */
5127 +    dev->tx_timeout      = ae531x_MAC_tx_timeout;
5128 +#else
5129 +    dev->tx_timeout      = NULL;
5130 +#endif
5131 +    dev->features        = NETIF_F_HW_CSUM |\
5132 +                           NETIF_F_HIGHDMA;
5133 +
5134 +    LEAVE();
5135 +}
5136 +
5137 +static void
5138 +ar5312EepromRead(char *EepromAddr, u_int16_t id, unsigned int off, 
5139 +                unsigned int nbytes, char *data)
5140 +{
5141 +       int i;
5142 +       
5143 +       for (i=0; i<nbytes; i++, off++) {
5144 +               data[i] = EepromAddr[off];
5145 +       }
5146 +}
5147 +
5148 +int
5149 +ae531x_get_numMACs(void)
5150 +{
5151 +    int devid;
5152 +    u16 radioMask;
5153 +
5154 +    /* Probe to find out the silicon revision and enable the
5155 +       correct number of macs */
5156 +    devid = ((u_int16_t) ((sysRegRead(AR531X_REV) >>8) & 
5157 +                         (AR531X_REV_MAJ | AR531X_REV_MIN)));
5158 +    switch (devid) {
5159 +    case AR5212_AR5312_REV2:
5160 +    case AR5212_AR5312_REV7:
5161 +        /* Need to determine if we have a 5312 or a 2312 since they
5162 +           have the same Silicon Rev ID*/
5163 +        ar5312EepromRead(radioConfig,0,2*AR531X_RADIO_MASK_OFF,2,
5164 +                        (char *) &radioMask);
5165 +        if ((radioMask & AR531X_RADIO0_MASK) != 0) {
5166 +            return 2;
5167 +        }
5168 +        return 1;
5169 +    case AR5212_AR2313_REV8:
5170 +        return 1;
5171 +    }
5172 +        
5173 +    /* default to 1 */
5174 +    return 1;
5175 +}
5176 +
5177 +BOOL
5178 +ae531x_twisted_enet(void)
5179 +{
5180 +    int wisoc_revision;
5181 +
5182 +    wisoc_revision = (sysRegRead(AR531X_REV) & AR531X_REV_MAJ) >> AR531X_REV_MAJ_S;
5183 +    if ( (wisoc_revision == AR531X_REV_MAJ_AR2313) ||
5184 +         /* next clause is used to determine AR2312, based on number of MACs. 
5185 +          * must do this since revision is same for 5312 and 2312.
5186 +          */
5187 +         (wisoc_revision == AR531X_REV_MAJ_AR5312 && ae531x_get_numMACs() == 1) ) {
5188 +        return TRUE;
5189 +    } else {
5190 +        return FALSE;
5191 +    }
5192 +}
5193 +
5194 +int
5195 +ae531x_get_board_config(void)
5196 +{
5197 +    int dataFound;
5198 +    char *bd_config;
5199 +
5200 +    /*
5201 +     * Find start of Board Configuration data, using heuristics:
5202 +     * Search back from the (aliased) end of flash by 0x1000 bytes
5203 +     * at a time until we find the string "5311", which marks the
5204 +     * start of Board Configuration.  Give up if we've searched
5205 +     * more than 500KB.
5206 +     */
5207 +    dataFound = 0;
5208 +    for (bd_config = (char *)0xbffff000;
5209 +         bd_config > (char *)0xbff80000;
5210 +         bd_config -= 0x1000)
5211 +    {
5212 +        if ( *(int *)bd_config == AR531X_BD_MAGIC) {
5213 +            dataFound = 1;
5214 +            break;
5215 +        }
5216 +    }
5217 +
5218 +    if (!dataFound) {
5219 +        printk("Could not find Board Configuration Data\n");
5220 +               bd_config = NULL;
5221 +    }
5222 +       
5223 +    ar531x_boardConfig = (struct ar531x_boarddata *) bd_config;
5224 +       
5225 +    return(dataFound);
5226 +}
5227 +
5228 +int
5229 +ae531x_get_radio_config(void)
5230 +{
5231 +    int dataFound;
5232 +    char *radio_config;
5233 +
5234 +    /* 
5235 +     * Now find the start of Radio Configuration data, using heuristics:
5236 +     * Search forward from Board Configuration data by 0x1000 bytes
5237 +     * at a time until we find non-0xffffffff.
5238 +     */
5239 +    dataFound = 0;
5240 +    for (radio_config = ((char *) ar531x_boardConfig) + 0x1000;
5241 +         radio_config < (char *)0xbffff000;
5242 +         radio_config += 0x1000)
5243 +    {
5244 +        if (*(int *)radio_config != 0xffffffff) {
5245 +            dataFound = 1;
5246 +            break;
5247 +        }
5248 +    }
5249 +
5250 +    if (!dataFound) { /* AR2316 relocates radio config to new location */
5251 +       dataFound = 0;
5252 +       for (radio_config = ((char *) ar531x_boardConfig) + 0xf8;
5253 +            radio_config < (char *)0xbffff0f8;
5254 +            radio_config += 0x1000)
5255 +       {
5256 +           if (*(int *)radio_config != 0xffffffff) {
5257 +               dataFound = 1;
5258 +               break;
5259 +           }
5260 +       }
5261 +    }
5262 +
5263 +    if (!dataFound) {
5264 +        printk("Could not find Radio Configuration data\n");
5265 +       radio_config = NULL;
5266 +    }
5267 +    radioConfig = radio_config;
5268 +    return(dataFound);
5269 +}
5270 +
5271 +static int __init
5272 +ae531x_MAC_setup(void)
5273 +{
5274 +    int next_dev, i;
5275 +    struct net_device *dev;
5276 +    ae531x_dev_sw_state_t *dev_sw_state;
5277 +    ae531x_MAC_state_t *MAC_state;
5278 +    ae531x_MAC_t *MACInfo;
5279 +    char *addr;
5280 +
5281 +    ARRIVE();
5282 +
5283 +    MOD_INC_USE_COUNT;
5284 +    for (i=0;i<AR531X_NUM_ENET_MAC * AE531X_DEV_PER_MAC; i++) {
5285 +       ae531x_MAC_dev[i] = NULL;
5286 +    }
5287 +    
5288 +    if (!ae531x_get_board_config()) {
5289 +       LEAVE();
5290 +       return -1;
5291 +    }
5292 +    if (!ae531x_get_radio_config()) {
5293 +       LEAVE();
5294 +       return(-1);
5295 +    }
5296 +    for(i=0, next_dev = AR531X_NUM_ENET_MAC-1; 
5297 +        i<ae531x_get_numMACs() && next_dev>=0; 
5298 +        i++, next_dev--){
5299 +       
5300 +        /* if MAC is bogus in config data, skip */
5301 +        addr = ae531x_enet_mac_address_get(next_dev);
5302 +        if((*(u32 *)addr == 0xffffffff) && (*(u16 *)(addr+4)==0xffff)){
5303 +            /* bogus MAC config data */
5304 +            continue;
5305 +        }
5306 +       
5307 +        dev = ae531x_MAC_dev[next_dev] =
5308 +            init_etherdev(NULL, sizeof(ae531x_dev_sw_state_t));
5309 +       
5310 +        if (dev == NULL) {
5311 +            LEAVE();
5312 +            return -1;
5313 +        }
5314 +       
5315 +        ae531x_MAC_setup_fntable(dev);
5316 +
5317 +        dev_sw_state = (ae531x_dev_sw_state_t *)dev->priv;
5318 +        dev_sw_state->enetUnit = next_dev;
5319 +        dev_sw_state->unit_on_MAC = 0;
5320 +        MAC_state = &per_MAC_info[next_dev];
5321 +        dev_sw_state->MAC_state = MAC_state;
5322 +        MAC_state->dev_sw_state[AE531X_LAN_PORT] = dev_sw_state;
5323 +        MAC_state->primary_dev = -1;
5324 +
5325 +        /* Initialize per-MAC information */
5326 +        MACInfo = &MAC_state->MACInfo;
5327 +
5328 +        MACInfo->unit = next_dev;
5329 +
5330 +        if (MACInfo->unit == 0) {
5331 +            MACInfo->macBase = (u32)(PHYS_TO_K1(AR531X_ENET0)+AE531X_MAC_OFFSET);
5332 +            MACInfo->dmaBase = (u32)(PHYS_TO_K1(AR531X_ENET0)+AE531X_DMA_OFFSET);
5333 +            MACInfo->phyBase = (u32)(PHYS_TO_K1(AR531X_ENET0)+AE531X_PHY_OFFSET);
5334 +            MAC_state->irq = AR531X_IRQ_ENET0_INTRS;
5335 +        } else {
5336 +#ifndef CONFIG_AR5315
5337 +            MACInfo->macBase = (u32) (PHYS_TO_K1(AR531X_ENET1)+AE531X_MAC_OFFSET);
5338 +            MACInfo->dmaBase = (u32) (PHYS_TO_K1(AR531X_ENET1)+AE531X_DMA_OFFSET);
5339 +            if (ae531x_twisted_enet()) {
5340 +                MACInfo->phyBase = (u32)(PHYS_TO_K1(AR531X_ENET0)+AE531X_PHY_OFFSET);
5341 +            } else {
5342 +                MACInfo->phyBase = (u32)(PHYS_TO_K1(AR531X_ENET1)+AE531X_PHY_OFFSET);
5343 +            }
5344 +            MAC_state->irq = AR531X_IRQ_ENET1_INTRS;
5345 +#endif
5346 +        }
5347 +
5348 +        MACInfo->OSinfo = (void *)MAC_state;
5349 +
5350 +    }
5351 +
5352 +    LEAVE();
5353 +    return 0;
5354 +}
5355 +module_init(ae531x_MAC_setup);
5356 +
5357 +/*******************************************************************************
5358 +* ae531x_MAC_unload is the module unload function
5359 +*/
5360 +static void __exit
5361 +ae531x_MAC_unload(void)
5362 +{
5363 +    int i;
5364 +
5365 +    for (i=0;i<AR531X_NUM_ENET_MAC * AE531X_DEV_PER_MAC; i++) {
5366 +        if (ae531x_MAC_dev[i] != NULL) {
5367 +            if( (((ae531x_dev_sw_state_t *)ae531x_MAC_dev[i]->priv)->dev) != NULL)
5368 +                  ae531x_MAC_stop(ae531x_MAC_dev[i]);
5369 +            ae531x_MAC_dev[i] = NULL;
5370 +        }
5371 +    }
5372 +   MOD_DEC_USE_COUNT;
5373 +}
5374 +
5375 +MODULE_AUTHOR("Atheros Communications, Inc.");
5376 +MODULE_DESCRIPTION("Support for Atheros WiSoC Ethernet device");
5377 +#ifdef MODULE_LICENSE
5378 +MODULE_LICENSE("Atheros");
5379 +#endif
5380 +module_exit(ae531x_MAC_unload);
5381 diff -urN linux-mips-orig/drivers/net/ath/ae531xmac.c linux-mips-new/drivers/net/ath/ae531xmac.c
5382 --- linux-mips-orig/drivers/net/ath/ae531xmac.c 1970-01-01 01:00:00.000000000 +0100
5383 +++ linux-mips-new/drivers/net/ath/ae531xmac.c  2005-12-31 12:33:57.673538824 +0000
5384 @@ -0,0 +1,951 @@
5385 +/*
5386 + * This file is subject to the terms and conditions of the GNU General Public
5387 + * License.  See the file "COPYING" in the main directory of this archive
5388 + * for more details.
5389 + *
5390 + * Copyright © 2003 Atheros Communications, Inc.,  All Rights Reserved.
5391 + */
5392 +
5393 +
5394 +/*
5395 + * Ethernet driver for Atheros' ae531x ethernet MAC.
5396 + */
5397 +
5398 +#if linux
5399 +#include <linux/config.h>
5400 +#include <linux/types.h>
5401 +#include <linux/delay.h>
5402 +#include <linux/netdevice.h>
5403 +#include <linux/etherdevice.h>
5404 +#include <linux/init.h>
5405 +#include <asm/io.h>
5406 +
5407 +#include "ar531xlnx.h"
5408 +#endif /* linux */
5409 +
5410 +#include "ae531xreg.h"
5411 +#include "ae531xmac.h"
5412 +
5413 +#ifdef DEBUG
5414 +int ae531x_MAC_debug = AE531X_DEBUG_ERROR;
5415 +#else
5416 +int ae531x_MAC_debug = 0;
5417 +#endif
5418 +
5419 +extern char *ae531x_enet_mac_address_get(int);
5420 +
5421 +/* Forward references to local functions */
5422 +static void ae531x_QueueDestroy(AE531X_QUEUE *q);
5423 +
5424 +
5425 +/******************************************************************************
5426 +*
5427 +* ae531x_ReadMacReg - read AE MAC register
5428 +*
5429 +* RETURNS: register value
5430 +*/
5431 +UINT32
5432 +ae531x_ReadMacReg(ae531x_MAC_t *MACInfo, UINT32 reg)
5433 +{
5434 +    UINT32 addr = MACInfo->macBase+reg;
5435 +    UINT32 data;
5436 +
5437 +    data = RegRead(addr);
5438 +    return data;
5439 +}
5440 +
5441 +
5442 +/******************************************************************************
5443 +*
5444 +* ae531x_WriteMacReg - write AE MAC register
5445 +*
5446 +* RETURNS: N/A
5447 +*/
5448 +void
5449 +ae531x_WriteMacReg(ae531x_MAC_t *MACInfo, UINT32 reg, UINT32 data)
5450 +{
5451 +    UINT32 addr = MACInfo->macBase+reg;
5452 +
5453 +    RegWrite(data, addr);
5454 +}
5455 +
5456 +
5457 +/******************************************************************************
5458 +*
5459 +* ae531x_SetMacReg - set bits in AE MAC register
5460 +*
5461 +* RETURNS: N/A
5462 +*/
5463 +void
5464 +ae531x_SetMacReg(ae531x_MAC_t *MACInfo, UINT32 reg, UINT32 val)
5465 +{
5466 +    UINT32 addr = MACInfo->macBase+reg;
5467 +    UINT32 data = RegRead(addr);
5468 +
5469 +    data |= val;
5470 +    RegWrite(data, addr);
5471 +}
5472 +
5473 +
5474 +/******************************************************************************
5475 +*
5476 +* ae531x_ClearMacReg - clear bits in AE MAC register
5477 +*
5478 +* RETURNS: N/A
5479 +*/
5480 +void
5481 +ae531x_ClearMacReg(ae531x_MAC_t *MACInfo, UINT32 reg, UINT32 val)
5482 +{
5483 +    UINT32 addr = MACInfo->macBase+reg;
5484 +    UINT32 data = RegRead(addr);
5485 +
5486 +    data &= ~val;
5487 +    RegWrite(data, addr);
5488 +}
5489 +
5490 +
5491 +/******************************************************************************
5492 +*
5493 +* ae531x_ReadDmaReg - read AE DMA register
5494 +*
5495 +* RETURNS: register value
5496 +*/
5497 +UINT32
5498 +ae531x_ReadDmaReg(ae531x_MAC_t *MACInfo, UINT32 reg)
5499 +{
5500 +    UINT32 addr = MACInfo->dmaBase+reg;
5501 +    UINT32 data = RegRead(addr);
5502 +
5503 +    return data;
5504 +}
5505 +
5506 +
5507 +/******************************************************************************
5508 +*
5509 +* ae531x_WriteDmaReg - write AE DMA register
5510 +*
5511 +* RETURNS: N/A
5512 +*/
5513 +void
5514 +ae531x_WriteDmaReg(ae531x_MAC_t *MACInfo, UINT32 reg, UINT32 data)
5515 +{
5516 +    UINT32 addr = MACInfo->dmaBase+reg;
5517 +
5518 +    RegWrite(data, addr);
5519 +}
5520 +
5521 +
5522 +/******************************************************************************
5523 + *
5524 + * ae531x_AckIntr - clear interrupt bits in the status register.
5525 + * Note: Interrupt bits are *cleared* by writing a 1.
5526 + */
5527 +void
5528 +ae531x_AckIntr(ae531x_MAC_t *MACInfo, UINT32 data)
5529 +{
5530 +      ae531x_WriteDmaReg(MACInfo, DmaStatus, data);
5531 +}
5532 +
5533 +
5534 +/******************************************************************************
5535 +*
5536 +* ae531x_SetDmaReg - set bits in an AE DMA register
5537 +*
5538 +* RETURNS: N/A
5539 +*/
5540 +void
5541 +ae531x_SetDmaReg(ae531x_MAC_t *MACInfo, UINT32 reg, UINT32 val)
5542 +{
5543 +    UINT32 addr = MACInfo->dmaBase+reg;
5544 +    UINT32 data = RegRead(addr);
5545 +
5546 +    data |= val;
5547 +    RegWrite(data, addr);
5548 +}
5549 +
5550 +
5551 +/******************************************************************************
5552 +*
5553 +* ae531x_ClearDmaReg - clear bits in an AE DMA register
5554 +*
5555 +* RETURNS: N/A
5556 +*/
5557 +void
5558 +ae531x_ClearDmaReg(ae531x_MAC_t *MACInfo, UINT32 reg, UINT32 val)
5559 +{
5560 +    UINT32 addr = MACInfo->dmaBase+reg;
5561 +    UINT32 data = RegRead(addr);
5562 +
5563 +    data &= ~val;
5564 +    RegWrite(data, addr);
5565 +}
5566 +
5567 +
5568 +/******************************************************************************
5569 +*
5570 +* ae531x_ReadMiiReg - read PHY registers via AE MAC Mii addr/data registers
5571 +*
5572 +* RETURNS: register value
5573 +*/
5574 +UINT32
5575 +ae531x_ReadMiiReg(UINT32 phyBase, UINT32 reg)
5576 +{
5577 +    UINT32 data;
5578 +    UINT32 addr = phyBase+reg;
5579 +
5580 +    data = RegRead(addr);
5581 +    return data;
5582 +}
5583 +
5584 +
5585 +/******************************************************************************
5586 +*
5587 +* ae531x_WriteMiiReg - write PHY registers via AE MAC Mii addr/data registers
5588 +*
5589 +* RETURNS: N/A
5590 +*/
5591 +void
5592 +ae531x_WriteMiiReg(UINT32 phyBase, UINT32 reg, UINT32 data)
5593 +{
5594 +    UINT32 addr = phyBase+reg;
5595 +
5596 +    RegWrite(data, addr);
5597 +}
5598 +
5599 +
5600 +/******************************************************************************
5601 +*
5602 +* ae531x_MiiRead - read AE Mii register
5603 +*
5604 +* RETURNS: register value
5605 +*/
5606 +UINT16
5607 +ae531x_MiiRead(UINT32 phyBase, UINT32 phyAddr, UINT8 reg)
5608 +{
5609 +    UINT32 addr;
5610 +    UINT16 data;
5611 +
5612 +    addr = ((phyAddr << MiiDevShift) & MiiDevMask) | ((reg << MiiRegShift) & MiiRegMask);
5613 +
5614 +    ae531x_WriteMiiReg(phyBase, MacMiiAddr, addr );
5615 +    do {
5616 +        /* nop */
5617 +    } while ((ae531x_ReadMiiReg(phyBase, MacMiiAddr ) & MiiBusy) == MiiBusy);
5618 +
5619 +    data = ae531x_ReadMiiReg(phyBase, MacMiiData) & 0xFFFF;
5620 +
5621 +    return data;
5622 +}
5623 +
5624 +
5625 +/******************************************************************************
5626 +*
5627 +* ae531x_MiiWrite - write AE Mii register
5628 +*
5629 +* RETURNS: N/A
5630 +*/
5631 +void
5632 +ae531x_MiiWrite(UINT32 phyBase, UINT32 phyAddr, UINT8 reg, UINT16 data)
5633 +{
5634 +    UINT32 addr;
5635 +
5636 +    ae531x_WriteMiiReg(phyBase, MacMiiData, data );
5637 +
5638 +    addr = ((phyAddr << MiiDevShift) & MiiDevMask) |
5639 +        ((reg << MiiRegShift) & MiiRegMask) | MiiWrite;
5640 +    ae531x_WriteMiiReg(phyBase, MacMiiAddr, addr );
5641 +
5642 +    do {
5643 +        /* nop */
5644 +    } while ((ae531x_ReadMiiReg(phyBase, MacMiiAddr ) & MiiBusy) == MiiBusy);
5645 +}
5646 +
5647 +
5648 +/*******************************************************************************
5649 +* ae531x_BeginResetMode - enter a special "reset mode" in which
5650 +*    -no interrupts are expected from the device
5651 +*    -the device will not transmit nor receive
5652 +*    -attempts to send or receive will return with an error and
5653 +*    -the device will be reset at the next convenient opportunity.
5654 +*/
5655 +void
5656 +ae531x_BeginResetMode(ae531x_MAC_t *MACInfo)
5657 +{
5658 +    /* Set the reset flag */
5659 +    MACInfo->aeProcessRst = 1;
5660 +}
5661 +
5662 +
5663 +/*******************************************************************************
5664 +* ae531x_EndResetMode - exit the special "reset mode" entered
5665 +* earlier via a call to ae531x_BeginResetMode.
5666 +*/
5667 +void
5668 +ae531x_EndResetMode(ae531x_MAC_t *MACInfo)
5669 +{
5670 +    MACInfo->aeProcessRst = 0;
5671 +}
5672 +
5673 +
5674 +/*******************************************************************************
5675 +* ae531x_IsInResetMode - determine whether or not the device is
5676 +* currently in "reset mode" (i.e. that a device reset is pending)
5677 +*/
5678 +BOOL
5679 +ae531x_IsInResetMode(ae531x_MAC_t *MACInfo)
5680 +{
5681 +    return MACInfo->aeProcessRst;
5682 +}
5683 +
5684 +
5685 +/******************************************************************************
5686 +*
5687 +* ae531x_DmaRxStart - Start Rx
5688 +*
5689 +* RETURNS: N/A
5690 +*/
5691 +static void
5692 +ae531x_DmaRxStart(ae531x_MAC_t *MACInfo)
5693 +{
5694 +    ae531x_SetDmaReg(MACInfo, DmaControl, DmaRxStart);
5695 +    sysWbFlush();
5696 +}
5697 +
5698 +
5699 +/******************************************************************************
5700 +*
5701 +* ae531x_DmaRxStop - Stop Rx
5702 +*
5703 +* RETURNS: N/A
5704 +*/
5705 +void
5706 +ae531x_DmaRxStop(ae531x_MAC_t *MACInfo)
5707 +{
5708 +    ae531x_ClearDmaReg(MACInfo, DmaControl, DmaRxStart);
5709 +    sysWbFlush();
5710 +}
5711 +
5712 +
5713 +/******************************************************************************
5714 +*
5715 +* ae531x_DmaTxStart - Start Tx
5716 +*
5717 +* RETURNS: N/A
5718 +*/
5719 +void
5720 +ae531x_DmaTxStart(ae531x_MAC_t *MACInfo)
5721 +{
5722 +    ae531x_SetDmaReg(MACInfo, DmaControl, DmaTxStart);
5723 +    sysWbFlush();
5724 +}
5725 +
5726 +
5727 +/******************************************************************************
5728 +*
5729 +* ae531x_DmaTxStop - Stop Tx
5730 +*
5731 +* RETURNS: N/A
5732 +*/
5733 +void
5734 +ae531x_DmaTxStop(ae531x_MAC_t *MACInfo)
5735 +{
5736 +    ae531x_ClearDmaReg(MACInfo, DmaControl, DmaTxStart);
5737 +    sysWbFlush();
5738 +}
5739 +
5740 +
5741 +/******************************************************************************
5742 +*
5743 +* ae531x_DmaIntEnable - Enable DMA interrupts
5744 +*
5745 +* RETURNS: N/A
5746 +*/
5747 +void
5748 +ae531x_DmaIntEnable(ae531x_MAC_t *MACInfo)
5749 +{
5750 +    ae531x_WriteDmaReg(MACInfo, DmaIntrEnb, DmaIntEnable);
5751 +}
5752 +
5753 +
5754 +/******************************************************************************
5755 +*
5756 +* ae531x_DmaIntDisable - Disable DMA interrupts
5757 +*
5758 +* RETURNS: N/A
5759 +*/
5760 +void
5761 +ae531x_DmaIntDisable(ae531x_MAC_t *MACInfo)
5762 +{
5763 +    ae531x_WriteDmaReg(MACInfo, DmaIntrEnb, DmaIntDisable);
5764 +}
5765 +
5766 +
5767 +/******************************************************************************
5768 +*
5769 +* ae531x_DmaIntClear - Clear DMA interrupts
5770 +*
5771 +* RETURNS: N/A
5772 +*/
5773 +static void
5774 +ae531x_DmaIntClear(ae531x_MAC_t *MACInfo)
5775 +{
5776 +    /* clear all interrupt requests */
5777 +    ae531x_WriteDmaReg(MACInfo, DmaStatus,
5778 +                      ae531x_ReadDmaReg(MACInfo, DmaStatus));  
5779 +}
5780 +
5781 +
5782 +/******************************************************************************
5783 +* Initialize generic queue data
5784 +*/
5785 +void
5786 +ae531x_QueueInit(AE531X_QUEUE *q, char *pMem, int count)
5787 +{
5788 +    ARRIVE();
5789 +    q->firstDescAddr = pMem;
5790 +    q->lastDescAddr = (VIRT_ADDR)((UINT32)q->firstDescAddr +
5791 +                                  (count - 1) * AE531X_QUEUE_ELE_SIZE);
5792 +    q->curDescAddr = q->firstDescAddr;
5793 +    q->count = count;
5794 +    LEAVE();
5795 +}
5796 +
5797 +
5798 +/******************************************************************************
5799 +* ae531x_TxQueueCreate - create a circular queue of descriptors for Transmit
5800 +*/
5801 +static int
5802 +ae531x_TxQueueCreate(ae531x_MAC_t *MACInfo,
5803 +                  AE531X_QUEUE *q,
5804 +                  char *pMem,
5805 +                  int count)
5806 +{
5807 +    int         i;
5808 +    VIRT_ADDR   descAddr;
5809 +
5810 +    ARRIVE();
5811 +
5812 +    ae531x_QueueInit(q, pMem, count);
5813 +    q->reapDescAddr = q->lastDescAddr;
5814 +
5815 +    /* Initialize Tx buffer descriptors.  */
5816 +    for (i=0, descAddr=q->firstDescAddr;
5817 +         i<count;
5818 +         i++, descAddr=(VIRT_ADDR)((UINT32)descAddr + AE531X_QUEUE_ELE_SIZE))
5819 +    {
5820 +        /* Update the size, BUFPTR, and SWPTR fields */
5821 +
5822 +        AE531X_DESC_STATUS_SET(descAddr, 0);
5823 +        AE531X_DESC_CTRLEN_SET(descAddr, 0);
5824 +
5825 +        AE531X_DESC_BUFPTR_SET(descAddr, (UINT32)0);
5826 +        AE531X_DESC_LNKBUF_SET(descAddr, (UINT32)0);
5827 +        AE531X_DESC_SWPTR_SET(descAddr, (void *)0);
5828 +    } /* for each desc */
5829 +
5830 +    /* Make the queue circular */
5831 +    AE531X_DESC_CTRLEN_SET(q->lastDescAddr,
5832 +                       DescEndOfRing|AE531X_DESC_CTRLEN_GET(q->lastDescAddr));
5833 +
5834 +    AE531X_PRINT(AE531X_DEBUG_RESET,
5835 +            ("ethmac%d Txbuf begin = %x, end = %x\n",
5836 +            MACInfo->unit,
5837 +            (UINT32)q->firstDescAddr,
5838 +            (UINT32)q->lastDescAddr));
5839 +
5840 +    LEAVE();
5841 +    return 0;
5842 +}
5843 +
5844 +
5845 +/******************************************************************************
5846 +* ae531x_RxQueueCreate - create a circular queue of Rx descriptors
5847 +*/
5848 +int
5849 +ae531x_RxQueueCreate(ae531x_MAC_t *MACInfo,
5850 +                  AE531X_QUEUE *q,
5851 +                  char *pMem,
5852 +                  int count)
5853 +{
5854 +    int               i;
5855 +    VIRT_ADDR         descAddr;
5856 +
5857 +    ARRIVE();
5858 +
5859 +    ae531x_QueueInit(q, pMem, count);
5860 +    q->reapDescAddr = NULL;
5861 +
5862 +
5863 +    /* Initialize Rx buffer descriptors */
5864 +    for (i=0, descAddr=q->firstDescAddr;
5865 +         i<count;
5866 +         i++, descAddr=(VIRT_ADDR)((UINT32)descAddr + AE531X_QUEUE_ELE_SIZE))
5867 +    {
5868 +        void *swptr;
5869 +        char *rxBuffer;
5870 +        int  rxBufferSize;
5871 +
5872 +        swptr = ae531x_rxbuf_alloc(MACInfo, &rxBuffer, &rxBufferSize);
5873 +        if (swptr == NULL) {
5874 +                AE531X_PRINT(AE531X_DEBUG_RESET,
5875 +                          ("ethmac%d RX queue: ae531x_rxbuf_alloc failed\n",
5876 +                           MACInfo->unit));
5877 +                ae531x_QueueDestroy(q);
5878 +                return -1;
5879 +        }
5880 +        AE531X_DESC_SWPTR_SET(descAddr, swptr);
5881 +
5882 +        AE531X_DESC_STATUS_SET(descAddr, DescOwnByDma);
5883 +        AE531X_DESC_CTRLEN_SET(descAddr, rxBufferSize);
5884 +        AE531X_DESC_BUFPTR_SET(descAddr, virt_to_bus(rxBuffer));
5885 +        AE531X_DESC_LNKBUF_SET(descAddr, (UINT32)0);
5886 +    } /* for each desc */
5887 +
5888 +    /* Make the queue circular */
5889 +    AE531X_DESC_CTRLEN_SET(q->lastDescAddr,
5890 +                       DescEndOfRing|AE531X_DESC_CTRLEN_GET(q->lastDescAddr));
5891 +
5892 +    AE531X_PRINT(AE531X_DEBUG_RESET,
5893 +              ("ethmac%d Rxbuf begin = %x, end = %x\n",
5894 +              MACInfo->unit,
5895 +              (UINT32)q->firstDescAddr,
5896 +              (UINT32)q->lastDescAddr));
5897 +
5898 +    LEAVE();
5899 +    return 0;
5900 +}
5901 +
5902 +
5903 +/******************************************************************************
5904 +* ae531x_QueueDestroy -- Free all buffers and descriptors associated 
5905 +* with a queue.
5906 +*/
5907 +static void
5908 +ae531x_QueueDestroy(AE531X_QUEUE *q)
5909 +{
5910 +    int i;
5911 +    int count;
5912 +    VIRT_ADDR    descAddr;
5913 +
5914 +    ARRIVE();
5915 +
5916 +    count = q->count;
5917 +
5918 +    for (i=0, descAddr=q->firstDescAddr;
5919 +         i<count;
5920 +         i++, descAddr=(VIRT_ADDR)((UINT32)descAddr + AE531X_QUEUE_ELE_SIZE)) {
5921 +
5922 +        AE531X_DESC_STATUS_SET(descAddr, 0);
5923 +        AE531X_DESC_CTRLEN_SET(descAddr, 0);
5924 +        AE531X_DESC_BUFPTR_SET(descAddr, (UINT32)0);
5925 +        AE531X_DESC_LNKBUF_SET(descAddr, (UINT32)0);
5926 +
5927 +        ae531x_swptr_free(descAddr); /* Free OS-specific software pointer */
5928 +    }
5929 +
5930 +    LEAVE();
5931 +}
5932 +
5933 +static void
5934 +ae531x_TxQueueDestroy(ae531x_MAC_t *MACInfo)
5935 +{
5936 +    ae531x_QueueDestroy(&MACInfo->txQueue);
5937 +}
5938 +
5939 +static void
5940 +ae531x_RxQueueDestroy(ae531x_MAC_t *MACInfo)
5941 +{
5942 +    ae531x_QueueDestroy(&MACInfo->rxQueue);
5943 +}
5944 +
5945 +
5946 +/******************************************************************************
5947 +* ae531x_AllocateQueues - Allocate receive and transmit queues
5948 +*/
5949 +int
5950 +ae531x_AllocateQueues(ae531x_MAC_t *MACInfo)
5951 +{
5952 +    size_t QMemSize;
5953 +    char *pTxBuf = NULL;
5954 +    char *pRxBuf = NULL;
5955 +
5956 +    ARRIVE();
5957 +
5958 +    MACInfo->txDescCount = AE531X_TX_DESC_COUNT_DEFAULT;
5959 +    QMemSize = AE531X_QUEUE_ELE_SIZE * MACInfo->txDescCount;
5960 +    pTxBuf = MALLOC(QMemSize);
5961 +    if (pTxBuf == NULL) {
5962 +        AE531X_PRINT(AE531X_DEBUG_RESET,
5963 +                  ("ethmac%d Failed to allocate TX queue\n", MACInfo->unit));
5964 +        goto AllocQFail;
5965 +    }
5966 +
5967 +    if (ae531x_TxQueueCreate(MACInfo, &MACInfo->txQueue, pTxBuf,
5968 +                          MACInfo->txDescCount) < 0)
5969 +    {
5970 +        AE531X_PRINT(AE531X_DEBUG_RESET,
5971 +                ("ethmac%d Failed to create TX queue\n", MACInfo->unit));
5972 +        goto AllocQFail;
5973 +    }
5974 +
5975 +    MACInfo->rxDescCount = AE531X_RX_DESC_COUNT_DEFAULT;
5976 +    QMemSize = AE531X_QUEUE_ELE_SIZE * MACInfo->rxDescCount;
5977 +    pRxBuf = MALLOC(QMemSize);
5978 +    if (pRxBuf == NULL) {
5979 +        AE531X_PRINT(AE531X_DEBUG_RESET,
5980 +                  ("ethmac%d Failed to allocate RX queue\n", MACInfo->unit));
5981 +        goto AllocQFail;
5982 +    }
5983 +
5984 +    if (ae531x_RxQueueCreate(MACInfo, &MACInfo->rxQueue, pRxBuf,
5985 +                          MACInfo->rxDescCount) < 0)
5986 +    {
5987 +        AE531X_PRINT(AE531X_DEBUG_RESET,
5988 +                ("ethmac%d Failed to create RX queue\n", MACInfo->unit));
5989 +        goto AllocQFail;
5990 +    }
5991 +
5992 +    AE531X_PRINT(AE531X_DEBUG_RESET,
5993 +            ("ethmac%d Memory setup complete.\n", MACInfo->unit));
5994 +
5995 +    LEAVE();
5996 +    return 0;
5997 +
5998 +AllocQFail:
5999 +    MACInfo->txDescCount = 0; /* sanity */
6000 +    MACInfo->rxDescCount = 0; /* sanity */
6001 +
6002 +    if (pTxBuf) {
6003 +        FREE(pTxBuf);
6004 +    }
6005 +    if (pRxBuf) {
6006 +        FREE(pRxBuf);
6007 +    }
6008 +    
6009 +    LEAVE();
6010 +    return -1;
6011 +}
6012 +
6013 +
6014 +/******************************************************************************
6015 +*
6016 +* ae531x_FreeQueues - Free Transmit & Receive queues
6017 +*/
6018 +void
6019 +ae531x_FreeQueues(ae531x_MAC_t *MACInfo)
6020 +{
6021 +    ae531x_TxQueueDestroy(MACInfo);
6022 +    FREE(MACInfo->txQueue.firstDescAddr);
6023 +
6024 +    ae531x_RxQueueDestroy(MACInfo);
6025 +    FREE(MACInfo->rxQueue.firstDescAddr);
6026 +}
6027 +
6028 +/******************************************************************************
6029 +*
6030 +* ae531x_DmaReset - Reset DMA and TLI controllers
6031 +*
6032 +* RETURNS: N/A
6033 +*/
6034 +void
6035 +ae531x_DmaReset(ae531x_MAC_t *MACInfo)
6036 +{
6037 +    int        i;
6038 +    UINT32     descAddr;
6039 +
6040 +    ARRIVE();
6041 +
6042 +    /* Disable device interrupts prior to any errors during stop */
6043 +    intDisable(MACInfo->ilevel);
6044 +
6045 +    /* Disable MAC rx and tx */
6046 +    ae531x_ClearMacReg(MACInfo, MacControl, (MacRxEnable | MacTxEnable));
6047 +
6048 +    udelay(1);
6049 +
6050 +    /* Reset dma controller */
6051 +    
6052 +    ae531x_WriteDmaReg(MACInfo, DmaBusMode, DmaResetOn);
6053 +
6054 +    /* Delay 2 usec */
6055 +    sysUDelay(2);
6056 +
6057 +    /* Flush the rx queue */
6058 +    descAddr = (UINT32)MACInfo->rxQueue.firstDescAddr;
6059 +    MACInfo->rxQueue.curDescAddr = MACInfo->rxQueue.firstDescAddr;
6060 +    for (i=0;
6061 +         i<(MACInfo->rxDescCount);
6062 +         i++, descAddr += AE531X_QUEUE_ELE_SIZE) {
6063 +            AE531X_DESC_STATUS_SET(descAddr, DescOwnByDma);
6064 +    }
6065 +
6066 +    /* Flush the tx queue */
6067 +    descAddr = (UINT32)MACInfo->txQueue.firstDescAddr;
6068 +    MACInfo->txQueue.curDescAddr = MACInfo->txQueue.firstDescAddr;
6069 +    MACInfo->txQueue.reapDescAddr = MACInfo->txQueue.lastDescAddr;
6070 +    for (i=0;
6071 +         i<(MACInfo->txDescCount);
6072 +         i++, descAddr += AE531X_QUEUE_ELE_SIZE) {
6073 +            AE531X_DESC_STATUS_SET (descAddr, 0);
6074 +    }
6075 +
6076 +    /* Set init register values  */
6077 +    ae531x_WriteDmaReg(MACInfo, DmaBusMode, DmaBusModeInit);
6078 +
6079 +    /* Install the first Tx and Rx queues on the device */
6080 +    ae531x_WriteDmaReg(MACInfo, DmaRxBaseAddr,
6081 +                      virt_to_bus(MACInfo->rxQueue.firstDescAddr));
6082 +    ae531x_WriteDmaReg(MACInfo, DmaTxBaseAddr,
6083 +                      virt_to_bus(MACInfo->txQueue.firstDescAddr));
6084 +
6085 +
6086 +    ae531x_WriteDmaReg(MACInfo, DmaControl, DmaStoreAndForward);
6087 +
6088 +    ae531x_WriteDmaReg(MACInfo, DmaIntrEnb, DmaIntDisable);
6089 +
6090 +    AE531X_PRINT(AE531X_DEBUG_RESET,
6091 +              ("ethmac%d: DMA RESET!\n", MACInfo->unit));
6092 +
6093 +    /* Turn on device interrupts -- enable most errors */
6094 +    ae531x_DmaIntClear(MACInfo);    /* clear interrupt requests  */
6095 +    ae531x_DmaIntEnable(MACInfo);   /* enable interrupts */
6096 +
6097 +    ae531x_EndResetMode(MACInfo);
6098 +
6099 +    intEnable(MACInfo->ilevel);
6100 +
6101 +    LEAVE();
6102 +}
6103 +
6104 +
6105 +/******************************************************************************
6106 +*
6107 +* ae531x_MACAddressSet - Set the ethernet address
6108 +*
6109 +* Sets the ethernet address according to settings in flash.
6110 +*
6111 +* RETURNS: void
6112 +*/
6113 +static void
6114 +ae531x_MACAddressSet(ae531x_MAC_t *MACInfo)
6115 +{
6116 +    unsigned int    data;
6117 +    UINT8 *macAddr;
6118 +
6119 +    ARRIVE();
6120 +        
6121 +    macAddr = ae531x_enet_mac_address_get(MACInfo->unit);
6122 +
6123 +    /* set our MAC address  */
6124 +    data = (macAddr[5]<<8) | macAddr[4];
6125 +    ae531x_WriteMacReg(MACInfo, MacAddrHigh, data );
6126 +
6127 +    data = (macAddr[3]<<24) | (macAddr[2]<<16) | (macAddr[1]<<8) | macAddr[0];
6128 +    ae531x_WriteMacReg(MACInfo, MacAddrLow, data );
6129 +
6130 +    AE531X_PRINT(AE531X_DEBUG_RESET,
6131 +              ("ethmac%d Verify MAC address %8.8X %8.8X \n",
6132 +               MACInfo->unit,
6133 +               ae531x_ReadMacReg(MACInfo, MacAddrLow),
6134 +               ae531x_ReadMacReg(MACInfo, MacAddrHigh)));
6135 +
6136 +    AE531X_PRINT(AE531X_DEBUG_RESET,
6137 +              ("  sb = %2.2X %2.2X %2.2X %2.2X %2.2X %2.2X\n",
6138 +               0xff&macAddr[0],
6139 +               0xff&macAddr[1],
6140 +               0xff&macAddr[2],
6141 +               0xff&macAddr[3],
6142 +               0xff&macAddr[4],
6143 +               0xff&macAddr[5]));
6144 +    LEAVE();
6145 +}
6146 +
6147 +
6148 +/******************************************************************************
6149 +*
6150 +* ae_SetMACFromPhy - read Phy settings and update Mac
6151 +*                    with current duplex and speed.
6152 +*
6153 +* RETURNS:
6154 +*/
6155 +static void
6156 +ae531x_SetMACFromPhy(ae531x_MAC_t *MACInfo)
6157 +{
6158 +    UINT32  macCtl;
6159 +    BOOL    fullDuplex;
6160 +    UINT32  timeout;
6161 +
6162 +    ARRIVE();
6163 +
6164 +    timeout = jiffies+(HZ/1000)*AE531X_NEGOT_TIMEOUT;
6165 +
6166 +    /* Get duplex mode from Phy */
6167 +    while (((fullDuplex = phyIsFullDuplex(MACInfo->unit)) == -1) &&
6168 +          (jiffies <= timeout));
6169 +
6170 +    /* Flag is set for full duplex mode, else cleared */
6171 +    macCtl = ae531x_ReadMacReg(MACInfo, MacControl);
6172 +
6173 +    if (fullDuplex) {
6174 +        /* set values of control registers */
6175 +        macCtl &= ~MacDisableRxOwn;
6176 +        macCtl |= MacFullDuplex;
6177 +        ae531x_WriteMacReg(MACInfo, MacControl, macCtl);
6178 +        ae531x_WriteMacReg(MACInfo, MacFlowControl, MacFlowControlInitFdx);
6179 +    } else {
6180 +       /* set values of control registers */
6181 +        ae531x_WriteMacReg(MACInfo, MacFlowControl, MacFlowControlInitHdx);
6182 +        macCtl |= MacDisableRxOwn;
6183 +        macCtl &= ~MacFullDuplex;
6184 +        ae531x_WriteMacReg(MACInfo, MacControl, macCtl);
6185 +    }
6186 +
6187 +    LEAVE();
6188 +}
6189 +
6190 +
6191 +/******************************************************************************
6192 +* ae531x_MACReset -- sets MAC address and duplex.
6193 +*/
6194 +void
6195 +ae531x_MACReset(ae531x_MAC_t *MACInfo)
6196 +{
6197 +    ae531x_MACAddressSet(MACInfo);
6198 +#ifndef CONFIG_AR5315
6199 +    ae531x_SetMACFromPhy(MACInfo);
6200 +#endif
6201 +}
6202 +
6203 +
6204 +/******************************************************************************
6205 +* ae531x_EnableComm -- enable Transmit and Receive
6206 +*/
6207 +void
6208 +ae531x_EnableComm(ae531x_MAC_t *MACInfo)
6209 +{
6210 +    ae531x_SetMacReg(MACInfo, MacControl, (MacRxEnable | MacTxEnable));
6211 +    ae531x_DmaRxStart(MACInfo);     /* start receiver  */
6212 +    ae531x_DmaTxStart(MACInfo);     /* start transmitter */
6213 +}
6214 +
6215 +
6216 +/******************************************************************************
6217 +* ae531x_DisableComm -- disable Transmit and Receive
6218 +*/
6219 +void
6220 +ae531x_DisableComm(ae531x_MAC_t *MACInfo)
6221 +{
6222 +    ae531x_ClearMacReg(MACInfo, MacControl, (MacRxEnable | MacTxEnable));
6223 +}
6224 +
6225 +
6226 +/******************************************************************************
6227 +* ae531x_reset -- Cold reset ethernet interface
6228 +*/
6229 +void
6230 +ae531x_reset(ae531x_MAC_t *MACInfo)
6231 +{
6232 +    UINT32 mask = 0;
6233 +    UINT32 regtmp;
6234 +#ifndef CONFIG_AR5315
6235 +   
6236 +    if (MACInfo->unit == 0) {
6237 +        mask = AR531X_RESET_ENET0 | AR531X_RESET_EPHY0;
6238 +    } else {
6239 +        mask = AR531X_RESET_ENET1 | AR531X_RESET_EPHY1;
6240 +    }
6241 +
6242 +    /* Put into reset */
6243 +    regtmp = sysRegRead(AR531X_RESET);
6244 +    sysRegWrite(AR531X_RESET, regtmp | mask);
6245 +    sysMsDelay(15);
6246 +
6247 +    /* Pull out of reset */
6248 +    regtmp = sysRegRead(AR531X_RESET);
6249 +    sysRegWrite(AR531X_RESET, regtmp & ~mask);
6250 +    sysUDelay(25);
6251 +
6252 +    /* Enable */
6253 +    if (MACInfo->unit == 0) {
6254 +        mask = AR531X_ENABLE_ENET0;
6255 +    } else {
6256 +        mask = AR531X_ENABLE_ENET1;
6257 +    }
6258 +    regtmp = sysRegRead(AR531X_ENABLE);
6259 +    sysRegWrite(AR531X_ENABLE, regtmp | mask);
6260 +#else
6261 +    if (MACInfo->unit == 0) {
6262 +        mask = AR531X_RESET_ENET0 | AR531X_RESET_EPHY0;
6263 +    }
6264 +    /* Enable Arbitration for Ethernet bus */
6265 +    regtmp = sysRegRead(AR531XPLUS_AHB_ARB_CTL);
6266 +    regtmp |= ARB_ETHERNET;
6267 +    sysRegWrite(AR531XPLUS_AHB_ARB_CTL, regtmp);
6268 +
6269 +    /* Put into reset */
6270 +    regtmp = sysRegRead(AR531X_RESET);
6271 +    sysRegWrite(AR531X_RESET, regtmp | mask);
6272 +    sysMsDelay(10);
6273 +
6274 +    /* Pull out of reset */
6275 +    regtmp = sysRegRead(AR531X_RESET);
6276 +    sysRegWrite(AR531X_RESET, regtmp & ~mask);
6277 +    sysMsDelay(10);
6278 +
6279 +    regtmp = sysRegRead(AR531XPLUS_IF_CTL);
6280 +    regtmp |= IF_TS_LOCAL;
6281 +    sysRegWrite(AR531XPLUS_IF_CTL, regtmp);
6282 +#endif
6283 +}
6284 +
6285 +
6286 +/******************************************************************************
6287 +* ae531x_unitLinkLost -- Called from PHY layer to notify the MAC layer
6288 +* that there are no longer any live links associated with a MAC.
6289 +*/
6290 +void
6291 +ae531x_unitLinkLost(int ethUnit)
6292 +{
6293 +    AE531X_PRINT(AE531X_DEBUG_LINK_CHANGE,
6294 +             ("enetmac%d link down\n", ethUnit));
6295 +}
6296 +
6297 +
6298 +/******************************************************************************
6299 +* ae531x_unitLinkGained -- Called from PHY layer to notify the MAC layer
6300 +* that there are 1 or more live links associated with a MAC.
6301 +*/
6302 +void
6303 +ae531x_unitLinkGained(int ethUnit)
6304 +{
6305 +#if CONFIG_AR5315
6306 +#define AE531X_POLL_MILLI_SECONDS 200 
6307 +    ae531x_MAC_t *MACInfo = ae531x_getMAcInfo(ethUnit);
6308 +    while(!MACInfo || !MACInfo->port_is_up)
6309 +    {
6310 +        set_current_state(TASK_UNINTERRUPTIBLE);
6311 +        schedule_timeout((AE531X_POLL_MILLI_SECONDS * HZ)/1000);
6312 +        MACInfo = ae531x_getMAcInfo(ethUnit);
6313 +    }
6314 +    ae531x_SetMACFromPhy(MACInfo);
6315 +#endif
6316 +    AE531X_PRINT(AE531X_DEBUG_LINK_CHANGE,
6317 +             ("enet%d link up\n", ethUnit));
6318 +}
6319 +
6320 +/******************************************************************************
6321 +* ae531x_ethMacDefault -- Called from PHY layer to determine the default
6322 +* ethernet MAC.  On some "twisted" platforms, the only usable MAC is 1,
6323 +* while on others the usable MAC is 0.  Future boards may allow both MACs
6324 +* to be used; in this case, return -1 to indicate that there IS NO default
6325 +* MAC.
6326 +*/
6327 +int
6328 +ae531x_ethMacDefault(void)
6329 +{
6330 +    if (ae531x_twisted_enet())
6331 +        return 1;
6332 +
6333 +    return 0;
6334 +
6335 +}
6336 diff -urN linux-mips-orig/drivers/net/ath/ae531xmac.h linux-mips-new/drivers/net/ath/ae531xmac.h
6337 --- linux-mips-orig/drivers/net/ath/ae531xmac.h 1970-01-01 01:00:00.000000000 +0100
6338 +++ linux-mips-new/drivers/net/ath/ae531xmac.h  2005-12-31 12:33:57.674538672 +0000
6339 @@ -0,0 +1,229 @@
6340 +/*
6341 + * This file is subject to the terms and conditions of the GNU General Public
6342 + * License.  See the file "COPYING" in the main directory of this archive
6343 + * for more details.
6344 + *
6345 + * Copyright © 2003 Atheros Communications, Inc.,  All Rights Reserved.
6346 + */
6347 +
6348 +/*
6349 + * See README to understand the decomposition of the ethernet driver.
6350 + *
6351 + * This file contains OS-independent pure software definitions for
6352 + * ethernet support on the AR531X platform.
6353 + */
6354 +
6355 +#ifndef _AE531XMAC_H_
6356 +#define _AE531XMAC_H_
6357 +
6358 +#include <linux/config.h>
6359 +#include <linux/module.h>
6360 +
6361 +/*
6362 + * DEBUG switches to control verbosity.
6363 + * Just modify the value of ae531x_MAC_debug.
6364 + */
6365 +#define AE531X_DEBUG_ALL         0xffffffff
6366 +#define AE531X_DEBUG_ERROR       0x00000001 /* Unusual conditions and Errors */
6367 +#define AE531X_DEBUG_ARRIVE      0x00000002 /* Arrive into a function */
6368 +#define AE531X_DEBUG_LEAVE       0x00000004 /* Leave a function */
6369 +#define AE531X_DEBUG_RESET       0x00000008 /* Reset */
6370 +#define AE531X_DEBUG_TX          0x00000010 /* Transmit */
6371 +#define AE531X_DEBUG_TX_REAP     0x00000020 /* Transmit Descriptor Reaping */
6372 +#define AE531X_DEBUG_RX          0x00000040 /* Receive */
6373 +#define AE531X_DEBUG_RX_STOP     0x00000080 /* Receive Early Stop */
6374 +#define AE531X_DEBUG_INT         0x00000100 /* Interrupts */
6375 +#define AE531X_DEBUG_LINK_CHANGE 0x00000200 /* PHY Link status changed */
6376 +
6377 +#define AE531X_NEGOT_TIMEOUT    500        /* ms to wait for autonegotiation */
6378 +
6379 +extern int ae531x_MAC_debug;
6380 +
6381 +#define AE531X_PRINT(FLG, X)                            \
6382 +{                                                   \
6383 +    if (ae531x_MAC_debug & (FLG)) {                  \
6384 +        DEBUG_PRINTF("%s#%d:%s ",                   \
6385 +                     __FILE__,                      \
6386 +                     __LINE__,                      \
6387 +                     __FUNCTION__);                 \
6388 +        DEBUG_PRINTF X;                             \
6389 +    }                                               \
6390 +}
6391 +
6392 +#define ARRIVE() AE531X_PRINT(AE531X_DEBUG_ARRIVE, ("Arrive{\n"))
6393 +#define LEAVE() AE531X_PRINT(AE531X_DEBUG_LEAVE, ("}Leave\n"))
6394 +
6395 +#define RegRead(addr)  \
6396 +       (*(volatile unsigned int *)(addr))
6397 +
6398 +#define RegWrite(val,addr)     \
6399 +       ((*(volatile unsigned int *)(addr)) = (val))
6400 +
6401 +/*****************************************************************
6402 + * Phy code is broken out into a separate layer, so that different
6403 + * PHY hardware can easily be supported.
6404 + *
6405 + * These functions are provided by the PHY layer for use by the MAC layer.
6406 + *   phySetup             -- Set phy hardware appropriately for a MAC unit
6407 + *
6408 + *   phyCheckStatusChange -- Look for dropped/initiated links on any
6409 + *                           phy port associated with a MAC unit
6410 + *
6411 + *   phyIsSpeed100        -- Determines whether or not a PHY is up and
6412 + *                           running at 100Mbit
6413 + *
6414 + *   phyIsFullDuplex      -- Determines whether or not a PHY is up and
6415 + *                           running in Full Duplex mode
6416 + *
6417 + */
6418 +#if CONFIG_MARVELL_ENET_PHY
6419 +/*
6420 + * Mapping of generic phy APIs to Marvell Ethernet Switch phy functions.
6421 + */
6422 +#include "mvPhy.h"
6423 +#define phySetup(ethUnit, phyBase)      mv_phySetup((ethUnit), (phyBase))
6424 +#define phyCheckStatusChange(ethUnit)   mv_phyCheckStatusChange(ethUnit)
6425 +#define phyIsSpeed100(ethUnit)          mv_phyIsSpeed100(ethUnit)
6426 +#define phyIsFullDuplex(ethUnit)        mv_phyIsFullDuplex(ethUnit)
6427 +
6428 +#if CONFIG_VENETDEV
6429 +#define PHY_TRAILER_SIZE    MV_PHY_TRAILER_SIZE
6430 +extern void mv_phyDetermineSource(char *data, int len, int *pFromLAN);
6431 +extern void mv_phySetDestinationPort(char *data, int len, int fromLAN);
6432 +#define phyDetermineSource(data, len, pFromLAN) mv_phyDetermineSource((data), (len), (pFromLAN))
6433 +#define phySetDestinationPort(data, len, fromLAN) mv_phySetDestinationPort((data), (len), (fromLAN))
6434 +#else
6435 +#define PHY_TRAILER_SIZE    0
6436 +#endif
6437 +#endif /* CONFIG_MARVELL_ENET_PHY */
6438 +
6439 +#if CONFIG_KENDIN_ENET_PHY || CONFIG_REALTEK_ENET_PHY || CONFIG_KENDIN_KS8995XA_ENET_PHY
6440 +/*
6441 + * Mapping of generic phy APIs to Kendin KS8721B and RealTek RTL8201BL phys.
6442 + */
6443 +#include "rtPhy.h"
6444 +#define phySetup(ethUnit, phyBase)      rt_phySetup((ethUnit), (phyBase))
6445 +#define phyCheckStatusChange(ethUnit)   rt_phyCheckStatusChange(ethUnit)
6446 +#define phyIsSpeed100(ethUnit)          rt_phyIsSpeed100(ethUnit)
6447 +#define phyIsFullDuplex(ethUnit)        rt_phyIsFullDuplex(ethUnit)
6448 +#endif
6449 +
6450 +#if CONFIG_ICPLUS_ENET_PHY
6451 +/*
6452 + * Mapping of generic phy APIs to Icplus phys.
6453 + */
6454 +#include "ipPhy.h"
6455 +#define phySetup(ethUnit, phyBase)      ip_phySetup((ethUnit), (phyBase))
6456 +#define phyCheckStatusChange(ethUnit)   ip_phyCheckStatusChange(ethUnit)
6457 +#define phyIsSpeed100(ethUnit)          ip_phyIsSpeed100(ethUnit)
6458 +#define phyIsFullDuplex(ethUnit)        ip_phyIsFullDuplex(ethUnit)
6459 +#endif
6460 +
6461 +#if !defined(PHY_TRAILER_SIZE)
6462 +#define PHY_TRAILER_SIZE    0
6463 +#endif
6464 +
6465 +/*****************************************************************
6466 + * MAC-independent interface to be used by PHY code
6467 + *
6468 + * These functions are provided by the MAC layer for use by the PHY layer.
6469 + */
6470 +#define phyRegRead ae531x_MiiRead
6471 +#define phyRegWrite ae531x_MiiWrite
6472 +#define phyLinkLost(ethUnit) ae531x_unitLinkLost(ethUnit)
6473 +#define phyLinkGained(ethUnit) ae531x_unitLinkGained(ethUnit)
6474 +#define phyEthMacDefault() ae531x_ethMacDefault()
6475 +
6476 +void ae531x_unitLinkLost(int unit);
6477 +void ae531x_unitLinkGained(int unit);
6478 +int ae531x_ethMacDefault(void);
6479 +
6480 +
6481 +/* 
6482 + * RXBUFF_RESERVE enables building header on WLAN-side in place 
6483 + * NB: Divisible by 2 but NOT 4. Otherwise handle_adel_int() will
6484 + *     be used by the ip layer for misaligned word accesses and 
6485 + *     performance will suffer - a lot.
6486 + */
6487 +#define ETH_CRC_LEN       4
6488 +#define RXBUFF_RESERVE   98
6489 +// #define RXBUFF_RESERVE   98
6490 +
6491 +/*****************************************************************
6492 + * Descriptor queue
6493 + */
6494 +typedef struct ae531x_queue {
6495 +    VIRT_ADDR   firstDescAddr;  /* descriptor array address */
6496 +    VIRT_ADDR   lastDescAddr;   /* last descriptor address */
6497 +    VIRT_ADDR   curDescAddr;    /* current descriptor address */
6498 +    VIRT_ADDR   reapDescAddr;   /* current tail of tx descriptors reaped */
6499 +    UINT16      count;          /* number of elements */
6500 +} AE531X_QUEUE;
6501 +
6502 +/* Given a descriptor, return the next one in a circular list */
6503 +#define AE531X_QUEUE_ELE_NEXT_GET(q, descAddr)                          \
6504 +        ((descAddr) == (q)->lastDescAddr) ? (q)->firstDescAddr :    \
6505 +        (VIRT_ADDR)((UINT32)(descAddr) + AE531X_QUEUE_ELE_SIZE)
6506 +
6507 +/* Move the "current descriptor" forward to the next one */
6508 +#define AE531X_CONSUME_DESC(q)    \
6509 +         q->curDescAddr = AE531X_QUEUE_ELE_NEXT_GET(q, q->curDescAddr)
6510 +
6511 +/*****************************************************************
6512 + * Per-ethernet-MAC OS-independent information
6513 + */
6514 +typedef struct ae531x_MAC_s {
6515 +    u32             unit;          /* MAC unit ID */
6516 +    u32             macBase;       /* MAC base address */
6517 +    u32             dmaBase;       /* DMA base address */
6518 +    u32             phyBase;       /* PHY base address */
6519 +    AE531X_QUEUE    txQueue;       /* Transmit descriptor queue */
6520 +    AE531X_QUEUE    rxQueue;       /* Receive descriptor queue */
6521 +    UINT16          txDescCount;   /* Transmit descriptor count */
6522 +    UINT16          rxDescCount;   /* Receive descriptor count */
6523 +    BOOL            aeProcessRst;  /* flag to indicate reset in progress */
6524 +    BOOL            port_is_up;    /* flag to indicate port is up */
6525 +    void            *OSinfo;       /* OS-dependent data */
6526 +} ae531x_MAC_t;
6527 +
6528 +#define        AE531X_TX_DESC_COUNT_DEFAULT    128    /* Transmit descriptors */
6529 +#define AE531X_RX_DESC_COUNT_DEFAULT   128    /* Receive descriptors */
6530 +
6531 +
6532 +/*****************************************************************
6533 + * Interfaces exported by the OS-independent MAC layer
6534 + */
6535 +void ae531x_BeginResetMode(ae531x_MAC_t *MACInfo);
6536 +void ae531x_EndResetMode(ae531x_MAC_t *MACInfo);
6537 +BOOL ae531x_IsInResetMode(ae531x_MAC_t *MACInfo);
6538 +int ae531x_RxQueueCreate(ae531x_MAC_t *MACInfo, AE531X_QUEUE *q,
6539 +                  char *pMem, int count);
6540 +int ae531x_QueueDelete(struct ae531x_queue *q);
6541 +void ae531x_DmaReset(ae531x_MAC_t *MACInfo);
6542 +void ae531x_MACReset(ae531x_MAC_t *MACInfo);
6543 +void ae531x_EnableComm(ae531x_MAC_t *MACInfo);
6544 +void ae531x_DisableComm(ae531x_MAC_t *MACInfo);
6545 +void ae531x_reset(ae531x_MAC_t *MACInfo);
6546 +int ae531x_AllocateQueues(ae531x_MAC_t *MACInfo);
6547 +void ae531x_FreeQueues(ae531x_MAC_t *MACInfo);
6548 +void ae531x_QueueInit(AE531X_QUEUE *q, char *pMem, int count);
6549 +UINT32 ae531x_ReadMacReg(ae531x_MAC_t *MACInfo, UINT32 reg);
6550 +void ae531x_WriteMacReg(ae531x_MAC_t *MACInfo, UINT32 reg, UINT32 data);
6551 +void ae531x_SetMacReg(ae531x_MAC_t *MACInfo, UINT32 reg, UINT32 val);
6552 +void ae531x_ClearMacReg(ae531x_MAC_t *MACInfo, UINT32 reg, UINT32 val);
6553 +void ae531x_SetDmaReg(ae531x_MAC_t *MACInfo, UINT32 reg, UINT32 val);
6554 +void ae531x_ClearDmaReg(ae531x_MAC_t *MACInfo, UINT32 reg, UINT32 val);
6555 +UINT32 ae531x_ReadDmaReg(ae531x_MAC_t *MACInfo, UINT32 reg);
6556 +void ae531x_WriteDmaReg(ae531x_MAC_t *MACInfo, UINT32 reg, UINT32 data);
6557 +UINT32 ae531x_ReadMiiReg(UINT32 phyBase, UINT32 reg);
6558 +void ae531x_WriteMiiReg(UINT32 phyBase, UINT32 reg, UINT32 data);
6559 +UINT16 ae531x_MiiRead(UINT32 phyBase, UINT32 phyAddr, UINT8 reg);
6560 +void ae531x_MiiWrite(UINT32 phyBase, UINT32 phyAddr, UINT8 reg, UINT16 data);
6561 +void ae531x_DmaIntEnable(ae531x_MAC_t *MACInfo);
6562 +void ae531x_DmaIntDisable(ae531x_MAC_t *MACInfo);
6563 +void ae531x_AckIntr(ae531x_MAC_t *MACInfo, UINT32 val);
6564 +void *ae531x_rxbuf_alloc(ae531x_MAC_t *MACInfo, char **rxBptr, int *rxBSize);
6565 +void ae531x_swptr_free(VIRT_ADDR txDesc);
6566 +BOOL ae531x_twisted_enet(void);
6567 +
6568 +#endif /* _AE531XMAC_H_ */
6569 diff -urN linux-mips-orig/drivers/net/ath/ae531xreg.h linux-mips-new/drivers/net/ath/ae531xreg.h
6570 --- linux-mips-orig/drivers/net/ath/ae531xreg.h 1970-01-01 01:00:00.000000000 +0100
6571 +++ linux-mips-new/drivers/net/ath/ae531xreg.h  2005-12-31 12:33:57.675538520 +0000
6572 @@ -0,0 +1,439 @@
6573 +/*
6574 + * This file is subject to the terms and conditions of the GNU General Public
6575 + * License.  See the file "COPYING" in the main directory of this archive
6576 + * for more details.
6577 + *
6578 + * Copyright © 2003 Atheros Communications, Inc.,  All Rights Reserved.
6579 + */
6580 +
6581 +/*
6582 + * See README to understand the decomposition of the ethernet driver.
6583 + *
6584 + * Register definitions for Atheros AR531X Ethernet MAC.
6585 + */
6586 +
6587 +#ifndef _AE531XREG_H_
6588 +#define _AE531XREG_H_
6589 +
6590 +#define AE531X_MAC_OFFSET 0x0000
6591 +#define AE531X_PHY_OFFSET 0x0000 /* Same as MAC offset */
6592 +#define AE531X_DMA_OFFSET 0x1000
6593 +
6594 +/***********************************************************/
6595 +/* MAC110 registers, base address is BAR+AE531X_MAC_OFFSET */
6596 +/***********************************************************/
6597 +#define MacControl            0x00  /* control */
6598 +#define MacAddrHigh           0x04  /* address high */
6599 +#define MacAddrLow            0x08  /* address low */
6600 +#define MacMultiHashHigh      0x0C  /* multicast hash table high */
6601 +#define MacMultiHashLow       0x10  /* multicast hash table low */
6602 +#define MacMiiAddr            0x14  /* MII address */
6603 +#define MacMiiData            0x18  /* MII data */
6604 +#define MacFlowControl        0x1C  /* Flow control */
6605 +#define MacVlan1Tag           0x4C  /* VLAN1 tag */
6606 +#define MacVlan2Tag           0x50  /* VLAN2 tag */
6607 +
6608 +
6609 +/***************************************************************/
6610 +/* DMA engine registers, base address is BAR+AE531X_DMA_OFFSET */
6611 +/***************************************************************/
6612 +#define DmaBusMode      0x00 /* CSR0 - Bus Mode */
6613 +#define DmaTxPollDemand 0x04 /* CSR1 - Transmit Poll Demand */
6614 +#define DmaRxPollDemand 0x08 /* CSR2 - Receive Poll Demand */
6615 +#define DmaRxBaseAddr   0x0C /* CSR3 - Receive list base address */
6616 +#define DmaTxBaseAddr   0x10 /* CSR4 - Transmit list base address */
6617 +#define DmaStatus       0x14 /* CSR5 - Dma status */
6618 +#define DmaControl      0x18 /* CSR6 - Dma control */
6619 +#define DmaIntrEnb      0x1C /* CSR7 - Interrupt enable */
6620 +#define DmaOverflowCnt  0x20 /* CSR8 - Missed Frame and Buff Overflow counter */
6621 +#define DmaTxCurrAddr   0x50 /* CSR20 - Current host transmit buffer address */
6622 +#define DmaRxCurrAddr   0x54 /* CSR21 - Current host receive buffer address */
6623 +
6624 +/**********************************************************/
6625 +/* MAC Control register layout                            */
6626 +/**********************************************************/
6627 +#define MacFilterOff           0x80000000 /* Receive all incoming packets RW */
6628 +#define MacFilterOn                     0 /* Receive filtered packets only 0 */
6629 +#define MacBigEndian           0x40000000 /* Big endian mode RW */
6630 +#define MacLittleEndian                 0 /* Little endian 0 */
6631 +#define MacHeartBeatOff        0x10000000 /* Heartbeat signal qual disable RW*/
6632 +#define MacHeartBeatOn                  0 /* Heartbeat signal qual enable 0 */
6633 +#define MacSelectSrl           0x08000000 /* Select SRL port RW */
6634 +#define MacSelectMii                    0 /* Select MII port 0 */
6635 +#define MacDisableRxOwn        0x00800000 /* Disable receive own packets RW */
6636 +#define MacEnableRxOwn                  0 /* Enable receive own packets 0 */
6637 +#define MacLoopbackExt         0x00400000 /* External loopback RW */
6638 +#define MacLoopbackInt         0x00200000 /* Internal loopback */
6639 +#define MacLoopbackOff                  0 /* Normal mode 00 */
6640 +#define MacFullDuplex          0x00100000 /* Full duplex mode RW */
6641 +#define MacHalfDuplex                   0 /* Half duplex mode 0 */
6642 +#define MacMulticastFilterOff  0x00080000 /* Pass all multicast packets RW */
6643 +#define MacMulticastFilterOn            0 /* Pass filtered mcast packets 0 */
6644 +#define MacPromiscuousModeOn   0x00040000 /* Receive all valid packets RW 1 */
6645 +#define MacPromiscuousModeOff           0 /* Receive filtered packets only */
6646 +#define MacFilterInverse       0x00020000 /* Inverse filtering RW */
6647 +#define MacFilterNormal                 0 /* Normal filtering 0 */
6648 +#define MacBadFramesEnable     0x00010000 /* Pass bad frames RW */
6649 +#define MacBadFramesDisable             0 /* Do not pass bad frames 0 */
6650 +#define MacPerfectFilterOff    0x00008000 /* Hash filtering only RW */
6651 +#define MacPerfectFilterOn              0 /* Both perfect and hash filtering 0 */
6652 +#define MacHashFilterOn        0x00002000 /* perform hash filtering RW */
6653 +#define MacHashFilterOff                0 /* perfect filtering only 0 */
6654 +#define MacLateCollisionOn     0x00001000 /* Enable late collision control RW */
6655 +#define MacLateCollisionOff             0 /* Disable late collision control 0 */
6656 +#define MacBroadcastDisable    0x00000800 /* Disable reception of bcast frames RW */
6657 +#define MacBroadcastEnable              0 /* Enable broadcast frames 0 */
6658 +#define MacRetryDisable        0x00000400 /* Disable retransmission RW */
6659 +#define MacRetryEnable                  0 /* Enable retransmission 0 */
6660 +#define MacPadStripEnable      0x00000100 /* Pad stripping enable RW */
6661 +#define MacPadStripDisable              0 /* Pad stripping disable 0 */
6662 +#define MacBackoff                      0 /* Backoff Limit RW 00 */
6663 +#define MacDeferralCheckEnable 0x00000020 /* Deferral check enable RW */
6664 +#define MacDeferralCheckDisable         0 /* Deferral check disable 0 */
6665 +#define MacTxEnable            0x00000008 /* Transmitter enable RW */
6666 +#define MacTxDisable                    0 /* Transmitter disable 0 */
6667 +#define MacRxEnable            0x00000004 /* Receiver enable RW */
6668 +#define MacRxDisable                    0 /* Receiver disable 0 */
6669 +
6670 +
6671 +/**********************************************************/
6672 +/* MII address register layout                            */
6673 +/**********************************************************/
6674 +#define MiiDevMask   0x0000F800 /* MII device address */
6675 +#define MiiDevShift          11
6676 +#define MiiRegMask   0x000007C0 /* MII register */
6677 +#define MiiRegShift           6
6678 +#define MiiWrite     0x00000002 /* Write to register */
6679 +#define MiiRead               0 /* Read from register */
6680 +#define MiiBusy      0x00000001 /* MII interface is busy */
6681 +
6682 +/**********************************************************/
6683 +/* MII Data register layout                               */
6684 +/**********************************************************/
6685 +#define MiiDataMask  0x0000FFFF /* MII Data */
6686 +
6687 +/**********************************************************/
6688 +/* MAC flow control register layout                       */
6689 +/**********************************************************/
6690 +#define MacPauseTimeMask      0xFFFF0000  /* PAUSE TIME field in ctrl frame */
6691 +#define MacPauseTimeShift             15
6692 +#define MacControlFrameEnable 0x00000004  /* Enable pass ctrl frames to host */
6693 +#define MacControlFrameDisable         0  /* Do not pass ctrl frames to host */
6694 +#define MacFlowControlEnable  0x00000002  /* Enable flow control */
6695 +#define MacFlowControlDisable          0  /* Disable flow control */
6696 +#define MacSendPauseFrame     0x00000001  /* send pause frame */
6697 +
6698 +/**********************************************************/
6699 +/* DMA bus mode register layout                           */
6700 +/**********************************************************/
6701 +#define DmaRxAlign16            0x01000000 /* Force all rx buffers to align on odd hw bndry */
6702 +#define DmaBigEndianDes         0x00100000 /* Big endian data buffer descriptors RW */
6703 +#define DmaLittleEndianDesc              0 /* Little endian data descriptors */
6704 +#define DmaBurstLength32        0x00002000 /* Dma burst length 32 RW */
6705 +#define DmaBurstLength16        0x00001000 /* Dma burst length 16 */
6706 +#define DmaBurstLength8         0x00000800 /* Dma burst length 8 */
6707 +#define DmaBurstLength4         0x00000400 /* Dma burst length 4 */
6708 +#define DmaBurstLength2         0x00000200 /* Dma burst length 2 */
6709 +#define DmaBurstLength1         0x00000100 /* Dma burst length 1 */
6710 +#define DmaBurstLength0         0x00000000 /* Dma burst length 0 */
6711 +#define DmaBigEndianData        0x00000080 /* Big endian data buffers RW */
6712 +#define DmaLittleEndianData              0 /* Little endian data buffers 0 */
6713 +#define DmaDescriptorSkip16     0x00000040 /* number of dwords to skip RW */
6714 +#define DmaDescriptorSkip8      0x00000020 /* between two unchained descriptors */
6715 +#define DmaDescriptorSkip4      0x00000010
6716 +#define DmaDescriptorSkip2      0x00000008
6717 +#define DmaDescriptorSkip1      0x00000004
6718 +#define DmaDescriptorSkip0               0
6719 +#define DmaReceivePriorityOff   0x00000002 /* equal rx and tx priorities RW */
6720 +#define DmaReceivePriorityOn             0 /* Rx has prioryty over Tx 0 */
6721 +#define DmaResetOn              0x00000001 /* Reset DMA engine RW */
6722 +#define DmaResetOff                      0
6723 +
6724 +/**********************************************************/
6725 +/* DMA Status register layout                             */
6726 +/**********************************************************/
6727 +#define DmaRxAbort        0x01000000 /* receiver bus abort R 0 */
6728 +#define DmaTxAbort        0x00800000 /* transmitter bus abort R 0 */
6729 +#define DmaTxState        0x00700000 /* Transmit process state R 000 */
6730 +#define DmaTxStopped      0x00000000 /* Stopped */
6731 +#define DmaTxFetching     0x00100000 /* Running - fetching the descriptor */
6732 +#define DmaTxWaiting      0x00200000 /* Running - waiting for end of transmission */
6733 +#define DmaTxReading      0x00300000 /* Running - reading the data from memory */
6734 +#define DmaTxSuspended    0x00600000 /* Suspended */
6735 +#define DmaTxClosing      0x00700000 /* Running - closing descriptor */
6736 +#define DmaRxState        0x000E0000 /* Receive process state 000 */
6737 +#define DmaRxStopped      0x00000000 /* Stopped */
6738 +#define DmaRxFetching     0x00020000 /* Running - fetching the descriptor */
6739 +#define DmaRxChecking     0x00040000 /* Running - checking for end of packet */
6740 +#define DmaRxWaiting      0x00060000 /* Running - waiting for packet */
6741 +#define DmaRxSuspended    0x00080000 /* Suspended */
6742 +#define DmaRxClosing      0x000A0000 /* Running - closing descriptor */
6743 +#define DmaRxFlushing     0x000C0000 /* Running - flushing the current frame */
6744 +#define DmaRxQueuing      0x000E0000 /* Running - queuing the recieve frame into host memory */
6745 +#define DmaIntNormal      0x00010000 /* Normal interrupt summary RW 0 */
6746 +#define DmaIntAbnormal    0x00008000 /* Abnormal interrupt summary RW 0 */
6747 +#define DmaIntEarlyRx     0x00004000 /* Early receive interrupt (Normal) RW 0 */
6748 +#define DmaIntBusError    0x00002000 /* Fatal bus error (Abnormal) RW 0 */
6749 +#define DmaIntEarlyTx     0x00000400 /* Early transmit interrupt RW 0 */
6750 +#define DmaIntRxStopped   0x00000100 /* Receive process stopped (Abnormal) RW 0 */
6751 +#define DmaIntRxNoBuffer  0x00000080 /* Receive buffer unavailable (Abnormal) RW 0*/
6752 +#define DmaIntRxCompleted 0x00000040 /* Completion of frame reception(Normal) RW 0*/
6753 +#define DmaIntTxUnderflow 0x00000020 /* Transmit underflow (Abnormal) RW 0 */
6754 +#define DmaIntTxJabber    0x00000008 /* Transmit Jabber Timeout (Abnormal) RW 0 */ 
6755 +#define DmaIntTxNoBuffer  0x00000004 /* Transmit buffer unavailable (Normal) RW 0*/
6756 +#define DmaIntTxStopped   0x00000002 /* Transmit process stopped (Abnormal) RW 0 */
6757 +#define DmaIntTxCompleted 0x00000001 /* Transmit completed (Normal) RW 0 */
6758 +
6759 +/**********************************************************/
6760 +/* DMA control register layout                            */
6761 +/**********************************************************/
6762 +#define DmaStoreAndForward 0x00000000 /* Store and forward RW 0 */
6763 +#define DmaTxThreshCtl256  0x0000c000 /* Non-SF threshold is 256 words */
6764 +#define DmaTxThreshCtl128  0x00008000 /* Non-SF threshold is 128 words */
6765 +#define DmaTxThreshCtl064  0x00004000 /* Non-SF threshold is 64 words */
6766 +#define DmaTxThreshCtl032  0x00000000 /* Non-SF threshold is 32 words */
6767 +#define DmaTxStart         0x00002000 /* Start/Stop transmission RW 0 */
6768 +#define DmaTxSecondFrame   0x00000004 /* Operate on second frame RW 0 */
6769 +#define DmaRxStart         0x00000002 /* Start/Stop reception RW 0 */
6770 +
6771 +/**********************************************************/
6772 +/* DMA interrupt enable register layout                   */
6773 +/**********************************************************/
6774 +#define DmaIeNormal      DmaIntNormal      /* Normal interrupt enable RW 0 */
6775 +#define DmaIeAbnormal    DmaIntAbnormal    /* Abnormal interrupt enable RW 0 */
6776 +#define DmaIeEarlyRx     DmaIntEarlyRx     /* Early receive interrupt enable RW 0 */
6777 +#define DmaIeBusError    DmaIntBusError    /* Fatal bus error enable RW 0 */
6778 +#define DmaIeEarlyTx     DmaIntEarlyTx     /* Early transmit interrupt enable RW 0 */
6779 +#define DmaIeRxStopped   DmaIntRxStopped   /* Receive process stopped enable RW 0 */
6780 +#define DmaIeRxNoBuffer  DmaIntRxNoBuffer  /* Receive buffer unavailable enable RW 0 */
6781 +#define DmaIeRxCompleted DmaIntRxCompleted /* Completion of frame reception enable RW 0 */
6782 +#define DmaIeTxUnderflow DmaIntTxUnderflow /* Transmit underflow enable RW 0 */
6783 +#define DmaIeTxJabber    DmaIntTxJabber    /* Transmit jabber timeout RW 0 */
6784 +#define DmaIeTxNoBuffer  DmaIntTxNoBuffer  /* Transmit buffer unavailable enable RW 0 */
6785 +#define DmaIeTxStopped   DmaIntTxStopped   /* Transmit process stopped enable RW 0 */
6786 +#define DmaIeTxCompleted DmaIntTxCompleted /* Transmit completed enable RW 0 */
6787 +
6788 +/****************************************************************/
6789 +/* DMA Missed Frame and Buffer Overflow Counter register layout */
6790 +/****************************************************************/
6791 +#define DmaRxBufferMissedFrame  0xffff0000  /* cleared on read */
6792 +#define DmaMissedFrameShift             16
6793 +#define DmaRxBufferOverflowCnt  0x0000ffff  /* cleared on read */
6794 +#define DmaMissedFrameCountMask 0x0000ffff
6795 +
6796 +/**********************************************************/
6797 +/* DMA Engine descriptor layout                           */
6798 +/**********************************************************/
6799 +/* status word of DMA descriptor */
6800 +#define DescOwnByDma         0x80000000 /* Descriptor is owned by DMA engine */
6801 +#define DescFrameLengthMask  0x3FFF0000 /* Receive descriptor frame length */
6802 +#define DescFrameLengthShift         16
6803 +#define DescError            0x00008000 /* Error summary bit OR of following bits */
6804 +#define DescRxTruncated      0x00004000 /* Rx - no more descs for receive frame */
6805 +#define DescRxLengthError    0x00001000 /* Rx - frame size not matching with length field */
6806 +#define DescRxRunt           0x00000800 /* Rx - runt frame, damaged by a
6807 +                                           collision or term before 64 bytes */
6808 +#define DescRxMulticast      0x00000400 /* Rx - received frame is multicast */
6809 +#define DescRxFirst          0x00000200 /* Rx - first descriptor of the frame */
6810 +#define DescRxLast           0x00000100 /* Rx - last descriptor of the frame */
6811 +#define DescRxLongFrame      0x00000080 /* Rx - frame is longer than 1518 bytes */
6812 +#define DescRxLateColl       0x00000040 /* Rx - frame was damaged by a late collision */
6813 +#define DescRxFrameEther     0x00000020 /* Rx - Frame type Ethernet 802.3*/ 
6814 +#define DescRxMiiError       0x00000008 /* Rx - error reported by MII interface */
6815 +#define DescRxDribbling      0x00000004 /* Rx - frame contains noninteger multiple of 8 bits */
6816 +#define DescRxCrc            0x00000002 /* Rx - CRC error */
6817 +#define DescTxTimeout        0x00004000 /* Tx - Transmit jabber timeout */
6818 +#define DescTxLostCarrier    0x00000800 /* Tx - carrier lost during tramsmission */
6819 +#define DescTxNoCarrier      0x00000400 /* Tx - no carrier signal from tranceiver */
6820 +#define DescTxLateCollision  0x00000200 /* Tx - transmission aborted due to collision */
6821 +#define DescTxExcCollisions  0x00000100 /* Tx - transmission aborted after 16 collisions */
6822 +#define DescTxHeartbeatFail  0x00000080 /* Tx - heartbeat collision check failure */
6823 +#define DescTxCollMask       0x00000078 /* Tx - Collision count */
6824 +#define DescTxCollShift               3
6825 +#define DescTxExcDeferral    0x00000004 /* Tx - excessive deferral */
6826 +#define DescTxUnderflow      0x00000002 /* Tx - late data arrival from memory */
6827 +#define DescTxDeferred       0x00000001 /* Tx - frame transmision deferred */
6828 +
6829 +/* length word of DMA descriptor */
6830 +#define DescTxIntEnable      0x80000000 /* Tx - interrupt on completion */
6831 +#define DescTxLast           0x40000000 /* Tx - Last segment of the frame */
6832 +#define DescTxFirst          0x20000000 /* Tx - First segment of the frame */
6833 +#define DescTxDisableCrc     0x04000000 /* Tx - Add CRC disabled (first segment only) */
6834 +#define DescEndOfRing        0x02000000 /* End of descriptors ring */
6835 +#define DescChain            0x01000000 /* Second buffer address is chain address */
6836 +#define DescTxDisablePadd    0x00800000 /* disable padding */
6837 +#define DescSize2Mask        0x003FF800 /* Buffer 2 size */
6838 +#define DescSize2Shift               11
6839 +#define DescSize1Mask        0x000007FF /* Buffer 1 size */
6840 +#define DescSize1Shift                0
6841 +
6842 +/**********************************************************/
6843 +/* Initial register values                                */
6844 +/**********************************************************/
6845 +/* Full-duplex mode with perfect filter on */
6846 +#define MacControlInitFdx \
6847 +       ( MacFilterOn \
6848 +       | MacLittleEndian \
6849 +       | MacHeartBeatOn \
6850 +       | MacSelectMii \
6851 +       | MacEnableRxOwn \
6852 +       | MacLoopbackOff \
6853 +       | MacFullDuplex \
6854 +       | MacMulticastFilterOn \
6855 +       | MacPromiscuousModeOff \
6856 +       | MacFilterNormal \
6857 +       | MacBadFramesDisable \
6858 +       | MacPerfectFilterOn \
6859 +       | MacHashFilterOff \
6860 +       | MacLateCollisionOff \
6861 +       | MacBroadcastEnable \
6862 +       | MacRetryEnable \
6863 +       | MacPadStripDisable \
6864 +       | MacDeferralCheckDisable \
6865 +       | MacTxEnable \
6866 +       | MacRxEnable)
6867 +
6868 +/* Full-duplex mode */
6869 +#define MacFlowControlInitFdx \
6870 +        ( MacControlFrameDisable \
6871 +        | MacFlowControlEnable)
6872 +
6873 +/* Half-duplex mode with perfect filter on */
6874 +#define MacControlInitHdx \
6875 +       ( MacFilterOn \
6876 +       | MacLittleEndian \
6877 +       | MacHeartBeatOn \
6878 +       | MacSelectMii \
6879 +       | MacDisableRxOwn \
6880 +       | MacLoopbackOff \
6881 +       | MacHalfDuplex \
6882 +       | MacMulticastFilterOn \
6883 +       | MacPromiscuousModeOff \
6884 +       | MacFilterNormal \
6885 +       | MacBadFramesDisable \
6886 +       | MacPerfectFilterOn \
6887 +       | MacHashFilterOff \
6888 +       | MacLateCollisionOff \
6889 +       | MacBroadcastEnable \
6890 +       | MacRetryEnable \
6891 +       | MacPadStripDisable \
6892 +       | MacDeferralCheckDisable \
6893 +       | MacTxEnable \
6894 +       | MacRxEnable)
6895 +
6896 +/* Half-duplex mode */
6897 +#define MacFlowControlInitHdx \
6898 +        ( MacControlFrameDisable \
6899 +        | MacFlowControlDisable)
6900 +
6901 +/* Bus Mode Rx odd half word align */
6902 +#define DmaBusModeInit  \
6903 +       ( DmaLittleEndianDesc \
6904 +       | DmaRxAlign16 \
6905 +       | DmaBurstLength32 \
6906 +       | DmaBigEndianData \
6907 +       | DmaDescriptorSkip1 \
6908 +       | DmaReceivePriorityOn \
6909 +       | DmaResetOff)
6910 +
6911 +#define DmaControlInit (DmaStoreAndForward)
6912 +
6913 +/* Interrupt groups */
6914 +#define DmaIntEnable \
6915 +     ( DmaIeNormal \
6916 +     | DmaIeAbnormal \
6917 +     | DmaIntBusError \
6918 +     | DmaIntRxStopped \
6919 +     | DmaIntRxNoBuffer \
6920 +     | DmaIntRxCompleted \
6921 +     | DmaIntTxUnderflow \
6922 +     | DmaIntTxStopped)
6923 +
6924 +#define DmaIntDisable 0
6925 +
6926 +#define DmaAllIntCauseMask \
6927 +      ( DmaIeNormal  \
6928 +      | DmaIeAbnormal  \
6929 +      | DmaIntEarlyRx  \
6930 +      | DmaIntBusError \
6931 +      | DmaIntEarlyTx  \
6932 +      | DmaIntRxStopped \
6933 +      | DmaIntRxNoBuffer \
6934 +      | DmaIntRxCompleted \
6935 +      | DmaIntTxUnderflow \
6936 +      | DmaIntTxJabber \
6937 +      | DmaIntTxNoBuffer \
6938 +      | DmaIntTxStopped \
6939 +      | DmaIntTxCompleted)
6940 +
6941 +#define UnhandledIntrMask    \
6942 +       (DmaAllIntCauseMask   \
6943 +       & ~(DmaIntRxNoBuffer  \
6944 +         | DmaIntTxStopped   \
6945 +         | DmaIntTxJabber    \
6946 +         | DmaIntTxUnderflow \
6947 +         | DmaIntBusError    \
6948 +         | DmaIntRxCompleted ))
6949 +
6950 +#define DescRxErrors    \
6951 +      (DescRxTruncated  \
6952 +     | DescRxRunt       \
6953 +     | DescRxLateColl   \
6954 +     | DescRxMiiError   \
6955 +     | DescRxCrc)
6956 +
6957 +#define DescTxErrors        \
6958 +     ( DescTxTimeout        \
6959 +     | DescTxLateCollision  \
6960 +     | DescTxExcCollisions  \
6961 +     | DescTxExcDeferral    \
6962 +     | DescTxUnderflow)
6963 +
6964 +/**********************************************************/
6965 +/* Descriptor Layout                                      */
6966 +/**********************************************************/
6967 +#define AE531X_DESC_STATUS     0x00 /* Status offset */
6968 +#define AE531X_DESC_CTRLEN     0x04 /* Control and Length offset */ 
6969 +#define AE531X_DESC_BUFPTR     0x08 /* Buffer pointer offset */
6970 +#define AE531X_DESC_LNKBUF     0x0c /* Link field offset, or ptr to 2nd buf */
6971 +#define AE531X_DESC_SWPTR      0x10 /* OS-Dependent software pointer */
6972 +
6973 +#define AE531X_DESC_SIZE       0x10 /* 4 words, 16 bytes */
6974 +#define AE531X_QUEUE_ELE_SIZE  0x14 /* with software pointer extension */
6975 +
6976 +/* Accessors to the dma descriptor fields */
6977 +#define AE531X_DESC_STATUS_GET(ptr) \
6978 +    *(volatile UINT32 *)((UINT32)(ptr) + AE531X_DESC_STATUS)
6979 +
6980 +#define AE531X_DESC_STATUS_SET(ptr, val)  \
6981 +    AE531X_DESC_STATUS_GET(ptr) = (val)
6982 +
6983 +#define AE531X_DESC_CTRLEN_GET(ptr) \
6984 +    *(volatile UINT32 *)((UINT32)ptr + AE531X_DESC_CTRLEN)
6985 +
6986 +#define AE531X_DESC_CTRLEN_SET(ptr, val)  \
6987 +    AE531X_DESC_CTRLEN_GET(ptr) = (val)
6988 +
6989 +#define AE531X_DESC_BUFPTR_GET(ptr) \
6990 +    *(volatile UINT32 *)((UINT32)ptr + AE531X_DESC_BUFPTR)
6991 +
6992 +#define AE531X_DESC_BUFPTR_SET(ptr,val)  \
6993 +    AE531X_DESC_BUFPTR_GET(ptr) = (UINT32)(val)
6994 +
6995 +#define AE531X_DESC_LNKBUF_GET(ptr)  \
6996 +    *(volatile UINT32 *)((UINT32)ptr + AE531X_DESC_LNKBUF)
6997 +
6998 +#define AE531X_DESC_LNKBUF_SET(ptr, val)  \
6999 +    AE531X_DESC_LNKBUF_GET(ptr) = (val)
7000 +
7001 +#define AE531X_DESC_SWPTR_GET(ptr) \
7002 +    (void *)(*(volatile UINT32 *) ((UINT32)ptr + AE531X_DESC_SWPTR))
7003 +
7004 +#define AE531X_DESC_SWPTR_SET(ptr,val)   \
7005 +    AE531X_DESC_SWPTR_GET(ptr) = (void *)(val)
7006 +
7007 +/* Get size of Rx data from desc, in bytes */
7008 +#define AE531X_DESC_STATUS_RX_SIZE(x) \
7009 +        (((x) & DescFrameLengthMask) >> DescFrameLengthShift)
7010 +
7011 +#endif /* _AE531XREG_H_ */
7012 diff -urN linux-mips-orig/drivers/net/ath/ar531x.h linux-mips-new/drivers/net/ath/ar531x.h
7013 --- linux-mips-orig/drivers/net/ath/ar531x.h    1970-01-01 01:00:00.000000000 +0100
7014 +++ linux-mips-new/drivers/net/ath/ar531x.h     2005-12-31 12:33:57.676538368 +0000
7015 @@ -0,0 +1,1124 @@
7016 +/*
7017 + * This file is subject to the terms and conditions of the GNU General Public
7018 + * License.  See the file "COPYING" in the main directory of this archive
7019 + * for more details.
7020 + *
7021 + * Copyright © 2003 Atheros Communications, Inc.,  All Rights Reserved.
7022 + */
7023 +
7024 +#ifndef AR531X_H
7025 +#define AR531X_H 1
7026 +
7027 +
7028 +#ifndef CONFIG_AR5315
7029 +
7030 +#include <asm/addrspace.h>
7031 +
7032 +/* Address Map */
7033 +#define AR531X_WLAN0            0x18000000
7034 +#define AR531X_WLAN1            0x18500000
7035 +#define AR531X_ENET0            0x18100000
7036 +#define AR531X_ENET1            0x18200000
7037 +#define AR531X_SDRAMCTL         0x18300000
7038 +#define AR531X_FLASHCTL         0x18400000
7039 +#define AR531X_APBBASE         0x1c000000
7040 +#define AR531X_FLASH            0x1e000000
7041 +
7042 +/*
7043 + * AR531X_NUM_ENET_MAC defines the number of ethernet MACs that
7044 + * should be considered available.  The AR5312 supports 2 enet MACS,
7045 + * even though many reference boards only actually use 1 of them
7046 + * (i.e. Only MAC 0 is actually connected to an enet PHY or PHY switch.
7047 + * The AR2312 supports 1 enet MAC.
7048 + */
7049 +#define AR531X_NUM_ENET_MAC             2
7050 +
7051 +/*
7052 + * Need these defines to determine true number of ethernet MACs
7053 + */
7054 +#define AR5212_AR5312_REV2      0x0052          /* AR5312 WMAC (AP31) */
7055 +#define AR5212_AR5312_REV7      0x0057          /* AR5312 WMAC (AP30-040) */
7056 +#define AR5212_AR2313_REV8      0x0058          /* AR2313 WMAC (AP43-030) */
7057 +#define AR531X_RADIO_MASK_OFF  0xc8
7058 +#define AR531X_RADIO0_MASK     0x0003
7059 +#define AR531X_RADIO1_MASK     0x000c
7060 +#define AR531X_RADIO1_S        2 
7061 +
7062 +/*
7063 + * AR531X_NUM_WMAC defines the number of Wireless MACs that\
7064 + * should be considered available.
7065 + */
7066 +#define AR531X_NUM_WMAC                 2
7067 +
7068 +/* Reset/Timer Block Address Map */
7069 +#define AR531X_RESETTMR                (AR531X_APBBASE  + 0x3000)
7070 +#define AR531X_TIMER           (AR531X_RESETTMR + 0x0000) /* countdown timer */
7071 +#define AR531X_WD_CTRL          (AR531X_RESETTMR + 0x0008) /* watchdog cntrl */
7072 +#define AR531X_WD_TIMER         (AR531X_RESETTMR + 0x000c) /* watchdog timer */
7073 +#define AR531X_ISR             (AR531X_RESETTMR + 0x0010) /* Intr Status Reg */
7074 +#define AR531X_IMR             (AR531X_RESETTMR + 0x0014) /* Intr Mask Reg */
7075 +#define AR531X_RESET           (AR531X_RESETTMR + 0x0020)
7076 +#define AR5312_CLOCKCTL1       (AR531X_RESETTMR + 0x0064)
7077 +#define AR5312_SCRATCH         (AR531X_RESETTMR + 0x006c)
7078 +#define AR531X_PROCADDR                (AR531X_RESETTMR + 0x0070)
7079 +#define AR531X_PROC1           (AR531X_RESETTMR + 0x0074)
7080 +#define AR531X_DMAADDR         (AR531X_RESETTMR + 0x0078)
7081 +#define AR531X_DMA1            (AR531X_RESETTMR + 0x007c)
7082 +#define AR531X_ENABLE           (AR531X_RESETTMR + 0x0080) /* interface enb */
7083 +#define AR531X_REV             (AR531X_RESETTMR + 0x0090) /* revision */
7084 +
7085 +/* AR531X_WD_CTRL register bit field definitions */
7086 +#define AR531X_WD_CTRL_IGNORE_EXPIRATION 0x0000
7087 +#define AR531X_WD_CTRL_NMI               0x0001
7088 +#define AR531X_WD_CTRL_RESET             0x0002
7089 +
7090 +/* AR531X_ISR register bit field definitions */
7091 +#define AR531X_ISR_NONE                0x0000
7092 +#define AR531X_ISR_TIMER       0x0001
7093 +#define AR531X_ISR_AHBPROC     0x0002
7094 +#define AR531X_ISR_AHBDMA      0x0004
7095 +#define AR531X_ISR_GPIO                0x0008
7096 +#define AR531X_ISR_UART0       0x0010
7097 +#define AR531X_ISR_UART0DMA    0x0020
7098 +#define AR531X_ISR_WD          0x0040
7099 +#define AR531X_ISR_LOCAL       0x0080
7100 +
7101 +/* AR531X_RESET register bit field definitions */
7102 +#define AR531X_RESET_SYSTEM     0x00000001  /* cold reset full system */
7103 +#define AR531X_RESET_PROC       0x00000002  /* cold reset MIPS core */
7104 +#define AR531X_RESET_WLAN0      0x00000004  /* cold reset WLAN MAC and BB */
7105 +#define AR531X_RESET_EPHY0      0x00000008  /* cold reset ENET0 phy */
7106 +#define AR531X_RESET_EPHY1      0x00000010  /* cold reset ENET1 phy */
7107 +#define AR531X_RESET_ENET0      0x00000020  /* cold reset ENET0 mac */
7108 +#define AR531X_RESET_ENET1      0x00000040  /* cold reset ENET1 mac */
7109 +#define AR531X_RESET_UART0      0x00000100  /* cold reset UART0 (high speed) */
7110 +#define AR531X_RESET_WLAN1      0x00000200  /* cold reset WLAN MAC/BB */
7111 +#define AR531X_RESET_APB        0x00000400  /* cold reset APB (ar5312) */
7112 +#define AR531X_RESET_WARM_PROC  0x00001000  /* warm reset MIPS core */
7113 +#define AR531X_RESET_WARM_WLAN0_MAC 0x00002000  /* warm reset WLAN0 MAC */
7114 +#define AR531X_RESET_WARM_WLAN0_BB  0x00004000  /* warm reset WLAN0 BaseBand */
7115 +#define AR531X_RESET_NMI        0x00010000  /* send an NMI to the processor */
7116 +#define AR531X_RESET_WARM_WLAN1_MAC 0x00020000  /* warm reset WLAN1 mac */
7117 +#define AR531X_RESET_WARM_WLAN1_BB  0x00040000  /* warm reset WLAN1 baseband */
7118 +#define AR531X_RESET_LOCAL_BUS  0x00080000  /* reset local bus */
7119 +#define AR531X_RESET_WDOG       0x00100000  /* last reset was a watchdog */
7120 +
7121 +#define AR531X_RESET_WMAC0_BITS \
7122 +        AR531X_RESET_WLAN0 |\
7123 +        AR531X_RESET_WARM_WLAN0_MAC |\
7124 +        AR531X_RESET_WARM_WLAN0_BB
7125 +
7126 +#define AR531X_RESERT_WMAC1_BITS \
7127 +        AR531X_RESET_WLAN1 |\
7128 +        AR531X_RESET_WARM_WLAN1_MAC |\
7129 +        AR531X_RESET_WARM_WLAN1_BB
7130 +
7131 +/* AR5312_CLOCKCTL1 register bit field definitions */
7132 +#define AR5312_CLOCKCTL1_PREDIVIDE_MASK    0x00000030
7133 +#define AR5312_CLOCKCTL1_PREDIVIDE_SHIFT            4
7134 +#define AR5312_CLOCKCTL1_MULTIPLIER_MASK   0x00001f00
7135 +#define AR5312_CLOCKCTL1_MULTIPLIER_SHIFT           8
7136 +#define AR5312_CLOCKCTL1_DOUBLER_MASK      0x00010000
7137 +
7138 +/* Valid for AR5312 and AR2312 */
7139 +#define AR5312_CLOCKCTL1_PREDIVIDE_MASK    0x00000030
7140 +#define AR5312_CLOCKCTL1_PREDIVIDE_SHIFT            4
7141 +#define AR5312_CLOCKCTL1_MULTIPLIER_MASK   0x00001f00
7142 +#define AR5312_CLOCKCTL1_MULTIPLIER_SHIFT           8
7143 +#define AR5312_CLOCKCTL1_DOUBLER_MASK      0x00010000
7144 +
7145 +/* Valid for AR2313 */
7146 +#define AR2313_CLOCKCTL1_PREDIVIDE_MASK    0x00003000
7147 +#define AR2313_CLOCKCTL1_PREDIVIDE_SHIFT           12
7148 +#define AR2313_CLOCKCTL1_MULTIPLIER_MASK   0x001f0000
7149 +#define AR2313_CLOCKCTL1_MULTIPLIER_SHIFT          16
7150 +#define AR2313_CLOCKCTL1_DOUBLER_MASK      0x00000000
7151 +
7152 +
7153 +/* AR531X_ENABLE register bit field definitions */
7154 +#define AR531X_ENABLE_WLAN0              0x0001
7155 +#define AR531X_ENABLE_ENET0              0x0002
7156 +#define AR531X_ENABLE_ENET1              0x0004
7157 +#define AR531X_ENABLE_UART_AND_WLAN1_PIO 0x0008   /* UART, and WLAN1 PIOs */
7158 +#define AR531X_ENABLE_WLAN1_DMA          0x0010   /* WLAN1 DMAs */
7159 +#define AR531X_ENABLE_WLAN1 \
7160 +            (AR531X_ENABLE_UART_AND_WLAN1_PIO | AR531X_ENABLE_WLAN1_DMA)
7161 +
7162 +/* AR531X_REV register bit field definitions */
7163 +#define AR531X_REV_WMAC_MAJ    0xf000
7164 +#define AR531X_REV_WMAC_MAJ_S  12
7165 +#define AR531X_REV_WMAC_MIN    0x0f00
7166 +#define AR531X_REV_WMAC_MIN_S  8
7167 +#define AR531X_REV_MAJ         0x00f0
7168 +#define AR531X_REV_MAJ_S       4
7169 +#define AR531X_REV_MIN         0x000f
7170 +#define AR531X_REV_MIN_S       0
7171 +#define AR531X_REV_CHIP        (REV_MAJ|REV_MIN)
7172 +
7173 +/* Major revision numbers, bits 7..4 of Revision ID register */
7174 +#define AR531X_REV_MAJ_AR5312          0x4
7175 +#define AR531X_REV_MAJ_AR2313          0x5
7176 +
7177 +/* Minor revision numbers, bits 3..0 of Revision ID register */
7178 +#define AR5312_REV_MIN_DUAL     0x0     /* Dual WLAN version */
7179 +#define AR5312_REV_MIN_SINGLE   0x1     /* Single WLAN version */
7180 +
7181 +/* AR531X_FLASHCTL register bit field definitions */
7182 +#define FLASHCTL_IDCY   0x0000000f      /* Idle cycle turn around time */
7183 +#define FLASHCTL_IDCY_S 0
7184 +#define FLASHCTL_WST1   0x000003e0      /* Wait state 1 */
7185 +#define FLASHCTL_WST1_S 5
7186 +#define FLASHCTL_RBLE   0x00000400      /* Read byte lane enable */
7187 +#define FLASHCTL_WST2   0x0000f800      /* Wait state 2 */
7188 +#define FLASHCTL_WST2_S 11
7189 +#define FLASHCTL_AC     0x00070000      /* Flash address check (added) */
7190 +#define FLASHCTL_AC_S   16
7191 +#define FLASHCTL_AC_128K 0x00000000
7192 +#define FLASHCTL_AC_256K 0x00010000
7193 +#define FLASHCTL_AC_512K 0x00020000
7194 +#define FLASHCTL_AC_1M   0x00030000
7195 +#define FLASHCTL_AC_2M   0x00040000
7196 +#define FLASHCTL_AC_4M   0x00050000
7197 +#define FLASHCTL_AC_8M   0x00060000
7198 +#define FLASHCTL_AC_RES  0x00070000     /* 16MB is not supported */
7199 +#define FLASHCTL_E      0x00080000      /* Flash bank enable (added) */
7200 +#define FLASHCTL_BUSERR 0x01000000      /* Bus transfer error status flag */
7201 +#define FLASHCTL_WPERR  0x02000000      /* Write protect error status flag */
7202 +#define FLASHCTL_WP     0x04000000      /* Write protect */
7203 +#define FLASHCTL_BM     0x08000000      /* Burst mode */
7204 +#define FLASHCTL_MW     0x30000000      /* Memory width */
7205 +#define FLASHCTL_MWx8   0x00000000      /* Memory width x8 */
7206 +#define FLASHCTL_MWx16  0x10000000      /* Memory width x16 */
7207 +#define FLASHCTL_MWx32  0x20000000      /* Memory width x32 (not supported) */
7208 +#define FLASHCTL_ATNR   0x00000000      /* Access type == no retry */
7209 +#define FLASHCTL_ATR    0x80000000      /* Access type == retry every */
7210 +#define FLASHCTL_ATR4   0xc0000000      /* Access type == retry every 4 */
7211 +
7212 +/* ARM Flash Controller -- 3 flash banks with either x8 or x16 devices.  */
7213 +#define AR531X_FLASHCTL0        (AR531X_FLASHCTL + 0x00)
7214 +#define AR531X_FLASHCTL1        (AR531X_FLASHCTL + 0x04)
7215 +#define AR531X_FLASHCTL2        (AR531X_FLASHCTL + 0x08)
7216 +
7217 +/* ARM SDRAM Controller -- just enough to determine memory size */
7218 +#define AR531X_MEM_CFG1 (AR531X_SDRAMCTL + 0x04)
7219 +#define MEM_CFG1_AC0    0x00000700      /* bank 0: SDRAM addr check (added) */
7220 +#define MEM_CFG1_AC0_S  8
7221 +#define MEM_CFG1_AC1    0x00007000      /* bank 1: SDRAM addr check (added) */
7222 +#define MEM_CFG1_AC1_S  12
7223 +
7224 +/* GPIO Address Map */
7225 +#define AR531X_GPIO         (AR531X_APBBASE  + 0x2000)
7226 +#define AR531X_GPIO_DO      (AR531X_GPIO + 0x00)        /* output register */
7227 +#define AR531X_GPIO_DI      (AR531X_GPIO + 0x04)        /* intput register */
7228 +#define AR531X_GPIO_CR      (AR531X_GPIO + 0x08)        /* control register */
7229 +
7230 +/* GPIO Control Register bit field definitions */
7231 +#define GPIO_CR_M(x)    (1 << (x))                      /* mask for i/o */
7232 +#define GPIO_CR_O(x)    (0 << (x))                      /* mask for output */
7233 +#define GPIO_CR_I(x)    (1 << (x))                      /* mask for input */
7234 +#define GPIO_CR_INT(x)  (1 << ((x)+8))                  /* mask for interrupt */
7235 +#define GPIO_CR_UART(x) (1 << ((x)+16))                 /* uart multiplex */
7236 +
7237 +
7238 +typedef unsigned int AR531X_REG;
7239 +
7240 +#define sysRegRead(phys)       \
7241 +       (*(volatile AR531X_REG *)PHYS_TO_K1(phys))
7242 +
7243 +#define sysRegWrite(phys, val) \
7244 +       ((*(volatile AR531X_REG *)PHYS_TO_K1(phys)) = (val))
7245 +
7246 +
7247 +/*
7248 + * This is board-specific data that is stored in a "fixed" location in flash.
7249 + * It is shared across operating systems, so it should not be changed lightly.
7250 + * The main reason we need it is in order to extract the ethernet MAC
7251 + * address(es).
7252 + */
7253 +struct ar531x_boarddata {
7254 +    u32 magic;                       /* board data is valid */
7255 +#define AR531X_BD_MAGIC 0x35333131   /* "5311", for all 531x platforms */
7256 +    u16 cksum;                       /* checksum (starting with BD_REV 2) */
7257 +    u16 rev;                         /* revision of this struct */
7258 +#define BD_REV  4
7259 +    char   boardName[64];            /* Name of board */
7260 +    u16 major;                       /* Board major number */
7261 +    u16 minor;                       /* Board minor number */
7262 +    u32 config;                      /* Board configuration */
7263 +#define BD_ENET0        0x00000001   /* ENET0 is stuffed */
7264 +#define BD_ENET1        0x00000002   /* ENET1 is stuffed */
7265 +#define BD_UART1        0x00000004   /* UART1 is stuffed */
7266 +#define BD_UART0        0x00000008   /* UART0 is stuffed (dma) */
7267 +#define BD_RSTFACTORY   0x00000010   /* Reset factory defaults stuffed */
7268 +#define BD_SYSLED       0x00000020   /* System LED stuffed */
7269 +#define BD_EXTUARTCLK   0x00000040   /* External UART clock */
7270 +#define BD_CPUFREQ      0x00000080   /* cpu freq is valid in nvram */
7271 +#define BD_SYSFREQ      0x00000100   /* sys freq is set in nvram */
7272 +#define BD_WLAN0        0x00000200   /* Enable WLAN0 */
7273 +#define BD_MEMCAP       0x00000400   /* CAP SDRAM @ memCap for testing */
7274 +#define BD_DISWATCHDOG  0x00000800   /* disable system watchdog */
7275 +#define BD_WLAN1        0x00001000   /* Enable WLAN1 (ar5212) */
7276 +#define BD_ISCASPER     0x00002000   /* FLAG for AR2312 */
7277 +#define BD_WLAN0_2G_EN  0x00004000   /* FLAG for radio0_2G */
7278 +#define BD_WLAN0_5G_EN  0x00008000   /* FLAG for radio0_2G */
7279 +#define BD_WLAN1_2G_EN  0x00020000   /* FLAG for radio0_2G */
7280 +#define BD_WLAN1_5G_EN  0x00040000   /* FLAG for radio0_2G */
7281 +    u16 resetConfigGpio;             /* Reset factory GPIO pin */
7282 +    u16 sysLedGpio;                  /* System LED GPIO pin */
7283 +
7284 +    u32 cpuFreq;                     /* CPU core frequency in Hz */
7285 +    u32 sysFreq;                     /* System frequency in Hz */
7286 +    u32 cntFreq;                     /* Calculated C0_COUNT frequency */
7287 +
7288 +    u8  wlan0Mac[6];
7289 +    u8  enet0Mac[6];
7290 +    u8  enet1Mac[6];
7291 +
7292 +    u16 pciId;                       /* Pseudo PCIID for common code */
7293 +    u16 memCap;                      /* cap bank1 in MB */
7294 +
7295 +    /* version 3 */
7296 +    u8  wlan1Mac[6];                 /* (ar5212) */
7297 +};
7298 +
7299 +#else
7300 +
7301 +/*
7302 + * Add support for Cobra
7303 + *
7304 + * AR531XPLUSreg.h Register definitions for Atheros AR5311 and AR5312 chipsets.
7305 + *   - WLAN registers are listed in
7306 + *         hal/ar5211/ar5211Reg.h
7307 + *         hal/ar5212/ar5212Reg.h
7308 + *   - Ethernet registers are listed in ar531xenet.h
7309 + *   - Standard UART is 16550 compatible.
7310 + */
7311 +
7312 +
7313 +/*
7314 + * Address map
7315 + */
7316 +#define AR531XPLUS_SDRAM0           0x00000000      /* DRAM */
7317 +#define AR531XPLUS_SPI_READ         0x08000000      /* SPI FLASH */
7318 +#define AR531XPLUS_WLAN0            0xB0000000      /* Wireless MMR */
7319 +#define AR531XPLUS_PCI              0xB0100000      /* PCI MMR */
7320 +#define AR531XPLUS_SDRAMCTL         0xB0300000      /* SDRAM MMR */
7321 +#define AR531XPLUS_LOCAL            0xB0400000      /* LOCAL BUS MMR */
7322 +#define AR531XPLUS_ENET0            0xB0500000      /* ETHERNET MMR */
7323 +#define AR531XPLUS_DSLBASE          0xB1000000      /* RESET CONTROL MMR */
7324 +#define AR531XPLUS_UART0            0xB1100003      /* UART MMR */
7325 +#define AR531XPLUS_SPI              0xB1300000      /* SPI FLASH MMR */
7326 +#define AR531XPLUS_FLASHBT          0xBfc00000      /* ro boot alias to FLASH */
7327 +#define AR531XPLUS_RAM1             0x40000000      /* ram alias */
7328 +#define AR531XPLUS_PCIEXT           0x80000000      /* pci external */
7329 +#define AR531XPLUS_RAM2             0xc0000000      /* ram alias */
7330 +#define AR531XPLUS_RAM3             0xe0000000      /* ram alias */
7331 +
7332 +#define AR531X_ENET0  AR531XPLUS_ENET0       
7333 +#define AR531X_ENET1  0 
7334 +/*
7335 + * Reset Register
7336 + */
7337 +#define AR531XPLUS_COLD_RESET       (AR531XPLUS_DSLBASE + 0x0000)
7338 +
7339 +/* Cold Reset */
7340 +#define RESET_COLD_AHB              0x00000001
7341 +#define RESET_COLD_APB              0x00000002
7342 +#define RESET_COLD_CPU              0x00000004
7343 +#define RESET_COLD_CPUWARM          0x00000008
7344 +#define RESET_SYSTEM                (RESET_COLD_CPU | RESET_COLD_APB | RESET_COLD_AHB)      /* full system */
7345 +
7346 +/* Warm Reset */
7347 +
7348 +#define AR531XPLUS_RESET            (AR531XPLUS_DSLBASE + 0x0004)
7349 +#define AR531X_RESET AR531XPLUS_RESET
7350 +
7351 +#define RESET_WARM_WLAN0_MAC        0x00000001      /* warm reset WLAN0 MAC */
7352 +#define RESET_WARM_WLAN0_BB         0x00000002      /* warm reset WLAN0 BaseBand */
7353 +#define RESET_MPEGTS_RSVD           0x00000004      /* warm reset MPEG-TS */
7354 +#define RESET_PCIDMA                0x00000008      /* warm reset PCI ahb/dma */
7355 +#define RESET_MEMCTL                0x00000010      /* warm reset memory controller */
7356 +#define RESET_LOCAL                 0x00000020      /* warm reset local bus */
7357 +#define RESET_I2C_RSVD              0x00000040      /* warm reset I2C bus */
7358 +#define RESET_SPI                   0x00000080      /* warm reset SPI interface */
7359 +#define RESET_UART0                 0x00000100      /* warm reset UART0 */
7360 +#define RESET_IR_RSVD               0x00000200      /* warm reset IR interface */
7361 +#define RESET_EPHY0                 0x00000400      /* cold reset ENET0 phy */
7362 +#define RESET_ENET0                 0x00000800      /* cold reset ENET0 mac */
7363 +
7364 +#define AR531X_RESET_ENET0 RESET_ENET0
7365 +#define AR531X_RESET_EPHY0 RESET_EPHY0
7366 +#define AR531X_RESET_ENET1 0
7367 +#define AR531X_RESET_EPHY1 0
7368 +
7369 +/*
7370 + * AHB master arbitration control
7371 + */
7372 +#define AR531XPLUS_AHB_ARB_CTL      (AR531XPLUS_DSLBASE + 0x0008)
7373 +
7374 +#define ARB_CPU                     0x00000001      /* CPU, default */
7375 +#define ARB_WLAN                    0x00000002      /* WLAN */
7376 +#define ARB_MPEGTS_RSVD             0x00000004      /* MPEG-TS */
7377 +#define ARB_LOCAL                   0x00000008      /* LOCAL */
7378 +#define ARB_PCI                     0x00000010      /* PCI */
7379 +#define ARB_ETHERNET                0x00000020      /* Ethernet */
7380 +#define ARB_RETRY                   0x00000100      /* retry policy, debug only */
7381 +
7382 +/*
7383 + * Config Register
7384 + */
7385 +#define AR531XPLUS_ENDIAN_CTL       (AR531XPLUS_DSLBASE + 0x000c)
7386 +
7387 +#define CONFIG_AHB                  0x00000001      /* EC - AHB bridge endianess */
7388 +#define CONFIG_WLAN                 0x00000002      /* WLAN byteswap */
7389 +#define CONFIG_MPEGTS_RSVD          0x00000004      /* MPEG-TS byteswap */
7390 +#define CONFIG_PCI                  0x00000008      /* PCI byteswap */
7391 +#define CONFIG_MEMCTL               0x00000010      /* Memory controller endianess */
7392 +#define CONFIG_LOCAL                0x00000020      /* Local bus byteswap */
7393 +#define CONFIG_ETHERNET             0x00000040      /* Ethernet byteswap */
7394 +
7395 +#define CONFIG_MERGE                0x00000200      /* CPU write buffer merge */
7396 +#define CONFIG_CPU                  0x00000400      /* CPU big endian */
7397 +#define CONFIG_PCIAHB               0x00000800
7398 +#define CONFIG_PCIAHB_BRIDGE        0x00001000
7399 +#define CONFIG_SPI                  0x00008000      /* SPI byteswap */
7400 +#define CONFIG_CPU_DRAM             0x00010000
7401 +#define CONFIG_CPU_PCI              0x00020000
7402 +#define CONFIG_CPU_MMR              0x00040000
7403 +#define CONFIG_BIG                  0x00000400      
7404 +
7405 +
7406 +/*
7407 + * NMI control
7408 + */
7409 +#define AR531XPLUS_NMI_CTL          (AR531XPLUS_DSLBASE + 0x0010)
7410 +
7411 +#define NMI_EN  1
7412 +
7413 +/*
7414 + * Revision Register - Initial value is 0x3010 (WMAC 3.0, AR531X 1.0).
7415 + */
7416 +#define AR531XPLUS_SREV             (AR531XPLUS_DSLBASE + 0x0014)
7417 +
7418 +#define AR531X_REV  AR531XPLUS_SREV
7419 +
7420 +#define REV_MAJ                     0x00f0
7421 +#define REV_MAJ_S                   4
7422 +#define REV_MIN                     0x000f
7423 +#define REV_MIN_S                   0
7424 +#define REV_CHIP                    (REV_MAJ|REV_MIN)
7425 +
7426 +#define AR531X_REV_MAJ REV_MAJ
7427 +#define AR531X_REV_MAJ_S REV_MAJ_S
7428 +#define AR531X_REV_MIN REV_MIN 
7429 +#define AR531X_REV_MIN_S REV_MIN_S 
7430 +#define REV_CHIP                    (REV_MAJ|REV_MIN)
7431 +/*
7432 + * Need these defines to determine true number of ethernet MACs
7433 + */
7434 +#define AR5212_AR5312_REV2      0x0052          /* AR5312 WMAC (AP31) */
7435 +#define AR5212_AR5312_REV7      0x0057          /* AR5312 WMAC (AP30-040) */
7436 +#define AR5212_AR2313_REV8      0x0058          /* AR2313 WMAC (AP43-030) */
7437 +#define AR531X_RADIO_MASK_OFF  0xc8
7438 +#define AR531X_RADIO0_MASK     0x0003
7439 +#define AR531X_RADIO1_MASK     0x000c
7440 +#define AR531X_RADIO1_S        2 
7441 +
7442 +/* Major revision numbers, bits 7..4 of Revision ID register */
7443 +#define AR531X_REV_MAJ_AR5312          0x4
7444 +#define AR531X_REV_MAJ_AR2313          0x5
7445 +
7446 +/*
7447 + * AR531X_NUM_ENET_MAC defines the number of ethernet MACs that
7448 + * should be considered available.  The AR5312 supports 2 enet MACS,
7449 + * even though many reference boards only actually use 1 of them
7450 + * (i.e. Only MAC 0 is actually connected to an enet PHY or PHY switch.
7451 + * The AR2312 supports 1 enet MAC.
7452 + */
7453 +#define AR531X_NUM_ENET_MAC             1
7454 +
7455 +/*
7456 + * Interface Enable
7457 + */
7458 +#define AR531XPLUS_IF_CTL           (AR531XPLUS_DSLBASE + 0x0018)
7459 +
7460 +#define IF_MASK                     0x00000007
7461 +#define IF_DISABLED                 0
7462 +#define IF_PCI                      1
7463 +#define IF_TS_LOCAL                 2
7464 +#define IF_ALL                      3   /* only for emulation with separate pins */
7465 +#define IF_LOCAL_HOST               0x00000008
7466 +#define IF_PCI_HOST                 0x00000010
7467 +#define IF_PCI_INTR                 0x00000020
7468 +#define IF_PCI_CLK_MASK             0x00030000
7469 +#define IF_PCI_CLK_INPUT            0 
7470 +#define IF_PCI_CLK_OUTPUT_LOW       1
7471 +#define IF_PCI_CLK_OUTPUT_CLK       2
7472 +#define IF_PCI_CLK_OUTPUT_HIGH      3
7473 +#define IF_PCI_CLK_SHIFT            16 
7474
7475 +                
7476 +/* Major revision numbers, bits 7..4 of Revision ID register */
7477 +#define REV_MAJ_AR5311              0x01
7478 +#define REV_MAJ_AR5312              0x04
7479 +#define REV_MAJ_AR5315              0x0B
7480 +
7481 +/*
7482 + * APB Interrupt control
7483 + */
7484 +
7485 +#define AR531XPLUS_ISR              (AR531XPLUS_DSLBASE + 0x0020)
7486 +#define AR531XPLUS_IMR              (AR531XPLUS_DSLBASE + 0x0024)
7487 +#define AR531XPLUS_GISR             (AR531XPLUS_DSLBASE + 0x0028)
7488 +
7489 +#define ISR_UART0                   0x0001           /* high speed UART */
7490 +#define ISR_I2C_RSVD                0x0002           /* I2C bus */
7491 +#define ISR_SPI                     0x0004           /* SPI bus */
7492 +#define ISR_AHB                     0x0008           /* AHB error */
7493 +#define ISR_APB                     0x0010           /* APB error */
7494 +#define ISR_TIMER                   0x0020           /* timer */
7495 +#define ISR_GPIO                    0x0040           /* GPIO */
7496 +#define ISR_WD                      0x0080           /* watchdog */
7497 +#define ISR_IR_RSVD                 0x0100           /* IR */
7498 +                                
7499 +#define IMR_UART0                   ISR_UART0
7500 +#define IMR_I2C_RSVD                ISR_I2C_RSVD
7501 +#define IMR_SPI                     ISR_SPI
7502 +#define IMR_AHB                     ISR_AHB
7503 +#define IMR_APB                     ISR_APB
7504 +#define IMR_TIMER                   ISR_TIMER
7505 +#define IMR_GPIO                    ISR_GPIO
7506 +#define IMR_WD                      ISR_WD
7507 +#define IMR_IR_RSVD                 ISR_IR_RSVD
7508 +
7509 +#define GISR_MISC                   0x0001
7510 +#define GISR_WLAN0                  0x0002
7511 +#define GISR_MPEGTS_RSVD            0x0004
7512 +#define GISR_LOCALPCI               0x0008
7513 +#define GISR_WMACPOLL               0x0010
7514 +#define GISR_TIMER                  0x0020
7515 +#define GISR_ETHERNET               0x0040
7516 +
7517 +/*
7518 + * Interrupt routing from IO to the processor IP bits
7519 + * Define our inter mask and level
7520 + */
7521 +#define AR531XPLUS_INTR_MISCIO      SR_IBIT3
7522 +#define AR531XPLUS_INTR_WLAN0       SR_IBIT4
7523 +#define AR531XPLUS_INTR_ENET0       SR_IBIT5
7524 +#define AR531XPLUS_INTR_LOCALPCI    SR_IBIT6
7525 +#define AR531XPLUS_INTR_WMACPOLL    SR_IBIT7
7526 +#define AR531XPLUS_INTR_COMPARE     SR_IBIT8
7527 +
7528 +/*
7529 + * Timers
7530 + */
7531 +#define AR531XPLUS_TIMER            (AR531XPLUS_DSLBASE + 0x0030)
7532 +#define AR531XPLUS_RELOAD           (AR531XPLUS_DSLBASE + 0x0034)
7533 +#define AR531XPLUS_WD               (AR531XPLUS_DSLBASE + 0x0038)
7534 +#define AR531XPLUS_WDC              (AR531XPLUS_DSLBASE + 0x003c)
7535 +
7536 +#define WDC_RESET                   0x00000002               /* reset on watchdog */
7537 +#define WDC_NMI                     0x00000001               /* NMI on watchdog */
7538 +#define WDC_IGNORE_EXPIRATION       0x00000000
7539 +
7540 +/*
7541 + * Interface Debug
7542 + */
7543 +#define AR531X_FLASHDBG             (AR531X_RESETTMR + 0x0040)
7544 +#define AR531X_MIIDBG               (AR531X_RESETTMR + 0x0044)
7545 +
7546 +
7547 +/*
7548 + * CPU Performance Counters
7549 + */
7550 +#define AR531XPLUS_PERFCNT0         (AR531XPLUS_DSLBASE + 0x0048)
7551 +#define AR531XPLUS_PERFCNT1         (AR531XPLUS_DSLBASE + 0x004c)
7552 +
7553 +#define PERF_DATAHIT                0x0001  /* Count Data Cache Hits */
7554 +#define PERF_DATAMISS               0x0002  /* Count Data Cache Misses */
7555 +#define PERF_INSTHIT                0x0004  /* Count Instruction Cache Hits */
7556 +#define PERF_INSTMISS               0x0008  /* Count Instruction Cache Misses */
7557 +#define PERF_ACTIVE                 0x0010  /* Count Active Processor Cycles */
7558 +#define PERF_WBHIT                  0x0020  /* Count CPU Write Buffer Hits */
7559 +#define PERF_WBMISS                 0x0040  /* Count CPU Write Buffer Misses */
7560 +                                
7561 +#define PERF_EB_ARDY                0x0001  /* Count EB_ARdy signal */
7562 +#define PERF_EB_AVALID              0x0002  /* Count EB_AValid signal */
7563 +#define PERF_EB_WDRDY               0x0004  /* Count EB_WDRdy signal */
7564 +#define PERF_EB_RDVAL               0x0008  /* Count EB_RdVal signal */
7565 +#define PERF_VRADDR                 0x0010  /* Count valid read address cycles */
7566 +#define PERF_VWADDR                 0x0020  /* Count valid write address cycles */
7567 +#define PERF_VWDATA                 0x0040  /* Count valid write data cycles */
7568 +
7569 +/*
7570 + * AHB Error Reporting.
7571 + */
7572 +#define AR531XPLUS_AHB_ERR0         (AR531XPLUS_DSLBASE + 0x0050)  /* error  */
7573 +#define AR531XPLUS_AHB_ERR1         (AR531XPLUS_DSLBASE + 0x0054)  /* haddr  */
7574 +#define AR531XPLUS_AHB_ERR2         (AR531XPLUS_DSLBASE + 0x0058)  /* hwdata */
7575 +#define AR531XPLUS_AHB_ERR3         (AR531XPLUS_DSLBASE + 0x005c)  /* hrdata */
7576 +#define AR531XPLUS_AHB_ERR4         (AR531XPLUS_DSLBASE + 0x0060)  /* status */
7577 +
7578 +#define AHB_ERROR_DET               1   /* AHB Error has been detected,          */
7579 +                                        /* write 1 to clear all bits in ERR0     */
7580 +#define AHB_ERROR_OVR               2   /* AHB Error overflow has been detected  */
7581 +#define AHB_ERROR_WDT               4   /* AHB Error due to wdt instead of hresp */
7582 +
7583 +#define PROCERR_HMAST               0x0000000f
7584 +#define PROCERR_HMAST_DFLT          0
7585 +#define PROCERR_HMAST_WMAC          1
7586 +#define PROCERR_HMAST_ENET          2
7587 +#define PROCERR_HMAST_PCIENDPT      3
7588 +#define PROCERR_HMAST_LOCAL         4
7589 +#define PROCERR_HMAST_CPU           5
7590 +#define PROCERR_HMAST_PCITGT        6
7591 +                                    
7592 +#define PROCERR_HMAST_S             0
7593 +#define PROCERR_HWRITE              0x00000010
7594 +#define PROCERR_HSIZE               0x00000060
7595 +#define PROCERR_HSIZE_S             5
7596 +#define PROCERR_HTRANS              0x00000180
7597 +#define PROCERR_HTRANS_S            7
7598 +#define PROCERR_HBURST              0x00000e00
7599 +#define PROCERR_HBURST_S            9
7600 +
7601 +
7602 +
7603 +/*
7604 + * Clock Control
7605 + */
7606 +#define AR531XPLUS_PLLC_CTL         (AR531XPLUS_DSLBASE + 0x0064)
7607 +#define AR531XPLUS_PLLV_CTL         (AR531XPLUS_DSLBASE + 0x0068)
7608 +#define AR531XPLUS_CPUCLK           (AR531XPLUS_DSLBASE + 0x006c)
7609 +#define AR531XPLUS_AMBACLK          (AR531XPLUS_DSLBASE + 0x0070)
7610 +#define AR531XPLUS_SYNCCLK          (AR531XPLUS_DSLBASE + 0x0074)
7611 +#define AR531XPLUS_DSL_SLEEP_CTL    (AR531XPLUS_DSLBASE + 0x0080)
7612 +#define AR531XPLUS_DSL_SLEEP_DUR    (AR531XPLUS_DSLBASE + 0x0084)
7613 +
7614 +/* PLLc Control fields */
7615 +#define PLLC_REF_DIV_M              0x00000003
7616 +#define PLLC_REF_DIV_S              0
7617 +#define PLLC_FDBACK_DIV_M           0x0000007C
7618 +#define PLLC_FDBACK_DIV_S           2
7619 +#define PLLC_ADD_FDBACK_DIV_M       0x00000080
7620 +#define PLLC_ADD_FDBACK_DIV_S       7
7621 +#define PLLC_CLKC_DIV_M             0x0001c000
7622 +#define PLLC_CLKC_DIV_S             14
7623 +#define PLLC_CLKM_DIV_M             0x00700000
7624 +#define PLLC_CLKM_DIV_S             20
7625 +
7626 +/* CPU CLK Control fields */
7627 +#define CPUCLK_CLK_SEL_M            0x00000003
7628 +#define CPUCLK_CLK_SEL_S            0
7629 +#define CPUCLK_CLK_DIV_M            0x0000000c
7630 +#define CPUCLK_CLK_DIV_S            2
7631 +
7632 +/* AMBA CLK Control fields */
7633 +#define AMBACLK_CLK_SEL_M           0x00000003
7634 +#define AMBACLK_CLK_SEL_S           0
7635 +#define AMBACLK_CLK_DIV_M           0x0000000c
7636 +#define AMBACLK_CLK_DIV_S           2
7637 +
7638 +#if defined(COBRA_EMUL)
7639 +#define AR531XPLUS_AMBA_CLOCK_RATE  20000000
7640 +#define AR531XPLUS_CPU_CLOCK_RATE   40000000
7641 +#else
7642 +#if defined(DEFAULT_PLL)
7643 +#define AR531XPLUS_AMBA_CLOCK_RATE  40000000
7644 +#define AR531XPLUS_CPU_CLOCK_RATE   40000000
7645 +#else
7646 +#define AR531XPLUS_AMBA_CLOCK_RATE  92000000
7647 +#define AR531XPLUS_CPU_CLOCK_RATE   184000000
7648 +#endif /* ! DEFAULT_PLL */
7649 +#endif /* ! COBRA_EMUL */
7650 +
7651 +#define AR531XPLUS_UART_CLOCK_RATE  AR531XPLUS_AMBA_CLOCK_RATE
7652 +#define AR531XPLUS_SDRAM_CLOCK_RATE AR531XPLUS_AMBA_CLOCK_RATE
7653 +
7654 +/*
7655 + * The UART computes baud rate as:
7656 + *   baud = clock / (16 * divisor)
7657 + * where divisor is specified as a High Byte (DLM) and a Low Byte (DLL).
7658 + */
7659 +#define DESIRED_BAUD_RATE           38400
7660 +
7661 +/*
7662 + * The WATCHDOG value is computed as
7663 + *  10 seconds * AR531X_WATCHDOG_CLOCK_RATE
7664 + */
7665 +#define DESIRED_WATCHDOG_SECONDS    10
7666 +#define AR531X_WATCHDOG_TIME \
7667 +        (DESIRED_WATCHDOG_SECONDS * AR531X_WATCHDOG_CLOCK_RATE)
7668 +
7669 +
7670 +#define CLOCKCTL_UART0  0x0010  /* enable UART0 external clock */
7671 +
7672 +
7673 + /*
7674 + * Applicable "PCICFG" bits for WLAN(s).  Assoc status and LED mode.
7675 + */
7676 +#define AR531X_PCICFG               (AR531X_RESETTMR + 0x00b0)
7677 +#define ASSOC_STATUS_M              0x00000003
7678 +#define ASSOC_STATUS_NONE           0
7679 +#define ASSOC_STATUS_PENDING        1   
7680 +#define ASSOC_STATUS_ASSOCIATED     2
7681 +#define LED_MODE_M                  0x0000001c
7682 +#define LED_BLINK_THRESHOLD_M       0x000000e0
7683 +#define LED_SLOW_BLINK_MODE         0x00000100
7684 +
7685 +/*
7686 + * GPIO
7687 + */
7688 +
7689 +#define AR531XPLUS_GPIO_DI          (AR531XPLUS_DSLBASE + 0x0088)
7690 +#define AR531XPLUS_GPIO_DO          (AR531XPLUS_DSLBASE + 0x0090)
7691 +#define AR531XPLUS_GPIO_CR          (AR531XPLUS_DSLBASE + 0x0098)
7692 +#define AR531XPLUS_GPIO_INT         (AR531XPLUS_DSLBASE + 0x00a0)
7693 +
7694 +#define GPIO_CR_M(x)                (1 << (x))                  /* mask for i/o */
7695 +#define GPIO_CR_O(x)                (1 << (x))                  /* output */
7696 +#define GPIO_CR_I(x)                (0 << (x))                  /* input */
7697 +
7698 +#define GPIO_INT(x,Y)               ((x) << (8 * (Y)))          /* interrupt enable */
7699 +#define GPIO_INT_M(Y)               ((0x3F) << (8 * (Y)))       /* mask for int */
7700 +#define GPIO_INT_LVL(x,Y)           ((x) << (8 * (Y) + 6))      /* interrupt level */
7701 +#define GPIO_INT_LVL_M(Y)           ((0x3) << (8 * (Y) + 6))    /* mask for int level */
7702 +
7703 +#define AR531XPLUS_RESET_GPIO       5
7704 +#define AR531XPLUS_NUM_GPIO         22
7705 +
7706 +    
7707 +/* 
7708 + *  PCI Clock Control
7709 + */     
7710
7711 +#define AR531XPLUS_PCICLK           (AR531XPLUS_DSLBASE + 0x00a4)
7712 +
7713 +#define PCICLK_INPUT_M              0x3
7714 +#define PCICLK_INPUT_S              0
7715 +                         
7716 +#define PCICLK_PLLC_CLKM            0
7717 +#define PCICLK_PLLC_CLKM1           1
7718 +#define PCICLK_PLLC_CLKC            2
7719 +#define PCICLK_REF_CLK              3 
7720 +
7721 +#define PCICLK_DIV_M                0xc
7722 +#define PCICLK_DIV_S                2
7723 +                         
7724 +#define PCICLK_IN_FREQ              0
7725 +#define PCICLK_IN_FREQ_DIV_6        1
7726 +#define PCICLK_IN_FREQ_DIV_8        2
7727 +#define PCICLK_IN_FREQ_DIV_10       3 
7728 +
7729 +/*
7730 + * Observation Control Register
7731 + */
7732 +#define AR531XPLUS_OCR              (AR531XPLUS_DSLBASE + 0x00b0)
7733 +#define OCR_GPIO0_IRIN              0x0040
7734 +#define OCR_GPIO1_IROUT             0x0080
7735 +#define OCR_GPIO3_RXCLR             0x0200
7736 +
7737 +/* 
7738 + *  General Clock Control
7739 + */     
7740
7741 +#define AR531XPLUS_MISCCLK          (AR531XPLUS_DSLBASE + 0x00b4)
7742 +#define MISCCLK_PLLBYPASS_EN        0x00000001
7743 +#define MISCCLK_PROCREFCLK          0x00000002
7744 +
7745 +/*
7746 + * SDRAM Controller
7747 + *   - No read or write buffers are included.
7748 + */
7749 +#define AR531XPLUS_MEM_CFG          (AR531XPLUS_SDRAMCTL + 0x00)
7750 +#define AR531XPLUS_MEM_CTRL         (AR531XPLUS_SDRAMCTL + 0x0c)
7751 +#define AR531XPLUS_MEM_REF          (AR531XPLUS_SDRAMCTL + 0x10)
7752 +
7753 +#define SDRAM_DATA_WIDTH_M          0x00006000
7754 +#define SDRAM_DATA_WIDTH_S          13
7755 +
7756 +#define SDRAM_COL_WIDTH_M           0x00001E00
7757 +#define SDRAM_COL_WIDTH_S           9
7758 +
7759 +#define SDRAM_ROW_WIDTH_M           0x000001E0
7760 +#define SDRAM_ROW_WIDTH_S           5
7761 +
7762 +#define SDRAM_BANKADDR_BITS_M       0x00000018
7763 +#define SDRAM_BANKADDR_BITS_S       3
7764 +
7765 +
7766 +/*
7767 + * SDRAM Memory Refresh (MEM_REF) value is computed as:
7768 + * MEMCTL_SREFR = (Tr * hclk_freq) / R
7769 + * where Tr is max. time of refresh of any single row
7770 + * R is number of rows in the DRAM
7771 + * For most 133MHz SDRAM parts, Tr=64ms, R=4096 or 8192
7772 + */
7773 +#if defined(COBRA_EMUL)
7774 +#define AR531XPLUS_SDRAM_MEMORY_REFRESH_VALUE  0x96
7775 +#else 
7776 +#if defined(DEFAULT_PLL)
7777 +#define AR531XPLUS_SDRAM_MEMORY_REFRESH_VALUE  0x200
7778 +#else
7779 +#define AR531XPLUS_SDRAM_MEMORY_REFRESH_VALUE  0x61a
7780 +#endif /* ! DEFAULT_PLL */
7781 +#endif 
7782 +
7783 +#if defined(AR531XPLUS)
7784 +
7785 +#define AR531XPLUS_SDRAM_DDR_SDRAM      0   /* Not DDR SDRAM */
7786 +#define AR531XPLUS_SDRAM_DATA_WIDTH     16  /* bits */   
7787 +#define AR531XPLUS_SDRAM_COL_WIDTH      8
7788 +#define AR531XPLUS_SDRAM_ROW_WIDTH      12
7789 +
7790 +#else
7791 +
7792 +#define AR531XPLUS_SDRAM_DDR_SDRAM      0   /* Not DDR SDRAM */
7793 +#define AR531XPLUS_SDRAM_DATA_WIDTH     16
7794 +#define AR531XPLUS_SDRAM_COL_WIDTH      8
7795 +#define AR531XPLUS_SDRAM_ROW_WIDTH      12
7796 +
7797 +#endif /* ! AR531XPLUS */
7798 +
7799 +/*
7800 + * SPI Flash Interface Registers
7801 + */
7802 +
7803 +#define AR531XPLUS_SPI_CTL      (AR531XPLUS_SPI + 0x00)
7804 +#define AR531XPLUS_SPI_OPCODE   (AR531XPLUS_SPI + 0x04)
7805 +#define AR531XPLUS_SPI_DATA     (AR531XPLUS_SPI + 0x08)
7806 +
7807 +#define SPI_CTL_START           0x00000100
7808 +#define SPI_CTL_BUSY            0x00010000
7809 +#define SPI_CTL_TXCNT_MASK      0x0000000f
7810 +#define SPI_CTL_RXCNT_MASK      0x000000f0
7811 +#define SPI_CTL_TX_RX_CNT_MASK  0x000000ff
7812 +#define SPI_CTL_SIZE_MASK       0x00060000
7813 +
7814 +#define SPI_CTL_CLK_SEL_MASK    0x03000000
7815 +#define SPI_OPCODE_MASK         0x000000ff
7816 +
7817 +/* 
7818 + * PCI-MAC Configuration registers 
7819 + */
7820 +#define PCI_MAC_RC              (AR531XPLUS_PCI + 0x4000) 
7821 +#define PCI_MAC_SCR             (AR531XPLUS_PCI + 0x4004)
7822 +#define PCI_MAC_INTPEND         (AR531XPLUS_PCI + 0x4008)
7823 +#define PCI_MAC_SFR             (AR531XPLUS_PCI + 0x400C)
7824 +#define PCI_MAC_PCICFG          (AR531XPLUS_PCI + 0x4010)
7825 +#define PCI_MAC_SREV            (AR531XPLUS_PCI + 0x4020)
7826 +
7827 +#define PCI_MAC_RC_MAC          0x00000001
7828 +#define PCI_MAC_RC_BB           0x00000002
7829 +
7830 +#define PCI_MAC_SCR_SLMODE_M    0x00030000
7831 +#define PCI_MAC_SCR_SLMODE_S    16        
7832 +#define PCI_MAC_SCR_SLM_FWAKE   0         
7833 +#define PCI_MAC_SCR_SLM_FSLEEP  1         
7834 +#define PCI_MAC_SCR_SLM_NORMAL  2         
7835 +
7836 +#define PCI_MAC_SFR_SLEEP       0x00000001
7837 +
7838 +#define PCI_MAC_PCICFG_SPWR_DN  0x00010000
7839 +
7840
7841 +
7842 +
7843 +/*
7844 + * PCI Bus Interface Registers
7845 + */
7846 +#define AR531XPLUS_PCI_1MS_REG      (AR531XPLUS_PCI + 0x0008)
7847 +#define AR531XPLUS_PCI_1MS_MASK     0x3FFFF         /* # of AHB clk cycles in 1ms */
7848 +
7849 +#define AR531XPLUS_PCI_MISC_CONFIG  (AR531XPLUS_PCI + 0x000c)
7850 +#define AR531XPLUS_PCIMISC_TXD_EN   0x00000001      /* Enable TXD for fragments */
7851 +#define AR531XPLUS_PCIMISC_CFG_SEL  0x00000002      /* mem or config cycles */
7852 +#define AR531XPLUS_PCIMISC_GIG_MASK 0x0000000C      /* bits 31-30 for pci req */
7853 +#define AR531XPLUS_PCIMISC_RST_MODE 0x00000030
7854 +#define AR531XPLUS_PCIRST_INPUT     0x00000000      /* 4:5=0 rst is input */
7855 +#define AR531XPLUS_PCIRST_LOW       0x00000010      /* 4:5=1 rst to GND */
7856 +#define AR531XPLUS_PCIRST_HIGH      0x00000020      /* 4:5=2 rst to VDD */
7857 +#define AR531XPLUS_PCIGRANT_EN      0x00000000      /* 6:7=0 early grant en */
7858 +#define AR531XPLUS_PCIGRANT_FRAME   0x00000040      /* 6:7=1 grant waits 4 frame */
7859 +#define AR531XPLUS_PCIGRANT_IDLE    0x00000080      /* 6:7=2 grant waits 4 idle */
7860 +#define AR531XPLUS_PCIGRANT_GAP     0x00000000      /* 6:7=2 grant waits 4 idle */
7861 +#define AR531XPLUS_PCICACHE_DIS     0x00001000      /* PCI external access cache disable */
7862 +
7863 +#define AR531XPLUS_PCI_OUT_TSTAMP   (AR531XPLUS_PCI + 0x0010)
7864 +
7865 +#define AR531XPLUS_PCI_UNCACHE_CFG  (AR531XPLUS_PCI + 0x0014)
7866 +
7867 +#define AR531XPLUS_PCI_IN_EN        (AR531XPLUS_PCI + 0x0100)
7868 +#define AR531XPLUS_PCI_IN_EN0       0x01            /* Enable chain 0 */
7869 +#define AR531XPLUS_PCI_IN_EN1       0x02            /* Enable chain 1 */
7870 +#define AR531XPLUS_PCI_IN_EN2       0x04            /* Enable chain 2 */
7871 +#define AR531XPLUS_PCI_IN_EN3       0x08            /* Enable chain 3 */
7872 +
7873 +#define AR531XPLUS_PCI_IN_DIS       (AR531XPLUS_PCI + 0x0104)
7874 +#define AR531XPLUS_PCI_IN_DIS0      0x01            /* Disable chain 0 */
7875 +#define AR531XPLUS_PCI_IN_DIS1      0x02            /* Disable chain 1 */
7876 +#define AR531XPLUS_PCI_IN_DIS2      0x04            /* Disable chain 2 */
7877 +#define AR531XPLUS_PCI_IN_DIS3      0x08            /* Disable chain 3 */
7878 +
7879 +#define AR531XPLUS_PCI_IN_PTR       (AR531XPLUS_PCI + 0x0200)
7880 +
7881 +#define AR531XPLUS_PCI_OUT_EN       (AR531XPLUS_PCI + 0x0400)
7882 +#define AR531XPLUS_PCI_OUT_EN0      0x01            /* Enable chain 0 */
7883 +
7884 +#define AR531XPLUS_PCI_OUT_DIS      (AR531XPLUS_PCI + 0x0404)
7885 +#define AR531XPLUS_PCI_OUT_DIS0     0x01            /* Disable chain 0 */
7886 +
7887 +#define AR531XPLUS_PCI_OUT_PTR      (AR531XPLUS_PCI + 0x0408)
7888 +
7889 +#define AR531XPLUS_PCI_INT_STATUS   (AR531XPLUS_PCI + 0x0500)   /* write one to clr */
7890 +#define AR531XPLUS_PCI_TXINT        0x00000001      /* Desc In Completed */
7891 +#define AR531XPLUS_PCI_TXOK         0x00000002      /* Desc In OK */
7892 +#define AR531XPLUS_PCI_TXERR        0x00000004      /* Desc In ERR */
7893 +#define AR531XPLUS_PCI_TXEOL        0x00000008      /* Desc In End-of-List */
7894 +#define AR531XPLUS_PCI_RXINT        0x00000010      /* Desc Out Completed */
7895 +#define AR531XPLUS_PCI_RXOK         0x00000020      /* Desc Out OK */
7896 +#define AR531XPLUS_PCI_RXERR        0x00000040      /* Desc Out ERR */
7897 +#define AR531XPLUS_PCI_RXEOL        0x00000080      /* Desc Out EOL */
7898 +#define AR531XPLUS_PCI_TXOOD        0x00000200      /* Desc In Out-of-Desc */
7899 +#define AR531XPLUS_PCI_MASK         0x0000FFFF      /* Desc Mask */
7900 +#define AR531XPLUS_PCI_EXT_INT      0x02000000      
7901 +#define AR531XPLUS_PCI_ABORT_INT    0x04000000      
7902 +
7903 +#define AR531XPLUS_PCI_INT_MASK     (AR531XPLUS_PCI + 0x0504)   /* same as INT_STATUS */
7904 +
7905 +#define AR531XPLUS_PCI_INTEN_REG    (AR531XPLUS_PCI + 0x0508)
7906 +#define AR531XPLUS_PCI_INT_DISABLE  0x00            /* disable pci interrupts */
7907 +#define AR531XPLUS_PCI_INT_ENABLE   0x01            /* enable pci interrupts */
7908 +
7909 +#define AR531XPLUS_PCI_HOST_IN_EN   (AR531XPLUS_PCI + 0x0800)
7910 +#define AR531XPLUS_PCI_HOST_IN_DIS  (AR531XPLUS_PCI + 0x0804)
7911 +#define AR531XPLUS_PCI_HOST_IN_PTR  (AR531XPLUS_PCI + 0x0810)
7912 +#define AR531XPLUS_PCI_HOST_OUT_EN  (AR531XPLUS_PCI + 0x0900)
7913 +#define AR531XPLUS_PCI_HOST_OUT_DIS (AR531XPLUS_PCI + 0x0904)
7914 +#define AR531XPLUS_PCI_HOST_OUT_PTR (AR531XPLUS_PCI + 0x0908)
7915 +
7916 +
7917 +/*
7918 + * Local Bus Interface Registers
7919 + */
7920 +#define AR531XPLUS_LB_CONFIG        (AR531XPLUS_LOCAL + 0x0000)
7921 +#define AR531XPLUS_LBCONF_OE        0x00000001      /* =1 OE is low-true */
7922 +#define AR531XPLUS_LBCONF_CS0       0x00000002      /* =1 first CS is low-true */
7923 +#define AR531XPLUS_LBCONF_CS1       0x00000004      /* =1 2nd CS is low-true */
7924 +#define AR531XPLUS_LBCONF_RDY       0x00000008      /* =1 RDY is low-true */
7925 +#define AR531XPLUS_LBCONF_WE        0x00000010      /* =1 Write En is low-true */
7926 +#define AR531XPLUS_LBCONF_WAIT      0x00000020      /* =1 WAIT is low-true */
7927 +#define AR531XPLUS_LBCONF_ADS       0x00000040      /* =1 Adr Strobe is low-true */
7928 +#define AR531XPLUS_LBCONF_MOT       0x00000080      /* =0 Intel, =1 Motorola */
7929 +#define AR531XPLUS_LBCONF_8CS       0x00000100      /* =1 8 bits CS, 0= 16bits */
7930 +#define AR531XPLUS_LBCONF_8DS       0x00000200      /* =1 8 bits Data S, 0=16bits */
7931 +#define AR531XPLUS_LBCONF_ADS_EN    0x00000400      /* =1 Enable ADS */
7932 +#define AR531XPLUS_LBCONF_ADR_OE    0x00000800      /* =1 Adr cap on OE, WE or DS */
7933 +#define AR531XPLUS_LBCONF_ADDT_MUX  0x00001000      /* =1 Adr and Data share bus */
7934 +#define AR531XPLUS_LBCONF_DATA_OE   0x00002000      /* =1 Data cap on OE, WE, DS */
7935 +#define AR531XPLUS_LBCONF_16DATA    0x00004000      /* =1 Data is 16 bits wide */
7936 +#define AR531XPLUS_LBCONF_SWAPDT    0x00008000      /* =1 Byte swap data */
7937 +#define AR531XPLUS_LBCONF_SYNC      0x00010000      /* =1 Bus synchronous to clk */
7938 +#define AR531XPLUS_LBCONF_INT       0x00020000      /* =1 Intr is low true */
7939 +#define AR531XPLUS_LBCONF_INT_CTR0  0x00000000      /* GND high-Z, Vdd is high-Z */
7940 +#define AR531XPLUS_LBCONF_INT_CTR1  0x00040000      /* GND drive, Vdd is high-Z */
7941 +#define AR531XPLUS_LBCONF_INT_CTR2  0x00080000      /* GND high-Z, Vdd drive */
7942 +#define AR531XPLUS_LBCONF_INT_CTR3  0x000C0000      /* GND drive, Vdd drive */
7943 +#define AR531XPLUS_LBCONF_RDY_WAIT  0x00100000      /* =1 RDY is negative of WAIT */
7944 +#define AR531XPLUS_LBCONF_INT_PULSE 0x00200000      /* =1 Interrupt is a pulse */
7945 +#define AR531XPLUS_LBCONF_ENABLE    0x00400000      /* =1 Falcon respond to LB */
7946 +
7947 +#define AR531XPLUS_LB_CLKSEL        (AR531XPLUS_LOCAL + 0x0004)
7948 +#define AR531XPLUS_LBCLK_EXT        0x0001          /* use external clk for lb */
7949 +
7950 +#define AR531XPLUS_LB_1MS           (AR531XPLUS_LOCAL + 0x0008)
7951 +#define AR531XPLUS_LB1MS_MASK       0x3FFFF         /* # of AHB clk cycles in 1ms */
7952 +
7953 +#define AR531XPLUS_LB_MISCCFG       (AR531XPLUS_LOCAL + 0x000C)
7954 +#define AR531XPLUS_LBM_TXD_EN       0x00000001      /* Enable TXD for fragments */
7955 +#define AR531XPLUS_LBM_RX_INTEN     0x00000002      /* Enable LB ints on RX ready */
7956 +#define AR531XPLUS_LBM_MBOXWR_INTEN 0x00000004      /* Enable LB ints on mbox wr */
7957 +#define AR531XPLUS_LBM_MBOXRD_INTEN 0x00000008      /* Enable LB ints on mbox rd */
7958 +#define AR531XPLUS_LMB_DESCSWAP_EN  0x00000010      /* Byte swap desc enable */
7959 +#define AR531XPLUS_LBM_TIMEOUT_MASK 0x00FFFF80
7960 +#define AR531XPLUS_LBM_TIMEOUT_SHFT 7
7961 +#define AR531XPLUS_LBM_PORTMUX      0x07000000
7962 +
7963 +
7964 +#define AR531XPLUS_LB_RXTSOFF       (AR531XPLUS_LOCAL + 0x0010)
7965 +
7966 +#define AR531XPLUS_LB_TX_CHAIN_EN   (AR531XPLUS_LOCAL + 0x0100)
7967 +#define AR531XPLUS_LB_TXEN_0        0x01
7968 +#define AR531XPLUS_LB_TXEN_1        0x02
7969 +#define AR531XPLUS_LB_TXEN_2        0x04
7970 +#define AR531XPLUS_LB_TXEN_3        0x08
7971 +
7972 +#define AR531XPLUS_LB_TX_CHAIN_DIS  (AR531XPLUS_LOCAL + 0x0104)
7973 +#define AR531XPLUS_LB_TX_DESC_PTR   (AR531XPLUS_LOCAL + 0x0200)
7974 +
7975 +#define AR531XPLUS_LB_RX_CHAIN_EN   (AR531XPLUS_LOCAL + 0x0400)
7976 +#define AR531XPLUS_LB_RXEN          0x01
7977 +
7978 +#define AR531XPLUS_LB_RX_CHAIN_DIS  (AR531XPLUS_LOCAL + 0x0404)
7979 +#define AR531XPLUS_LB_RX_DESC_PTR   (AR531XPLUS_LOCAL + 0x0408)
7980 +
7981 +#define AR531XPLUS_LB_INT_STATUS    (AR531XPLUS_LOCAL + 0x0500)
7982 +#define AR531XPLUS_INT_TX_DESC      0x0001
7983 +#define AR531XPLUS_INT_TX_OK        0x0002
7984 +#define AR531XPLUS_INT_TX_ERR       0x0004
7985 +#define AR531XPLUS_INT_TX_EOF       0x0008
7986 +#define AR531XPLUS_INT_RX_DESC      0x0010
7987 +#define AR531XPLUS_INT_RX_OK        0x0020
7988 +#define AR531XPLUS_INT_RX_ERR       0x0040
7989 +#define AR531XPLUS_INT_RX_EOF       0x0080
7990 +#define AR531XPLUS_INT_TX_TRUNC     0x0100
7991 +#define AR531XPLUS_INT_TX_STARVE    0x0200
7992 +#define AR531XPLUS_INT_LB_TIMEOUT   0x0400
7993 +#define AR531XPLUS_INT_LB_ERR       0x0800
7994 +#define AR531XPLUS_INT_MBOX_WR      0x1000
7995 +#define AR531XPLUS_INT_MBOX_RD      0x2000
7996 +
7997 +/* Bit definitions for INT MASK are the same as INT_STATUS */
7998 +#define AR531XPLUS_LB_INT_MASK      (AR531XPLUS_LOCAL + 0x0504)
7999 +
8000 +#define AR531XPLUS_LB_INT_EN        (AR531XPLUS_LOCAL + 0x0508)
8001 +#define AR531XPLUS_LB_MBOX          (AR531XPLUS_LOCAL + 0x0600)
8002 +
8003 +
8004 +
8005 +/*
8006 + * IR Interface Registers
8007 + */
8008 +#define AR531XPLUS_IR_PKTDATA                   (AR531XPLUS_IR + 0x0000)
8009 +
8010 +#define AR531XPLUS_IR_PKTLEN                    (AR531XPLUS_IR + 0x07fc) /* 0 - 63 */
8011 +
8012 +#define AR531XPLUS_IR_CONTROL                   (AR531XPLUS_IR + 0x0800)
8013 +#define AR531XPLUS_IRCTL_TX                     0x00000000  /* use as tranmitter */
8014 +#define AR531XPLUS_IRCTL_RX                     0x00000001  /* use as receiver   */
8015 +#define AR531XPLUS_IRCTL_SAMPLECLK_MASK         0x00003ffe  /* Sample clk divisor mask */
8016 +#define AR531XPLUS_IRCTL_SAMPLECLK_SHFT                  1
8017 +#define AR531XPLUS_IRCTL_OUTPUTCLK_MASK         0x03ffc000  /* Output clk divisor mask */
8018 +#define AR531XPLUS_IRCTL_OUTPUTCLK_SHFT                 14
8019 +
8020 +#define AR531XPLUS_IR_STATUS                    (AR531XPLUS_IR + 0x0804)
8021 +#define AR531XPLUS_IRSTS_RX                     0x00000001  /* receive in progress */
8022 +#define AR531XPLUS_IRSTS_TX                     0x00000002  /* transmit in progress */
8023 +
8024 +#define AR531XPLUS_IR_CONFIG                    (AR531XPLUS_IR + 0x0808)
8025 +#define AR531XPLUS_IRCFG_INVIN                  0x00000001  /* invert input polarity */
8026 +#define AR531XPLUS_IRCFG_INVOUT                 0x00000002  /* invert output polarity */
8027 +#define AR531XPLUS_IRCFG_SEQ_START_WIN_SEL      0x00000004  /* 1 => 28, 0 => 7 */
8028 +#define AR531XPLUS_IRCFG_SEQ_START_THRESH       0x000000f0  /*  */
8029 +#define AR531XPLUS_IRCFG_SEQ_END_UNIT_SEL       0x00000100  /*  */
8030 +#define AR531XPLUS_IRCFG_SEQ_END_UNIT_THRESH    0x00007e00  /*  */
8031 +#define AR531XPLUS_IRCFG_SEQ_END_WIN_SEL        0x00008000  /*  */
8032 +#define AR531XPLUS_IRCFG_SEQ_END_WIN_THRESH     0x001f0000  /*  */
8033 +#define AR531XPLUS_IRCFG_NUM_BACKOFF_WORDS      0x01e00000  /*  */
8034 +
8035 +/*
8036 + * PCI memory constants: Memory area 1 and 2 are the same size -
8037 + * (twice the PCI_TLB_PAGE_SIZE). The definition of
8038 + * CPU_TO_PCI_MEM_SIZE is coupled with the TLB setup routine
8039 + * sysLib.c/sysTlbInit(), in that it assumes that 2 pages of size
8040 + * PCI_TLB_PAGE_SIZE are set up in the TLB for each PCI memory space.
8041 + */
8042
8043 +#define CPU_TO_PCI_MEM_BASE1    0xE0000000
8044 +#define CPU_TO_PCI_MEM_SIZE1    (2*PCI_TLB_PAGE_SIZE)
8045
8046 +
8047 +/* TLB attributes for PCI transactions */
8048 +
8049 +#define PCI_MMU_PAGEMASK        0x00003FFF
8050 +#define MMU_PAGE_UNCACHED       0x00000010
8051 +#define MMU_PAGE_DIRTY          0x00000004
8052 +#define MMU_PAGE_VALID          0x00000002
8053 +#define MMU_PAGE_GLOBAL         0x00000001
8054 +#define PCI_MMU_PAGEATTRIB      (MMU_PAGE_UNCACHED|MMU_PAGE_DIRTY|\
8055 +                                 MMU_PAGE_VALID|MMU_PAGE_GLOBAL)
8056 +#define PCI_MEMORY_SPACE1_VIRT  0xE0000000      /* Used for non-prefet  mem   */
8057 +#define PCI_MEMORY_SPACE1_PHYS  0x80000000
8058 +#define PCI_TLB_PAGE_SIZE       0x01000000
8059 +#define TLB_HI_MASK             0xFFFFE000
8060 +#define TLB_LO_MASK             0x3FFFFFFF
8061 +#define PAGEMASK_SHIFT          11
8062 +#define TLB_LO_SHIFT            6
8063 +
8064 +#define PCI_MAX_LATENCY         0xFFF           /* Max PCI latency            */
8065 +
8066 +#define HOST_PCI_DEV_ID         3
8067 +#define HOST_PCI_MBAR0          0x10000000
8068 +#define HOST_PCI_MBAR1          0x20000000
8069 +#define HOST_PCI_MBAR2          0x30000000
8070 +
8071 +#define HOST_PCI_SDRAM_BASEADDR HOST_PCI_MBAR1
8072 +#define PCI_DEVICE_MEM_SPACE    0x800000
8073 +
8074 +
8075 +typedef unsigned int AR531X_REG;
8076 +
8077 +#define sysRegRead(phys)       \
8078 +       (*(volatile AR531X_REG *)PHYS_TO_K1(phys))
8079 +
8080 +#define sysRegWrite(phys, val) \
8081 +       ((*(volatile AR531X_REG *)PHYS_TO_K1(phys)) = (val))
8082 +
8083 +
8084 +
8085 +/*
8086 + * This is board-specific data that is stored in a "fixed" location in flash.
8087 + * It is shared across operating systems, so it should not be changed lightly.
8088 + * The main reason we need it is in order to extract the ethernet MAC
8089 + * address(es).
8090 + */
8091 +struct ar531x_boarddata {
8092 +    u32 magic;                       /* board data is valid */
8093 +#define AR531X_BD_MAGIC 0x35333131   /* "5311", for all 531x platforms */
8094 +    u16 cksum;                       /* checksum (starting with BD_REV 2) */
8095 +    u16 rev;                         /* revision of this struct */
8096 +#define BD_REV  4
8097 +    char   boardName[64];            /* Name of board */
8098 +    u16 major;                       /* Board major number */
8099 +    u16 minor;                       /* Board minor number */
8100 +    u32 config;                      /* Board configuration */
8101 +#define BD_ENET0        0x00000001   /* ENET0 is stuffed */
8102 +#define BD_ENET1        0x00000002   /* ENET1 is stuffed */
8103 +#define BD_UART1        0x00000004   /* UART1 is stuffed */
8104 +#define BD_UART0        0x00000008   /* UART0 is stuffed (dma) */
8105 +#define BD_RSTFACTORY   0x00000010   /* Reset factory defaults stuffed */
8106 +#define BD_SYSLED       0x00000020   /* System LED stuffed */
8107 +#define BD_EXTUARTCLK   0x00000040   /* External UART clock */
8108 +#define BD_CPUFREQ      0x00000080   /* cpu freq is valid in nvram */
8109 +#define BD_SYSFREQ      0x00000100   /* sys freq is set in nvram */
8110 +#define BD_WLAN0        0x00000200   /* Enable WLAN0 */
8111 +#define BD_MEMCAP       0x00000400   /* CAP SDRAM @ memCap for testing */
8112 +#define BD_DISWATCHDOG  0x00000800   /* disable system watchdog */
8113 +#define BD_WLAN1        0x00001000   /* Enable WLAN1 (ar5212) */
8114 +#define BD_ISCASPER     0x00002000   /* FLAG for AR2312 */
8115 +#define BD_WLAN0_2G_EN  0x00004000   /* FLAG for radio0_2G */
8116 +#define BD_WLAN0_5G_EN  0x00008000   /* FLAG for radio0_2G */
8117 +#define BD_WLAN1_2G_EN  0x00020000   /* FLAG for radio0_2G */
8118 +#define BD_WLAN1_5G_EN  0x00040000   /* FLAG for radio0_2G */
8119 +    u16 resetConfigGpio;             /* Reset factory GPIO pin */
8120 +    u16 sysLedGpio;                  /* System LED GPIO pin */
8121 +
8122 +    u32 cpuFreq;                     /* CPU core frequency in Hz */
8123 +    u32 sysFreq;                     /* System frequency in Hz */
8124 +    u32 cntFreq;                     /* Calculated C0_COUNT frequency */
8125 +
8126 +    u8  wlan0Mac[6];
8127 +    u8  enet0Mac[6];
8128 +    u8  enet1Mac[6];
8129 +
8130 +    u16 pciId;                       /* Pseudo PCIID for common code */
8131 +    u16 memCap;                      /* cap bank1 in MB */
8132 +
8133 +    /* version 3 */
8134 +    u8  wlan1Mac[6];                 /* (ar5212) */
8135 +};
8136 +
8137 +#endif
8138 +
8139 +#endif /* AR531X_H */
8140 diff -urN linux-mips-orig/drivers/net/ath/ar531xlnx.h linux-mips-new/drivers/net/ath/ar531xlnx.h
8141 --- linux-mips-orig/drivers/net/ath/ar531xlnx.h 1970-01-01 01:00:00.000000000 +0100
8142 +++ linux-mips-new/drivers/net/ath/ar531xlnx.h  2005-12-31 12:33:57.676538368 +0000
8143 @@ -0,0 +1,137 @@
8144 +/*
8145 + * This file is subject to the terms and conditions of the GNU General Public
8146 + * License.  See the file "COPYING" in the main directory of this archive
8147 + * for more details.
8148 + *
8149 + * Copyright © 2003 Atheros Communications, Inc.,  All Rights Reserved.
8150 + */
8151 +
8152 +/*
8153 + * This file contains definitions needed in order to compile
8154 + * AR531X products for linux.  Definitions that are largely
8155 + * AR531X-specific and independent of operating system belong
8156 + * in ar531x.h rather than this file.
8157 + */
8158 +#ifndef __AR531XLNX_H
8159 +#define __AR531XLNX_H
8160 +#include "ar531x.h"
8161 +
8162 +#define MIPS_CPU_IRQ_BASE              0x00
8163 +#define AR531X_HIGH_PRIO                0x10
8164 +#define AR531X_MISC_IRQ_BASE           0x20
8165 +#define AR531X_GPIO_IRQ_BASE            0x30
8166 +
8167 +/* Software's idea of interrupts handled by "CPU Interrupt Controller" */
8168 +#if CONFIG_AR5315
8169 +#define AR531X_IRQ_NONE                MIPS_CPU_IRQ_BASE+0
8170 +#define AR531X_IRQ_MISC_INTRS  MIPS_CPU_IRQ_BASE+2 /* C0_CAUSE: 0x0400 */
8171 +#define AR531X_IRQ_WLAN0_INTRS MIPS_CPU_IRQ_BASE+3 /* C0_CAUSE: 0x0800 */
8172 +#define AR531X_IRQ_ENET0_INTRS MIPS_CPU_IRQ_BASE+4 /* C0_CAUSE: 0x1000 */
8173 +#define AR531X_IRQ_LCBUS_PCI   MIPS_CPU_IRQ_BASE+6 /* C0_CAUSE: 0x4000 */
8174 +#define AR531X_IRQ_WLAN0_POLL  MIPS_CPU_IRQ_BASE+6 /* C0_CAUSE: 0x4000 */
8175 +#define AR531X_IRQ_CPU_CLOCK   MIPS_CPU_IRQ_BASE+7 /* C0_CAUSE: 0x8000 */
8176 +#else
8177 +#define AR531X_IRQ_NONE                MIPS_CPU_IRQ_BASE+0
8178 +#define AR531X_IRQ_WLAN0_INTRS MIPS_CPU_IRQ_BASE+2 /* C0_CAUSE: 0x0400 */
8179 +#define AR531X_IRQ_ENET0_INTRS MIPS_CPU_IRQ_BASE+3 /* C0_CAUSE: 0x0800 */
8180 +#define AR531X_IRQ_ENET1_INTRS MIPS_CPU_IRQ_BASE+4 /* C0_CAUSE: 0x1000 */
8181 +#define AR531X_IRQ_WLAN1_INTRS MIPS_CPU_IRQ_BASE+5 /* C0_CAUSE: 0x2000 */
8182 +#define AR531X_IRQ_MISC_INTRS  MIPS_CPU_IRQ_BASE+6 /* C0_CAUSE: 0x4000 */
8183 +#define AR531X_IRQ_CPU_CLOCK   MIPS_CPU_IRQ_BASE+7 /* C0_CAUSE: 0x8000 */
8184 +#endif
8185 +
8186 +/* Miscellaneous interrupts, which share IP6 or IP2 */
8187 +#define AR531X_MISC_IRQ_NONE           AR531X_MISC_IRQ_BASE+0
8188 +#define AR531X_MISC_IRQ_TIMER          AR531X_MISC_IRQ_BASE+1
8189 +#define AR531X_MISC_IRQ_AHB_PROC       AR531X_MISC_IRQ_BASE+2
8190 +#define AR531X_MISC_IRQ_AHB_DMA                AR531X_MISC_IRQ_BASE+3
8191 +#define AR531X_MISC_IRQ_GPIO           AR531X_MISC_IRQ_BASE+4
8192 +#define AR531X_MISC_IRQ_UART0          AR531X_MISC_IRQ_BASE+5
8193 +#define AR531X_MISC_IRQ_UART0_DMA      AR531X_MISC_IRQ_BASE+6
8194 +#define AR531X_MISC_IRQ_WATCHDOG       AR531X_MISC_IRQ_BASE+7
8195 +#define AR531X_MISC_IRQ_LOCAL          AR531X_MISC_IRQ_BASE+8
8196 +#define AR531X_MISC_IRQ_COUNT          9
8197 +
8198 +/* GPIO Interrupts [0..7], share AR531X_MISC_IRQ_GPIO */
8199 +#define AR531X_GPIO_IRQ_NONE            AR531X_MISC_IRQ_BASE+0
8200 +#define AR531X_GPIO_IRQ(n)              AR531X_MISC_IRQ_BASE+(n)+1
8201 +#define AR531X_GPIO_IRQ_COUNT           9
8202 +
8203 +#define PHYS_TO_K1(physaddr) KSEG1ADDR(physaddr)
8204 +#define PHYS_TO_K0(physaddr) KSEG0ADDR(physaddr)
8205 +#define UNMAPPED_TO_PHYS(vaddr)  PHYSADDR(vaddr)
8206 +#define IS_UNMAPPED_VADDR(vaddr) \
8207 +    ((KSEGX(vaddr) == KSEG0) || (KSEGX(vaddr) == KSEG1))
8208 +
8209 +/* IOCTL commands for /proc/ar531x */
8210 +#define AR531X_CTRL_DO_BREAKPOINT       1
8211 +#define AR531X_CTRL_DO_MADWIFI          2
8212 +
8213 +/*
8214 + * Definitions for operating system portability.
8215 + * These are vxWorks-->Linux translations.
8216 + */
8217 +#define LOCAL static
8218 +#define BOOL int
8219 +#define TRUE 1
8220 +#define FALSE 0
8221 +#define UINT8 u8
8222 +#define UINT16 u16
8223 +#define UINT32 u32
8224 +#define PRINTF printk
8225 +#if /* DEBUG */ 1
8226 +#define DEBUG_PRINTF printk
8227 +#define printf printk
8228 +#define INLINE
8229 +#else
8230 +DEBUG_PRINTF while (0) printk
8231 +#define INLINE inline
8232 +#endif
8233 +#define sysUDelay(usecs) udelay(usecs)
8234 +#define sysMsDelay(msecs) mdelay(msecs)
8235 +typedef volatile UINT8 *VIRT_ADDR;
8236 +#define MALLOC(sz) kmalloc(sz, GFP_KERNEL)
8237 +#define MALLOC_NOSLEEP(sz) kmalloc(sz, GFP_ATOMIC)
8238 +#define FREE(ptr) kfree((void *)ptr)
8239 +#define BSP_BUG() do { printk("kernel BSP BUG at %s:%d!\n", __FILE__, __LINE__); *(int *)0=0; } while (0)
8240 +#define BSP_BUG_ON(condition) do { if (unlikely((condition)!=0)) BSP_BUG(); } while(0)
8241 +#define ASSERT(x) BSP_BUG_ON(!(x))
8242 +
8243 +extern struct ar531x_boarddata *ar531x_board_configuration;
8244 +extern char *ar531x_radio_configuration;
8245 +extern char *enet_mac_address_get(int MACUnit);
8246 +
8247 +extern void kgdbInit(void);
8248 +extern int kgdbEnabled(void);
8249 +extern void breakpoint(void);
8250 +extern int kgdbInterrupt(void);
8251 +extern unsigned int ar531x_cpu_frequency(void);
8252 +extern unsigned int ar531x_sys_frequency(void);
8253 +
8254 +/* GPIO support */
8255 +extern struct irqaction spurious_gpio;
8256 +extern unsigned int gpioIntMask;
8257 +extern void ar531x_gpio_intr_init(int irq_base);
8258 +extern void ar531x_gpio_ctrl_output(int gpio);
8259 +extern void ar531x_gpio_ctrl_input(int gpio);
8260 +extern void ar531x_gpio_set(int gpio, int val);
8261 +extern int  ar531x_gpio_get(int gpio);
8262 +extern void ar531x_gpio_intr_enable(unsigned int irq);
8263 +extern void ar531x_gpio_intr_disable(unsigned int irq);
8264 +
8265 +/* Watchdog Timer support */
8266 +extern int watchdog_start(unsigned int milliseconds);
8267 +extern int watchdog_stop(void);
8268 +extern int watchdog_is_enabled(void);
8269 +extern unsigned int watchdog_min_timer_reached(void);
8270 +extern void watchdog_notify_alive(void);
8271 +
8272 +#define A_DATA_CACHE_INVAL(start, length) \
8273 +        dma_cache_inv((UINT32)(start),(length))
8274 +
8275 +#define sysWbFlush() mb()
8276 +
8277 +#define intDisable(x) cli()
8278 +#define intEnable(x) sti()
8279 +
8280 +#endif   /* __AR531XLNX_H */
8281 diff -urN linux-mips-orig/drivers/net/ath/ipPhy.c linux-mips-new/drivers/net/ath/ipPhy.c
8282 --- linux-mips-orig/drivers/net/ath/ipPhy.c     1970-01-01 01:00:00.000000000 +0100
8283 +++ linux-mips-new/drivers/net/ath/ipPhy.c      2005-12-31 12:33:57.677538216 +0000
8284 @@ -0,0 +1,833 @@
8285 +/*
8286 + * This file is subject to the terms and conditions of the GNU General Public
8287 + * License.  See the file "COPYING" in the main directory of this archive
8288 + * for more details.
8289 + *
8290 + * Copyright © 2003 Atheros Communications, Inc.,  All Rights Reserved.
8291 + */
8292 +
8293 +/*
8294 + * Manage the ICPLUS ethernet PHY.
8295 + *
8296 + * All definitions in this file are operating system independent!
8297 + */
8298 +
8299 +#if defined(linux)
8300 +#include <linux/config.h>
8301 +#include <linux/types.h>
8302 +#include <linux/netdevice.h>
8303 +#include <linux/etherdevice.h>
8304 +#include <linux/delay.h>
8305 +
8306 +#include "ar531xlnx.h"
8307 +#endif
8308 +
8309 +#include "ae531xmac.h"
8310 +#include "ae531xreg.h"
8311 +#include "ipPhy.h"
8312 +
8313 +/* PHY selections and access functions */
8314 +
8315 +typedef enum {
8316 +    PHY_SRCPORT_INFO, 
8317 +    PHY_PORTINFO_SIZE,
8318 +} PHY_CAP_TYPE;
8319 +
8320 +typedef enum {
8321 +    PHY_SRCPORT_NONE,
8322 +    PHY_SRCPORT_VLANTAG, 
8323 +    PHY_SRCPORT_TRAILER,
8324 +} PHY_SRCPORT_TYPE;
8325 +
8326 +#ifdef DEBUG
8327 +#define DRV_DEBUG 1
8328 +#endif
8329 +#define DRV_DEBUG 1
8330 +
8331 +#if DRV_DEBUG
8332 +#define DRV_DEBUG_PHYERROR  0x00000001
8333 +#define DRV_DEBUG_PHYCHANGE 0x00000002
8334 +#define DRV_DEBUG_PHYSETUP  0x00000004
8335 +
8336 +int ipPhyDebug = DRV_DEBUG_PHYERROR;
8337 +
8338 +#define DRV_LOG(FLG, X0, X1, X2, X3, X4, X5, X6)    \
8339 +{                                                   \
8340 +    if (ipPhyDebug & (FLG)) {                       \
8341 +        logMsg(X0, X1, X2, X3, X4, X5, X6);         \
8342 +    }                                               \
8343 +}
8344 +
8345 +#define DRV_MSG(x,a,b,c,d,e,f)                      \
8346 +    logMsg(x,a,b,c,d,e,f)
8347 +
8348 +#define DRV_PRINT(FLG, X)                           \
8349 +{                                                   \
8350 +    if (ipPhyDebug & (FLG)) {                       \
8351 +        printf X;                                   \
8352 +    }                                               \
8353 +}
8354 +
8355 +#else /* !DRV_DEBUG */
8356 +#define DRV_LOG(DBG_SW, X0, X1, X2, X3, X4, X5, X6)
8357 +#define DRV_MSG(x,a,b,c,d,e,f)
8358 +#define DRV_PRINT(DBG_SW,X)
8359 +#endif
8360 +
8361 +#define IP_LAN_PORT_VLAN          1
8362 +#define IP_WAN_PORT_VLAN          2
8363 +
8364 +#define ENET_UNIT_DEFAULT 0
8365 +
8366 +/*
8367 + * Track per-PHY port information.
8368 + */
8369 +typedef struct {
8370 +    BOOL   isEnetPort;       /* normal enet port */
8371 +    BOOL   isPhyAlive;       /* last known state of link */
8372 +    int    ethUnit;          /* MAC associated with this phy port */
8373 +    UINT32 phyBase;
8374 +    UINT32 phyAddr;          /* PHY registers associated with this phy port */
8375 +    UINT32 VLANTableSetting; /* Value to be written to VLAN table */
8376 +} ipPhyInfo_t;
8377 +
8378 +/*
8379 + * Per-PHY information, indexed by PHY unit number.
8380 + */
8381 +ipPhyInfo_t ipPhyInfo[] = {
8382 +    /*
8383 +     * On AP30/AR5312, all PHYs are associated with MAC0.
8384 +     * AP30/AR5312's MAC1 isn't used for anything.
8385 +     * CONFIG_VENETDEV==1 (router) configuration:
8386 +     *    Ports 0,1,2, and 3 are "LAN ports"
8387 +     *    Port 4 is a WAN port
8388 +     *    Port 5 connects to MAC0 in the AR5312
8389 +     * CONFIG_VENETDEV==0 (bridge) configuration:
8390 +     *    Ports 0,1,2,3,4 are "LAN ports"
8391 +     *    Port 5 connects to the MAC0 in the AR5312
8392 +     */
8393 +    {TRUE,   /* phy port 0 -- LAN port 0 */
8394 +     FALSE,
8395 +     ENET_UNIT_DEFAULT,
8396 +     (UINT32) (PHYS_TO_K1(AR531X_ENET0)+AE531X_PHY_OFFSET),
8397 +     IP_PHY0_ADDR,
8398 +     IP_LAN_PORT_VLAN
8399 +    },
8400 +
8401 +    {TRUE,   /* phy port 1 -- LAN port 1 */
8402 +     FALSE,
8403 +     ENET_UNIT_DEFAULT,
8404 +     (UINT32) (PHYS_TO_K1(AR531X_ENET0)+AE531X_PHY_OFFSET),
8405 +     IP_PHY1_ADDR,
8406 +     IP_LAN_PORT_VLAN
8407 +    },
8408 +
8409 +    {TRUE,   /* phy port 2 -- LAN port 2 */
8410 +     FALSE,
8411 +     ENET_UNIT_DEFAULT,
8412 +     (UINT32) (PHYS_TO_K1(AR531X_ENET0)+AE531X_PHY_OFFSET),
8413 +     IP_PHY2_ADDR, 
8414 +     IP_LAN_PORT_VLAN
8415 +    },
8416 +
8417 +    {TRUE,   /* phy port 3 -- LAN port 3 */
8418 +     FALSE,
8419 +     ENET_UNIT_DEFAULT,
8420 +     (UINT32) (PHYS_TO_K1(AR531X_ENET0)+AE531X_PHY_OFFSET),
8421 +     IP_PHY3_ADDR, 
8422 +     IP_LAN_PORT_VLAN
8423 +    },
8424 +
8425 +    {TRUE,   /* phy port 4 -- WAN port or LAN port 4 */
8426 +     FALSE,
8427 +     ENET_UNIT_DEFAULT,
8428 +     (UINT32) (PHYS_TO_K1(AR531X_ENET0)+AE531X_PHY_OFFSET),
8429 +     IP_PHY4_ADDR, 
8430 +     IP_LAN_PORT_VLAN   /* Send to all ports */
8431 +    },
8432 +
8433 +    {FALSE,  /* phy port 5 -- CPU port (no RJ45 connector) */
8434 +     TRUE,
8435 +     ENET_UNIT_DEFAULT,
8436 +     (UINT32) (PHYS_TO_K1(AR531X_ENET0)+AE531X_PHY_OFFSET),
8437 +     0x00, 
8438 +     IP_LAN_PORT_VLAN    /* Send to all ports */
8439 +    },
8440 +};
8441 +
8442 +#define IP_GLOBALREGBASE    ((UINT32) (PHYS_TO_K1(AR531X_ENET0)))
8443 +
8444 +#define IP_PHY_MAX (sizeof(ipPhyInfo) / sizeof(ipPhyInfo[0]))
8445 +
8446 +/* Range of valid PHY IDs is [MIN..MAX] */
8447 +#define IP_ID_MIN 0
8448 +#define IP_ID_MAX (IP_PHY_MAX-1)
8449 +
8450 +/* Convenience macros to access myPhyInfo */
8451 +#define IP_IS_ENET_PORT(phyUnit) (ipPhyInfo[phyUnit].isEnetPort)
8452 +#define IP_IS_PHY_ALIVE(phyUnit) (ipPhyInfo[phyUnit].isPhyAlive)
8453 +#define IP_ETHUNIT(phyUnit) (ipPhyInfo[phyUnit].ethUnit)
8454 +#define IP_PHYBASE(phyUnit) (ipPhyInfo[phyUnit].phyBase)
8455 +#define IP_PHYADDR(phyUnit) (ipPhyInfo[phyUnit].phyAddr)
8456 +#define IP_VLAN_TABLE_SETTING(phyUnit) (ipPhyInfo[phyUnit].VLANTableSetting)
8457 +
8458 +
8459 +#define IP_IS_ETHUNIT(phyUnit, ethUnit) \
8460 +            (IP_IS_ENET_PORT(phyUnit) &&        \
8461 +            IP_ETHUNIT(phyUnit) == (ethUnit))
8462 +
8463 +/* Forward references */
8464 +BOOL       ip_phyIsLinkAlive(int phyUnit);
8465 +LOCAL void ip_VLANInit(int ethUnit);
8466 +LOCAL void ip_verifyReady(int ethUnit);
8467 +#if DEBUG
8468 +void       ip_phyShow(int phyUnit);
8469 +void       ip_phySet(int phyUnit, UINT32 regnum, UINT32 value);
8470 +void       ip_globalSet(UINT32 phyAddr, UINT32 regnum, UINT32 value);
8471 +#endif
8472 +
8473 +/******************************************************************************
8474 +*
8475 +* ip_phyIsLinkAlive - test to see if the specified link is alive
8476 +*
8477 +* RETURNS:
8478 +*    TRUE  --> link is alive
8479 +*    FALSE --> link is down
8480 +*/
8481 +BOOL
8482 +ip_phyIsLinkAlive(int phyUnit)
8483 +{
8484 +    UINT16 phyHwStatus;
8485 +    UINT32 phyBase;
8486 +    UINT32 phyAddr;
8487 +
8488 +    phyBase = IP_PHYBASE(phyUnit);
8489 +    phyAddr = IP_PHYADDR(phyUnit);
8490 +
8491 +    phyHwStatus = phyRegRead(phyBase, phyAddr, IP_PHY_STATUS);
8492 +
8493 +    if (phyHwStatus & IP_STATUS_LINK_PASS) {
8494 +        return TRUE;
8495 +    } else {
8496 +        return FALSE;
8497 +    }
8498 +}
8499 +
8500 +/******************************************************************************
8501 +*
8502 +* ip_VLANInit - initialize "port-based VLANs" for the specified enet unit.
8503 +*/
8504 +LOCAL void
8505 +ip_VLANInit(int ethUnit)
8506 +{
8507 +    int     phyUnit;
8508 +    UINT32  phyBase;
8509 +    UINT32  phyReg;
8510 +
8511 +    phyBase = IP_GLOBALREGBASE;
8512 +    
8513 +    for (phyUnit=0; phyUnit < IP_PHY_MAX; phyUnit++) {
8514 +        if (IP_ETHUNIT(phyUnit) != ethUnit) {
8515 +            continue;
8516 +        }
8517 +        phyRegWrite(phyBase, IP_GLOBAL_PHY29_ADDR, 
8518 +                    IP_GLOBAL_PHY29_24_REG + ((phyUnit == 5) ? (phyUnit + 1) : phyUnit),
8519 +                                    IP_VLAN_TABLE_SETTING(phyUnit));
8520 +        
8521 +        /* Send all packets to all ports */
8522 +        phyReg = phyRegRead(phyBase, IP_GLOBAL_PHY30_ADDR, IP_GLOBAL_PHY30_1_REG);
8523 +        phyReg = phyReg | ((1 << phyUnit) << IP_VLAN1_OUTPUT_PORT_MASK_S);
8524 +        phyRegWrite(phyBase, IP_GLOBAL_PHY30_ADDR, IP_GLOBAL_PHY30_1_REG, phyReg);
8525 +    }
8526 +    phyReg = phyRegRead(phyBase, IP_GLOBAL_PHY30_ADDR, IP_GLOBAL_PHY30_9_REG);
8527 +    phyReg = phyReg | TAG_VLAN_ENABLE;
8528 +    phyReg = phyReg & ~VID_INDX_SEL_M;
8529 +    phyRegWrite(phyBase, IP_GLOBAL_PHY30_ADDR, IP_GLOBAL_PHY30_9_REG, phyReg);
8530 +
8531 +}
8532 +
8533 +
8534 +LOCAL void
8535 +ip_verifyReady(int ethUnit)
8536 +{
8537 +    int     phyUnit;
8538 +    UINT32  phyBase = 0;
8539 +    UINT32  phyAddr;
8540 +    UINT16  phyID1;
8541 +    UINT16  phyID2;
8542 +
8543 +    /*
8544 +     * The first read to the Phy port registers always fails and
8545 +     * returns 0.   So get things started with a bogus read.
8546 +     */
8547 +    for (phyUnit=0; phyUnit < IP_PHY_MAX; phyUnit++) {
8548 +        if (!IP_IS_ETHUNIT(phyUnit, ethUnit)) {
8549 +            continue;
8550 +        }
8551 +
8552 +        phyBase = IP_PHYBASE(phyUnit);
8553 +        phyAddr = IP_PHYADDR(phyUnit);
8554 +    
8555 +        phyID1 = phyRegRead(phyBase, phyAddr, IP_PHY_ID1); /* returns 0 */
8556 +        break;
8557 +    }
8558 +
8559 +    for (phyUnit=0; phyUnit < IP_PHY_MAX; phyUnit++) {
8560 +        if (!IP_IS_ETHUNIT(phyUnit, ethUnit)) {
8561 +            continue;
8562 +        }
8563 +
8564 +        /*******************/
8565 +        /* Verify phy port */
8566 +        /*******************/
8567 +        phyBase = IP_PHYBASE(phyUnit);
8568 +        phyAddr = IP_PHYADDR(phyUnit);
8569 +    
8570 +        phyID1 = phyRegRead(phyBase, phyAddr, IP_PHY_ID1);
8571 +        if (phyID1 != IP_PHY_ID1_EXPECTATION) {
8572 +            DRV_PRINT(DRV_DEBUG_PHYERROR,
8573 +                      ("Invalid PHY ID1 for enet%d port%d.  Expected 0x%04x, read 0x%04x\n",
8574 +                       ethUnit,
8575 +                       phyUnit,
8576 +                       IP_PHY_ID1_EXPECTATION,
8577 +                       phyID1));
8578 +            return;
8579 +        }
8580 +    
8581 +        phyID2 = phyRegRead(phyBase, phyAddr, IP_PHY_ID2);
8582 +        if ((phyID2 & IP_OUI_LSB_MASK) != IP_OUI_LSB_EXPECTATION) {
8583 +            DRV_PRINT(DRV_DEBUG_PHYERROR,
8584 +                      ("Invalid PHY ID2 for enet%d port %d.  Expected 0x%04x, read 0x%04x\n",
8585 +                       ethUnit,
8586 +                       phyUnit,
8587 +                       IP_OUI_LSB_EXPECTATION,
8588 +                       phyID2));
8589 +            return;
8590 +        }
8591 +    
8592 +        DRV_PRINT(DRV_DEBUG_PHYSETUP,
8593 +                  ("Found PHY enet%d port%d: model 0x%x revision 0x%x\n",
8594 +                   ethUnit,
8595 +                   phyUnit,
8596 +                   (phyID2 & IP_MODEL_NUM_MASK) >> IP_MODEL_NUM_SHIFT,
8597 +                   (phyID2 & IP_REV_NUM_MASK) >> IP_REV_NUM_SHIFT));
8598 +    
8599 +    }
8600 +}
8601 +
8602 +
8603 +/******************************************************************************
8604 +*
8605 +* ip_phySetup - reset and setup the PHY associated with
8606 +* the specified MAC unit number.
8607 +*
8608 +* Resets the associated PHY port.
8609 +*
8610 +* RETURNS:
8611 +*    TRUE  --> associated PHY is alive
8612 +*    FALSE --> no LINKs on this ethernet unit
8613 +*/
8614 +
8615 +BOOL
8616 +ip_phySetup(int ethUnit, UINT32 _phyBase)
8617 +{
8618 +    int     phyUnit;
8619 +    UINT16  phyHwStatus;
8620 +    UINT16  timeout;
8621 +    int     liveLinks = 0;
8622 +    UINT32  phyBase = 0;
8623 +    BOOL    foundPhy = FALSE;
8624 +    UINT32  phyAddr;
8625 +    
8626 +    /* Reset PHYs*/
8627 +    for (phyUnit=0; phyUnit < IP_PHY_MAX; phyUnit++) {
8628 +        if (!IP_IS_ETHUNIT(phyUnit, ethUnit)) {
8629 +            continue;
8630 +        }
8631 +
8632 +        phyBase = IP_PHYBASE(phyUnit);
8633 +        phyAddr = IP_PHYADDR(phyUnit);
8634 +
8635 +        phyRegWrite(phyBase, phyAddr, IP_PHY_CONTROL,
8636 +                    IP_CTRL_SOFTWARE_RESET);
8637 +    }
8638 +    /*
8639 +     * After the phy is reset, it takes a little while before
8640 +     * it can respond properly.
8641 +     */
8642 +    sysMsDelay(300);
8643 +    /* Verify that the switch is what we think it is, and that it's ready */
8644 +    ip_verifyReady(ethUnit);
8645 +
8646 +    /* See if there's any configuration data for this enet */
8647 +    for (phyUnit=0; phyUnit < IP_PHY_MAX; phyUnit++) {
8648 +        if (IP_ETHUNIT(phyUnit) != ethUnit) {
8649 +            continue;
8650 +        }
8651 +
8652 +        phyBase = IP_PHYBASE(phyUnit);
8653 +        foundPhy = TRUE;
8654 +        break;
8655 +    }
8656 +
8657 +    if (!foundPhy) {
8658 +        return FALSE; /* No PHY's configured for this ethUnit */
8659 +    }
8660 +
8661 +#ifdef COBRA_TODO
8662 +    /* Initialize global switch settings */
8663 +
8664 +    /* Initialize the aging time */
8665 +
8666 +    /* Set the learning properties */
8667 +#endif
8668 +
8669 +    /* start auto negogiation on each phy */
8670 +    for (phyUnit=0; phyUnit < IP_PHY_MAX; phyUnit++) {
8671 +        if (!IP_IS_ETHUNIT(phyUnit, ethUnit)) {
8672 +            continue;
8673 +        }
8674 +
8675 +        phyBase = IP_PHYBASE(phyUnit);
8676 +        phyAddr = IP_PHYADDR(phyUnit);
8677 +        
8678 +        phyRegWrite(phyBase, phyAddr, IP_AUTONEG_ADVERT,
8679 +                                        IP_ADVERTISE_ALL);
8680 +        phyRegWrite(phyBase, phyAddr, IP_PHY_CONTROL,
8681 +                    IP_CTRL_AUTONEGOTIATION_ENABLE | IP_CTRL_START_AUTONEGOTIATION);
8682 +    }
8683 +
8684 +    /*
8685 +     * Wait up to .75 seconds for ALL associated PHYs to finish
8686 +     * autonegotiation.  The only way we get out of here sooner is
8687 +     * if ALL PHYs are connected AND finish autonegotiation.
8688 +     */
8689 +    timeout=5;
8690 +    for (phyUnit=0; (phyUnit < IP_PHY_MAX) /*&& (timeout > 0) */; phyUnit++) {
8691 +        if (!IP_IS_ETHUNIT(phyUnit, ethUnit)) {
8692 +            continue;
8693 +        }
8694 +        for (;;) {
8695 +            phyBase = IP_PHYBASE(phyUnit);
8696 +            phyAddr = IP_PHYADDR(phyUnit);
8697 +
8698 +            phyHwStatus = phyRegRead(phyBase, phyAddr, IP_PHY_STATUS);
8699 +
8700 +            if (IP_AUTONEG_DONE(phyHwStatus)) {
8701 +                DRV_PRINT(DRV_DEBUG_PHYSETUP,
8702 +                          ("Port %d, Neg Success\n", phyUnit));
8703 +                break;
8704 +            }
8705 +            if (timeout == 0) {
8706 +                DRV_PRINT(DRV_DEBUG_PHYSETUP,
8707 +                          ("Port %d, Negogiation timeout\n", phyUnit));
8708 +                break;
8709 +            }
8710 +            if (--timeout == 0) {
8711 +                DRV_PRINT(DRV_DEBUG_PHYSETUP,
8712 +                          ("Port %d, Negogiation timeout\n", phyUnit));
8713 +                break;
8714 +            }
8715 +
8716 +            sysMsDelay(150);
8717 +        }
8718 +    }
8719 +
8720 +    /*
8721 +     * All PHYs have had adequate time to autonegotiate.
8722 +     * Now initialize software status.
8723 +     *
8724 +     * It's possible that some ports may take a bit longer
8725 +     * to autonegotiate; but we can't wait forever.  They'll
8726 +     * get noticed by mv_phyCheckStatusChange during regular
8727 +     * polling activities.
8728 +     */
8729 +    for (phyUnit=0; phyUnit < IP_PHY_MAX; phyUnit++) {
8730 +        if (!IP_IS_ETHUNIT(phyUnit, ethUnit)) {
8731 +            continue;
8732 +        }
8733 +
8734 +        if (ip_phyIsLinkAlive(phyUnit)) {
8735 +            liveLinks++;
8736 +            IP_IS_PHY_ALIVE(phyUnit) = TRUE;
8737 +        } else {
8738 +            IP_IS_PHY_ALIVE(phyUnit) = FALSE;
8739 +        }
8740 +
8741 +        DRV_PRINT(DRV_DEBUG_PHYSETUP,
8742 +            ("eth%d: Phy Status=%4.4x\n",
8743 +            ethUnit, 
8744 +            phyRegRead(IP_PHYBASE(phyUnit),
8745 +                       IP_PHYADDR(phyUnit),
8746 +                       IP_PHY_STATUS)));
8747 +    }
8748 +#if 0
8749 +    /* XXX Divy. Disable WAN/LAN seggregation. See bug 17866 */
8750 +    ip_VLANInit(ethUnit);
8751 +#endif
8752 +    return (liveLinks > 0);
8753 +}
8754 +
8755 +/******************************************************************************
8756 +*
8757 +* ip_phyIsDuplexFull - Determines whether the phy ports associated with the
8758 +* specified device are FULL or HALF duplex.
8759 +*
8760 +* RETURNS:
8761 +*    1  --> FULL
8762 +*    0 --> HALF
8763 +*/
8764 +int
8765 +ip_phyIsFullDuplex(int ethUnit)
8766 +{
8767 +    int     phyUnit;
8768 +    UINT32  phyBase;
8769 +    UINT32  phyAddr;
8770 +    UINT16  phyHwStatus;
8771 +
8772 +    for (phyUnit=0; phyUnit < IP_PHY_MAX; phyUnit++) {
8773 +        if (!IP_IS_ETHUNIT(phyUnit, ethUnit)) {
8774 +            continue;
8775 +        }
8776 +
8777 +        if (ip_phyIsLinkAlive(phyUnit)) {
8778 +
8779 +            phyBase = IP_PHYBASE(phyUnit);
8780 +            phyAddr = IP_PHYADDR(phyUnit);
8781 +
8782 +            phyHwStatus = phyRegRead(phyBase, phyAddr, IP_LINK_PARTNER_ABILITY);
8783 +            printk("ipPhy.c: phyHwStatus 0x%x\n",phyHwStatus);
8784 +            if ((phyHwStatus & IP_LINK_100BASETX_FULL_DUPLEX) || 
8785 +                (phyHwStatus & IP_LINK_10BASETX_FULL_DUPLEX)) {
8786 +                return TRUE;
8787 +            }
8788 +        }
8789 +        return -1;
8790 +    }
8791 +
8792 +    return FALSE;
8793 +
8794 +}
8795 +
8796 +
8797 +/******************************************************************************
8798 +*
8799 +* ip_phyIsSpeed100 - Determines the speed of phy ports associated with the
8800 +* specified device.
8801 +*
8802 +* RETURNS:
8803 +*    TRUE --> 100Mbit
8804 +*    FALSE --> 10Mbit
8805 +*/
8806 +
8807 +BOOL
8808 +ip_phyIsSpeed100(int ethUnit)
8809 +{
8810 +    int     phyUnit;
8811 +    UINT16  phyHwStatus;
8812 +    UINT32  phyBase;
8813 +    UINT32  phyAddr;
8814 +
8815 +    for (phyUnit=0; phyUnit < IP_PHY_MAX; phyUnit++) {
8816 +        if (!IP_IS_ETHUNIT(phyUnit, ethUnit)) {
8817 +            continue;
8818 +        }
8819 +
8820 +        if (ip_phyIsLinkAlive(phyUnit)) {
8821 +
8822 +            phyBase = IP_PHYBASE(phyUnit);
8823 +            phyAddr = IP_PHYADDR(phyUnit);
8824 +
8825 +            phyHwStatus = phyRegRead(phyBase, phyAddr, IP_LINK_PARTNER_ABILITY);
8826 +
8827 +            if (phyHwStatus & IP_LINK_100BASETX) {
8828 +                return TRUE;
8829 +            }
8830 +        }
8831 +    }
8832 +
8833 +    return FALSE;
8834 +}
8835 +
8836 +/*****************************************************************************
8837 +*
8838 +* ip_phyCheckStatusChange -- checks for significant changes in PHY state.
8839 +*
8840 +* A "significant change" is:
8841 +*     dropped link (e.g. ethernet cable unplugged) OR
8842 +*     autonegotiation completed + link (e.g. ethernet cable plugged in)
8843 +*
8844 +* When a PHY is plugged in, phyLinkGained is called.
8845 +* When a PHY is unplugged, phyLinkLost is called.
8846 +*/
8847 +
8848 +void
8849 +ip_phyCheckStatusChange(int ethUnit)
8850 +{
8851 +
8852 +    int           phyUnit;
8853 +    UINT16        phyHwStatus;
8854 +    ipPhyInfo_t   *lastStatus;
8855 +    int           linkCount   = 0;
8856 +    int           lostLinks   = 0;
8857 +    int           gainedLinks = 0;
8858 +    UINT32        phyBase;
8859 +    UINT32        phyAddr;
8860 +
8861 +    for (phyUnit=0; phyUnit < IP_PHY_MAX; phyUnit++) {
8862 +        if (!IP_IS_ETHUNIT(phyUnit, ethUnit)) {
8863 +            continue;
8864 +        }
8865 +
8866 +        phyBase = IP_PHYBASE(phyUnit);
8867 +        phyAddr = IP_PHYADDR(phyUnit);
8868 +
8869 +        lastStatus = &ipPhyInfo[phyUnit];
8870 +        phyHwStatus = phyRegRead(phyBase, phyAddr, IP_PHY_STATUS);
8871 +
8872 +        if (lastStatus->isPhyAlive) { /* last known link status was ALIVE */
8873 +            /* See if we've lost link */
8874 +            if (phyHwStatus & IP_STATUS_LINK_PASS) {
8875 +                linkCount++;
8876 +            } else {
8877 +                lostLinks++;
8878 +#ifdef COBRA_TODO
8879 +                mv_flushATUDB(phyUnit);
8880 +#endif
8881 +                DRV_PRINT(DRV_DEBUG_PHYCHANGE,("\nenet%d port%d down\n",
8882 +                                               ethUnit, phyUnit));
8883 +                lastStatus->isPhyAlive = FALSE;
8884 +            }
8885 +        } else { /* last known link status was DEAD */
8886 +            /* Check for AutoNegotiation complete */
8887 +            if (IP_AUTONEG_DONE(phyHwStatus)) {
8888 +                gainedLinks++;
8889 +                linkCount++;
8890 +                DRV_PRINT(DRV_DEBUG_PHYCHANGE,("\nenet%d port%d up\n",
8891 +                                               ethUnit, phyUnit));
8892 +                lastStatus->isPhyAlive = TRUE;
8893 +            }
8894 +        }
8895 +    }
8896 +
8897 +    if (linkCount == 0) {
8898 +        if (lostLinks) {
8899 +            /* We just lost the last link for this MAC */
8900 +            phyLinkLost(ethUnit);
8901 +        }
8902 +    } else {
8903 +        if (gainedLinks == linkCount) {
8904 +            /* We just gained our first link(s) for this MAC */
8905 +            phyLinkGained(ethUnit);
8906 +        }
8907 +    }
8908 +
8909 +}
8910 +
8911 +#if DEBUG
8912 +
8913 +/* Define the registers of interest for a phyShow command */
8914 +typedef struct ipRegisterTableEntry_s {
8915 +    UINT32 regNum;
8916 +    char  *regIdString;
8917 +} ipRegisterTableEntry_t;
8918 +
8919 +ipRegisterTableEntry_t ipPhyRegisterTable[] = {
8920 +    {IP_PHY_CONTROL,                 "PHY Control                     "},
8921 +    {IP_PHY_STATUS,                  "PHY Status                      "},
8922 +    {IP_PHY_ID1,                     "PHY Identifier 1                "},
8923 +    {IP_PHY_ID2,                     "PHY Identifier 2                "},
8924 +    {IP_AUTONEG_ADVERT,              "Auto-Negotiation Advertisement  "},
8925 +    {IP_LINK_PARTNER_ABILITY,        "Link Partner Ability            "},
8926 +    {IP_AUTONEG_EXPANSION,           "Auto-Negotiation Expansion      "},
8927 +};
8928 +int ipPhyNumRegs = sizeof(ipPhyRegisterTable) / sizeof(ipPhyRegisterTable[0]);
8929 +
8930 +
8931 +ipRegisterTableEntry_t ipPhy29GlobalRegisterTable[] = {
8932 +    {IP_GLOBAL_PHY29_18_REG,        "29_18_REG   "},
8933 +    {IP_GLOBAL_PHY29_19_REG,        "29_19_REG   "},
8934 +    {IP_GLOBAL_PHY29_20_REG,        "29_20_REG   "},
8935 +    {IP_GLOBAL_PHY29_21_REG,        "29_21_REG   "},
8936 +    {IP_GLOBAL_PHY29_22_REG,        "29_22_REG   "},
8937 +    {IP_GLOBAL_PHY29_23_REG,        "29_23_REG   "},
8938 +    {IP_GLOBAL_PHY29_24_REG,        "29_24_REG   "},
8939 +    {IP_GLOBAL_PHY29_25_REG,        "29_25_REG   "},
8940 +    {IP_GLOBAL_PHY29_26_REG,        "29_26_REG   "},
8941 +    {IP_GLOBAL_PHY29_27_REG,        "29_27_REG   "},
8942 +    {IP_GLOBAL_PHY29_28_REG,        "29_28_REG   "},
8943 +    {IP_GLOBAL_PHY29_29_REG,        "29_29_REG   "},
8944 +    {IP_GLOBAL_PHY29_30_REG,        "29_30_REG   "},
8945 +    {IP_GLOBAL_PHY29_31_REG,        "29_31_REG   "},
8946 +};
8947 +int ipPhy29GlobalNumRegs =
8948 +    sizeof(ipPhy29GlobalRegisterTable) / sizeof(ipPhy29GlobalRegisterTable[0]);
8949 +
8950 +
8951 +ipRegisterTableEntry_t ipPhy30GlobalRegisterTable[] = {
8952 +    {IP_GLOBAL_PHY30_0_REG,   "30_0_REG    "},
8953 +    {IP_GLOBAL_PHY30_1_REG,   "30_1_REG    "},
8954 +    {IP_GLOBAL_PHY30_2_REG,   "30_2_REG    "},
8955 +    {IP_GLOBAL_PHY30_3_REG,   "30_3_REG    "},
8956 +    {IP_GLOBAL_PHY30_4_REG,   "30_4_REG    "},
8957 +    {IP_GLOBAL_PHY30_5_REG,   "30_5_REG    "},
8958 +    {IP_GLOBAL_PHY30_6_REG,   "30_6_REG    "},
8959 +    {IP_GLOBAL_PHY30_7_REG,   "30_7_REG    "},
8960 +    {IP_GLOBAL_PHY30_8_REG,   "30_8_REG    "},
8961 +    {IP_GLOBAL_PHY30_9_REG,   "30_9_REG    "},
8962 +    {IP_GLOBAL_PHY30_10_REG,  "30_10_REG   "},
8963 +    {IP_GLOBAL_PHY30_11_REG,  "30_11_REG   "},
8964 +    {IP_GLOBAL_PHY30_12_REG,  "30_12_REG   "},
8965 +    {IP_GLOBAL_PHY30_13_REG,  "30_13_REG   "},
8966 +    {IP_GLOBAL_PHY30_16_REG,  "30_16_REG   "},
8967 +    {IP_GLOBAL_PHY30_17_REG,  "30_17_REG   "},
8968 +    {IP_GLOBAL_PHY30_18_REG,  "30_18_REG   "},
8969 +    {IP_GLOBAL_PHY30_20_REG,  "30_20_REG   "},
8970 +    {IP_GLOBAL_PHY30_21_REG,  "30_21_REG   "},
8971 +    {IP_GLOBAL_PHY30_22_REG,  "30_22_REG   "},
8972 +    {IP_GLOBAL_PHY30_23_REG,  "30_23_REG   "},
8973 +    {IP_GLOBAL_PHY30_24_REG,  "30_24_REG   "},
8974 +    {IP_GLOBAL_PHY30_25_REG,  "30_25_REG   "},
8975 +    {IP_GLOBAL_PHY30_26_REG,  "30_26_REG   "},
8976 +    {IP_GLOBAL_PHY30_27_REG,  "30_27_REG   "},
8977 +    {IP_GLOBAL_PHY30_28_REG,  "30_28_REG   "},
8978 +    {IP_GLOBAL_PHY30_29_REG,  "30_29_REG   "},
8979 +    {IP_GLOBAL_PHY30_30_REG,  "30_30_REG   "},
8980 +    {IP_GLOBAL_PHY30_31_REG,  "30_31_REG   "},
8981 +};
8982 +int ipPhy30GlobalNumRegs =
8983 +    sizeof(ipPhy30GlobalRegisterTable) / sizeof(ipPhy30GlobalRegisterTable[0]);
8984 +
8985 +ipRegisterTableEntry_t ipPhy31GlobalRegisterTable[] = {
8986 +    {IP_GLOBAL_PHY31_0_REG,   "31_0_REG    "},
8987 +    {IP_GLOBAL_PHY31_1_REG,   "31_1_REG    "},
8988 +    {IP_GLOBAL_PHY31_2_REG,   "31_2_REG    "},
8989 +    {IP_GLOBAL_PHY31_3_REG,   "31_3_REG    "},
8990 +    {IP_GLOBAL_PHY31_4_REG,   "31_4_REG    "},
8991 +    {IP_GLOBAL_PHY31_5_REG,   "31_5_REG    "},
8992 +    {IP_GLOBAL_PHY31_6_REG,   "31_6_REG    "},
8993 +};
8994 +
8995 +int ipPhy31GlobalNumRegs =
8996 +    sizeof(ipPhy31GlobalRegisterTable) / sizeof(ipPhy31GlobalRegisterTable[0]);
8997 +
8998 +
8999 +/*****************************************************************************
9000 +*
9001 +* ip_phyShow - Dump the state of a PHY.
9002 +* There are two sets of registers for each phy port:
9003 +*  "phy registers" and
9004 +*  "switch port registers"
9005 +* We dump 'em all, plus the switch global registers.
9006 +*/
9007 +void
9008 +ip_phyShow(int phyUnit)
9009 +{
9010 +    int     i;
9011 +    UINT16  value;
9012 +    UINT32  phyBase;
9013 +    UINT32  phyAddr;
9014 +
9015 +    if (!ip_validPhyId(phyUnit)) {
9016 +        return;
9017 +    }
9018 +
9019 +    phyBase        = IP_PHYBASE(phyUnit);
9020 +    phyAddr        = IP_PHYADDR(phyUnit);
9021 +
9022 +    printf("PHY state for PHY%d (enet%d, phyBase 0x%8x, phyAddr 0x%x)\n",
9023 +           phyUnit,
9024 +           IP_ETHUNIT(phyUnit),
9025 +           IP_PHYBASE(phyUnit),
9026 +           IP_PHYADDR(phyUnit));
9027 +
9028 +    printf("PHY Registers:\n");
9029 +    for (i=0; i < ipPhyNumRegs; i++) {
9030 +
9031 +        value = phyRegRead(phyBase, phyAddr, ipPhyRegisterTable[i].regNum);
9032 +
9033 +        printf("Reg %02d (0x%02x) %s = 0x%08x\n",
9034 +               ipPhyRegisterTable[i].regNum,
9035 +               ipPhyRegisterTable[i].regNum,
9036 +               ipPhyRegisterTable[i].regIdString,
9037 +               value);
9038 +    }
9039 +
9040 +    phyBase = IP_GLOBALREGBASE;
9041 +
9042 +    printf("Switch Global Registers:\n");
9043 +    printf("Phy29 Registers:\n");
9044 +    for (i=0; i < ipPhy29GlobalNumRegs; i++) {
9045 +
9046 +        value = phyRegRead(phyBase, IP_GLOBAL_PHY29_ADDR,
9047 +                           ipPhy29GlobalRegisterTable[i].regNum);
9048 +
9049 +        printf("Reg %02d (0x%02x) %s = 0x%08x\n",
9050 +               ipPhy29GlobalRegisterTable[i].regNum,
9051 +               ipPhy29GlobalRegisterTable[i].regNum,
9052 +               ipPhy29GlobalRegisterTable[i].regIdString,
9053 +               value);
9054 +    }
9055 +
9056 +    printf("Phy30 Registers:\n");
9057 +    for (i=0; i < ipPhy30GlobalNumRegs; i++) {
9058 +
9059 +        value = phyRegRead(phyBase, IP_GLOBAL_PHY30_ADDR,
9060 +                           ipPhy30GlobalRegisterTable[i].regNum);
9061 +
9062 +        printf("Reg %02d (0x%02x) %s = 0x%08x\n",
9063 +               ipPhy30GlobalRegisterTable[i].regNum,
9064 +               ipPhy30GlobalRegisterTable[i].regNum,
9065 +               ipPhy30GlobalRegisterTable[i].regIdString,
9066 +               value);
9067 +    }
9068 +    printf("Phy31 Registers:\n");
9069 +    for (i=0; i < ipPhy31GlobalNumRegs; i++) {
9070 +
9071 +        value = phyRegRead(phyBase, IP_GLOBAL_PHY31_ADDR,
9072 +                           ipPhy31GlobalRegisterTable[i].regNum);
9073 +
9074 +        printf("Reg %02d (0x%02x) %s = 0x%08x\n",
9075 +               ipPhy31GlobalRegisterTable[i].regNum,
9076 +               ipPhy31GlobalRegisterTable[i].regNum,
9077 +               ipPhy31GlobalRegisterTable[i].regIdString,
9078 +               value);
9079 +    }
9080 +}
9081 +
9082 +/*****************************************************************************
9083 +*
9084 +* ip_phySet - Modify the value of a PHY register (debug only).
9085 +*/
9086 +void
9087 +ip_phySet(int phyUnit, UINT32 regnum, UINT32 value)
9088 +{
9089 +    UINT32  phyBase;
9090 +    UINT32  phyAddr;
9091 +
9092 +    if (ip_validPhyId(phyUnit)) {
9093 +
9094 +        phyBase = IP_PHYBASE(phyUnit);
9095 +        phyAddr = IP_PHYADDR(phyUnit);
9096 +
9097 +        phyRegWrite(phyBase, phyAddr, regnum, value);
9098 +    }
9099 +}
9100 +
9101 +/*****************************************************************************
9102 +*
9103 +* ip_globalSet - Modify the value of a global register
9104 +* (debug only).
9105 +*/
9106 +void
9107 +ip_globalSet(UINT32 phyAddr, UINT32 regnum, UINT32 value)
9108 +{
9109 +    UINT32  phyBase;
9110 +
9111 +    phyBase = IP_GLOBALREGBASE;
9112 +
9113 +    phyRegWrite(phyBase, phyAddr, regnum, value);
9114 +}
9115 +
9116 +
9117 +#endif
9118 diff -urN linux-mips-orig/drivers/net/ath/ipPhy.h linux-mips-new/drivers/net/ath/ipPhy.h
9119 --- linux-mips-orig/drivers/net/ath/ipPhy.h     1970-01-01 01:00:00.000000000 +0100
9120 +++ linux-mips-new/drivers/net/ath/ipPhy.h      2005-12-31 12:33:57.678538064 +0000
9121 @@ -0,0 +1,172 @@
9122 +/*
9123 + * This file is subject to the terms and conditions of the GNU General Public
9124 + * License.  See the file "COPYING" in the main directory of this archive
9125 + * for more details.
9126 + *
9127 + * Copyright © 2003 Atheros Communications, Inc.,  All Rights Reserved.
9128 + */
9129 +
9130 +/*
9131 + * icPhy.h - definitions for the ethernet PHY.
9132 + * This code supports a simple 1-port ethernet phy, ICPLUS,
9133 + * All definitions in this file are operating system independent!
9134 + */
9135 +
9136 +#ifndef IPPHY_H
9137 +#define IPPHY_H
9138 +
9139 +/*****************/
9140 +/* PHY Registers */
9141 +/*****************/
9142 +#define IP_PHY_CONTROL                 0
9143 +#define IP_PHY_STATUS                  1
9144 +#define IP_PHY_ID1                     2
9145 +#define IP_PHY_ID2                     3
9146 +#define IP_AUTONEG_ADVERT              4
9147 +#define IP_LINK_PARTNER_ABILITY        5
9148 +#define IP_AUTONEG_EXPANSION           6
9149 +
9150 +
9151 +/* IP_PHY_CONTROL fields */
9152 +#define IP_CTRL_SOFTWARE_RESET                    0x8000
9153 +#define IP_CTRL_SPEED_100                         0x2000
9154 +#define IP_CTRL_AUTONEGOTIATION_ENABLE            0x1000
9155 +#define IP_CTRL_START_AUTONEGOTIATION             0x0200
9156 +#define IP_CTRL_SPEED_FULL_DUPLEX                 0x0100
9157 +
9158 +/* Phy status fields */
9159 +#define IP_STATUS_AUTO_NEG_DONE                   0x0020
9160 +#define IP_STATUS_LINK_PASS                       0x0004
9161 +
9162 +#define IP_AUTONEG_DONE(ip_phy_status)                   \
9163 +    (((ip_phy_status) &                                  \
9164 +        (IP_STATUS_AUTO_NEG_DONE)) ==                    \
9165 +        (IP_STATUS_AUTO_NEG_DONE))
9166 +
9167 +/* ICPLUS_PHY_ID1 fields */
9168 +#define IP_PHY_ID1_EXPECTATION                    0x0243 /* OUI >> 6 */
9169 +
9170 +/* ICPLUS_PHY_ID2 fields */
9171 +#define IP_OUI_LSB_MASK                           0xfc00
9172 +#define IP_OUI_LSB_EXPECTATION                    0x0c00
9173 +#define IP_OUI_LSB_SHIFT                              10
9174 +#define IP_MODEL_NUM_MASK                         0x03f0
9175 +#define IP_MODEL_NUM_SHIFT                             4
9176 +#define IP_REV_NUM_MASK                           0x000f
9177 +#define IP_REV_NUM_SHIFT                               0
9178 +
9179 +/* Link Partner ability */
9180 +#define IP_LINK_100BASETX_FULL_DUPLEX       0x0100
9181 +#define IP_LINK_100BASETX                   0x0080
9182 +#define IP_LINK_10BASETX_FULL_DUPLEX        0x0040
9183 +#define IP_LINK_10BASETX                    0x0020
9184 +
9185 +/* Advertisement register. */
9186 +#define IP_ADVERTISE_100FULL                0x0100
9187 +#define IP_ADVERTISE_100HALF                0x0080  
9188 +#define IP_ADVERTISE_10FULL                 0x0040  
9189 +#define IP_ADVERTISE_10HALF                 0x0020  
9190 +
9191 +#define IP_ADVERTISE_ALL (IP_ADVERTISE_10HALF | IP_ADVERTISE_10FULL | \
9192 +                       IP_ADVERTISE_100HALF | IP_ADVERTISE_100FULL)
9193 +               
9194 +               
9195 +#define IP_VLAN_TAG_VALID                   0x81
9196 +#define IP_VLAN_TAG_SIZE                    4
9197 +#define IP_VLAN_TAG_OFFSET                  12   /* After DA & SA */
9198 +#define IP_SPECIAL_TAG_VALID                0x81
9199 +              
9200 +/****************************/
9201 +/* Global Control Registers */
9202 +/****************************/
9203 +/* IP Global register doesn't have names based on functionality
9204 + * hence has to live with this names  for now */
9205 +#define IP_GLOBAL_PHY29_18_REG  18
9206 +#define IP_GLOBAL_PHY29_19_REG  19
9207 +#define IP_GLOBAL_PHY29_20_REG  20
9208 +#define IP_GLOBAL_PHY29_21_REG  21
9209 +#define IP_GLOBAL_PHY29_22_REG  22
9210 +#define IP_GLOBAL_PHY29_23_REG  23
9211 +#define IP_GLOBAL_PHY29_24_REG  24
9212 +#define IP_GLOBAL_PHY29_25_REG  25
9213 +#define IP_GLOBAL_PHY29_26_REG  26
9214 +#define IP_GLOBAL_PHY29_27_REG  27
9215 +#define IP_GLOBAL_PHY29_28_REG  28
9216 +#define IP_GLOBAL_PHY29_29_REG  29
9217 +#define IP_GLOBAL_PHY29_30_REG  30
9218 +#define IP_GLOBAL_PHY29_31_REG  31
9219 +
9220 +
9221 +#define IP_GLOBAL_PHY30_0_REG   0
9222 +#define IP_GLOBAL_PHY30_1_REG   1
9223 +#define IP_GLOBAL_PHY30_2_REG   2
9224 +#define IP_GLOBAL_PHY30_3_REG   3
9225 +#define IP_GLOBAL_PHY30_4_REG   4
9226 +#define IP_GLOBAL_PHY30_5_REG   5
9227 +#define IP_GLOBAL_PHY30_6_REG   6
9228 +#define IP_GLOBAL_PHY30_7_REG   7
9229 +#define IP_GLOBAL_PHY30_8_REG   8
9230 +#define IP_GLOBAL_PHY30_9_REG   9
9231 +#define IP_GLOBAL_PHY30_10_REG  10
9232 +#define IP_GLOBAL_PHY30_11_REG  11
9233 +#define IP_GLOBAL_PHY30_12_REG  12
9234 +#define IP_GLOBAL_PHY30_13_REG  13
9235 +#define IP_GLOBAL_PHY30_16_REG  16
9236 +#define IP_GLOBAL_PHY30_17_REG  17
9237 +#define IP_GLOBAL_PHY30_18_REG  18
9238 +#define IP_GLOBAL_PHY30_20_REG  20
9239 +#define IP_GLOBAL_PHY30_21_REG  21
9240 +#define IP_GLOBAL_PHY30_22_REG  22
9241 +#define IP_GLOBAL_PHY30_23_REG  23
9242 +#define IP_GLOBAL_PHY30_24_REG  24
9243 +#define IP_GLOBAL_PHY30_25_REG  25
9244 +#define IP_GLOBAL_PHY30_26_REG  26
9245 +#define IP_GLOBAL_PHY30_27_REG  27
9246 +#define IP_GLOBAL_PHY30_28_REG  28
9247 +#define IP_GLOBAL_PHY30_29_REG  29
9248 +#define IP_GLOBAL_PHY30_30_REG  30
9249 +#define IP_GLOBAL_PHY30_31_REG  31
9250 +
9251 +#define IP_GLOBAL_PHY31_0_REG   0
9252 +#define IP_GLOBAL_PHY31_1_REG   1
9253 +#define IP_GLOBAL_PHY31_2_REG   2
9254 +#define IP_GLOBAL_PHY31_3_REG   3
9255 +#define IP_GLOBAL_PHY31_4_REG   4
9256 +#define IP_GLOBAL_PHY31_5_REG   5
9257 +#define IP_GLOBAL_PHY31_6_REG   6
9258 +
9259 +#define IP_GLOBAL_PHY29_31_REG  31
9260 +
9261 +
9262 +#define IP_VLAN0_OUTPUT_PORT_MASK_S     0
9263 +#define IP_VLAN1_OUTPUT_PORT_MASK_S     8
9264 +#define IP_VLAN2_OUTPUT_PORT_MASK_S     0
9265 +#define IP_VLAN3_OUTPUT_PORT_MASK_S     8
9266 +
9267 +/* Masks and shifts for 29.23 register */
9268 +#define IP_PORTX_ADD_TAG_S               11
9269 +#define IP_PORTX_REMOVE_TAG_S            6       
9270 +#define IP_PORT5_ADD_TAG_S               1
9271 +#define IP_PORT5_REMOVE_TAG_S            0
9272 +
9273 +/* 
9274 + * 30.9   Definitions 
9275 + */
9276 +#define TAG_VLAN_ENABLE         0x0080
9277 +#define VID_INDX_SEL_M          0x0070            
9278 +#define VID_INDX_SEL_S          4            
9279 +
9280 +                  
9281 +/* PHY Addresses */
9282 +#define IP_PHY0_ADDR    0
9283 +#define IP_PHY1_ADDR    1
9284 +#define IP_PHY2_ADDR    2
9285 +#define IP_PHY3_ADDR    3
9286 +#define IP_PHY4_ADDR    4
9287 +
9288 +#define IP_GLOBAL_PHY29_ADDR    29
9289 +#define IP_GLOBAL_PHY30_ADDR    30
9290 +#define IP_GLOBAL_PHY31_ADDR    31
9291 +
9292 +
9293 +#endif
9294 diff -urN linux-mips-orig/drivers/net/ath/kendSwitchPhy.c linux-mips-new/drivers/net/ath/kendSwitchPhy.c
9295 --- linux-mips-orig/drivers/net/ath/kendSwitchPhy.c     1970-01-01 01:00:00.000000000 +0100
9296 +++ linux-mips-new/drivers/net/ath/kendSwitchPhy.c      2005-12-31 12:33:57.678538064 +0000
9297 @@ -0,0 +1,286 @@
9298 +/*
9299 + * This file is subject to the terms and conditions of the GNU General Public
9300 + * License.  See the file "COPYING" in the main directory of this archive
9301 + * for more details.
9302 + *
9303 + * Copyright © 2003 Atheros Communications, Inc.,  All Rights Reserved.
9304 + */
9305 +
9306 +/*
9307 + * Manage the ethernet PHY.
9308 + * This code supports a simple 1-port ethernet phy, Realtek RTL8201BL,
9309 + * and compatible PHYs, such as the Kendin KS8721B.
9310 + * All definitions in this file are operating system independent!
9311 + */
9312 +
9313 +#if defined(linux)
9314 +#include <linux/config.h>
9315 +#include <linux/types.h>
9316 +#include <linux/netdevice.h>
9317 +#include <linux/etherdevice.h>
9318 +#include <linux/delay.h>
9319 +
9320 +#include "ar531xlnx.h"
9321 +#endif
9322 +
9323 +#if defined(__ECOS)
9324 +#include "ae531xecos.h"
9325 +#endif
9326 +
9327 +
9328 +#include "ae531xmac.h"
9329 +#include "ae531xreg.h"
9330 +#include "rtPhy.h"
9331 +
9332 +#define RT_MAX_PORTS 5 /* max addressable ports per MIIM */
9333 +
9334 +#if /* DEBUG */ 1
9335 +#define RT_DEBUG_ERROR     0x00000001
9336 +#define RT_DEBUG_PHYSETUP  0x00000002
9337 +#define RT_DEBUG_PHYCHANGE 0x00000004
9338 +
9339 +/* XXX: must hardcode this since same MIIM for all ethUnits */
9340 +const UINT32 phyBase = 0xb8100000;
9341 +
9342 +int rtPhyDebug = RT_DEBUG_ERROR;
9343 +
9344 +#define RT_PRINT(FLG, X)                            \
9345 +{                                                   \
9346 +    if (rtPhyDebug & (FLG)) {                       \
9347 +        DEBUG_PRINTF X;                             \
9348 +    }                                               \
9349 +}
9350 +#else
9351 +#define RT_PRINT(FLG, X)
9352 +#endif
9353 +
9354 +/*
9355 + * Track per-PHY state.
9356 + */
9357 +static BOOL rtPhyAlive[RT_MAX_PORTS];
9358 +
9359 +
9360 +/******************************************************************************
9361 +*
9362 +* rt_phySetup - reset and setup the PHY associated with
9363 +* the specified MAC unit number.
9364 +*
9365 +* Resets the associated PHY port.
9366 +*
9367 +* RETURNS:
9368 +*    TRUE  --> associated PHY is alive
9369 +*    FALSE --> no LINKs on this ethernet unit
9370 +*/
9371 +
9372 +BOOL
9373 +rt_phySetup(int ethUnit, UINT32 phyBaseIgnored)
9374 +{
9375 +    BOOL    linkAlive = FALSE;
9376 +
9377 +    /* Reset phy */
9378 +       if (ethUnit == 0) {
9379 +               int i;
9380 +               for (i=1; i<5; i++) {
9381 +                       phyRegWrite(phyBase, i, GEN_ctl, AUTONEGENA);
9382 +                       sysMsDelay(200);
9383 +                       if (phyRegRead(phyBase, i, GEN_sts) & (AUTOCMPLT | LINK)) {
9384 +                               rtPhyAlive[i] = TRUE;
9385 +                       }
9386 +                       else {
9387 +                               rtPhyAlive[i] = FALSE;
9388 +                       }
9389 +               }
9390 +       }
9391 +       else {
9392 +               phyRegWrite(phyBase, 5, GEN_ctl, AUTONEGENA);
9393 +               sysMsDelay(200);
9394 +               if (phyRegRead(phyBase, 5, GEN_sts) & (AUTOCMPLT | LINK)) {
9395 +                       rtPhyAlive[5] = TRUE;
9396 +               }
9397 +               else {
9398 +                       rtPhyAlive[5] = FALSE;
9399 +               }
9400 +       }
9401 +
9402 +    return linkAlive;
9403 +}
9404 +
9405 +/******************************************************************************
9406 +*
9407 +* rt_phyIsDuplexFull - Determines whether the phy ports associated with the
9408 +* specified device are FULL or HALF duplex.
9409 +*
9410 +* RETURNS:
9411 +*    1  --> FULL
9412 +*    0 --> HALF
9413 +*/
9414 +int
9415 +rt_phyIsFullDuplex(int ethUnit)
9416 +{
9417 +       UINT16  phyLpa = 0;
9418 +
9419 +       if (ethUnit == 0) {
9420 +               int i;
9421 +               /* 4 ports connected. If any are half-duplex report half. */
9422 +               for (i=1; i<5; i++) {
9423 +                       phyLpa = phyRegRead(phyBase, i, AN_lpa);
9424 +                       if ( (!(phyLpa & (LPA_TXFD | LPA_10FD))) && 
9425 +                                (phyLpa & (LPA_TX | LPA_10)) ) {
9426 +                               return 0;
9427 +                       }
9428 +               }
9429 +               return 1;
9430 +       }
9431 +       else {
9432 +               phyLpa = phyRegRead(phyBase, 5, AN_lpa);
9433 +               if (phyLpa & (LPA_TXFD | LPA_10FD) ) {
9434 +                       return 1;
9435 +               }
9436 +               else {
9437 +                       return 0;
9438 +               }
9439 +       }
9440 +}
9441 +
9442 +/******************************************************************************
9443 +*
9444 +* rt_phyIsSpeed100 - Determines the speed of phy ports associated with the
9445 +* specified device.
9446 +*
9447 +* RETURNS:
9448 +*    TRUE --> 100Mbit
9449 +*    FALSE --> 10Mbit
9450 +*/
9451 +BOOL
9452 +rt_phyIsSpeed100(int ethUnit)
9453 +{
9454 +    UINT16  phyLpa;
9455 +
9456 +       if (ethUnit == 0) {
9457 +               int i;
9458 +               /* 4 ports connected. If any are not 100 report 10. */
9459 +               for (i=1; i<5; i++) {
9460 +                       phyLpa = phyRegRead(phyBase, i, AN_lpa);
9461 +                       if ( (!(phyLpa & (LPA_TXFD | LPA_TX))) && 
9462 +                                (phyLpa & (LPA_10FD | LPA_10)) ) {
9463 +                               printk("10\n");
9464 +                               return FALSE;
9465 +                       }
9466 +               }
9467 +               printk("100\n");
9468 +               return TRUE;
9469 +       }
9470 +       else {
9471 +               phyLpa = phyRegRead(phyBase, 5, AN_lpa);
9472 +               if (phyLpa & (LPA_TXFD | LPA_TX) ) {
9473 +                       printk("100\n");
9474 +                       return TRUE;
9475 +               }
9476 +               else {
9477 +                       printk("10\n");
9478 +                       return FALSE;
9479 +               }
9480 +       }
9481 +}
9482 +
9483 +/*****************************************************************************
9484 +*
9485 +* rt_phyCheckStatusChange -- checks for significant changes in PHY state.
9486 +*
9487 +* A "significant change" is:
9488 +*     dropped link (e.g. ethernet cable unplugged) OR
9489 +*     autonegotiation completed + link (e.g. ethernet cable plugged in)
9490 +*
9491 +* When a PHY is plugged in, phyLinkGained is called.
9492 +* When a PHY is unplugged, phyLinkLost is called.
9493 +*/
9494 +void
9495 +rt_phyCheckStatusChange(int ethUnit)
9496 +{
9497 +    UINT16          phyHwStatus;
9498 +       int i, loopLower, loopUpper;
9499 +       
9500 +       if (ethUnit == 0) {
9501 +               loopLower = 1;
9502 +               loopUpper = 4;
9503 +       }
9504 +       else {
9505 +               loopLower = 5;
9506 +               loopUpper = 5;
9507 +       }
9508 +
9509 +       for (i=loopLower; i<=loopUpper; i++) {
9510 +               phyHwStatus = phyRegRead(phyBase, i, GEN_sts);
9511 +
9512 +               if (rtPhyAlive[i]) { /* last known status was ALIVE */
9513 +                       /* See if we've lost link */
9514 +                       if (!(phyHwStatus & LINK)) {
9515 +                               RT_PRINT(RT_DEBUG_PHYCHANGE,("\nethmac%d link down\n", ethUnit));
9516 +                               rtPhyAlive[i] = FALSE;
9517 +                               phyLinkLost(ethUnit);
9518 +                       }
9519 +               } else { /* last known status was DEAD */
9520 +                       /* Check for AN complete */
9521 +                       if ((phyHwStatus & (AUTOCMPLT | LINK)) == (AUTOCMPLT | LINK)) {
9522 +                               RT_PRINT(RT_DEBUG_PHYCHANGE,("\nethmac%d link up\n", ethUnit));
9523 +                               rtPhyAlive[i] = TRUE;
9524 +                               phyLinkGained(ethUnit);
9525 +                       }
9526 +               }
9527 +       }
9528 +}
9529 +
9530 +#if DEBUG
9531 +
9532 +/* Define the PHY registers of interest for a phyShow command */
9533 +struct rtRegisterTable_s {
9534 +    UINT32 regNum;
9535 +    char  *regIdString;
9536 +} rtRegisterTable[] =
9537 +{
9538 +    {GEN_ctl,    "Basic Mode Control (GEN_ctl)    "},
9539 +    {GEN_sts,    "Basic Mode Status (GEN_sts)     "},
9540 +    {GEN_id_hi,  "PHY Identifier 1 (GET_id_hi)    "},
9541 +    {GEN_id_lo,  "PHY Identifier 2 (GET_id_lo)    "},
9542 +    {AN_adv,     "Auto-Neg Advertisement (AN_adv) "},
9543 +    {AN_lpa,     "Auto-Neg Link Partner Ability   "},
9544 +    {AN_exp,     "Auto-Neg Expansion              "},
9545 +};
9546 +
9547 +int rtNumRegs = sizeof(rtRegisterTable) / sizeof(rtRegisterTable[0]);
9548 +
9549 +/*
9550 + * Dump the state of a PHY.
9551 + */
9552 +void
9553 +rt_phyShow(int phyUnit)
9554 +{
9555 +    int i;
9556 +    UINT16  value;
9557 +       int j, loopLower, loopUpper;
9558 +
9559 +    printf("PHY state for ethphy%d\n", phyUnit);
9560 +       
9561 +       if (phyUnit == 0) {
9562 +               loopLower = 1;
9563 +               loopUpper = 4;
9564 +       }
9565 +       else {
9566 +               loopLower = 5;
9567 +               loopUpper = 5;
9568 +       }
9569 +
9570 +       for (j=loopLower; j<=loopUpper; j++) {
9571 +               printk("PHY port %d:\n", j);
9572 +               for (i=0; i<rtNumRegs; i++) {
9573 +                       
9574 +                       value = phyRegRead(phyBase, j, rtRegisterTable[i].regNum);
9575 +                       
9576 +                       printf("Reg %02d (0x%02x) %s = 0x%08x\n",
9577 +                                  rtRegisterTable[i].regNum, rtRegisterTable[i].regNum,
9578 +                                  rtRegisterTable[i].regIdString, value);
9579 +               }
9580 +       }
9581 +}
9582 +
9583 +#endif
9584 diff -urN linux-mips-orig/drivers/net/ath/Makefile linux-mips-new/drivers/net/ath/Makefile
9585 --- linux-mips-orig/drivers/net/ath/Makefile    1970-01-01 01:00:00.000000000 +0100
9586 +++ linux-mips-new/drivers/net/ath/Makefile     2005-12-31 12:33:57.678538064 +0000
9587 @@ -0,0 +1,78 @@
9588 +################################################################################
9589 +#
9590 +# This file is subject to the terms and conditions of the GNU General Public
9591 +# License.  See the file "COPYING" in the main directory of this archive
9592 +# for more details.
9593 +#
9594 +# Copyright © 2004 Atheros Communications, Inc.,  All Rights Reserved.
9595 +#
9596 +# Makefile for Atheros ar531x ethernet driver
9597 +#
9598 +# Note! Dependencies are done automagically by 'make dep', which also
9599 +# removes any old dependencies. DON'T put your own dependencies here
9600 +# unless it's something special (ie not a .c file).
9601 +#
9602 +################################################################################
9603 +
9604 +#
9605 +# Makefile for the Atheros ar531x ethernet driver
9606 +#
9607 +
9608 +obj= .
9609 +
9610 +obj-m           += ae531x.o
9611 +ae531x-objs     := ae531xlnx.o ae531xmac.o
9612 +export-objs     := ae531xlnx.o
9613 +list-multi      := ae531x.o
9614 +
9615 +ifeq ($(CONFIG_KENDIN_ENET_PHY),y)
9616 +  ae531x-objs += rtPhy.o
9617 +endif
9618 +ifeq ($(CONFIG_KENDIN_KS8995XA_ENET_PHY),y)
9619 +  ae531x-objs += kendSwitchPhy.o
9620 +endif
9621 +ifeq ($(CONFIG_MARVELL_ENET_PHY),y)
9622 +  ae531x-objs += mvPhy.o
9623 +endif
9624 +ifeq ($(CONFIG_ICPLUS_ENET_PHY),y)
9625 +  ae531x-objs += ipPhy.o
9626 +endif
9627 +
9628 +#
9629 +# If building directly into kernel
9630 +#
9631 +ifneq ($(MAKING_MODULES),1)
9632 +obj-$(CONFIG_NET_ATHEROS_ETHER) := ae531x.o $(ae531x-objs)
9633 +O_TARGET := ae531x.o
9634 +endif
9635 +
9636 +INCS += -I.
9637 +
9638 +EXTRA_CFLAGS+=$(INCS) ${COPTS} -g
9639 +ifeq ($(DEBUG_BUILD),1)
9640 +EXTRA_CFLAGS+=-DDEBUG
9641 +endif
9642 +
9643 +# release tag versioning
9644 +-include $(KERNELPATH)/ath_version.mk
9645 +
9646 +-include $(TOPDIR)/Rules.make
9647 +STRIP= ${TOOLPREFIX}strip
9648 +
9649 +ifndef MODPATH
9650 +MODPATH = ${KERNELPATH}/arch/mips/ar531x/ROOTDISK/rootdir/lib/modules/${KERNELRELEASE}/
9651 +endif
9652 +
9653 +all:
9654 +       $(MAKE) -C ${KERNELPATH} SUBDIRS=$(shell pwd) modules
9655 +
9656 +install: all
9657 +       $(STRIP) -S ae531x.o
9658 +       cp ae531x.o ${KERNELPATH}/arch/mips/ar531x/ROOTDISK/rootdir/lib/modules/$(strip $(shell head -n 1 $(KERNELPATH)/Makefile | cut -f 2 -d'=')).$(strip $(shell head -n 2 $(KERNELPATH)/Makefile | tail -1 | cut -f 2 -d'=')).$(strip $(shell head -n 3 $(KERNELPATH)/Makefile | tail -1 | cut -f 2 -d'='))${EXTRAVERSION}/net/.
9659 +
9660 +clean:
9661 +       -rm -f *~ *.o *.ko *.mod.c
9662 +       -rm -f .version .*.o.flags .*.o.d .*.o.cmd .*.ko.cmd
9663 +
9664 +ae531x.o : $(ae531x-objs)
9665 +       $(LD) -o ae531x.o -r $(ae531x-objs)
9666 diff -urN linux-mips-orig/drivers/net/ath/mvPhy.c linux-mips-new/drivers/net/ath/mvPhy.c
9667 --- linux-mips-orig/drivers/net/ath/mvPhy.c     1970-01-01 01:00:00.000000000 +0100
9668 +++ linux-mips-new/drivers/net/ath/mvPhy.c      2005-12-31 12:33:57.726530768 +0000
9669 @@ -0,0 +1,1230 @@
9670 +/*
9671 + * This file is subject to the terms and conditions of the GNU General Public
9672 + * License.  See the file "COPYING" in the main directory of this archive
9673 + * for more details.
9674 + *
9675 + * Copyright © 2003 Atheros Communications, Inc.,  All Rights Reserved.
9676 + */
9677 +
9678 +/*
9679 +* Manage the ethernet PHY switch, Marvell 88E6060.
9680 +* 
9681 +* This module is intended to be largely OS and platform-independent.
9682 +*/
9683 +
9684 +#if defined(linux)
9685 +#include <linux/config.h>
9686 +#include <linux/types.h>
9687 +#include <linux/netdevice.h>
9688 +#include <linux/etherdevice.h>
9689 +#include <linux/delay.h>
9690 +
9691 +#include "ar531xlnx.h"
9692 +#endif
9693 +
9694 +#if defined(__ECOS)
9695 +#include "ae531xecos.h"
9696 +#endif
9697 +
9698 +
9699 +#include "ae531xmac.h"
9700 +#include "ae531xreg.h"
9701 +#include "mvPhy.h"
9702 +
9703 +#if /* DEBUG */ 1
9704 +#define MV_DEBUG_ERROR     0x00000001
9705 +#define MV_DEBUG_PHYSETUP  0x00000002
9706 +#define MV_DEBUG_PHYCHANGE 0x00000004
9707 +
9708 +int mvPhyDebug = MV_DEBUG_ERROR;
9709 +
9710 +#define MV_PRINT(FLG, X)                            \
9711 +{                                                   \
9712 +    if (mvPhyDebug & (FLG)) {                       \
9713 +        DEBUG_PRINTF X;                             \
9714 +    }                                               \
9715 +}
9716 +#else
9717 +#define MV_PRINT(FLG, X)
9718 +#endif
9719 +
9720 +#if CONFIG_VENETDEV
9721 +/*
9722 + * On AR5312 with CONFIG_VENETDEV==1,
9723 + *   ports 0..3 are LAN ports  (accessed through ae0)
9724 + *   port 4 is the WAN port.   (accessed through ae1)
9725 + * 
9726 + * The phy switch settings in the mvPhyInfo table are set accordingly.
9727 + */
9728 +#define MV_WAN_PORT          4
9729 +#define MV_IS_LAN_PORT(port) ((port) <  MV_WAN_PORT)
9730 +#define MV_IS_WAN_PORT(port) ((port) == MV_WAN_PORT)
9731 +#endif
9732 +
9733 +/*
9734 + * Track per-PHY port information.
9735 + */
9736 +typedef struct {
9737 +    BOOL   isEnetPort;       /* normal enet port */
9738 +    BOOL   isPhyAlive;       /* last known state of link */
9739 +    int    ethUnit;          /* MAC associated with this phy port */
9740 +    UINT32 phyBase;
9741 +    UINT32 phyAddr;          /* PHY registers associated with this phy port */
9742 +    UINT32 switchPortAddr;   /* switch port regs assoc'ed with this phy port */
9743 +    UINT32 VLANTableSetting; /* Value to be written to VLAN table */
9744 +} mvPhyInfo_t;
9745 +
9746 +/******************************************************************************
9747 + * Per-PHY information, indexed by PHY unit number.
9748 + *
9749 + * This table is board-dependent.  It includes information
9750 + * about which enet MAC controls which PHY port.
9751 + */
9752 +mvPhyInfo_t mvPhyInfo[] = {
9753 +    /*
9754 +     * On AP30/AR5312, all PHYs are associated with MAC0.
9755 +     * AP30/AR5312's MAC1 isn't used for anything.
9756 +     * CONFIG_VENETDEV==1 (router) configuration:
9757 +     *    Ports 0,1,2, and 3 are "LAN ports"
9758 +     *    Port 4 is a WAN port
9759 +     *    Port 5 connects to MAC0 in the AR5312
9760 +     * CONFIG_VENETDEV==0 (bridge) configuration:
9761 +     *    Ports 0,1,2,3,4 are "LAN ports"
9762 +     *    Port 5 connects to the MAC0 in the AR5312
9763 +     */
9764 +    {isEnetPort: TRUE,   /* phy port 0 -- LAN port 0 */
9765 +     isPhyAlive: FALSE,
9766 +     ethUnit: 0,
9767 +     phyBase: 0,
9768 +     phyAddr: 0x10,
9769 +     switchPortAddr: 0x18,
9770 +#if CONFIG_VENETDEV
9771 +     VLANTableSetting: 0x2e
9772 +#else
9773 +     VLANTableSetting: 0x3e
9774 +#endif
9775 +    },
9776 +
9777 +    {isEnetPort: TRUE,   /* phy port 1 -- LAN port 1 */
9778 +     isPhyAlive: FALSE,
9779 +     ethUnit: 0,
9780 +     phyBase: 0,
9781 +     phyAddr: 0x11,
9782 +     switchPortAddr: 0x19,
9783 +#if CONFIG_VENETDEV
9784 +     VLANTableSetting: 0x2d
9785 +#else
9786 +     VLANTableSetting: 0x3d
9787 +#endif
9788 +    },
9789 +
9790 +    {isEnetPort: TRUE,   /* phy port 2 -- LAN port 2 */
9791 +     isPhyAlive: FALSE,
9792 +     ethUnit: 0,
9793 +     phyBase: 0,
9794 +     phyAddr: 0x12, 
9795 +     switchPortAddr: 0x1a,
9796 +#if CONFIG_VENETDEV
9797 +     VLANTableSetting: 0x2b
9798 +#else
9799 +     VLANTableSetting: 0x3b
9800 +#endif
9801 +    },
9802 +
9803 +    {isEnetPort: TRUE,   /* phy port 3 -- LAN port 3 */
9804 +     isPhyAlive: FALSE,
9805 +     ethUnit: 0,
9806 +     phyBase: 0,
9807 +     phyAddr: 0x13, 
9808 +     switchPortAddr: 0x1b,
9809 +#if CONFIG_VENETDEV
9810 +     VLANTableSetting: 0x27
9811 +#else
9812 +     VLANTableSetting: 0x37
9813 +#endif
9814 +    },
9815 +
9816 +    {isEnetPort: TRUE,   /* phy port 4 -- WAN port or LAN port 4 */
9817 +     isPhyAlive: FALSE,
9818 +     ethUnit: 0,
9819 +     phyBase: 0,
9820 +     phyAddr: 0x14, 
9821 +     switchPortAddr: 0x1c,
9822 +#if CONFIG_VENETDEV
9823 +     VLANTableSetting: 0x1020  /* WAN port */
9824 +#else
9825 +     VLANTableSetting: 0x2f    /* LAN port 4 */
9826 +#endif
9827 +    },
9828 +
9829 +    {isEnetPort: FALSE,  /* phy port 5 -- CPU port (no RJ45 connector) */
9830 +     isPhyAlive: TRUE,
9831 +     ethUnit: 0,
9832 +     phyBase: 0,
9833 +     phyAddr: 0x15, 
9834 +     switchPortAddr: 0x1d,
9835 +#if CONFIG_VENETDEV
9836 +     VLANTableSetting: 0x0f    /* Send only to LAN ports */
9837 +#else
9838 +     VLANTableSetting: 0x1f    /* Send to all ports */
9839 +#endif
9840 +    },
9841 +};
9842 +
9843 +#define MV_PHY_MAX (sizeof(mvPhyInfo) / sizeof(mvPhyInfo[0]))
9844 +
9845 +/* Range of valid PHY IDs is [MIN..MAX] */
9846 +#define MV_ID_MIN 0
9847 +#define MV_ID_MAX (MV_PHY_MAX-1)
9848 +
9849 +/* Convenience macros to access myPhyInfo */
9850 +#define MV_IS_ENET_PORT(phyUnit) (mvPhyInfo[phyUnit].isEnetPort)
9851 +#define MV_IS_PHY_ALIVE(phyUnit) (mvPhyInfo[phyUnit].isPhyAlive)
9852 +#define MV_ETHUNIT(phyUnit) (mvPhyInfo[phyUnit].ethUnit)
9853 +#define MV_PHYBASE(phyUnit) (mvPhyInfo[phyUnit].phyBase)
9854 +#define MV_PHYADDR(phyUnit) (mvPhyInfo[phyUnit].phyAddr)
9855 +#define MV_SWITCH_PORT_ADDR(phyUnit) (mvPhyInfo[phyUnit].switchPortAddr)
9856 +#define MV_VLAN_TABLE_SETTING(phyUnit) (mvPhyInfo[phyUnit].VLANTableSetting)
9857 +
9858 +#define MV_IS_ETHUNIT(phyUnit, ethUnit) \
9859 +    (MV_IS_ENET_PORT(phyUnit) &&        \
9860 +    MV_ETHUNIT(phyUnit) == (ethUnit))
9861 +
9862 +
9863 +/* Forward references */
9864 +BOOL       mv_phyIsLinkAlive(int phyUnit);
9865 +LOCAL void mv_VLANInit(int ethUnit);
9866 +LOCAL void mv_enableConfiguredPorts(int ethUnit);
9867 +LOCAL void mv_verifyReady(int ethUnit);
9868 +BOOL       mv_phySetup(int ethUnit, UINT32 phyBase);
9869 +int        mv_phyIsFullDuplex(int ethUnit);
9870 +BOOL       mv_phyIsSpeed100(int phyUnit);
9871 +LOCAL BOOL mv_validPhyId(int phyUnit);
9872 +void       mv_flushATUDB(int phyUnit);
9873 +void       mv_phyCheckStatusChange(int ethUnit);
9874 +#if DEBUG
9875 +void       mv_phyShow(int phyUnit);
9876 +void       mv_phySet(int phyUnit, UINT32 regnum, UINT32 value);
9877 +void       mv_switchPortSet(int phyUnit, UINT32 regnum, UINT32 value);
9878 +void       mv_switchGlobalSet(int phyUnit, UINT32 regnum, UINT32 value);
9879 +void       mv_showATUDB(int phyUnit);
9880 +void       mv_countGoodFrames(int phyUnit);
9881 +void       mv_countBadFrames(int phyUnit);
9882 +void       mv_showFrameCounts(int phyUnit);
9883 +#endif
9884 +
9885 +
9886 +/******************************************************************************
9887 +*
9888 +* mv_phyIsLinkAlive - test to see if the specified link is alive
9889 +*
9890 +* RETURNS:
9891 +*    TRUE  --> link is alive
9892 +*    FALSE --> link is down
9893 +*/
9894 +BOOL
9895 +mv_phyIsLinkAlive(int phyUnit)
9896 +{
9897 +    UINT16 phyHwStatus;
9898 +    UINT32 phyBase;
9899 +    UINT32 phyAddr;
9900 +
9901 +    phyBase = MV_PHYBASE(phyUnit);
9902 +    phyAddr = MV_PHYADDR(phyUnit);
9903 +
9904 +    phyHwStatus = phyRegRead(phyBase, phyAddr, MV_PHY_SPECIFIC_STATUS);
9905 +
9906 +    if (phyHwStatus & MV_STATUS_REAL_TIME_LINK_UP) {
9907 +        return TRUE;
9908 +    } else {
9909 +        return FALSE;
9910 +    }
9911 +}
9912 +
9913 +/******************************************************************************
9914 +*
9915 +* mv_VLANInit - initialize "port-based VLANs" for the specified enet unit.
9916 +*/
9917 +LOCAL void
9918 +mv_VLANInit(int ethUnit)
9919 +{
9920 +    int     phyUnit;
9921 +    UINT32  phyBase;
9922 +    UINT32  switchPortAddr;
9923 +
9924 +    for (phyUnit=0; phyUnit < MV_PHY_MAX; phyUnit++) {
9925 +        if (MV_ETHUNIT(phyUnit) != ethUnit) {
9926 +            continue;
9927 +        }
9928 +
9929 +        phyBase        = MV_PHYBASE(phyUnit);
9930 +        switchPortAddr = MV_SWITCH_PORT_ADDR(phyUnit);
9931 +
9932 +        phyRegWrite(phyBase, switchPortAddr, MV_PORT_BASED_VLAN_MAP,
9933 +                    MV_VLAN_TABLE_SETTING(phyUnit));
9934 +    }
9935 +}
9936 +
9937 +#define phyPortConfigured(phyUnit) TRUE /* TBDFREEDOM2 */
9938 +
9939 +/******************************************************************************
9940 +*
9941 +* mv_enableConfiguredPorts - enable whichever PHY ports are supposed
9942 +* to be enabled according to administrative configuration.
9943 +*/
9944 +LOCAL void
9945 +mv_enableConfiguredPorts(int ethUnit)
9946 +{
9947 +    int     phyUnit;
9948 +    UINT32  phyBase;
9949 +    UINT32  switchPortAddr;
9950 +    UINT16  portControl;
9951 +    UINT16  portAssociationVector;
9952 +
9953 +    for (phyUnit=0; phyUnit < MV_PHY_MAX; phyUnit++) {
9954 +        if (MV_ETHUNIT(phyUnit) != ethUnit) {
9955 +            continue;
9956 +        }
9957 +
9958 +        phyBase        = MV_PHYBASE(phyUnit);
9959 +        switchPortAddr = MV_SWITCH_PORT_ADDR(phyUnit);
9960 +
9961 +        if (phyPortConfigured(phyUnit)) {
9962 +
9963 +            portControl = MV_PORT_CONTROL_PORT_STATE_FORWARDING;
9964 +#if CONFIG_VENETDEV
9965 +            if (!MV_IS_ENET_PORT(phyUnit)) {       /* CPU port */
9966 +                portControl |= MV_PORT_CONTROL_INGRESS_TRAILER
9967 +                            | MV_PORT_CONTROL_EGRESS_MODE;
9968 +            }
9969 +#endif
9970 +            phyRegWrite(phyBase, switchPortAddr, MV_PORT_CONTROL, portControl);
9971 +
9972 +            portAssociationVector = 1 << phyUnit;
9973 +
9974 +            phyRegWrite(phyBase, switchPortAddr,
9975 +                MV_PORT_ASSOCIATION_VECTOR, portAssociationVector);
9976 +        }
9977 +    }
9978 +}
9979 +
9980 +/******************************************************************************
9981 +*
9982 +* mv_verifyReady - validates that we're dealing with the device
9983 +* we think we're dealing with, and that it's ready.
9984 +*/
9985 +LOCAL void
9986 +mv_verifyReady(int ethUnit)
9987 +{
9988 +    int     phyUnit;
9989 +    UINT16  globalStatus;
9990 +    UINT32  phyBase = 0;
9991 +    UINT32  phyAddr;
9992 +    UINT32  switchPortAddr;
9993 +    UINT16  phyID1;
9994 +    UINT16  phyID2;
9995 +    UINT16  switchID;
9996 +
9997 +    /*
9998 +     * The first read to the Phy port registers always fails and
9999 +     * returns 0.   So get things started with a bogus read.
10000 +     */
10001 +    for (phyUnit=0; phyUnit < MV_PHY_MAX; phyUnit++) {
10002 +        if (!MV_IS_ETHUNIT(phyUnit, ethUnit)) {
10003 +            continue;
10004 +        }
10005 +        phyBase = MV_PHYBASE(phyUnit);
10006 +        phyAddr = MV_PHYADDR(phyUnit);
10007 +    
10008 +        (void)phyRegRead(phyBase, phyAddr, MV_PHY_ID1); /* returns 0 */
10009 +        break;
10010 +    }
10011 +
10012 +    for (phyUnit=0; phyUnit < MV_PHY_MAX; phyUnit++) {
10013 +        if (!MV_IS_ETHUNIT(phyUnit, ethUnit)) {
10014 +            continue;
10015 +        }
10016 +
10017 +        /*******************/
10018 +        /* Verify phy port */
10019 +        /*******************/
10020 +        phyBase = MV_PHYBASE(phyUnit);
10021 +        phyAddr = MV_PHYADDR(phyUnit);
10022 +    
10023 +        phyID1 = phyRegRead(phyBase, phyAddr, MV_PHY_ID1);
10024 +        if (phyID1 != MV_PHY_ID1_EXPECTATION) {
10025 +            MV_PRINT(MV_DEBUG_PHYSETUP,
10026 +                      ("Invalid PHY ID1 for ethmac%d port%d.  Expected 0x%04x, read 0x%04x\n",
10027 +                       ethUnit,
10028 +                       phyUnit,
10029 +                       MV_PHY_ID1_EXPECTATION,
10030 +                       phyID1));
10031 +            return;
10032 +        }
10033 +    
10034 +        phyID2 = phyRegRead(phyBase, phyAddr, MV_PHY_ID2);
10035 +        if ((phyID2 & MV_OUI_LSB_MASK) != MV_OUI_LSB_EXPECTATION) {
10036 +            MV_PRINT(MV_DEBUG_PHYSETUP,
10037 +                      ("Invalid PHY ID2 for ethmac%d port %d.  Expected 0x%04x, read 0x%04x\n",
10038 +                       ethUnit,
10039 +                       phyUnit,
10040 +                       MV_OUI_LSB_EXPECTATION,
10041 +                       phyID2));
10042 +            return;
10043 +        }
10044 +    
10045 +        MV_PRINT(MV_DEBUG_PHYSETUP,
10046 +                  ("Found PHY ethmac%d port%d: model 0x%x revision 0x%x\n",
10047 +                   ethUnit,
10048 +                   phyUnit,
10049 +                   (phyID2 & MV_MODEL_NUM_MASK) >> MV_MODEL_NUM_SHIFT,
10050 +                   (phyID2 & MV_REV_NUM_MASK) >> MV_REV_NUM_SHIFT));
10051 +    
10052 +    
10053 +        /**********************/
10054 +        /* Verify switch port */
10055 +        /**********************/
10056 +        switchPortAddr = MV_SWITCH_PORT_ADDR(phyUnit);
10057 +    
10058 +        switchID = phyRegRead(phyBase, switchPortAddr, MV_SWITCH_ID);
10059 +        if ((switchID & MV_SWITCH_ID_DEV_MASK) !=
10060 +            MV_SWITCH_ID_DEV_EXPECTATION) {
10061 +    
10062 +            MV_PRINT(MV_DEBUG_PHYSETUP,
10063 +                      ("Invalid switch ID for ethmac%d port %d.  Expected 0x%04x, read 0x%04x\n",
10064 +                       ethUnit,
10065 +                       phyUnit,
10066 +                       MV_SWITCH_ID_DEV_EXPECTATION,
10067 +                       switchID));
10068 +            return;
10069 +        }
10070 +    
10071 +        MV_PRINT(MV_DEBUG_PHYSETUP,
10072 +                  ("Found PHY switch for enet %d port %d deviceID 0x%x revision 0x%x\n",
10073 +                    ethUnit,
10074 +                    phyUnit,
10075 +                    (switchID & MV_SWITCH_ID_DEV_MASK) >> MV_SWITCH_ID_DEV_SHIFT,
10076 +                    (switchID & MV_SWITCH_ID_REV_MASK) >> MV_SWITCH_ID_REV_SHIFT))
10077 +    }
10078 +    
10079 +    /*******************************/
10080 +    /* Verify that switch is ready */
10081 +    /*******************************/
10082 +    if (phyBase) {
10083 +        globalStatus = phyRegRead(phyBase, MV_SWITCH_GLOBAL_ADDR,
10084 +                                  MV_SWITCH_GLOBAL_STATUS);
10085 +
10086 +        if (!(globalStatus & MV_SWITCH_STATUS_READY_MASK)) {
10087 +            MV_PRINT(MV_DEBUG_PHYSETUP,
10088 +                      ("PHY switch for ethmac%d NOT ready!\n",
10089 +                       ethUnit));
10090 +        }
10091 +    } else {
10092 +        MV_PRINT(MV_DEBUG_PHYSETUP,
10093 +                  ("No ports configured for ethmac%d\n", ethUnit));
10094 +    }
10095 +}
10096 +
10097 +/******************************************************************************
10098 +*
10099 +* mv_phySetup - reset and setup the PHY switch.
10100 +*
10101 +* Resets each PHY port.
10102 +*
10103 +* RETURNS:
10104 +*    TRUE  --> at least 1 PHY with LINK
10105 +*    FALSE --> no LINKs on this ethernet unit
10106 +*/
10107 +BOOL
10108 +mv_phySetup(int ethUnit, UINT32 phyBase)
10109 +{
10110 +    int     phyUnit;
10111 +    int     liveLinks = 0;
10112 +    BOOL    foundPhy = FALSE;
10113 +    UINT32  phyAddr;
10114 +    UINT16  atuControl;
10115 +
10116 +    /*
10117 +     * Allow platform-specific code to determine the default Ethernet MAC
10118 +     * at run-time.  If phyEthMacDefault returns a negative value, use the
10119 +     * static mvPhyInfo table "as is".  But if phyEthMacDefault returns a
10120 +     * non-negative value, use it as the default ethernet unit.
10121 +     */
10122 +    {
10123 +        int ethMacDefault = phyEthMacDefault();
10124 +
10125 +        if (ethMacDefault >= 0) {
10126 +            for (phyUnit=0; phyUnit < MV_PHY_MAX; phyUnit++) {
10127 +                MV_ETHUNIT(phyUnit)=ethMacDefault;
10128 +            }
10129 +        }
10130 +    }
10131 +
10132 +    /*
10133 +     * See if there's any configuration data for this enet,
10134 +     * and set up phyBase in table.
10135 +     */
10136 +    for (phyUnit=0; phyUnit < MV_PHY_MAX; phyUnit++) {
10137 +        if (MV_ETHUNIT(phyUnit) != ethUnit) {
10138 +            continue;
10139 +        }
10140 +
10141 +        MV_PHYBASE(phyUnit) = phyBase;
10142 +        foundPhy = TRUE;
10143 +    }
10144 +
10145 +    if (!foundPhy) {
10146 +        return FALSE; /* No PHY's configured for this ethUnit */
10147 +    }
10148 +
10149 +    /* Verify that the switch is what we think it is, and that it's ready */
10150 +    mv_verifyReady(ethUnit);
10151 +
10152 +    /* Initialize global switch settings */
10153 +    atuControl  = MV_ATUCTRL_AGE_TIME_DEFAULT << MV_ATUCTRL_AGE_TIME_SHIFT;
10154 +    atuControl |= MV_ATUCTRL_ATU_SIZE_DEFAULT << MV_ATUCTRL_ATU_SIZE_SHIFT;
10155 +    phyRegWrite(phyBase, MV_SWITCH_GLOBAL_ADDR, MV_ATU_CONTROL, atuControl);
10156 +
10157 +    /* Reset PHYs and start autonegoation on each. */
10158 +    for (phyUnit=0; phyUnit < MV_PHY_MAX; phyUnit++) {
10159 +        if (MV_ETHUNIT(phyUnit) != ethUnit) {
10160 +            continue;
10161 +        }
10162 +
10163 +        phyBase = MV_PHYBASE(phyUnit);
10164 +        phyAddr = MV_PHYADDR(phyUnit);
10165 +
10166 +        phyRegWrite(phyBase, phyAddr, MV_PHY_CONTROL,
10167 +                    MV_CTRL_SOFTWARE_RESET | MV_CTRL_AUTONEGOTIATION_ENABLE);
10168 +    }
10169 +
10170 +#if 0 /* Don't wait -- we'll detect shortly after the link comes up */
10171 +{
10172 +    int timeout;
10173 +    UINT16  phyHwStatus;
10174 +
10175 +    /*
10176 +     * Wait 5 seconds for ALL associated PHYs to finish autonegotiation.
10177 +     */
10178 +    timeout=50;
10179 +    for (phyUnit=0; (phyUnit < MV_PHY_MAX) && (timeout > 0); phyUnit++) {
10180 +        if (!MV_IS_ETHUNIT(phyUnit, ethUnit)) {
10181 +            continue;
10182 +        }
10183 +        for (;;) {
10184 +            phyBase = MV_PHYBASE(phyUnit);
10185 +            phyAddr = MV_PHYADDR(phyUnit);
10186 +
10187 +            phyHwStatus = phyRegRead(phyBase, phyAddr, MV_PHY_SPECIFIC_STATUS);
10188 +
10189 +            if (MV_AUTONEG_DONE(phyHwStatus)) {
10190 +                break;
10191 +            }
10192 +
10193 +            if (--timeout == 0) {
10194 +                break;
10195 +            }
10196 +
10197 +            sysMsDelay(100);
10198 +        }
10199 +    }
10200 +}
10201 +#endif
10202 +
10203 +    /*
10204 +     * All PHYs have had adequate time to autonegotiate.
10205 +     * Now initialize software status.
10206 +     *
10207 +     * It's possible that some ports may take a bit longer
10208 +     * to autonegotiate; but we can't wait forever.  They'll
10209 +     * get noticed by mv_phyCheckStatusChange during regular
10210 +     * polling activities.
10211 +     */
10212 +    for (phyUnit=0; phyUnit < MV_PHY_MAX; phyUnit++) {
10213 +        if (!MV_IS_ETHUNIT(phyUnit, ethUnit)) {
10214 +            continue;
10215 +        }
10216 +
10217 +        if (mv_phyIsLinkAlive(phyUnit)) {
10218 +            liveLinks++;
10219 +            MV_IS_PHY_ALIVE(phyUnit) = TRUE;
10220 +        } else {
10221 +            MV_IS_PHY_ALIVE(phyUnit) = FALSE;
10222 +        }
10223 +
10224 +        MV_PRINT(MV_DEBUG_PHYSETUP,
10225 +            ("ethmac%d: Phy Status=%4.4x\n",
10226 +            ethUnit, 
10227 +            phyRegRead(MV_PHYBASE(phyUnit),
10228 +                       MV_PHYADDR(phyUnit),
10229 +                       MV_PHY_SPECIFIC_STATUS)));
10230 +    }
10231 +
10232 +    mv_VLANInit(ethUnit);
10233 +
10234 +    mv_enableConfiguredPorts(ethUnit);
10235 +
10236 +    return (liveLinks > 0);
10237 +}
10238 +
10239 +
10240 +/******************************************************************************
10241 +*
10242 +* mv_phyIsDuplexFull - Determines whether the phy ports associated with the
10243 +* specified device are FULL or HALF duplex.
10244 +*
10245 +* RETURNS:
10246 +*    1 --> at least one associated PHY in FULL DUPLEX
10247 +*    0 --> all half duplex
10248 +*   -1 --> No links
10249 +*/
10250 +int
10251 +mv_phyIsFullDuplex(int ethUnit)
10252 +{
10253 +    int     phyUnit;
10254 +    UINT32  phyBase;
10255 +    UINT32  phyAddr;
10256 +    UINT16  phyHwStatus;
10257 +    int     oneIsReady=0;
10258 +
10259 +    for (phyUnit=0; phyUnit < MV_PHY_MAX; phyUnit++) {
10260 +        if (!MV_IS_ETHUNIT(phyUnit, ethUnit)) {
10261 +            continue;
10262 +        }
10263 +
10264 +        if (mv_phyIsLinkAlive(phyUnit)) {
10265 +           oneIsReady = 1;
10266 +
10267 +            phyBase = MV_PHYBASE(phyUnit);
10268 +            phyAddr = MV_PHYADDR(phyUnit);
10269 +
10270 +            phyHwStatus = phyRegRead(phyBase, phyAddr, MV_PHY_SPECIFIC_STATUS);
10271 +
10272 +            if (phyHwStatus & MV_STATUS_RESOLVED_DUPLEX_FULL) {
10273 +                return 1;
10274 +            }
10275 +        }
10276 +    }
10277 +    if (oneIsReady)
10278 +       return 0;
10279 +    else
10280 +       return -1;
10281 +}
10282 +
10283 +/******************************************************************************
10284 +*
10285 +* mv_phyIsSpeed100 - Determines the speed of a phy port
10286 +*
10287 +* RETURNS:
10288 +*    TRUE --> PHY operating at 100 Mbit
10289 +*    FALSE --> link down, or not operating at 100 Mbit
10290 +*/
10291 +BOOL
10292 +mv_phyIsSpeed100(int phyUnit)
10293 +{
10294 +    UINT16  phyHwStatus;
10295 +    UINT32  phyBase;
10296 +    UINT32  phyAddr;
10297 +
10298 +    if (MV_IS_ENET_PORT(phyUnit)) {
10299 +        if (mv_phyIsLinkAlive(phyUnit)) {
10300 +
10301 +            phyBase = MV_PHYBASE(phyUnit);
10302 +            phyAddr = MV_PHYADDR(phyUnit);
10303 +
10304 +            phyHwStatus = phyRegRead(phyBase, phyAddr, MV_PHY_SPECIFIC_STATUS);
10305 +
10306 +            if (phyHwStatus & MV_STATUS_RESOLVED_SPEED_100) {
10307 +                return TRUE;
10308 +            }
10309 +        }
10310 +    }
10311 +
10312 +    return FALSE;
10313 +}
10314 +
10315 +#if CONFIG_VENETDEV
10316 +/******************************************************************************
10317 +*
10318 +* mv_phyDetermineSource - Examine a received frame's Egress Trailer
10319 +* to determine whether it came from a LAN or WAN port.
10320 +*
10321 +* RETURNS:
10322 +*    Sets *pFromLAN: 1-->LAN, 0-->WAN
10323 +*    Modifies *pLen to remove PHY trailer from frame
10324 +*/
10325 +void
10326 +mv_phyDetermineSource(char *data, int len, int *pFromLAN)
10327 +{
10328 +    unsigned char *phyTrailer;
10329 +    unsigned char incomingPort;
10330 +
10331 +    phyTrailer = &data[len - MV_PHY_TRAILER_SIZE];
10332 +    ASSERT(phyTrailer[0] == MV_EGRESS_TRAILER_VALID);
10333 +
10334 +    incomingPort = phyTrailer[1];
10335 +    if (MV_IS_LAN_PORT(incomingPort)) {
10336 +        *pFromLAN = 1;
10337 +    } else {
10338 +        ASSERT(MV_IS_WAN_PORT(incomingPort));
10339 +        *pFromLAN = 0;
10340 +    }
10341 +}
10342 +
10343 +
10344 +/******************************************************************************
10345 +*
10346 +* mv_phySetDestinationPort - Set the Ingress Trailer to force the
10347 +* frame to be sent to LAN or WAN, as specified.
10348 +*
10349 +*/
10350 +void
10351 +mv_phySetDestinationPort(char *data, int len, int fromLAN)
10352 +{
10353 +    char *phyTrailer;
10354 +
10355 +    phyTrailer = &data[len];
10356 +    if (fromLAN) {
10357 +        /* LAN ports: Use default settings, as per mvPhyInfo */
10358 +        phyTrailer[0] = 0x00;
10359 +        phyTrailer[1] = 0x00;
10360 +    } else {
10361 +        /* WAN port: Direct to WAN port */
10362 +        phyTrailer[0] = MV_INGRESS_TRAILER_OVERRIDE;
10363 +        phyTrailer[1] = 1 << MV_WAN_PORT;
10364 +    }
10365 +    phyTrailer[2] = 0x00;
10366 +    phyTrailer[3] = 0x00;
10367 +}
10368 +#endif
10369 +
10370 +
10371 +/*****************************************************************************
10372 +*
10373 +* Validate that the specified PHY unit number is a valid PHY ID.
10374 +* Print a message if it is invalid.
10375 +* RETURNS
10376 +*   TRUE  --> valid
10377 +*   FALSE --> invalid
10378 +*/
10379 +LOCAL BOOL
10380 +mv_validPhyId(int phyUnit)
10381 +{
10382 +    if ((phyUnit >= MV_ID_MIN) && (phyUnit <= MV_ID_MAX)) {
10383 +        return TRUE;
10384 +    } else {
10385 +        PRINTF("PHY unit number must be in the range [%d..%d]\n",
10386 +            MV_ID_MIN, MV_ID_MAX);
10387 +        return FALSE;
10388 +    } 
10389 +}
10390 +
10391 +
10392 +/*****************************************************************************
10393 +*
10394 +* mv_waitWhileATUBusy - spins until the ATU completes
10395 +* its previous operation.
10396 +*/
10397 +LOCAL void
10398 +mv_waitWhileATUBusy(UINT32 phyBase)
10399 +{
10400 +    BOOL   isBusy;
10401 +    UINT16 ATUOperation;
10402 +
10403 +    do {
10404 +
10405 +        ATUOperation = phyRegRead(phyBase, MV_SWITCH_GLOBAL_ADDR,
10406 +                                  MV_ATU_OPERATION);
10407 +
10408 +        isBusy = (ATUOperation & MV_ATU_BUSY_MASK) == MV_ATU_IS_BUSY;
10409 +
10410 +    } while(isBusy);
10411 +}
10412 +
10413 +/*****************************************************************************
10414 +*
10415 +* mv_flushATUDB - flushes ALL entries in the Address Translation Unit
10416 +* DataBase associated with phyUnit.  [Since we use a single DB for
10417 +* all PHYs, this flushes the entire shared DataBase.]
10418 +*
10419 +* The current implementation flushes even more than absolutely needed --
10420 +* it flushes all entries for all phyUnits on the same ethernet as the
10421 +* specified phyUnit.
10422 +*
10423 +* It is called only when a link failure is detected on a port that was
10424 +* previously working.  In other words, when the cable is unplugged.
10425 +*/
10426 +void
10427 +mv_flushATUDB(int phyUnit)
10428 +{
10429 +    UINT32 phyBase;
10430 +
10431 +    if (!mv_validPhyId(phyUnit)) {
10432 +        PRINTF("Invalid port number: %d\n", phyUnit);
10433 +        return;
10434 +    }
10435 +
10436 +    phyBase = MV_PHYBASE(phyUnit);
10437 +    
10438 +    /* Wait for previous operation (if any) to complete */
10439 +    mv_waitWhileATUBusy(phyBase);
10440 +
10441 +    /* Tell hardware to flush all entries */
10442 +    phyRegWrite(phyBase, MV_SWITCH_GLOBAL_ADDR, MV_ATU_OPERATION, 
10443 +                MV_ATU_OP_FLUSH_ALL | MV_ATU_IS_BUSY);
10444 +
10445 +    mv_waitWhileATUBusy(phyBase);
10446 +}
10447
10448 +/*****************************************************************************
10449 +*
10450 +* mv_phyCheckStatusChange -- checks for significant changes in PHY state.
10451 +*
10452 +* A "significant change" is:
10453 +*     dropped link (e.g. ethernet cable unplugged) OR
10454 +*     autonegotiation completed + link (e.g. ethernet cable plugged in)
10455 +*/
10456 +void
10457 +mv_phyCheckStatusChange(int ethUnit)
10458 +{
10459 +    int           phyUnit;
10460 +    UINT16        phyHwStatus;
10461 +    mvPhyInfo_t   *lastStatus;
10462 +    int           linkCount   = 0;
10463 +    int           lostLinks   = 0;
10464 +    int           gainedLinks = 0;
10465 +    UINT32        phyBase;
10466 +    UINT32        phyAddr;
10467 +
10468 +    for (phyUnit=0; phyUnit < MV_PHY_MAX; phyUnit++) {
10469 +        if (!MV_IS_ETHUNIT(phyUnit, ethUnit)) {
10470 +            continue;
10471 +        }
10472 +
10473 +        phyBase = MV_PHYBASE(phyUnit);
10474 +        phyAddr = MV_PHYADDR(phyUnit);
10475 +
10476 +        lastStatus = &mvPhyInfo[phyUnit];
10477 +        phyHwStatus = phyRegRead(phyBase, phyAddr, MV_PHY_SPECIFIC_STATUS);
10478 +
10479 +        if (lastStatus->isPhyAlive) { /* last known link status was ALIVE */
10480 +            /* See if we've lost link */
10481 +            if (phyHwStatus & MV_STATUS_REAL_TIME_LINK_UP) {
10482 +                linkCount++;
10483 +            } else {
10484 +                lostLinks++;
10485 +                mv_flushATUDB(phyUnit);
10486 +                MV_PRINT(MV_DEBUG_PHYCHANGE,("\nethmac%d port%d down\n",
10487 +                                               ethUnit, phyUnit));
10488 +                lastStatus->isPhyAlive = FALSE;
10489 +            }
10490 +        } else { /* last known link status was DEAD */
10491 +            /* Check for AutoNegotiation complete */
10492 +            if (MV_AUTONEG_DONE(phyHwStatus)) {
10493 +                gainedLinks++;
10494 +               linkCount++;
10495 +                MV_PRINT(MV_DEBUG_PHYCHANGE,("\nethmac%d port%d up\n",
10496 +                                               ethUnit, phyUnit));
10497 +                lastStatus->isPhyAlive = TRUE;
10498 +            }
10499 +        }
10500 +    }
10501 +
10502 +    if (linkCount == 0) {
10503 +        if (lostLinks) {
10504 +            /* We just lost the last link for this MAC */
10505 +            phyLinkLost(ethUnit);
10506 +        }
10507 +    } else {
10508 +        if (gainedLinks == linkCount) {
10509 +            /* We just gained our first link(s) for this MAC */
10510 +            phyLinkGained(ethUnit);
10511 +        }
10512 +    }
10513 +}
10514 +
10515 +#if DEBUG
10516 +
10517 +/* Define the registers of interest for a phyShow command */
10518 +typedef struct mvRegisterTableEntry_s {
10519 +    UINT32 regNum;
10520 +    char  *regIdString;
10521 +} mvRegisterTableEntry_t;
10522 +
10523 +mvRegisterTableEntry_t mvPhyRegisterTable[] = {
10524 +    {MV_PHY_CONTROL,                 "PHY Control                     "},
10525 +    {MV_PHY_STATUS,                  "PHY Status                      "},
10526 +    {MV_PHY_ID1,                     "PHY Identifier 1                "},
10527 +    {MV_PHY_ID2,                     "PHY Identifier 2                "},
10528 +    {MV_AUTONEG_ADVERT,              "Auto-Negotiation Advertisement  "},
10529 +    {MV_LINK_PARTNER_ABILITY,        "Link Partner Ability            "},
10530 +    {MV_AUTONEG_EXPANSION,           "Auto-Negotiation Expansion      "},
10531 +    {MV_NEXT_PAGE_TRANSMIT,          "Next Page Transmit              "},
10532 +    {MV_LINK_PARTNER_NEXT_PAGE,      "Link Partner Next Page          "},
10533 +    {MV_PHY_SPECIFIC_CONTROL_1,      "PHY-Specific Control Register 1 "},
10534 +    {MV_PHY_SPECIFIC_STATUS,         "PHY-Specific Status             "},
10535 +    {MV_PHY_INTERRUPT_ENABLE,        "PHY Interrupt Enable            "},
10536 +    {MV_PHY_INTERRUPT_STATUS,        "PHY Interrupt Status            "},
10537 +    {MV_PHY_INTERRUPT_PORT_SUMMARY,  "PHY Interrupt Port Summary      "},
10538 +    {MV_RECEIVE_ERROR_COUNTER,       "Receive Error Counter           "},
10539 +    {MV_LED_PARALLEL_SELECT,         "LED Parallel Select             "},
10540 +    {MV_LED_STREAM_SELECT_LEDS,      "LED Stream Select               "},
10541 +    {MV_PHY_LED_CONTROL,             "PHY LED Control                 "},
10542 +    {MV_PHY_MANUAL_LED_OVERRIDE,     "PHY Manual LED Override         "},
10543 +    {MV_VCT_CONTROL,                 "VCT Control                     "},
10544 +    {MV_VCT_STATUS,                  "VCT Status                      "},
10545 +    {MV_PHY_SPECIFIC_CONTROL_2,      "PHY-Specific Control Register 2 "},
10546 +};
10547 +int mvPhyNumRegs = sizeof(mvPhyRegisterTable) / sizeof(mvPhyRegisterTable[0]);
10548 +
10549 +
10550 +mvRegisterTableEntry_t mvSwitchPortRegisterTable[] = {
10551 +    {MV_PORT_STATUS,              "Port Status             "},
10552 +    {MV_SWITCH_ID,                "Switch ID               "},
10553 +    {MV_PORT_CONTROL,             "Port Control            "},
10554 +    {MV_PORT_BASED_VLAN_MAP,      "Port-Based VLAN Map     "},
10555 +    {MV_PORT_ASSOCIATION_VECTOR,  "Port Association Vector "},
10556 +    {MV_RX_COUNTER,               "RX Counter              "},
10557 +    {MV_TX_COUNTER,               "TX Counter              "},
10558 +};
10559 +int mvSwitchPortNumRegs =
10560 +    sizeof(mvSwitchPortRegisterTable) / sizeof(mvSwitchPortRegisterTable[0]);
10561 +
10562 +
10563 +mvRegisterTableEntry_t mvSwitchGlobalRegisterTable[] = {
10564 +    {MV_SWITCH_GLOBAL_STATUS,  "Switch Global Status  "},
10565 +    {MV_SWITCH_MAC_ADDR0,      "Switch MAC Addr 0 & 1 "},
10566 +    {MV_SWITCH_MAC_ADDR2,      "Switch MAC Addr 2 & 3 "},
10567 +    {MV_SWITCH_MAC_ADDR4,      "Switch MAC Addr 4 & 5 "},
10568 +    {MV_SWITCH_GLOBAL_CONTROL, "Switch Global Control "},
10569 +    {MV_ATU_CONTROL,           "ATU Control           "},
10570 +    {MV_ATU_OPERATION,         "ATU Operation         "},
10571 +    {MV_ATU_DATA,              "ATU Data              "},
10572 +    {MV_ATU_MAC_ADDR0,         "ATU MAC Addr 0 & 1    "},
10573 +    {MV_ATU_MAC_ADDR2,         "ATU MAC Addr 2 & 3    "},
10574 +    {MV_ATU_MAC_ADDR4,         "ATU MAC Addr 4 & 5    "},
10575 +};
10576 +int mvSwitchGlobalNumRegs =
10577 +    sizeof(mvSwitchGlobalRegisterTable) / sizeof(mvSwitchGlobalRegisterTable[0]);
10578 +
10579 +void my_mvPhyShow(int ethUnit)
10580 +{
10581 +    int phyUnit;
10582 +    for (phyUnit=0; (phyUnit < MV_PHY_MAX); phyUnit++) {
10583 +        if (!MV_IS_ETHUNIT(phyUnit, ethUnit)) {
10584 +            continue;
10585 +        }
10586 +       mv_phyShow(phyUnit);
10587 +    }
10588 +}
10589 +
10590 +/*****************************************************************************
10591 +*
10592 +* mv_phyShow - Dump the state of a PHY.
10593 +* There are two sets of registers for each phy port:
10594 +*  "phy registers" and
10595 +*  "switch port registers"
10596 +* We dump 'em all, plus the switch global registers.
10597 +*/
10598 +void
10599 +mv_phyShow(int phyUnit)
10600 +{
10601 +    int     i;
10602 +    UINT16  value;
10603 +    UINT32  phyBase;
10604 +    UINT32  phyAddr;
10605 +    UINT32  switchPortAddr;
10606 +
10607 +    if (!mv_validPhyId(phyUnit)) {
10608 +        return;
10609 +    }
10610 +
10611 +    phyBase        = MV_PHYBASE(phyUnit);
10612 +    phyAddr        = MV_PHYADDR(phyUnit);
10613 +    switchPortAddr = MV_SWITCH_PORT_ADDR(phyUnit);
10614 +
10615 +    printk("PHY state for PHY%d (ethmac%d, phyBase 0x%8x, phyAddr 0x%x, switchAddr 0x%x)\n",
10616 +           phyUnit,
10617 +           MV_ETHUNIT(phyUnit),
10618 +           MV_PHYBASE(phyUnit),
10619 +           MV_PHYADDR(phyUnit),
10620 +           MV_SWITCH_PORT_ADDR(phyUnit));
10621 +
10622 +    printk("PHY Registers:\n");
10623 +    for (i=0; i < mvPhyNumRegs; i++) {
10624 +
10625 +        value = phyRegRead(phyBase, phyAddr, mvPhyRegisterTable[i].regNum);
10626 +
10627 +        printk("Reg %02d (0x%02x) %s = 0x%08x\n",
10628 +               mvPhyRegisterTable[i].regNum,
10629 +               mvPhyRegisterTable[i].regNum,
10630 +               mvPhyRegisterTable[i].regIdString,
10631 +               value);
10632 +    }
10633 +
10634 +    printk("Switch Port Registers:\n");
10635 +    for (i=0; i < mvSwitchPortNumRegs; i++) {
10636 +
10637 +        value = phyRegRead(phyBase, switchPortAddr,
10638 +                           mvSwitchPortRegisterTable[i].regNum);
10639 +
10640 +        printk("Reg %02d (0x%02x) %s = 0x%08x\n",
10641 +               mvSwitchPortRegisterTable[i].regNum,
10642 +               mvSwitchPortRegisterTable[i].regNum,
10643 +               mvSwitchPortRegisterTable[i].regIdString,
10644 +               value);
10645 +    }
10646 +
10647 +    printk("Switch Global Registers:\n");
10648 +    for (i=0; i < mvSwitchGlobalNumRegs; i++) {
10649 +
10650 +        value = phyRegRead(phyBase, MV_SWITCH_GLOBAL_ADDR,
10651 +                           mvSwitchGlobalRegisterTable[i].regNum);
10652 +
10653 +        printk("Reg %02d (0x%02x) %s = 0x%08x\n",
10654 +               mvSwitchGlobalRegisterTable[i].regNum,
10655 +               mvSwitchGlobalRegisterTable[i].regNum,
10656 +               mvSwitchGlobalRegisterTable[i].regIdString,
10657 +               value);
10658 +    }
10659 +}
10660 +
10661 +/*****************************************************************************
10662 +*
10663 +* mv_phySet - Modify the value of a PHY register (debug only).
10664 +*/
10665 +void
10666 +mv_phySet(int phyUnit, UINT32 regnum, UINT32 value)
10667 +{
10668 +    UINT32  phyBase;
10669 +    UINT32  phyAddr;
10670 +
10671 +    if (mv_validPhyId(phyUnit)) {
10672 +
10673 +        phyBase = MV_PHYBASE(phyUnit);
10674 +        phyAddr = MV_PHYADDR(phyUnit);
10675 +
10676 +        phyRegWrite(phyBase, phyAddr, regnum, value);
10677 +    }
10678 +}
10679 +
10680 +
10681 +/*****************************************************************************
10682 +*
10683 +* mv_switchPortSet - Modify the value of a switch port register (debug only).
10684 +*/
10685 +void
10686 +mv_switchPortSet(int phyUnit, UINT32 regnum, UINT32 value)
10687 +{
10688 +    UINT32  phyBase;
10689 +    UINT32  switchPortAddr;
10690 +
10691 +    if (mv_validPhyId(phyUnit)) {
10692 +
10693 +        phyBase = MV_PHYBASE(phyUnit);
10694 +        switchPortAddr = MV_SWITCH_PORT_ADDR(phyUnit);
10695 +
10696 +        phyRegWrite(phyBase, switchPortAddr, regnum, value);
10697 +    }
10698 +}
10699
10700 +/*****************************************************************************
10701 +*
10702 +* mv_switchGlobalSet - Modify the value of a switch global register
10703 +* (debug only).
10704 +*/
10705 +void
10706 +mv_switchGlobalSet(int phyUnit, UINT32 regnum, UINT32 value)
10707 +{
10708 +    UINT32  phyBase;
10709 +
10710 +    if (mv_validPhyId(phyUnit)) {
10711 +
10712 +        phyBase = MV_PHYBASE(phyUnit);
10713 +
10714 +        phyRegWrite(phyBase, MV_SWITCH_GLOBAL_ADDR, regnum, value);
10715 +    }
10716 +}
10717 +
10718 +/*****************************************************************************
10719 +*
10720 +* mv_showATUDB - Dump the contents of the Address Translation Unit DataBase
10721 +* for the PHY switch associated with the specified phy.
10722 +*/
10723 +void
10724 +mv_showATUDB(int phyUnit)
10725 +{
10726 +    UINT32 phyBase;
10727 +    UINT16 ATUData;
10728 +    UINT16 ATUMac0;
10729 +    UINT16 ATUMac2;
10730 +    UINT16 ATUMac4;
10731 +    int portVec;
10732 +    int entryState;
10733 +
10734 +    if (!mv_validPhyId(phyUnit)) {
10735 +        printk("Invalid port number: %d\n", phyUnit);
10736 +        return;
10737 +    }
10738 +
10739 +    phyBase = MV_PHYBASE(phyUnit);
10740 +    
10741 +    /* Wait for previous operation (if any) to complete */
10742 +    mv_waitWhileATUBusy(phyBase);
10743 +
10744 +    /* Initialize ATU MAC to all 1's */
10745 +    phyRegWrite(phyBase, MV_SWITCH_GLOBAL_ADDR, MV_ATU_MAC_ADDR0, 0xffff);
10746 +    phyRegWrite(phyBase, MV_SWITCH_GLOBAL_ADDR, MV_ATU_MAC_ADDR2, 0xffff);
10747 +    phyRegWrite(phyBase, MV_SWITCH_GLOBAL_ADDR, MV_ATU_MAC_ADDR4, 0xffff);
10748 +
10749 +    printk("   MAC ADDRESS    EntryState PortVector\n");
10750 +
10751 +    for(;;) {
10752 +        /* Tell hardware to get next MAC info */
10753 +        phyRegWrite(phyBase, MV_SWITCH_GLOBAL_ADDR, MV_ATU_OPERATION, 
10754 +                    MV_ATU_OP_GET_NEXT | MV_ATU_IS_BUSY);
10755 +
10756 +        mv_waitWhileATUBusy(phyBase);
10757 +
10758 +        ATUData = phyRegRead(phyBase, MV_SWITCH_GLOBAL_ADDR, MV_ATU_DATA);
10759 +        entryState = (ATUData & MV_ENTRYSTATE_MASK) >> MV_ENTRYSTATE_SHIFT;
10760 +
10761 +        if (entryState == 0) {
10762 +            /* We've hit the end of the list */
10763 +            break;
10764 +        }
10765 +
10766 +        ATUMac0 = phyRegRead(phyBase, MV_SWITCH_GLOBAL_ADDR, MV_ATU_MAC_ADDR0);
10767 +        ATUMac2 = phyRegRead(phyBase, MV_SWITCH_GLOBAL_ADDR, MV_ATU_MAC_ADDR2);
10768 +        ATUMac4 = phyRegRead(phyBase, MV_SWITCH_GLOBAL_ADDR, MV_ATU_MAC_ADDR4);
10769 +
10770 +        portVec    = (ATUData & MV_PORTVEC_MASK) >> MV_PORTVEC_SHIFT;
10771 +
10772 +        printk("%02x:%02x:%02x:%02x:%02x:%02x    0x%02x       0x%02x\n",
10773 +               ATUMac0 >> 8,    /* MAC byte 0 */
10774 +               ATUMac0 & 0xff,  /* MAC byte 1 */
10775 +               ATUMac2 >> 8,    /* MAC byte 2 */
10776 +               ATUMac2 & 0xff,  /* MAC byte 3 */
10777 +               ATUMac4 >> 8,    /* MAC byte 4 */
10778 +               ATUMac4 & 0xff,  /* MAC byte 5 */
10779 +               entryState,
10780 +               portVec);
10781 +    }
10782 +}
10783 +
10784 +LOCAL BOOL countingGoodFrames;
10785 +
10786 +/*****************************************************************************
10787 +*
10788 +* mv_countGoodFrames - starts counting GOOD RX/TX frames per port
10789 +*/
10790 +void
10791 +mv_countGoodFrames(int phyUnit)
10792 +{
10793 +    UINT32 phyBase;
10794 +    UINT16 globalControl;
10795 +
10796 +    if (mv_validPhyId(phyUnit)) {
10797 +        /*
10798 +         * Guarantee that counters are cleared by
10799 +         * forcing CtrMode to toggle and end on GOODFRAMES.
10800 +         */
10801 +
10802 +        phyBase = MV_PHYBASE(phyUnit);
10803 +
10804 +        /* Read current Switch Global Control Register */
10805 +        globalControl = phyRegRead(phyBase, MV_SWITCH_GLOBAL_ADDR,
10806 +                                   MV_SWITCH_GLOBAL_CONTROL);
10807 +
10808 +        /* Set CtrMode to count BAD frames */
10809 +        globalControl = ((globalControl & ~MV_CTRMODE_MASK) |
10810 +                         MV_CTRMODE_BADFRAMES);
10811 +
10812 +        /* Push new value out to hardware */
10813 +        phyRegWrite(phyBase, MV_SWITCH_GLOBAL_ADDR,
10814 +                    MV_SWITCH_GLOBAL_CONTROL, globalControl);
10815 +
10816 +        /* Now toggle CtrMode to count GOOD frames */
10817 +        globalControl = ((globalControl & ~MV_CTRMODE_MASK) |
10818 +                         MV_CTRMODE_GOODFRAMES);
10819 +
10820 +        /* Push new value out to hardware */
10821 +        phyRegWrite(phyBase, MV_SWITCH_GLOBAL_ADDR,
10822 +                    MV_SWITCH_GLOBAL_CONTROL, globalControl);
10823 +
10824 +        countingGoodFrames = TRUE;
10825 +    }
10826 +}
10827 +
10828 +/*****************************************************************************
10829 +*
10830 +* mv_countBadFrames - starts counting BAD RX/TX frames per port
10831 +*/
10832 +void
10833 +mv_countBadFrames(int phyUnit)
10834 +{
10835 +    UINT32 phyBase;
10836 +    UINT16 globalControl;
10837 +
10838 +    if (mv_validPhyId(phyUnit)) {
10839 +        /*
10840 +         * Guarantee that counters are cleared by
10841 +         * forcing CtrMode to toggle and end on BADFRAMES.
10842 +         */
10843 +
10844 +        phyBase = MV_PHYBASE(phyUnit);
10845 +
10846 +        /* Read current Switch Global Control Register */
10847 +        globalControl = phyRegRead(phyBase, MV_SWITCH_GLOBAL_ADDR,
10848 +                                   MV_SWITCH_GLOBAL_CONTROL);
10849 +
10850 +        /* Set CtrMode to count GOOD frames */
10851 +        globalControl = ((globalControl & ~MV_CTRMODE_MASK) |
10852 +                         MV_CTRMODE_GOODFRAMES);
10853 +
10854 +        /* Push new value out to hardware */
10855 +        phyRegWrite(phyBase, MV_SWITCH_GLOBAL_ADDR,
10856 +                    MV_SWITCH_GLOBAL_CONTROL, globalControl);
10857 +
10858 +        /* Now toggle CtrMode to count BAD frames */
10859 +        globalControl = ((globalControl & ~MV_CTRMODE_MASK) |
10860 +                         MV_CTRMODE_BADFRAMES);
10861 +
10862 +        /* Push new value out to hardware */
10863 +        phyRegWrite(phyBase, MV_SWITCH_GLOBAL_ADDR,
10864 +                    MV_SWITCH_GLOBAL_CONTROL, globalControl);
10865 +
10866 +        countingGoodFrames = FALSE;
10867 +    }
10868 +}
10869 +
10870 +/*****************************************************************************
10871 +*
10872 +* mv_showFrameCounts - shows current GOOD/BAD Frame counts
10873 +*/
10874 +void
10875 +mv_showFrameCounts(int phyUnit)
10876 +{
10877 +    UINT16 rxCounter;
10878 +    UINT16 txCounter;
10879 +    UINT32 phyBase;
10880 +    UINT32 switchPortAddr;
10881 +
10882 +    if (!mv_validPhyId(phyUnit)) {
10883 +        return;
10884 +    }
10885 +
10886 +    phyBase = MV_PHYBASE(phyUnit);
10887 +    switchPortAddr = MV_SWITCH_PORT_ADDR(phyUnit);
10888 +
10889 +    rxCounter = phyRegRead(phyBase, switchPortAddr, MV_RX_COUNTER);
10890 +
10891 +    txCounter = phyRegRead(phyBase, switchPortAddr, MV_TX_COUNTER);
10892 +
10893 +    printk("port%d %s frames: receive: %05d   transmit: %05d\n",
10894 +           phyUnit,
10895 +           (countingGoodFrames ? "good" : "error"),
10896 +           rxCounter,
10897 +           txCounter);
10898 +}
10899 +#endif
10900 diff -urN linux-mips-orig/drivers/net/ath/mvPhy.h linux-mips-new/drivers/net/ath/mvPhy.h
10901 --- linux-mips-orig/drivers/net/ath/mvPhy.h     1970-01-01 01:00:00.000000000 +0100
10902 +++ linux-mips-new/drivers/net/ath/mvPhy.h      2005-12-31 12:33:57.727530616 +0000
10903 @@ -0,0 +1,162 @@
10904 +/*
10905 + * This file is subject to the terms and conditions of the GNU General Public
10906 + * License.  See the file "COPYING" in the main directory of this archive
10907 + * for more details.
10908 + *
10909 + * Copyright © 2003 Atheros Communications, Inc.,  All Rights Reserved.
10910 + */
10911 +
10912 +/*
10913 + * mvPhy.h - definitions for the ethernet PHY -- Marvell 88E6060
10914 + * All definitions in this file are operating system independent!
10915 + */
10916 +
10917 +#ifndef MVPHY_H
10918 +#define MVPHY_H
10919 +
10920 +/*****************/
10921 +/* PHY Registers */
10922 +/*****************/
10923 +#define MV_PHY_CONTROL                 0
10924 +#define MV_PHY_STATUS                  1
10925 +#define MV_PHY_ID1                     2
10926 +#define MV_PHY_ID2                     3
10927 +#define MV_AUTONEG_ADVERT              4
10928 +#define MV_LINK_PARTNER_ABILITY        5
10929 +#define MV_AUTONEG_EXPANSION           6
10930 +#define MV_NEXT_PAGE_TRANSMIT          7
10931 +#define MV_LINK_PARTNER_NEXT_PAGE      8
10932 +#define MV_PHY_SPECIFIC_CONTROL_1     16
10933 +#define MV_PHY_SPECIFIC_STATUS        17
10934 +#define MV_PHY_INTERRUPT_ENABLE       18
10935 +#define MV_PHY_INTERRUPT_STATUS       19
10936 +#define MV_PHY_INTERRUPT_PORT_SUMMARY 20
10937 +#define MV_RECEIVE_ERROR_COUNTER      21
10938 +#define MV_LED_PARALLEL_SELECT        22
10939 +#define MV_LED_STREAM_SELECT_LEDS     23
10940 +#define MV_PHY_LED_CONTROL            24
10941 +#define MV_PHY_MANUAL_LED_OVERRIDE    25
10942 +
10943 +#define MV_VCT_CONTROL                26
10944 +#define MV_VCT_STATUS                 27
10945 +#define MV_PHY_SPECIFIC_CONTROL_2     28
10946 +
10947 +/* MV_PHY_CONTROL fields */
10948 +#define MV_CTRL_SOFTWARE_RESET                    0x8000
10949 +#define MV_CTRL_AUTONEGOTIATION_ENABLE            0x1000
10950 +#define MV_CTRL_FULL_DUPLEX                      0x0100
10951 +#define MV_CTRL_100_MBPS                         0x2000
10952 +
10953 +/* MV_PHY_ID1 fields */
10954 +#define MV_PHY_ID1_EXPECTATION                    0x0141 /* OUI >> 6 */
10955 +
10956 +/* MV_PHY_ID2 fields */
10957 +#define MV_OUI_LSB_MASK                           0xfc00
10958 +#define MV_OUI_LSB_EXPECTATION                    0x0c00
10959 +#define MV_OUI_LSB_SHIFT                              10
10960 +#define MV_MODEL_NUM_MASK                         0x03f0
10961 +#define MV_MODEL_NUM_SHIFT                             4
10962 +#define MV_REV_NUM_MASK                           0x000f
10963 +#define MV_REV_NUM_SHIFT                               0
10964 +
10965 +/* MV_PHY_SPECIFIC_STATUS fields */
10966 +#define MV_STATUS_RESOLVED_SPEED_100              0x4000
10967 +#define MV_STATUS_RESOLVED_DUPLEX_FULL            0x2000
10968 +#define MV_STATUS_RESOLVED                        0x0800
10969 +#define MV_STATUS_REAL_TIME_LINK_UP               0x0400
10970 +
10971 +/* Check if autonegotiation is complete and link is up */
10972 +#define MV_AUTONEG_DONE(mv_phy_specific_status)                   \
10973 +    (((mv_phy_specific_status) &                                  \
10974 +        (MV_STATUS_RESOLVED | MV_STATUS_REAL_TIME_LINK_UP)) ==    \
10975 +        (MV_STATUS_RESOLVED | MV_STATUS_REAL_TIME_LINK_UP))
10976 +
10977 +
10978 +/*************************/
10979 +/* Switch Port Registers */
10980 +/*************************/
10981 +#define MV_PORT_STATUS                 0
10982 +#define MV_SWITCH_ID                   3
10983 +#define MV_PORT_CONTROL                4
10984 +#define MV_PORT_BASED_VLAN_MAP         6
10985 +#define MV_PORT_ASSOCIATION_VECTOR    11
10986 +#define MV_RX_COUNTER                 16
10987 +#define MV_TX_COUNTER                 17
10988 +
10989 +/* MV_SWITCH_ID fields */
10990 +#define MV_SWITCH_ID_DEV_MASK                       0xfff0
10991 +#define MV_SWITCH_ID_DEV_EXPECTATION                0x0600
10992 +#define MV_SWITCH_ID_DEV_SHIFT                           4
10993 +#define MV_SWITCH_ID_REV_MASK                       0x000f
10994 +#define MV_SWITCH_ID_REV_SHIFT                           0
10995 +
10996 +/* MV_PORT_CONTROL fields */
10997 +#define MV_PORT_CONTROL_PORT_STATE_MASK             0x0003
10998 +#define MV_PORT_CONTROL_PORT_STATE_DISABLED         0x0000
10999 +#define MV_PORT_CONTROL_PORT_STATE_FORWARDING       0x0003
11000 +
11001 +#define MV_PORT_CONTROL_EGRESS_MODE                 0x0100 /* Receive */
11002 +#define MV_PORT_CONTROL_INGRESS_TRAILER             0x4000 /* Transmit */
11003 +
11004 +#define MV_EGRESS_TRAILER_VALID                       0x80
11005 +#define MV_INGRESS_TRAILER_OVERRIDE                   0x80
11006 +
11007 +#define MV_PHY_TRAILER_SIZE                              4
11008 +
11009 +
11010 +/***************************/
11011 +/* Switch Global Registers */
11012 +/***************************/
11013 +#define MV_SWITCH_GLOBAL_STATUS        0
11014 +#define MV_SWITCH_MAC_ADDR0            1
11015 +#define MV_SWITCH_MAC_ADDR2            2
11016 +#define MV_SWITCH_MAC_ADDR4            3
11017 +#define MV_SWITCH_GLOBAL_CONTROL       4
11018 +#define MV_ATU_CONTROL                10
11019 +#define MV_ATU_OPERATION              11
11020 +#define MV_ATU_DATA                   12
11021 +#define MV_ATU_MAC_ADDR0              13
11022 +#define MV_ATU_MAC_ADDR2              14
11023 +#define MV_ATU_MAC_ADDR4              15
11024 +
11025 +/* MV_SWITCH_GLOBAL_STATUS fields */
11026 +#define MV_SWITCH_STATUS_READY_MASK  0x0800
11027 +
11028 +/* MV_SWITCH_GLOBAL_CONTROL fields */
11029 +#define MV_CTRMODE_MASK              0x0100
11030 +#define MV_CTRMODE_GOODFRAMES        0x0000
11031 +#define MV_CTRMODE_BADFRAMES         0x0100
11032 +
11033 +/* MV_ATU_CONTROL fields */
11034 +#define MV_ATUCTRL_ATU_SIZE_MASK     0x3000
11035 +#define MV_ATUCTRL_ATU_SIZE_SHIFT        12
11036 +#define MV_ATUCTRL_ATU_SIZE_DEFAULT       2 /* 1024 entry database */
11037 +#define MV_ATUCTRL_AGE_TIME_MASK     0x0ff0
11038 +#define MV_ATUCTRL_AGE_TIME_SHIFT         4
11039 +#define MV_ATUCTRL_AGE_TIME_DEFAULT      19 /* 19 * 16 = 304 seconds */
11040 +
11041 +/* MV_ATU_OPERATION fields */
11042 +#define MV_ATU_BUSY_MASK             0x8000
11043 +#define MV_ATU_IS_BUSY               0x8000
11044 +#define MV_ATU_IS_FREE               0x0000
11045 +#define MV_ATU_OP_MASK               0x7000
11046 +#define MV_ATU_OP_FLUSH_ALL          0x1000
11047 +#define MV_ATU_OP_GET_NEXT           0x4000
11048 +
11049 +/* MV_ATU_DATA fields */
11050 +#define MV_ENTRYPRI_MASK             0xc000
11051 +#define MV_ENTRYPRI_SHIFT                14
11052 +#define MV_PORTVEC_MASK              0x03f0
11053 +#define MV_PORTVEC_SHIFT                  4
11054 +#define MV_ENTRYSTATE_MASK           0x000f
11055 +#define MV_ENTRYSTATE_SHIFT               0
11056 +
11057 +/* PHY Address for the switch itself */
11058 +#define MV_SWITCH_GLOBAL_ADDR 0x1f
11059 +
11060 +BOOL    mv_phySetup(int ethUnit, UINT32 phyBase);
11061 +void    mv_phyCheckStatusChange(int ethUnit);
11062 +BOOL    mv_phyIsSpeed100(int ethUnit);
11063 +int     mv_phyIsFullDuplex(int ethUnit);
11064 +
11065 +#endif /* MVPHY_H */
11066 diff -urN linux-mips-orig/drivers/net/ath/rtPhy.c linux-mips-new/drivers/net/ath/rtPhy.c
11067 --- linux-mips-orig/drivers/net/ath/rtPhy.c     1970-01-01 01:00:00.000000000 +0100
11068 +++ linux-mips-new/drivers/net/ath/rtPhy.c      2005-12-31 12:33:57.727530616 +0000
11069 @@ -0,0 +1,272 @@
11070 +/*
11071 + * This file is subject to the terms and conditions of the GNU General Public
11072 + * License.  See the file "COPYING" in the main directory of this archive
11073 + * for more details.
11074 + *
11075 + * Copyright © 2003 Atheros Communications, Inc.,  All Rights Reserved.
11076 + */
11077 +
11078 +/*
11079 + * Manage the ethernet PHY.
11080 + * This code supports a simple 1-port ethernet phy, Realtek RTL8201BL,
11081 + * and compatible PHYs, such as the Kendin KS8721B.
11082 + * All definitions in this file are operating system independent!
11083 + */
11084 +
11085 +#if defined(linux)
11086 +#include <linux/config.h>
11087 +#include <linux/types.h>
11088 +#include <linux/netdevice.h>
11089 +#include <linux/etherdevice.h>
11090 +#include <linux/delay.h>
11091 +
11092 +#include "ar531xlnx.h"
11093 +#endif
11094 +
11095 +#if defined(__ECOS)
11096 +#include "ae531xecos.h"
11097 +#endif
11098 +
11099 +
11100 +#include "ae531xmac.h"
11101 +#include "ae531xreg.h"
11102 +#include "rtPhy.h"
11103 +
11104 +#if /* DEBUG */ 1
11105 +#define RT_DEBUG_ERROR     0x00000001
11106 +#define RT_DEBUG_PHYSETUP  0x00000002
11107 +#define RT_DEBUG_PHYCHANGE 0x00000004
11108 +
11109 +int rtPhyDebug = RT_DEBUG_ERROR;
11110 +
11111 +#define RT_PRINT(FLG, X)                            \
11112 +{                                                   \
11113 +    if (rtPhyDebug & (FLG)) {                       \
11114 +        DEBUG_PRINTF X;                             \
11115 +    }                                               \
11116 +}
11117 +#else
11118 +#define RT_PRINT(FLG, X)
11119 +#endif
11120 +
11121 +/*
11122 + * Track per-PHY port information.
11123 + */
11124 +typedef struct {
11125 +    BOOL   phyAlive;    /* last known state of link */
11126 +    UINT32 phyBase;
11127 +    UINT32 phyAddr;
11128 +} rtPhyInfo_t;
11129 +
11130 +#define ETH_PHY_ADDR           1
11131 +
11132 +/*
11133 + * This table defines the mapping from phy units to
11134 + * per-PHY information.
11135 + *
11136 + * This table is somewhat board-dependent.
11137 + */
11138 +rtPhyInfo_t rtPhyInfo[] = {
11139 +    {phyAlive: FALSE,  /* PHY 0 */
11140 +     phyBase: 0,       /* filled in by rt_phySetup */
11141 +     phyAddr: ETH_PHY_ADDR},                             
11142 +
11143 +    {phyAlive: FALSE,  /* PHY 1 */
11144 +     phyBase: 0,       /* filled in by rt_phySetup */
11145 +     phyAddr: ETH_PHY_ADDR}
11146 +};
11147 +
11148 +/* Convert from phy unit# to (phyBase, phyAddr) pair */
11149 +#define RT_PHYBASE(phyUnit) (rtPhyInfo[phyUnit].phyBase)
11150 +#define RT_PHYADDR(phyUnit) (rtPhyInfo[phyUnit].phyAddr)
11151 +
11152 +
11153 +/******************************************************************************
11154 +*
11155 +* rt_phySetup - reset and setup the PHY associated with
11156 +* the specified MAC unit number.
11157 +*
11158 +* Resets the associated PHY port.
11159 +*
11160 +* RETURNS:
11161 +*    TRUE  --> associated PHY is alive
11162 +*    FALSE --> no LINKs on this ethernet unit
11163 +*/
11164 +
11165 +BOOL
11166 +rt_phySetup(int ethUnit, UINT32 phyBase)
11167 +{
11168 +    BOOL    linkAlive = FALSE;
11169 +    UINT32  phyAddr;
11170 +
11171 +    RT_PHYBASE(ethUnit) = phyBase;
11172 +
11173 +    phyAddr = RT_PHYADDR(ethUnit);
11174 +
11175 +    /* Reset phy */
11176 +    phyRegWrite(phyBase, phyAddr, GEN_ctl, PHY_SW_RST | AUTONEGENA);
11177 +
11178 +    sysMsDelay(1500);
11179 +
11180 +    return linkAlive;
11181 +}
11182 +
11183 +/******************************************************************************
11184 +*
11185 +* rt_phyIsDuplexFull - Determines whether the phy ports associated with the
11186 +* specified device are FULL or HALF duplex.
11187 +*
11188 +* RETURNS:
11189 +*    1  --> FULL
11190 +*    0 --> HALF
11191 +*/
11192 +int
11193 +rt_phyIsFullDuplex(int ethUnit)
11194 +{
11195 +    UINT16  phyCtl;
11196 +    UINT32  phyBase;
11197 +    UINT32  phyAddr;
11198 +
11199 +    phyBase = RT_PHYBASE(ethUnit);
11200 +    phyAddr = RT_PHYADDR(ethUnit);
11201 +
11202 +    phyCtl = phyRegRead(phyBase, phyAddr, GEN_ctl);
11203 +
11204 +    if (phyCtl & DUPLEX) {
11205 +        return 1;
11206 +    } else {
11207 +        return 0;
11208 +    }
11209 +}
11210 +
11211 +/******************************************************************************
11212 +*
11213 +* rt_phyIsSpeed100 - Determines the speed of phy ports associated with the
11214 +* specified device.
11215 +*
11216 +* RETURNS:
11217 +*    TRUE --> 100Mbit
11218 +*    FALSE --> 10Mbit
11219 +*/
11220 +BOOL
11221 +rt_phyIsSpeed100(int phyUnit)
11222 +{
11223 +    UINT16  phyLpa;
11224 +    UINT32  phyBase;
11225 +    UINT32  phyAddr;
11226 +
11227 +    phyBase = RT_PHYBASE(phyUnit);
11228 +    phyAddr = RT_PHYADDR(phyUnit);
11229 +
11230 +    phyLpa = phyRegRead(phyBase, phyAddr, AN_lpa);
11231 +
11232 +    if (phyLpa & (LPA_TXFD | LPA_TX)) {
11233 +        return TRUE;
11234 +    } else {
11235 +        return FALSE;
11236 +    }
11237 +}
11238 +
11239 +/*****************************************************************************
11240 +*
11241 +* rt_phyCheckStatusChange -- checks for significant changes in PHY state.
11242 +*
11243 +* A "significant change" is:
11244 +*     dropped link (e.g. ethernet cable unplugged) OR
11245 +*     autonegotiation completed + link (e.g. ethernet cable plugged in)
11246 +*
11247 +* On AR5311, there is a 1-to-1 mapping of ethernet units to PHYs.
11248 +* When a PHY is plugged in, phyLinkGained is called.
11249 +* When a PHY is unplugged, phyLinkLost is called.
11250 +*/
11251 +void
11252 +rt_phyCheckStatusChange(int ethUnit)
11253 +{
11254 +    UINT16          phyHwStatus;
11255 +    rtPhyInfo_t     *lastStatus = &rtPhyInfo[ethUnit];
11256 +    UINT32          phyBase;
11257 +    UINT32          phyAddr;
11258 +
11259 +    phyBase = RT_PHYBASE(ethUnit);
11260 +    phyAddr = RT_PHYADDR(ethUnit);
11261 +
11262 +    phyHwStatus = phyRegRead(phyBase, phyAddr, GEN_sts);
11263 +
11264 +    if (lastStatus->phyAlive) { /* last known status was ALIVE */
11265 +        /* See if we've lost link */
11266 +        if (!(phyHwStatus & LINK)) {
11267 +            RT_PRINT(RT_DEBUG_PHYCHANGE,("\nethmac%d link down\n", ethUnit));
11268 +            lastStatus->phyAlive = FALSE;
11269 +            phyLinkLost(ethUnit);
11270 +        }
11271 +    } else { /* last known status was DEAD */
11272 +        /* Check for AN complete */
11273 +        if ((phyHwStatus & (AUTOCMPLT | LINK)) == (AUTOCMPLT | LINK)) {
11274 +            RT_PRINT(RT_DEBUG_PHYCHANGE,("\nethmac%d link up\n", ethUnit));
11275 +            lastStatus->phyAlive = TRUE;
11276 +            phyLinkGained(ethUnit);
11277 +        }
11278 +    }
11279 +}
11280 +
11281 +#if DEBUG
11282 +
11283 +/* Define the PHY registers of interest for a phyShow command */
11284 +struct rtRegisterTable_s {
11285 +    UINT32 regNum;
11286 +    char  *regIdString;
11287 +} rtRegisterTable[] =
11288 +{
11289 +    {GEN_ctl,    "Basic Mode Control (GEN_ctl)    "},
11290 +    {GEN_sts,    "Basic Mode Status (GEN_sts)     "},
11291 +    {GEN_id_hi,  "PHY Identifier 1 (GET_id_hi)    "},
11292 +    {GEN_id_lo,  "PHY Identifier 2 (GET_id_lo)    "},
11293 +    {AN_adv,     "Auto-Neg Advertisement (AN_adv) "},
11294 +    {AN_lpa,     "Auto-Neg Link Partner Ability   "},
11295 +    {AN_exp,     "Auto-Neg Expansion              "},
11296 +};
11297 +
11298 +int rtNumRegs = sizeof(rtRegisterTable) / sizeof(rtRegisterTable[0]);
11299 +
11300 +/*
11301 + * Dump the state of a PHY.
11302 + */
11303 +void
11304 +rt_phyShow(int phyUnit)
11305 +{
11306 +    int i;
11307 +    UINT16  value;
11308 +    UINT32  phyBase;
11309 +    UINT32  phyAddr;
11310 +
11311 +    phyBase = RT_PHYBASE(phyUnit);
11312 +    phyAddr = RT_PHYADDR(phyUnit);
11313 +
11314 +    printf("PHY state for ethphy%d\n", phyUnit);
11315 +
11316 +    for (i=0; i<rtNumRegs; i++) {
11317 +
11318 +        value = phyRegRead(phyBase, phyAddr, rtRegisterTable[i].regNum);
11319 +
11320 +        printf("Reg %02d (0x%02x) %s = 0x%08x\n",
11321 +            rtRegisterTable[i].regNum, rtRegisterTable[i].regNum,
11322 +            rtRegisterTable[i].regIdString, value);
11323 +    }
11324 +}
11325 +
11326 +/*
11327 + * Modify the value of a PHY register.
11328 + * This makes it a bit easier to modify PHY values during debug.
11329 + */
11330 +void
11331 +rt_phySet(int phyUnit, UINT32 regnum, UINT32 value)
11332 +{
11333 +    UINT32  phyBase;
11334 +    UINT32  phyAddr;
11335 +
11336 +    phyBase = RT_PHYBASE(phyUnit);
11337 +    phyAddr = RT_PHYADDR(phyUnit);
11338 +
11339 +    phyRegWrite(phyBase, phyAddr, regnum, value);
11340 +}
11341 +#endif
11342 diff -urN linux-mips-orig/drivers/net/ath/rtPhy.h linux-mips-new/drivers/net/ath/rtPhy.h
11343 --- linux-mips-orig/drivers/net/ath/rtPhy.h     1970-01-01 01:00:00.000000000 +0100
11344 +++ linux-mips-new/drivers/net/ath/rtPhy.h      2005-12-31 12:33:57.727530616 +0000
11345 @@ -0,0 +1,50 @@
11346 +/*
11347 + * This file is subject to the terms and conditions of the GNU General Public
11348 + * License.  See the file "COPYING" in the main directory of this archive
11349 + * for more details.
11350 + *
11351 + * Copyright © 2003 Atheros Communications, Inc.,  All Rights Reserved.
11352 + */
11353 +
11354 +/*
11355 + * rtPhy.h - definitions for the ethernet PHY.
11356 + * This code supports a simple 1-port ethernet phy, Realtek RTL8201BL,
11357 + * and compatible PHYs, such as the Kendin KS8721B.
11358 + * All definitions in this file are operating system independent!
11359 + */
11360 +
11361 +#ifndef RTPHY_H
11362 +#define RTPHY_H
11363 +
11364 +/* MII Registers */
11365 +
11366 +#define        GEN_ctl         00
11367 +#define        GEN_sts         01
11368 +#define        GEN_id_hi       02
11369 +#define        GEN_id_lo       03
11370 +#define        AN_adv          04
11371 +#define        AN_lpa          05
11372 +#define        AN_exp          06
11373 +
11374 +/* GEN_ctl */ 
11375 +#define        PHY_SW_RST      0x8000
11376 +#define        LOOPBACK        0x4000
11377 +#define        SPEED           0x2000  /* 100 Mbit/s */
11378 +#define        AUTONEGENA      0x1000
11379 +#define        DUPLEX          0x0100  /* Duplex mode */
11380 +
11381 +               
11382 +/* GEN_sts */
11383 +#define        AUTOCMPLT       0x0020  /* Autonegotiation completed */
11384 +#define        LINK            0x0004  /* Link status */
11385 +
11386 +/* GEN_ids */
11387 +#define RT_PHY_ID1_EXPECTATION  0x22
11388 +
11389 +/* AN_lpa */
11390 +#define        LPA_TXFD        0x0100  /* Link partner supports 100 TX Full Duplex */
11391 +#define        LPA_TX          0x0080  /* Link partner supports 100 TX Half Duplex */
11392 +#define        LPA_10FD        0x0040  /* Link partner supports 10 BT Full Duplex */
11393 +#define        LPA_10          0x0020  /* Link partner supports 10 BT Half Duplex */
11394 +
11395 +#endif /* RTPHY_H */
11396 diff -urN linux-mips/include/linux/raid/md_p.h mips-linux-2.4.25/include/linux/raid/md_p.h
11397 --- linux-mips/include/linux/raid/md_p.h        2005-12-24 15:12:07.189098448 +0000
11398 +++ mips-linux-2.4.25/include/linux/raid/md_p.h 2005-12-30 17:28:10.345721232 +0000
11399 @@ -151,10 +151,12 @@
11400          */
11401         mdp_disk_t disks[MD_SB_DISKS];
11402  
11403 +#if MD_SB_RESERVED_WORDS
11404         /*
11405          * Reserved
11406          */
11407         __u32 reserved[MD_SB_RESERVED_WORDS];
11408 +#endif
11409  
11410         /*
11411          * Active descriptor