LinuxPPC-Dev Archive on lore.kernel.org
 help / color / mirror / Atom feed
* Re: ftrace introduces instability into kernel 2.6.27(-rc2,-rc3)
From: Mathieu Desnoyers @ 2008-08-19 13:05 UTC (permalink / raw)
  To: Eran Liberty
  Cc: linuxppc-dev, Steven Rostedt, Paul E. McKenney, linux-kernel,
	Steven Rostedt
In-Reply-To: <48AAB7FF.4070502@extricom.com>

* Eran Liberty (liberty@extricom.com) wrote:
> Steven Rostedt wrote:
>> On Mon, 18 Aug 2008, Eran Liberty wrote:
>>
>>   
>>> Steven Rostedt wrote:
>>>     
>>>> Eran Liberty wrote:
>>>>       
>>>>> After compiling a kernel with ftrace I started to experience all sorts 
>>>>> of
>>>>> crashes.
>>>>>         
>>>> Just to make sure...
>>>>
>>>> ftrace enables markers too, and RCU has tracing with the markers. This 
>>>> may
>>>> not be the problem, but I just want to eliminate as many variables as
>>>> possible.
>>>> Could you disable ftrace, but keep the markers on too.  Also, could you
>>>> enable ftrace again and turn on the FTRACE_STARTUP_TEST.
>>>>       
>>> for the fun of it I took out all my propriety modules; so now its a non
>>> tainted kernel.
>>>
>>> Here is the matrix:
>>>
>>> !FTRACE x !MARKERS => stable
>>> !FTRACE x MARKERS => stable
>>> FTRACE x !MARKERS => n/a (FTRACE forces MARKERS)
>>> FTRACE x MARKERS => unstable
>>> FTRACE x FTRACE_STARTUP_TEST x MARKERS => unstable + tests passed
>>>     
>>
>> Thanks
>>
>>   
>>> Testing tracer sched_switch: PASSED
>>> Testing tracer ftrace: PASSED
>>> Testing dynamic ftrace: PASSED
>>>
>>> Oops: Exception in kernel mode, sig: 11 [#1]
>>> Exsw1600
>>> Modules linked in:
>>> NIP: c00bbb20 LR: c00bbb20 CTR: 00000000
>>>     
>>
>> Could you load this into gdb for me and show me the output of:
>>
>> gdb> li *0xc00bbb20
>>
>> (Assuming you compiled with debuginfo on)
>>
>> and...
>>
>> gdb> disass 0xc00bbb20
>>
>>   
>>> REGS: dd5b1c50 TRAP: 0700   Not tainted  (2.6.27-rc2)
>>> MSR: 00029000 <EE,ME>  CR: 24082282  XER: 20000000
>>> TASK = ddcce060[1707] 'find' THREAD: dd5b0000
>>> GPR00: 00000000 dd5b1d00 ddcce060 dd801180 dd5b1d68 dd5b1d58 dd80125b 
>>> 100234ec
>>> GPR08: c0800000 00019330 0000ffff dd5b1d20 24000288 100ad874 100936f8 
>>> 1008a1d0
>>> GPR16: 10083f80 dd5b1e2c dd5b1d68 fffffff4 c0380000 dd5b1d60 dd5b1d58 
>>> dd802084
>>> GPR24: dc3d7700 dd802018 dd5b1d68 c0380000 dd801180 dd5b1d68 00000000 
>>> dd5b1d00
>>> NIP [c00bbb20] d_lookup+0x40/0x90
>>> LR [c00bbb20] d_lookup+0x40/0x90
>>> Call Trace:
>>> [dd5b1d00] [dd5b1d58] 0xdd5b1d58 (unreliable)
>>> [dd5b1d20] [c00aebc4] do_lookup+0xe8/0x220
>>> [dd5b1d50] [c00b0a80] __link_path_walk+0x5a4/0xd54
>>> [dd5b1dc0] [c00b1288] path_walk+0x58/0xe0
>>> [dd5b1df0] [c00b13f8] do_path_lookup+0x78/0x13c
>>> [dd5b1e20] [c00b20f4] user_path_at+0x64/0xac
>>> [dd5b1e90] [c00a9028] vfs_lstat_fd+0x34/0x74
>>> [dd5b1ec0] [c00a90fc] vfs_lstat+0x30/0x48
>>> [dd5b1ed0] [c00a9144] sys_lstat64+0x30/0x5c
>>> [dd5b1f40] [c0010554] ret_from_syscall+0x0/0x3c
>>> Instruction dump:
>>> 7c0802a6 bf61000c 3f60c038 7c3f0b78 90010024 7c7c1b78 7c9d2378 83db32a0
>>> 73c00001 7f83e378 7fa4eb78 4082002f <00000000> 2f830000 409e0030 801b32a0
>>>     
>>
>> Ouch! we have a 00000000 instruction. I'm almost done with the new mcount 
>> record for PPC (I have it done for ppc64, I'm just porting it to 32). I'm 
>> thinking this new code may solve your issues too. I hate the daemon.
>>
>> -- Steve
>>
>>
>>   
>
> I have attached ddd. Up on crashing it points on this line
>
> struct dentry * d_lookup(struct dentry * parent, struct qstr * name)
> {
>        struct dentry * dentry = NULL;
>        unsigned long seq;
>          do {
>                seq = read_seqbegin(&rename_lock);
>                dentry = __d_lookup(parent, name);     <==== ddd marker
>                if (dentry)
>                        break;
>        } while (read_seqretry(&rename_lock, seq));
>        return dentry;
> }
>
> (gdb) bt
> #0  d_lookup (parent=0xdd801180, name=0xd99b3d68) at fs/dcache.c:1361
> #1  0xc00ae7c8 in real_lookup (nd=<value optimized out>, name=<value 
> optimized out>, parent=0xdd801180) at fs/namei.c:507
> #2  do_lookup (nd=0xd99b3e28, name=0xd99b3d68, path=0xd99b3d58) at 
> fs/namei.c:825
> #3  0xc00b0684 in __link_path_walk (name=0xddc23009 "", nd=0xd99b3e28) at 
> fs/namei.c:982
> #4  0xc00b0e8c in link_path_walk (nd=<value optimized out>, name=<value 
> optimized out>) at fs/namei.c:570
> #5  path_walk (name=0xddc23000 "/proc/mtd", nd=0xd99b3e28) at 
> fs/namei.c:1041
> #6  0xc00b0ffc in do_path_lookup (dfd=<value optimized out>, 
> name=0xddc23000 "/proc/mtd", flags=<value optimized out>, nd=0xd99b3e28) at 
> fs/namei.c:1091
> #7  0xc00b1cf8 in user_path_at (dfd=-100, name=<value optimized out>, 
> flags=0, path=0xd99b3e98) at fs/namei.c:1334
> #8  0xc00a8c98 in vfs_lstat_fd (dfd=-578809472, name=0xd99b3d68 "", 
> stat=0xd99b3ed8) at fs/stat.c:83
> #9  0xc00a8d6c in vfs_lstat (name=0xd99b3d68 "", stat=0xd99b3d58) at 
> fs/stat.c:93
> #10 0xc00a8db4 in sys_lstat64 (filename=0xdd801180 "", statbuf=0xbfe285d8) 
> at fs/stat.c:381
> #11 0xc0010554 in syscall_dotrace_cont ()
>
> both cp & lr points to 0xC00BB724
> (gdb) info registers
> r0             0x0    0
> r1             0xd99b3d00    3650829568
> r2             0xddccf2e0    3721196256
> r3             0xdd801180    3716157824
> r4             0xd99b3d68    3650829672
> r5             0xd99b3d58    3650829656
> r6             0xdd822a5b    3716295259
> r7             0x100234ec    268580076
> r8             0xc0800000    3229614080
> r9             0x19330    103216
> r10            0xffff    65535
> r11            0xd99b3d20    3650829600
> r12            0x24000288    603980424
> r13            0x100ad874    269146228
> r14            0x100936f8    269039352
> r15            0x1008a1d0    269001168
> r16            0x10083f80    268976000
> r17            0xd99b3e2c    3650829868
> r18            0xd99b3d68    3650829672
> r19            0xfffffff4    4294967284
> r20            0xc0380000    3224895488
> r21            0xd99b3d60    3650829664
> r22            0xd99b3d58    3650829656
> r23            0xdd802084    3716161668
> r24            0xdc3fb280    3695161984
> r25            0xdd802018    3716161560
> r26            0xd99b3d68    3650829672
> r27            0xc0380000    3224895488
> r28            0xdd801180    3716157824
> r29            0xd99b3d68    3650829672
> r30            0x0    0
> r31            0xd99b3d00    3650829568
> pc             0xc00bb724    3221993252
> cr             0x24082282    604512898
> lr             0xc00bb724    3221993252
> ctr            0x0    0
> xer            0x20000000    536870912
>
> (gdb) li *0xC00BB724
> Line 1361 of "fs/dcache.c" starts at address 0xc00bb724 <d_lookup+64> and 
> ends at 0xc00bb728 <d_lookup+68>.
>
> (gdb) disassemble 0xC00BB724
> Dump of assembler code for function d_lookup:
> 0xc00bb6e4 <d_lookup+0>:    mflr    r0
> 0xc00bb6e8 <d_lookup+4>:    stw     r0,4(r1)
> 0xc00bb6ec <d_lookup+8>:    nop
> 0xc00bb6f0 <d_lookup+12>:    stwu    r1,-32(r1)
> 0xc00bb6f4 <d_lookup+16>:    mflr    r0
> 0xc00bb6f8 <d_lookup+20>:    stmw    r27,12(r1)
> 0xc00bb6fc <d_lookup+24>:    lis     r27,-16328
> 0xc00bb700 <d_lookup+28>:    mr      r31,r1
> 0xc00bb704 <d_lookup+32>:    stw     r0,36(r1)
> 0xc00bb708 <d_lookup+36>:    mr      r28,r3
> 0xc00bb70c <d_lookup+40>:    mr      r29,r4
> 0xc00bb710 <d_lookup+44>:    lwz     r30,12960(r27)
> 0xc00bb714 <d_lookup+48>:    andi.   r0,r30,1
> 0xc00bb718 <d_lookup+52>:    mr      r3,r28
> 0xc00bb71c <d_lookup+56>:    mr      r4,r29
> 0xc00bb720 <d_lookup+60>:    bnela-  0x2c
> 0xc00bb724 <d_lookup+64>:    .long 0x0
> 0xc00bb728 <d_lookup+68>:    cmpwi   cr7,r3,0
> 0xc00bb72c <d_lookup+72>:    bne-    cr7,0xc00bb75c <d_lookup+120>
> 0xc00bb730 <d_lookup+76>:    lwz     r0,12960(r27)
> 0xc00bb734 <d_lookup+80>:    cmpw    cr7,r0,r30
> 0xc00bb738 <d_lookup+84>:    beq-    cr7,0xc00bb75c <d_lookup+120>
> 0xc00bb73c <d_lookup+88>:    mr      r30,r0
> 0xc00bb740 <d_lookup+92>:    andi.   r0,r30,1
> 0xc00bb744 <d_lookup+96>:    mr      r3,r28
> 0xc00bb748 <d_lookup+100>:    mr      r4,r29
> 0xc00bb74c <d_lookup+104>:    beq+    0xc00bb724 <d_lookup+64>
> 0xc00bb750 <d_lookup+108>:    lwz     r0,12960(r27)
> 0xc00bb754 <d_lookup+112>:    mr      r30,r0
> 0xc00bb758 <d_lookup+116>:    b       0xc00bb740 <d_lookup+92>
> 0xc00bb75c <d_lookup+120>:    lwz     r11,0(r1)
> 0xc00bb760 <d_lookup+124>:    lwz     r0,4(r11)
> 0xc00bb764 <d_lookup+128>:    lmw     r27,-20(r11)
> 0xc00bb768 <d_lookup+132>:    mtlr    r0
> 0xc00bb76c <d_lookup+136>:    mr      r1,r11
> 0xc00bb770 <d_lookup+140>:    blr
> End of assembler dump.
> (gdb)
>
> Hope this is helpfull
>

Can you also give us

objdump -S --start-address=0xC00BB724 vmlinux | head 20

?

Then we could compare the result with the OOPS instruction dump :

7c0802a6 bf61000c 3f60c038 7c3f0b78 90010024 7c7c1b78 7c9d2378 83db32a0
73c00001 7f83e378 7fa4eb78 4082002f <00000000> 2f830000 409e0030 801b32a0

Mathieu


> Liberty
>
>
>

-- 
Mathieu Desnoyers
OpenPGP key fingerprint: 8CD5 52C3 8E3C 4140 715F  BA06 3F25 A8FE 3BAE 9A68

^ permalink raw reply

* Re: ftrace introduces instability into kernel 2.6.27(-rc2,-rc3)
From: Mathieu Desnoyers @ 2008-08-19 13:02 UTC (permalink / raw)
  To: Eran Liberty
  Cc: linux-kernel, rostedt, linuxppc-dev, Steven Rostedt,
	Paul E. McKenney
In-Reply-To: <48AA98E4.6060606@extricom.com>

* Eran Liberty (liberty@extricom.com) wrote:
> Mathieu Desnoyers wrote:
>> Can you check if, at some point during the system execution (starting
>> from boot), 0xdd5b1d58 is an address where a module is loaded ? (the
>> module can be later unloaded, what I wonder is if this address would
>> appear to have had a loaded+unloaded module).
>>
>> Actually, could you try to compile your kernel without "MODULE_UNLOAD" ?
>>
>> Mathieu
>>   
> No modules...
>
> ~ # uname -a
> Linux 2.6.27-rc2 #6 Tue Aug 19 12:33:34 IDT 2008 ppc unknown
> ~ # gunzip /proc/config.gz -c | grep UNLOAD
> # CONFIG_MODULE_UNLOAD is not set
> ~ # gunzip /proc/config.gz -c | grep FTRACE
> CONFIG_HAVE_FTRACE=y
> CONFIG_HAVE_DYNAMIC_FTRACE=y
> CONFIG_FTRACE=y
> CONFIG_DYNAMIC_FTRACE=y
> CONFIG_FTRACE_SELFTEST=y
> CONFIG_FTRACE_STARTUP_TEST=y
> ~ # gunzip /proc/config.gz -c | grep MARKERS
> CONFIG_MARKERS=y
> ~ # lsmod
> Module                  Size  Used by
> ~ # while [ 1 ] ; do find / > /dev/null ; echo .  ; done
> .
> Oops: Exception in kernel mode, sig: 11 [#1]
> Exsw1600
> Modules linked in:
> NIP: c00bb724 LR: c00bb724 CTR: 00000000
> REGS: d8b59c50 TRAP: 0700   Not tainted  (2.6.27-rc2)
> MSR: 00029000 <EE,ME>  CR: 24082282  XER: 20000000
> TASK = dbc68de0[1712] 'find' THREAD: d8b58000
> GPR00: 00000000 d8b59d00 dbc68de0 dd801180 d8b59d68 d8b59d58 dd8019db 
> 100234ec
> GPR08: c0800000 00019330 0000ffff d8b59d20 24000288 100ad874 100936f8 
> 1008a1d0
> GPR16: 10083f80 d8b59e2c d8b59d68 fffffff4 c0380000 d8b59d60 d8b59d58 
> dd802084

Register GPR30 is always zero... (also true for the other oops)

> GPR24: ddc69500 dd802018 d8b59d68 c0380000 dd801180 d8b59d68 00000000 
> d8b59d00
> NIP [c00bb724] d_lookup+0x40/0x90
> LR [c00bb724] d_lookup+0x40/0x90
> Call Trace:
> [d8b59d00] [d8b59d58] 0xd8b59d58 (unreliable)
> [d8b59d20] [c00ae7c8] do_lookup+0xe8/0x220
> [d8b59d50] [c00b0684] __link_path_walk+0x5a4/0xd54
> [d8b59dc0] [c00b0e8c] path_walk+0x58/0xe0
> [d8b59df0] [c00b0ffc] do_path_lookup+0x78/0x13c
> [d8b59e20] [c00b1cf8] user_path_at+0x64/0xac
> [d8b59e90] [c00a8c98] vfs_lstat_fd+0x34/0x74
> [d8b59ec0] [c00a8d6c] vfs_lstat+0x30/0x48
> [d8b59ed0] [c00a8db4] sys_lstat64+0x30/0x5c
> [d8b59f40] [c0010554] ret_from_syscall+0x0/0x3c
> Instruction dump:
> 7c0802a6 bf61000c 3f60c038 7c3f0b78 90010024 7c7c1b78 7c9d2378 83db32a0

Just like this instruction... maybe related ?

Mathieu

> 73c00001 7f83e378 7fa4eb78 4082002f <00000000> 2f830000 409e0030 801b32a0
> ---[ end trace 7766edd310cd3442 ]---
>

-- 
Mathieu Desnoyers
OpenPGP key fingerprint: 8CD5 52C3 8E3C 4140 715F  BA06 3F25 A8FE 3BAE 9A68

^ permalink raw reply

* Re: [PATCH] powerpc, scc: duplicate SCC_UHC_USBCEN
From: Kou Ishizaki @ 2008-08-19 13:02 UTC (permalink / raw)
  To: roel.kluin; +Cc: paulus, linux-kernel, linuxppc-dev
In-Reply-To: <48A9F256.2000901@gmail.com>



Roel,

> untested, is it correct?

Your patch is correct.

Thanks for your pointing it out and sending the patch. I tested your
patch and it works good.

Fortunately, this bug is not fatal because it seems that the SCC-UHC
sets SCC_UHC_USBEN and SCC_UHC_USBCEN at once.


Your patch does not contain 'Signed-off-by' line. Could you re-post it
with your sign?


> ---
> arch/powerpc/platforms/cell/celleb_scc.h:224:
> #define SCC_UHC_USBEN           0x00010000
> #define SCC_UHC_USBCEN          0x00020000
> 
> ---
> diff --git a/arch/powerpc/platforms/cell/celleb_scc_uhc.c b/arch/powerpc/platforms/cell/celleb_scc_uhc.c
> index d63b720..b086f33 100644
> --- a/arch/powerpc/platforms/cell/celleb_scc_uhc.c
> +++ b/arch/powerpc/platforms/cell/celleb_scc_uhc.c
> @@ -31,7 +31,7 @@
>  
>  static inline int uhc_clkctrl_ready(u32 val)
>  {
> -	const u32 mask = SCC_UHC_USBCEN | SCC_UHC_USBCEN;
> +	const u32 mask = SCC_UHC_USBCEN | SCC_UHC_USBEN;
>  	return((val & mask) == mask);
>  }
>  
> _______________________________________________
> Linuxppc-dev mailing list
> Linuxppc-dev@ozlabs.org
> https://ozlabs.org/mailman/listinfo/linuxppc-dev

Best regards,
Kou Ishizaki

^ permalink raw reply

* cpm2: Fix race condition in CPM2 GPIO library.
From: Laurent Pinchart @ 2008-08-19 12:20 UTC (permalink / raw)
  To: linuxppc-dev

The CPM2 GPIO library code uses the non thread-safe clrbits32/setbits32
macros. This patch protects them with a spinlock.

Signed-off-by: Laurent Pinchart <laurentp@cse-semaphore.com>
---
 arch/powerpc/sysdev/cpm_common.c |   37 ++++++++++++++++++++++++++-----------
 1 files changed, 26 insertions(+), 11 deletions(-)

diff --git a/arch/powerpc/sysdev/cpm_common.c b/arch/powerpc/sysdev/cpm_common.c
index 53da8a0..00d3d17 100644
--- a/arch/powerpc/sysdev/cpm_common.c
+++ b/arch/powerpc/sysdev/cpm_common.c
@@ -254,15 +254,11 @@ static int cpm2_gpio32_get(struct gpio_chip *gc, unsigned int gpio)
 	return !!(in_be32(&iop->dat) & pin_mask);
 }
 
-static void cpm2_gpio32_set(struct gpio_chip *gc, unsigned int gpio, int value)
+static void __cpm2_gpio32_set(struct of_mm_gpio_chip *mm_gc, u32 pin_mask,
+	int value)
 {
-	struct of_mm_gpio_chip *mm_gc = to_of_mm_gpio_chip(gc);
 	struct cpm2_gpio32_chip *cpm2_gc = to_cpm2_gpio32_chip(mm_gc);
 	struct cpm2_ioports __iomem *iop = mm_gc->regs;
-	unsigned long flags;
-	u32 pin_mask = 1 << (31 - gpio);
-
-	spin_lock_irqsave(&cpm2_gc->lock, flags);
 
 	if (value)
 		cpm2_gc->cpdata |= pin_mask;
@@ -270,6 +266,18 @@ static void cpm2_gpio32_set(struct gpio_chip *gc, unsigned int gpio, int value)
 		cpm2_gc->cpdata &= ~pin_mask;
 
 	out_be32(&iop->dat, cpm2_gc->cpdata);
+}
+
+static void cpm2_gpio32_set(struct gpio_chip *gc, unsigned int gpio, int value)
+{
+	struct of_mm_gpio_chip *mm_gc = to_of_mm_gpio_chip(gc);
+	struct cpm2_gpio32_chip *cpm2_gc = to_cpm2_gpio32_chip(mm_gc);
+	unsigned long flags;
+	u32 pin_mask = 1 << (31 - gpio);
+
+	spin_lock_irqsave(&cpm2_gc->lock, flags);
+
+	__cpm2_gpio32_set(mm_gc, pin_mask, value);
 
 	spin_unlock_irqrestore(&cpm2_gc->lock, flags);
 }
@@ -277,14 +285,17 @@ static void cpm2_gpio32_set(struct gpio_chip *gc, unsigned int gpio, int value)
 static int cpm2_gpio32_dir_out(struct gpio_chip *gc, unsigned int gpio, int val)
 {
 	struct of_mm_gpio_chip *mm_gc = to_of_mm_gpio_chip(gc);
+	struct cpm2_gpio32_chip *cpm2_gc = to_cpm2_gpio32_chip(mm_gc);
 	struct cpm2_ioports __iomem *iop = mm_gc->regs;
-	u32 pin_mask;
+	unsigned long flags;
+	u32 pin_mask = 1 << (31 - gpio);
 
-	pin_mask = 1 << (31 - gpio);
+	spin_lock_irqsave(&cpm2_gc->lock, flags);
 
 	setbits32(&iop->dir, pin_mask);
+	__cpm2_gpio32_set(mm_gc, pin_mask, val);
 
-	cpm2_gpio32_set(gc, gpio, val);
+	spin_unlock_irqrestore(&cpm2_gc->lock, flags);
 
 	return 0;
 }
@@ -292,13 +303,17 @@ static int cpm2_gpio32_dir_out(struct gpio_chip *gc, unsigned int gpio, int val)
 static int cpm2_gpio32_dir_in(struct gpio_chip *gc, unsigned int gpio)
 {
 	struct of_mm_gpio_chip *mm_gc = to_of_mm_gpio_chip(gc);
+	struct cpm2_gpio32_chip *cpm2_gc = to_cpm2_gpio32_chip(mm_gc);
 	struct cpm2_ioports __iomem *iop = mm_gc->regs;
-	u32 pin_mask;
+	unsigned long flags;
+	u32 pin_mask = 1 << (31 - gpio);
 
-	pin_mask = 1 << (31 - gpio);
+	spin_lock_irqsave(&cpm2_gc->lock, flags);
 
 	clrbits32(&iop->dir, pin_mask);
 
+	spin_unlock_irqrestore(&cpm2_gc->lock, flags);
+
 	return 0;
 }
 
-- 
1.5.0


-- 
Laurent Pinchart
CSE Semaphore Belgium

Chaussee de Bruxelles, 732A
B-1410 Waterloo
Belgium

T +32 (2) 387 42 59
F +32 (2) 387 42 75

^ permalink raw reply related

* Re: Clock / Timebase / Bus Frequencies Help
From: Richard Whitlock @ 2008-08-19 12:23 UTC (permalink / raw)
  To: Scott Wood; +Cc: richw@netcomuk.co.uk, linuxppc-dev
In-Reply-To: <20080818155921.GA26475@loki.buserror.net>

Scott,
Thanks for that - you're right - redboot has the wrong crystal frequency 
in the cdl for our board.

Cheers,


Richard.

Scott Wood wrote:
> On Mon, Aug 18, 2008 at 07:52:12AM -0400, richw@netcomuk.co.uk wrote:
>   
>> We've got an 8347 based board very similar to the A&M asp8347. Core clock
>> is 400MHz. Bus clock is 266666666Hz.
>> According to the data sheet for the 8347, the decrementer clock runs at a
>> quarter of the rate of the bus clock. I have two questions:
>> In arch/powerpc/boot/redboot-83xx.c, the timebase clock is passed to
>> dt_fixup_cpu_clocks() as bi_busfreq / 16. If I leave it like this, my
>> system clock runs approximately 4 times too fast. 
>> Can anyone point me in the direction of an explanation for the div by 16
>> rather than 4?
>>     
>
> It's a bug, which I pointed out here:
> http://ozlabs.org/pipermail/linuxppc-dev/2008-June/058704.html
>
>   
>> If I change the call to dt_fixup_cpu_clocks so that bi_busfreq/4 is passed
>> in, then the clock runs more accurately. However, its still not correct.
>> This gives a decrementer frequency of 66666666Hz, but if I hard code the
>> value to 66000000Hz, the clock runs accurately.
>> Can anyone shed any light on why the value passed in by the boot loader
>> (redboot) seems to be inaccurate.
>>     
>
> Redboot probably has the wrong crystal frequency hardcoded.
>
> -Scott
> _______________________________________________
> Linuxppc-dev mailing list
> Linuxppc-dev@ozlabs.org
> https://ozlabs.org/mailman/listinfo/linuxppc-dev
>
>
>   

^ permalink raw reply

* Re: ftrace introduces instability into kernel 2.6.27(-rc2,-rc3)
From: Eran Liberty @ 2008-08-19 12:09 UTC (permalink / raw)
  To: Steven Rostedt
  Cc: linuxppc-dev, Steven Rostedt, Paul E. McKenney, Mathieu Desnoyers,
	linux-kernel
In-Reply-To: <alpine.DEB.1.10.0808181439480.796@gandalf.stny.rr.com>

Steven Rostedt wrote:
> On Mon, 18 Aug 2008, Eran Liberty wrote:
>
>   
>> Steven Rostedt wrote:
>>     
>>> Eran Liberty wrote:
>>>       
>>>> After compiling a kernel with ftrace I started to experience all sorts of
>>>> crashes.
>>>>         
>>> Just to make sure...
>>>
>>> ftrace enables markers too, and RCU has tracing with the markers. This may
>>> not be the problem, but I just want to eliminate as many variables as
>>> possible.
>>> Could you disable ftrace, but keep the markers on too.  Also, could you
>>> enable ftrace again and turn on the FTRACE_STARTUP_TEST.
>>>       
>> for the fun of it I took out all my propriety modules; so now its a non
>> tainted kernel.
>>
>> Here is the matrix:
>>
>> !FTRACE x !MARKERS => stable
>> !FTRACE x MARKERS => stable
>> FTRACE x !MARKERS => n/a (FTRACE forces MARKERS)
>> FTRACE x MARKERS => unstable
>> FTRACE x FTRACE_STARTUP_TEST x MARKERS => unstable + tests passed
>>     
>
> Thanks
>
>   
>> Testing tracer sched_switch: PASSED
>> Testing tracer ftrace: PASSED
>> Testing dynamic ftrace: PASSED
>>
>> Oops: Exception in kernel mode, sig: 11 [#1]
>> Exsw1600
>> Modules linked in:
>> NIP: c00bbb20 LR: c00bbb20 CTR: 00000000
>>     
>
> Could you load this into gdb for me and show me the output of:
>
> gdb> li *0xc00bbb20
>
> (Assuming you compiled with debuginfo on)
>
> and...
>
> gdb> disass 0xc00bbb20
>
>   
>> REGS: dd5b1c50 TRAP: 0700   Not tainted  (2.6.27-rc2)
>> MSR: 00029000 <EE,ME>  CR: 24082282  XER: 20000000
>> TASK = ddcce060[1707] 'find' THREAD: dd5b0000
>> GPR00: 00000000 dd5b1d00 ddcce060 dd801180 dd5b1d68 dd5b1d58 dd80125b 100234ec
>> GPR08: c0800000 00019330 0000ffff dd5b1d20 24000288 100ad874 100936f8 1008a1d0
>> GPR16: 10083f80 dd5b1e2c dd5b1d68 fffffff4 c0380000 dd5b1d60 dd5b1d58 dd802084
>> GPR24: dc3d7700 dd802018 dd5b1d68 c0380000 dd801180 dd5b1d68 00000000 dd5b1d00
>> NIP [c00bbb20] d_lookup+0x40/0x90
>> LR [c00bbb20] d_lookup+0x40/0x90
>> Call Trace:
>> [dd5b1d00] [dd5b1d58] 0xdd5b1d58 (unreliable)
>> [dd5b1d20] [c00aebc4] do_lookup+0xe8/0x220
>> [dd5b1d50] [c00b0a80] __link_path_walk+0x5a4/0xd54
>> [dd5b1dc0] [c00b1288] path_walk+0x58/0xe0
>> [dd5b1df0] [c00b13f8] do_path_lookup+0x78/0x13c
>> [dd5b1e20] [c00b20f4] user_path_at+0x64/0xac
>> [dd5b1e90] [c00a9028] vfs_lstat_fd+0x34/0x74
>> [dd5b1ec0] [c00a90fc] vfs_lstat+0x30/0x48
>> [dd5b1ed0] [c00a9144] sys_lstat64+0x30/0x5c
>> [dd5b1f40] [c0010554] ret_from_syscall+0x0/0x3c
>> Instruction dump:
>> 7c0802a6 bf61000c 3f60c038 7c3f0b78 90010024 7c7c1b78 7c9d2378 83db32a0
>> 73c00001 7f83e378 7fa4eb78 4082002f <00000000> 2f830000 409e0030 801b32a0
>>     
>
> Ouch! we have a 00000000 instruction. I'm almost done with the new mcount 
> record for PPC (I have it done for ppc64, I'm just porting it to 32). I'm 
> thinking this new code may solve your issues too. I hate the daemon.
>
> -- Steve
>
>
>   

I have attached ddd. Up on crashing it points on this line

struct dentry * d_lookup(struct dentry * parent, struct qstr * name)
{
        struct dentry * dentry = NULL;
        unsigned long seq;
   
        do {
                seq = read_seqbegin(&rename_lock);
                dentry = __d_lookup(parent, name);     <==== ddd marker
                if (dentry)
                        break;
        } while (read_seqretry(&rename_lock, seq));
        return dentry;
}

(gdb) bt
#0  d_lookup (parent=0xdd801180, name=0xd99b3d68) at fs/dcache.c:1361
#1  0xc00ae7c8 in real_lookup (nd=<value optimized out>, name=<value 
optimized out>, parent=0xdd801180) at fs/namei.c:507
#2  do_lookup (nd=0xd99b3e28, name=0xd99b3d68, path=0xd99b3d58) at 
fs/namei.c:825
#3  0xc00b0684 in __link_path_walk (name=0xddc23009 "", nd=0xd99b3e28) 
at fs/namei.c:982
#4  0xc00b0e8c in link_path_walk (nd=<value optimized out>, name=<value 
optimized out>) at fs/namei.c:570
#5  path_walk (name=0xddc23000 "/proc/mtd", nd=0xd99b3e28) at 
fs/namei.c:1041
#6  0xc00b0ffc in do_path_lookup (dfd=<value optimized out>, 
name=0xddc23000 "/proc/mtd", flags=<value optimized out>, nd=0xd99b3e28) 
at fs/namei.c:1091
#7  0xc00b1cf8 in user_path_at (dfd=-100, name=<value optimized out>, 
flags=0, path=0xd99b3e98) at fs/namei.c:1334
#8  0xc00a8c98 in vfs_lstat_fd (dfd=-578809472, name=0xd99b3d68 "", 
stat=0xd99b3ed8) at fs/stat.c:83
#9  0xc00a8d6c in vfs_lstat (name=0xd99b3d68 "", stat=0xd99b3d58) at 
fs/stat.c:93
#10 0xc00a8db4 in sys_lstat64 (filename=0xdd801180 "", 
statbuf=0xbfe285d8) at fs/stat.c:381
#11 0xc0010554 in syscall_dotrace_cont ()

both cp & lr points to 0xC00BB724
(gdb) info registers
r0             0x0    0
r1             0xd99b3d00    3650829568
r2             0xddccf2e0    3721196256
r3             0xdd801180    3716157824
r4             0xd99b3d68    3650829672
r5             0xd99b3d58    3650829656
r6             0xdd822a5b    3716295259
r7             0x100234ec    268580076
r8             0xc0800000    3229614080
r9             0x19330    103216
r10            0xffff    65535
r11            0xd99b3d20    3650829600
r12            0x24000288    603980424
r13            0x100ad874    269146228
r14            0x100936f8    269039352
r15            0x1008a1d0    269001168
r16            0x10083f80    268976000
r17            0xd99b3e2c    3650829868
r18            0xd99b3d68    3650829672
r19            0xfffffff4    4294967284
r20            0xc0380000    3224895488
r21            0xd99b3d60    3650829664
r22            0xd99b3d58    3650829656
r23            0xdd802084    3716161668
r24            0xdc3fb280    3695161984
r25            0xdd802018    3716161560
r26            0xd99b3d68    3650829672
r27            0xc0380000    3224895488
r28            0xdd801180    3716157824
r29            0xd99b3d68    3650829672
r30            0x0    0
r31            0xd99b3d00    3650829568
pc             0xc00bb724    3221993252
cr             0x24082282    604512898
lr             0xc00bb724    3221993252
ctr            0x0    0
xer            0x20000000    536870912

(gdb) li *0xC00BB724
Line 1361 of "fs/dcache.c" starts at address 0xc00bb724 <d_lookup+64> 
and ends at 0xc00bb728 <d_lookup+68>.

(gdb) disassemble 0xC00BB724
Dump of assembler code for function d_lookup:
0xc00bb6e4 <d_lookup+0>:    mflr    r0
0xc00bb6e8 <d_lookup+4>:    stw     r0,4(r1)
0xc00bb6ec <d_lookup+8>:    nop
0xc00bb6f0 <d_lookup+12>:    stwu    r1,-32(r1)
0xc00bb6f4 <d_lookup+16>:    mflr    r0
0xc00bb6f8 <d_lookup+20>:    stmw    r27,12(r1)
0xc00bb6fc <d_lookup+24>:    lis     r27,-16328
0xc00bb700 <d_lookup+28>:    mr      r31,r1
0xc00bb704 <d_lookup+32>:    stw     r0,36(r1)
0xc00bb708 <d_lookup+36>:    mr      r28,r3
0xc00bb70c <d_lookup+40>:    mr      r29,r4
0xc00bb710 <d_lookup+44>:    lwz     r30,12960(r27)
0xc00bb714 <d_lookup+48>:    andi.   r0,r30,1
0xc00bb718 <d_lookup+52>:    mr      r3,r28
0xc00bb71c <d_lookup+56>:    mr      r4,r29
0xc00bb720 <d_lookup+60>:    bnela-  0x2c
0xc00bb724 <d_lookup+64>:    .long 0x0
0xc00bb728 <d_lookup+68>:    cmpwi   cr7,r3,0
0xc00bb72c <d_lookup+72>:    bne-    cr7,0xc00bb75c <d_lookup+120>
0xc00bb730 <d_lookup+76>:    lwz     r0,12960(r27)
0xc00bb734 <d_lookup+80>:    cmpw    cr7,r0,r30
0xc00bb738 <d_lookup+84>:    beq-    cr7,0xc00bb75c <d_lookup+120>
0xc00bb73c <d_lookup+88>:    mr      r30,r0
0xc00bb740 <d_lookup+92>:    andi.   r0,r30,1
0xc00bb744 <d_lookup+96>:    mr      r3,r28
0xc00bb748 <d_lookup+100>:    mr      r4,r29
0xc00bb74c <d_lookup+104>:    beq+    0xc00bb724 <d_lookup+64>
0xc00bb750 <d_lookup+108>:    lwz     r0,12960(r27)
0xc00bb754 <d_lookup+112>:    mr      r30,r0
0xc00bb758 <d_lookup+116>:    b       0xc00bb740 <d_lookup+92>
0xc00bb75c <d_lookup+120>:    lwz     r11,0(r1)
0xc00bb760 <d_lookup+124>:    lwz     r0,4(r11)
0xc00bb764 <d_lookup+128>:    lmw     r27,-20(r11)
0xc00bb768 <d_lookup+132>:    mtlr    r0
0xc00bb76c <d_lookup+136>:    mr      r1,r11
0xc00bb770 <d_lookup+140>:    blr
End of assembler dump.
(gdb)

Hope this is helpfull

Liberty

^ permalink raw reply

* Re: [PATCH 1/4] kvmppc: read device tree hypervisor node infrastructure
From: Josh Boyer @ 2008-08-19 11:56 UTC (permalink / raw)
  To: ehrhardt; +Cc: linuxppc-dev, hollisb, kvm-ppc
In-Reply-To: <1219146725.26429.3.camel@jdub.homelinux.org>

On Tue, 2008-08-19 at 07:52 -0400, Josh Boyer wrote:
> On Tue, 2008-08-19 at 12:36 +0200, ehrhardt@linux.vnet.ibm.com wrote:
> > diff --git a/arch/powerpc/kernel/kvm.c b/arch/powerpc/kernel/kvm.c
> > new file mode 100644
> > --- /dev/null
> > +++ b/arch/powerpc/kernel/kvm.c
> > @@ -0,0 +1,30 @@
> 
> > +#include <linux/percpu.h>
> > +#include <linux/mm.h>
> > +#include <linux/kvm_para.h>
> > +
> > +void __init kvm_guest_init(void)
> > +{
> > +	if (!kvm_para_available())
> > +		return;
> > +}
> 
> This looks really odd.  You have a void function that checks the return
> value of another function and returns if not true or.. returns if true.
> Why bother with the if at all?

Nevermind.  I see you add more code below this in patch 3.  Still looks
odd by itself, but makes more sense when the whole series is applied.

josh

^ permalink raw reply

* Re: powerpc/cell/oprofile: avoid double free of profile buffer
From: Robert Richter @ 2008-08-19 11:53 UTC (permalink / raw)
  To: Arnd Bergmann
  Cc: linux-kernel, linuxppc-dev, Paul Mackerras, oprofile-list, cel,
	cbe-oss-dev
In-Reply-To: <200808110925.44243.arnd@arndb.de>

On 11.08.08 09:25:43, Arnd Bergmann wrote:
> From: Carl Love <cel@us.ibm.com>
> 
> If an error occurs on opcontrol start, the event and per cpu buffers
> are released.  If later opcontrol shutdown is called then the free
> function will be called again to free buffers that no longer
> exist.  This results in a kernel oops.  The following changes
> prevent the call to delete buffers that don't exist.
> 
> Signed-off-by: Carl Love <carll@us.ibm.com>
> Signed-off-by: Arnd Bergmann <arnd@arndb.de>

Acked-by: Robert Richter <robert.richter@amd.com>

-Robert

-- 
Advanced Micro Devices, Inc.
Operating System Research Center
email: robert.richter@amd.com

^ permalink raw reply

* Re: [PATCH 1/4] kvmppc: read device tree hypervisor node infrastructure
From: Josh Boyer @ 2008-08-19 11:52 UTC (permalink / raw)
  To: ehrhardt; +Cc: linuxppc-dev, hollisb, kvm-ppc
In-Reply-To: <1219142204-12044-2-git-send-email-ehrhardt@linux.vnet.ibm.com>

On Tue, 2008-08-19 at 12:36 +0200, ehrhardt@linux.vnet.ibm.com wrote:
> diff --git a/arch/powerpc/kernel/kvm.c b/arch/powerpc/kernel/kvm.c
> new file mode 100644
> --- /dev/null
> +++ b/arch/powerpc/kernel/kvm.c
> @@ -0,0 +1,30 @@

> +#include <linux/percpu.h>
> +#include <linux/mm.h>
> +#include <linux/kvm_para.h>
> +
> +void __init kvm_guest_init(void)
> +{
> +	if (!kvm_para_available())
> +		return;
> +}

This looks really odd.  You have a void function that checks the return
value of another function and returns if not true or.. returns if true.
Why bother with the if at all?

One could ask the same about the entire function, but it does look
cleaner to call kvm_guest_init that kvm_para_available directly from
other code.

josh

^ permalink raw reply

* Re: [PATCH 4/4] kvmppc: convert wrteei to wrtee as kvm guest optimization
From: Arnd Bergmann @ 2008-08-19 11:42 UTC (permalink / raw)
  To: linuxppc-dev; +Cc: hollisb, kvm-ppc
In-Reply-To: <1219142204-12044-5-git-send-email-ehrhardt@linux.vnet.ibm.com>

On Tuesday 19 August 2008, ehrhardt@linux.vnet.ibm.com wrote:
> Dependent on the already existing CONFIG_KVM_GUEST config option this patch
> changes wrteei to wrtee allowing the hypervisor to rewrite those to nontrapping
> instructions. Maybe we should split the kvm guest otpimizations in two parts
> one for the overhead free optimizations and on for the rest that might add
> some complexity for non virtualized execution (like this one).
> 
> Signed-off-by: Christian Ehrhardt <ehrhardt@linux.vnet.ibm.com>

How significant is the performance impact of this change for non-virtualized
systems? If it's very low, maybe you should not bother with the #ifdef, and
if it's noticable, you might be better off using dynamic patching for this.

	Arnd <><

^ permalink raw reply

* Re: [PATCH 2/4] kvmppc: add hypercall infrastructure - guest part
From: Arnd Bergmann @ 2008-08-19 11:28 UTC (permalink / raw)
  To: linuxppc-dev; +Cc: hollisb, kvm-ppc
In-Reply-To: <1219142204-12044-3-git-send-email-ehrhardt@linux.vnet.ibm.com>

T24gVHVlc2RheSAxOSBBdWd1c3QgMjAwOCwgZWhyaGFyZHRAbGludXgudm5ldC5pYm0uY29tIHdy
b3RlOgo+ICtzdGF0aWMgaW5saW5lIGxvbmcga3ZtX2h5cGVyY2FsbDEodW5zaWduZWQgaW50IG5y
LCB1bnNpZ25lZCBsb25nIHAxKQo+ICt7Cj4gK6CgoKCgoKByZWdpc3RlciB1bnNpZ25lZCBsb25n
IGhjYWxsIGFzbSAoInIwIikgPSBucjsKPiAroKCgoKCgoHJlZ2lzdGVyIHVuc2lnbmVkIGxvbmcg
YXJnMSBhc20gKCJyMyIpID0gcDE7Cj4gK6CgoKCgoKByZWdpc3RlciBsb25nIHJldCBhc20gKCJy
MTEiKTsKPiArCj4gK6CgoKCgoKBhc20gdm9sYXRpbGUoIi5sb25nICUxIgo+ICugoKCgoKCgoKCg
oKCgoKCgoKCgoKCgoDogIj1yIihyZXQpCj4gK6CgoKCgoKCgoKCgoKCgoKCgoKCgoKCgOiAiaSIo
S1ZNX0hZUEVSQ0FMTF9CSU4pLCAiciIoaGNhbGwpLCAiciIoYXJnMSkKPiAroKCgoKCgoKCgoKCg
oKCgoKCgoKCgoKA6ICJyNCIsICJyNSIsICJyNiIsICJyNyIsICJyOCIsCj4gK6CgoKCgoKCgoKCg
oKCgoKCgoKCgoKCgIKAicjkiLCAicjEwIiwgInIxMiIsICJjYyIpOwo+ICugoKCgoKCgcmV0dXJu
IHJldDsKPiArfQoKV2hhdCBpcyB0aGUgcmVhc29uaW5nIGZvciBtYWtpbmcgdGhlIGNhbGxpbmcg
Y29udmVudGlvbiBkaWZmZXJlbnQgZnJvbQphbGwgdGhlIGV4aXN0aW5nIGhjYWxsIGludGVyZmFj
ZXMgaGVyZT8KCnBzZXJpZXMgdXNlcyByMyBmb3IgdGhlIGhjYWxsIG51bWJlciwgbHYxIGFuZCBi
ZWF0IHVzZSByMTEsIHNvIHVzaW5nCnIwIGp1c3QgZm9yIHRoZSBzYWtlIG9mIGJlaW5nIGRpZmZl
cmVudCBzZWVtcyBjb3VudGVyaW50dWl0aXZlLgoKCUFybmQgPD48Cg==

^ permalink raw reply

* Re: No output from SMC1 console with the 2.6.26 kernel (8xx based board)
From: Matvejchikov Ilya @ 2008-08-19 11:13 UTC (permalink / raw)
  To: Scott Wood; +Cc: Ben Gardiner, linuxppc-embedded
In-Reply-To: <20080730154545.GB25428@ld0162-tx32.am.freescale.net>

Hi all,

The problem was in incorrect (not full) brg-node definition. Instead of
brg@119f0 {
    compatible = "fsl,cpm-brg", "fsl,cpm2-brg";
    reg = <119f0 10 115f0 10>;
 };
there must be:
brg@119f0 {
    compatible = "fsl,cpm-brg", "fsl,cpm2-brg";
    reg = <119f0 10 115f0 10>;
    clock-frequency = <my_clock_frequency>;
 };

The PQ2 (and some others) DTS files needs to be updated.

Thanks.

^ permalink raw reply

* Re: [PATCH] ibmebus/of_platform: Move "name" sysfs attribute into generic OF devices
From: Joachim Fenkes @ 2008-08-19 10:52 UTC (permalink / raw)
  To: Paul Mackerras
  Cc: Stephen Rothwell, Olaf Hering, Paul Mackerras, LKML, LinuxPPC-Dev,
	Christoph Raisch, Hoang-Nam Nguyen, Alexander Schmidt1,
	Stefan Roscher, David S. Miller
In-Reply-To: <18602.18568.338552.482669@cargo.ozlabs.ibm.com>

Paul Mackerras <paulus@samba.org> wrote on 19.08.2008 06:14:00:
 
> > Recent of_platform changes made of_bus_type_init() overwrite the bus 
type's
> > .dev_attrs list, so move ibmebus' "name" attribute (which is needed by 
eHCA
> > userspace support) into generic OF device code. Tested on POWER.
> 
> Is this a bugfix that is needed for 2.6.27?

Yes, definitely. The eHCA userspace driver relies on the name attribute to 
check for valid adapters (it checks that the name is "lhca"), so with the 
name attribute gone, eHCA userspace will cease to work.

Regards,
  Joachim

^ permalink raw reply

* Re: Clock / Timebase / Bus Frequencies Help
From: Richard Whitlock @ 2008-08-19 10:45 UTC (permalink / raw)
  To: surendranath.moilla; +Cc: linuxppc-dev
In-Reply-To: <60403.136.182.158.145.1219088591.squirrel@webmail.cmcltd.com>

Hi,

Is it really hanging?
Or is it just sending console output somewhere else?
Try pinging the board after you think its hung. Can you ssh in and dmesg 
to find out what went wrong?
I've had two problems similar to this recently. The first was that the 
serial clock frequency was wrong in the dts file.
The second was schoolboy error when the console was handed over to ttyS1 
when I was plugged in to ttyS0.
If that all fails - put a scope on your serial port and see what its 
really doing.
Good luck,




Richard.

surendranath.moilla@cmcltd.com wrote:
> Hi,
>
>   I have a similar problem with custom MPC8360 board.
> I am able to boot Linux with the mpc836x_dts.dtb provided by freescale.
> but when use dtb customised for my  board i am unable to boot Linux.
> It is hanging after the console handover to real console from boot console.
>
> I am filling all the frequencies properly, can someone help me to fix this
> Where to set the baud rate in dts file.
>
> Here is the log:
>
>
> => tftp $loadaddr /nfk684/vpm_test/uImage
> Using FSL UEC0 device
> TFTP from server 192.168.0.2; our IP address is 192.168.0.100
> Filename '/nfk684/vpm_test/uImage'.
> Load address: 0x200000
> Loading: #################################################################
>          ##########
> done
> Bytes transferred = 1095689 (10b809 hex)
> => tftp $fdtaddr /nfk684/vpm_test/mpc8360_vpm.dtb
> Using FSL UEC0 device
> TFTP from server 192.168.0.2; our IP address is 192.168.0.100
> Filename '/nfk684/vpm_test/mpc8360_vpm.dtb'.
> Load address: 0x400000
> Loading: #
> done
> Bytes transferred = 12288 (3000 hex)
> => bootm $loadaddr - $fdtaddr
> ## Booting image at 00200000 ...
>    Image Name:   Linux-2.6.22
>    Image Type:   PowerPC Linux Kernel Image (gzip compressed)
>    Data Size:    1095625 Bytes =  1 MB
>    Load Address: 00000000
>    Entry Point:  00000000
>    Verifying Checksum ... OK
>    Uncompressing Kernel Image ... OK
>    Booting using the fdt at 0x400000
>  Probing machine type
> Using MPC8360 VPM machine description
> Linux version 2.6.22 (nfk684@ilec4411) (gcc version 4.0.0 (DENX ELDK 4.1
> 4.0.0))
>  #17 Fri Aug 15 16:13:41 CDT 2008
> setup_arch: bootmem
> mpc8360_vpm_setup_arch()
> Bad clock source for time stamp 1
> Bad clock source for time stamp 2
> arch: exit
> Zone PFN ranges:
>   DMA             0 ->    65536
>   Normal      65536 ->    65536
> early_node_map[1] active PFN ranges
>     0:        0 ->    65536
> Built 1 zonelists.  Total pages: 65024
> Kernel command line: root=/dev/ram rw console=ttyS1,115200
> IPIC (128 IRQ sources) at fdefc700
> QEIC (64 IRQ sources) at fdefb080
> PID hash table entries: 1024 (order: 10, 4096 bytes)
> Dentry cache hash table entries: 32768 (order: 5, 131072 bytes)
> Inode-cache hash table entries: 16384 (order: 4, 65536 bytes)
> Memory: 257280k/262144k available (2152k kernel code, 4624k reserved, 96k
> data,
> 80k bss, 128k init)
> Mount-cache hash table entries: 512
> NET: Registered protocol family 16
>
> Generic PHY: Registered new driver
> SCSI subsystem initialized
> NET: Registered protocol family 2
> IP route cache hash table entries: 2048 (order: 1, 8192 bytes)
> TCP established hash table entries: 8192 (order: 4, 65536 bytes)
> TCP bind hash table entries: 8192 (order: 3, 32768 bytes)
> TCP: Hash tables configured (established 8192 bind 8192)
> TCP reno registered
> JFFS2 version 2.2. (NAND) © 2001-2006 Red Hat, Inc.
> io scheduler noop registered
> io scheduler anticipatory registered (default)
> io scheduler deadline registered
> io scheduler cfq registered
> Generic RTC Driver v1.07
> Serial: 8250/16550 driver $Revision: 1.90 $ 4 ports, IRQ sharing disabled
> serial8250.0: ttyS0 at MMIO 0xe0004500 (irq = 16) is a 16550A
> serial8250.0: ttyS1 at MMIO 0xe0004600 (irq = 17) is a 16550A
> console handover: boot [udbg0] -> real [ttyS1]
>
> Regards
> Surendra
>
>
>   
>> On Mon, Aug 18, 2008 at 07:52:12AM -0400, richw@netcomuk.co.uk wrote:
>>     
>>> We've got an 8347 based board very similar to the A&M asp8347. Core
>>> clock
>>> is 400MHz. Bus clock is 266666666Hz.
>>> According to the data sheet for the 8347, the decrementer clock runs at
>>> a
>>> quarter of the rate of the bus clock. I have two questions:
>>> In arch/powerpc/boot/redboot-83xx.c, the timebase clock is passed to
>>> dt_fixup_cpu_clocks() as bi_busfreq / 16. If I leave it like this, my
>>> system clock runs approximately 4 times too fast.
>>> Can anyone point me in the direction of an explanation for the div by 16
>>> rather than 4?
>>>       
>> It's a bug, which I pointed out here:
>> http://ozlabs.org/pipermail/linuxppc-dev/2008-June/058704.html
>>
>>     
>>> If I change the call to dt_fixup_cpu_clocks so that bi_busfreq/4 is
>>> passed
>>> in, then the clock runs more accurately. However, its still not correct.
>>> This gives a decrementer frequency of 66666666Hz, but if I hard code the
>>> value to 66000000Hz, the clock runs accurately.
>>> Can anyone shed any light on why the value passed in by the boot loader
>>> (redboot) seems to be inaccurate.
>>>       
>> Redboot probably has the wrong crystal frequency hardcoded.
>>
>> -Scott
>> _______________________________________________
>> Linuxppc-dev mailing list
>> Linuxppc-dev@ozlabs.org
>> https://ozlabs.org/mailman/listinfo/linuxppc-dev
>>
>>     
>
>
> _______________________________________________
> Linuxppc-dev mailing list
> Linuxppc-dev@ozlabs.org
> https://ozlabs.org/mailman/listinfo/linuxppc-dev
>
>
>   

^ permalink raw reply

* [PATCH 4/4] kvmppc: convert wrteei to wrtee as kvm guest optimization
From: ehrhardt @ 2008-08-19 10:36 UTC (permalink / raw)
  To: linuxppc-dev, kvm-ppc; +Cc: hollisb
In-Reply-To: <1219142204-12044-1-git-send-email-ehrhardt@linux.vnet.ibm.com>

From: Christian Ehrhardt <ehrhardt@linux.vnet.ibm.com>

Dependent on the already existing CONFIG_KVM_GUEST config option this patch
changes wrteei to wrtee allowing the hypervisor to rewrite those to nontrapping
instructions. Maybe we should split the kvm guest otpimizations in two parts
one for the overhead free optimizations and on for the rest that might add
some complexity for non virtualized execution (like this one).

Signed-off-by: Christian Ehrhardt <ehrhardt@linux.vnet.ibm.com>
---

[diffstat]
 hw_irq.h |   12 ++++++++++++
 1 file changed, 12 insertions(+)

[diff]
diff --git a/include/asm-powerpc/hw_irq.h b/include/asm-powerpc/hw_irq.h
--- a/include/asm-powerpc/hw_irq.h
+++ b/include/asm-powerpc/hw_irq.h
@@ -72,7 +72,11 @@
 static inline void local_irq_disable(void)
 {
 #ifdef CONFIG_BOOKE
+#ifdef CONFIG_KVM_GUEST
+	__asm__ __volatile__("wrtee %0": : "r"(0) :"memory");
+#else
 	__asm__ __volatile__("wrteei 0": : :"memory");
+#endif
 #else
 	unsigned long msr;
 	__asm__ __volatile__("": : :"memory");
@@ -84,7 +88,11 @@
 static inline void local_irq_enable(void)
 {
 #ifdef CONFIG_BOOKE
+#ifdef CONFIG_KVM_GUEST
+	__asm__ __volatile__("wrtee %0": : "r"(MSR_EE) :"memory");
+#else
 	__asm__ __volatile__("wrteei 1": : :"memory");
+#endif
 #else
 	unsigned long msr;
 	__asm__ __volatile__("": : :"memory");
@@ -99,7 +107,11 @@
 	msr = mfmsr();
 	*flags = msr;
 #ifdef CONFIG_BOOKE
+#ifdef CONFIG_KVM_GUEST
+	__asm__ __volatile__("wrtee %0": : "r"(0) :"memory");
+#else
 	__asm__ __volatile__("wrteei 0": : :"memory");
+#endif
 #else
 	SET_MSR_EE(msr & ~MSR_EE);
 #endif

^ permalink raw reply

* [PATCH 0/4][RFC] kvmppc: paravirtualization interface - guest part v2
From: ehrhardt @ 2008-08-19 10:36 UTC (permalink / raw)
  To: linuxppc-dev, kvm-ppc; +Cc: hollisb

From: Christian Ehrhardt <ehrhardt@linux.vnet.ibm.com>

This patch series implements a paravirtualization interface using:
- the device tree mechanism to pass hypervisor informations to the guest
- hypercalls for guest->host calls
- an example exploiter of that interface (magic page)

Version 2 includes changes to the feedback of my last submission and is now
tested against the implemented and working host part. The host part discussion
can be found on kvm-ppc@vger.kernel.org.

The used hypercall ABI was already discussed on the embedded-hypervisor mailing
list and is available at http://kvm.qumranet.com/kvmwiki/PowerPC_Hypercall_ABI

The device tree format used here (=base for the discussions on
embedded-hypervisor) is the following.
- A node "hypervisor" to show the general availability of some hypervisor data
- flags for features like the example "feature,pv-magicpage"
  setting 1 = available, everything else = unavailable
- Some features might need to pass more data and can use an entry in the
  device tree like the example of "data,pv-magicpage-size"

I hope that eventually this guest patch series (that is modifying the boot
process and adding e.g. new ppc fixmaps could go upstream (when discussed
and agreed somewhen) via linuxppc-dev, while the kvm host part will go via
kvm (Avi Kivity).

[patches in series]
[PATCH 1/4] kvmppc: read device tree hypervisor node infrastructure
[PATCH 2/4] kvmppc: add hypercall infrastructure - guest part
[PATCH 3/4] kvmppc: magic page paravirtualization - guest part
[PATCH 4/4] kvmppc: convert wrteei to wrtee as kvm guest optimization

---
[diffstat]
 arch/powerpc/kernel/kvm.c            |   51 ++++++++++++++++++++++++++++++
 b/arch/powerpc/kernel/Makefile       |    2 +
 b/arch/powerpc/kernel/kvm.c          |   30 +++++++++++++++++
 b/arch/powerpc/kernel/setup_32.c     |    3 +
 b/arch/powerpc/platforms/44x/Kconfig |    7 ++++
 b/include/asm-powerpc/fixmap.h       |   10 +++++
 b/include/asm-powerpc/hw_irq.h       |   12 +++++++
 b/include/asm-powerpc/kvm_para.h     |   43 +++++++++++++++++++++++--
 b/mm/page_alloc.c                    |    1
 include/asm-powerpc/kvm_para.h       |   59 +++++++++++++++++++++++++++++++++++
 10 files changed, 214 insertions(+), 4 deletions(-)

^ permalink raw reply

* [PATCH 3/4] kvmppc: magic page paravirtualization - guest part
From: ehrhardt @ 2008-08-19 10:36 UTC (permalink / raw)
  To: linuxppc-dev, kvm-ppc; +Cc: hollisb
In-Reply-To: <1219142204-12044-1-git-send-email-ehrhardt@linux.vnet.ibm.com>

From: Christian Ehrhardt <ehrhardt@linux.vnet.ibm.com>

This patch adds the guest handling for the magic page mechanism. A Hypervisor
can modify the device tree passed to the guest. Using that already existing
interface a guest can simply detect available hypervisor features and agree
on the supported ones using hypercalls.
In this example it is checked for the feature switch "feature,pv-magicpage"
in the hypervisor node and additional data which represents the size the
hypervisor requests in "data,pv-magicpage-size".
When the guest reads that data and wants to support it the memory is allocated
and passed to the hypervisor using the KVM_HCALL_RESERVE_MAGICPAGE hypercall.

Signed-off-by: Christian Ehrhardt <ehrhardt@linux.vnet.ibm.com>
---

[diffstat]
 arch/powerpc/kernel/kvm.c      |   51 +++++++++++++++++++++++++++++++++++++++++
 include/asm-powerpc/fixmap.h   |   10 +++++++-
 include/asm-powerpc/kvm_para.h |   26 ++++++++++++++++++++
 mm/page_alloc.c                |    1
 4 files changed, 87 insertions(+), 1 deletion(-)

[diff]

diff --git a/arch/powerpc/kernel/kvm.c b/arch/powerpc/kernel/kvm.c
--- a/arch/powerpc/kernel/kvm.c
+++ b/arch/powerpc/kernel/kvm.c
@@ -22,9 +22,60 @@
 #include <linux/percpu.h>
 #include <linux/mm.h>
 #include <linux/kvm_para.h>
+#include <linux/bootmem.h>
+#include <asm/fixmap.h>
+
+/*
+ * this is guest memory granted to the hypervisor;
+ * the hypervisor can place data in this area and rewrite
+ * privileged instructions to read from this area without
+ * trapping.
+ * Only the Hypervisor needs to be aware of the structure layout
+ * which makes the guest more felxible - the guest only guarantees
+ * the size which is requested by the hypervisor and read from a
+ * device tree entry.
+ */
+static void *kvm_magicpage;
+
+static void __init kvmppc_register_magic_page(void)
+{
+	unsigned long gvaddr;
+	unsigned long gpaddr;
+	int size;
+	long err;
+
+	size = kvmppc_pv_read_data(KVM_PVDATA_MAGICPAGE_SIZE);
+	if (size < 0) {
+		printk(KERN_ERR "%s: couldn't read size for kvmppc style "
+			"paravirtualization support (got %d)\n",
+			__func__, size);
+		return;
+	}
+
+	/* FIXME Guest SMP needs that percpu which */
+	kvm_magicpage = alloc_bootmem(size);
+	if (!kvm_magicpage) {
+		printk(KERN_ERR "%s - failed to allocate %d bytes\n",
+			 __func__, size);
+		return;
+	}
+	gpaddr = (unsigned long)__pa(kvm_magicpage);
+	gvaddr = fix_to_virt(FIX_KVM_PV);
+
+	err = kvm_hypercall2(KVM_HCALL_RESERVE_MAGICPAGE, gvaddr, gpaddr);
+	if (err)
+		printk(KERN_ERR "%s: couldn't register pv mem\n", __func__);
+	else
+		printk(KERN_NOTICE "%s: registered %d bytes for pv mem support"
+			" (gvaddr 0x%08lx gpaddr 0x%08lx)\n",
+			 __func__, size, gvaddr, gpaddr);
+}
 
 void __init kvm_guest_init(void)
 {
 	if (!kvm_para_available())
 		return;
+
+	if (kvm_para_has_feature(KVM_FEATURE_PPCPV_MAGICPAGE))
+		kvmppc_register_magic_page();
 }
diff --git a/include/asm-powerpc/fixmap.h b/include/asm-powerpc/fixmap.h
--- a/include/asm-powerpc/fixmap.h
+++ b/include/asm-powerpc/fixmap.h
@@ -36,7 +36,7 @@
  *
  * these 'compile-time allocated' memory buffers are
  * fixed-size 4k pages. (or larger if used with an increment
- * highger than 1) use fixmap_set(idx,phys) to associate
+ * higher than 1) use fixmap_set(idx,phys) to associate
  * physical memory with fixmap indices.
  *
  * TLB entries of such buffers will not be flushed across
@@ -44,6 +44,14 @@
  */
 enum fixed_addresses {
 	FIX_HOLE,
+#ifdef CONFIG_KVM_GUEST
+	/*
+	 * reserved virtual address space for paravirtualization - needs to be
+	 *  <=32k away from base address 0 to be able to reach it with
+	 * immediate addressing using base 0 instead of needing a register.
+	 */
+	FIX_KVM_PV,
+#endif
 #ifdef CONFIG_HIGHMEM
 	FIX_KMAP_BEGIN,	/* reserved pte's for temporary kernel mappings */
 	FIX_KMAP_END = FIX_KMAP_BEGIN+(KM_TYPE_NR*NR_CPUS)-1,
diff --git a/include/asm-powerpc/kvm_para.h b/include/asm-powerpc/kvm_para.h
--- a/include/asm-powerpc/kvm_para.h
+++ b/include/asm-powerpc/kvm_para.h
@@ -28,10 +28,18 @@
 
 #define KVM_HYPERCALL_BIN 0x03ffffff
 
+#define KVM_HCALL_RESERVE_MAGICPAGE	0
+
+#define KVM_PVDATA_MAGICPAGE_SIZE	"data,pv-magicpage-size"
+
+/* List of PV features supported, returned as a bitfield */
+#define KVM_FEATURE_PPCPV_MAGICPAGE	0
+
 static struct kvmppc_para_features {
 	char *dtcell;
 	int feature;
 } para_features[] = {
+	{ "feature,pv-magicpage", KVM_FEATURE_PPCPV_MAGICPAGE }
 };
 
 static inline int kvm_para_available(void)
@@ -67,6 +75,24 @@
 	of_node_put(dn);
 
 	return features;
+}
+
+/* reads the specified data field out of the hypervisor node */
+static inline int kvmppc_pv_read_data(char *dtcell)
+{
+	struct device_node *dn;
+	const int *dtval;
+
+	dn = of_find_node_by_path("/hypervisor");
+	if (!dn)
+		return -EINVAL;
+
+	dtval = of_get_property(dn, dtcell, NULL);
+	of_node_put(dn);
+	if (dtval)
+		return *dtval;
+	else
+		return -EINVAL;
 }
 
 void kvm_guest_init(void);
diff --git a/mm/page_alloc.c b/mm/page_alloc.c
--- a/mm/page_alloc.c
+++ b/mm/page_alloc.c
@@ -550,6 +550,7 @@
 				prefetchw(p + 1);
 			__ClearPageReserved(p);
 			set_page_count(p, 0);
+
 		}
 
 		set_page_refcounted(page);

^ permalink raw reply

* [PATCH 1/4] kvmppc: read device tree hypervisor node infrastructure
From: ehrhardt @ 2008-08-19 10:36 UTC (permalink / raw)
  To: linuxppc-dev, kvm-ppc; +Cc: hollisb
In-Reply-To: <1219142204-12044-1-git-send-email-ehrhardt@linux.vnet.ibm.com>

From: Christian Ehrhardt <ehrhardt@linux.vnet.ibm.com>

This patch adds the guest portion of the device tree based host->guest
communication. Using the device tree infrastructure this patch implements
kvm_para_available and kvm_arch_para_features (in this patch just the
infrastructure, no specific feature registered).

Signed-off-by: Christian Ehrhardt <ehrhardt@linux.vnet.ibm.com>
---

[diffstat]
 arch/powerpc/kernel/Makefile       |    2 ++
 arch/powerpc/kernel/kvm.c          |   30 ++++++++++++++++++++++++++++++
 arch/powerpc/kernel/setup_32.c     |    3 +++
 arch/powerpc/platforms/44x/Kconfig |    7 +++++++
 include/asm-powerpc/kvm_para.h     |   37 ++++++++++++++++++++++++++++++++++---
 5 files changed, 76 insertions(+), 3 deletions(-)

[diff]

diff --git a/arch/powerpc/kernel/Makefile b/arch/powerpc/kernel/Makefile
--- a/arch/powerpc/kernel/Makefile
+++ b/arch/powerpc/kernel/Makefile
@@ -80,6 +80,8 @@
 
 obj-$(CONFIG_8XX_MINIMAL_FPEMU) += softemu8xx.o
 
+obj-$(CONFIG_KVM_GUEST)		+= kvm.o
+
 ifneq ($(CONFIG_PPC_INDIRECT_IO),y)
 obj-y				+= iomap.o
 endif
diff --git a/arch/powerpc/kernel/kvm.c b/arch/powerpc/kernel/kvm.c
new file mode 100644
--- /dev/null
+++ b/arch/powerpc/kernel/kvm.c
@@ -0,0 +1,30 @@
+/*
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License, version 2, as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ *
+ * Copyright IBM Corp. 2008
+ *
+ * Authors:
+ * 	Hollis Blanchard <hollisb@us.ibm.com>
+ * 	Christian Ehrhardt <ehrhardt@de.ibm.com>
+ */
+
+#include <linux/percpu.h>
+#include <linux/mm.h>
+#include <linux/kvm_para.h>
+
+void __init kvm_guest_init(void)
+{
+	if (!kvm_para_available())
+		return;
+}
diff --git a/arch/powerpc/kernel/setup_32.c b/arch/powerpc/kernel/setup_32.c
--- a/arch/powerpc/kernel/setup_32.c
+++ b/arch/powerpc/kernel/setup_32.c
@@ -17,6 +17,7 @@
 #include <linux/cpu.h>
 #include <linux/console.h>
 #include <linux/lmb.h>
+#include <linux/kvm_para.h>
 
 #include <asm/io.h>
 #include <asm/prom.h>
@@ -319,5 +320,7 @@
 		ppc_md.setup_arch();
 	if ( ppc_md.progress ) ppc_md.progress("arch: exit", 0x3eab);
 
+	kvm_guest_init();
+
 	paging_init();
 }
diff --git a/arch/powerpc/platforms/44x/Kconfig b/arch/powerpc/platforms/44x/Kconfig
--- a/arch/powerpc/platforms/44x/Kconfig
+++ b/arch/powerpc/platforms/44x/Kconfig
@@ -152,3 +152,10 @@
 # 44x errata/workaround config symbols, selected by the CPU models above
 config IBM440EP_ERR42
 	bool
+
+config KVM_GUEST
+	bool "KVM Guest support"
+	depends on EXPERIMENTAL
+	help
+	This option enables various optimizations for running under the KVM
+	hypervisor.
diff --git a/include/asm-powerpc/kvm_para.h b/include/asm-powerpc/kvm_para.h
--- a/include/asm-powerpc/kvm_para.h
+++ b/include/asm-powerpc/kvm_para.h
@@ -14,7 +14,9 @@
  *
  * Copyright IBM Corp. 2008
  *
- * Authors: Hollis Blanchard <hollisb@us.ibm.com>
+ * Authors:
+ * 	Hollis Blanchard <hollisb@us.ibm.com>
+ * 	Christian Ehrhardt <ehrhardt@de.ibm.com>
  */
 
 #ifndef __POWERPC_KVM_PARA_H__
@@ -22,15 +24,50 @@
 
 #ifdef __KERNEL__
 
+#include <linux/of.h>
+
+static struct kvmppc_para_features {
+	char *dtcell;
+	int feature;
+} para_features[] = {
+};
+
 static inline int kvm_para_available(void)
 {
-	return 0;
+	struct device_node *dn;
+	int ret;
+
+	dn = of_find_node_by_path("/hypervisor");
+	ret = !!dn;
+
+	of_node_put(dn);
+
+	return ret;
 }
 
 static inline unsigned int kvm_arch_para_features(void)
 {
-	return 0;
+	struct device_node *dn;
+	const int *dtval;
+	unsigned int features = 0;
+	int i;
+
+	dn = of_find_node_by_path("/hypervisor");
+	if (!dn)
+		return 0;
+
+	for (i = 0; i < ARRAY_SIZE(para_features); i++) {
+		dtval = of_get_property(dn, para_features[i].dtcell, NULL);
+		if (dtval && *dtval == 1)
+			features |= (1 << para_features[i].feature);
+	}
+
+	of_node_put(dn);
+
+	return features;
 }
+
+void kvm_guest_init(void);
 
 #endif /* __KERNEL__ */
 

^ permalink raw reply

* [PATCH 2/4] kvmppc: add hypercall infrastructure - guest part
From: ehrhardt @ 2008-08-19 10:36 UTC (permalink / raw)
  To: linuxppc-dev, kvm-ppc; +Cc: hollisb
In-Reply-To: <1219142204-12044-1-git-send-email-ehrhardt@linux.vnet.ibm.com>

From: Christian Ehrhardt <ehrhardt@linux.vnet.ibm.com>

This adds the guest portion of the hypercall infrastructure, basically an
illegal instruction with a defined layout.
See http://kvm.qumranet.com/kvmwiki/PowerPC_Hypercall_ABI for more detail
on the hypercall ABI for powerpc.

Signed-off-by: Christian Ehrhardt <ehrhardt@linux.vnet.ibm.com>
---

[diffstat]
 kvm_para.h |   33 +++++++++++++++++++++++++++++++++
 1 file changed, 33 insertions(+)

[diff]

diff --git a/include/asm-powerpc/kvm_para.h b/include/asm-powerpc/kvm_para.h
--- a/include/asm-powerpc/kvm_para.h
+++ b/include/asm-powerpc/kvm_para.h
@@ -25,6 +25,8 @@
 #ifdef __KERNEL__
 
 #include <linux/of.h>
+
+#define KVM_HYPERCALL_BIN 0x03ffffff
 
 static struct kvmppc_para_features {
 	char *dtcell;
@@ -69,6 +71,37 @@
 
 void kvm_guest_init(void);
 
+static inline long kvm_hypercall1(unsigned int nr, unsigned long p1)
+{
+	register unsigned long hcall asm ("r0") = nr;
+	register unsigned long arg1 asm ("r3") = p1;
+	register long ret asm ("r11");
+
+	asm volatile(".long %1"
+			: "=r"(ret)
+			: "i"(KVM_HYPERCALL_BIN), "r"(hcall), "r"(arg1)
+			: "r4", "r5", "r6", "r7", "r8",
+			  "r9", "r10", "r12", "cc");
+	return ret;
+}
+
+static inline long kvm_hypercall2(unsigned int nr,
+					unsigned long p1, unsigned long p2)
+{
+	register unsigned long hcall asm ("r0") = nr;
+	register unsigned long arg1 asm ("r3") = p1;
+	register unsigned long arg2 asm ("r4") = p2;
+	register long ret asm ("r11");
+
+	asm volatile(".long %1"
+			: "=r"(ret)
+			: "i"(KVM_HYPERCALL_BIN), "r"(hcall),
+				"r"(arg1), "r"(arg2)
+			: "r5", "r6", "r7", "r8",
+			  "r9", "r10", "r12", "cc");
+	return ret;
+}
+
 #endif /* __KERNEL__ */
 
 #endif /* __POWERPC_KVM_PARA_H__ */

^ permalink raw reply

* 8347 PCI IDE with Promise 20275 problems
From: Richard Whitlock @ 2008-08-19 10:34 UTC (permalink / raw)
  To: linuxppc-dev

Hi,

We have a board closely based on the A&M asp8347 with the addition of a 
promise technologies 20275 ATA controller.
Starting with the ASP dts file I have added the following:

  pci0: pci@ff008500 {
        cell-index = <1>;
        interrupt-map-mask = <0xf800 0x0 0x0 0x7>;
        interrupt-map = <

                /* IDSEL 0x11 */
                 0x8800 0x0 0x0 0x1 &ipic 19 0x8
                 0x8800 0x0 0x0 0x2 &ipic 19 0x8
                 0x8800 0x0 0x0 0x3 &ipic 19 0x8
                 0x8800 0x0 0x0 0x4 &ipic 19 0x8>;

        interrupt-parent = <&ipic>;
        interrupts = <0x42 0x8>;
        bus-range = <0 0>;
        ranges = <0x02000000 0x0 0xc0000000 0xc0000000 0x0 0x10000000
              0x42000000 0x0 0xb0000000 0xb0000000 0x0 0x00100000
              0x01000000 0x0 0x00000000 0xb8000000 0x0 0x00100000>;
        clock-frequency = <33333333>;
        #interrupt-cells = <1>;
        #size-cells = <2>;
        #address-cells = <3>;
        reg = <0xff008500 0x100>;
        compatible = "fsl,mpc8349-pci";
        device_type = "pci";
    };

I have based the numbers around what I found in our original 2.6.20 ppc 
port which works fine.
The following is from the ppc tree platform specific header for our board:

----------------------------------------------------------------------------------
#define _IRQ1 MPC83xx_IRQ_EXT3
#define _IRQ2 MPC83xx_IRQ_EXT4
#define PCI_IRQ_INFO()                                                  \
    static char pci_irq_table[][4] =                                \
        /*                                                          \
         *      PCI IDSEL/INTPIN->INTLINE                           \
         *       A      B      C      D                             \
         */                                                         \
    {                                                               \
            { _IRQ1, _IRQ1, _IRQ1, _IRQ1 }, /* IDSEL 11 = IDE disk       
*/ \
            {     0,     0,     0,     0 }, /* IDSEL 12                  
*/ \
            { _IRQ2, _IRQ2, _IRQ2, _IRQ2 }, /* IDSEL 13 = USB controller 
*/ \
    };                                                              \
                                                                        \
    const long min_idsel = 11, max_idsel = 13, irqs_per_slot = 4;

#define EXT_IRQ_SENSES()                                \
    u8 senses[8] = {                                    \
        0,            /* EXT 0 */             \
        0,            /* EXT 1 */             \
        0,            /* EXT 2 */             \
        IRQ_SENSE_LEVEL,    /* EXT 3 = PCI.11 */    \
        IRQ_SENSE_LEVEL,    /* EXT 4 = PCI.13 */    \
        IRQ_SENSE_LEVEL,    /* EXT 5 = JCB */       \
        0,            /* EXT 6 */             \
        0,            /* EXT 7 */             \
    };
#endif


// Note: these need to match how RedBoot has set up the hardware.
// In particular, the PCILAWRn/PCILBAWRn registers (PCI address window)

#define MPC83xx_PCI1_LOWER_IO    0x00000000
#define MPC83xx_PCI1_UPPER_IO    0x000FFFFF
#define MPC83xx_PCI1_IO_BASE    0xB8000000
#define MPC83xx_PCI1_IO_SIZE    0x00100000

#define MPC83xx_PCI1_LOWER_MEM    0xC0000000
#define MPC83xx_PCI1_UPPER_MEM    0xCFFFFFFF
#define MPC83xx_PCI1_MEM_OFFSET    0x00000000

----------------------------------------------------------------------------------

The driver we are using is pata_pdc2027x. Everything seems to work OK, 
except that every time we read from the hardware, we get all f's.
Specifically, pdc_detect_pll_input_clock() fails, since the clock 
frequency appears to be 0Hz.

On boot I get the following:

Found MPC83xx PCI host bridge at 0x00000000ff008500. Firmware bus 
number: 0->0
PCI host bridge /pci@ff008500 (primary) ranges:
 MEM 0x00000000c0000000..0x00000000cfffffff -> 0x00000000c0000000
 MEM 0x00000000b0000000..0x00000000b00fffff -> 0x00000000b0000000 Prefetch
  IO 0x00000000b8000000..0x00000000b80fffff -> 0x0000000000000000
Top of RAM: 0x8000000, Total RAM: 0x8000000
Memory hole size: 0MB
Zone PFN ranges:
  DMA      0x00000000 -> 0x00008000
  Normal   0x00008000 -> 0x00008000
Movable zone start PFN for each node
early_node_map[1] active PFN ranges
    0: 0x00000000 -> 0x00008000
On node 0 totalpages: 32768
free_area_init_node: node 0, pgdat c032f8cc, node_mem_map c040c000
  DMA zone: 32512 pages, LIFO batch:7
Built 1 zonelists in Zone order, mobility grouping on.  Total pages: 32512
Kernel command line: root=/dev/nfs 
nfsroot=192.168.111.41:/tftpboot/powerpc_q2_



and on trying to mount a CF card I get this:

Mapping pci region - start: c8100000, length: 16384
pata_pdc2027x 0000:00:0b.0: PLL input clock 0 kHz
pata_pdc2027x: Invalid PLL input clock 0kHz, give up!
scsi0 : pata_pdc2027x
scsi1 : pata_pdc2027x
ata1: PATA max UDMA/133 mmio m16384@0xc8100000 cmd 0xc81017c0 irq 16
ata2: PATA max UDMA/133 mmio m16384@0xc8100000 cmd 0xc81015c0 irq 16
pata_pdc2027x: 40-conductor cable detected on port 0
pata_pdc2027x: 40-conductor cable detected on port 1
Could not mount CF card - mountStatus = -1



Any ideas?


Thanks,





Richard.

^ permalink raw reply

* Re: ftrace introduces instability into kernel 2.6.27(-rc2,-rc3)
From: Eran Liberty @ 2008-08-19  9:56 UTC (permalink / raw)
  To: Mathieu Desnoyers
  Cc: linuxppc-dev, Steven Rostedt, Paul E. McKenney, linux-kernel,
	rostedt
In-Reply-To: <20080818184158.GA1798@Krystal>

Mathieu Desnoyers wrote:
> Can you check if, at some point during the system execution (starting
> from boot), 0xdd5b1d58 is an address where a module is loaded ? (the
> module can be later unloaded, what I wonder is if this address would
> appear to have had a loaded+unloaded module).
>
> Actually, could you try to compile your kernel without "MODULE_UNLOAD" ?
>
> Mathieu
>   
No modules...

~ # uname -a
Linux 2.6.27-rc2 #6 Tue Aug 19 12:33:34 IDT 2008 ppc unknown
~ # gunzip /proc/config.gz -c | grep UNLOAD
# CONFIG_MODULE_UNLOAD is not set
~ # gunzip /proc/config.gz -c | grep FTRACE
CONFIG_HAVE_FTRACE=y
CONFIG_HAVE_DYNAMIC_FTRACE=y
CONFIG_FTRACE=y
CONFIG_DYNAMIC_FTRACE=y
CONFIG_FTRACE_SELFTEST=y
CONFIG_FTRACE_STARTUP_TEST=y
~ # gunzip /proc/config.gz -c | grep MARKERS
CONFIG_MARKERS=y
~ # lsmod
Module                  Size  Used by
~ # while [ 1 ] ; do find / > /dev/null ; echo .  ; done
.
Oops: Exception in kernel mode, sig: 11 [#1]
Exsw1600
Modules linked in:
NIP: c00bb724 LR: c00bb724 CTR: 00000000
REGS: d8b59c50 TRAP: 0700   Not tainted  (2.6.27-rc2)
MSR: 00029000 <EE,ME>  CR: 24082282  XER: 20000000
TASK = dbc68de0[1712] 'find' THREAD: d8b58000
GPR00: 00000000 d8b59d00 dbc68de0 dd801180 d8b59d68 d8b59d58 dd8019db 
100234ec
GPR08: c0800000 00019330 0000ffff d8b59d20 24000288 100ad874 100936f8 
1008a1d0
GPR16: 10083f80 d8b59e2c d8b59d68 fffffff4 c0380000 d8b59d60 d8b59d58 
dd802084
GPR24: ddc69500 dd802018 d8b59d68 c0380000 dd801180 d8b59d68 00000000 
d8b59d00
NIP [c00bb724] d_lookup+0x40/0x90
LR [c00bb724] d_lookup+0x40/0x90
Call Trace:
[d8b59d00] [d8b59d58] 0xd8b59d58 (unreliable)
[d8b59d20] [c00ae7c8] do_lookup+0xe8/0x220
[d8b59d50] [c00b0684] __link_path_walk+0x5a4/0xd54
[d8b59dc0] [c00b0e8c] path_walk+0x58/0xe0
[d8b59df0] [c00b0ffc] do_path_lookup+0x78/0x13c
[d8b59e20] [c00b1cf8] user_path_at+0x64/0xac
[d8b59e90] [c00a8c98] vfs_lstat_fd+0x34/0x74
[d8b59ec0] [c00a8d6c] vfs_lstat+0x30/0x48
[d8b59ed0] [c00a8db4] sys_lstat64+0x30/0x5c
[d8b59f40] [c0010554] ret_from_syscall+0x0/0x3c
Instruction dump:
7c0802a6 bf61000c 3f60c038 7c3f0b78 90010024 7c7c1b78 7c9d2378 83db32a0
73c00001 7f83e378 7fa4eb78 4082002f <00000000> 2f830000 409e0030 801b32a0
---[ end trace 7766edd310cd3442 ]---

^ permalink raw reply

* Re: [alsa-devel] [PATCH] duplicate SNDRV_PCM_FMTBIT_S{16,24}_BE
From: Takashi Iwai @ 2008-08-19  9:52 UTC (permalink / raw)
  To: Johannes Berg; +Cc: linuxppc-dev, alsa-devel, roel kluin, linux-kernel
In-Reply-To: <3ef3fed769e5aa57681bacea1230e82b.squirrel@secure.sipsolutions.net>

At Tue, 19 Aug 2008 08:15:05 +0200 (CEST),
Johannes Berg wrote:
> 
> roel kluin wrote:
> > untested, is it correct?
> 
> not a clue, do you know how long ago that was? :)
> does the driver check endianness anywhere?

AFAIK snd-aoa supports only bit-endian formats (at least in
sound/aoa/soundbus/i2sbus-pcm.c), so this addition makes little
sense.

Better to drop the duplicated words there.


thanks,

Takashi

> > duplicate SNDRV_PCM_FMTBIT_S{16,24}_BE
> >
> > Signed-off-by: Roel Kluin <roel.kluin@gmail.com>
> > ---
> > diff --git a/sound/aoa/codecs/snd-aoa-codec-tas.c
> > b/sound/aoa/codecs/snd-aoa-codec-tas.c
> > index 7a16a33..c922505 100644
> > --- a/sound/aoa/codecs/snd-aoa-codec-tas.c
> > +++ b/sound/aoa/codecs/snd-aoa-codec-tas.c
> > @@ -654,15 +654,15 @@ static struct snd_kcontrol_new bass_control = {
> >  static struct transfer_info tas_transfers[] = {
> >  	{
> >  		/* input */
> > -		.formats = SNDRV_PCM_FMTBIT_S16_BE | SNDRV_PCM_FMTBIT_S16_BE |
> > -			   SNDRV_PCM_FMTBIT_S24_BE | SNDRV_PCM_FMTBIT_S24_BE,
> > +		.formats = SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S16_BE |
> > +			   SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S24_BE,
> >  		.rates = SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_44100 |
> > SNDRV_PCM_RATE_48000,
> >  		.transfer_in = 1,
> >  	},
> >  	{
> >  		/* output */
> > -		.formats = SNDRV_PCM_FMTBIT_S16_BE | SNDRV_PCM_FMTBIT_S16_BE |
> > -			   SNDRV_PCM_FMTBIT_S24_BE | SNDRV_PCM_FMTBIT_S24_BE,
> > +		.formats = SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S16_BE |
> > +			   SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S24_BE,
> >  		.rates = SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_44100 |
> > SNDRV_PCM_RATE_48000,
> >  		.transfer_in = 0,
> >  	},
> >
> >
> 
> _______________________________________________
> Alsa-devel mailing list
> Alsa-devel@alsa-project.org
> http://mailman.alsa-project.org/mailman/listinfo/alsa-devel
> 

^ permalink raw reply

* [PATCH] Linux Device Driver for Xilinx LL TEMAC 10/100/1000 Ethernet NIC
From: David H. Lynch Jr. @ 2008-08-19  9:34 UTC (permalink / raw)
  To: linuxppc-embedded, netdev

[-- Attachment #1: Type: text/plain, Size: 8 bytes --]

Pass II

[-- Attachment #2: lltemac --]
[-- Type: text/plain, Size: 45237 bytes --]

Linux Device Driver for Xilinx LL TEMAC 10/100/1000 Ethernet NIC

Original Author Yoshio Kashiwagi
Updated and Maintained by David Lynch

Signed-off-by: David H. Lynch Jr. <dhlii@dlasys.net>

---

 drivers/net/Kconfig            |    5 
 drivers/net/Makefile           |    1 
 drivers/net/xps_lltemac.c      | 1562 ++++++++++++++++++++++++++++++++++++++++
 include/linux/xilinx_devices.h |    2 
 4 files changed, 1569 insertions(+), 1 deletions(-)

diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig
index 033e13f..71b4c17 100644
--- a/drivers/net/Kconfig
+++ b/drivers/net/Kconfig
@@ -2332,6 +2332,11 @@ config MV643XX_ETH
 	  Some boards that use the Discovery chipset are the Momenco
 	  Ocelot C and Jaguar ATX and Pegasos II.
 
+config XPS_LLTEMAC
+	tristate "Xilinx LLTEMAC 10/100/1000 Ethernet MAC driver"
+	help
+	  This driver supports the Xilinx 10/100/1000 LLTEMAC found in Virtex 4 FPGAs
+
 config QLA3XXX
 	tristate "QLogic QLA3XXX Network Driver Support"
 	depends on PCI
diff --git a/drivers/net/Makefile b/drivers/net/Makefile
index 1f09934..9196bab 100644
--- a/drivers/net/Makefile
+++ b/drivers/net/Makefile
@@ -126,6 +126,7 @@ obj-$(CONFIG_AX88796) += ax88796.o
 obj-$(CONFIG_TSI108_ETH) += tsi108_eth.o
 obj-$(CONFIG_PICO_TEMAC) += pico_temac.o
 obj-$(CONFIG_MV643XX_ETH) += mv643xx_eth.o
+obj-$(CONFIG_XPS_LLTEMAC) += xps_lltemac.o
 obj-$(CONFIG_QLA3XXX) += qla3xxx.o
 
 obj-$(CONFIG_PPP) += ppp_generic.o
diff --git a/drivers/net/xps_lltemac.c b/drivers/net/xps_lltemac.c
new file mode 100644
index 0000000..8af4e7a
--- /dev/null
+++ b/drivers/net/xps_lltemac.c
@@ -0,0 +1,1562 @@
+/*======================================================================
+
+ Driver for Xilinx temac ethernet NIC's
+
+ Author: Yoshio Kashiwagi
+ Copyright (c) 2008 Nissin Systems Co.,Ltd.
+
+ Revisons: David H. Lynch Jr. <dhlii@dlasys.net>
+ Copyright (C) 2005-2008 DLA Systems
+
+======================================================================*/
+/* DRV_NAME is for compatibility with existing xilinx ll temac driver
+ * also with  of/dtc object names */
+#define DRV_NAME        "xilinx_lltemac"
+#define DRV_AUTHOR      "Yoshio Kashiwagi"
+#define DRV_EMAIL       ""
+
+#include <linux/module.h>
+#include <linux/netdevice.h>
+#include <linux/etherdevice.h>
+#include <linux/init.h>
+#include <linux/skbuff.h>
+#include <linux/platform_device.h>
+#include <linux/spinlock.h>
+
+#include <linux/mii.h>
+#include <linux/in.h>
+#include <linux/pci.h>
+
+#include <linux/ip.h>
+#include <linux/tcp.h>      /* just needed for sizeof(tcphdr) */
+#include <linux/udp.h>      /* needed for sizeof(udphdr) */
+#include <linux/delay.h>
+#include <linux/io.h>
+
+#define MII_ANI                     0x10
+#define PHY_NUM                     0
+#define PHY_TIMEOUT                 10000
+
+#define MII_SSR                     0x11
+#define MII_SSR_LINK                    (1 << 10)
+#define MII_SSR_SPDMASK                 0xC000
+#define MII_SSR_SPD1000                 (1 << 15)
+#define MII_SSR_SPD100                  (1 << 14)
+#define MII_SSR_SPD10                   0
+#define MII_SSR_FD                      (1 << 13)
+
+#define MII_ISR                     0x13
+#define MII_REG_MAX					0xff
+#define TEMAC_REG_MAX				0x3ff
+#define PHY_ADDR_INVALID			0xff
+
+/* packet size info */
+#define XTE_MTU                    1500    /* max MTU size of Ethernet frame */
+#define XTE_HDR_SIZE               14      /* size of Ethernet header */
+#define XTE_TRL_SIZE               4       /* size of Ethernet trailer (FCS) */
+#define XTE_MAX_FRAME_SIZE         (XTE_MTU + XTE_HDR_SIZE + XTE_TRL_SIZE)
+#define XTE_JUMBO_MTU              9000
+#define XTE_MAX_JUMBO_FRAME_SIZE   (XTE_JUMBO_MTU + XTE_HDR_SIZE + XTE_TRL_SIZE)
+
+/*  Configuration options */
+
+/*  Accept all incoming packets.
+ *  This option defaults to disabled (cleared) */
+#define XTE_OPTION_PROMISC                      (1 << 0)
+/*  Jumbo frame support for Tx & Rx.
+ *  This option defaults to disabled (cleared) */
+#define XTE_OPTION_JUMBO                        (1 << 1)
+/*  VLAN Rx & Tx frame support.
+ *  This option defaults to disabled (cleared) */
+#define XTE_OPTION_VLAN                         (1 << 2)
+/*  Enable recognition of flow control frames on Rx
+ *  This option defaults to enabled (set) */
+#define XTE_OPTION_FLOW_CONTROL                 (1 << 4)
+/*  Strip FCS and PAD from incoming frames.
+ *  Note: PAD from VLAN frames is not stripped.
+ *  This option defaults to disabled (set) */
+#define XTE_OPTION_FCS_STRIP                    (1 << 5)
+/*  Generate FCS field and add PAD automatically for outgoing frames.
+ *  This option defaults to enabled (set) */
+#define XTE_OPTION_FCS_INSERT                   (1 << 6)
+/*  Enable Length/Type error checking for incoming frames. When this option is
+set, the MAC will filter frames that have a mismatched type/length field
+and if XTE_OPTION_REPORT_RXERR is set, the user is notified when these
+types of frames are encountered. When this option is cleared, the MAC will
+allow these types of frames to be received.
+This option defaults to enabled (set) */
+#define XTE_OPTION_LENTYPE_ERR                  (1 << 7)
+/*  Enable the transmitter.
+ *  This option defaults to enabled (set) */
+#define XTE_OPTION_TXEN                         (1 << 11)
+/*  Enable the receiver
+*   This option defaults to enabled (set) */
+#define XTE_OPTION_RXEN                         (1 << 12)
+
+/*  Default options set when device is initialized or reset */
+#define XTE_OPTION_DEFAULTS                     \
+	(XTE_OPTION_TXEN |                          \
+	 XTE_OPTION_FLOW_CONTROL |                  \
+	 XTE_OPTION_RXEN)
+
+/* XPS_LL_TEMAC SDMA registers definition */
+
+#define TX_NXTDESC_PTR      0x00            /* r */
+#define TX_CURBUF_ADDR      0x04            /* r */
+#define TX_CURBUF_LENGTH    0x08            /* r */
+#define TX_CURDESC_PTR      0x0c            /* rw */
+#define TX_TAILDESC_PTR     0x10            /* rw */
+#define TX_CHNL_CTRL        0x14            /* rw */
+/*
+ 0:7      24:31       IRQTimeout
+ 8:15     16:23       IRQCount
+ 16:20    11:15       Reserved
+ 21       10          0
+ 22       9           UseIntOnEnd
+ 23       8           LdIRQCnt
+ 24       7           IRQEn
+ 25:28    3:6         Reserved
+ 29       2           IrqErrEn
+ 30       1           IrqDlyEn
+ 31       0           IrqCoalEn
+*/
+#define CHNL_CTRL_IRQ_IOE       (1 << 9)
+#define CHNL_CTRL_IRQ_EN        (1 << 7)
+#define CHNL_CTRL_IRQ_ERR_EN    (1 << 2)
+#define CHNL_CTRL_IRQ_DLY_EN    (1 << 1)
+#define CHNL_CTRL_IRQ_COAL_EN   (1 << 0)
+#define TX_IRQ_REG          0x18            /* rw */
+/*
+  0:7      24:31       DltTmrValue
+ 8:15     16:23       ClscCntrValue
+ 16:17    14:15       Reserved
+ 18:21    10:13       ClscCnt
+ 22:23    8:9         DlyCnt
+ 24:28    3::7        Reserved
+ 29       2           ErrIrq
+ 30       1           DlyIrq
+ 31       0           CoalIrq
+ */
+#define TX_CHNL_STS         0x1c            /* r */
+/*
+   0:9      22:31   Reserved
+ 10       21      TailPErr
+ 11       20      CmpErr
+ 12       19      AddrErr
+ 13       18      NxtPErr
+ 14       17      CurPErr
+ 15       16      BsyWr
+ 16:23    8:15    Reserved
+ 24       7       Error
+ 25       6       IOE
+ 26       5       SOE
+ 27       4       Cmplt
+ 28       3       SOP
+ 29       2       EOP
+ 30       1       EngBusy
+ 31       0       Reserved
+*/
+
+#define RX_NXTDESC_PTR      0x20            /* r */
+#define RX_CURBUF_ADDR      0x24            /* r */
+#define RX_CURBUF_LENGTH    0x28            /* r */
+#define RX_CURDESC_PTR      0x2c            /* rw */
+#define RX_TAILDESC_PTR     0x30            /* rw */
+#define RX_CHNL_CTRL        0x34            /* rw */
+/*
+ 0:7      24:31       IRQTimeout
+ 8:15     16:23       IRQCount
+ 16:20    11:15       Reserved
+ 21       10          0
+ 22       9           UseIntOnEnd
+ 23       8           LdIRQCnt
+ 24       7           IRQEn
+ 25:28    3:6         Reserved
+ 29       2           IrqErrEn
+ 30       1           IrqDlyEn
+ 31       0           IrqCoalEn
+ */
+#define RX_IRQ_REG          0x38            /* rw */
+#define IRQ_COAL        (1 << 0)
+#define IRQ_DLY         (1 << 1)
+#define IRQ_ERR         (1 << 2)
+#define IRQ_DMAERR      (1 << 7)            /* this is not documented ??? */
+/*
+ 0:7      24:31       DltTmrValue
+ 8:15     16:23       ClscCntrValue
+ 16:17    14:15       Reserved
+ 18:21    10:13       ClscCnt
+ 22:23    8:9         DlyCnt
+ 24:28    3::7        Reserved
+*/
+#define RX_CHNL_STS         0x3c        /* r */
+#define CHNL_STS_ENGBUSY    (1 << 1)
+#define CHNL_STS_EOP        (1 << 2)
+#define CHNL_STS_SOP        (1 << 3)
+#define CHNL_STS_CMPLT      (1 << 4)
+#define CHNL_STS_SOE        (1 << 5)
+#define CHNL_STS_IOE        (1 << 6)
+#define CHNL_STS_ERR        (1 << 7)
+
+#define CHNL_STS_BSYWR      (1 << 16)
+#define CHNL_STS_CURPERR    (1 << 17)
+#define CHNL_STS_NXTPERR    (1 << 18)
+#define CHNL_STS_ADDRERR    (1 << 19)
+#define CHNL_STS_CMPERR     (1 << 20)
+#define CHNL_STS_TAILERR    (1 << 21)
+/*
+ 0:9      22:31   Reserved
+ 10       21      TailPErr
+ 11       20      CmpErr
+ 12       19      AddrErr
+ 13       18      NxtPErr
+ 14       17      CurPErr
+ 15       16      BsyWr
+ 16:23    8:15    Reserved
+ 24       7       Error
+ 25       6       IOE
+ 26       5       SOE
+ 27       4       Cmplt
+ 28       3       SOP
+ 29       2       EOP
+ 30       1       EngBusy
+ 31       0       Reserved
+*/
+
+#define DMA_CONTROL_REG             0x40            /* rw */
+#define DMA_CONTROL_RST                 (1 << 0)
+
+/* XPS_LL_TEMAC direct registers definition */
+
+#define XTE_RAF0_OFFSET              0x00
+#define RAF0_RST                        (1 << 0)
+#define RAF0_MCSTREJ                    (1 << 1)
+#define RAF0_BCSTREJ                    (1 << 2)
+#define XTE_TPF0_OFFSET              0x04
+#define XTE_IFGP0_OFFSET             0x08
+#define XTE_ISR0_OFFSET              0x0c
+#define ISR0_HARDACSCMPLT               (1 << 0)
+#define ISR0_AUTONEG                    (1 << 1)
+#define ISR0_RXCMPLT                    (1 << 2)
+#define ISR0_RXREJ                      (1 << 3)
+#define ISR0_RXFIFOOVR                  (1 << 4)
+#define ISR0_TXCMPLT                    (1 << 5)
+#define ISR0_RXDCMLCK                   (1 << 6)
+
+#define XTE_IPR0_OFFSET              0x10
+#define XTE_IER0_OFFSET              0x14
+
+#define XTE_MSW0_OFFSET              0x20
+#define XTE_LSW0_OFFSET              0x24
+#define XTE_CTL0_OFFSET              0x28
+#define XTE_RDY0_OFFSET              0x2c
+
+#define XTE_RSE_MIIM_RR_MASK      0x0002
+#define XTE_RSE_MIIM_WR_MASK      0x0004
+#define XTE_RSE_CFG_RR_MASK       0x0020
+#define XTE_RSE_CFG_WR_MASK       0x0040
+
+/* XPS_LL_TEMAC indirect registers offset definition */
+
+/*  Rx configuration word 0 */
+#define XTE_RXC0_OFFSET                 0x00000200
+/*  Rx configuration word 1 */
+#define XTE_RXC1_OFFSET                 0x00000240
+/*  Receiver reset */
+#define XTE_RXC1_RXRST_MASK                 (1 << 31)
+/*  Jumbo frame enable */
+#define XTE_RXC1_RXJMBO_MASK                (1 << 30)
+/*  FCS not stripped */
+#define XTE_RXC1_RXFCS_MASK                 (1 << 29)
+/*  Receiver enable */
+#define XTE_RXC1_RXEN_MASK                  (1 << 28)
+/*  VLAN enable */
+#define XTE_RXC1_RXVLAN_MASK                (1 << 27)
+/*  Half duplex */
+#define XTE_RXC1_RXHD_MASK                  (1 << 26)
+/*  Length/type check disable */
+#define XTE_RXC1_RXLT_MASK                  (1 << 25)
+
+/*  Tx configuration */
+#define XTE_TXC_OFFSET                  0x00000280
+/*  Transmitter reset */
+#define XTE_TXC_TXRST_MASK                  (1 << 31)
+/*  Jumbo frame enable */
+#define XTE_TXC_TXJMBO_MASK                 (1 << 30)
+/*  Generate FCS */
+#define XTE_TXC_TXFCS_MASK                  (1 << 29)
+/*  Transmitter enable */
+#define XTE_TXC_TXEN_MASK                   (1 << 28)
+/*  VLAN enable */
+#define XTE_TXC_TXVLAN_MASK                 (1 << 27)
+/*  Half duplex */
+#define XTE_TXC_TXHD_MASK                   (1 << 26)
+/*  Flow control configuration */
+#define XTE_FCC_OFFSET                  0x000002C0
+/*  Rx flow control enable */
+#define XTE_FCC_RXFLO_MASK                  (1 << 29)
+/*  Tx flow control enable */
+#define XTE_FCC_TXFLO_MASK                  (1 << 30)
+
+/*  EMAC configuration */
+#define XTE_EMCFG_OFFSET                0x00000300
+/*  Link speed */
+#define XTE_EMCFG_LINKSPD_MASK          0xC0000000
+/*  Host interface enable */
+#define XTE_EMCFG_HOSTEN_MASK               (1 << 26)
+/*  XTE_EMCFG_LINKSPD_MASK for 10 Mbit */
+#define XTE_EMCFG_LINKSPD_10            0x00000000
+/*  XTE_EMCFG_LINKSPD_MASK for 100 Mbit */
+#define XTE_EMCFG_LINKSPD_100               (1 << 30)
+/*  XTE_EMCFG_LINKSPD_MASK for 1000 Mbit */
+#define XTE_EMCFG_LINKSPD_1000              (1 << 31)
+
+/*  RGMII/SGMII configuration */
+#define XTE_GMIC_OFFSET                 0x00000320
+/*  Management configuration */
+#define XTE_MC_OFFSET                   0x00000340
+/*  MII management enable */
+#define XTE_MC_MDIO_MASK                    (1 << 6)
+/* 100 MHz host clock */
+#define XTE_MDIO_CLOCK_DIV_100MHz       0x28
+/* Default MDIO clock divisor */
+#define XTE_MDIO_DIV_DFT                29
+/*  Unicast address word 0 */
+#define XTE_UAW0_OFFSET                 0x00000380
+/*  Unicast address word 1 */
+#define XTE_UAW1_OFFSET                 0x00000384
+
+/*  Multicast address word 0 */
+#define XTE_MAW0_OFFSET                 0x00000388
+/*  Multicast address word 1 */
+#define XTE_MAW1_OFFSET                 0x0000038C
+/*  Promisciuous mode */
+#define XTE_AFM_OFFSET                  0x00000390
+/*  Promiscuous mode enable */
+#define XTE_AFM_EPPRM_MASK                  (1 << 31)
+
+/* Interrupt Request status */
+#define XTE_TIS_OFFSET                  0x000003A0
+#define TIS_FRIS                            (1 << 0)
+#define TIS_MRIS                            (1 << 1)
+#define TIS_MWIS                            (1 << 2)
+#define TIS_ARIS                            (1 << 3)
+#define TIS_AWIS                            (1 << 4)
+#define TIS_CRIS                            (1 << 5)
+#define TIS_CWIS                            (1 << 6)
+/* Interrupt Request enable */
+#define XTE_TIE_OFFSET                  0x000003A4
+
+/**  MII Mamagement Control register (MGTCR) */
+
+/*  MII data */
+#define XTE_MGTDR_OFFSET                0x000003B0
+/*  MII control */
+#define XTE_MIIMAI_OFFSET               0x000003B4
+
+#define CNTLREG_WRITE_ENABLE_MASK   0x8000
+#define CNTLREG_EMAC1SEL_MASK       0x0400
+#define CNTLREG_ADDRESSCODE_MASK    0x03ff
+
+/* CDMAC descriptor status bit definitions */
+
+#define STS_CTRL_APP0_ERR         (1 << 31)
+#define STS_CTRL_APP0_IRQONEND    (1 << 30)
+/* undoccumented */
+#define STS_CTRL_APP0_STOPONEND   (1 << 29)
+#define STS_CTRL_APP0_CMPLT       (1 << 28)
+#define STS_CTRL_APP0_SOP         (1 << 27)
+#define STS_CTRL_APP0_EOP         (1 << 26)
+#define STS_CTRL_APP0_ENGBUSY     (1 << 25)
+/* undocumented */
+#define STS_CTRL_APP0_ENGRST      (1 << 24)
+
+#define TX_CONTROL_CALC_CSUM_MASK   1
+
+#define XTE_ALIGN       32
+#define BUFFER_ALIGN(adr) ((XTE_ALIGN - ((u32) adr)) % XTE_ALIGN)
+
+#define MULTICAST_CAM_TABLE_NUM 4
+
+#define TX_BD_NUM   64
+#define RX_BD_NUM   128
+
+#define XILINX_GSRD3_NAPI
+
+
+/* TX/RX CURDESC_PTR points to first descriptor */
+/* TX/RX TAILDESC_PTR points to last descriptor in linked list */
+
+struct cdmac_bd {
+	struct cdmac_bd        *next;
+	unsigned char          *phys;
+	u32                    len;
+	u32                    app0;
+	u32                    app1;           /* TX start << 16 | insert */
+	u32                    app2;           /* TX csum */
+	u32                    app3;           /* unused ? */
+	u32                    app4;           /* skb for TX length for RX */
+} ;
+/* APP0 bits
+ 0    Error
+ 1    IrqOnEnd    generate an interrupt at completion of DMA  op
+ 2    reserved
+ 3    completed   Current descriptor completed
+ 4    SOP         TX - marks first desc/ RX marks first desct
+ 5    EOP         TX marks last desc/RX marks last desc
+ 6    EngBusy     DMA is processing
+ 7    reserved
+ 8:31 application specific
+ */
+
+struct temac_region {
+	void __iomem                *addr;
+	void __iomem                *base;
+	unsigned long               len;
+};
+
+struct temac_local {
+	/* Statistics for this device */
+	struct net_device_stats     stats;
+	struct net_device           *dev;
+	struct temac_region			regs;
+	struct temac_region			sdma;
+	int                         tx_irq;
+	int                         rx_irq;
+
+	int                         emac_num;
+	u16                         phy_addr;
+	/* Speed of link 10/100/1000 */
+	int                         LinkSpeed;
+	/* Current options word */
+	u32                    options;
+	spinlock_t                  lock;
+	spinlock_t                  rx_lock;
+	struct cdmac_bd             *tx_bd_v;
+	struct cdmac_bd             *tx_bd_p;
+	struct cdmac_bd             *rx_bd_v;
+	struct cdmac_bd             *rx_bd_p;
+	int                         tx_bd_ci;
+	int                         tx_bd_next;
+	int                         tx_bd_tail;
+	int                         rx_bd_ci;
+	struct sk_buff              **rx_skb;
+};
+
+
+static u32
+tior(struct net_device *ndev, int offset)
+{
+	struct temac_local *lp = netdev_priv(ndev);
+
+	return in_be32((u32 *)(lp->regs.addr + offset));
+}
+
+static void
+tiow(struct net_device *ndev, int offset, u32 value)
+{
+	struct temac_local *lp = netdev_priv(ndev);
+	out_be32((u32 *) (lp->regs.addr + offset), value);
+}
+
+static u32
+tio_setclr(struct net_device *ndev, u32 reg_num, u32 val, int flg)
+{
+	u32 Reg = tior(ndev, reg_num) & ~val;
+	if (flg)
+		Reg |= val;
+	tiow(ndev, reg_num, Reg);
+	return 0;
+}
+
+static u32
+sd_ior(struct net_device *ndev, int offset)
+{
+	struct temac_local *lp = netdev_priv(ndev);
+	return in_be32((u32 *)(lp->sdma.addr + offset));
+}
+
+static void
+sd_iow(struct net_device *ndev, int offset, u32 value)
+{
+	struct temac_local *lp = netdev_priv(ndev);
+	out_be32((u32 *) (lp->sdma.addr + offset), value);
+}
+
+static unsigned int
+mdio_read(struct net_device *ndev, int phy_id, int reg_num)
+{
+	struct temac_local *lp = netdev_priv(ndev);
+	u32 timeout = PHY_TIMEOUT;
+	u32 rv = 0;
+	unsigned long flags;
+
+	if ((reg_num >  MII_REG_MAX) ||
+		(phy_id == PHY_ADDR_INVALID)) {
+		dev_err(&ndev->dev,
+			"mdio_read(%x, %x) invalid reg_num or invalid phy_id\n",
+			reg_num, phy_id);
+		return -1;
+	}
+
+	spin_lock_irqsave(&lp->lock, flags);
+
+	tiow(ndev, XTE_LSW0_OFFSET,
+			((phy_id << 5) | (reg_num)));
+	tiow(ndev, XTE_CTL0_OFFSET,
+			XTE_MIIMAI_OFFSET | (lp->emac_num << 10));
+	while (!(tior(ndev, XTE_RDY0_OFFSET) & XTE_RSE_MIIM_RR_MASK)) {
+		udelay(1);
+		if (--timeout == 0) {
+			dev_err(&ndev->dev, "read_MII busy timeout!!\n");
+			return -1;
+		}
+	}
+	rv = tior(ndev, XTE_LSW0_OFFSET);
+
+	spin_unlock_irqrestore(&lp->lock, flags);
+	return rv;
+}
+
+static void
+mdio_write(struct net_device *ndev, int phy_id, int reg_num, int reg_val)
+{
+	struct temac_local *lp = netdev_priv(ndev);
+	u32 timeout = PHY_TIMEOUT, status;
+	unsigned long flags;
+
+	if ((reg_num >  MII_REG_MAX) ||
+		(phy_id == PHY_ADDR_INVALID)) {
+		dev_err(&ndev->dev,
+			"mdio_write(%x, %x)invalid reg_num or invalid phy_id\n",
+			reg_num, phy_id);
+		return -1;
+	}
+
+	spin_lock_irqsave(&lp->lock, flags);
+
+	tiow(ndev, XTE_LSW0_OFFSET,
+			reg_val);
+	tiow(ndev, XTE_CTL0_OFFSET,
+			CNTLREG_WRITE_ENABLE_MASK | XTE_MGTDR_OFFSET);
+	tiow(ndev, XTE_LSW0_OFFSET,
+			((phy_id << 5) | (reg_num)));
+	tiow(ndev, XTE_CTL0_OFFSET,
+			CNTLREG_WRITE_ENABLE_MASK
+			| XTE_MIIMAI_OFFSET
+			| (lp->emac_num << 10));
+	while (!(status = tior(ndev, XTE_RDY0_OFFSET) & XTE_RSE_MIIM_WR_MASK)) {
+		udelay(1);
+		if (--timeout == 0) {
+			dev_err(&ndev->dev, "write_MII busy timeout!!\n");
+			return ;
+		}
+	}
+
+	spin_unlock_irqrestore(&lp->lock, flags);
+}
+
+static u32
+emac_cfg_read(struct net_device *ndev, u16 reg_num)
+{
+	struct temac_local *lp = netdev_priv(ndev);
+	u32 timeout = PHY_TIMEOUT;
+
+	if (reg_num > TEMAC_REG_MAX) {
+		dev_err(&ndev->dev,
+				"emac_cfg_read(%x) invalid reg_num\n",
+				reg_num);
+		return -1;
+	}
+
+	tiow(ndev, XTE_CTL0_OFFSET, (lp->emac_num << 10) | reg_num);
+	while (!(tior(ndev, XTE_RDY0_OFFSET) & XTE_RSE_CFG_RR_MASK)) {
+		udelay(1);
+		if (--timeout == 0) {
+			dev_err(&ndev->dev, "read temac busy timeout!!\n");
+			return -1;
+		}
+	}
+	return (u32) tior(ndev, XTE_LSW0_OFFSET);
+
+}
+
+static void
+emac_cfg_write(struct net_device *ndev, u32 reg_num, u32 val)
+{
+	struct temac_local *lp = netdev_priv(ndev);
+	u32 timeout = PHY_TIMEOUT;
+
+	if (reg_num > TEMAC_REG_MAX) {
+		dev_err(&ndev->dev,
+				"emac_cfg_write(%x) invalid reg_num\n",
+				reg_num);
+		return -1;
+	}
+
+	tiow(ndev, XTE_LSW0_OFFSET, val);
+	tiow(ndev,
+			XTE_CTL0_OFFSET,
+			(CNTLREG_WRITE_ENABLE_MASK
+			 | (lp->emac_num << 10)
+			 | reg_num));
+	while (!(tior(ndev, XTE_RDY0_OFFSET) & XTE_RSE_CFG_WR_MASK)) {
+		udelay(1);
+		if (--timeout == 0) {
+			dev_err(&ndev->dev, "write temac busy timeout!!\n");
+			return ;
+		}
+	}
+}
+
+static u32
+emac_cfg_setclr(struct net_device *ndev, u32 reg_num, u32 val, int flg)
+{
+	u32 Reg;
+	if (reg_num > TEMAC_REG_MAX) {
+		dev_err(&ndev->dev,
+				"emac_cfg_setclr(%x) invalid reg_num\n",
+				reg_num);
+		return -1;
+	}
+
+	Reg = emac_cfg_read(ndev, reg_num) & ~val;
+	if (flg)
+		Reg |= val;
+	emac_cfg_write(ndev, reg_num, Reg);
+	return 0;
+}
+
+static int
+temac_set_mac_address(struct net_device *ndev, void *address)
+{
+	if (address)
+		memcpy(ndev->dev_addr, address, ETH_ALEN);
+
+	if (!is_valid_ether_addr(ndev->dev_addr))
+		random_ether_addr(ndev->dev_addr);
+
+	/* set up unicast MAC address filter set its mac address */
+	emac_cfg_write(ndev, XTE_UAW0_OFFSET,
+			((ndev->dev_addr[0]) |
+			(ndev->dev_addr[1] << 8) |
+			(ndev->dev_addr[2] << 16) |
+			(ndev->dev_addr[3] << 24)));
+	/* There are reserved bits in EUAW1
+	 * so don't affect them Set MAC bits [47:32] in EUAW1 */
+	emac_cfg_write(ndev, XTE_UAW1_OFFSET,
+			  (ndev->dev_addr[4] & 0x000000ff) |
+			  (ndev->dev_addr[5] << 8));
+
+	return 0;
+}
+
+static void
+temac_set_multicast_list(struct net_device *ndev)
+{
+	struct temac_local *lp = netdev_priv(ndev);
+	u32 multi_addr_msw, multi_addr_lsw;
+	int i;
+
+	spin_lock(&lp->lock);
+
+	if (ndev->flags & (IFF_ALLMULTI | IFF_PROMISC)
+			|| ndev->mc_count > MULTICAST_CAM_TABLE_NUM) {
+		/*
+		 *	We must make the kernel realise we had to move
+		 *	into promisc mode or we start all out war on
+		 *	the cable. If it was a promisc request the
+		 *	flag is already set. If not we assert it.
+		 */
+		ndev->flags |= IFF_PROMISC;
+		dev_info(&ndev->dev, "%s: Promiscuous mode enabled.\n",
+				ndev->name);
+		emac_cfg_write(ndev, XTE_AFM_OFFSET, XTE_AFM_EPPRM_MASK);
+	} else if (ndev->mc_count) {
+		struct dev_mc_list *mclist;
+		for (i = 0, mclist = ndev->mc_list;
+				mclist && i < ndev->mc_count;
+				i++, mclist = mclist->next) {
+
+			if (i >= MULTICAST_CAM_TABLE_NUM)
+				break;
+			multi_addr_msw = ((mclist->dmi_addr[3] << 24)
+						| (mclist->dmi_addr[2] << 16)
+						| (mclist->dmi_addr[1] << 8)
+							| mclist->dmi_addr[0]);
+			emac_cfg_write(ndev, XTE_MAW0_OFFSET, multi_addr_msw);
+			multi_addr_lsw = ((mclist->dmi_addr[5] << 8)
+							| mclist->dmi_addr[4]);
+			multi_addr_lsw |= (i << 16);
+			emac_cfg_write(ndev, XTE_MAW1_OFFSET, multi_addr_lsw);
+		}
+	}  else {
+		dev_info(&ndev->dev, "%s: Promiscuous mode disabled.\n",
+				ndev->name);
+		emac_cfg_write(ndev,
+				XTE_AFM_OFFSET,
+			emac_cfg_read(ndev, XTE_AFM_OFFSET)
+			& ~XTE_AFM_EPPRM_MASK);
+		emac_cfg_write(ndev, XTE_MAW0_OFFSET, 0);
+		emac_cfg_write(ndev, XTE_MAW1_OFFSET, 0);
+	}
+	spin_unlock(&lp->lock);
+}
+
+static void
+temac_phy_init(struct net_device *ndev)
+{
+	struct temac_local *lp = netdev_priv(ndev);
+	unsigned int ret, Reg;
+	int ii;
+
+	/* Set default MDIO divisor */
+	/* Set up MII management registers to write to PHY  */
+	emac_cfg_write(ndev,
+		 XTE_MC_OFFSET,
+		 XTE_MC_MDIO_MASK | XTE_MDIO_DIV_DFT);
+
+	/*
+	   Set A-N Advertisement Regs for Full Duplex modes ONLY
+	 */
+	mdio_write(ndev,
+		 PHY_NUM,
+		 MII_ADVERTISE,
+		 mdio_read(ndev,
+		 PHY_NUM,
+		 MII_ADVERTISE)
+		| ADVERTISE_10FULL
+		| ADVERTISE_100FULL
+		| ADVERTISE_CSMA);
+	mdio_write(ndev, PHY_NUM, MII_CTRL1000, ADVERTISE_1000FULL);
+
+	/*
+	   Soft reset the PHY
+	 */
+	mdio_write(ndev,
+			PHY_NUM,
+			MII_BMCR,
+			mdio_read(ndev, PHY_NUM, MII_BMCR)
+			| BMCR_RESET
+			| BMCR_ANENABLE
+			| BMCR_ANRESTART);
+
+	/* Wait for a PHY Link (auto-negotiation to complete)...  */
+	ret = mdio_read(ndev, PHY_NUM, MII_BMSR);
+	ii = 64;
+	while (((ret & BMSR_LSTATUS) != BMSR_LSTATUS) && ii--) {
+		mdelay(500);
+		ret = mdio_read(ndev, PHY_NUM, MII_BMSR);
+	}
+	ret = mdio_read(ndev, PHY_NUM, MII_SSR);
+
+	Reg = emac_cfg_read(ndev, XTE_EMCFG_OFFSET) & ~XTE_EMCFG_LINKSPD_MASK;
+	if (ret & MII_SSR_LINK) {
+		switch (ret & MII_SSR_SPDMASK) {
+		case MII_SSR_SPD1000:   /* 1000Base-T */
+			lp->LinkSpeed = 1000;
+			emac_cfg_write(ndev,
+					XTE_EMCFG_OFFSET,
+					Reg | (u32) XTE_EMCFG_LINKSPD_1000);
+			break;
+		case MII_SSR_SPD100:    /* 100Base-T */
+			lp->LinkSpeed = 100;
+			emac_cfg_write(ndev,
+					XTE_EMCFG_OFFSET,
+					Reg | XTE_EMCFG_LINKSPD_100);
+			break;
+		case MII_SSR_SPD10: /* 10Base-T */
+			lp->LinkSpeed = 10;
+			break;
+		};
+		if ((ret & MII_SSR_FD) == 0x0) {
+			/* set up Tx/Rx config reg for half duplex */
+			ret = emac_cfg_read(ndev, XTE_TXC_OFFSET);
+			emac_cfg_write(ndev,
+					XTE_TXC_OFFSET,
+					ret | XTE_TXC_TXHD_MASK);
+			ret = emac_cfg_read(ndev, XTE_RXC1_OFFSET);
+			emac_cfg_write(ndev,
+					XTE_RXC1_OFFSET,
+					ret | XTE_RXC1_RXHD_MASK);
+		}
+	}
+}
+
+/* -----------------------------------------------------------------------------
+----------------------------------------------------------------------------- */
+static int
+temac_bd_init(struct net_device *ndev)
+{
+	struct temac_local *lp = netdev_priv(ndev);
+	struct sk_buff *skb;
+	int ii;
+
+	lp->rx_skb = kzalloc(sizeof(struct sk_buff)*RX_BD_NUM, GFP_KERNEL);
+	/* allocate the tx and rx ring buffer descriptors. */
+	/* returns a virtual addres and a physical address. */
+	lp->tx_bd_v = dma_alloc_coherent(NULL,
+			sizeof(struct cdmac_bd) * TX_BD_NUM,
+			(dma_addr_t *)&lp->tx_bd_p,
+			GFP_KERNEL);
+	lp->rx_bd_v = dma_alloc_coherent(NULL,
+			sizeof(struct cdmac_bd) * RX_BD_NUM,
+			(dma_addr_t *)&lp->rx_bd_p,
+			GFP_KERNEL);
+
+	for (ii = 0; ii < TX_BD_NUM; ii++) {
+		memset((char *)&lp->tx_bd_v[ii], 0, sizeof(struct cdmac_bd));
+		if (ii == (TX_BD_NUM - 1))
+			lp->tx_bd_v[ii].next = &lp->tx_bd_p[0];
+		else
+			lp->tx_bd_v[ii].next = &lp->tx_bd_p[ii + 1];
+
+	}
+	for (ii = 0; ii < RX_BD_NUM; ii++) {
+		memset((char *)&lp->rx_bd_v[ii], 0, sizeof(struct cdmac_bd));
+		if (ii == (RX_BD_NUM - 1))
+			lp->rx_bd_v[ii].next = &lp->rx_bd_p[0];
+		else
+			lp->rx_bd_v[ii].next = &lp->rx_bd_p[ii + 1];
+
+		skb = alloc_skb(XTE_MAX_JUMBO_FRAME_SIZE
+				+ XTE_ALIGN, GFP_ATOMIC);
+		if (skb == 0) {
+			dev_err(&ndev->dev, "alloc_skb error %d\n", ii);
+			return -1;
+		}
+		lp->rx_skb[ii] = skb;
+		skb_reserve(skb,  BUFFER_ALIGN(skb->data));
+		/* returns physical address of skb->data */
+		lp->rx_bd_v[ii].phys = (unsigned char *)pci_map_single(NULL,
+				skb->data,
+				XTE_MAX_JUMBO_FRAME_SIZE,
+				PCI_DMA_FROMDEVICE);
+		lp->rx_bd_v[ii].len = XTE_MAX_JUMBO_FRAME_SIZE;
+		lp->rx_bd_v[ii].app0 = STS_CTRL_APP0_IRQONEND;
+	}
+
+	sd_iow(ndev,
+			TX_CHNL_CTRL,
+			0x10220400
+			| CHNL_CTRL_IRQ_EN
+			| CHNL_CTRL_IRQ_DLY_EN
+			| CHNL_CTRL_IRQ_COAL_EN);
+	/* 0x10220483 */
+	/* 0x00100483 */
+	sd_iow(ndev,
+			RX_CHNL_CTRL,
+			0xff010000
+			| CHNL_CTRL_IRQ_EN
+			| CHNL_CTRL_IRQ_DLY_EN
+			| CHNL_CTRL_IRQ_COAL_EN
+			| CHNL_CTRL_IRQ_IOE);
+	/* 0xff010283 */
+
+	sd_iow(ndev, RX_CURDESC_PTR,  (uintptr_t)&lp->rx_bd_p[0]);
+	sd_iow(ndev, RX_TAILDESC_PTR, (uintptr_t)&lp->rx_bd_p[RX_BD_NUM - 1]);
+
+	return 0;
+}
+
+struct temac_option {
+	int		flg;
+	u32		opt;
+	u32		reg;
+	u32		m_or;
+	u32		m_and;
+
+};
+
+struct temac_option temac_options[] = {
+		/* Turn on jumbo packet support for both Rx and Tx */
+	{	0,
+		XTE_OPTION_JUMBO,
+		XTE_TXC_OFFSET,
+		XTE_TXC_TXJMBO_MASK,
+		0
+	},
+	{	0,
+		XTE_OPTION_JUMBO,
+		XTE_RXC1_OFFSET,
+		XTE_RXC1_RXJMBO_MASK,
+		0
+	},
+	/* Turn on VLAN packet support for both Rx and Tx */
+	{	0,
+		XTE_OPTION_VLAN,
+		XTE_TXC_OFFSET,
+		XTE_TXC_TXVLAN_MASK,
+		0
+	},
+	{	0,
+		XTE_OPTION_VLAN,
+		XTE_RXC1_OFFSET,
+		XTE_RXC1_RXVLAN_MASK,
+		0
+	},
+	/* Turn on FCS stripping on receive packets */
+	{	0,
+		XTE_OPTION_FCS_STRIP,
+		XTE_RXC1_OFFSET,
+		XTE_RXC1_RXFCS_MASK,
+		0
+	},
+	/* Turn on FCS insertion on transmit packets */
+	{	0,
+		XTE_OPTION_FCS_INSERT,
+		XTE_TXC_OFFSET,
+		XTE_TXC_TXFCS_MASK,
+		0
+	},
+	/* Turn on length/type field checking on receive packets */
+	{	0,
+		XTE_OPTION_LENTYPE_ERR,
+		XTE_RXC1_OFFSET,
+		XTE_RXC1_RXLT_MASK,
+		0
+	},
+	/* Turn on flow control */
+	{	0,
+		XTE_OPTION_FLOW_CONTROL,
+		XTE_FCC_OFFSET,
+		XTE_FCC_RXFLO_MASK,
+		0
+	},
+	/* Turn on flow control */
+	{	0,
+		XTE_OPTION_FLOW_CONTROL,
+		XTE_FCC_OFFSET,
+		XTE_FCC_TXFLO_MASK,
+		0
+	},
+	/* Turn on promiscuous frame filtering (all frames are received ) */
+	{	0,
+		XTE_OPTION_PROMISC,
+		XTE_AFM_OFFSET,
+		XTE_AFM_EPPRM_MASK,
+		0
+	},
+	/* Enable transmitter if not already enabled */
+	{	0,
+		XTE_OPTION_TXEN,
+		XTE_TXC_OFFSET,
+		XTE_TXC_TXEN_MASK,
+		0
+	},
+	/* Enable receiver? */
+	{	0,
+		XTE_OPTION_RXEN,
+		XTE_RXC1_OFFSET,
+		XTE_RXC1_RXEN_MASK,
+		0
+	},
+	{	0,
+		0,
+		0,
+		0,
+		0
+   }
+};
+
+static u32
+temac_setoptions(struct net_device *ndev, u32 Options) {
+	struct temac_local *lp = netdev_priv(ndev);
+	struct temac_option *tp = &temac_options[0];
+
+	while (tp->opt) {
+		if (tp->flg)
+			tio_setclr(ndev,
+					tp->reg,
+					tp->m_or,
+					(Options & tp->opt));
+		else
+			emac_cfg_setclr(ndev,
+					tp->reg,
+					tp->m_or,
+					(Options & tp->opt));
+		tp++;
+	}
+	lp->options |= Options;
+
+	return (0);
+}
+
+/* Initilize temac */
+static void
+temac_device_reset(struct net_device *ndev)
+{
+	struct temac_local *lp = netdev_priv(ndev);
+	u32 timeout = 1000;
+
+	/* Perform a software reset */
+
+	/* 0x300 host enable bit ? */
+	/* reset PHY through control register ?:1 */
+
+	/* Reset the device */
+	emac_cfg_write(ndev, XTE_RXC1_OFFSET, XTE_RXC1_RXRST_MASK);
+	/* Wait for the receiver to finish reset */
+	while (emac_cfg_read(ndev, XTE_RXC1_OFFSET) & XTE_RXC1_RXRST_MASK) {
+		udelay(1);
+		if (--timeout == 0) {
+			dev_err(&ndev->dev,
+				"temac_device_reset RX reset timeout!!\n");
+			break;
+		}
+	}
+
+	emac_cfg_write(ndev, XTE_TXC_OFFSET, XTE_TXC_TXRST_MASK);
+	/* Wait for the transmitter to finish reset */
+	timeout = 1000;
+	while (emac_cfg_read(ndev, XTE_TXC_OFFSET) & XTE_TXC_TXRST_MASK) {
+		udelay(1);
+		if (--timeout == 0) {
+			dev_err(&ndev->dev,
+				"temac_device_reset TX reset timeout!!\n");
+			break;
+		}
+	}
+
+	/* Disable the receiver */
+	emac_cfg_write(ndev,
+			XTE_RXC1_OFFSET,
+			emac_cfg_read(ndev, XTE_RXC1_OFFSET)
+			& ~XTE_RXC1_RXEN_MASK);
+
+	/* reset */
+	tiow(ndev, XTE_RAF0_OFFSET, 1);
+	/* wait for reset */
+	timeout = 1000;
+	while (tior(ndev, XTE_RAF0_OFFSET) & 1) {
+		udelay(1);
+		if (--timeout == 0) {
+			dev_err(&ndev->dev,
+				"temac_device_reset RAF reset timeout!!\n");
+			break;
+		}
+	}
+
+	/* ISR0/IER0/IPR0 bits */
+	/* b1         autoneg complete */
+	/* b2         receive complete */
+	/* b5         transmit complete */
+	/* b0       = interrupts from TIS/TIE registers */
+
+
+	/* Reset */
+	sd_iow(ndev, DMA_CONTROL_REG, DMA_CONTROL_RST);
+	timeout = 1000;
+	while (sd_ior(ndev, DMA_CONTROL_REG) & DMA_CONTROL_RST) {
+		udelay(1);
+		if (--timeout == 0) {
+			dev_err(&ndev->dev,
+				"temac_device_reset DMA reset timeout!!\n");
+			break;
+		}
+	}
+
+	dev_info(&ndev->dev,
+			"%s: Xilinx Embedded Tri-Mode Ethernet MAC %s %s\n",
+			ndev->name,
+			__DATE__,
+			__TIME__);
+	dev_info(&ndev->dev, "temac %08x sdma %08x\n",
+			lp->regs.addr,
+			lp->sdma.addr);
+
+	temac_bd_init(ndev);
+
+	emac_cfg_write(ndev, XTE_RXC0_OFFSET, 0);
+	emac_cfg_write(ndev, XTE_RXC1_OFFSET, 0);
+	emac_cfg_write(ndev, XTE_TXC_OFFSET, 0);
+	emac_cfg_write(ndev, XTE_FCC_OFFSET, XTE_FCC_RXFLO_MASK);
+
+	/* Sync default options with HW
+	 * but leave receiver and transmitter disabled.  */
+	temac_setoptions(ndev,
+			lp->options & ~(XTE_OPTION_TXEN | XTE_OPTION_RXEN));
+
+	temac_phy_init(ndev);
+
+	temac_set_mac_address(ndev, 0);
+	/* Set address filter table */
+	temac_set_multicast_list(ndev);
+	if (temac_setoptions(ndev, lp->options))
+		dev_err(&ndev->dev, "Error setting TEMAC options\n");
+
+	/* Init Driver variable */
+	ndev->trans_start = 0;
+	spin_lock_init(&lp->lock);
+	spin_lock_init(&lp->rx_lock);
+}
+
+static void
+temac_hard_start_xmit_done(struct net_device *ndev)
+{
+	struct temac_local *lp = netdev_priv(ndev);
+	struct cdmac_bd *cur_p;
+	unsigned int stat = 0;
+
+	cur_p = &lp->tx_bd_v[lp->tx_bd_ci];
+	stat = cur_p->app0;
+
+	while (stat & STS_CTRL_APP0_CMPLT) {
+		pci_unmap_single(NULL,
+				(unsigned long)cur_p->phys,
+				cur_p->len,
+				PCI_DMA_TODEVICE);
+		if (cur_p->app4)
+			dev_kfree_skb_irq((struct sk_buff *)cur_p->app4);
+		cur_p->app0 = 0;
+
+		lp->stats.tx_packets++;
+		lp->stats.tx_bytes += cur_p->len;
+
+		lp->tx_bd_ci++;
+		if (lp->tx_bd_ci >= TX_BD_NUM)
+			lp->tx_bd_ci = 0;
+
+		cur_p = &lp->tx_bd_v[lp->tx_bd_ci];
+		stat = cur_p->app0;
+	}
+
+	netif_wake_queue(ndev);
+}
+
+static int
+temac_hard_start_xmit(struct sk_buff *skb, struct net_device *ndev)
+{
+	struct temac_local *lp = netdev_priv(ndev);
+	struct cdmac_bd *cur_p, *start_p, *tail_p;
+	int ii;
+	unsigned long num_frag;
+	skb_frag_t *frag;
+
+	num_frag = skb_shinfo(skb)->nr_frags;
+	frag = &skb_shinfo(skb)->frags[0];
+	start_p = &lp->tx_bd_p[lp->tx_bd_tail];
+	cur_p = &lp->tx_bd_v[lp->tx_bd_tail];
+
+	if (cur_p->app0 & STS_CTRL_APP0_CMPLT) {
+		if (!netif_queue_stopped(ndev)) {
+			netif_stop_queue(ndev);
+			return NETDEV_TX_BUSY;
+		}
+		return NETDEV_TX_BUSY;
+	}
+
+	cur_p->app0 = 0;
+	if (skb->ip_summed == CHECKSUM_PARTIAL) {
+		const struct iphdr *ip = ip_hdr(skb);
+		int length = 0, start, insert = 0, headlen;
+
+		switch (ip->protocol) {
+		case IPPROTO_TCP:
+			start = sizeof(struct iphdr) + ETH_HLEN;
+			insert = sizeof(struct iphdr) + ETH_HLEN + 16;
+			length = ip->tot_len - sizeof(struct iphdr);
+			headlen = ETH_HLEN
+				+ sizeof(struct iphdr)
+				+ sizeof(struct tcphdr);
+			break;
+		case IPPROTO_UDP:
+			start = sizeof(struct iphdr) + ETH_HLEN;
+			insert = sizeof(struct iphdr) + ETH_HLEN + 6;
+			length = ip->tot_len - sizeof(struct iphdr);
+			headlen = ETH_HLEN
+				+ sizeof(struct iphdr)
+				+ sizeof(struct udphdr);
+			break;
+		default:
+			break;
+		}
+		cur_p->app1 = ((start << 16) | insert);
+		cur_p->app2 = csum_tcpudp_magic(ip->saddr,
+				ip->daddr,
+				length,
+				ip->protocol,
+				0);
+		skb->data[insert] = 0;
+		skb->data[insert + 1] = 0;
+	}
+	cur_p->app0 |= STS_CTRL_APP0_SOP;
+	cur_p->len = skb_headlen(skb);
+	cur_p->phys = (unsigned char *)pci_map_single(NULL,
+			skb->data, skb->len,
+			PCI_DMA_TODEVICE);
+	cur_p->app4 = (unsigned long)skb;
+
+	for (ii = 0; ii < num_frag; ii++) {
+		lp->tx_bd_tail++;
+		if (lp->tx_bd_tail >= TX_BD_NUM)
+			lp->tx_bd_tail = 0;
+
+		cur_p = &lp->tx_bd_v[lp->tx_bd_tail];
+		cur_p->phys = (unsigned char *)pci_map_single(NULL,
+				(void *)page_address(frag->page)
+				+ frag->page_offset,
+				frag->size,
+				PCI_DMA_TODEVICE);
+		cur_p->len = frag->size;
+		cur_p->app0 = 0;
+		frag++;
+	}
+	cur_p->app0 |= STS_CTRL_APP0_EOP;
+
+	tail_p = &lp->tx_bd_p[lp->tx_bd_tail];
+	lp->tx_bd_tail++;
+	if (lp->tx_bd_tail >= TX_BD_NUM)
+		lp->tx_bd_tail = 0;
+
+		/* EngBusy ? */
+	if (!(sd_ior(ndev, TX_CHNL_STS) & CHNL_STS_ENGBUSY)) {
+		sd_iow(ndev, TX_CURDESC_PTR, (uintptr_t)start_p);
+		/* DMA start */
+		sd_iow(ndev, TX_TAILDESC_PTR, (uintptr_t)tail_p);
+	}
+
+	return 0;
+}
+
+
+static void
+ll_temac_recv(struct net_device *ndev)
+{
+	struct temac_local *lp = netdev_priv(ndev);
+	struct sk_buff *skb, *new_skb;
+	unsigned int bdstat;
+	struct cdmac_bd *cur_p, *tail_p;
+	int length;
+	unsigned long skb_vaddr;
+	unsigned long flags;
+
+	spin_lock_irqsave(&lp->rx_lock, flags);
+
+	tail_p = &lp->rx_bd_p[lp->rx_bd_ci];
+	cur_p = &lp->rx_bd_v[lp->rx_bd_ci];
+
+	bdstat = cur_p->app0;
+	while ((bdstat & STS_CTRL_APP0_CMPLT)) {
+
+		skb = lp->rx_skb[lp->rx_bd_ci];
+		length = cur_p->app4;
+
+		skb_vaddr = virt_to_bus(skb->data);
+		pci_unmap_single(NULL, skb_vaddr, length, PCI_DMA_FROMDEVICE);
+
+		skb_put(skb, length);
+		skb->dev = ndev;
+		skb->protocol = eth_type_trans(skb, ndev);
+		skb->ip_summed = CHECKSUM_NONE;
+
+		netif_rx(skb);
+
+		lp->stats.rx_packets++;
+		lp->stats.rx_bytes += length;
+
+		new_skb = alloc_skb(XTE_MAX_JUMBO_FRAME_SIZE + XTE_ALIGN,
+				GFP_ATOMIC);
+		if (new_skb == 0) {
+			dev_err(&ndev->dev, "no memory for new sk_buff\n");
+			spin_unlock_irqrestore(&lp->rx_lock, flags);
+			return;
+		}
+
+		skb_reserve(new_skb, BUFFER_ALIGN(new_skb->data));
+
+		cur_p->app0 = STS_CTRL_APP0_IRQONEND;
+		cur_p->phys = (unsigned char *)
+				pci_map_single(NULL, new_skb->data,
+						   XTE_MAX_JUMBO_FRAME_SIZE,
+						   PCI_DMA_FROMDEVICE);
+		cur_p->len    = XTE_MAX_JUMBO_FRAME_SIZE;
+		lp->rx_skb[lp->rx_bd_ci] = new_skb;
+
+		lp->rx_bd_ci++;
+		if (lp->rx_bd_ci >= RX_BD_NUM)
+			lp->rx_bd_ci = 0;
+
+		cur_p = &lp->rx_bd_v[lp->rx_bd_ci];
+		bdstat = cur_p->app0;
+	}
+	sd_iow(ndev, RX_TAILDESC_PTR, (uintptr_t)tail_p);
+
+	spin_unlock_irqrestore(&lp->rx_lock, flags);
+}
+
+static irqreturn_t
+ll_temac_tx_interrupt(int irq, void *dev_id)
+{
+	unsigned int status;
+	struct net_device *ndev = (struct net_device *)dev_id;
+
+	status = sd_ior(ndev, TX_IRQ_REG);
+	sd_iow(ndev, TX_IRQ_REG, status);
+
+	if (status & (IRQ_COAL | IRQ_DLY))
+		temac_hard_start_xmit_done(ndev);
+	if (status & 0x080)
+		dev_err(&ndev->dev, "DMA error 0x%x\n", status);
+
+	return IRQ_HANDLED;
+}
+
+static irqreturn_t
+ll_temac_rx_interrupt(int irq, void *dev_id)
+{
+	unsigned int status;
+	struct net_device *ndev = (struct net_device *)dev_id;
+
+	status = sd_ior(ndev, RX_IRQ_REG);
+	sd_iow(ndev, RX_IRQ_REG, status);
+
+	if (status & (IRQ_COAL | IRQ_DLY))
+		ll_temac_recv(ndev);
+
+	return IRQ_HANDLED;
+}
+
+static struct net_device_stats *
+temac_get_stats(struct net_device *ndev)
+{
+	return netdev_priv(ndev);
+}
+
+static int
+temac_open(struct net_device *ndev)
+{
+	struct temac_local *lp = netdev_priv(ndev);
+	int erC = 0;
+
+	/* if (netif_device_present(ndev))
+	 *	raise link
+	*/
+	erC = request_irq(lp->tx_irq, ll_temac_tx_interrupt,
+			0, ndev->name, ndev);
+	erC = request_irq(lp->rx_irq, ll_temac_rx_interrupt,
+			0, ndev->name, ndev);
+	temac_device_reset(ndev);
+	return 0;
+}
+
+static int
+temac_stop(struct net_device *ndev)
+{
+	struct temac_local *lp = netdev_priv(ndev);
+	/* if (netif_device_present(ndev))
+	 *	drop link
+	*/
+	free_irq(lp->tx_irq, ndev);
+	free_irq(lp->rx_irq, ndev);
+	/* free buffers */
+
+	return 0;
+}
+
+#ifdef CONFIG_NET_POLL_CONTROLLER
+static void
+temac_poll_controller(struct net_device *ndev)
+{
+	struct temac_local *lp = netdev_priv(ndev);
+
+	disable_irq(lp->tx_irq);
+	disable_irq(lp->rx_irq);
+
+	ll_temac_rx_interrupt(lp->tx_irq, ndev, 0);
+	ll_temac_tx_interrupt(lp->rx_irq, ndev, 0);
+
+	enable_irq(lp->tx_irq);
+	enable_irq(lp->rx_irq);
+}
+#endif
+
+static int __init
+temac_device_map(struct platform_device *pdev, struct net_device *ndev,
+		int num, struct temac_region *reg)
+{
+	struct resource *res;
+	int erC = 0;
+
+	res = platform_get_resource(pdev, IORESOURCE_MEM, num);
+	if (res == 0) {
+		erC = -ENODEV;
+		goto fail;
+	}
+	if (request_mem_region(res->start, res->end - res->start,
+				pdev->name) == 0) {
+		dev_err(&pdev->dev,
+				"%s: failed to request registers\n",
+				pdev->name);
+		erC = -ENXIO;
+		goto fail;
+	}
+
+	reg->base = (uintptr_t)res->start;
+	reg->len  = res->end - res->start;
+	reg->addr = ioremap_nocache((uintptr_t)reg->base, reg->len);
+	if (reg->addr == 0) {
+		dev_err(&pdev->dev,
+			"%s: failed to remap registers\n", pdev->name);
+		erC = -ENXIO;
+		goto fail_remap;
+	}
+	return 0;
+fail_remap:
+	release_region((u32)reg->addr, reg->len);
+fail:
+	return erC;
+}
+/*
+Search TEMAC board, allocate space and register it
+ */
+static int __init
+temac_device_probe(struct platform_device *pdev)
+{
+	struct net_device *ndev = alloc_etherdev(sizeof(struct temac_local));
+	struct xlltemac_platform_data *pdata =
+		(struct xlltemac_platform_data *) pdev->dev.platform_data;
+	struct temac_local *lp;
+	u8 addr[] = { 0x0, 0x50, 0xc2, 0x44, 0x2f, 0xff };
+	int erC = 0;
+
+	/* Init network device */
+	if (!ndev) {
+		dev_err(&pdev->dev, "could not allocate device.\n");
+		return -ENOMEM;
+	}
+	platform_set_drvdata(pdev, ndev);
+	SET_NETDEV_DEV(ndev, &pdev->dev);
+	/* setup board info structure */
+	/* Clear memory */
+	lp = netdev_priv(ndev);
+	memset(lp, 0, sizeof(struct temac_local));
+	erC = temac_device_map(pdev, ndev, 0, &lp->regs);
+	if (erC) {
+		dev_err(&pdev->dev, "could not allocate temac regs.\n");
+		goto nodev;
+	}
+	ndev->base_addr = (u32) lp->regs.addr;
+
+	erC = temac_device_map(pdev, ndev, 1, &lp->sdma);
+	if (erC) {
+		dev_err(&pdev->dev, "could not allocate sdma regs.\n");
+		goto nodev;
+	}
+	lp->rx_irq = platform_get_irq(pdev, 0);
+	if (lp->rx_irq < 0) {
+		dev_err(&pdev->dev, "could not allocate rx irq.\n");
+		erC = -ENOMEM;
+		goto nodev;
+	}
+	lp->tx_irq = platform_get_irq(pdev, 1);
+	if (lp->tx_irq < 0) {
+		dev_err(&pdev->dev, "could not allocate tx irq.\n");
+		erC = -ENOMEM;
+		goto nodev;
+	}
+
+	dev_info(&pdev->dev, DRV_NAME ".c:v " __DATE__ " "
+			DRV_AUTHOR " " DRV_EMAIL "\n");
+
+	lp->dev = ndev;
+	lp->emac_num = 0;
+	lp->options = XTE_OPTION_DEFAULTS;
+
+	temac_set_mac_address(ndev, addr);
+	/* from this point we assume that we have found a TEMAC */
+	/* driver system function */
+	ether_setup(ndev);
+	/* The TEMAC-specific entries in the device structure. */
+	ndev->open = &temac_open;
+	ndev->stop = &temac_stop;
+	ndev->get_stats = &temac_get_stats;
+	ndev->set_mac_address = &temac_set_mac_address;
+	ndev->hard_start_xmit = &temac_hard_start_xmit;
+	ndev->set_multicast_list = &temac_set_multicast_list;
+#ifdef CONFIG_NET_POLL_CONTROLLER
+	ndev->poll_controller = &temac_poll_controller;
+#endif
+	ndev->flags &= ~IFF_MULTICAST;  /* clear multicast */
+
+	/* Scatter/gather IO. */
+	ndev->features = NETIF_F_SG ;
+	/* Scatter/gather IO. */
+	ndev->features |= NETIF_F_FRAGLIST;
+#if 0
+	/* Can checksum TCP/UDP over IPv4. */
+	ndev->features |= NETIF_F_IP_CSUM
+	/* Can checksum all the packets. */
+	ndev->features |= NETIF_F_HW_CSUM
+
+	/* Can checksum TCP/UDP over IPV6 */
+	ndev->features |= NETIF_F_IPV6_CSUM
+	/* Can DMA to high memory. */
+	ndev->features |= NETIF_F_HIGHDMA
+	/* Transmit VLAN hw acceleration */
+	ndev->features |= NETIF_F_HW_VLAN_TX
+	/* Receive VLAN hw acceleration */
+	ndev->features |= NETIF_F_HW_VLAN_RX
+	/* Receive filtering on VLAN */
+	ndev->features |= NETIF_F_HW_VLAN_FILTER
+	/* Device cannot handle VLAN packets */
+	ndev->features |= NETIF_F_VLAN_CHALLENGED
+	/* Enable software GSO. */
+	ndev->features |= NETIF_F_GSO
+	/* Has multiple TX/RX queues */
+	ndev->features |= NETIF_F_MULTI_QUEUE
+	/* large receive offload */
+	 ndev->features |= NETIF_F_LRO
+#endif
+
+
+	erC = register_netdev(ndev);
+	if (!erC)
+		return 0;
+
+nodev:
+	free_netdev(ndev);
+	ndev = NULL;
+	return erC;
+}
+
+static int __devexit temac_device_remove(struct platform_device *pdev)
+{
+	struct net_device *dev = platform_get_drvdata(pdev);
+
+	unregister_netdev(dev);
+	platform_set_drvdata(pdev, NULL);
+	free_netdev(dev);
+	return 0;
+}
+static struct platform_driver temac_device_driver = {
+	.probe      = temac_device_probe,
+	.remove     = __devexit_p(temac_device_remove),
+	.suspend    = NULL,
+	.resume     = NULL,
+	.driver     = {
+		.name   = DRV_NAME,
+		.owner  = THIS_MODULE,
+	},
+};
+
+static int __init
+temac_init_module(void)
+{
+	return platform_driver_register(&temac_device_driver);
+}
+
+static void __exit
+temac_cleanup_module(void)
+{
+	platform_driver_unregister(&temac_device_driver);
+}
+
+module_init(temac_init_module);
+module_exit(temac_cleanup_module);
+
+MODULE_DESCRIPTION("Xilinx Tri-Mode Eth MAC driver");
+MODULE_ALIAS("platform:" DRV_NAME);
+MODULE_AUTHOR(DRV_AUTHOR);
+MODULE_LICENSE("GPL");
+/* vim:set ts=4 sts=4 sw=4 noet list nowrap: */
diff --git a/include/linux/xilinx_devices.h b/include/linux/xilinx_devices.h
index 41ad421..40512d5 100755
--- a/include/linux/xilinx_devices.h
+++ b/include/linux/xilinx_devices.h
@@ -94,7 +94,7 @@ struct xtemac_platform_data {
 #define XTEMAC_DMA_SGDMA	3	/* scatter gather DMA */
 #endif
 
-#if defined(CONFIG_XILINX_LLTEMAC)
+#if defined(CONFIG_XILINX_LLTEMAC) || defined(CONFIG_XPS_LLTEMAC)
 /* LLTEMAC platform data */
 struct xlltemac_platform_data {
 	u8 tx_csum;

^ permalink raw reply related

* Re: [PATCH 1/3] gpiolib: make gpio_to_chip() public
From: Laurent Pinchart @ 2008-08-19  9:26 UTC (permalink / raw)
  To: avorontsov
  Cc: David Brownell, Greg Kroah-Hartman, linux-usb, linux-kernel,
	linuxppc-dev, Li Yang, Timur Tabi
In-Reply-To: <20080818153300.GA10163@oksana.dev.rtsoft.ru>

[-- Attachment #1: Type: text/plain, Size: 5545 bytes --]

On Monday 18 August 2008, Anton Vorontsov wrote:
> On Mon, Aug 18, 2008 at 04:44:36PM +0200, Laurent Pinchart wrote:
> > On Monday 18 August 2008, Anton Vorontsov wrote:
> > > On Mon, Aug 18, 2008 at 03:58:46PM +0200, Laurent Pinchart wrote:
> > > [...]
> > > > > Not exactly. But you can do this way, if you need to preserve
> > > > > a direction. What I did is a bit different though.
> > > > > 
> > > > > qe_gpio_set_dedicated() actually just restores a mode that
> > > > > firmware had set up, including direction (since direction could
> > > > > be a part of dedicated configuration).
> > > > > 
> > > > > That is, upon GPIO controller registration, we save all registers,
> > > > > then driver can set up a pin to a GPIO mode via standard API, and
> > > > > then it can _revert_ a pin to a dedicated function via
> > > > > qe_gpio_set_dedicated() call. Dedicated function is specified by
> > > > > the firmware (or board file), we're just restoring it.
> > > > 
> > > > The semantic of the set_dedicated() operation needs to be clearly
> > > > defined then.
> > > 
> > > It is. We set up a dedicated function that firmware (or board file)
> > > has configured.
> > 
> > A comment in the source would help.
> > 
> > > > I can live with this behaviour, but it might not be
> > > > acceptable for everybody.
> > > 
> > > For example?
> > > 
> > > > Your patch requires the firmware to set a pin in dedicated mode at
> > > > bootup in order to be used later in dedicated mode.
> > > 
> > > Yes. On a PowerPC this is always true: firmware should set up PIO
> > > config. Linux' board file could fixup the firmware though.
> > 
> > That's not what I meant. What if the hardware requires to pin to be
> > configured in GPIO mode with a fixed value until the SOC-specific
> > driver that will drive the GPIO is loaded ? That's not possible
> > with your API.
> 
> Yes, this isn't possible with this API. Because you can do this
> with standard GPIO API! ;-)
> 
> Just call gpio_direction_*() in the board file, before probing the
> hardware.

You'd have to do that after the GPIO drivers saved the pin registers.

> > Until a SOC peripheral is initialized by its associated Linux driver,
> > the behaviour of a GPIO pin in dedicated mode will be undefined.
> 
> Huh?! Then all current software is simply broken: we're setting pinmux
> config _prior_ to controller initialization.

Undefined behaviour doesn't mean broken behaviour :-) Signals coming from SOC peripherals are mostly undefined until the peripheral is initialized. For most hardware that doesn't matter much, but it might in some cases. For instance the state of the RTS signal on a serial port probably doesn't matter before we start serial communication, but some boards might require that RTS is deasserted before the controller is initialized. We can just ignore the issue for now and wait until it bites us.

> > The firmware/board code will probably want to set the pin as a GPIO
> > output with a fixed value until the driver initializes the hardware.
> 
> Probably? Do you have any such hardware?

Nope. I was referring to the hardware such as in the above example.

> > > Another option would be to add some argument to the set_dedicated
> > > call, thus the software could specify arbitrary dedicated
> > > function (thus no need to save/restore anything). But this would
> > > be SOC-model specific, thus no driver can use this argument anyway.
> > 
> > Drivers that require dedicated mode are SOC-specific anyway.
> 
> I didn't say "SOC-specific". I said "SOC-model specific", which
> means that the driver would be not portable even across QE chips
> (i.e. MPC8323 vs. MPC8360, you can assume that the "CLK12" function
> is having same PAR/ODR/DAT/DIR bits).

If I'm not mistaken, the PAR bit is used to select between GPIO and dedicated mode by definition. It should be safe to assume that setting a GPIO in dedicated mode requires the PAR bit to be set. But as I stated above, we can ignore that for now until a hardware use case comes up.

> > > > If, for some
> > > > reason (driver not loaded, ...), no GPIO user shows up for that
> > > > pin, it will stay configured in dedicated mode.
> > > 
> > > Yes.
> > > 
> > > > It might be better to set the PAR bit unconditionally in
> > > 
> > > Why it might be better?
> > 
> > Because, as explained a few lines down, the board initialization code
> > will be able to configure a pin in a known state (PAR not set) at boot
> > time until a driver requests the pin to be switched to dedicated mode.
> 
> You can do this as I described above. But prior to this, yes, you have
> to configure the pins and let Linux save these values. There is no other
> way to pass this information, unfortunately.

Ok.

I started implementing CPM2 dedicated mode support to be used in the CPM UART driver for RTS/CTS flow control, and soon realized there was a show stopper. The CPM UART driver is mostly CPM1/CPM2 agnostic. I can't use a function such as cpm2_gpio32_set_dedicated, as that wouldn't work on a CPM1 (at least not on all its ports). I could call the right function depending on which port the GPIO is on, but that's really hackish and would defeat the purpose of using GPIOs. What we really need there is a set_dedicated/set_option/set_whatever function in the GPIO API :-/

-- 
Laurent Pinchart
CSE Semaphore Belgium

Chaussee de Bruxelles, 732A
B-1410 Waterloo
Belgium

T +32 (2) 387 42 59
F +32 (2) 387 42 75

[-- Attachment #2: This is a digitally signed message part. --]
[-- Type: application/pgp-signature, Size: 197 bytes --]

^ permalink raw reply

* Re: [MPC7448] machdep_calls
From: Sébastien Chrétien @ 2008-08-19  9:23 UTC (permalink / raw)
  To: benh; +Cc: Linuxppc-dev
In-Reply-To: <1219130863.8062.39.camel@pasglop>

[-- Attachment #1: Type: text/plain, Size: 3243 bytes --]

So I will write .setup_arch of machine_call  structure.
When is ppc_md.setup_arch() called ?

2008/8/19, Benjamin Herrenschmidt <benh@kernel.crashing.org>:
>
> On Tue, 2008-08-19 at 09:00 +0200, Sébastien Chrétien wrote:
> > I have no screen that's why I have to use UART. I followed the CPM
> > model in head_32.S :
> > #ifdef CONFIG_PPC_EARLY_DEBUG_CPM
> > setup_cpm_bat:
> >     lis    r8, 0xf000
> >     ori    r8, r8,    0x002a
> >     mtspr    SPRN_DBAT1L, r8
> >
> >     lis    r11, 0xf000
> >     ori    r11, r11, (BL_1M << 2) | 2
> >     mtspr    SPRN_DBAT1U, r11
> >
> >     blr
> > #endif
>
>
> The "EARLY DEBUG" stuff is a pile of hacks to help with bringup,
> it's definitely not a long term solution to your problems.
>
> You may also want to look at Grant Likely's work on doing proper
> early ioremap using BATs.
>
>
> > With this code  I can use udbg.
> >
> > According to you, what is the best way ?
>
>
> The above is fine for early debug console. But that's definitely
> not the only kind of thing you may want to put in your setup_arch()...
> Look at what others do.
>
> Ben.
>
>
> > 2008/8/18, Benjamin Herrenschmidt <benh@kernel.crashing.org>:
> >         On Mon, 2008-08-18 at 16:17 +0200, Sébastien Chrétien wrote:
> >         > The mpc7448hpc2 uses a tsi108-bridge. My board uses an IP on
> >         a FPGA..
> >         > I read the code of mpc7448_hpc2.c.
> >         > It uses a ioremap in order to iniatilize the tsi108
> >         registers. But I
> >         > have already initialized MMU with my registers in HEAD_32.S.
> >         Do I need
> >         > to use ioremap in setup_arch() ?
> >
> >
> >         Why did you hack head_32.S ? You shouldn't do that... This is
> >         common
> >         code, not platform code.
> >
> >         Ben.
> >
> >         >
> >         >
> >         >
> >         > 2008/8/18, Michael Ellerman <michael@ellerman.id.au>:
> >         >         On Mon, 2008-08-18 at 13:35 +0200, Sébastien
> >         Chrétien wrote:
> >         >         > Can somebody explain me the aim of the
> >         >         function  "setup_arch" in the
> >         >         > machine_call structure ?
> >         >
> >         >
> >         >         Is this MPC7448 anything like an mpc7448hpc2 ?
> >         >
> >         >         If so maybe you should start by looking at the code
> >         for it in:
> >         >
> >         >         arch/powerpc/platforms/embedded6xx/mpc7448_hpc2.c
> >         >
> >         >         Even if it's not related, that will give you some
> >         idea of what
> >         >         the
> >         >         callbacks are for.
> >         >
> >         >         cheers
> >         >
> >         >         --
> >         >         Michael Ellerman
> >         >         OzLabs, IBM Australia Development Lab
> >         >
> >         >         wwweb: http://michael.ellerman.id.au
> >         >         phone: +61 2 6212 1183 (tie line 70 21183)
> >         >
> >         >         We do not inherit the earth from our ancestors,
> >         >         we borrow it from our children. - S.M.A.R.T Person
> >         >
> >         >
> >
> >
>
>

[-- Attachment #2: Type: text/html, Size: 7166 bytes --]

^ permalink raw reply


This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox