This patch has been created from AVM's opensrc packages for 3490.06.20 and 7360.06.20
by applying to the kernel sources they contain the following command:

    diff -durN --no-dereference 3490.06.20 7360.06.20 > this.patch

--- linux-2.6.32/arch/mips/kernel/yield_context.c
+++ linux-2.6.32/arch/mips/kernel/yield_context.c
@@ -490,7 +490,7 @@
 \*--------------------------------------------------------------------------------*/
 void yield_context_dump(void)
 {
-	char buf[256];
+	char buf[512];
 	struct seq_file s = {
 		.buf = buf,
 		.size = sizeof(buf),
@@ -807,7 +807,7 @@
 	stackpointer = regs ? regs->regs[29] : 0L;
 	if((stackpointer < (unsigned long)&per_tc->yield_sp[0]) || (stackpointer >= (unsigned long)&per_tc->yield_sp[YIELD_MAX_STACK_ELEMENTS])) {
 		printk(KERN_EMERG"Fatal Error: Stackpointer %08lx exceed stack!\n", stackpointer);
-	} else {
+	} else if(stackpointer) {
 		unsigned int linenefeed = 0;
 		unsigned int *p      = (unsigned int *)stackpointer;
 		printk(KERN_EMERG"Stack:\n");
--- linux-2.6.32/drivers/block/nbd.c
+++ linux-2.6.32/drivers/block/nbd.c
@@ -655,7 +655,8 @@
 
 		mutex_unlock(&lo->tx_lock);
 
-		thread = kthread_create(nbd_thread, lo, lo->disk->disk_name);
+		thread = kthread_create(nbd_thread, lo, "%s",
+					lo->disk->disk_name);
 		if (IS_ERR(thread)) {
 			mutex_lock(&lo->tx_lock);
 			return PTR_ERR(thread);
--- linux-2.6.32/drivers/char/avm_new/ar7wdt_main.c
+++ linux-2.6.32/drivers/char/avm_new/ar7wdt_main.c
@@ -982,6 +982,30 @@
 	}
 }
 #endif
+
+/*--------------------------------------------------------------------------------*\
+\*--------------------------------------------------------------------------------*/
+int __get_userinfo(char *buf, unsigned int maxbuflen, struct mm_struct *mmm, unsigned long addr) {
+    struct vm_area_struct *vm;
+    unsigned int i = 0;
+    if(mmm == NULL) {
+        return 1;
+    }
+    vm = mmm->mmap;
+    while(vm) {
+        /*--- printk(KERN_INFO"%s[%x]:%p %x -%x\n", __func__, addr, vm, vm->vm_start, vm->vm_end); ---*/
+        if((addr >= vm->vm_start) && (addr < vm->vm_end)) {
+            snprintf(buf, maxbuflen,"seg=%3u of=0x%08lx [%s]", i, addr - (unsigned long)vm->vm_start, 
+                         (vm->vm_file && vm->vm_file->f_path.dentry) ? (char *)vm->vm_file->f_path.dentry->d_name.name : "");
+            /*--- printk(KERN_INFO"%s", buf); ---*/
+            return 0;
+        }
+        vm = vm->vm_next;
+        i++;
+    }
+    return 1;
+}
+
 /*--------------------------------------------------------------------------------*\
 \*--------------------------------------------------------------------------------*/
 static void __sched_show_user_task(struct task_struct *task){
--- linux-2.6.32/drivers/char/avm_new/avm_debug.c
+++ linux-2.6.32/drivers/char/avm_new/avm_debug.c
@@ -432,7 +432,7 @@
     return idx;
 }
 
-inline void avm_debug_enable_avm_printk(void)
+void avm_debug_enable_avm_printk(void)
 {
 #ifdef CONFIG_PRINTK
 
@@ -448,7 +448,7 @@
 #endif /* CONFIG_PRINTK */
 }
 
-inline void avm_debug_disable_avm_printk(void)
+void avm_debug_disable_avm_printk(void)
 {
 #ifdef CONFIG_PRINTK
 
@@ -474,7 +474,7 @@
 
     /* Always use original Linux printk */
     printk_linux(KERN_ERR "\nblock cpu%x for %lu ms\n",
-		smp_processor_id(), timer);
+		raw_smp_processor_id(), timer);
 
     while(timer--) {
         udelay(1000);
@@ -490,7 +490,7 @@
 static void torture_function(unsigned long context)
 {
 	printk_linux(KERN_ERR "\nblock timer on cpu%x for %lu ms\n",
-		     smp_processor_id(), context);
+		     raw_smp_processor_id(), context);
 
 	while (context--)
 		udelay(1000);
@@ -646,7 +646,7 @@
                 add_timer_on(&torture_Timer[cpu], cpu);
             } else 
 #if defined(CONFIG_SMP)
-            if(cpu != smp_processor_id()) {
+            if(cpu != raw_smp_processor_id()) {
                 smp_call_function_single(cpu, torture, (void *)val, 0);
             } else 
 #endif /*--- #if defined(CONFIG_SMP) ---*/
@@ -1219,7 +1219,7 @@
     if(pud->NextIsLong == TRUE) {
         signed long long lValue;
         lValue = va_arg(*marker, long long);
-        sprintf(Data, "%llx", lValue);
+        snprintf(Data, sizeof(Data), "%llx", lValue);
     } else {
         Val = va_arg(*marker, int); 
         if((mode == 1) && (Val == 0)) {
@@ -1369,7 +1369,7 @@
         return;
     }
     if(check_memory_pointer(B)){
-        sprintf(tmp, "(inval=0x%x)", (unsigned int)B);
+        snprintf(tmp, sizeof(tmp), "(inval=0x%x)", (unsigned int)B);
         B = tmp;
     }
     if(pud->Leftjust == TRUE) { /*--- reverse ---*/
@@ -1408,7 +1408,7 @@
         pstring = "(null)";
     }
     if(check_memory_pointer(pstring)){
-        sprintf(tmp, "(inval=0x%x)", (unsigned int)pstring);
+        snprintf(tmp, sizeof(tmp), "(inval=0x%x)", (unsigned int)pstring);
         pstring = tmp;
     }
     if (pud->field_prec == 0) {
@@ -1472,7 +1472,7 @@
 
 #if defined(CONFIG_SMP)
 #define CPU_ARGUMENT_STRING()  "[%x] "
-#define CPU_ID()    ,smp_processor_id()
+#define CPU_ID()    ,raw_smp_processor_id()
 #else
 #define CPU_ARGUMENT_STRING() " "
 #define CPU_ID()    
@@ -1505,7 +1505,7 @@
 #if defined(CONFIG_PRINTK_TIME)
         /* Follow the token with the time */
         unsigned long clk_rem;
-        unsigned long long clk = cpu_clock(smp_processor_id());
+        unsigned long long clk = cpu_clock(raw_smp_processor_id());
         clk_rem = do_div(clk, 1000000000);
 #endif /*--- #if defined(CONFIG_PRINTK_TIME) ---*/
         if(lost) {
@@ -1546,6 +1546,8 @@
 #ifdef CONFIG_KALLSYMS
    if(Mode && (*Mode & 0x2)) {
 #else
+       /*--- wir benoetigen Modul-Textaufloesung: ---*/
+#endif/*--- #ifdef CONFIG_KALLSYMS ---*/
         if(Mode && (*Mode & 0x1)) {
             len = debug_prefix(DebugData, 0);
             if(len > 0) {
@@ -1553,8 +1555,6 @@
                 pud->Sum = len;
             }
         }
-       /*--- wir benoetigen Modul-Textaufloesung: ---*/
-#endif/*--- #ifdef CONFIG_KALLSYMS ---*/
         pud->Pos        = 0;
         pud->NextIsLong = FALSE;
         pud->p_ext = no_extension;
@@ -1730,13 +1730,17 @@
 /*-------------------------------------------------------------------------------------*\
 \*-------------------------------------------------------------------------------------*/
 void avm_DebugPrintf(const char *format, ...) {
-    int print_time = 0x1| 0x2;
+    int print_time = 0x2;
+	const char *start_format = format;
     va_list marker;
 
     int level = skip_loglevel(&format, 0);
     if (console_loglevel < level) {
         return;
     }
+	if(start_format != format) {
+		print_time |= 0x1;	/*--- Loglevel gefunden -> Timestamp davor ---*/
+    }
     va_start(marker,format);
     if(likely(avm_debug.init)) {
         avm_DebugvPrintf(&print_time, format, marker);
--- linux-2.6.32/drivers/char/avm_new/avm_proc_profile.c
+++ linux-2.6.32/drivers/char/avm_new/avm_proc_profile.c
@@ -572,28 +572,6 @@
 
 /*--------------------------------------------------------------------------------*\
 \*--------------------------------------------------------------------------------*/
-int __get_userinfo(char *buf, unsigned int maxbuflen, struct mm_struct *mmm, unsigned long addr) {
-    struct vm_area_struct *vm;
-    unsigned int i = 0;
-    if(mmm == NULL) {
-        return 1;
-    }
-    vm = mmm->mmap;
-    while(vm) {
-        /*--- printk(KERN_INFO"%s[%x]:%p %x -%x\n", __func__, addr, vm, vm->vm_start, vm->vm_end); ---*/
-        if((addr >= vm->vm_start) && (addr < vm->vm_end)) {
-            snprintf(buf, maxbuflen,"seg=%3u of=0x%08lx [%s]", i, addr - (unsigned long)vm->vm_start, 
-                         (vm->vm_file && vm->vm_file->f_path.dentry) ? (char *)vm->vm_file->f_path.dentry->d_name.name : "");
-            /*--- printk(KERN_INFO"%s", buf); ---*/
-            return 0;
-        }
-        vm = vm->vm_next;
-        i++;
-    }
-    return 1;
-}
-/*--------------------------------------------------------------------------------*\
-\*--------------------------------------------------------------------------------*/
 int get_user_info(char *buf, unsigned int maxbuflen, pid_t pid, unsigned long addr) {
     struct pid *ppid;
     unsigned int pc_value __attribute__((unused)), ret = 1;
@@ -1075,15 +1053,17 @@
 /*--------------------------------------------------------------------------------*\
 \*--------------------------------------------------------------------------------*/
 static void performance_counter_action(char *p __attribute__((unused))) {
-		char *p1  __attribute__((unused));
 #if defined(CONFIG_MIPS) && !defined(CONFIG_MIPS_UR8)
         unsigned int perf_reg_number = 0;
         int perf_reg_flags = 0;
         int perf_reg_index = 0;
         unsigned int i;
         unsigned int perf_max_registers;
+#if defined(CONFIG_CPU_MIPS_34K)
+		char *p1  __attribute__((unused));
         int perf_vpeid = -1;
         int perf_tcid = -1;
+#endif
         int new_perf_ctl = 0;
 
 #if defined(CONFIG_CPU_MIPS_34K)
@@ -1224,6 +1204,7 @@
         SKIP_NON_SPACE(p);
         SKIP_SPACE(p);
 
+#if defined(CONFIG_CPU_MIPS_34K)
         if((p1 = strstr(p, "examine_vpe="))){
 			unsigned int param;
             sscanf(p1, "examine_vpe=%x", &param);
@@ -1239,7 +1220,6 @@
             SKIP_NON_SPACE(p);
             SKIP_SPACE(p);
         }
-#if defined(CONFIG_CPU_MIPS_34K)
         if((p1 = strstr(p, "counting_tc_mask="))) {
 			unsigned int param;
             sscanf(p1 , "counting_tc_mask=%x", &param);
--- linux-2.6.32/drivers/char/avm_new/avm_sammel.c
+++ linux-2.6.32/drivers/char/avm_new/avm_sammel.c
@@ -107,10 +107,6 @@
             *p++ = ' ';
             *p   = '\0';
         }
-
-        if(strstr(AVM_NEW_HWREV_LIST, buff)) {
-            avm_event_enable_push_button = 1;
-        }
     }
 
     /*--------------------------------------------------------------------------------------*\
--- linux-2.6.32/drivers/char/avm_new/init_avm
+++ linux-2.6.32/drivers/char/avm_new/init_avm
@@ -25,20 +25,6 @@
     KERNEL_CLASS=26
 fi
 
-tmp=`grep 'BUTTON=y' $FRITZ_BOX_BUILD_DIR/arch/etc/init.d/rc.${KERNEL_LAYOUT}.init`
-
-AVM_NEW_HWREV_LIST=""
-for i in $tmp ; do
-    case $i in
-        HW=*)
-            HWREV=${i##HW=}
-            AVM_NEW_HWREV_LIST="$AVM_NEW_HWREV_LIST ${HWREV%%[a-zA-Z]*}"
-            ;;
-        *)
-            ;;
-    esac
-done
-
 for i in `find . -name Makefile.$KERNEL_CLASS` ; do
     dest=${i%.$KERNEL_CLASS}
     source="`pwd`/$i"
@@ -49,7 +35,6 @@
     echo -e "#############################################" >>$dest
     echo -e "" >>$dest
     cat  $source >> $dest
-    echo "EXTRA_CFLAGS	+= -DAVM_NEW_HWREV_LIST=\"\\\"$AVM_NEW_HWREV_LIST \\\"\"" >>$dest
 done
 
 ln -fs `pwd`/linux_avm_event.h ../../../include/linux/avm_event.h 
--- linux-2.6.32/drivers/char/avm_new/Makefile
+++ linux-2.6.32/drivers/char/avm_new/Makefile
@@ -1,6 +1,6 @@
 #############################################
 # Makefile: automaticly generated by ./init_avm
-#           Mi 17. Sep 11:27:25 CEST 2014
+#           Di 17. Mär 15:39:29 CET 2015
 #############################################
 
 #############################################
@@ -104,5 +104,3 @@
 
 EXTRA_CFLAGS	+= -Wall -Wextra
 # EXTRA_CFLAGS	+= -g -ggdb -save-temps
-EXTRA_CFLAGS	+= -DAVM_NEW_HWREV_LIST="\" 156 191 171 137 168 197 139 145 167 141 144 170 175 177 181 183 196 202 203 209 185 193 212 192 198 210 211 189 179 188 180 96 184 195 207 190 201 194 200 205 206 172 173 \""
-EXTRA_CFLAGS	+= -DAVM_NEW_HWREV_LIST="\" 156 191 171 137 168 197 139 145 167 141 144 170 175 177 181 183 196 202 203 209 185 193 212 192 198 210 211 189 179 188 180 96 184 195 207 190 201 194 200 205 206 214 172 173 \""
--- linux-2.6.32/drivers/char/avm_new/Makefile.26
+++ linux-2.6.32/drivers/char/avm_new/Makefile.26
@@ -99,4 +99,3 @@
 
 EXTRA_CFLAGS	+= -Wall -Wextra
 # EXTRA_CFLAGS	+= -g -ggdb -save-temps
-EXTRA_CFLAGS	+= -DAVM_NEW_HWREV_LIST="\" 156 191 171 137 168 197 139 145 167 141 144 170 175 177 181 183 196 202 203 209 185 193 212 192 198 210 211 189 179 188 180 96 184 195 207 190 201 194 200 205 206 172 173 \""
--- linux-2.6.32/drivers/char/avm_power/avm_power.h
+++ linux-2.6.32/drivers/char/avm_power/avm_power.h
@@ -80,6 +80,7 @@
     struct _power_managment_clients *next;
     char *client_name;
     int (*CallBackPowerManagmentControl)(int state);
+    atomic_t link;
 };
 
 /*--------------------------------------------------------------------------------*\
--- linux-2.6.32/drivers/char/avm_power/avm_power_if.c
+++ linux-2.6.32/drivers/char/avm_power/avm_power_if.c
@@ -28,6 +28,7 @@
 #include <linux/slab.h>
 #include <linux/sched.h>
 #include <linux/avm_power.h>
+#include <linux/sched.h>
 #include "avm_power.h"
 #if defined(DECTSYNC_PATCH)
 #include "dectsync.h"
@@ -42,6 +43,8 @@
 #define DEB_TRC_PT(args...)
 #endif/*--- #else ---*//*--- #if defined(DEBUG_TRACE_POWERTAB) ---*/
 
+static DEFINE_SPINLOCK(gpw_client_lock);
+
 /*-------------------------------------------------------------------------------------*\
  * Liste von registrierten Treibern, die den PowermanagmentCallback-Befehl bekommen
 \*-------------------------------------------------------------------------------------*/
@@ -375,17 +378,38 @@
     }
     return NULL;
 }
+/*--------------------------------------------------------------------------------*\
+ * ret: 0 freigegeben 
+\*--------------------------------------------------------------------------------*/
+static inline int put_pwclient(struct _power_managment_clients *client) {
+	if(atomic_read(&client->link) == 0) {
+		printk(KERN_ERR"%s error link already zero\n", __func__);
+		return 0;
+	}
+	if (atomic_dec_and_test(&client->link)) {
+		/*--- printk(KERN_INFO"%s free\n", __func__); ---*/
+		kfree(client);
+		return 0;
+	}
+	return 1;
+}
 /*-------------------------------------------------------------------------------------*\
 \*-------------------------------------------------------------------------------------*/
-struct _power_managment_clients *find_pwclient_by_name(char *client_name) {
-    struct _power_managment_clients *client = (struct _power_managment_clients *)PwClientAnker;
+struct _power_managment_clients *get_pwclient_by_name(char *client_name) {
+    struct _power_managment_clients *client;
+	unsigned long flags;
 
+	spin_lock_irqsave(&gpw_client_lock, flags);
+    client = (struct _power_managment_clients *)PwClientAnker;
     while(client) {
         if(strcmp(client_name, client->client_name) == 0) {
+			atomic_add(1, &client->link);
+			spin_unlock_irqrestore(&gpw_client_lock, flags);
             return client;
         }
         client = client->next;
     }
+	spin_unlock_irqrestore(&gpw_client_lock, flags);
     return NULL; 
 }
 /*-------------------------------------------------------------------------------------*\
@@ -398,22 +422,26 @@
     if(new == NULL) {
         return NULL;
     }
+	atomic_set(&new->link, 1);
     new->client_name = (char *)new + sizeof(struct _power_managment_clients);
     strcpy(new->client_name, client_name);
     new->CallBackPowerManagmentControl = CallBackPowerManagmentControl;
-    new->next = NULL;
-    flags = avm_power_lock();
+
+	spin_lock_irqsave(&gpw_client_lock, flags);
     new->next     = (struct _power_managment_clients *)PwClientAnker;
     PwClientAnker = new;
-    avm_power_unlock(flags);
+	spin_unlock_irqrestore(&gpw_client_lock, flags);
     return new; 
 }
 /*-------------------------------------------------------------------------------------*\
 \*-------------------------------------------------------------------------------------*/
-static void del_pwclient(struct _power_managment_clients *delclient) {
+static int del_pwclient(struct _power_managment_clients *delclient) {
+	unsigned long flags;
     struct _power_managment_clients *prevclient = NULL; 
-    unsigned long flags = avm_power_lock();
-    struct _power_managment_clients *client = (struct _power_managment_clients *)PwClientAnker;
+    struct _power_managment_clients *client;
+
+	spin_lock_irqsave(&gpw_client_lock, flags);
+    client = (struct _power_managment_clients *)PwClientAnker;
     while(client) {
         if(client == delclient) {
             if(prevclient == NULL) {
@@ -422,14 +450,14 @@
             } else {
                 prevclient->next = client->next;
             }
-            avm_power_unlock(flags);
-            kfree(client);
-            return;
+			spin_unlock_irqrestore(&gpw_client_lock, flags);
+            return put_pwclient(client);
         }
         prevclient = client;
         client     = client->next;
     }
-    avm_power_unlock(flags);
+	spin_unlock_irqrestore(&gpw_client_lock, flags);
+	return 0;
 }
 /*-------------------------------------------------------------------------------------*\
  * Powermanagment des Treibers anmelden
@@ -439,13 +467,13 @@
 void *PowerManagmentRegister(char *client_name, int (*CallBackPowerManagmentControl)(int state)){
     struct _power_managment_clients *client;
     DEB_INFO("[avm_power] PowerManagmentRegister(\"%s\", 0x%p)\n", client_name, CallBackPowerManagmentControl);
-
     if(client_name == NULL || CallBackPowerManagmentControl == NULL) {
         DEB_ERR("[avm_power]PowerManagmentRegister: invalid param %p %p\n", client_name, CallBackPowerManagmentControl);
         return NULL;
     }
-    client = find_pwclient_by_name(client_name);
+    client = get_pwclient_by_name(client_name);
     if(client) {
+		put_pwclient(client);
         return client;
     }
     return add_pwclient(client_name, CallBackPowerManagmentControl);
@@ -456,11 +484,14 @@
 \*-------------------------------------------------------------------------------------*/
 void PowerManagmentRelease(void *Handle){
     struct _power_managment_clients *delclient = (struct _power_managment_clients *)Handle;
+    printk(KERN_ERR"[avm_power] PowerManagmentRelease(0x%p)\n", Handle);
     if(Handle == NULL) {
         DEB_ERR("[avm_power]%s: invalid Handle\n", __func__);
         return;
     }
-    del_pwclient(delclient);
+    if(del_pwclient(delclient)) {
+		schedule_timeout(HZ/10); /*--- er scheint noch in CallBackPowerManagmentControl zu haengen: hier warten ! ---*/
+	}
 }
 EXPORT_SYMBOL(PowerManagmentRelease);
 
@@ -509,7 +540,7 @@
         return 1;
     }
     while(powermodetab[i].client_name) {
-        registered_client = find_pwclient_by_name(powermodetab[i].client_name);
+        registered_client = get_pwclient_by_name(powermodetab[i].client_name);
         if(registered_client == NULL) {
             if(powermodetab[i].mandatory & AVM_PM_CB_UNINSTALLED_OR_FAILED) {
                 DEB_TRC_PT("[avm_power] '%s' not registered can't execute powermanagment ->stop\n", powermodetab[i].client_name);
@@ -519,6 +550,7 @@
             }
         } else {
             if((async_context == 0) && (powermodetab[i].mandatory & AVM_PM_ASYNC)) {
+				put_pwclient(registered_client);
                 return powermode_action_async(&powermodetab[i]);
             }
             if((powermodetab[i].mandatory & AVM_PM_LOCK) && (locked == 0)) {
@@ -535,6 +567,7 @@
             } else {
                 /*--- DEB_TRC_PT("[avm_power] '%s'=0x%x powermanagment ok\n", powermodetab[i].client_name, powermodetab[i].state); ---*/
             }
+			put_pwclient(registered_client);
         }
         if(ret) {
             break;
@@ -553,14 +586,14 @@
 \*--------------------------------------------------------------------------------*/
 int powermode_action_nolist(char *client_name, int State) {
     struct _power_managment_clients *registered_client;
-    registered_client = find_pwclient_by_name(client_name);
+	int ret;
+    registered_client = get_pwclient_by_name(client_name);
     if(registered_client == NULL) {
         return 2;
     }
-    if(registered_client->CallBackPowerManagmentControl(State)) {
-        return 1;
-    }
-    return 0;
+    ret = registered_client->CallBackPowerManagmentControl(State);
+	put_pwclient(registered_client);
+    return ret ? 1 : 0;
 }
 /*-------------------------------------------------------------------------------------*\
 \*-------------------------------------------------------------------------------------*/
--- linux-2.6.32/drivers/char/tffs-2.0/tffs_panic.c
+++ linux-2.6.32/drivers/char/tffs-2.0/tffs_panic.c
@@ -43,6 +43,9 @@
 #include <linux/seq_file.h>
 #endif /*--- #if defined(CONFIG_PROC_FS) ---*/
 #include "tffs_local.h"
+#if defined(CONFIG_AVM_WATCHDOG)
+#include <linux/ar7wdt.h>
+#endif/*--- #if defined(CONFIG_AVM_WATCHDOG) ---*/
 
 #define ARRAY_EL(a) (sizeof(a) / sizeof(a[0]))
 
@@ -52,6 +55,8 @@
 #endif/*--- #if defined(CONFIG_MACH_AR934x) ---*/
 
 unsigned int tffs_spi_mode = 0;
+unsigned int tffs_panic_log_suppress = 0;
+EXPORT_SYMBOL(tffs_panic_log_suppress);
 
 #if !defined(CRASHPANIC_LOG_PER_REMOTE_EVENT_SOURCE)
 static struct file tffs_panic_file;
@@ -61,7 +66,7 @@
 /*--------------------------------------------------------------------------------*\
  * Schreiben im Panic-Kontext
 \*--------------------------------------------------------------------------------*/
-void tffs_panic_log_open(void) {
+static void tffs_panic_log_open(void) {
     int ret __attribute__((unused));
     if(tffs_panic_open_flag == 1)
         return;
@@ -73,20 +78,21 @@
     tffs_panic_inode.i_rdev = MKDEV(0, FLASH_FS_ID_PANIC_LOG);   /*--- major muss 0 sein fuer Kernel Mode ---*/
 
     ret = tffs_open(&tffs_panic_inode, &tffs_panic_file);
-    if(ret)
+    if(ret) {
         return;
+	}
 #endif/*--- #if !defined(CRASHPANIC_LOG_PER_REMOTE_EVENT_SOURCE) ---*/
     tffs_panic_open_flag = 1;
 }
 /*--------------------------------------------------------------------------------*\
  * Schreiben im Panic-Kontext
 \*--------------------------------------------------------------------------------*/
-void tffs_panic_log_write(char *buffer, unsigned int len) {
+static void tffs_panic_log_write(char *buffer, unsigned int len) {
     static loff_t off __attribute__((unused));
     if(tffs_panic_open_flag == 0)
         return;
 #if defined(CRASHPANIC_LOG_PER_REMOTE_EVENT_SOURCE)
-    avm_event_send_log(remote_panic, 1, buffer, len);
+    avm_event_send_log(remote_panic, FLAG_REMOTELOG_APPEND, buffer, len);
 #else /*--- #if defined(CRASHPANIC_LOG_PER_REMOTE_EVENT_SOURCE) ---*/
     tffs_write(&tffs_panic_file, buffer, len, &off);
 #endif/*--- #else  ---*//*--- #if defined(CRASHPANIC_LOG_PER_REMOTE_EVENT_SOURCE) ---*/
@@ -94,10 +100,11 @@
 /*--------------------------------------------------------------------------------*\
  * Schreiben im Panic-Kontext
 \*--------------------------------------------------------------------------------*/
-void tffs_panic_log_close(void) {
+static void tffs_panic_log_close(void) {
     if(tffs_panic_open_flag == 0)
         return;
 #if defined(CRASHPANIC_LOG_PER_REMOTE_EVENT_SOURCE)
+    avm_event_send_log(remote_panic, FLAG_REMOTELOG_APPEND_FINISHED | FLAG_REMOTELOG_REBOOT, NULL, 0);
     printk("%s wait on reboot from host-cpu\n", __func__);
     for(;;) ;   /*--- ... der arm soll booten - ansonsten auf Watchdog warten ---*/
 #else/*--- #if defined(CRASHPANIC_LOG_PER_REMOTE_EVENT_SOURCE) ---*/
@@ -106,6 +113,78 @@
 }
 /*--------------------------------------------------------------------------------*\
 \*--------------------------------------------------------------------------------*/
+static unsigned int get_act_time(void) {
+    struct timeval now;
+    do_gettimeofday(&now);
+    return (unsigned int)(now.tv_sec);
+}
+/*--------------------------------------------------------------------------------*\
+\*--------------------------------------------------------------------------------*/
+static char *time_to_ascii(unsigned long local_time, char *buf, int len, char *prefix) {
+    static char *month[] = { "Jan",  "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" };
+    static char *day[]   = { "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"};
+    struct rtc_time tm;
+    rtc_time_to_tm(local_time, &tm);
+    snprintf(buf, len, "%s %s %02d %02d:%02d:%02d %02d UTC %s", day[tm.tm_wday],  month[tm.tm_mon], tm.tm_mday, 
+                                                  tm.tm_hour, tm.tm_min, tm.tm_sec, tm.tm_year + 1900,
+                                                  prefix
+                                                  );
+    return buf;
+}
+/*--------------------------------------------------------------------------------*\
+ * maxsize of buf: 14 + 10 + 2 + 2 + 2  = 30
+\*--------------------------------------------------------------------------------*/
+static char *human_readable_time(char *buf, unsigned long buf_size, unsigned long time) {
+	unsigned long seconds, minutes, hours, days;
+
+	seconds = time % 60; time /= 60;
+	minutes = time % 60; time /= 60; 
+	hours	= time % 24; time /= 24;
+	days	= time;
+	snprintf(buf, buf_size, "%lu d %lu h %lu min %lu s", days, hours, minutes, seconds);
+    return buf;
+}
+/*--------------------------------------------------------------------------------*\
+\*--------------------------------------------------------------------------------*/
+void tffs_panic_log_printkbuf(void) {
+    if(tffs_panic_log_suppress == 0) {
+        unsigned long printk_get_buffer(char **p_log_buf, unsigned long *p_log_end, unsigned long *p_anzahl);
+        char *buf;
+        unsigned long end;
+        unsigned long anzahl;
+        unsigned long len = printk_get_buffer(&buf, &end, &anzahl);
+        struct timespec uptime;
+		char htime[32], huptime[128];
+        char time_stamp_buf[sizeof("UPTIME: \n") + sizeof(htime) + sizeof(huptime) + 10 + sizeof("\n( - panic on )\nPANIC LOG VERSION 2.0\n")];
+        unsigned long time_stamp_buf_len;
+
+        tffs_panic_log_suppress = 1;
+        tffs_panic_log_open();
+        do_posix_clock_monotonic_gettime(&uptime);
+        monotonic_to_bootbased(&uptime);
+        time_stamp_buf_len = snprintf(time_stamp_buf, sizeof(time_stamp_buf), "UPTIME: %lu\n(%s - panic on %s)\nPANIC LOG VERSION 2.0\n",  
+																			(unsigned long)uptime.tv_sec, 
+																			human_readable_time(huptime, sizeof(huptime), (unsigned long)uptime.tv_sec),
+																			time_to_ascii((unsigned long)get_act_time(), htime, sizeof(htime), "")
+																			);
+        tffs_panic_log_write(time_stamp_buf, time_stamp_buf_len);
+#if defined(CONFIG_AVM_WATCHDOG)
+        AVM_WATCHDOG_emergency_retrigger();
+#endif
+        if(anzahl < len) {  /*--- alles im Buffer ---*/
+            tffs_panic_log_write(buf, anzahl);
+        } else {
+            tffs_panic_log_write(buf + end, len - end);
+#if defined(CONFIG_AVM_WATCHDOG)
+            AVM_WATCHDOG_emergency_retrigger();
+#endif
+            tffs_panic_log_write(buf, end);
+        }
+        tffs_panic_log_close();
+    }
+}
+/*--------------------------------------------------------------------------------*\
+\*--------------------------------------------------------------------------------*/
 void tffs_panic_log_register_spi(void) {
     tffs_spi_mode = 1;
 }
@@ -115,8 +194,12 @@
 static unsigned int calc_sum_and_correct(unsigned char *buf, int buf_len, int correct) {
     unsigned int i, sum = 0;
     for(i = 0; i < buf_len; i++) {
-        if(correct && (buf[i] == 0)) buf[i] = ' ';   /*--- correct buffer (support null-teminated string) ---*/
-        sum += buf[i];
+		unsigned int val = buf[i];
+		if(val == 0) {
+			val = ' ';
+			if(correct) buf[i] = val;   /*--- correct buffer (support null-teminated string) ---*/
+    }
+        sum += val; 
     }
     return sum ^ (buf_len << 16);
 }
@@ -140,7 +223,7 @@
 
     ret = tffs_open(&tffs_inode, &tffs_file);
     if(ret) {
-        printk(KERN_ERR"%s tffs_open failed ret=%d\n", __func__, ret);
+        /*--- printk(KERN_ERR"%s tffs_open failed ret=%d\n", __func__, ret); ---*/
         return;
     }
     open_data = (struct _tffs_open *)tffs_file.private_data;
@@ -181,7 +264,7 @@
 #endif
             cs = calc_sum_and_correct(logbufuncached, event.loglen, 0);
             if(cs != event.checksum) {
-                printk(KERN_ERR"%s: obscure checksum %x != %x -> ignore\n", __func__, event.checksum, cs);
+                printk(KERN_ERR"%s: type=%d obscure checksum %x != %x -> ignore\n", __func__, event.logtype, event.checksum, cs);
                 iounmap(logbufuncached);
                 return;
             }
@@ -204,12 +287,18 @@
 /*--------------------------------------------------------------------------------*\
 \*--------------------------------------------------------------------------------*/
 static void remote_log_register_sink(void *private __attribute__((unused)), unsigned int param1 __attribute__((unused)), unsigned int param2 __attribute__((unused))){ 
+#if AVM_DIST_EVENT_VERSION > 0x10000
+	struct _avm_event_id_mask id_mask;
+#endif
     if(remote_log_event_sink_handle) {
         return;
     }
     remote_log_event_sink_handle = avm_event_sink_register("log_remote_sink",
-                                                          (1ULL << avm_event_id_log) |
-                                                           0,
+#if AVM_DIST_EVENT_VERSION > 0x10000
+   													       avm_event_build_id_mask(&id_mask, 1, avm_event_id_log),
+#else
+						                                   1ULL << avm_event_id_log,
+#endif
                                                            remote_log_sink,
                                                            NULL
                                                           );
@@ -239,6 +328,7 @@
     }
     return MAX_LOG_IDS;
 }
+static unsigned int log_read_multiple[MAX_LOG_IDS];
 /*--------------------------------------------------------------------------------*\
 \*--------------------------------------------------------------------------------*/
 static int tffs_panic_log_read(unsigned char *buf, int buf_len, unsigned int id) {
@@ -267,24 +357,6 @@
 }
 /*--------------------------------------------------------------------------------*\
 \*--------------------------------------------------------------------------------*/
-static char *time_to_ascii(char *buf, int len, char *prefix) {
-    static char *month[] = { "Jan",  "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" };
-    static char *day[]   = { "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"};
-    struct rtc_time tm;
-    struct timeval now;
-    unsigned int local_time;
-    do_gettimeofday(&now);
-    /*--- local_time = (u32)(now.tv_sec - (sys_tz.tz_minuteswest * 60)); ---*//*---  tz_minuteswest == 0 ?  ---*/
-    local_time = (u32)(now.tv_sec);
-    rtc_time_to_tm(local_time, &tm);
-    snprintf(buf, len, "%s %s %02d %02d:%02d:%02d %d UTC %s", day[tm.tm_wday],  month[tm.tm_mon], tm.tm_mday, 
-                                                  tm.tm_hour, tm.tm_min, tm.tm_sec, tm.tm_year + 1900,
-                                                  prefix
-                                                  );
-    return buf;
-}
-/*--------------------------------------------------------------------------------*\
-\*--------------------------------------------------------------------------------*/
 static int paniclog_show(struct seq_file *seq, void *data __attribute__((unused))) {
 
     /*--- printk(KERN_INFO"%s %p %p\n", __func__, seq->private, data); ---*/
@@ -294,54 +366,65 @@
     return 0;
 }
 /*--------------------------------------------------------------------------------*\
- * return: Pointer auf Zeitstempel, gefuelltes checksum, read_once
- *
- * 2 Formate werden unterstuezt:
- * alt: panic_cs, panic_sram_cs, read_once_cr, time
- * neu: [id]cs,[id2]cs,.., read_once_cr; time
 \*--------------------------------------------------------------------------------*/
-const char *parse_crash_env(const char *crashp, unsigned int checksum[], unsigned int *read_once) {
-    memset(checksum, 0, MAX_LOG_IDS * sizeof(unsigned int));
-    *read_once =  0;
-    if(*crashp == 0) {
-        return crashp;
+struct _time_checksum {
+	unsigned int cs;
+	unsigned int ts;		/* timestamp on read */
+#define READ_BY_CR			0x1
+#define READ_BY_SD			0x2
+#define FIRST_READ_BY_SD	0x4		/* first read by SD */
+	unsigned int readmask;
+};
+#define SKIP_UNTIL_CHAR(p, sign) while(*p && (*p != sign)) p++
+/*--------------------------------------------------------------------------------*\
+\*--------------------------------------------------------------------------------*/
+static inline unsigned COUNT_UNTIL_CHAR(const char *p, unsigned char sign, unsigned char count_sign) {
+	unsigned int count = 0;
+	while(*p && (*p != sign)) {
+		if(*p == count_sign) {
+			count++;
     }
-    if(*crashp != '[') {
-        /*--- altes Format: ---*/
-        sscanf(crashp, "0x%x,0x%x,0x%x;", &checksum[0], &checksum[1], read_once);
-        while(*crashp && (*crashp != ';')) crashp++;        
-        if(*crashp == ';') crashp++;
-        return crashp;
+		p++;
     }
+	return count;
+}
+/*--------------------------------------------------------------------------------*\
+ * return: gefuelltes checksum
+ * [id]cs,ts,readmask,[id2]cs,ts,readmask
+\*--------------------------------------------------------------------------------*/
+void parse_crash_env(const char *crashp, struct _time_checksum checksum[]) {
+    memset(checksum, 0, MAX_LOG_IDS * sizeof(struct _time_checksum));
     while(*crashp) {
-        unsigned int id, val;
+        unsigned int id, val, val1, val2;
         if(*crashp == '[') {
-            sscanf(++crashp,"%x]%x,", &id,&val);
+            sscanf(++crashp,"%x]%x,%x,%x", &id, &val, &val1, &val2);
             if(id < MAX_LOG_IDS) {
-                checksum[id] = val;
+				unsigned int count = COUNT_UNTIL_CHAR(crashp, '[', ',');
+                checksum[id].cs		  = val;
+				checksum[id].ts	      = val1;
+				if(count >= 1) {
+					checksum[id].ts	      = val1;
             }
-            while(*crashp && (*crashp != ',')) crashp++;        
-            if(*crashp == ',') crashp++;
+				if(count >= 2) {
+					checksum[id].readmask = val2;
+				}
+            }
+			SKIP_UNTIL_CHAR(crashp, '[');
         } else {
-            sscanf(crashp,"%x,", read_once);
-            while(*crashp && (*crashp != ';')) crashp++;        
-            if(*crashp == ';') crashp++;
-            return crashp;
+            return;
         }
     }
-    return crashp;
 }
 /*--------------------------------------------------------------------------------*\
 \*--------------------------------------------------------------------------------*/
-static void set_crash_env(char *crashp, int len, unsigned int checksum[], unsigned int read_once, const char *timestart) {
+static void set_crash_env(char *crashp, int len, struct _time_checksum checksum[]) {
     unsigned int written, i;
     for(i = 0; i < MAX_LOG_IDS; i++) {
         if(len > 0) {
-            written = snprintf(crashp, len, "[%x]%x,", i, checksum[i]);
+            written = snprintf(crashp, len, "[%x]%x,%x,%x", i, checksum[i].cs, checksum[i].ts, checksum[i].readmask);
             len -= written, crashp += written;
         }
     }
-    if(len > 0) snprintf(crashp, len, "%x;%s\n", read_once, timestart);
 }
 /*--------------------------------------------------------------------------------*\
 \*--------------------------------------------------------------------------------*/
@@ -351,17 +434,25 @@
     const char *timestart = "";
     int buf_len = (0x1 << 17) - 64; /*--- ReserveTimestamp ---*/
     int len = buf_len;
-    unsigned int tffs_once_cr = 0;
-    unsigned int saved_checksum[MAX_LOG_IDS];
+    struct _time_checksum saved_checksum[MAX_LOG_IDS];
+	unsigned int new_read_mask = 0;
     unsigned int map_idx = map_log_id_to_index(id);
     char *buf;
 
-    memset(saved_checksum, 0, MAX_LOG_IDS);
     /*--- printk(KERN_ERR"%s: id=%d map_idx=%x %s\n", __func__, id, map_idx, crashreport ? "cr" : "sd"); ---*/
     if(map_idx >= MAX_LOG_IDS) {
         /*--- printk("%s: error: id=%d too big\n", __func__, map_idx); ---*/
         return -ENODATA;
     }
+    /*--- printk(KERN_ERR"%s: id=%d map_idx=%x %s f:_flags=%x\n", __func__, id, map_idx, crashreport ? "cr" : "sd", file->f_flags); ---*/
+    if(file->f_flags & O_WRONLY) {
+		unsigned int mapvalue;
+	    mapvalue  = crashreport ? READ_BY_CR : READ_BY_SD;
+		mapvalue |= map_idx << 8;
+		file->private_data = (void *)mapvalue;
+		return 0;
+	}
+    memset(saved_checksum, 0, sizeof(saved_checksum));
 	buf = kmalloc(len, GFP_KERNEL);
     if(buf == NULL) {
 		return -ENOMEM;
@@ -369,53 +460,60 @@
     len = sizeof(crashenv);
     crashenv[0] = 0;
     if(TFFS_Read(NULL, FLASH_FS_CRASH, crashenv, &len) == 0) {
-        timestart = parse_crash_env(crashenv, &saved_checksum[0], &tffs_once_cr);
-        strncpy(timebuf, timestart, sizeof(timebuf) - 1);
-        timestart = timebuf;
-        /*--- printk(KERN_ERR"%s: cs[]=%x %x %x %x readonce=%x\n(%s)", __func__, saved_checksum[0], saved_checksum[1], saved_checksum[2], saved_checksum[3], tffs_once_cr, crashenv); ---*/
+        parse_crash_env(crashenv, &saved_checksum[0]);
     }
     buf[0] = 0;
     if((len = tffs_panic_log_read(buf, buf_len, id)) > 0) {
         unsigned int new_sum = calc_sum_and_correct(buf, len, 1);
         /*--- printk(KERN_INFO"%s: sum=%x len=%d\n", __func__, new_sum, len); ---*/
-        if(new_sum != saved_checksum[map_idx]) {
-            /*--- new panic-log: clear counter ---*/
-            tffs_once_cr &= ~(1 << map_idx);
-            timestart = time_to_ascii(timebuf, sizeof(timebuf), crashreport ? "by crash report" : "by support data");
-            saved_checksum[map_idx] = new_sum;
+        if(new_sum != saved_checksum[map_idx].cs) {
+            /*--- new panic-log: set struct ---*/
+			new_read_mask					 = crashreport ? READ_BY_CR : (READ_BY_SD | FIRST_READ_BY_SD);
+			saved_checksum[map_idx].readmask = 0;
+			saved_checksum[map_idx].ts		 = get_act_time();
+            saved_checksum[map_idx].cs		 = new_sum;
+        } else {
+			new_read_mask					 = crashreport ? READ_BY_CR : READ_BY_SD;
         }
     } else {
         len = 0;
     }
-#if defined(CONFIG_MACH_AR934x)
+#if defined(CONFIG_MACH_AR934x) || defined(CONFIG_MACH_QCA953x)
     if(id == FLASH_FS_ID_PANIC_LOG) {
         unsigned int sram_len = ath_restore_log_from_ram(buf, buf_len);
         if(sram_len) {
             unsigned int new_sram_sum;
-            if(crashreport) tffs_once_cr |= (1 << map_idx); /*--- mark flashfile as readed ... ---*/
             map_idx = 1;
             /*--- ... and prefer sram-log---*/
             len = sram_len;
             new_sram_sum = calc_sum_and_correct(buf, len, 1);
             /*--- printk(KERN_INFO"%s: prefer sram-trace len=%d", __func__, sram_len); ---*/
-            if(new_sram_sum != saved_checksum[map_idx]) {
+            if(new_sram_sum != saved_checksum[map_idx].cs) {
                 struct timeval now;
                 /*--- new sram-panic-log: clear counter ---*/
-                tffs_once_cr &= ~(1 << map_idx);
-                timestart = time_to_ascii(timebuf, sizeof(timebuf), crashreport ? "by crash report" : "by support data");
-                saved_checksum[map_idx] = new_sram_sum;
+				new_read_mask					 = crashreport ? READ_BY_CR : (READ_BY_SD | FIRST_READ_BY_SD);
+				saved_checksum[map_idx].readmask = 0;
+				saved_checksum[map_idx].ts		 = get_act_time();
+                saved_checksum[map_idx].cs		 = new_sram_sum;
+            } else {
+				new_read_mask					 = crashreport ? READ_BY_CR : READ_BY_SD;
             }
         }
     }
 #endif/*--- #if defined(CONFIG_MACH_AR934x) ---*/
-    if((len == 0) || (crashreport && (tffs_once_cr & (1 << map_idx)))) {
+    if((len == 0) || (((saved_checksum[map_idx].readmask & new_read_mask) == new_read_mask) &&
+					  !((log_read_multiple[map_idx] & new_read_mask) == new_read_mask)
+				)) {
         /*--- check if sent ---*/
         kfree(buf);
         return -ENODATA;
     }
-    if(crashreport) tffs_once_cr |= (1 << map_idx);
+	saved_checksum[map_idx].readmask |= new_read_mask;
+	if(saved_checksum[map_idx].ts){
+		timestart = time_to_ascii(saved_checksum[map_idx].ts, timebuf, sizeof(timebuf), (saved_checksum[map_idx].readmask & FIRST_READ_BY_SD) ? "by support data" : "by crash report");
+	}
     sprintf(&buf[len], "-----\n(first) sent on: %s\n", timestart);
-    set_crash_env(crashenv, sizeof(crashenv), saved_checksum, tffs_once_cr, timestart);
+    set_crash_env(crashenv, sizeof(crashenv), saved_checksum);
     TFFS_Write(NULL, FLASH_FS_CRASH, crashenv, strlen(crashenv) + 1, 0);
 
     return single_open(file, paniclog_show, buf);
@@ -440,27 +538,70 @@
 
 /*--------------------------------------------------------------------------------*\
 \*--------------------------------------------------------------------------------*/
+static ssize_t log_proc_write(struct file *file, const char *buffer, size_t count, loff_t *offset __maybe_unused) {
+    unsigned char procfs_buffer[64];
+    size_t procfs_buffer_size;
+	unsigned int id, report;
+
+	/*--- von wo kommen wir: ---*/
+	id	   = ((unsigned int) file->private_data) >> 8;
+	report = ((unsigned int)file->private_data)  & 0xFF;
+	if(id >= MAX_LOG_IDS) {
+		return count;
+	}
+    if (count >= sizeof(procfs_buffer)) {
+       procfs_buffer_size = sizeof(procfs_buffer) - 1;
+    } else {
+       procfs_buffer_size = count;
+    }
+    /* write data to the buffer */
+    if ( copy_from_user(procfs_buffer, buffer, procfs_buffer_size - 1) ) {
+        return -EFAULT;
+    }
+    procfs_buffer[procfs_buffer_size] = 0;
+	if(strstr(procfs_buffer, "readmultiple")) {
+		log_read_multiple[id] |= report;
+	} else if(strstr(procfs_buffer, "readonce")) {
+		log_read_multiple[id] &= ~report;
+	} else {
+		printk(KERN_INFO"unknown option: use readmultiple or readonce\n");
+	}
+	/*--- 	printk(KERN_INFO"%s: '%s' %p log_read_multiple[%d]=%x (report=%x)\n", __func__, procfs_buffer, file->private_data, id, log_read_multiple[id], report); ---*/
+    return count;
+}
+/*--------------------------------------------------------------------------------*\
+\*--------------------------------------------------------------------------------*/
+static int log_proc_release(struct inode *inode, struct file *file) {
+    if(!(file->f_flags & O_WRONLY)) {
+		/*--- printk(KERN_INFO"%s: free after read\n", __func__); ---*/
+		return seq_release_private(inode, file); /*---  gibt txtbuf frei ----*/
+	}
+	/*--- 	printk(KERN_INFO"%s no free\n", __func__); ---*/
+	return 0;
+}
+/*--------------------------------------------------------------------------------*\
+\*--------------------------------------------------------------------------------*/
 static struct _logproc {
     const char *dir;
     const char *name;
     struct file_operations fops;
     struct proc_dir_entry *dir_entry;
 } logproc[] = {
-    { dir: "avm/log_cr", name: "panic",  fops: {open: paniclog_open_cr,  read: seq_read, llseek: seq_lseek, release: seq_release_private /*--- gibt txtbuf frei ---*/}}, 
-    { dir: "avm/log_cr", name: "crash",  fops: {open: crashlog_open_cr,  read: seq_read, llseek: seq_lseek, release: seq_release_private /*--- gibt txtbuf frei ---*/}}, 
+    { dir: "avm/log_cr", name: "panic",  fops: {open: paniclog_open_cr, write: log_proc_write, read: seq_read, llseek: seq_lseek, release: log_proc_release }}, 
+    { dir: "avm/log_cr", name: "crash",  fops: {open: crashlog_open_cr, write: log_proc_write, read: seq_read, llseek: seq_lseek, release: log_proc_release }}, 
 #if defined(CRASHPANIC_LOG_PER_REMOTE_EVENT_SINK)
-    { dir: "avm/log_cr", name: "panic2", fops: {open: panic2log_open_cr, read: seq_read, llseek: seq_lseek, release: seq_release_private /*--- gibt txtbuf frei ---*/}},
-    { dir: "avm/log_cr", name: "crash2", fops: {open: crash2log_open_cr, read: seq_read, llseek: seq_lseek, release: seq_release_private /*--- gibt txtbuf frei ---*/}}, 
+    { dir: "avm/log_cr", name: "panic2", fops: {open: panic2log_open_cr,write: log_proc_write, read: seq_read, llseek: seq_lseek, release: log_proc_release }},
+    { dir: "avm/log_cr", name: "crash2", fops: {open: crash2log_open_cr,write: log_proc_write, read: seq_read, llseek: seq_lseek, release: log_proc_release }}, 
 #endif/*--- #if defined(CRASHPANIC_LOG_PER_REMOTE_EVENT_SINK) ---*/
-    { dir: "avm/log_sd", name: "panic",  fops: {open: paniclog_open_sd,  read: seq_read, llseek: seq_lseek, release: seq_release_private /*--- gibt txtbuf frei ---*/}}, 
-    { dir: "avm/log_sd", name: "crash",  fops: {open: crashlog_open_sd,  read: seq_read, llseek: seq_lseek, release: seq_release_private /*--- gibt txtbuf frei ---*/}}, 
+    { dir: "avm/log_sd", name: "panic",  fops: {open: paniclog_open_sd, write: log_proc_write, read: seq_read, llseek: seq_lseek, release: log_proc_release }}, 
+    { dir: "avm/log_sd", name: "crash",  fops: {open: crashlog_open_sd, write: log_proc_write, read: seq_read, llseek: seq_lseek, release: log_proc_release }}, 
 #if defined(CRASHPANIC_LOG_PER_REMOTE_EVENT_SINK)
-    { dir: "avm/log_sd", name: "panic2", fops: {open: panic2log_open_sd, read: seq_read, llseek: seq_lseek, release: seq_release_private /*--- gibt txtbuf frei ---*/}}, 
-    { dir: "avm/log_sd", name: "crash2", fops: {open: crash2log_open_sd, read: seq_read, llseek: seq_lseek, release: seq_release_private /*--- gibt txtbuf frei ---*/}},
+    { dir: "avm/log_sd", name: "panic2", fops: {open: panic2log_open_sd, write: log_proc_write, read: seq_read, llseek: seq_lseek, release: log_proc_release }}, 
+    { dir: "avm/log_sd", name: "crash2", fops: {open: crash2log_open_sd, write: log_proc_write, read: seq_read, llseek: seq_lseek, release: log_proc_release }},
 #endif/*--- #if defined(CRASHPANIC_LOG_PER_REMOTE_EVENT_SINK) ---*/
     /*--- compatible to the "old" solution: ---*/
-    { dir: NULL, name: "avm_panic_cr",  fops: {open: paniclog_open_cr,  read: seq_read, llseek: seq_lseek, release: seq_release_private /*--- gibt txtbuf frei ---*/}}, 
-    { dir: NULL, name: "avm_panic_sd",  fops: {open: paniclog_open_sd,  read: seq_read, llseek: seq_lseek, release: seq_release_private /*--- gibt txtbuf frei ---*/}}, 
+    { dir: NULL, name: "avm_panic_cr",  fops: {open: paniclog_open_cr,  write: log_proc_write, read: seq_read, llseek: seq_lseek, release: seq_release_private /*--- gibt txtbuf frei ---*/}}, 
+    { dir: NULL, name: "avm_panic_sd",  fops: {open: paniclog_open_sd,  write: log_proc_write, read: seq_read, llseek: seq_lseek, release: seq_release_private /*--- gibt txtbuf frei ---*/}}, 
 };
 /*--------------------------------------------------------------------------------*\
 \*--------------------------------------------------------------------------------*/
@@ -480,12 +621,12 @@
         }
 #if !defined(CRASHPANIC_LOG_PER_REMOTE_EVENT_SOURCE)
         if(logproc[i].dir == NULL) {
-            if(!proc_create(logproc[i].name, 0444, NULL, &logproc[i].fops)) {
+            if(!proc_create(logproc[i].name, 0666, NULL, &logproc[i].fops)) {
                 printk(KERN_ERR"%s can't proc_create(%s)\n", __func__, logproc[i].name);
             }
         } else if(dir_entry) {
             logproc[i].dir_entry = dir_entry;
-            if(!proc_create(logproc[i].name, 0444, dir_entry, &logproc[i].fops)) {
+            if(!proc_create(logproc[i].name, 0666, dir_entry, &logproc[i].fops)) {
                 printk(KERN_ERR"%s can't proc_create(%s)\n", __func__, logproc[i].name);
             }
         }
--- linux-2.6.32/drivers/mtd/nand/ifxmips_mtd_dmanand.c
+++ linux-2.6.32/drivers/mtd/nand/ifxmips_mtd_dmanand.c
@@ -40,7 +40,6 @@
 #include <linux/smp_lock.h>
 #include <asm/io.h>
 #include <asm/system.h>
-#include <asm/prom.h>
 
 /* Project header */
 #include <ifx_types.h>
@@ -106,6 +105,7 @@
 /* HSNAND private structure */
 struct hsnand_info {
     enum chip_ecc       ecc_error;
+    enum chip_hwecc     enable_hwecc;
 #if defined(CONFIG_AR10)
     unsigned int        current_page;
     unsigned int        ndac_ctl_1;
@@ -115,7 +115,6 @@
     unsigned char       *tmp_buffer;
     wait_queue_head_t   hsnand_wait;
     volatile long       wait_flag;
-    enum chip_ecc (*read_eccstatus)(struct mtd_info *mtd, unsigned int command);
 };
 
 struct hsnand_info hsnand_dev;
@@ -166,24 +165,25 @@
 void debug_nand(void) {   
 
     printk("\n**** Dumping HSNAND/EBU Registers *****\n");
-    printk("EBU_CLC:        0x%08x\n", IFX_REG_R32(IFX_EBU_CLC));
-    printk("IEN_ECC:        0x%08x\n", IFX_REG_R32(IFX_EBU_ECC_IEN));
-    printk("ECC CR:         0x%08x\n", IFX_REG_R32(IFX_EBU_NAND_ECC_CR));
-    printk("ECC0:           0x%08x\n", IFX_REG_R32(IFX_EBU_NAND_ECC0));
-    printk("EBU CON:        0x%08x\n", IFX_REG_R32(IFX_EBU_CON));
-    printk("ADDRSEL1:       0x%08x\n", IFX_REG_R32(IFX_EBU_ADDSEL1));
-    printk("EBU_NAND_CON:   0x%08x\n", IFX_REG_R32(IFX_EBU_NAND_CON));
-    printk("EBU_BUSCON:     0x%08x\n", IFX_REG_R32(IFX_EBU_BUSCON1));
-    printk("CS_BASE_A:      0x%08x\n", IFX_REG_R32(IFX_CS_BASE_A));
-    printk("HSNAND_DEV:     0x%08x\n", IFX_REG_R32(IFX_NAND_INFO));
-    printk("NDAC_CTL1:      0x%08x\n", IFX_REG_R32(IFX_NDAC_CTL1));
-    printk("NDAC_CTL2:      0x%08x\n", IFX_REG_R32(IFX_NDAC_CTL2));
-    printk("HSMD_CTL:       0x%08x\n", IFX_REG_R32(IFX_HSMD_CTRL));
-    printk("RX_CNT:         0x%08x\n", IFX_REG_R32(IFX_RX_CNT));
-    printk("INTR_MSK_CTRL:  0x%08x\n",IFX_REG_R32(IFX_HSNAND_INTR_MASK_CTRL));
-    printk("INTR_STAT:      0x%08x\n", IFX_REG_R32(IFX_HSNAND_INTR_STAT));
-    printk("RX_CNT:         0x%08x\n", IFX_REG_R32(IFX_RX_CNT));
-    printk("DX_PLUS:        0x%08x\n", IFX_REG_R32(IFX_DPLUS_CTRL));
+    printk("EBU_CLC:   	  0x%08x\n", IFX_REG_R32(IFX_EBU_CLC));
+    printk("IEN_ECC:      0x%08x\n", IFX_REG_R32(IFX_EBU_ECC_IEN));
+    printk("EBU CON:	  0x%08x\n", IFX_REG_R32(IFX_EBU_CON));
+    printk("ADDRSEL1:     0x%08x\n", IFX_REG_R32(IFX_EBU_ADDSEL1));
+    printk("EBU_NAND_CON: 0x%08x\n", IFX_REG_R32(IFX_EBU_NAND_CON));
+    printk("EBU_BUSCON:   0x%08x\n", IFX_REG_R32(IFX_EBU_BUSCON1));
+    printk("CS_BASE_A:    0x%08x\n", IFX_REG_R32(IFX_CS_BASE_A));
+    printk("HSNAND_DEV:	  0x%08x\n", IFX_REG_R32(IFX_NAND_INFO));
+    printk("NDAC_CTL1: 	  0x%08x\n", IFX_REG_R32(IFX_NDAC_CTL1));
+    printk("NDAC_CTL2: 	  0x%08x\n", IFX_REG_R32(IFX_NDAC_CTL2));
+    printk("HSMD_CTL:  	  0x%08x\n", IFX_REG_R32(IFX_HSMD_CTRL));
+    printk("RX_CNT:    	  0x%08x\n", IFX_REG_R32(IFX_RX_CNT));
+    printk("NAND_ECC_CR:  0x%08x\n", IFX_REG_R32(IFX_EBU_NAND_ECC_CR));
+    printk("INTR_MSK_CTRL: 0x%08x\n",IFX_REG_R32(IFX_HSNAND_INTR_MASK_CTRL));
+    printk("INTR_STAT: 	  0x%08x\n", IFX_REG_R32(IFX_HSNAND_INTR_STAT));
+    printk("ECC CR:	  0x%08x\n", IFX_REG_R32(IFX_EBU_NAND_ECC_CR));
+    printk("ECC0 :	  0x%08x\n", IFX_REG_R32(IFX_EBU_NAND_ECC0));
+    printk("RX_CNT:	  0x%08x\n", IFX_REG_R32(IFX_RX_CNT));
+    printk("DX_PLUS:	  0x%08x\n", IFX_REG_R32(IFX_DPLUS_CTRL));
 }
 
 void debug_dma(int channel)
@@ -221,7 +221,11 @@
 
 /*------------------------------------------------------------------------------------------*\
 \*------------------------------------------------------------------------------------------*/
-static void ifx_hsnand_setup_chipecc(enum chip_hwecc status) {
+static void ifx_hsnand_setup_hwecc(enum chip_hwecc status) {
+
+    struct hsnand_info *hsnand = &hsnand_dev;
+
+    hsnand->enable_hwecc = status;
 
     RESET_CHIP();
 
@@ -236,92 +240,6 @@
 }
 
 /*------------------------------------------------------------------------------------------*\
-\*------------------------------------------------------------------------------------------*/
-static void ifx_hsnand_hwctl(struct mtd_info *mtd, int mode) {
-
-#if 0
-    unsigned int reg, ecc_status;
-
-    *IFX_EBU_NAND_ECC0 = 0;
-
-    reg = SM(IFX_EBU_ECC_IEN_ENABLE, IFX_EBU_ECC_IEN_IR);
-    IFX_REG_W32(reg | IFX_REG_R32(IFX_EBU_ECC_IEN), IFX_EBU_ECC_IEN);
-    *IFX_EBU_NAND_CON |= IFX_EBU_NAND_CON_ECC;
-    *IFX_RX_CNT = 0;
-    reg = SM(IFX_EBU_NAND_ECC_CRM_ENABLE, IFX_EBU_NAND_ECC_CRM) |
-          SM(IFX_EBU_NAND_ECC_PAGE_512, IFX_EBU_NAND_ECC_PAGE);
-    IFX_REG_W32(reg, IFX_EBU_NAND_ECC_CR);
-
-    debug_nand();
-#endif
-} 
-
-/*------------------------------------------------------------------------------------------*\
-\*------------------------------------------------------------------------------------------*/
-static enum chip_ecc ifx_hsnand_read_eccstatus(struct mtd_info *mtd, unsigned int command) {
-
-    unsigned int status;
-    register struct nand_chip *chip = mtd->priv;
-
-    chip->cmd_ctrl(mtd, NAND_CMD_STATUS, NAND_CLE | NAND_CTRL_CHANGE);
-    status = chip->read_byte(mtd);
-    chip->cmd_ctrl(mtd, command, NAND_NCE | NAND_CLE | NAND_CTRL_CHANGE);
-    chip->cmd_ctrl(mtd, NAND_CMD_NONE, NAND_NCE | NAND_CTRL_CHANGE);
-
-    if(status & NAND_STATUS_FAIL) {
-        return uncorrectable;
-    }
-    if(status & NAND_STATUS_CRITICAL_BLOCK) {
-        return correctable;
-    }
-    return no_error;
-}
-
-/*------------------------------------------------------------------------------------------*\
- * Toshiba ECC-Status
- * | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
- * | Sector - info | Errors        |
-\*------------------------------------------------------------------------------------------*/
-static enum chip_ecc ifx_hsnand_toshiba_read_eccstatus(struct mtd_info *mtd, unsigned int command) {
-
-    unsigned int i, status, eccstatus;
-    register struct nand_chip *chip = mtd->priv;
-    enum chip_ecc chip_ecc_status = no_error;
-
-    chip->cmd_ctrl(mtd, NAND_CMD_STATUS, NAND_CLE | NAND_CTRL_CHANGE);
-    status = chip->read_byte(mtd);
-
-    if (status & NAND_STATUS_CRITICAL_BLOCK) {
-        printk(KERN_ERR "{%s} status 0x%x ecc.steps %d\n", __func__, status, chip->ecc.steps);
-
-        chip->cmd_ctrl(mtd, NAND_CMD_ECCSTATUS, NAND_CLE | NAND_CTRL_CHANGE);
-
-        /*-------------------------------------------------------------*\
-         * die FLASH-interne ECC wird für je 512 Byte berechnet,
-         * wir schreiben aber eine 1Bit ECC für 256 Bytes
-        \*-------------------------------------------------------------*/
-        for (i = 0; i < (chip->ecc.steps >> 1); i++) {
-            eccstatus = chip->read_byte(mtd);
-            printk(KERN_ERR "{%s} Sector %d eccstatus 0x%x\n", __func__, i, eccstatus);
-
-            if ((eccstatus & 0xFF) < 7) {
-                chip_ecc_status = correctable;
-            }
-        }
-    }
-
-    if (status & NAND_STATUS_FAIL) {
-        printk(KERN_ERR "{%s} status 0x%x\n", __func__, status);
-        chip_ecc_status = uncorrectable;
-    }
-
-    chip->cmd_ctrl(mtd, command, NAND_NCE | NAND_CLE | NAND_CTRL_CHANGE);
-    chip->cmd_ctrl(mtd, NAND_CMD_NONE, NAND_NCE | NAND_CTRL_CHANGE);
-
-    return chip_ecc_status;
-}
-
-/*------------------------------------------------------------------------------------------*\
  * fn static void ifx_hsnand_write_page_raw(struct mtd_info *mtd, struct nand_chip *chip, const u8 *buf)
  * ingroup  IFX_HSNAND_DRV
  * brief write page with hardware ECC checking mechanism
@@ -332,13 +250,7 @@
 \*------------------------------------------------------------------------------------------*/
 static void ifx_hsnand_write_page_raw(struct mtd_info *mtd, struct nand_chip *chip, const u8 *buf)
 {
-
-    if (mtd->writesize == 4096) {           /*--- der VR9 kann keine 4k Pages schreiben ---*/
-        chip->write_buf(mtd, buf, 2048);
-        chip->write_buf(mtd, &buf[2048], 2048);
-    } else 
-        chip->write_buf(mtd, buf, mtd->writesize);
-
+    chip->write_buf(mtd, buf, mtd->writesize);
 	chip->write_buf(mtd, chip->oob_poi, mtd->oobsize);
     return;
 }
@@ -384,11 +296,12 @@
 }
 
 /*------------------------------------------------------------------------------------------*\
- * read page with internal micron-nandchip ecc
 \*------------------------------------------------------------------------------------------*/
-static int ifx_hsnand_micron_read_page_hwecc(struct mtd_info *mtd, struct nand_chip *chip, uint8_t *buf, int page)
+static int ifx_hsnand_read_page_hwecc(struct mtd_info *mtd, struct nand_chip *chip, uint8_t *buf, int page)
 {
     struct hsnand_info *hsnand = &hsnand_dev;
+    unsigned int eccbytes = (1<<9);
+    unsigned int eccsteps = chip->ecc.size / eccbytes;
     unsigned int i, biterror, biterror_oob, biterror_oob_ecc;
     unsigned int oob_offset, oob_len;
 
@@ -401,7 +314,7 @@
 
     switch (hsnand->ecc_error) {
         case correctable:
-            ifx_hsnand_setup_chipecc(chip_disable_hwecc);     /*--- noch mal lesen ohne HWECC ---*/
+            ifx_hsnand_setup_hwecc(chip_disable_hwecc);     /*--- noch mal lesen ohne HWECC ---*/
 
 #if defined(CONFIG_VR9)
             chip->cmdfunc(mtd, NAND_CMD_READ0, 0, page);
@@ -413,11 +326,11 @@
             chip->ecc.read_oob(mtd, chip, page, 1);
 #endif
 
-            ifx_hsnand_setup_chipecc(chip_enable_hwecc);
+            ifx_hsnand_setup_hwecc(chip_enable_hwecc);
 
-            for (i = 0; i < chip->ecc.steps; i++) {
+            for (i = 0; i < eccsteps; i++) {
 
-                biterror = ifx_hsnand_verify_hwecc(&buf[i * chip->ecc.size], &hsnand->hwecc_buffer[i * chip->ecc.size], chip->ecc.size);
+                biterror = ifx_hsnand_verify_hwecc(&buf[i * eccbytes], &hsnand->hwecc_buffer[i * eccbytes], eccbytes);
 #if 1
                 oob_offset = chip->ecc.layout->oobfree[i].offset;
                 oob_len = chip->ecc.layout->oobfree[i].length;
@@ -456,37 +369,6 @@
 
 /*------------------------------------------------------------------------------------------*\
 \*------------------------------------------------------------------------------------------*/
-static int ifx_hsnand_toshiba_read_page_hwecc(struct mtd_info *mtd, struct nand_chip *chip, uint8_t *buf, int page)
-{
-    struct hsnand_info *hsnand = &hsnand_dev;
-
-    if (mtd->writesize == 4096) {           /*--- der VR9 kann keine 4k Pages schreiben ---*/
-        chip->read_buf(mtd, buf, 2048);
-        chip->read_buf(mtd, &buf[2048], 2048);
-    } else 
-        chip->read_buf(mtd, buf, mtd->writesize);
-#if defined(CONFIG_VR9)
-	chip->read_buf(mtd, chip->oob_poi, mtd->oobsize);
-#else
-    chip->ecc.read_oob(mtd, chip, page, 1);
-#endif
-
-    switch (hsnand->ecc_error) {
-        case correctable:
-            mtd->ecc_stats.corrected++;
-            break;
-        case uncorrectable:
-            mtd->ecc_stats.failed++;
-            break;
-        case no_error:
-            break;
-    }
-
-	return 0;
-}
-
-/*------------------------------------------------------------------------------------------*\
-\*------------------------------------------------------------------------------------------*/
 static int ifx_hsnand_write_page(struct mtd_info *mtd, struct nand_chip *chip, const uint8_t *buf, int page, int cached __attribute__((unused)), int raw)
 {
 	int status;
@@ -540,7 +422,7 @@
                 break;
             case correctable:
                 printk(KERN_ERR "VERIFY-ERROR on page: %d: rewrite also results in a correctable error\n", page);
-                chip->ecc.read_page_raw(mtd, chip, hsnand->tmp_buffer, page);   /*--- ifx_hsnand_read_page_hwecc(mtd, chip, hsnand->tmp_buffer, page); ---*/
+                ifx_hsnand_read_page_hwecc(mtd, chip, hsnand->tmp_buffer, page);
                 if(mtd->ecc_stats.failed - stats.failed) {
                     printk(KERN_ERR "VERIFY-ERROR on page: %d: too many biterrors\n", page);
                     return -EIO;
@@ -1000,17 +882,26 @@
         case NAND_CMD_READ0:
         case NAND_CMD_READ1:
             {
+                unsigned int status;
                 struct hsnand_info *hsnand = &hsnand_dev;
                 
-                if (hsnand->read_eccstatus)
-                    hsnand->ecc_error = hsnand->read_eccstatus(mtd, command);
-                else
-                    hsnand->ecc_error = no_error;
+                hsnand->ecc_error = no_error;
+                if (likely(hsnand->enable_hwecc == chip_enable_hwecc)) {
 
-                if (hsnand->ecc_error == uncorrectable)
-                    printk(KERN_ERR "[%s] read block failed (column: 0x%x page: 0x%x)\n", __func__, column, page_addr);
-                if (hsnand->ecc_error == correctable)
-                    printk(KERN_ERR "[%s] read block is critical (column: 0x%x page: 0x%x)\n", __func__, column, page_addr);
+                    chip->cmd_ctrl(mtd, NAND_CMD_STATUS, NAND_CLE | NAND_CTRL_CHANGE);
+                    status = chip->read_byte(mtd);
+                    chip->cmd_ctrl(mtd, command, NAND_NCE | NAND_CLE | NAND_CTRL_CHANGE);
+                    chip->cmd_ctrl(mtd, NAND_CMD_NONE, NAND_NCE | NAND_CTRL_CHANGE);
+
+                    if(status & NAND_STATUS_FAIL) {
+                        printk(KERN_ERR "[%s] read block failed (status: 0x%x, column: 0x%x page: 0x%x)\n", __func__, status, column, page_addr);
+                        hsnand->ecc_error = uncorrectable;
+                    }
+                    if(status & NAND_STATUS_CRITICAL_BLOCK) {
+                        printk(KERN_ERR "[%s] read block is critical (status: 0x%x, column: 0x%x page: 0x%x)\n", __func__, status, column, page_addr);
+                        hsnand->ecc_error = correctable;
+                    }
+                }
             }
             break;
 
@@ -1091,7 +982,7 @@
 
 /*------------------------------------------------------------------------------------------*\
 \*------------------------------------------------------------------------------------------*/
-void ifx_hsnand_chip_init(unsigned int chipselect) {
+void ifx_hsnand_chip_init(void) {
 
     u32 reg;
     
@@ -1139,68 +1030,66 @@
 #endif
 #endif /*--- #if !defined(CONFIG_AR10) ---*/
 
-    if (chipselect) {
-        reg = (NAND_BASE_ADDRESS & 0x1fffff00)| IFX_EBU_ADDSEL1_MASK(2)| IFX_EBU_ADDSEL1_REGEN;
-        IFX_REG_W32(reg, IFX_EBU_ADDSEL1);
-
-        reg = IFX_EBU_BUSCON1_SETUP | 
-              SM(IFX_EBU_BUSCON1_ALEC3,IFX_EBU_BUSCON1_ALEC) |
-              SM(IFX_EBU_BUSCON1_BCGEN_RES,IFX_EBU_BUSCON1_BCGEN) |
-              SM(IFX_EBU_BUSCON1_WAITWRC2,IFX_EBU_BUSCON1_WAITWRC) |
-              SM(IFX_EBU_BUSCON1_WAITRDC2,IFX_EBU_BUSCON1_WAITRDC) |
-              SM(IFX_EBU_BUSCON1_HOLDC1,IFX_EBU_BUSCON1_HOLDC) |
-              SM(IFX_EBU_BUSCON1_RECOVC1,IFX_EBU_BUSCON1_RECOVC) |
-              SM(IFX_EBU_BUSCON1_CMULT4,IFX_EBU_BUSCON1_CMULT);
-        IFX_REG_W32(reg, IFX_EBU_BUSCON1);
+#if defined(CONFIG_NAND_CS1)
+    reg = (NAND_BASE_ADDRESS & 0x1fffff00)| IFX_EBU_ADDSEL1_MASK(2)| IFX_EBU_ADDSEL1_REGEN;
+    IFX_REG_W32(~IFX_EBU_ADDSEL1_REGEN, IFX_EBU_ADDSEL0);
+    IFX_REG_W32(reg, IFX_EBU_ADDSEL1);
+    reg = IFX_EBU_BUSCON1_SETUP | 
+          SM(IFX_EBU_BUSCON1_ALEC3,IFX_EBU_BUSCON1_ALEC) |
+          SM(IFX_EBU_BUSCON1_BCGEN_RES,IFX_EBU_BUSCON1_BCGEN) |
+          SM(IFX_EBU_BUSCON1_WAITWRC2,IFX_EBU_BUSCON1_WAITWRC) |
+          SM(IFX_EBU_BUSCON1_WAITRDC2,IFX_EBU_BUSCON1_WAITRDC) |
+          SM(IFX_EBU_BUSCON1_HOLDC1,IFX_EBU_BUSCON1_HOLDC) |
+          SM(IFX_EBU_BUSCON1_RECOVC1,IFX_EBU_BUSCON1_RECOVC) |
+          SM(IFX_EBU_BUSCON1_CMULT4,IFX_EBU_BUSCON1_CMULT);
+    IFX_REG_W32(reg, IFX_EBU_BUSCON1);
 
-        reg = SM(IFX_EBU_NAND_CON_NANDM_ENABLE, IFX_EBU_NAND_CON_NANDM) |
-              SM(IFX_EBU_NAND_CON_CSMUX_E_ENABLE,IFX_EBU_NAND_CON_CSMUX_E) |
-              SM(IFX_EBU_NAND_CON_CS_P_LOW,IFX_EBU_NAND_CON_CS_P) |
-              SM(IFX_EBU_NAND_CON_SE_P_LOW,IFX_EBU_NAND_CON_SE_P) |
-              SM(IFX_EBU_NAND_CON_WP_P_LOW,IFX_EBU_NAND_CON_WP_P) |
-              SM(IFX_EBU_NAND_CON_PRE_P_LOW,IFX_EBU_NAND_CON_PRE_P) |
-              SM(IFX_EBU_NAND_CON_IN_CS1,IFX_EBU_NAND_CON_IN_CS) |
-              SM(IFX_EBU_NAND_CON_OUT_CS1,IFX_EBU_NAND_CON_OUT_CS) |
-              SM(IFX_EBU_NAND_CON_ECC_ON,IFX_EBU_NAND_CON_ECC);
-        IFX_REG_W32(reg,IFX_EBU_NAND_CON);         
+    reg = SM(IFX_EBU_NAND_CON_NANDM_ENABLE, IFX_EBU_NAND_CON_NANDM) |
+          SM(IFX_EBU_NAND_CON_CSMUX_E_ENABLE,IFX_EBU_NAND_CON_CSMUX_E) |
+          SM(IFX_EBU_NAND_CON_CS_P_LOW,IFX_EBU_NAND_CON_CS_P) |
+          SM(IFX_EBU_NAND_CON_SE_P_LOW,IFX_EBU_NAND_CON_SE_P) |
+          SM(IFX_EBU_NAND_CON_WP_P_LOW,IFX_EBU_NAND_CON_WP_P) |
+          SM(IFX_EBU_NAND_CON_PRE_P_LOW,IFX_EBU_NAND_CON_PRE_P) |
+          SM(IFX_EBU_NAND_CON_IN_CS1,IFX_EBU_NAND_CON_IN_CS) |
+          SM(IFX_EBU_NAND_CON_OUT_CS1,IFX_EBU_NAND_CON_OUT_CS);
+    IFX_REG_W32(reg,IFX_EBU_NAND_CON);         
 
 #if defined(CONFIG_VR9)
-        IFX_REG_W32(NAND_BASE_ADDRESS & 0x1fffffff, IFX_CS_BASE_A);
+    IFX_REG_W32(NAND_BASE_ADDRESS & 0x1fffffff, IFX_CS_BASE_A);
 
-        /*--- set DMA-Baseaddress - include Chip-Select ---*/ 
-        IFX_REG_W32((NAND_BASE_ADDRESS & 0x1fffffff) + NAND_CMD_CS, IFX_BASE_A);
+    /*--- set DMA-Baseaddress - include Chip-Select ---*/ 
+    IFX_REG_W32((NAND_BASE_ADDRESS & 0x1fffffff) + NAND_CMD_CS, IFX_BASE_A);
 #endif /*--- #if defined(CONFIG_VR9) ---*/
-    } else {
-        reg = (NAND_BASE_ADDRESS & 0x1fffff00)| IFX_EBU_ADDSEL0_MASK(3)| IFX_EBU_ADDSEL0_REGEN;
-        IFX_REG_W32(reg, IFX_EBU_ADDSEL0);
-
-        reg = IFX_EBU_BUSCON1_SETUP | 
-              SM( IFX_EBU_BUSCON1_ALEC3      ,IFX_EBU_BUSCON1_ALEC) |
-              SM( IFX_EBU_BUSCON1_BCGEN_RES  ,IFX_EBU_BUSCON1_BCGEN) |
-              SM( IFX_EBU_BUSCON1_WAITWRC2   ,IFX_EBU_BUSCON1_WAITWRC) |
-              SM( IFX_EBU_BUSCON1_WAITRDC2   ,IFX_EBU_BUSCON1_WAITRDC) |
-              SM( IFX_EBU_BUSCON1_HOLDC1     ,IFX_EBU_BUSCON1_HOLDC) |
-              SM( IFX_EBU_BUSCON1_RECOVC1    ,IFX_EBU_BUSCON1_RECOVC) |
-              SM( IFX_EBU_BUSCON1_CMULT4     ,IFX_EBU_BUSCON1_CMULT);
-        IFX_REG_W32(reg, IFX_EBU_BUSCON0);
+#else
+    reg = (NAND_BASE_ADDRESS & 0x1fffff00)| IFX_EBU_ADDSEL0_MASK(3)| IFX_EBU_ADDSEL0_REGEN;
+    IFX_REG_W32(reg, IFX_EBU_ADDSEL0);
+    reg = IFX_EBU_BUSCON1_SETUP | 
+          SM( IFX_EBU_BUSCON1_ALEC3      ,IFX_EBU_BUSCON1_ALEC) |
+          SM( IFX_EBU_BUSCON1_BCGEN_RES  ,IFX_EBU_BUSCON1_BCGEN) |
+          SM( IFX_EBU_BUSCON1_WAITWRC2   ,IFX_EBU_BUSCON1_WAITWRC) |
+          SM( IFX_EBU_BUSCON1_WAITRDC2   ,IFX_EBU_BUSCON1_WAITRDC) |
+          SM( IFX_EBU_BUSCON1_HOLDC1     ,IFX_EBU_BUSCON1_HOLDC) |
+          SM( IFX_EBU_BUSCON1_RECOVC1    ,IFX_EBU_BUSCON1_RECOVC) |
+          SM( IFX_EBU_BUSCON1_CMULT4     ,IFX_EBU_BUSCON1_CMULT);
+    IFX_REG_W32(reg, IFX_EBU_BUSCON0);
 
-        reg = SM( IFX_EBU_NAND_CON_NANDM_ENABLE     , IFX_EBU_NAND_CON_NANDM) |
-              SM( IFX_EBU_NAND_CON_CSMUX_E_ENABLE   ,IFX_EBU_NAND_CON_CSMUX_E) |
-              SM( IFX_EBU_NAND_CON_CS_P_LOW         ,IFX_EBU_NAND_CON_CS_P) |
-              SM( IFX_EBU_NAND_CON_SE_P_LOW         ,IFX_EBU_NAND_CON_SE_P) |
-              SM( IFX_EBU_NAND_CON_WP_P_LOW         ,IFX_EBU_NAND_CON_WP_P) |
-              SM( IFX_EBU_NAND_CON_PRE_P_LOW        ,IFX_EBU_NAND_CON_PRE_P) |
-              SM( IFX_EBU_NAND_CON_IN_CS0           ,IFX_EBU_NAND_CON_IN_CS) |
-              SM( IFX_EBU_NAND_CON_OUT_CS0          ,IFX_EBU_NAND_CON_OUT_CS);
-        IFX_REG_W32(reg,IFX_EBU_NAND_CON);         
+    reg = SM( IFX_EBU_NAND_CON_NANDM_ENABLE     , IFX_EBU_NAND_CON_NANDM) |
+          SM( IFX_EBU_NAND_CON_CSMUX_E_ENABLE   ,IFX_EBU_NAND_CON_CSMUX_E) |
+          SM( IFX_EBU_NAND_CON_CS_P_LOW         ,IFX_EBU_NAND_CON_CS_P) |
+          SM( IFX_EBU_NAND_CON_SE_P_LOW         ,IFX_EBU_NAND_CON_SE_P) |
+          SM( IFX_EBU_NAND_CON_WP_P_LOW         ,IFX_EBU_NAND_CON_WP_P) |
+          SM( IFX_EBU_NAND_CON_PRE_P_LOW        ,IFX_EBU_NAND_CON_PRE_P) |
+          SM( IFX_EBU_NAND_CON_IN_CS0           ,IFX_EBU_NAND_CON_IN_CS) |
+          SM( IFX_EBU_NAND_CON_OUT_CS0          ,IFX_EBU_NAND_CON_OUT_CS);
+    IFX_REG_W32(reg,IFX_EBU_NAND_CON);         
 
 #if defined(CONFIG_VR9)
-        IFX_REG_W32(NAND_BASE_ADDRESS & 0x1fffffff, IFX_CS_BASE_A);
+    IFX_REG_W32(NAND_BASE_ADDRESS & 0x1fffffff, IFX_CS_BASE_A);
 
-        /*--- set DMA-Baseaddress - include Chip-Select ---*/ 
-        IFX_REG_W32((NAND_BASE_ADDRESS & 0x1fffffff) + NAND_CMD_CS, IFX_BASE_A);
+    /*--- set DMA-Baseaddress - include Chip-Select ---*/ 
+    IFX_REG_W32((NAND_BASE_ADDRESS & 0x1fffffff) + NAND_CMD_CS, IFX_BASE_A);
 #endif /*--- #if defined(CONFIG_VR9) ---*/
-    }
+#endif
 
     mb();
 
@@ -1210,7 +1099,7 @@
 
 /*------------------------------------------------------------------------------------------*\
 \*------------------------------------------------------------------------------------------*/
-int ifx_nand_avm_check_for_hweccnand(struct nand_chip *this, unsigned int ChipID) {
+int ifx_nand_avm_check_for_hweccnand(struct nand_chip *this) {
 #define PRINT_TO_SCREEN(...)    printk(KERN_ERR "[NAND] "); printk(__VA_ARGS__); printk("\n")
 #define MAX_HWECC_TRIES         10
 
@@ -1221,21 +1110,34 @@
     // sonst
     //    SW-ECC vom NAND-Treiber
     unsigned char result = 0;
-    unsigned int manuf = (ChipID >> 8) & 0xFF;
-    unsigned int dev_id = ChipID & 0xFF;
+    unsigned char chip_maf_id;
+    unsigned char chip_dev_id;
+    unsigned char cellinfo, extid;
+
+    RESET_CHIP();
+
+    WRITE_NAND_COMMAND(0x90); // Read id
+    WRITE_NAND_ADDRESS(0x00);
+
+    chip_maf_id = READ_NAND();
+    chip_dev_id = READ_NAND();
 
                              /*---  MT29F1G08ABADA            MT29F4G08ABADA ---*/
-    if( (manuf == 0x2c) && ((dev_id == 0xf1) || (dev_id == 0xdc)) ) {    
+    if( (chip_maf_id == 0x2c) && ((chip_dev_id == 0xf1) || (chip_dev_id == 0xdc)) ) {    
         int no_tries = 0;
 
+        cellinfo = READ_NAND();
+        extid    = READ_NAND();
+
 try_again:
-        ifx_hsnand_setup_chipecc(chip_enable_hwecc);
+        ifx_hsnand_setup_hwecc(chip_enable_hwecc);
 
         // use getfeature to read result
         WRITE_NAND_COMMAND(0xEE); // getFeature
         WRITE_NAND_ADDRESS(0x90); // array operation mode
         while( ! NAND_READY);
-        result = READ_NAND();       // read 4 bytes...
+        // read 4 bytes...
+        result = READ_NAND();
 
 #if defined(DEBUG_HSNAND)
         PRINT_TO_SCREEN("read feature bytes (after setting hw ecc): P1=0x%02x|P2=0x%02x|P3=0x%02x|P4=0x%02x",
@@ -1256,8 +1158,12 @@
         }
 
         if(!result) {
+            struct hsnand_info *hsnand = &hsnand_dev;
+
             this->ecc.layout = &nand_oob_64_NANDwithHWEcc_FAILURE;
             
+            hsnand->enable_hwecc = CHIP_DISABLE_HW_ECC;
+
             PRINT_TO_SCREEN("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!");
             PRINT_TO_SCREEN("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!");
             PRINT_TO_SCREEN("!! MT29F1/MT29F4 erkannt, konnte aber den Hardware-ECC nicht aktivieren -> nutze SW-ECC !!");
@@ -1265,43 +1171,18 @@
             PRINT_TO_SCREEN("!!   -YAFFS wird trotzdem massenhaft Warnungen auswerfen -> ECC stimmt halt nicht       !!");
             PRINT_TO_SCREEN("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!");
             PRINT_TO_SCREEN("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!");
-            return 0;
+            return 1;
+        } else {
+            printk("[HSNAND] Hardware-ECC activated");
+            this->ecc.layout = &nand_oob_64_NANDwithHWEcc;
+            this->ecc.size = 1024 << (extid & 0x3);   /*--- die ecc.size muss gleich der mtd->write_size sein! ---*/
+            this->ecc.mode = NAND_ECC_HW;
         }
     } else {
-        return 0;
+        printk("[HSNAND] no Hardware-ECC found");
+        return 1;
     }
-    return 1;
-}
-
-static uint8_t scan_ff_pattern[] = { 0xff, 0xff };
-
-static struct nand_bbt_descr largepage_memorybased = {
-    .options = 0,
-    .offs = 0,
-    .len = 1,
-    .pattern = scan_ff_pattern
-};
-
-/*------------------------------------------------------------------------------------------*\
-\*------------------------------------------------------------------------------------------*/
-unsigned int getChipID(void) {
-
-    unsigned char maf_id, dev_id, part_spec, extid;
-
-    RESET_CHIP();
-
-    WRITE_NAND_COMMAND(0x90); // Read id
-    WRITE_NAND_ADDRESS(0x00);
-
-    maf_id      = READ_NAND();
-    dev_id      = READ_NAND();
-
-    part_spec   = READ_NAND();     /*--- not needed ---*/
-    extid       = READ_NAND();
-    part_spec   = READ_NAND();
-
-    /*--- printk("{%s} chip_id 0x%x maf_id 0x%x\n", __func__, dev_id, maf_id); ---*/
-    return (dev_id | (maf_id << 8) | (extid << 16) | (part_spec << 24));
+    return 0;
 }
 
 /*------------------------------------------------------------------------------------------*\
@@ -1316,7 +1197,6 @@
 {
     struct nand_chip *this;
     struct hsnand_info *hsnand = &hsnand_dev;
-    unsigned int i, ChipID;
     int err = 0;
 
     if(ifxmips_flashsize_nand == 0ULL) {
@@ -1324,24 +1204,7 @@
         return -ENXIO;
     }
 
-#if defined(CONFIG_VR9)
-    {    
-        unsigned int hwrev = 0;
-        char *s;
-
-        s = prom_getenv("HWRevision");
-        if (s) {
-            hwrev = simple_strtoul(s, NULL, 10);
-        } 
-
-        if (hwrev == 209)
-            ifx_hsnand_chip_init(1);
-        else
-            ifx_hsnand_chip_init(0);
-    }
-#else
-    ifx_hsnand_chip_init(1);
-#endif
+    ifx_hsnand_chip_init();
  
     ifx_hsnand_mtd = kmalloc(sizeof(struct mtd_info) + sizeof (struct nand_chip), GFP_KERNEL);
     if (!ifx_hsnand_mtd) {
@@ -1354,7 +1217,7 @@
     memset(ifx_hsnand_mtd, 0, sizeof(struct mtd_info));
     memset(this, 0, sizeof(struct nand_chip));
  
-    ifx_hsnand_mtd->name = kmalloc(16, GFP_KERNEL);
+    ifx_hsnand_mtd->name = (char *) kmalloc(16, GFP_KERNEL);
     if (ifx_hsnand_mtd->name == NULL) {
         printk("Unable to allocate HSNAND MTD device name\n");
         err = -ENOMEM;
@@ -1380,114 +1243,67 @@
 
     this->options = NAND_SKIP_BBTSCAN;
 
-    ChipID = getChipID();
+    if (ifx_nand_avm_check_for_hweccnand(this)) {
 
-    /*--- printk("{%s} ChipID 0x%x\n", __func__, ChipID); ---*/
-    for (i = 0; ifx_chip_info[i].chip_id; i++) {
-        /*--- printk("{%s} ifx_chip_info 0x%x\n", __func__, ifx_chip_info[i].chip_id); ---*/
-        if ((ChipID & 0xFFFF) == ifx_chip_info[i].chip_id) {
-            break;
+        /*--- setup nandfunctions without hwecc & dma (first step) ---*/
+        sprintf((char *)ifx_hsnand_mtd->name, IFX_MTD_NAND_BANK_NAME);
+
+        this->ecc.mode = NAND_ECC_SOFT;
+
+        this->read_buf      = ifx_nand_read_buf;
+        this->write_buf     = ifx_nand_write_buf;
+
+    } else {
+        err = ifx_hsnand_dma_setup(ifx_hsnand_mtd);
+        if (err < 0) {
+            printk(KERN_ERR "[%s] HSNAND DMA setup failed\n", __func__);
+            goto out;
         }
-    }
-    this->ecc.size     = ifx_chip_info[i].eccsize;
-    this->ecc.bytes    = ifx_chip_info[i].eccbytes;
-    this->ecc.layout   = ifx_chip_info[i].chip_ecclayout;
-    this->ecc.mode     = ifx_chip_info[i].ecc_mode;
 
-    this->cmdfunc      = ifx_hsnand_command; 
+        this->cmdfunc      = ifx_hsnand_command; 
 
 #if defined(CONFIG_VR9)
-    this->read_buf     = ifx_hsnand_read_buf;
-    this->write_buf    = ifx_hsnand_write_buf;
+        this->read_buf     = ifx_hsnand_read_buf;
+        this->write_buf    = ifx_hsnand_write_buf;
 #else
-    this->read_buf     = ifx_hsnand_ar10_read_buf;
-    this->write_buf    = ifx_hsnand_ar10_write_buf;
+        this->read_buf     = ifx_hsnand_ar10_read_buf;
+        this->write_buf    = ifx_hsnand_ar10_write_buf;
 #endif
 
-    if (ifx_nand_avm_check_for_hweccnand(this, ChipID)) {
-        printk("[HSNAND] Hardware-ECC activated\n");
-        /*------------------------------------------------------------------------------------------*\
-         * wir nutzen die HWECC des NAND-Chip
-        \*------------------------------------------------------------------------------------------*/
-        hsnand->read_eccstatus = ifx_hsnand_read_eccstatus;
         this->write_page   = ifx_hsnand_write_page;
        
         this->ecc.write_page = ifx_hsnand_write_page_raw;
         this->ecc.write_page_raw = ifx_hsnand_write_page_raw;
 
-        this->ecc.read_page  = ifx_hsnand_micron_read_page_hwecc;
-        this->ecc.read_page_raw  = ifx_hsnand_micron_read_page_hwecc;
-#if defined(CONFIG_AR10)
-        this->ecc.read_oob = ifx_hsnand_ar10_read_oob;
-        this->ecc.write_oob = ifx_hsnand_ar10_write_oob;
-#endif
-
-    } else if (((ChipID & 0xFFFF) == 0x98f1) || ((ChipID & 0xFFFF) == 0x98dc)) {
-        printk("[HSNAND] Toshiba-BENAND\n");
-        /*------------------------------------------------------------------------------------------*\
-         * Toshiba- BENAND wir nutzen die HWECC des NAND-Chip
-         * schreiben aber mit ECC1 per Hardware in den Flash und nutzen die Standartfunktion
-         * nand_write_page_hwecc wir müssen also
-         * chip->ecc.hwctl
-         * chip->ecc.calculate  setzen
-        \*------------------------------------------------------------------------------------------*/
-        hsnand->read_eccstatus = ifx_hsnand_toshiba_read_eccstatus;
-        this->write_page   = ifx_hsnand_write_page;
-        
-        /*--- if ((ChipID & 0xFFFF) == 0x98dc) { ---*/
-        if (((*IFX_RCU_RST_STAT >> 17) & 0xF) == 0xC) {     /*--- boot from NAND ---*/
-            this->ecc.hwctl = ifx_hsnand_hwctl;
-            this->ecc.calculate = nand_calculate_ecc;
-            this->ecc.correct = nand_correct_data;
-        } else {
-            this->ecc.write_page = ifx_hsnand_write_page_raw;
-            this->ecc.write_page_raw = ifx_hsnand_write_page_raw;
-        }
-
-        this->ecc.read_page  = ifx_hsnand_toshiba_read_page_hwecc;
-        this->ecc.read_page_raw  = ifx_hsnand_toshiba_read_page_hwecc;
-#if defined(CONFIG_AR10)
+#if defined(CONFIG_VR9)
+        this->ecc.read_page  = ifx_hsnand_read_page_hwecc;
+        this->ecc.read_page_raw  = ifx_hsnand_read_page_hwecc;
+#else
+        this->ecc.read_page  = ifx_hsnand_read_page_hwecc;
+        this->ecc.read_page_raw  = ifx_hsnand_read_page_hwecc;
         this->ecc.read_oob = ifx_hsnand_ar10_read_oob;
         this->ecc.write_oob = ifx_hsnand_ar10_write_oob;
 #endif
-    } else {
-        /*------------------------------------------------------------------------------------------*\
-        \*------------------------------------------------------------------------------------------*/
-        sprintf((char *)ifx_hsnand_mtd->name, IFX_MTD_NAND_BANK_NAME);
-        
-        this->ecc.mode      = NAND_ECC_SOFT;
-        this->read_buf      = ifx_nand_read_buf;
-        this->write_buf     = ifx_nand_write_buf;
-    }
-
-    /*--- wir nutzen auf jeden Fall den DMA ---*/
-    err = ifx_hsnand_dma_setup(ifx_hsnand_mtd);
-    if (err < 0) {
-        printk(KERN_ERR "[%s] HSNAND DMA setup failed\n", __func__);
-        goto out;
+        init_waitqueue_head(&hsnand->hsnand_wait);	
     }
 
-    init_waitqueue_head(&hsnand->hsnand_wait);	
-
     if (nand_scan(ifx_hsnand_mtd, 1)) {
         printk(KERN_ERR "[%s] Probing for NAND flash failed, flash not found!\n", __func__);
         err = -ENXIO;
         goto out;
     }
 
-    hsnand->hwecc_buffer = kmalloc(ifx_hsnand_mtd->writesize + ifx_hsnand_mtd->oobsize, GFP_KERNEL | GFP_DMA);
+    hsnand->hwecc_buffer = (unsigned char *)kmalloc(ifx_hsnand_mtd->writesize + ifx_hsnand_mtd->oobsize, GFP_KERNEL | GFP_DMA);
     if ( ! hsnand->hwecc_buffer) {
         err = -ENOMEM;
         goto out;
     }
-    hsnand->tmp_buffer = kmalloc(ifx_hsnand_mtd->writesize + ifx_hsnand_mtd->oobsize, GFP_KERNEL | GFP_DMA);
+    hsnand->tmp_buffer = (unsigned char *)kmalloc(ifx_hsnand_mtd->writesize + ifx_hsnand_mtd->oobsize, GFP_KERNEL | GFP_DMA);
     if ( ! hsnand->tmp_buffer) {
         err = -ENOMEM;
         goto out;
     }
      
-    this->badblock_pattern = &largepage_memorybased;
-
     /*--- vor scan_bbt muss hwecc_buffer gesetzt sein ---*/
 	if (this->scan_bbt(ifx_hsnand_mtd)) {
         printk(KERN_ERR "[%s] scan NAND BBT failed!\n", __func__);
--- linux-2.6.32/drivers/mtd/nand/ifxmips_mtd_nand.h
+++ linux-2.6.32/drivers/mtd/nand/ifxmips_mtd_nand.h
@@ -28,15 +28,20 @@
 
 #define IFX_EBU_ENABLE 		1 
 
+#ifdef CONFIG_AR10 
 #if defined (CONFIG_NAND_CS0) 
 #define NAND_PHYS_BASE_CS0          0x10000000 
 #define NAND_BASE_ADDRESS_CS0       (NAND_PHYS_BASE_CS0 | KSEG1) 
 #define NAND_BASE_ADDRESS 	        NAND_BASE_ADDRESS_CS0 
-#else
+#elif defined (CONFIG_NAND_CS1) 
 #define NAND_PHYS_BASE_CS1	        0x14000000	 
 #define NAND_BASE_ADDRESS_CS1       (NAND_PHYS_BASE_CS1 | KSEG1) 
 #define NAND_BASE_ADDRESS	        NAND_BASE_ADDRESS_CS1 
 #endif  /* CONFIG_NAND_CSx */ 
+#else 
+#define NAND_PHYS_BASE              0x14000000 
+#define NAND_BASE_ADDRESS           (NAND_PHYS_BASE | KSEG1) 
+#endif /* CONFIG_AR10 */ 
 
 #define NAND_WRITE(addr, val)     *((volatile u8*)(NAND_BASE_ADDRESS | (addr))) = val; mb(); while((IFX_REG_R32(IFX_EBU_NAND_WAIT) & IFX_EBU_NAND_WAIT_WR_C) == 0)
 #define NAND_READ(addr, val)      val = *((volatile u8*)(NAND_BASE_ADDRESS | (addr))); mb(); while((IFX_REG_R32(IFX_EBU_NAND_WAIT) & IFX_EBU_NAND_WAIT_WR_C) == 0) 
@@ -264,13 +269,6 @@
  * in chips can be defined here. 
 */
 
-struct nand_bbt_descr generic_largepage_memorybased = {
-    .options = 0,
-    .offs = 0,
-    .len = 1,
-    .pattern = ifx_hsnand_2048_bbt_pattern
-};
-
 struct nand_bbt_descr generic_bbt_main_descr = {
         .options = NAND_BBT_LASTBLOCK | NAND_BBT_CREATE | NAND_BBT_WRITE
                 | NAND_BBT_2BIT | NAND_BBT_VERSION | NAND_BBT_PERCHIP,
@@ -310,7 +308,7 @@
     .eccbytes = 12,
     .eccpos = {2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13},
     .oobavail = 50,
-    .oobfree = {{14, 50}}
+    .oobfree = {{13, 63}}
 };
 
 /* MLC driver ecc layout */ 
@@ -497,19 +495,6 @@
                  .length = 38}}
 };
 
-static struct nand_ecclayout oobinfo_4096_generic = {
-    .eccbytes =  48,
-    .eccpos = {  80,  81,  82,  83,  84,  85,  86,  87,
-		         88,  89,  90,  91,  92,  93,  94,  95,
-		         96,  97,  98,  99, 100, 101, 102, 103, 
-                104, 105, 106, 107, 108, 109, 110, 111,
-		        112, 113, 114, 115, 116, 117, 118, 119, 
-		        120, 121, 122, 123, 124, 125, 126, 127 
-    },
-    .oobavail = 78,
-    .oobfree = {{ .offset = 2, .length = 78 }}
-};
-
 /*------------------------------------------------------------------------------------------*\
 \*------------------------------------------------------------------------------------------*/
 struct nand_ecclayout nand_oob_64_NANDwithHWEcc_FAILURE = {
@@ -538,21 +523,27 @@
 
 /*------------------------------------------------------------------------------------------*\
 \*------------------------------------------------------------------------------------------*/
-struct ifx_nand_info {
-    unsigned int chip_id;
-    unsigned int addr_cycle;
-    nand_ecc_modes_t ecc_mode;
-    unsigned int eccsize;
-    unsigned int eccbytes;
+struct nand_extra_info {
+    u32 chip_id;
+    int addr_cycle;
     struct nand_ecclayout *chip_ecclayout;
+    struct nand_bbt_descr *chip_bbt_main_descr;
+    struct nand_bbt_descr *chip_bbt_mirror_descr;
 };
 
-struct ifx_nand_info ifx_chip_info[] = {
-    { 0x2cf1, 5, NAND_ECC_HW,   512, 0, &nand_oob_64_NANDwithHWEcc },   /*--- Micron ---*/
-    { 0x2cdc, 5, NAND_ECC_HW,   512, 0, &nand_oob_64_NANDwithHWEcc },   /*--- Micron ---*/
-    { 0x98f1, 5, NAND_ECC_HW,   256, 3, &oobinfo_2048_generic },        /*--- Toshiba ---*/
-    { 0x98dc, 5, NAND_ECC_HW,   256, 3, &oobinfo_4096_generic },        /*--- Toshiba 4k Page ---*/
-    {      0, 0, NAND_ECC_SOFT, 256, 3, &oobinfo_2048_generic },        /*--- wird als default gesetzt ---*/
+struct nand_extra_info chip_extra_info[] = {
+    { 0xec75, 3, &ifx_oobinfo_512, &ifx_hsnand_main_desc_512, &ifx_hsnand_mirror_desc_512 },
+    { 0xecf1, 5, &ifx_oobinfo_2048, &ifx_hsnand_main_desc_2048, &ifx_hsnand_mirror_desc_2048 },
+    { 0xecdc, 5, &ifx_oobinfo_2048, &ifx_hsnand_main_desc_2048, &ifx_hsnand_mirror_desc_2048 },
+    { 0xc176, 4, NULL, NULL, NULL },  // IFX nand
+    { 0xecd3, 5, NULL, NULL, NULL }, //samsung mlc
+    { 0xaddc, 5, NULL, NULL, NULL }, // hynix
+    { 0x2c68, 5, NULL, NULL, NULL }, // micron
+    { 0x2c88, 5, NULL, NULL, NULL }, // micron
+    { 0xFFFF, 3, &oobinfo_512_generic, &generic_bbt_main_descr, &generic_bbt_mirror_descr },
+    { 0xFFFF, 3, &oobinfo_2048_generic, &generic_bbt_main_descr, &generic_bbt_mirror_descr },
+
+
 };
 
 #endif /* IFXMIPS_NAND_H */
--- linux-2.6.32/drivers/usb/musb/ifxhcd.c
+++ linux-2.6.32/drivers/usb/musb/ifxhcd.c
@@ -154,19 +154,28 @@
 	/* AVM/BC 20131115 Fix: from old ifxhcd_complete_urb */
 	if (!_urbd->epqh) {
 		IFX_ERROR("%s: invalid epqd\n",__func__);
-	}
+	} else if(_urbd->is_active) {
+		if (_urbd->epqh->urbd != _urbd) {
+			IFX_ERROR("%s: mismatching ephq->urbd:%p->%p, urbd %p\n",__func__, _urbd->epqh, _urbd->epqh->urbd, _urbd);
+		}
+		
+		/* AVM/WKR 20141010 Fix: set urbd inactive */
+		_urbd->is_active = 0;
+		_urbd->epqh->urbd = NULL;
+		
 #if defined(__UNALIGNED_BUFFER_ADJ__)
-	else if(_urbd->is_active) {
 		if( _urbd->epqh->aligned_checked   &&
-		    _urbd->epqh->using_aligned_buf &&
-		    _urbd->xfer_buff &&
-		    _urbd->is_in )
+			_urbd->epqh->using_aligned_buf &&
+			_urbd->xfer_buff &&
+			_urbd->is_in ) 
+		{
 			memcpy(_urbd->xfer_buff,_urbd->epqh->aligned_buf,_urbd->xfer_len);
+		}
 		_urbd->epqh->using_aligned_buf=0;
 		_urbd->epqh->using_aligned_setup=0;
 		_urbd->epqh->aligned_checked=0;
-	}
 #endif
+	}
 
 	local_ifxhcd_complete_urb(_ifxhcd, _urbd, _status);
 }
@@ -184,13 +193,20 @@
 
 	_urbd->status = _status;
 
+	IFX_WARN_ON(!_urbd->is_active);
 	/* AVM/BC 20131115 Fix: from old ifxhcd_complete_urb */
 	if (!_urbd->epqh) {
 		IFX_ERROR("%s: invalid epqd\n",__func__);
-	}
-#if defined(__UNALIGNED_BUFFER_ADJ__)
-	else if(_urbd->is_active) {
+	} else if(_urbd->is_active) {
+		if (_urbd->epqh->urbd != _urbd) {
+			IFX_ERROR("%s: mismatching ephq->urbd:%p->%p, urbd %p\n",__func__, _urbd->epqh, _urbd->epqh->urbd, _urbd);
+		}
+		
+		/* AVM/WKR 20141010 Fix: set urbd inactive */
+		_urbd->is_active = 0;
+		_urbd->epqh->urbd = NULL;
 
+#if defined(__UNALIGNED_BUFFER_ADJ__)
 		if( _urbd->epqh->aligned_checked   &&
 		    _urbd->epqh->using_aligned_buf &&
 		    _urbd->xfer_buff &&
@@ -200,8 +216,9 @@
 		_urbd->epqh->using_aligned_buf=0;
 		_urbd->epqh->using_aligned_setup=0;
 		_urbd->epqh->aligned_checked=0;
-	}
 #endif
+	}
+	
 	if (	(_status != 0) 
 		||  ((_urbd->urb) && !(_urbd->urb->transfer_flags & URB_NO_INTERRUPT)))
 	{
@@ -239,6 +256,27 @@
 	}
 }
 
+/* 20140917 AVM/WK giveback all urbs in complete list
+	call in SPIN_LOCK before ephq_free
+*/
+static void complete_all_deferred_urbs(ifxhcd_hcd_t *_ifxhcd)
+{
+	while (!list_empty(&_ifxhcd->urbd_complete_list))
+	{
+		struct list_head *urbd_ptr;
+		ifxhcd_urbd_t    *urbd;
+
+		urbd_ptr = _ifxhcd->urbd_complete_list.next;
+		list_del_init(urbd_ptr);
+
+		urbd = list_entry(urbd_ptr, ifxhcd_urbd_t, urbd_list_entry);
+		IFX_PRINT ("%s: complete deferred urbs epqh %p urbd %p ->urb %p\n",__func__, urbd->epqh, urbd, urbd->urb);
+
+		local_ifxhcd_complete_urb(_ifxhcd, urbd, urbd->status);
+
+	}
+
+}
 
 /*!
  \brief Free all EPS in one Processes all the URBs in a single list of EPQHs. Completes them with
@@ -269,6 +307,9 @@
 //static
 void epqh_list_free_all(ifxhcd_hcd_t *_ifxhcd)
 {
+	/* 20140917 AVM/WK giveback all urbs in complete list first*/
+	complete_all_deferred_urbs(_ifxhcd);
+
 	epqh_list_free(_ifxhcd, &_ifxhcd->epqh_np_active   );
 	epqh_list_free(_ifxhcd, &_ifxhcd->epqh_np_ready    );
 	epqh_list_free(_ifxhcd, &_ifxhcd->epqh_intr_active );
@@ -516,7 +557,7 @@
 	 */
 //	retval = usb_add_hcd(syshcd, _ifxhcd->core_if.irq, SA_INTERRUPT|SA_SHIRQ);
 #if defined (CONFIG_USB_HOST_IFX_AVM_YIELD)
-	retval = usb_add_hcd(syshcd, _ifxhcd->core_if.irq, IRQF_DISABLED | IRQF_SHARED |IRQF_TRIGGER_RISING);
+	retval = usb_add_hcd(syshcd, _ifxhcd->core_if.irq, IRQF_DISABLED | IRQF_TRIGGER_RISING);
 #else
 	retval = usb_add_hcd(syshcd, _ifxhcd->core_if.irq, IRQF_DISABLED | IRQF_SHARED );
 #endif /*--- defined (CONFIG_USB_HOST_IFX_AVM_YIELD) ---*/
@@ -879,6 +920,7 @@
 			epqh->is_active=0;
 	else if (epqh->is_active && urbd->is_active)
 	{
+		IFX_BUG_ON(epqh->urbd != urbd);
 		/*== AVM/WK 20100709 - halt channel only if really started ==*/
 		//if (epqh->hc->xfer_started && !epqh->hc->wait_for_sof) {
 		/*== AVM/WK 20101112 - halt channel if started ==*/
@@ -987,6 +1029,8 @@
 			}
 #endif
 
+			/* 20140917 AVM/WK giveback all urbs in complete list */
+			complete_all_deferred_urbs(ifxhcd);
 			ifxhcd_epqh_free(epqh);
 			_sysep->hcpriv = NULL;
 		}
@@ -1471,6 +1515,8 @@
 	urbd = list_entry(_epqh->urbd_list.next, ifxhcd_urbd_t, urbd_list_entry);
 	urb  = urbd->urb;
 
+	IFX_BUG_ON(_epqh->urbd);
+
 	_epqh->hc   = ifxhc;
 	_epqh->urbd = urbd;
 	ifxhc->epqh = _epqh;
@@ -1892,25 +1938,26 @@
 
 	if(xfer_len > 0 && ((unsigned long)_urbd->xfer_buff) & 3)
 	{
-		IFX_WARN("WARN:adjusting unaligned xfer_buff %p, len %u\n",_urbd->xfer_buff, xfer_len);
+		IFX_PRINT("adjusting unaligned xfer_buff %p, len %u, EP %02X\n",_urbd->xfer_buff, xfer_len, usb_pipeendpoint(_urbd->urb->pipe));
+		if(_epqh->old_aligned_buf)
+		{
+			ifxusb_free_buf(_epqh->old_aligned_buf);
+			_epqh->old_aligned_buf = NULL;
+		}
+		
 		if(_epqh->aligned_buf_len < xfer_len)
 		{
+			IFX_WARN("enhancing aligned_buf from %u to %u\n", _epqh->aligned_buf_len, xfer_len);
 			if(_epqh->new_aligned_buf) 
 			{
 				ifxusb_free_buf(_epqh->new_aligned_buf);
 				_epqh->new_aligned_buf = NULL;
 			}
-			if(_epqh->old_aligned_buf)
-			{
-				ifxusb_free_buf(_epqh->old_aligned_buf);
-				_epqh->old_aligned_buf = NULL;
-			}
 
 			_epqh->new_aligned_buf = ifxusb_alloc_buf(xfer_len, _urbd->is_in);
-			if(_epqh->new_aligned_buf)
-				_epqh->aligned_buf_len = xfer_len;
-			else
-				IFX_WARN("%s():%d\n",__func__,__LINE__);
+			_epqh->aligned_buf_len = xfer_len;
+			IFX_BUG_ON(!_epqh->new_aligned_buf);
+
 		}
 	}
 
@@ -1918,11 +1965,13 @@
 	{
 		if(((unsigned long)_urbd->setup_buff) & 3)
 		{
-			IFX_WARN("WARN:adjusting unaligned setup_buff %p\n",_urbd->setup_buff);
-			if(! _epqh->aligned_setup) {
+			IFX_PRINT("adjusting unaligned setup_buff %p\n",_urbd->setup_buff);
+			if(! _epqh->aligned_setup)
+			{
+				IFX_WARN("alloc aligned_setup\n");
 				_epqh->aligned_setup = ifxusb_alloc_buf(8,0);
-				IFX_WARN_ON(!_epqh->aligned_setup);
 			}
+			IFX_BUG_ON(!_epqh->aligned_setup);
 		}
 	}
 }
--- linux-2.6.32/drivers/usb/musb/ifxhcd_intr.c
+++ linux-2.6.32/drivers/usb/musb/ifxhcd_intr.c
@@ -3148,8 +3148,12 @@
 	IFX_DEBUGPL(DBG_HCDV, "  0x%08x & 0x%08x = 0x%08x\n",
 		    hcintval, hcintmsk, hcint.d32);
 
-	if (list_empty(&ifxhc->epqh->urbd_list)) {
-		IFX_WARN("handle_hc_n_intr: No urbd in hch#%d,flags=%X\n", _num, hcint.d32);
+	/* == 20140908 AVM/WK Fix: orphaned interrupt must be acked and will not be handled ==*/
+	if ((!ifxhc->epqh) || (list_empty(&ifxhc->epqh->urbd_list))) {
+		IFX_WARN_ON(!ifxhc->epqh);
+		IFX_WARN_ON(ifxhc->epqh && list_empty(&ifxhc->epqh->urbd_list));
+		IFX_WARN("WARN:handle_hc_n_intr: No urbd in hch#%d,flags=%X\n", _num, hcint.d32);
+		ifxusb_wreg(&hc_regs->hcint,hcintval);
 		return 0;
 	}
 	
@@ -3727,8 +3731,6 @@
 {
 	int retval = 0;
 
-	unsigned long     flags;
-
 	ifxusb_core_if_t *core_if = &_ifxhcd->core_if;
 	/* AVM/BC 20101111 Unnecesary variable removed*/
 	//gint_data_t gintsts,gintsts2;
@@ -3741,16 +3743,12 @@
 	}
 	#endif
 
-	SPIN_LOCK_IRQSAVE(&_ifxhcd->lock, flags);
-
 	/* Check if HOST Mode */
 	if (ifxusb_is_device_mode(core_if))
 	{
-		SPIN_UNLOCK_IRQRESTORE(&_ifxhcd->lock, flags);
 		IFX_ERROR("%s() CRITICAL!  IN DEVICE MODE\n", __func__);
 		return 0;
 	}
-
 	gintsts.d32 = ifxusb_read_core_intr(core_if);
 
 #if defined (CONFIG_USB_HOST_IFX_AVM_YIELD)
@@ -3758,79 +3756,86 @@
 	gintsts.b.hcintr = 0;
 #endif
 
-	//Common INT
-	if (gintsts.b.modemismatch)
-	{
-		retval |= handle_mode_mismatch_intr(_ifxhcd);
-		gintsts.b.modemismatch=0;
-	}
-	if (gintsts.b.otgintr)
-	{
-		retval |= handle_otg_intr(_ifxhcd);
-		gintsts.b.otgintr=0;
-	}
-	if (gintsts.b.conidstschng)
-	{
-		retval |= handle_conn_id_status_change_intr(_ifxhcd);
-		gintsts.b.conidstschng=0;
-	}
-	if (gintsts.b.disconnect)
-	{
-		retval |= handle_disconnect_intr(_ifxhcd);
-		gintsts.b.disconnect=0;
-	}
-	if (gintsts.b.sessreqintr)
-	{
-		retval |= handle_session_req_intr(_ifxhcd);
-		gintsts.b.sessreqintr=0;
-	}
-	if (gintsts.b.wkupintr)
-	{
-		retval |= handle_wakeup_detected_intr(_ifxhcd);
-		gintsts.b.wkupintr=0;
-	}
-	if (gintsts.b.usbsuspend)
+	if (gintsts.d32) 
 	{
-		retval |= handle_usb_suspend_intr(_ifxhcd);
-		gintsts.b.usbsuspend=0;
-	}
+		unsigned long     flags;
+
+		SPIN_LOCK_IRQSAVE(&_ifxhcd->lock, flags);
+
+		//Common INT
+		if (gintsts.b.modemismatch)
+		{
+			retval |= handle_mode_mismatch_intr(_ifxhcd);
+			gintsts.b.modemismatch=0;
+		}
+		if (gintsts.b.otgintr)
+		{
+			retval |= handle_otg_intr(_ifxhcd);
+			gintsts.b.otgintr=0;
+		}
+		if (gintsts.b.conidstschng)
+		{
+			retval |= handle_conn_id_status_change_intr(_ifxhcd);
+			gintsts.b.conidstschng=0;
+		}
+		if (gintsts.b.disconnect)
+		{
+			retval |= handle_disconnect_intr(_ifxhcd);
+			gintsts.b.disconnect=0;
+		}
+		if (gintsts.b.sessreqintr)
+		{
+			retval |= handle_session_req_intr(_ifxhcd);
+			gintsts.b.sessreqintr=0;
+		}
+		if (gintsts.b.wkupintr)
+		{
+			retval |= handle_wakeup_detected_intr(_ifxhcd);
+			gintsts.b.wkupintr=0;
+		}
+		if (gintsts.b.usbsuspend)
+		{
+			retval |= handle_usb_suspend_intr(_ifxhcd);
+			gintsts.b.usbsuspend=0;
+		}
 
 #if !defined (CONFIG_USB_HOST_IFX_AVM_YIELD)
-	//Host Int
-	if (gintsts.b.sofintr)
-	{
-		retval |= handle_sof_intr (_ifxhcd);
-		gintsts.b.sofintr=0;
-	}
+		//Host Int
+		if (gintsts.b.sofintr)
+		{
+			retval |= handle_sof_intr (_ifxhcd);
+			gintsts.b.sofintr=0;
+		}
 #endif
 
-	if (gintsts.b.portintr)
-	{
-		retval |= handle_port_intr (_ifxhcd);
-		gintsts.b.portintr=0;
-	}
+		if (gintsts.b.portintr)
+		{
+			retval |= handle_port_intr (_ifxhcd);
+			gintsts.b.portintr=0;
+		}
 
 #if !defined (CONFIG_USB_HOST_IFX_AVM_YIELD)
-	if (gintsts.b.hcintr)
-	{
-		int i;
-		haint_data_t haint;
-		haint.d32 = ifxusb_read_host_all_channels_intr(core_if);
-		for (i=0; i< core_if->params.host_channels; i++)
-			if (haint.b2.chint & (1 << i))
-				retval |= handle_hc_n_intr (_ifxhcd, i);
-		gintsts.b.hcintr=0;
-	}
-	
+		if (gintsts.b.hcintr)
+		{
+			int i;
+			haint_data_t haint;
+			haint.d32 = ifxusb_read_host_all_channels_intr(core_if);
+			for (i=0; i< core_if->params.host_channels; i++)
+				if (haint.b2.chint & (1 << i))
+					retval |= handle_hc_n_intr (_ifxhcd, i);
+			gintsts.b.hcintr=0;
+		}
 #endif
 
 #if !defined (CONFIG_USB_HOST_IFX_AVM_YIELD)
-	if (atomic_read( &_ifxhcd->need_eps)) {
-		tasklet_schedule(&_ifxhcd->comp_task);
-	}
+		if (atomic_read( &_ifxhcd->need_eps)) 
+		{
+			tasklet_schedule(&_ifxhcd->comp_task);
+		}
 #endif
 
-	SPIN_UNLOCK_IRQRESTORE(&_ifxhcd->lock, flags);
+		SPIN_UNLOCK_IRQRESTORE(&_ifxhcd->lock, flags);
+	}
 
 	return retval;
 }
--- linux-2.6.32/drivers/usb/musb/ifxhcd_queue.c
+++ linux-2.6.32/drivers/usb/musb/ifxhcd_queue.c
@@ -194,6 +194,9 @@
 		IFX_WARN("%s() invalid epqh state\n",__func__);
 
 	#if defined(__UNALIGNED_BUFFER_ADJ__)
+		WARN_ON(_epqh->using_aligned_buf);
+		WARN_ON(_epqh->using_aligned_setup);
+
 		if(_epqh->aligned_buf)
 			ifxusb_free_buf(_epqh->aligned_buf);
 		if(_epqh->new_aligned_buf)
@@ -314,6 +317,7 @@
 		else
 			list_move_tail(&_epqh->epqh_list_entry, &_ifxhcd->epqh_np_ready);
 	}
+	IFX_BUG_ON(_epqh->urbd);
 	_epqh->is_active=0;
 //	local_irq_restore(flags);
 }
@@ -332,6 +336,7 @@
 	if (!list_empty(&_epqh->urbd_list))
 		IFX_WARN("%s() invalid epqh state(not empty)\n",__func__);
 
+	IFX_BUG_ON(_epqh->urbd);
 	_epqh->is_active=0;
 	list_del_init(&_epqh->epqh_list_entry);
 	#ifdef __EPQD_DESTROY_TIMEOUT__
--- linux-2.6.32/drivers/usb/musb/ifxusb_plat.h
+++ linux-2.6.32/drivers/usb/musb/ifxusb_plat.h
@@ -1189,8 +1189,8 @@
 /*  Basic message printing. */
 #define IFX_PRINT(x...) avm_DebugPrintf(KERN_INFO IFXUSB x )
 
-#define IFX_WARN_ON(x...) if(x){IFX_WARN("WARN:%s in %s:line %u\n",##x,__func__,__LINE__);}
-#define IFX_BUG_ON(x...) if(x){IFX_ERROR("BUG:%s in %s:line %u\n",##x,__func__,__LINE__);}
+#define IFX_WARN_ON(x) if(x){IFX_WARN("WARN:%s in %s:line %u\n",#x,__func__,__LINE__);}
+#define IFX_BUG_ON(x) if(x){IFX_ERROR("BUG:%s in %s:line %u\n",#x,__func__,__LINE__);}
 
 #endif
 
--- linux-2.6.32/include/linux/avm_pa.h
+++ linux-2.6.32/include/linux/avm_pa.h
@@ -1,7 +1,7 @@
 /*
  *     Definitions for AVM packet acceleration
  *
- * Copyright (c) 2011-2013 AVM GmbH <info@avm.de>
+ * Copyright (c) 2011-2014 AVM GmbH <info@avm.de>
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -137,7 +137,7 @@
    struct packet_type    *ptype; /* avm_pa_framing_ptype */
 };
 
-#define AVM_PA_PID_ECFG_VERSION 2
+#define AVM_PA_PID_ECFG_VERSION 3
 struct avm_pa_pid_ecfg {
     int           version;
 	/* version 0 */
@@ -152,6 +152,9 @@
 	/* version 2 */
 	void  (*rx_slow)(void *arg, PKT *pkt);
     void  *rx_slow_arg;
+	/* version 3 */
+#define AVM_PA_PID_GROUP_WLAN_STA             1
+	int   pid_group;
 };
 
 struct avm_pa_vpid_cfg {
--- linux-2.6.32/include/linux/mtd/nand.h
+++ linux-2.6.32/include/linux/mtd/nand.h
@@ -101,7 +101,6 @@
 #define NAND_CMD_STATUS_ERROR1	0x74
 #define NAND_CMD_STATUS_ERROR2	0x75
 #define NAND_CMD_STATUS_ERROR3	0x76
-#define NAND_CMD_ECCSTATUS      0x7A
 #define NAND_CMD_STATUS_RESET	0x7f
 #define NAND_CMD_STATUS_CLEAR	0xff
 #define NAND_CMD_CACHEREAD_SEQ_CONTINUE     0x31
--- linux-2.6.32/include/linux/tffs.h
+++ linux-2.6.32/include/linux/tffs.h
@@ -637,10 +637,8 @@
 extern unsigned int TFFS_Info(void *, unsigned int *);
 extern unsigned char *TFFS_Read_Buffer(void *, unsigned int **);
 extern unsigned char *TFFS_Write_Buffer(void *, unsigned int **);
-void tffs_panic_log_open(void);
-void tffs_panic_log_close(void);
-extern void tffs_panic_log_write(char *buffer, unsigned int len);
 extern unsigned int tffs_panic_log_suppress;
+void tffs_panic_log_printkbuf(void);
 void tffs_panic_log_register_spi(void);
 #endif /*--- #if defined(CONFIG_TFFS) ---*/
 
--- linux-2.6.32/kernel/panic.c
+++ linux-2.6.32/kernel/panic.c
@@ -31,8 +31,6 @@
 
 #ifdef CONFIG_TFFS_PANIC_LOG
 #include <linux/tffs.h>
-unsigned int tffs_panic_log_suppress = 0;
-EXPORT_SYMBOL(tffs_panic_log_suppress);
 #endif /*--- #ifdef CONFIG_TFFS_PANIC_LOG ---*/
 int panic_on_oops = 1;
 static unsigned long tainted_mask;
@@ -109,36 +107,7 @@
 	smp_send_stop();
 
 #ifdef CONFIG_TFFS_PANIC_LOG
-    if(tffs_panic_log_suppress == 0) {
-        unsigned long printk_get_buffer(char **p_log_buf, unsigned long *p_log_end, unsigned long *p_anzahl);
-        char *buf;
-        unsigned long end;
-        unsigned long anzahl;
-        unsigned long len = printk_get_buffer(&buf, &end, &anzahl);
-        struct timespec uptime;
-        static char time_stamp_buf[sizeof("UPTIME: \n") + 10 + sizeof("PANIC LOG VERSION 2.0\n")];
-        unsigned long time_stamp_buf_len;
-
-        tffs_panic_log_suppress = 1;
-        tffs_panic_log_open();
-        do_posix_clock_monotonic_gettime(&uptime);
-        monotonic_to_bootbased(&uptime);
-        time_stamp_buf_len = snprintf(time_stamp_buf, sizeof(time_stamp_buf), "UPTIME: %lu\nPANIC LOG VERSION 2.0\n", (unsigned long) uptime.tv_sec);
-        tffs_panic_log_write(time_stamp_buf, time_stamp_buf_len + 1);
-#if defined(CONFIG_AVM_WATCHDOG)
-        AVM_WATCHDOG_emergency_retrigger();
-#endif
-        if(anzahl < len) {  /*--- alles im Buffer ---*/
-            tffs_panic_log_write(buf, anzahl);
-        } else {
-            tffs_panic_log_write(buf + end, len - end);
-#if defined(CONFIG_AVM_WATCHDOG)
-            AVM_WATCHDOG_emergency_retrigger();
-#endif
-            tffs_panic_log_write(buf, end);
-        }
-        tffs_panic_log_close();
-    }
+	tffs_panic_log_printkbuf();
 #endif /*--- #ifdef CONFIG_TFFS_PANIC_LOG ---*/
 	atomic_notifier_call_chain(&panic_notifier_list, 0, buf);
 
--- linux-2.6.32/net/avm_pa/avm_pa.c
+++ linux-2.6.32/net/avm_pa/avm_pa.c
@@ -1,10 +1,10 @@
-#define AVM_PA_VERSION "4.3.8 2014-07-08"
+#define AVM_PA_VERSION "4.3.10 2014-09-21"
 /*
  * Packet Accelerator Interface
  *
  * vim:set expandtab shiftwidth=3 softtabstop=3:
  * 
- * Copyright (c) 2011-2013 AVM GmbH <info@avm.de>
+ * Copyright (c) 2011-2014 AVM GmbH <info@avm.de>
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -83,6 +83,18 @@
  *   ACTIVE -> pa_kill_session()     -> DEAD
  *   DEAD   -> pa_session_gc()       -> FREE
  *
+ * Changes for 4.3.10:
+ * - pa_session_get lieferte sessions mit session_id 0
+ *   => alte Sessions in /proc/net/avm_pa/bessions
+ * - FUSIV: Session vom WLAN expireten immer sofort, da in
+ *          avm_pa_hardware_session_report() die Counter immer 0 sind.
+ * - FUSIV: Guard gegen Crashes in handle_fp_bridge_pkt() und
+ *          handle_fp_route_pkt() weil die Session in den Wald zeigt.
+ *
+ * Changes for 4.3.9:
+ * - Pid groups eingefuehrt (WLAN-Repeater 1750)
+ * - Ingress Pid change check only for unicast
+ *
  * Changes for 4.3.8:
  * - Bugfix: bridge packets were cut, when third position of
  *           mac address was 0x00, because ethernet header
@@ -2387,6 +2399,7 @@
    struct avm_pa_global *ctx = &pa_glob;
    u32 hash = macaddr_hash(mac);
    struct avm_pa_macaddr *p;
+   int pid_group = PA_PID(ctx, pid_handle)->ecfg.pid_group;
    int pid_changed = 0;
    AVM_PA_LOCK_DECLARE;
 
@@ -2394,9 +2407,13 @@
    
    for (p = ctx->macaddr_hash[hash%CONFIG_AVM_PA_MAX_SESSION]; p; p = p->link) {
       if (memcmp(mac, &p->mac, ETH_ALEN) == 0) {
-         if (   p->pid_handle != pid_handle
-             && PA_PID(ctx, p->pid_handle)->ingress_pid_handle != pid_handle)
-            pid_changed = 1;
+         if (p->pid_handle != pid_handle) {
+            struct avm_pa_pid *pid = PA_PID(ctx, p->pid_handle);
+            if (pid->ingress_pid_handle != pid_handle) {
+               if (pid_group == 0 || pid_group != pid->ecfg.pid_group)
+                  pid_changed = 1;
+            }
+         }
          break;
       }
    }
@@ -2591,7 +2608,7 @@
    struct avm_pa_session *session;
 
    session = PA_SESSION(ctx, session_handle);
-   if (!pa_session_valid(session))
+   if (!pa_session_valid(session) || session->session_handle == 0)
       session = 0;
    return session;
 }
@@ -3609,8 +3626,10 @@
    if ((ethh = pa_get_ethhdr(pid->ingress_framing, pkt)) != 0) {
       if ((session = pa_bsession_search(pid, ethh_hash(ethh), ethh)) != 0)
          goto accelerate;
-      if ((pid->ecfg.flags & AVM_PA_PID_FLAG_NO_PID_CHANGED_CHECK) == 0)
-         pa_check_and_handle_ingress_pid_change(ethh->h_source, pid_handle);
+      if ((ethh->h_dest[0] & 1) == 0) {
+         if ((pid->ecfg.flags & AVM_PA_PID_FLAG_NO_PID_CHANGED_CHECK) == 0)
+            pa_check_and_handle_ingress_pid_change(ethh->h_source, pid_handle);
+      }
    }
 
    info->ingress_pid_handle = pid_handle;
@@ -4334,6 +4353,8 @@
       return -1;
    memset(&pid->ecfg, 0, sizeof(struct avm_pa_pid_ecfg));
    switch (ecfg->version) {
+      case 3:
+        pid->ecfg.pid_group = ecfg->pid_group;
       case 2:
         pid->ecfg.rx_slow = ecfg->rx_slow;
         pid->ecfg.rx_slow_arg = ecfg->rx_slow_arg;
--- linux-2.6.32/net/avm_pa/avm_pa_fusiv.c
+++ linux-2.6.32/net/avm_pa/avm_pa_fusiv.c
@@ -1,8 +1,10 @@
-#ifdef CONFIG_FUSIV_VX180
+#if defined(CONFIG_FUSIV_VX180) || defined(CONFIG_FUSIV_VX185)
 /*
- * Copyright (c) 2011-2013 AVM GmbH <info@avm.de>
+ * Copyright (c) 2011-2014 AVM GmbH <info@avm.de>
  * All rights reserved.
  *
+ * vim:set expandtab shiftwidth=3 softtabstop=3:
+ *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
  * are met:
@@ -49,6 +51,10 @@
 #include <netpro/apdefs.h>
 #include <netpro/userapi.h>
 #include <netpro/hostapif.h>
+#ifdef CONFIG_FUSIV_VX185
+#include <netpro/vx185/ftindex.h>
+#include <netpro/vx185/descriptorsdefs.h>
+#endif
 
 #include <netpro/apstatistics.h>
 
@@ -56,15 +62,19 @@
 #undef AVM_PA_FUSIV_TRACE
 
 #if defined(AVM_PA_FUSIV_DEBUG)
-#  define AVM_PA_FUSIV_DBG(a...) printk(KERN_ERR "[avm_pa_fusiv] " a);
+#define AVM_PA_FUSIV_DBG(a...) printk(KERN_ERR "[avm_pa_fusiv] " a);
 #else
-#  define AVM_PA_FUSIV_DBG(a...)
+#define AVM_PA_FUSIV_DBG(a...)
 #endif
 
 #if defined(AVM_PA_FUSIV_TRACE)
-#  define AVM_PA_FUSIV_TRC(a...) printk(KERN_ERR "[avm_pa_fusiv] " a);
+#define AVM_PA_FUSIV_TRC(a...) printk(KERN_ERR "[avm_pa_fusiv] " a);
 #else
-#  define AVM_PA_FUSIV_TRC(a...)
+#define AVM_PA_FUSIV_TRC(a...)
+#endif
+
+#ifdef CONFIG_FUSIV_VX185
+extern descInfo_t descinfo[];
 #endif
 
 extern newapIfStruct_t apArray[];
@@ -79,45 +89,51 @@
  * AVM PA fusiv
 \*------------------------------------------------------------------------------------------*/
 struct avm_pa_fusiv_session {
-    struct avm_pa_session *avm_session;
-    unsigned char valid_session;
-	unsigned char rxApId;
-	unsigned char txApId;
-	unsigned short flowhash;
-	enum fusivflowtype flowtype;
-	union 
-	{
-	   apFlowEntry_t     *v4;
-	   apIpv6FlowEntry_t *v6;
-	} flow;
-	apNewBridgeEntry_t *bridgeFlow;
-#ifdef CONFIG_FUSIV_KERNEL_APSTATISTICS_PER_INTERFACE
-	apStatistics_t prevStat;
+   struct avm_pa_session *avm_session;
+   unsigned char valid_session;
+   unsigned char rxApId;
+   unsigned char txApId;
+   unsigned short flowhash;
+   enum fusivflowtype flowtype;
+   union {
+      apFlowEntry_t *v4;
+      apIpv6FlowEntry_t *v6;
+   } flow;
+   apNewBridgeEntry_t *bridgeFlow;
+#if defined(CONFIG_FUSIV_VX180) && defined(CONFIG_FUSIV_KERNEL_APSTATISTICS_PER_INTERFACE)
+   apStatistics_t prevStat;
 #endif
 };
 
 static int avm_pa_fusiv_add_session(struct avm_pa_session *avm_session);
 static int avm_pa_fusiv_remove_session(struct avm_pa_session *avm_session);
-int avm_pa_fusiv_try_to_accelerate(avm_pid_handle pid_handle, struct sk_buff *skb);
+int avm_pa_fusiv_try_to_accelerate(avm_pid_handle pid_handle,
+                                   struct sk_buff *skb);
 int avm_pa_fusiv_alloc_rx_channel(avm_pid_handle pid_handle);
 int avm_pa_fusiv_alloc_tx_channel(avm_pid_handle pid_handle);
 
-static DEFINE_SPINLOCK( session_list_lock );
+static DEFINE_SPINLOCK(session_list_lock);
 
 static struct avm_hardware_pa avm_pa_fusiv = {
-   .add_session               = avm_pa_fusiv_add_session,
-   .remove_session            = avm_pa_fusiv_remove_session,
-   .try_to_accelerate         = avm_pa_fusiv_try_to_accelerate,
-   .alloc_rx_channel          = avm_pa_fusiv_alloc_rx_channel,
-   .alloc_tx_channel          = avm_pa_fusiv_alloc_tx_channel,
-   .free_rx_channel           = NULL/*avm_pa_fusiv_free_rx_channel*/,
-   .free_tx_channel           = NULL/*avm_pa_fusiv_free_tx_channel*/,
+   .add_session = avm_pa_fusiv_add_session,
+   .remove_session = avm_pa_fusiv_remove_session,
+   .try_to_accelerate = avm_pa_fusiv_try_to_accelerate,
+   .alloc_rx_channel = avm_pa_fusiv_alloc_rx_channel,
+   .alloc_tx_channel = avm_pa_fusiv_alloc_tx_channel,
+   .free_rx_channel = NULL /* avm_pa_fusiv_free_rx_channel */ ,
+   .free_tx_channel = NULL /* avm_pa_fusiv_free_tx_channel */ ,
 };
 
+static struct avm_pa_fusiv_session
+   fusiv_session_array[CONFIG_AVM_PA_MAX_SESSION];
 
-static struct avm_pa_fusiv_session fusiv_session_array[CONFIG_AVM_PA_MAX_SESSION];
+static int inline avm_pa_fusiv_session_valid(struct avm_pa_fusiv_session *sess)
+{
+   return    sess >= &fusiv_session_array[0]
+          && sess < &fusiv_session_array[CONFIG_AVM_PA_MAX_SESSION];
+}
 
-#ifdef CONFIG_FUSIV_KERNEL_APSTATISTICS_PER_INTERFACE
+#if defined(CONFIG_FUSIV_VX180) && defined(CONFIG_FUSIV_KERNEL_APSTATISTICS_PER_INTERFACE)
 #define AVM_PA_FUSIV_STAT_POLLING_TIME 1
 static struct timer_list statistics_timer;
 #endif
@@ -127,693 +143,1025 @@
 
 static const char *mac2str(const void *cp, char *buf, size_t size)
 {
-    const unsigned char *mac = (const unsigned char *)cp;
-    snprintf(buf, size, "%02X:%02X:%02X:%02X:%02X:%02X",
-                        mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);
-    return buf;
+   const unsigned char *mac = (const unsigned char *) cp;
+
+   snprintf(buf, size, "%02X:%02X:%02X:%02X:%02X:%02X", mac[0], mac[1], mac[2],
+            mac[3], mac[4], mac[5]);
+   return buf;
 }
 
-/*------------------------------------------------------------------------------------------*\
-\*------------------------------------------------------------------------------------------*/
+/*--------------------------------------------------------------------------*\
+\*--------------------------------------------------------------------------*/
 
-void handle_fp_bridge_pkt(apPreHeader_t *apBuf, struct net_device *dev) {
+void handle_fp_bridge_pkt(apPreHeader_t * apBuf, struct net_device *dev)
+{
 
-	struct sk_buff *skb;
-    apNewBridgeEntry_t *ap_bridge_entry;
-	
-	AVM_PA_FUSIV_TRC("call handle_fp_bridge_pkt\n");
+   struct sk_buff *skb;
+   apNewBridgeEntry_t *ap_bridge_entry;
 
-	ap_bridge_entry = (apNewBridgeEntry_t *)(PHYS_TO_K1(apBuf->matchedEntryAddr));
+   AVM_PA_FUSIV_TRC("call handle_fp_bridge_pkt\n");
 
-	if (ap_bridge_entry && ap_bridge_entry->userHandle) {
-	   struct avm_pa_fusiv_session *fusiv_session = 
-		  (struct avm_pa_fusiv_session *) (ap_bridge_entry->userHandle);
+   ap_bridge_entry = (apNewBridgeEntry_t *)(apBuf->matchedEntryAddr);
 
-	   if (fusiv_session->avm_session) {
-		   skb = (struct sk_buff *)translateApbuf2Mbuf(apBuf);
-		   avm_pa_tx_channel_accelerated_packet(fusiv_session->avm_session->egress[0].pid_handle, 
-				                                fusiv_session->avm_session->session_handle, 
-												skb);
-	       AVM_PA_FUSIV_TRC("handle_fp_bridge_pkt: packet accelerated (pid %u session %u) \n",
-				 fusiv_session->avm_session->egress[0].pid_handle, 
-				 fusiv_session->avm_session->session_handle);
-		   
-	   }
-	}
+   if (ap_bridge_entry) {
+#ifdef CONFIG_FUSIV_VX185
+      if ((unsigned int)ap_bridge_entry & (1 << FT_ENTRY_IN_LMEM_CHKFRMHOST_BIT))
+         ap_bridge_entry = (apNewBridgeEntry_t *)LMEM_PIO2CBUS(ap_bridge_entry);
+#endif
+      ap_bridge_entry = (apNewBridgeEntry_t *)PHYS_TO_K1(ap_bridge_entry);
+   }
+
+   if (ap_bridge_entry && ap_bridge_entry->userHandle) {
+      struct avm_pa_fusiv_session *fusiv_session =
+         (struct avm_pa_fusiv_session *) (ap_bridge_entry->userHandle);
+
+      if (unlikely(!avm_pa_fusiv_session_valid(fusiv_session))) {
+         if (net_ratelimit())
+            printk(KERN_ERR "handle_fp_bridge_pkt: avm session invalid %p\n",
+                            fusiv_session);
+         putCluster(apBuf);
+         return;
+      }
+
+      if (fusiv_session->avm_session) {
+         if ((skb = (struct sk_buff *) translateApbuf2Mbuf(apBuf)) != 0) {
+            avm_pa_tx_channel_accelerated_packet(fusiv_session->avm_session->
+                                                 egress[0].pid_handle,
+                                                 fusiv_session->
+                                                 avm_session->session_handle,
+                                                 skb);
+            AVM_PA_FUSIV_TRC
+               ("handle_fp_bridge_pkt: packet accelerated (pid %u session %u) \n",
+                fusiv_session->avm_session->egress[0].pid_handle,
+                fusiv_session->avm_session->session_handle);
+         }
+         return;
+      }
+   }
+   putCluster(apBuf);
 }
 
-void handle_fp_route_pkt(apPreHeader_t *apBuf, struct net_device *dev) {
+void handle_fp_route_pkt(apPreHeader_t * apBuf, struct net_device *dev)
+{
 
-	struct sk_buff *skb;
-    apFlowEntry_t *flow;
-	
-	AVM_PA_FUSIV_TRC("call handle_fp_route_pkt\n");
+   struct sk_buff *skb;
+   apFlowEntry_t *flow;
 
-	flow = (apFlowEntry_t *)(PHYS_TO_K1(apBuf->matchedEntryAddr));
+   AVM_PA_FUSIV_TRC("call handle_fp_route_pkt\n");
 
-	if (flow && flow->userHandle) {
-	   struct avm_pa_fusiv_session *fusiv_session = 
-		  (struct avm_pa_fusiv_session *) (flow->userHandle);
+   flow = (apFlowEntry_t *)(apBuf->matchedEntryAddr);
 
-	   if (fusiv_session->avm_session) {
-		   skb = (struct sk_buff *)translateApbuf2Mbuf(apBuf);
-		   avm_pa_tx_channel_accelerated_packet(fusiv_session->avm_session->egress[0].pid_handle, 
-				                                fusiv_session->avm_session->session_handle, 
-												skb);
-	       AVM_PA_FUSIV_TRC("handle_fp_route_pkt: packet accelerated (pid %u session %u) \n",
-				 fusiv_session->avm_session->egress[0].pid_handle, 
-				 fusiv_session->avm_session->session_handle);
-		   
-	   }
-	}
+   if (flow) {
+#ifdef CONFIG_FUSIV_VX185
+      if ((unsigned int)flow & (1 << FT_ENTRY_IN_LMEM_CHKFRMHOST_BIT))
+         flow = (apFlowEntry_t *)LMEM_PIO2CBUS(flow);
+#endif
+      flow = (apFlowEntry_t *)PHYS_TO_K1(flow);
+   }
+
+   if (flow && flow->userHandle) {
+      struct avm_pa_fusiv_session *fusiv_session =
+         (struct avm_pa_fusiv_session *) (flow->userHandle);
+
+      if (unlikely(!avm_pa_fusiv_session_valid(fusiv_session))) {
+         if (net_ratelimit())
+            printk(KERN_ERR "handle_fp_route_pkt: avm session invalid %p\n",
+                            fusiv_session);
+         putCluster(apBuf);
+         return;
+      }
+
+      if (fusiv_session->avm_session) {
+         if ((skb = (struct sk_buff *) translateApbuf2Mbuf(apBuf)) != 0) {
+            avm_pa_tx_channel_accelerated_packet(fusiv_session->avm_session->
+                                                 egress[0].pid_handle,
+                                                 fusiv_session->
+                                                 avm_session->session_handle,
+                                                 skb);
+            AVM_PA_FUSIV_TRC
+               ("handle_fp_route_pkt: packet accelerated (pid %u session %u) \n",
+                fusiv_session->avm_session->egress[0].pid_handle,
+                fusiv_session->avm_session->session_handle);
+         }
+         return;
+      }
+   }
+   putCluster(apBuf);
 }
 
-typedef void (*wlan_tx_cb)(void *,void *);
 #define MAX_SSID_LEN 6
+
 struct txInfo {
-	struct net_device *netdev;
-	wlan_tx_cb                 *fp;
-	unsigned char bssid[MAX_SSID_LEN];
+   struct net_device *netdev;
+   void (*fp) (apPreHeader_t *, struct net_device *);
+   unsigned char bssid[MAX_SSID_LEN];
 };
 
 struct txInfo tx_info_bridge = {
-	.fp = handle_fp_bridge_pkt,
+   .fp = handle_fp_bridge_pkt,
 };
 
 struct txInfo tx_info_route = {
-	.fp = handle_fp_route_pkt,
+   .fp = handle_fp_route_pkt,
 };
 
+static int avm_pa_fusiv_add_bridge_session(struct avm_pa_session *avm_session)
+{
+   apNewBridgeEntry_t bridgeEntry, *newBridgeEntry;
+   struct avm_pa_fusiv_session new_session;
+   struct avm_pa_pid_hwinfo *ingress_hw, *egress_hw;
+   unsigned short hash;
+   unsigned long slock_flags;
+   int res = AVM_PA_TX_ERROR_SESSION;
+   int rc;
 
-static int avm_pa_fusiv_add_bridge_session(struct avm_pa_session *avm_session) {
-	apNewBridgeEntry_t bridgeEntry, *newBridgeEntry;
-    struct avm_pa_fusiv_session new_session;
-	struct avm_pa_pid_hwinfo *ingress_hw, *egress_hw;
-	unsigned short hash;
-    unsigned long slock_flags;
-    int res = AVM_PA_TX_ERROR_SESSION;
-	int rc;
+   ingress_hw = avm_pa_pid_get_hwinfo(avm_session->ingress_pid_handle);
+   egress_hw = avm_pa_pid_get_hwinfo(avm_session->egress[0].pid_handle);
 
-	ingress_hw = avm_pa_pid_get_hwinfo( avm_session->ingress_pid_handle );
-	egress_hw  = avm_pa_pid_get_hwinfo( avm_session->egress[0].pid_handle );
+   if ((ingress_hw == NULL) || (egress_hw == NULL))
+      return res;
 
-	memset(&bridgeEntry, 0, sizeof (bridgeEntry));
+   /* == AVM/UGA 20140707 AP2AP/Bridging accallertion for WLAN/PERI AP ==
+    * reenabled since we most probably fixed the buffer leak in apClassify
+    */
+#if 0
+   /*
+    * == AVM/SKI 20140515 == AP2AP/Bridging accallertion for WLAN/PERI AP
+    * disabled because of currently unknown AP buffer leak. 
+    */
+   if (egress_hw->apId == PERI_ID)
+      return res;
+#endif
 
-	if (egress_hw->apId == PERI_ID) {
-	   bridgeEntry.egressList[0].pEgress = (void *)0xFFFFFFFF;
-	   bridgeEntry.egressList[1].pEgress = &tx_info_bridge;
-	   bridgeEntry.rxPort = (unsigned short)((K1_TO_PHYS (PERI_BASE_ADDR)) >> 16);
-	} else if (ingress_hw->apId == PERI_ID) {
-	   bridgeEntry.egressList[0].pEgress = (void *)(K1_TO_PHYS(apArray[egress_hw->apId].apTxFifo));
-	   if (egress_hw->apId == MAC1_ID)
-		  bridgeEntry.rxPort = (unsigned short)((K1_TO_PHYS (MAC1_BASE_ADDR)) >> 16);
-	   else if (egress_hw->apId == MAC2_ID)
-		  bridgeEntry.rxPort = (unsigned short)((K1_TO_PHYS (MAC2_BASE_ADDR)) >> 16);
-	} else {
-	   AVM_PA_FUSIV_DBG("avm_pa_fusiv_add_bridge_session: unsupported bridging AP%u -> AP%u\n",
-			            ingress_hw->apId, egress_hw->apId);
-	   return res;
-	}
-	bridgeEntry.egressList[0].pFlowID = (void *)0;
-	bridgeEntry.used = 1;
-	bridgeEntry.vlanAddr = 1;
-	bridgeEntry.bridgeState = AP_BRIDGE_OPERATIONAL;
-    bridgeEntry.operations = (0x1 << AP_BRIDGE_VALID_BIT);
-	memcpy(bridgeEntry.macAddr, avm_session->bsession->ethh.h_dest, ETH_ALEN);
-	bridgeEntry.userHandle =  (unsigned int)&fusiv_session_array[ avm_session->session_handle ];
-	hash = apBridgeCalculateHash(ingress_hw->apId, &bridgeEntry);
+   memset(&bridgeEntry, 0, sizeof(bridgeEntry));
 
-	rc = apAddBridgeEntry(1, hash, &bridgeEntry, &newBridgeEntry);
+   if (egress_hw->apId == PERI_ID) {
+      bridgeEntry.egressList[0].pEgress = (void *) 0xFFFFFFFF;
+      bridgeEntry.egressList[1].pEgress = &tx_info_bridge;
+      bridgeEntry.rxPort =
+         (unsigned short) ((K1_TO_PHYS(PERI_BASE_ADDR)) >> 16);
+   } else if (ingress_hw->apId == PERI_ID) {
+      bridgeEntry.egressList[0].pEgress =
+         (void *) (K1_TO_PHYS(apArray[egress_hw->apId].apTxFifo));
+      if (egress_hw->apId == MAC1_ID)
+         bridgeEntry.rxPort =
+            (unsigned short) ((K1_TO_PHYS(MAC1_BASE_ADDR)) >> 16);
+      else if (egress_hw->apId == MAC2_ID)
+         bridgeEntry.rxPort =
+            (unsigned short) ((K1_TO_PHYS(MAC2_BASE_ADDR)) >> 16);
+   } else {
+      AVM_PA_FUSIV_DBG
+         ("avm_pa_fusiv_add_bridge_session: unsupported bridging AP%u -> AP%u\n",
+          ingress_hw->apId, egress_hw->apId);
+      return res;
+   }
+   bridgeEntry.egressList[0].pFlowID = (void *) 0;
+   bridgeEntry.used = 1;
+   bridgeEntry.vlanAddr = 1;
+   bridgeEntry.bridgeState = AP_BRIDGE_OPERATIONAL;
+   bridgeEntry.operations = (0x1 << AP_BRIDGE_VALID_BIT);
+   memcpy(bridgeEntry.macAddr, avm_session->bsession->ethh.h_dest, ETH_ALEN);
+   bridgeEntry.userHandle =
+      (unsigned int) &fusiv_session_array[avm_session->session_handle];
+   hash = apBridgeCalculateHash(ingress_hw->apId, &bridgeEntry);
 
-	if (rc != 0) {
-	   AVM_PA_FUSIV_DBG("apAddBridgeEntry returned %d\n", rc);
-	   return res;
-	}
+   rc = apAddBridgeEntry(1, hash, &bridgeEntry, &newBridgeEntry);
 
-	AVM_PA_FUSIV_DBG("apAddBridgeEntry successful hash %u\n", hash);
+   if (rc != 0) {
+      AVM_PA_FUSIV_DBG("apAddBridgeEntry returned %d\n", rc);
+      return res;
+   }
 
-	new_session.avm_session = avm_session;
-	new_session.valid_session = 1;
-	new_session.rxApId = ingress_hw->apId;
-	new_session.txApId = egress_hw->apId;
-	new_session.flowhash = hash;
-	new_session.bridgeFlow = newBridgeEntry;
-	new_session.flowtype = fusiv_bridge_flow;
+   AVM_PA_FUSIV_DBG("apAddBridgeEntry successful hash %u\n", hash);
 
-	// take_session_lock
-	spin_lock_irqsave( &session_list_lock, slock_flags);
-	if ( !fusiv_session_array[ avm_session->session_handle ].valid_session ){
-		fusiv_session_array[ avm_session->session_handle ] = new_session;
-		res = AVM_PA_TX_SESSION_ADDED;
-	} else {
-        AVM_PA_FUSIV_DBG("session add failed - double call for add by avm_pa?!");
-        dump_stack();
-	}
-	// release_session_lock
-	spin_unlock_irqrestore( &session_list_lock, slock_flags);
-	return res;
+   new_session.avm_session = avm_session;
+   new_session.valid_session = 1;
+   new_session.rxApId = ingress_hw->apId;
+   new_session.txApId = egress_hw->apId;
+   new_session.flowhash = hash;
+   new_session.bridgeFlow = newBridgeEntry;
+   new_session.flowtype = fusiv_bridge_flow;
+
+#if defined(CONFIG_FUSIV_VX180) && defined(CONFIG_FUSIV_KERNEL_APSTATISTICS_PER_INTERFACE)
+   memset(&new_session.prevStat, 0, sizeof(apStatistics_t));
+#endif
+
+   // take_session_lock
+   spin_lock_irqsave(&session_list_lock, slock_flags);
+   if (!fusiv_session_array[avm_session->session_handle].valid_session) {
+      fusiv_session_array[avm_session->session_handle] = new_session;
+      res = AVM_PA_TX_SESSION_ADDED;
+   } else {
+      UINT32 moved;
+      apDeleteBridgeEntry(1, hash, newBridgeEntry, &moved);
+      printk(KERN_CRIT "session add failed - double call for add by avm_pa?!");
+      dump_stack();
+   }
+   // release_session_lock
+   spin_unlock_irqrestore(&session_list_lock, slock_flags);
+   return res;
 }
 
+/*--------------------------------------------------------------------------*\
+\*--------------------------------------------------------------------------*/
 
-/*------------------------------------------------------------------------------------------*\
-\*------------------------------------------------------------------------------------------*/
+/* 
+ * TODO: fuer Vx185 muss die DESC ADDR richtig gesetzt werden, z.B.:
+ * COPY_DESC(DESC_SELECT_ROUTE_SNAT_PPPOE_PLAIN, flow.descAddr);
+ */
 
-static int avm_pa_fusiv_add_session_v4(struct avm_pa_session *avm_session) {
-    unsigned long slock_flags;
-    int i, rc;
-    struct avm_pa_fusiv_session new_session;
-    int res = AVM_PA_TX_ERROR_SESSION;
-	apFlowEntry_t flow;
-	apFlowEntry_t *newflow;
-	unsigned int proto, priority, mtu;
-	struct avm_pa_pid_hwinfo *ingress_hw, *egress_hw;
-	unsigned short flowhash;
-	char srcmac[32], dstmac[32], insrc[32];
+static int avm_pa_fusiv_add_session_v4(struct avm_pa_session *avm_session)
+{
+   unsigned long slock_flags;
+   int i, rc;
+   struct avm_pa_fusiv_session new_session;
+   int res = AVM_PA_TX_ERROR_SESSION;
+   apFlowEntry_t flow;
+   apFlowEntry_t *newflow;
+   unsigned int proto, priority, mtu;
+   struct avm_pa_pid_hwinfo *ingress_hw, *egress_hw;
+   unsigned short flowhash;
+   char srcmac[32], dstmac[32], insrc[32];
 
-	AVM_PA_FUSIV_DBG("avm_pa_fusiv_add_session_v4: start\n");
-	
-	ingress_hw = avm_pa_pid_get_hwinfo( avm_session->ingress_pid_handle );
-	egress_hw  = avm_pa_pid_get_hwinfo( avm_session->egress[0].pid_handle );
+   AVM_PA_FUSIV_DBG("avm_pa_fusiv_add_session_v4: start\n");
 
-	proto = avm_session->ingress.pkttype & AVM_PA_PKTTYPE_PROTO_MASK;
+   ingress_hw = avm_pa_pid_get_hwinfo(avm_session->ingress_pid_handle);
+   egress_hw = avm_pa_pid_get_hwinfo(avm_session->egress[0].pid_handle);
 
-	memset(&flow, 0, sizeof(flow));
-	flow.entryType = AP_TCP_UDP_ENTRY;
+   if (ingress_hw == 0 || egress_hw == 0)
+      return res;
 
-	for (i = 0; i < avm_session->ingress.nmatch; i++) {
-	   struct avm_pa_match_info *p = &avm_session->ingress.match[i];
-	   hdrunion_t *hdr = (hdrunion_t *)&avm_session->ingress.hdrcopy[p->offset + avm_session->ingress.hdroff];
-	   
-	   switch (p->type) {
-	   case AVM_PA_VLAN:
-		  break;
-	   case AVM_PA_ETH:
-		  memcpy(flow.inSrcMacAddr, &hdr->ethh.h_source, ETH_ALEN);
-		  break;
-	   case AVM_PA_PPP:
-		  break;
-	   case AVM_PA_PPPOE:
-		  {
-			 flow.inSessionId = hdr->pppoeh.sid;
-		     flow.operations |= (1 << AP_CHECK_PPPOE_BIT);
-		  }
-		  break;
-	   case AVM_PA_IPV4:
-		  flow.srcIPAddr = hdr->iph.saddr;
-		  flow.dstIPAddr = hdr->iph.daddr;
-		  flow.pktInfo.l3Proto.proto = proto;
-		  break;
-	   case AVM_PA_IPV6:
-		  break;
-	   case AVM_PA_PORTS:
-		  flow.otherInfo.tcpUdpInfo.srcPort = ntohs(hdr->ports[0]);
-		  flow.otherInfo.tcpUdpInfo.dstPort = ntohs(hdr->ports[1]);
-		  break;
-	   default:
-		  AVM_PA_FUSIV_DBG("avm_pa_fusiv_add_session_v4: can not accelerate, unsupported ingress match type %d \n", p->type);
-		  return res;
-	   }
-	}
+   proto = avm_session->ingress.pkttype & AVM_PA_PKTTYPE_PROTO_MASK;
 
-	for (i = 0; i < avm_session->egress[0].match.nmatch; i++) {
-	   struct avm_pa_match_info *p = avm_session->egress[0].match.match+i;
-	   hdrunion_t *hdr = (hdrunion_t *)&avm_session->egress[0].match.hdrcopy[p->offset + avm_session->egress[0].match.hdroff ];
-		
-	   switch (p->type) {
-	   case AVM_PA_VLAN:
-		  if (flow.operations & (1 << AP_ADD_VLAN_HDR_BIT))
-			 return AVM_PA_TX_ERROR_SESSION;
-	      flow.vlanId = hdr->vlanh.vlan_tci;
-	      flow.operations |= (1 << AP_ADD_VLAN_HDR_BIT);
-		  break;
-	   case AVM_PA_ETH:
-		  memcpy(flow.srcMacAddr, &hdr->ethh.h_source, ETH_ALEN);
-		  memcpy(flow.dstMacAddr, &hdr->ethh.h_dest, ETH_ALEN);
-		  flow.operations |= (1 << AP_DO_ETH_HDR_BIT);
-		  break;
-	   case AVM_PA_PPP:
-		  break;
-	   case AVM_PA_PPPOE:
-		  {
-			 struct pppoehdr *pppoe_hdr = (struct pppoehdr *)(avm_session->egress[0].match.hdrcopy 
-									   + avm_session->egress[0].match.hdroff + avm_session->egress[0].pppoe_offset);
-			 flow.outSessionId = pppoe_hdr->sid;
-			 flow.operations |= (1 << AP_ADD_PPPOE_HDR_BIT);
-			 break;
-		  }
-	   case AVM_PA_IPV4:
-		  break;
-	   case AVM_PA_IPV6:
-		  memcpy(flow.srcIpv6Addr, hdr->ipv6h.saddr.s6_addr32, 16);
-		  memcpy(flow.dstIpv6Addr, hdr->ipv6h.daddr.s6_addr32, 16);
-		  flow.operations |= (1 << AP_IPV4_TO_IPV6_TUNNEL_BIT);
-		  break;
-	   case AVM_PA_PORTS:
-		  break;
-	   default:
-		  AVM_PA_FUSIV_DBG("avm_pa_fusiv_add_session_v4: can not accelerate, unsupported egress match type %d \n", p->type);
-		  break;
-	   }
-	}
+   memset(&flow, 0, sizeof(flow));
+#ifdef CONFIG_FUSIV_VX180
+   flow.entryType = AP_TCP_UDP_ENTRY;
+#endif
 
-	/* ATA -> LAN: add port VLAN for WAN Port */
-	if (   (flow.operations & (1 << AP_ADD_VLAN_HDR_BIT)) == 0
-		&& (egress_hw->apId == MAC1_ID) && (ingress_hw->apId == MAC1_ID)
-		&& (avm_session->egress[0].pid_handle != avm_session->ingress_pid_handle)) {
-	   flow.vlanId = avm_cpmac_get_wan_port_vlan();
-	   flow.operations |= (1 << AP_ADD_VLAN_HDR_BIT);
-	}
+   for (i = 0; i < avm_session->ingress.nmatch; i++) {
+      struct avm_pa_match_info *p = &avm_session->ingress.match[i];
+      hdrunion_t *hdr =
+         (hdrunion_t *) & avm_session->ingress.hdrcopy[p->offset +
+                                                       avm_session->ingress.
+                                                       hdroff];
 
-#if CONFIG_FUSIV_KERNEL_APSTATISTICS_PER_INTERFACE
-	memset(&flow.apStatistics, 0, sizeof(apStatistics_t));
-    memset(&new_session.prevStat, 0, sizeof(apStatistics_t));
+      switch (p->type) {
+         case AVM_PA_VLAN:
+            break;
+         case AVM_PA_ETH:
+#ifdef CONFIG_FUSIV_VX180
+            memcpy(flow.inSrcMacAddr, &hdr->ethh.h_source, ETH_ALEN);
+#else
+            memcpy(flow.apCompare.fields.inMAC, &hdr->ethh.h_source, ETH_ALEN);
 #endif
+            break;
+         case AVM_PA_PPP:
+            break;
+         case AVM_PA_PPPOE:
+            {
+#ifdef CONFIG_FUSIV_VX180
+               flow.inSessionId = hdr->pppoeh.sid;
+#else
+               flow.apCompare.inSessionID = hdr->pppoeh.sid;
+#endif
+               flow.operations |= (1 << AP_CHECK_PPPOE_BIT);
+            }
+            break;
+         case AVM_PA_IPV4:
+#ifdef CONFIG_FUSIV_VX180
+            flow.srcIPAddr = hdr->iph.saddr;
+            flow.dstIPAddr = hdr->iph.daddr;
+            flow.pktInfo.l3Proto.proto = proto;
+#else
+            flow.apCompare.srcIP = hdr->iph.saddr;
+            flow.apCompare.dstIP = hdr->iph.daddr;
+            flow.apCompare.protocol = proto;
+#endif
+            break;
+         case AVM_PA_IPV6:
+            break;
+         case AVM_PA_PORTS:
+#ifdef CONFIG_FUSIV_VX180
+            flow.otherInfo.tcpUdpInfo.srcPort = ntohs(hdr->ports[0]);
+            flow.otherInfo.tcpUdpInfo.dstPort = ntohs(hdr->ports[1]);
+#else
+            flow.apCompare.fields.ports.srcPort = ntohs(hdr->ports[0]);
+            flow.apCompare.fields.ports.dstPort = ntohs(hdr->ports[1]);
+#endif
+            break;
+         default:
+            AVM_PA_FUSIV_DBG
+               ("avm_pa_fusiv_add_session_v4: can not accelerate, unsupported ingress match type %d\n",
+                p->type);
+            return res;
+      }
+   }
 
-	if (avm_session->mod.v4_mod.flags & AVM_PA_V4_MOD_DADDR) {
-	   flow.natDstIPAddr = avm_session->mod.v4_mod.daddr;
-	   flow.natDstPort = flow.otherInfo.tcpUdpInfo.dstPort;
-	   flow.operations |= (1 << AP_DO_DST_NAT_BIT);
-	}
-	if (avm_session->mod.v4_mod.flags & AVM_PA_V4_MOD_DPORT) {
-	   flow.natDstPort = avm_session->mod.v4_mod.dport;
-	   flow.operations |= (1 << AP_DO_DST_NAT_BIT);
-	}
-	if (avm_session->mod.v4_mod.flags & AVM_PA_V4_MOD_SADDR) {
-	   flow.natIPAddr = avm_session->mod.v4_mod.saddr;
-	   flow.natPort = flow.otherInfo.tcpUdpInfo.srcPort;
-	   flow.operations |= (1 << AP_DO_SRC_NAT_BIT);
-	}
-	if (avm_session->mod.v4_mod.flags & AVM_PA_V4_MOD_SPORT) {
-	   flow.natPort = avm_session->mod.v4_mod.sport;
-	   flow.operations |= (1 << AP_DO_SRC_NAT_BIT);
-	}
+   for (i = 0; i < avm_session->egress[0].match.nmatch; i++) {
+      struct avm_pa_match_info *p = avm_session->egress[0].match.match + i;
+      hdrunion_t *hdr =
+         (hdrunion_t *) & avm_session->egress[0].match.hdrcopy[p->offset +
+                                                               avm_session->
+                                                               egress[0].match.
+                                                               hdroff];
 
-	priority = avm_session->egress[0].output.priority;
-	priority = (priority & TC_H_MIN_MASK);
-	if (priority > 7) priority = 7;
-	flow.egressList[0].pFlowID = (void *) priority;
+      switch (p->type) {
+         case AVM_PA_VLAN:
+            if (flow.operations & (1 << AP_ADD_VLAN_HDR_BIT))
+               return AVM_PA_TX_ERROR_SESSION;
+#ifdef CONFIG_FUSIV_VX180
+            flow.vlanId = hdr->vlanh.vlan_tci;
+#else
+            flow.apModify.vlanID = hdr->vlanh.vlan_tci;
+            flow.apModify.etherType = 0x8100;
+#endif
+            flow.operations |= (1 << AP_ADD_VLAN_HDR_BIT);
+            break;
+         case AVM_PA_ETH:
+#ifdef CONFIG_FUSIV_VX180
+            memcpy(flow.srcMacAddr, &hdr->ethh.h_source, ETH_ALEN);
+            memcpy(flow.dstMacAddr, &hdr->ethh.h_dest, ETH_ALEN);
+#else
+            memcpy(flow.apModify.srcMAC, &hdr->ethh.h_source, ETH_ALEN);
+            memcpy(flow.apModify.dstMAC, &hdr->ethh.h_dest, ETH_ALEN);
+#endif
+            flow.operations |= (1 << AP_DO_ETH_HDR_BIT);
+            break;
+         case AVM_PA_PPP:
+            break;
+         case AVM_PA_PPPOE:
+            {
+               struct pppoehdr *pppoe_hdr =
+                  (struct pppoehdr *) (avm_session->egress[0].match.hdrcopy +
+                                       avm_session->egress[0].match.hdroff +
+                                       avm_session->egress[0].pppoe_offset);
+#ifdef CONFIG_FUSIV_VX180
+               flow.outSessionId = pppoe_hdr->sid;
+#else
+               flow.apModify.sessionID = pppoe_hdr->sid;
+               flow.apModify.etherType = 0x8864;
+#endif
+               flow.operations |= (1 << AP_ADD_PPPOE_HDR_BIT);
+               break;
+            }
+         case AVM_PA_IPV4:
+            break;
+         case AVM_PA_IPV6:
+#ifdef CONFIG_FUSIV_VX180
+            memcpy(flow.srcIpv6Addr, hdr->ipv6h.saddr.s6_addr32, 16);
+            memcpy(flow.dstIpv6Addr, hdr->ipv6h.daddr.s6_addr32, 16);
+            flow.operations |= (1 << AP_IPV4_TO_IPV6_TUNNEL_BIT);
+#endif
+            break;
+         case AVM_PA_PORTS:
+            break;
+         default:
+            AVM_PA_FUSIV_DBG
+               ("avm_pa_fusiv_add_session_v4: can not accelerate, unsupported egress match type %d\n",
+                p->type);
+            break;
+      }
+   }
 
-	mtu = avm_session->egress[0].mtu;
-	flow.egressList[0].pFlowID = (void *)((UINT32)flow.egressList[0].pFlowID |
-		              (UINT32)(mtu) << MTU_SIZE_OFFSET_INSIDE_FLOW_ID);
+   /*
+    * ATA -> LAN: add port VLAN for WAN Port 
+    */
+   if ((flow.operations & (1 << AP_ADD_VLAN_HDR_BIT)) == 0
+       && (egress_hw->apId == MAC1_ID) && (ingress_hw->apId == MAC1_ID)
+       && (avm_session->egress[0].pid_handle !=
+           avm_session->ingress_pid_handle)) {
+#ifdef CONFIG_FUSIV_VX180
+      flow.vlanId = avm_cpmac_get_wan_port_vlan();
+      flow.operations |= (1 << AP_ADD_VLAN_HDR_BIT);
+#else
+      flow.apModify.vlanID = avm_cpmac_get_wan_port_vlan();
+      flow.operations |= (1 << AP_ADD_VLAN_HDR_BIT);
+#endif
+   }
+#if defined(CONFIG_FUSIV_VX180) && defined(CONFIG_FUSIV_KERNEL_APSTATISTICS_PER_INTERFACE)
+   memset(&flow.apStatistics, 0, sizeof(apStatistics_t));
+   memset(&new_session.prevStat, 0, sizeof(apStatistics_t));
+#endif
+
+   if (avm_session->mod.v4_mod.flags & AVM_PA_V4_MOD_DADDR) {
+#ifdef CONFIG_FUSIV_VX180
+      flow.natDstIPAddr = avm_session->mod.v4_mod.daddr;
+      flow.natDstPort = flow.otherInfo.tcpUdpInfo.dstPort;
+#else
+      flow.apModify.natIP = avm_session->mod.v4_mod.daddr;
+      flow.apModify.natPort = flow.apCompare.fields.ports.dstPort;
+#endif
+      flow.operations |= (1 << AP_DO_DST_NAT_BIT);
+   }
+   if (avm_session->mod.v4_mod.flags & AVM_PA_V4_MOD_DPORT) {
+#ifdef CONFIG_FUSIV_VX180
+      flow.natDstPort = avm_session->mod.v4_mod.dport;
+#else
+      flow.apModify.natPort = avm_session->mod.v4_mod.dport;
+#endif
+      flow.operations |= (1 << AP_DO_DST_NAT_BIT);
+   }
+   if (avm_session->mod.v4_mod.flags & AVM_PA_V4_MOD_SADDR) {
+#ifdef CONFIG_FUSIV_VX180
+      flow.natIPAddr = avm_session->mod.v4_mod.saddr;
+      flow.natPort = flow.otherInfo.tcpUdpInfo.srcPort;
+#else
+      flow.apModify.natIP = avm_session->mod.v4_mod.saddr;
+      flow.apModify.natPort = flow.apCompare.fields.ports.srcPort;
+#endif
+      flow.operations |= (1 << AP_DO_SRC_NAT_BIT);
+   }
+   if (avm_session->mod.v4_mod.flags & AVM_PA_V4_MOD_SPORT) {
+#ifdef CONFIG_FUSIV_VX180
+      flow.natPort = avm_session->mod.v4_mod.sport;
+#else
+      flow.apModify.natPort = avm_session->mod.v4_mod.sport;
+#endif
+      flow.operations |= (1 << AP_DO_SRC_NAT_BIT);
+   }
+
+   priority = avm_session->egress[0].output.priority;
+   priority = (priority & TC_H_MIN_MASK);
+   if (priority > 7)
+      priority = 7;
+   flow.egressList[0].pFlowID = (void *) priority;
+
+   mtu = avm_session->egress[0].mtu;
+   flow.egressList[0].pFlowID = (void *) ((UINT32) flow.egressList[0].pFlowID |
+                                          (UINT32) (mtu) <<
+                                          MTU_SIZE_OFFSET_INSIDE_FLOW_ID);
 
    if (egress_hw->apId == PERI_ID) {
-	   flow.egressList[0].pEgress = (void *)0xFFFFFFFF;
-	   flow.egressList[1].pEgress = &tx_info_route;
-	} else {
-	   flow.egressList[0].pEgress = (void *)(K1_TO_PHYS(apArray[egress_hw->apId].apTxFifo));
-	}
+      flow.egressList[0].pEgress = (void *) 0xFFFFFFFF;
+      flow.egressList[1].pEgress = &tx_info_route;
+   } else {
+      flow.egressList[0].pEgress =
+         (void *) (K1_TO_PHYS(apArray[egress_hw->apId].apTxFifo));
+   }
 
-	flow.userHandle = (unsigned int)&fusiv_session_array[ avm_session->session_handle ];
-	flow.operations |= (0x1 << AP_ROUTE_VALID_BIT);
+   flow.userHandle =
+      (unsigned int) &fusiv_session_array[avm_session->session_handle];
+   flow.operations |= (0x1 << AP_ROUTE_VALID_BIT);
 
-	flowhash = apCalculateHash(ingress_hw->apId, &flow);
+   flowhash = apCalculateHash(ingress_hw->apId, &flow);
 
-	rc = apAddFlowEntry(ingress_hw->apId, flowhash, &flow, &newflow);
+   rc = apAddFlowEntry(ingress_hw->apId, flowhash, &flow, &newflow);
 
-	if (rc != 0) {
-	   AVM_PA_FUSIV_DBG("avm_pa_fusiv_add_session_v4: can not accelerate, apAddFlowEntry returned %d \n", rc);
-	   return res;
-	}
+   if (rc != 0) {
+      AVM_PA_FUSIV_DBG
+         ("avm_pa_fusiv_add_session_v4: can not accelerate, apAddFlowEntry returned %d\n",
+          rc);
+      return res;
+   }
 
-	new_session.avm_session = avm_session;
-	new_session.valid_session = 1;
-	new_session.rxApId = ingress_hw->apId;
-	new_session.txApId = egress_hw->apId;
-	new_session.flowhash = flowhash;
-	new_session.flow.v4 = newflow;
-	new_session.flowtype = fusiv_flow_v4;
+   new_session.avm_session = avm_session;
+   new_session.valid_session = 1;
+   new_session.rxApId = ingress_hw->apId;
+   new_session.txApId = egress_hw->apId;
+   new_session.flowhash = flowhash;
+   new_session.flow.v4 = newflow;
+   new_session.flowtype = fusiv_flow_v4;
+   new_session.bridgeFlow = 0;
 
-    mac2str(flow.srcMacAddr, srcmac, sizeof(srcmac));
-    mac2str(flow.dstMacAddr, dstmac, sizeof(dstmac));
-    mac2str(flow.inSrcMacAddr, insrc, sizeof(insrc));
-	AVM_PA_FUSIV_DBG("apAddFlowEntry: AP#%d->AP#%d srcmac %s dstmac %s insrc %s\n",
-		   ingress_hw->apId, egress_hw->apId, srcmac, dstmac, insrc);
-	
-	// take_session_lock
-	spin_lock_irqsave( &session_list_lock, slock_flags);
-	if ( !fusiv_session_array[ avm_session->session_handle ].valid_session ){
-		fusiv_session_array[ avm_session->session_handle ] = new_session;
-		res = AVM_PA_TX_SESSION_ADDED;
-	} else {
-        AVM_PA_FUSIV_DBG("session add failed - double call for add by avm_pa?!");
-        dump_stack();
-	}
-	// release_session_lock
-	spin_unlock_irqrestore( &session_list_lock, slock_flags);
+#ifdef CONFIG_FUSIV_VX180
+   mac2str(flow.srcMacAddr, srcmac, sizeof(srcmac));
+   mac2str(flow.dstMacAddr, dstmac, sizeof(dstmac));
+   mac2str(flow.inSrcMacAddr, insrc, sizeof(insrc));
+#else
+   mac2str(flow.apModify.srcMAC, srcmac, sizeof(srcmac));
+   mac2str(flow.apModify.dstMAC, dstmac, sizeof(dstmac));
+   mac2str(flow.apCompare.fields.inMAC, insrc, sizeof(insrc));
+#endif
+   AVM_PA_FUSIV_DBG
+      ("apAddFlowEntry: AP#%d->AP#%d srcmac %s dstmac %s insrc %s\n",
+       ingress_hw->apId, egress_hw->apId, srcmac, dstmac, insrc);
 
-	AVM_PA_FUSIV_DBG("avm_pa_fusiv_add_session_v4: done\n");
+   // take_session_lock
+   spin_lock_irqsave(&session_list_lock, slock_flags);
+   if (!fusiv_session_array[avm_session->session_handle].valid_session) {
+      fusiv_session_array[avm_session->session_handle] = new_session;
+      res = AVM_PA_TX_SESSION_ADDED;
+   } else {
+      UINT32 moved;
+      if (apDeleteFlowEntry(ingress_hw->apId, flowhash, newflow, &moved) == 0) {
+         if (moved) {
+            struct avm_pa_fusiv_session *fusiv_session = (struct avm_pa_fusiv_session *) (newflow->userHandle);
+            fusiv_session->flow.v4 = newflow;
+         }
+      }
+      printk(KERN_CRIT "session add failed - double call for add by avm_pa?!");
+      dump_stack();
+   }
+   // release_session_lock
+   spin_unlock_irqrestore(&session_list_lock, slock_flags);
 
-    return res;
+   AVM_PA_FUSIV_DBG("avm_pa_fusiv_add_session_v4: done\n");
+
+   return res;
 }
 
-static int avm_pa_fusiv_add_session_v6(struct avm_pa_session *avm_session) {
-    unsigned long slock_flags;
-    int i, rc;
-    struct avm_pa_fusiv_session new_session;
-    int res = AVM_PA_TX_ERROR_SESSION;
-	apIpv6FlowEntry_t flow;
-	apIpv6FlowEntry_t *newflow;
-	unsigned int proto, priority;
-	struct avm_pa_pid_hwinfo *ingress_hw, *egress_hw;
-	unsigned short flowhash;
-	char srcmac[32], dstmac[32], insrc[32];
+static int avm_pa_fusiv_add_session_v6(struct avm_pa_session *avm_session)
+{
+   unsigned long slock_flags;
+   int i, rc;
+   struct avm_pa_fusiv_session new_session;
+   int res = AVM_PA_TX_ERROR_SESSION;
+   apIpv6FlowEntry_t flow;
+   apIpv6FlowEntry_t *newflow;
+   unsigned int proto, priority;
+   struct avm_pa_pid_hwinfo *ingress_hw, *egress_hw;
+   unsigned short flowhash;
+   char srcmac[32], dstmac[32], insrc[32];
 
-	AVM_PA_FUSIV_DBG("avm_pa_fusiv_add_session_v6: start\n");
-	
-	ingress_hw = avm_pa_pid_get_hwinfo( avm_session->ingress_pid_handle );
-	egress_hw  = avm_pa_pid_get_hwinfo( avm_session->egress[0].pid_handle );
+   AVM_PA_FUSIV_DBG("avm_pa_fusiv_add_session_v6: start\n");
 
-	proto = avm_session->ingress.pkttype & AVM_PA_PKTTYPE_PROTO_MASK;
+   ingress_hw = avm_pa_pid_get_hwinfo(avm_session->ingress_pid_handle);
+   egress_hw = avm_pa_pid_get_hwinfo(avm_session->egress[0].pid_handle);
 
-	memset(&flow, 0, sizeof(flow));
+   if (ingress_hw == 0 || egress_hw == 0)
+      return res;
 
-	if (proto == IPPROTO_UDP)
-	   flow.entryType = AP_UDP_ENTRY;
-	else if (proto == IPPROTO_TCP)
-	   flow.entryType = AP_TCP_ENTRY;
-	else {
-	   AVM_PA_FUSIV_DBG("avm_pa_fusiv_add_session_v6: unsupported protocol %u\n", proto);
-	   return res;
-	}
+   if (ingress_hw->apId == PERI_ID || egress_hw->apId == PERI_ID)
+      return res;
 
-	for (i = 0; i < avm_session->ingress.nmatch; i++) {
-	   struct avm_pa_match_info *p = &avm_session->ingress.match[i];
-	   hdrunion_t *hdr = (hdrunion_t *)&avm_session->ingress.hdrcopy[p->offset + avm_session->ingress.hdroff];
-	   
-	   switch (p->type) {
-	   case AVM_PA_VLAN:
-		  break;
-	   case AVM_PA_ETH:
-		  memcpy(&flow.inSrcMacAddr, &hdr->ethh.h_source, ETH_ALEN);
-		  break;
-	   case AVM_PA_PPP:
-		  break;
-	   case AVM_PA_PPPOE:
-		  {
-			 flow.inSessionId = hdr->pppoeh.sid;
-		     flow.operations |= (1 << AP_CHECK_PPPOE_BIT);
-		  }
-		  break;
-	   case AVM_PA_IPV4:
-		  break;
-	   case AVM_PA_IPV6:
-		  memcpy(flow.srcIpv6Addr, hdr->ipv6h.saddr.s6_addr32, 16);
-		  memcpy(flow.dstIpv6Addr, hdr->ipv6h.daddr.s6_addr32, 16);
-		  break;
-	   case AVM_PA_PORTS:
-		  flow.otherInfo.tcpUdpInfo.srcPort = ntohs(hdr->ports[0]);
-		  flow.otherInfo.tcpUdpInfo.dstPort = ntohs(hdr->ports[1]);
-		  break;
-	   default:
-		  AVM_PA_FUSIV_DBG("avm_pa_fusiv_add_session_v6: can not accelerate, unsupported ingress match type %d \n", p->type);
-		  return res;
-	   }
-	}
+   proto = avm_session->ingress.pkttype & AVM_PA_PKTTYPE_PROTO_MASK;
 
-	for (i = 0; i < avm_session->egress[0].match.nmatch; i++) {
-	   struct avm_pa_match_info *p = avm_session->egress[0].match.match+i;
-	   hdrunion_t *hdr = (hdrunion_t *)&avm_session->egress[0].match.hdrcopy[p->offset + avm_session->egress[0].match.hdroff ];
-		
-	   switch (p->type) {
-	   case AVM_PA_VLAN:
-	      if (flow.operations & (1 << AP_ADD_VLAN_HDR_BIT))
-		     return AVM_PA_TX_ERROR_SESSION;
-	      flow.vlanId = hdr->vlanh.vlan_tci;
-	      flow.operations |= (1 << AP_ADD_VLAN_HDR_BIT);
-		  break;
-	   case AVM_PA_ETH:
-		  memcpy(flow.srcMacAddr, &hdr->ethh.h_source, ETH_ALEN);
-		  memcpy(flow.dstMacAddr, &hdr->ethh.h_dest, ETH_ALEN);
-		  flow.operations |= (1 << AP_DO_ETH_HDR_BIT);
-		  break;
-	   case AVM_PA_PPP:
-		  break;
-	   case AVM_PA_PPPOE:
-		  {
-			 struct pppoehdr *pppoe_hdr = (struct pppoehdr *)(avm_session->egress[0].match.hdrcopy 
-									   + avm_session->egress[0].match.hdroff + avm_session->egress[0].pppoe_offset);
-			 flow.outSessionId = pppoe_hdr->sid;
-			 flow.operations |= (1 << AP_ADD_PPPOE_HDR_BIT);
-			 break;
-		  }
-	   case AVM_PA_IPV4:
-		  flow.srcIPAddr = hdr->iph.saddr;
-		  flow.dstIPAddr = hdr->iph.daddr;
-		  flow.operations |= (0x1 << AP_IPV6_TO_IPV4_TUNNEL_BIT);
-		  break;
-	   case AVM_PA_IPV6:
-		  break;
-	   case AVM_PA_PORTS:
-		  break;
-	   default:
-		  AVM_PA_FUSIV_DBG("avm_pa_fusiv_add_session_v6: can not accelerate, unsupported egress match type %d \n", p->type);
-		  break;
-	   }
-	}
+   memset(&flow, 0, sizeof(flow));
 
-	/* ATA -> LAN: add port VLAN for WAN Port */
-	if (   (flow.operations & (1 << AP_ADD_VLAN_HDR_BIT)) == 0
-	    && (egress_hw->apId == MAC1_ID) && (ingress_hw->apId == MAC1_ID)
-		&& (avm_session->egress[0].pid_handle != avm_session->ingress_pid_handle)) {
-	   flow.vlanId = avm_cpmac_get_wan_port_vlan();
-	   flow.operations |= (1 << AP_ADD_VLAN_HDR_BIT);
-	}
+#ifdef CONFIG_FUSIV_VX180
+   if (proto == IPPROTO_UDP) {
+      flow.entryType = AP_UDP_ENTRY;
+   } else if (proto == IPPROTO_TCP) {
+      flow.entryType = AP_TCP_ENTRY;
+   } else {
+      AVM_PA_FUSIV_DBG("avm_pa_fusiv_add_session_v6: unsupported protocol %u\n",
+                       proto);
+      return res;
+   }
+#endif
 
-#if CONFIG_FUSIV_KERNEL_APSTATISTICS_PER_INTERFACE
-	memset(&flow.apStatistics, 0, sizeof(apStatistics_t));
-    memset(&new_session.prevStat, 0, sizeof(apStatistics_t));
+   for (i = 0; i < avm_session->ingress.nmatch; i++) {
+      struct avm_pa_match_info *p = &avm_session->ingress.match[i];
+      hdrunion_t *hdr =
+         (hdrunion_t *) & avm_session->ingress.hdrcopy[p->offset +
+                                                       avm_session->ingress.
+                                                       hdroff];
+
+      switch (p->type) {
+         case AVM_PA_VLAN:
+            break;
+         case AVM_PA_ETH:
+#ifdef CONFIG_FUSIV_VX180
+            memcpy(&flow.inSrcMacAddr, &hdr->ethh.h_source, ETH_ALEN);
+#else
+            memcpy(&flow.apCompare.inMAC, &hdr->ethh.h_source, ETH_ALEN);
 #endif
+            break;
+         case AVM_PA_PPP:
+            break;
+         case AVM_PA_PPPOE:
+            {
+#ifdef CONFIG_FUSIV_VX180
+               flow.inSessionId = hdr->pppoeh.sid;
+#else
+               flow.apCompare.inSessionID = hdr->pppoeh.sid;
+#endif
+               flow.operations |= (1 << AP_CHECK_PPPOE_BIT);
+            }
+            break;
+         case AVM_PA_IPV4:
+            break;
+         case AVM_PA_IPV6:
+#ifdef CONFIG_FUSIV_VX180
+            memcpy(flow.srcIpv6Addr, hdr->ipv6h.saddr.s6_addr32, 16);
+            memcpy(flow.dstIpv6Addr, hdr->ipv6h.daddr.s6_addr32, 16);
+#else
+            memcpy(flow.apCompare.srcIpv6Addr, hdr->ipv6h.saddr.s6_addr32, 16);
+            memcpy(flow.apCompare.dstIpv6Addr, hdr->ipv6h.daddr.s6_addr32, 16);
+#endif
+            break;
+         case AVM_PA_PORTS:
+#ifdef CONFIG_FUSIV_VX180
+            flow.otherInfo.tcpUdpInfo.srcPort = ntohs(hdr->ports[0]);
+            flow.otherInfo.tcpUdpInfo.dstPort = ntohs(hdr->ports[1]);
+#else
+            flow.apCompare.fields.ports.srcPort = ntohs(hdr->ports[0]);
+            flow.apCompare.fields.ports.dstPort = ntohs(hdr->ports[1]);
+#endif
+            break;
+         default:
+            AVM_PA_FUSIV_DBG
+               ("avm_pa_fusiv_add_session_v6: can not accelerate, unsupported ingress match type %d\n",
+                p->type);
+            return res;
+      }
+   }
 
-	priority = avm_session->egress[0].output.priority;
-	priority = (priority & TC_H_MIN_MASK);
-	if (priority > 7) priority = 7;
+   for (i = 0; i < avm_session->egress[0].match.nmatch; i++) {
+      struct avm_pa_match_info *p = avm_session->egress[0].match.match + i;
+      hdrunion_t *hdr =
+         (hdrunion_t *) & avm_session->egress[0].match.hdrcopy[p->offset +
+                                                               avm_session->
+                                                               egress[0].match.
+                                                               hdroff];
 
-	flow.userHandle = (unsigned int)&fusiv_session_array[ avm_session->session_handle ];
-	flow.egressList[0].pEgress = (void *)(K1_TO_PHYS(apArray[egress_hw->apId].apTxFifo));
-	flow.egressList[0].pFlowID = (void *) priority;
-	flow.operations |= (0x1 << AP_ROUTE_VALID_BIT);
+      switch (p->type) {
+         case AVM_PA_VLAN:
+            if (flow.operations & (1 << AP_ADD_VLAN_HDR_BIT))
+               return AVM_PA_TX_ERROR_SESSION;
 
-	flowhash = apIpv6CalculateHash(ingress_hw->apId, &flow);
+#ifdef CONFIG_FUSIV_VX180
+            flow.vlanId = hdr->vlanh.vlan_tci;
+#else
+            flow.apModify.vlanID = hdr->vlanh.vlan_tci;
+#endif
+            flow.operations |= (1 << AP_ADD_VLAN_HDR_BIT);
+            break;
+         case AVM_PA_ETH:
+#ifdef CONFIG_FUSIV_VX180
+            memcpy(flow.srcMacAddr, &hdr->ethh.h_source, ETH_ALEN);
+            memcpy(flow.dstMacAddr, &hdr->ethh.h_dest, ETH_ALEN);
+#else
+            memcpy(flow.apModify.srcMacAddr, &hdr->ethh.h_source, ETH_ALEN);
+            memcpy(flow.apModify.dstMacAddr, &hdr->ethh.h_dest, ETH_ALEN);
+#endif
+            flow.operations |= (1 << AP_DO_ETH_HDR_BIT);
+            break;
+         case AVM_PA_PPP:
+            break;
+         case AVM_PA_PPPOE:
+            {
+               struct pppoehdr *pppoe_hdr =
+                  (struct pppoehdr *) (avm_session->egress[0].match.hdrcopy +
+                                       avm_session->egress[0].match.hdroff +
+                                       avm_session->egress[0].pppoe_offset);
+#ifdef CONFIG_FUSIV_VX180
+               flow.outSessionId = pppoe_hdr->sid;
+#else
+               flow.apModify.sessionID = pppoe_hdr->sid;
+#endif
+               flow.operations |= (1 << AP_ADD_PPPOE_HDR_BIT);
+               break;
+            }
+         case AVM_PA_IPV4:
+#ifdef CONFIG_FUSIV_VX180
+            flow.srcIPAddr = hdr->iph.saddr;
+            flow.dstIPAddr = hdr->iph.daddr;
+            flow.operations |= (0x1 << AP_IPV6_TO_IPV4_TUNNEL_BIT);
+#endif
+            break;
+         case AVM_PA_IPV6:
+            break;
+         case AVM_PA_PORTS:
+            break;
+         default:
+            AVM_PA_FUSIV_DBG
+               ("avm_pa_fusiv_add_session_v6: can not accelerate, unsupported egress match type %d\n",
+                p->type);
+            break;
+      }
+   }
 
-	rc = apIpv6AddFlowEntry(ingress_hw->apId, flowhash, &flow, &newflow);
+   /*
+    * ATA -> LAN: add port VLAN for WAN Port 
+    */
+   if ((flow.operations & (1 << AP_ADD_VLAN_HDR_BIT)) == 0
+       && (egress_hw->apId == MAC1_ID) && (ingress_hw->apId == MAC1_ID)
+       && (avm_session->egress[0].pid_handle !=
+           avm_session->ingress_pid_handle)) {
+#ifdef CONFIG_FUSIV_VX180
+      flow.vlanId = avm_cpmac_get_wan_port_vlan();
+      flow.operations |= (1 << AP_ADD_VLAN_HDR_BIT);
+#else
+      flow.apModify.vlanID = avm_cpmac_get_wan_port_vlan();
+      flow.operations |= (1 << AP_ADD_VLAN_HDR_BIT);
+#endif
+   }
+#if defined(CONFIG_FUSIV_VX180) && defined(CONFIG_FUSIV_KERNEL_APSTATISTICS_PER_INTERFACE)
+   memset(&flow.apStatistics, 0, sizeof(apStatistics_t));
+   memset(&new_session.prevStat, 0, sizeof(apStatistics_t));
+#endif
 
-	if (rc != 0) {
-	   AVM_PA_FUSIV_DBG("avm_pa_fusiv_add_session_v6: can not accelerate, apAddFlowEntry returned %d \n", rc);
-	   return res;
-	}
+   priority = avm_session->egress[0].output.priority;
+   priority = (priority & TC_H_MIN_MASK);
+   if (priority > 7)
+      priority = 7;
 
-	new_session.avm_session = avm_session;
-	new_session.valid_session = 1;
-	new_session.rxApId = ingress_hw->apId;
-	new_session.txApId = egress_hw->apId;
-	new_session.flowhash = flowhash;
-	new_session.flow.v6 = newflow;
-	new_session.flowtype = fusiv_flow_v6;
+   flow.userHandle =
+      (unsigned int) &fusiv_session_array[avm_session->session_handle];
+   flow.egressList[0].pEgress =
+      (void *) (K1_TO_PHYS(apArray[egress_hw->apId].apTxFifo));
+   flow.egressList[0].pFlowID = (void *) priority;
+   flow.operations |= (0x1 << AP_ROUTE_VALID_BIT);
 
-    mac2str(flow.srcMacAddr, srcmac, sizeof(srcmac));
-    mac2str(flow.dstMacAddr, dstmac, sizeof(dstmac));
-    mac2str(flow.inSrcMacAddr, insrc, sizeof(insrc));
-	AVM_PA_FUSIV_DBG("apAddFlowEntry: AP#%d->AP#%d srcmac %s dstmac %s insrc %s\n",
-		   ingress_hw->apId, egress_hw->apId, srcmac, dstmac, insrc);
-	
-	// take_session_lock
-	spin_lock_irqsave( &session_list_lock, slock_flags);
-	if ( !fusiv_session_array[ avm_session->session_handle ].valid_session ){
-		fusiv_session_array[ avm_session->session_handle ] = new_session;
-		res = AVM_PA_TX_SESSION_ADDED;
-	} else {
-        AVM_PA_FUSIV_DBG("session add failed - double call for add by avm_pa?!");
-        dump_stack();
-	}
-	// release_session_lock
-	spin_unlock_irqrestore( &session_list_lock, slock_flags);
+   flowhash = apIpv6CalculateHash(ingress_hw->apId, &flow);
 
-	AVM_PA_FUSIV_DBG("avm_pa_fusiv_add_session_v6: done\n");
+   rc = apIpv6AddFlowEntry(ingress_hw->apId, flowhash, &flow, &newflow);
 
-    return res;
+   if (rc != 0) {
+      AVM_PA_FUSIV_DBG
+         ("avm_pa_fusiv_add_session_v6: can not accelerate, apAddFlowEntry returned %d\n",
+          rc);
+      return res;
+   }
+
+   new_session.avm_session = avm_session;
+   new_session.valid_session = 1;
+   new_session.rxApId = ingress_hw->apId;
+   new_session.txApId = egress_hw->apId;
+   new_session.flowhash = flowhash;
+   new_session.flow.v6 = newflow;
+   new_session.flowtype = fusiv_flow_v6;
+   new_session.bridgeFlow = 0;
+
+#ifdef CONFIG_FUSIV_VX180
+   mac2str(flow.srcMacAddr, srcmac, sizeof(srcmac));
+   mac2str(flow.dstMacAddr, dstmac, sizeof(dstmac));
+   mac2str(flow.inSrcMacAddr, insrc, sizeof(insrc));
+#else
+   mac2str(flow.apModify.srcMacAddr, srcmac, sizeof(srcmac));
+   mac2str(flow.apModify.dstMacAddr, dstmac, sizeof(dstmac));
+   mac2str(flow.apCompare.inMAC, insrc, sizeof(insrc));
+#endif
+
+   AVM_PA_FUSIV_DBG
+      ("apAddFlowEntry: AP#%d->AP#%d srcmac %s dstmac %s insrc %s\n",
+       ingress_hw->apId, egress_hw->apId, srcmac, dstmac, insrc);
+
+   // take_session_lock
+   spin_lock_irqsave(&session_list_lock, slock_flags);
+   if (!fusiv_session_array[avm_session->session_handle].valid_session) {
+      fusiv_session_array[avm_session->session_handle] = new_session;
+      res = AVM_PA_TX_SESSION_ADDED;
+   } else {
+      UINT32 moved;
+      if (apIpv6DeleteFlowEntry(ingress_hw->apId, flowhash, newflow, &moved) == 0) {
+         if (moved) {
+            struct avm_pa_fusiv_session *fusiv_session = (struct avm_pa_fusiv_session *) (newflow->userHandle);
+            fusiv_session->flow.v6 = newflow;
+         }
+      }
+      printk(KERN_CRIT "session add failed - double call for add by avm_pa?!");
+      dump_stack();
+   }
+   // release_session_lock
+   spin_unlock_irqrestore(&session_list_lock, slock_flags);
+
+   AVM_PA_FUSIV_DBG("avm_pa_fusiv_add_session_v6: done\n");
+
+   return res;
 }
 
-static int avm_pa_fusiv_add_session(struct avm_pa_session *avm_session) {
-	struct avm_pa_pkt_match *ingress;
-	struct avm_pa_egress *egress;
-	struct avm_pa_pid_hwinfo *ingress_hw, *egress_hw;
-	unsigned int proto;
-	static int called = 0;
-	unsigned short hash;
+static int avm_pa_fusiv_add_session(struct avm_pa_session *avm_session)
+{
+   struct avm_pa_pkt_match *ingress;
+   struct avm_pa_egress *egress;
+   struct avm_pa_pid_hwinfo *ingress_hw, *egress_hw;
+   unsigned int proto;
 
-    BUG_ON( avm_session->session_handle >= CONFIG_AVM_PA_MAX_SESSION);
+   BUG_ON(avm_session->session_handle >= CONFIG_AVM_PA_MAX_SESSION);
 
-	if (avm_session->negress != 1) {
-	   AVM_PA_FUSIV_DBG("avm_pa_fusiv_add_session: can not accelerate, egress = %d\n", avm_session->negress);
-	   return AVM_PA_TX_ERROR_SESSION;
-	}
+   if (avm_session->negress != 1) {
+      AVM_PA_FUSIV_DBG
+         ("avm_pa_fusiv_add_session: can not accelerate, egress = %d\n",
+          avm_session->negress);
+      return AVM_PA_TX_ERROR_SESSION;
+   }
 
-	ingress = &avm_session->ingress;
-	egress = &avm_session->egress[0];
-	ingress_hw = avm_pa_pid_get_hwinfo( avm_session->ingress_pid_handle );
-	egress_hw  = avm_pa_pid_get_hwinfo( avm_session->egress[0].pid_handle );
+   ingress = &avm_session->ingress;
+   egress = &avm_session->egress[0];
+   ingress_hw = avm_pa_pid_get_hwinfo(avm_session->ingress_pid_handle);
+   egress_hw = avm_pa_pid_get_hwinfo(avm_session->egress[0].pid_handle);
 
-	if (!ingress_hw || !egress_hw) {
-	   AVM_PA_FUSIV_DBG("avm_pa_fusiv_add_session: can not accelerate, hw pointer not valid\n");
-	   return AVM_PA_TX_ERROR_SESSION;
-	}
+   if (!ingress_hw || !egress_hw) {
+      AVM_PA_FUSIV_DBG
+         ("avm_pa_fusiv_add_session: can not accelerate, hw pointer not valid\n");
+      return AVM_PA_TX_ERROR_SESSION;
+   }
 
-	if ((egress_hw->apId == 0) || (ingress_hw->apId == 0)) {
-	   AVM_PA_FUSIV_DBG("avm_pa_fusiv_add_session: can not accelerate, %s AP-ID is 0\n",
-			 egress_hw->apId ? "ingress" : "egress");
-	   return AVM_PA_TX_ERROR_SESSION;
-	}
-	if (egress_hw->apId == BMU_ID) {
-	   AVM_PA_FUSIV_DBG("avm_pa_fusiv_add_session: can not accelerate, AP-ID %d not supported\n",
-			 egress_hw->apId);
-	   return AVM_PA_TX_ERROR_SESSION;
-	}
+   if ((egress_hw->apId == 0) || (ingress_hw->apId == 0)) {
+      AVM_PA_FUSIV_DBG
+         ("avm_pa_fusiv_add_session: can not accelerate, %s AP-ID is 0\n",
+          egress_hw->apId ? "ingress" : "egress");
+      return AVM_PA_TX_ERROR_SESSION;
+   }
+   if (egress_hw->apId == BMU_ID) {
+      AVM_PA_FUSIV_DBG
+         ("avm_pa_fusiv_add_session: can not accelerate, AP-ID %d not supported\n",
+          egress_hw->apId);
+      return AVM_PA_TX_ERROR_SESSION;
+   }
 
-	if (avm_session->bsession)
-	   return avm_pa_fusiv_add_bridge_session(avm_session);
+   if (avm_session->bsession)
+      return avm_pa_fusiv_add_bridge_session(avm_session);
 
-	proto = avm_session->ingress.pkttype & AVM_PA_PKTTYPE_PROTO_MASK;
-	if (proto != IPPROTO_TCP && proto != IPPROTO_UDP) {
-	   AVM_PA_FUSIV_DBG("avm_pa_fusiv_add_session: can not accelerate, protocol %u not supported \n", proto);
-	   return AVM_PA_TX_ERROR_SESSION;
-	}
-	if ((ingress->pkttype & AVM_PA_PKTTYPE_LISP) || (egress->match.pkttype & AVM_PA_PKTTYPE_LISP)) {
-	   AVM_PA_FUSIV_DBG("avm_pa_fusiv_add_session: can not accelerate LISP tunnel packets \n");
-	   return AVM_PA_TX_ERROR_SESSION;
-	}
+   proto = avm_session->ingress.pkttype & AVM_PA_PKTTYPE_PROTO_MASK;
+   if (proto != IPPROTO_TCP && proto != IPPROTO_UDP) {
+      AVM_PA_FUSIV_DBG
+         ("avm_pa_fusiv_add_session: can not accelerate, protocol %u not supported \n",
+          proto);
+      return AVM_PA_TX_ERROR_SESSION;
+   }
+   if ((ingress->pkttype & AVM_PA_PKTTYPE_LISP)
+       || (egress->match.pkttype & AVM_PA_PKTTYPE_LISP)) {
+      AVM_PA_FUSIV_DBG
+         ("avm_pa_fusiv_add_session: can not accelerate LISP tunnel packets \n");
+      return AVM_PA_TX_ERROR_SESSION;
+   }
 
-	if (((ingress->pkttype & AVM_PA_PKTTYPE_IP_MASK) == AVM_PA_PKTTYPE_IPV4)) {
-	   /* IPV4 -> IPV4 */
-	   if (((ingress->pkttype & AVM_PA_PKTTYPE_IPENCAP_MASK) == AVM_PA_PKTTYPE_NONE)
-		   && (egress->match.pkttype & AVM_PA_PKTTYPE_IPENCAP_MASK) == AVM_PA_PKTTYPE_NONE)
-	      return avm_pa_fusiv_add_session_v4(avm_session);
-	   /* IPV4 -> IPV4 in IPV6 (DsLite) */
-	   if (((ingress->pkttype & AVM_PA_PKTTYPE_IPENCAP_MASK) == AVM_PA_PKTTYPE_NONE)
-		   && (egress->match.pkttype & AVM_PA_PKTTYPE_IPENCAP_MASK) == AVM_PA_PKTTYPE_IPV6ENCAP)
-	      return avm_pa_fusiv_add_session_v4(avm_session); /* currently buggy */
-	      //return AVM_PA_TX_ERROR_SESSION;
-	   /* IPV4 in IPV6 -> IPV4 (DsLite) */
-	   if (((ingress->pkttype & AVM_PA_PKTTYPE_IPENCAP_MASK) == AVM_PA_PKTTYPE_IPV6ENCAP)
-		   && (egress->match.pkttype & AVM_PA_PKTTYPE_IPENCAP_MASK) == AVM_PA_PKTTYPE_NONE)
-	      return avm_pa_fusiv_add_session_v4(avm_session);
-	} else if ((ingress->pkttype & AVM_PA_PKTTYPE_IP_MASK) == AVM_PA_PKTTYPE_IPV6) {
-	   /* IPV6 -> IPV6 */
-	   if (((ingress->pkttype & AVM_PA_PKTTYPE_IPENCAP_MASK) == AVM_PA_PKTTYPE_NONE)
-		   && (egress->match.pkttype & AVM_PA_PKTTYPE_IPENCAP_MASK) == AVM_PA_PKTTYPE_NONE)
-	      return avm_pa_fusiv_add_session_v6(avm_session);
-	   /* IPV6 -> IPV6 in IPV4 (6to4) */
-	   if (((ingress->pkttype & AVM_PA_PKTTYPE_IPENCAP_MASK) == AVM_PA_PKTTYPE_NONE)
-		   && (egress->match.pkttype & AVM_PA_PKTTYPE_IPENCAP_MASK) == AVM_PA_PKTTYPE_IPV4ENCAP)
-	      return avm_pa_fusiv_add_session_v6(avm_session);
-	   /* IPV6 in IPV4 -> IPV6 (6to4) */
-	   if (((ingress->pkttype & AVM_PA_PKTTYPE_IPENCAP_MASK) == AVM_PA_PKTTYPE_IPV4ENCAP)
-		   && (egress->match.pkttype & AVM_PA_PKTTYPE_IPENCAP_MASK) == AVM_PA_PKTTYPE_NONE)
-	      return avm_pa_fusiv_add_session_v6(avm_session);
-	}
-	AVM_PA_FUSIV_DBG("avm_pa_fusiv_add_session: can not accelerate, unsupported protocol\n");
-	return AVM_PA_TX_ERROR_SESSION;
+   if ((ingress->pkttype & AVM_PA_PKTTYPE_IP_MASK) == AVM_PA_PKTTYPE_IPV4) {
+      /*
+       * IPV4 -> IPV4 
+       */
+      if ((ingress->pkttype & AVM_PA_PKTTYPE_IPENCAP_MASK) ==
+          AVM_PA_PKTTYPE_NONE
+          && (egress->match.pkttype & AVM_PA_PKTTYPE_IPENCAP_MASK) ==
+          AVM_PA_PKTTYPE_NONE)
+         return avm_pa_fusiv_add_session_v4(avm_session);
+#ifdef CONFIG_FUSIV_VX180
+      /*
+       * IPV4 -> IPV4 in IPV6 (DsLite) 
+       */
+      if ((ingress->pkttype & AVM_PA_PKTTYPE_IPENCAP_MASK) ==
+          AVM_PA_PKTTYPE_NONE
+          && (egress->match.pkttype & AVM_PA_PKTTYPE_IPENCAP_MASK) ==
+          AVM_PA_PKTTYPE_IPV6ENCAP)
+         return avm_pa_fusiv_add_session_v4(avm_session); /* currently buggy */
+      /*
+       * IPV4 in IPV6 -> IPV4 (DsLite) 
+       */
+      if ((ingress->pkttype & AVM_PA_PKTTYPE_IPENCAP_MASK) ==
+          AVM_PA_PKTTYPE_IPV6ENCAP
+          && (egress->match.pkttype & AVM_PA_PKTTYPE_IPENCAP_MASK) ==
+          AVM_PA_PKTTYPE_NONE)
+         return avm_pa_fusiv_add_session_v4(avm_session);
+#endif
+   } else if ((ingress->pkttype & AVM_PA_PKTTYPE_IP_MASK) ==
+              AVM_PA_PKTTYPE_IPV6) {
+      /*
+       * IPV6 -> IPV6 
+       */
+      if ((ingress->pkttype & AVM_PA_PKTTYPE_IPENCAP_MASK) ==
+          AVM_PA_PKTTYPE_NONE
+          && (egress->match.pkttype & AVM_PA_PKTTYPE_IPENCAP_MASK) ==
+          AVM_PA_PKTTYPE_NONE)
+         return avm_pa_fusiv_add_session_v6(avm_session);
+#ifdef CONFIG_FUSIV_VX180
+      /*
+       * IPV6 -> IPV6 in IPV4 (6to4) 
+       */
+      if ((ingress->pkttype & AVM_PA_PKTTYPE_IPENCAP_MASK) ==
+          AVM_PA_PKTTYPE_NONE
+          && (egress->match.pkttype & AVM_PA_PKTTYPE_IPENCAP_MASK) ==
+          AVM_PA_PKTTYPE_IPV4ENCAP)
+         return avm_pa_fusiv_add_session_v6(avm_session);
+      /*
+       * IPV6 in IPV4 -> IPV6 (6to4) 
+       */
+      if ((ingress->pkttype & AVM_PA_PKTTYPE_IPENCAP_MASK) ==
+          AVM_PA_PKTTYPE_IPV4ENCAP
+          && (egress->match.pkttype & AVM_PA_PKTTYPE_IPENCAP_MASK) ==
+          AVM_PA_PKTTYPE_NONE)
+         return avm_pa_fusiv_add_session_v6(avm_session);
+#endif
+   }
+   AVM_PA_FUSIV_DBG
+      ("avm_pa_fusiv_add_session: can not accelerate, unsupported protocol\n");
+   return AVM_PA_TX_ERROR_SESSION;
 }
 
-
 /*------------------------------------------------------------------------------------------*\
 \*------------------------------------------------------------------------------------------*/
-static int avm_pa_fusiv_remove_session( struct avm_pa_session *avm_session ){
-	int status = AVM_PA_TX_ERROR_SESSION;
-    unsigned long slock_flags;
-    struct avm_pa_fusiv_session session_to_remove;
-	void *moved;
-	int rc = 0;
-	
-    BUG_ON( avm_session->session_handle >= CONFIG_AVM_PA_MAX_SESSION);
+static int avm_pa_fusiv_remove_session(struct avm_pa_session *avm_session)
+{
+   int status = AVM_PA_TX_ERROR_SESSION;
+   unsigned long slock_flags;
+   struct avm_pa_fusiv_session session_to_remove;
+   void *moved;
+   int rc = 0;
 
-    // take_session_lock
-	spin_lock_irqsave( &session_list_lock, slock_flags);
-    if ( ( avm_session == fusiv_session_array[ avm_session->session_handle ].avm_session)
-            && fusiv_session_array[ avm_session->session_handle ].valid_session ){
-        session_to_remove = fusiv_session_array[ avm_session->session_handle ];
-    } else {
-        // no valid session found
-        // release_session_lock and return
-	    spin_unlock_irqrestore( &session_list_lock, slock_flags);
-	    return status;
-    }
-    // release_session_lock
-	spin_unlock_irqrestore( &session_list_lock, slock_flags);
+   BUG_ON(avm_session->session_handle >= CONFIG_AVM_PA_MAX_SESSION);
 
-	if (session_to_remove.flowtype == fusiv_flow_v4 && session_to_remove.flow.v4) {
-	   if ((rc = apDeleteFlowEntry(session_to_remove.rxApId, session_to_remove.flowhash, 
-				                   session_to_remove.flow.v4, (void *)&moved)) == 0) {
-		  apFlowEntry_t *flowp = session_to_remove.flow.v4;
+   // take_session_lock
+   spin_lock_irqsave(&session_list_lock, slock_flags);
+   if ((avm_session ==
+        fusiv_session_array[avm_session->session_handle].avm_session)
+       && fusiv_session_array[avm_session->session_handle].valid_session) {
+      session_to_remove = fusiv_session_array[avm_session->session_handle];
+   } else {
+      // no valid session found
+      // release_session_lock and return
+      spin_unlock_irqrestore(&session_list_lock, slock_flags);
+      return status;
+   }
+   // release_session_lock
+   spin_unlock_irqrestore(&session_list_lock, slock_flags);
+
+   if (session_to_remove.flowtype == fusiv_flow_v4 && session_to_remove.flow.v4) {
+      if ((rc = apDeleteFlowEntry(session_to_remove.rxApId,
+                                  session_to_remove.flowhash,
+                                  session_to_remove.flow.v4,
+                                  (void *) &moved)) == 0) {
+         apFlowEntry_t *flowp = session_to_remove.flow.v4;
 
 #if defined(CONFIG_FUSIV_KERNEL_APSTATISTICS_PER_INTERFACE) && defined(AVM_PA_FUSIV_DEBUG)
-		  AVM_PA_FUSIV_DBG("ap2apFlowDelete Stats %lu rxPkt %lu rxByte %lu txPkt %lu txByte \n",
-				flowp->apStatistics.rxPkt, flowp->apStatistics.rxByte, flowp->apStatistics.txPkt, flowp->apStatistics.txByte);
+         AVM_PA_FUSIV_DBG
+            ("ap2apFlowDelete Stats %lu rxPkt %lu rxByte %lu txPkt %lu txByte\n",
+             flowp->apStatistics.rxPkt, flowp->apStatistics.rxByte,
+             flowp->apStatistics.txPkt, flowp->apStatistics.txByte);
 #endif
-		  if (moved) {
-		     struct avm_pa_fusiv_session *fusiv_session = (struct avm_pa_fusiv_session *) (flowp->userHandle);
-			 fusiv_session->flow.v4 = flowp;
-			 AVM_PA_FUSIV_DBG("avm_pa_fusiv_remove_session: v4 flow entry moved \n");
-		  }
-		  AVM_PA_FUSIV_DBG("avm_pa_fusiv_remove_session: apDeleteFlowEntry successful \n");
-	   } else {
-		  AVM_PA_FUSIV_DBG("avm_pa_fusiv_remove_session: apDeleteFlowEntry failed (rc=%u) APID %d\n", rc, session_to_remove.rxApId);
-	   }
-	} else if (session_to_remove.flowtype == fusiv_flow_v6 && session_to_remove.flow.v6) {
-	   if ((rc = apIpv6DeleteFlowEntry(session_to_remove.rxApId, session_to_remove.flowhash, 
-				                   session_to_remove.flow.v6, (void *)&moved)) == 0) {
-		  apIpv6FlowEntry_t *flowp = session_to_remove.flow.v6;
+         if (moved) {
+            struct avm_pa_fusiv_session *fusiv_session =
+               (struct avm_pa_fusiv_session *) (flowp->userHandle);
+
+            fusiv_session->flow.v4 = flowp;
+            AVM_PA_FUSIV_DBG
+               ("avm_pa_fusiv_remove_session: v4 flow entry moved\n");
+         }
+         AVM_PA_FUSIV_DBG
+            ("avm_pa_fusiv_remove_session: apDeleteFlowEntry successful\n");
+      } else {
+         AVM_PA_FUSIV_DBG
+            ("avm_pa_fusiv_remove_session: apDeleteFlowEntry failed (rc=%u) APID %d\n",
+             rc, session_to_remove.rxApId);
+      }
+   } else if (session_to_remove.flowtype == fusiv_flow_v6
+              && session_to_remove.flow.v6) {
+      if ((rc =
+           apIpv6DeleteFlowEntry(session_to_remove.rxApId,
+                                 session_to_remove.flowhash,
+                                 session_to_remove.flow.v6,
+                                 (void *) &moved)) == 0) {
+         apIpv6FlowEntry_t *flowp = session_to_remove.flow.v6;
 
 #if defined(CONFIG_FUSIV_KERNEL_APSTATISTICS_PER_INTERFACE) && defined(AVM_PA_FUSIV_DEBUG)
-		  AVM_PA_FUSIV_DBG("ap2apFlowDelete Stats %lu rxPkt %lu rxByte %lu txPkt %lu txByte \n",
-				flowp->apStatistics.rxPkt, flowp->apStatistics.rxByte, flowp->apStatistics.txPkt, flowp->apStatistics.txByte);
+         AVM_PA_FUSIV_DBG
+            ("ap2apFlowDelete Stats %lu rxPkt %lu rxByte %lu txPkt %lu txByte \n",
+             flowp->apStatistics.rxPkt, flowp->apStatistics.rxByte,
+             flowp->apStatistics.txPkt, flowp->apStatistics.txByte);
 #endif
-		  if (moved) {
-		     struct avm_pa_fusiv_session *fusiv_session = (struct avm_pa_fusiv_session *) (flowp->userHandle);
-			 fusiv_session->flow.v6 = flowp;
-			 AVM_PA_FUSIV_DBG("avm_pa_fusiv_remove_session: v6 flow entry moved \n");
-		  }
-		  AVM_PA_FUSIV_DBG("avm_pa_fusiv_remove_session: apIpv6DeleteFlowEntry successful \n");
-	   } else {
-		  AVM_PA_FUSIV_DBG("avm_pa_fusiv_remove_session: apIpv6DeleteFlowEntry failed (rc=%d) \n", rc);
-	   }
-	} else if (session_to_remove.flowtype == fusiv_bridge_flow && session_to_remove.bridgeFlow) {
-	   if ((rc = apDeleteBridgeEntry(1, session_to_remove.flowhash,
-				   session_to_remove.bridgeFlow, (void *)&moved)) == 0) {
-		  apNewBridgeEntry_t *flowp = session_to_remove.bridgeFlow;
+         if (moved) {
+            struct avm_pa_fusiv_session *fusiv_session =
+               (struct avm_pa_fusiv_session *) (flowp->userHandle);
+
+            fusiv_session->flow.v6 = flowp;
+            AVM_PA_FUSIV_DBG
+               ("avm_pa_fusiv_remove_session: v6 flow entry moved\n");
+         }
+         AVM_PA_FUSIV_DBG
+            ("avm_pa_fusiv_remove_session: apIpv6DeleteFlowEntry successful\n");
+      } else {
+         AVM_PA_FUSIV_DBG
+            ("avm_pa_fusiv_remove_session: apIpv6DeleteFlowEntry failed (rc=%d)\n",
+             rc);
+      }
+   } else if (session_to_remove.flowtype == fusiv_bridge_flow
+              && session_to_remove.bridgeFlow) {
+      if ((rc =
+           apDeleteBridgeEntry(1, session_to_remove.flowhash,
+                               session_to_remove.bridgeFlow,
+                               (void *) &moved)) == 0) {
 #if defined(CONFIG_FUSIV_KERNEL_APSTATISTICS_PER_INTERFACE) && defined(AVM_PA_FUSIV_DEBUG)
-		  AVM_PA_FUSIV_DBG("apDeleteBridgeEntry Stats %lu rxPkt %lu rxByte %lu txPkt %lu txByte \n",
-				flowp->apStatistics.rxPkt, flowp->apStatistics.rxByte, flowp->apStatistics.txPkt, flowp->apStatistics.txByte);
-#endif
-		  AVM_PA_FUSIV_DBG("avm_pa_fusiv_remove_session: apDeleteBridgeEntry successful \n");
-	   } else {
-		  AVM_PA_FUSIV_DBG("avm_pa_fusiv_remove_session: apDeleteBridgeEntry failed (rc=%d) \n", rc);
-	   }
-	}
+         apNewBridgeEntry_t *flowp = session_to_remove.bridgeFlow;
 
-    // take_session_lock
-	spin_lock_irqsave( &session_list_lock, slock_flags);
-    if ( ( avm_session == fusiv_session_array[ avm_session->session_handle ].avm_session)
-            && fusiv_session_array[ avm_session->session_handle ].valid_session ){
-        memset(&fusiv_session_array[ avm_session->session_handle ],0 , sizeof(struct avm_pa_fusiv_session) );
-    	status = AVM_PA_TX_OK;
-    } else {
-        AVM_PA_FUSIV_DBG("session has been removed already - double call for remove by avm_pa?!");
-        dump_stack();
-    }
-    // release_session_lock
-	spin_unlock_irqrestore( &session_list_lock, slock_flags);
+         AVM_PA_FUSIV_DBG
+            ("apDeleteBridgeEntry Stats %lu rxPkt %lu rxByte %lu txPkt %lu txByte\n",
+             flowp->apStatistics.rxPkt, flowp->apStatistics.rxByte,
+             flowp->apStatistics.txPkt, flowp->apStatistics.txByte);
+#endif
+         AVM_PA_FUSIV_DBG
+            ("avm_pa_fusiv_remove_session: apDeleteBridgeEntry successful\n");
+      } else {
+         AVM_PA_FUSIV_DBG
+            ("avm_pa_fusiv_remove_session: apDeleteBridgeEntry failed (rc=%d)\n",
+             rc);
+      }
+   }
+   // take_session_lock
+   spin_lock_irqsave(&session_list_lock, slock_flags);
+   if ((avm_session ==
+        fusiv_session_array[avm_session->session_handle].avm_session)
+       && fusiv_session_array[avm_session->session_handle].valid_session) {
+      memset(&fusiv_session_array[avm_session->session_handle], 0,
+             sizeof(struct avm_pa_fusiv_session));
+      status = AVM_PA_TX_OK;
+   } else {
+      printk(KERN_CRIT
+             "session has been removed already - double call for remove by avm_pa?!");
+      dump_stack();
+   }
+   // release_session_lock
+   spin_unlock_irqrestore(&session_list_lock, slock_flags);
 
-    return status;
+   return status;
 }
 
-
 /*------------------------------------------------------------------------------------------*\
 \*------------------------------------------------------------------------------------------*/
 
-
-#ifdef CONFIG_FUSIV_KERNEL_APSTATISTICS_PER_INTERFACE
-static void avm_pa_check_stat(unsigned long dummy) {
+#if defined(CONFIG_FUSIV_VX180) && defined(CONFIG_FUSIV_KERNEL_APSTATISTICS_PER_INTERFACE)
+static void avm_pa_check_stat(unsigned long dummy)
+{
    unsigned int i;
    struct avm_pa_fusiv_session *session;
    unsigned long bytes_since_last_report;
@@ -823,168 +1171,227 @@
    apNewBridgeEntry_t *bridgeflow;
    unsigned long slock_flags;
 
-   spin_lock_irqsave( &session_list_lock, slock_flags);
+   spin_lock_irqsave(&session_list_lock, slock_flags);
 
    for (i = 0; i < CONFIG_AVM_PA_MAX_SESSION; i++) {
-      session =  &fusiv_session_array[i];
-	  if (!session->valid_session) continue;
+      session = &fusiv_session_array[i];
+      if (!session->valid_session)
+         continue;
+      if (session->rxApId == PERI_ID) /* not used on rx */
+         continue;
 
-	  if (session->flowtype == fusiv_flow_v4) {
-	     flowpv4 = session->flow.v4;
-		 if (flowpv4->apStatistics.txByte >= session->prevStat.txByte) {
-			bytes_since_last_report = flowpv4->apStatistics.txByte - session->prevStat.txByte;
-		 } else {
-			bytes_since_last_report = 
-			   ((unsigned long) -1) - session->prevStat.txByte + flowpv4->apStatistics.txByte;
-		 }
-		 if (flowpv4->apStatistics.txPkt >= session->prevStat.txPkt) {
-			packets_since_last_report = flowpv4->apStatistics.txPkt - session->prevStat.txPkt;
-		 } else {
-			packets_since_last_report = 
-			   ((unsigned long) -1) - session->prevStat.txPkt + flowpv4->apStatistics.txPkt;
-		 }
-		 session->prevStat.txByte = flowpv4->apStatistics.txByte;
-		 session->prevStat.rxByte = flowpv4->apStatistics.rxByte;
-		 session->prevStat.txPkt = flowpv4->apStatistics.txPkt;
-		 session->prevStat.rxPkt = flowpv4->apStatistics.rxPkt;
-	  } else if (session->flowtype == fusiv_flow_v6) {
-	     flowpv6 = session->flow.v6;
-		 if (flowpv6->apStatistics.txByte >= session->prevStat.txByte) {
-			bytes_since_last_report = flowpv6->apStatistics.txByte - session->prevStat.txByte;
-		 } else {
-			bytes_since_last_report = 
-			   ((unsigned long) -1) - session->prevStat.txByte + flowpv6->apStatistics.txByte;
-		 }
-		 if (flowpv6->apStatistics.txPkt >= session->prevStat.txPkt) {
-			packets_since_last_report = flowpv6->apStatistics.txPkt - session->prevStat.txPkt;
-		 } else {
-			packets_since_last_report = 
-			   ((unsigned long) -1) - session->prevStat.txPkt + flowpv6->apStatistics.txPkt;
-		 }
-		 session->prevStat.txByte = flowpv6->apStatistics.txByte;
-		 session->prevStat.rxByte = flowpv6->apStatistics.rxByte;
-		 session->prevStat.txPkt = flowpv6->apStatistics.txPkt;
-		 session->prevStat.rxPkt = flowpv6->apStatistics.rxPkt;
-	  } else if (session->flowtype == fusiv_bridge_flow) {
-	     bridgeflow = session->bridgeFlow;
-		 if (bridgeflow->apStatistics.txByte >= session->prevStat.txByte) {
-			bytes_since_last_report = bridgeflow->apStatistics.txByte - session->prevStat.txByte;
-		 } else {
-			bytes_since_last_report = 
-			   ((unsigned long) -1) - session->prevStat.txByte + bridgeflow->apStatistics.txByte;
-		 }
-		 if (bridgeflow->apStatistics.txPkt >= session->prevStat.txPkt) {
-			packets_since_last_report = bridgeflow->apStatistics.txPkt - session->prevStat.txPkt;
-		 } else {
-			packets_since_last_report = 
-			   ((unsigned long) -1) - session->prevStat.txPkt + bridgeflow->apStatistics.txPkt;
-		 }
-		 session->prevStat.txByte = bridgeflow->apStatistics.txByte;
-		 session->prevStat.rxByte = bridgeflow->apStatistics.rxByte;
-		 session->prevStat.txPkt = bridgeflow->apStatistics.txPkt;
-		 session->prevStat.rxPkt = bridgeflow->apStatistics.rxPkt;
-		 AVM_PA_FUSIV_DBG("bridge flow stats %lu bytse \n", bytes_since_last_report);
-	  }
+      if (session->flowtype == fusiv_flow_v4) {
+         flowpv4 = session->flow.v4;
+         if (flowpv4->apStatistics.txByte >= session->prevStat.txByte) {
+            bytes_since_last_report =
+               flowpv4->apStatistics.txByte - session->prevStat.txByte;
+         } else {
+            bytes_since_last_report =
+               ((unsigned long) -1) - session->prevStat.txByte +
+               flowpv4->apStatistics.txByte;
+         }
+         if (flowpv4->apStatistics.txPkt >= session->prevStat.txPkt) {
+            packets_since_last_report =
+               flowpv4->apStatistics.txPkt - session->prevStat.txPkt;
+         } else {
+            packets_since_last_report =
+               ((unsigned long) -1) - session->prevStat.txPkt +
+               flowpv4->apStatistics.txPkt;
+         }
+         session->prevStat.txByte = flowpv4->apStatistics.txByte;
+         session->prevStat.rxByte = flowpv4->apStatistics.rxByte;
+         session->prevStat.txPkt = flowpv4->apStatistics.txPkt;
+         session->prevStat.rxPkt = flowpv4->apStatistics.rxPkt;
+      } else if (session->flowtype == fusiv_flow_v6) {
+         flowpv6 = session->flow.v6;
+         if (flowpv6->apStatistics.txByte >= session->prevStat.txByte) {
+            bytes_since_last_report =
+               flowpv6->apStatistics.txByte - session->prevStat.txByte;
+         } else {
+            bytes_since_last_report =
+               ((unsigned long) -1) - session->prevStat.txByte +
+               flowpv6->apStatistics.txByte;
+         }
+         if (flowpv6->apStatistics.txPkt >= session->prevStat.txPkt) {
+            packets_since_last_report =
+               flowpv6->apStatistics.txPkt - session->prevStat.txPkt;
+         } else {
+            packets_since_last_report =
+               ((unsigned long) -1) - session->prevStat.txPkt +
+               flowpv6->apStatistics.txPkt;
+         }
+         session->prevStat.txByte = flowpv6->apStatistics.txByte;
+         session->prevStat.rxByte = flowpv6->apStatistics.rxByte;
+         session->prevStat.txPkt = flowpv6->apStatistics.txPkt;
+         session->prevStat.rxPkt = flowpv6->apStatistics.rxPkt;
+      } else if (session->flowtype == fusiv_bridge_flow) {
+         bridgeflow = session->bridgeFlow;
+         if (bridgeflow->apStatistics.txByte >= session->prevStat.txByte) {
+            bytes_since_last_report =
+               bridgeflow->apStatistics.txByte - session->prevStat.txByte;
+         } else {
+            bytes_since_last_report =
+               ((unsigned long) -1) - session->prevStat.txByte +
+               bridgeflow->apStatistics.txByte;
+         }
+         if (bridgeflow->apStatistics.txPkt >= session->prevStat.txPkt) {
+            packets_since_last_report =
+               bridgeflow->apStatistics.txPkt - session->prevStat.txPkt;
+         } else {
+            packets_since_last_report =
+               ((unsigned long) -1) - session->prevStat.txPkt +
+               bridgeflow->apStatistics.txPkt;
+         }
+         session->prevStat.txByte = bridgeflow->apStatistics.txByte;
+         session->prevStat.rxByte = bridgeflow->apStatistics.rxByte;
+         session->prevStat.txPkt = bridgeflow->apStatistics.txPkt;
+         session->prevStat.rxPkt = bridgeflow->apStatistics.rxPkt;
+         AVM_PA_FUSIV_DBG("bridge flow stats %lu bytes\n",
+                          bytes_since_last_report);
+      } else {
+         packets_since_last_report = 0;
+         bytes_since_last_report = 0;
+      }
 
-	  if (session->avm_session && session->avm_session->session_handle)
-	     avm_pa_hardware_session_report(session->avm_session->session_handle,
-			                            packets_since_last_report, bytes_since_last_report);
-	  else 
-	     AVM_PA_FUSIV_DBG("avm_pa_check_stat: no session handle\n");
+      if (session->avm_session && session->avm_session->session_handle) {
+#if 0
+
+         printk(KERN_ERR "avm_pa_hardware_session_report(%u): rxId %u txId %u pkts %lu bytes %llu\n",
+                         session->avm_session->session_handle,
+                         (unsigned)session->rxApId,
+                         (unsigned)session->txApId,
+                         packets_since_last_report,
+                         bytes_since_last_report);
+#endif
+         avm_pa_hardware_session_report(session->avm_session->session_handle,
+                                        packets_since_last_report,
+                                        bytes_since_last_report);
+      } else {
+         AVM_PA_FUSIV_DBG("avm_pa_check_stat: no session handle\n");
+      }
    }
-   spin_unlock_irqrestore( &session_list_lock, slock_flags);
+   spin_unlock_irqrestore(&session_list_lock, slock_flags);
 
-   mod_timer(&statistics_timer,  jiffies + HZ * AVM_PA_FUSIV_STAT_POLLING_TIME - 1);
+   mod_timer(&statistics_timer,
+             jiffies + HZ * AVM_PA_FUSIV_STAT_POLLING_TIME - 1);
 
-   //TODO: statistics bei loeschen
+   // TODO: statistics bei loeschen
 }
 #endif
 
 /*------------------------------------------------------------------------------------------*\
 \*------------------------------------------------------------------------------------------*/
-void pkt_from_ap(apPreHeader_t *ap_buf) {
-	struct sk_buff *skb;
-	avm_pid_handle pid_handle;
+void pkt_from_ap(apPreHeader_t * ap_buf)
+{
+   struct sk_buff *skb;
+   avm_pid_handle pid_handle;
 
-	pid_handle = ap_buf->specInfoElement;
-	ap_buf->specInfoElement = 1;
+   pid_handle = ap_buf->specInfoElement;
+   ap_buf->specInfoElement = 1;
 
-	AVM_PA_FUSIV_TRC("%s called pid_handle %u\n", __func__, pid_handle);
+   AVM_PA_FUSIV_TRC("%s called pid_handle %u\n", __func__, pid_handle);
 
-	skb = (struct sk_buff *)translateApbuf2Mbuf(ap_buf);
-    avm_pa_rx_channel_packet_not_accelerated(pid_handle, skb);
+   if ((skb = (struct sk_buff *) translateApbuf2Mbuf(ap_buf)) != 0)
+      avm_pa_rx_channel_packet_not_accelerated(pid_handle, skb);
 }
 
-extern int  apClassify(unsigned char apId, apPreHeader_t *pFrame, void *handle);
+extern int apClassify(unsigned char apId, apPreHeader_t * pFrame, void *handle);
 extern void (*wlan_pkt_from_ap_ptr) (apPreHeader_t *);
 
-int avm_pa_fusiv_try_to_accelerate(avm_pid_handle pid_handle, struct sk_buff *skb) {
+int avm_pa_fusiv_try_to_accelerate(avm_pid_handle pid_handle,
+                                   struct sk_buff *skb)
+{
 
-	struct avm_pa_pid_hwinfo *hwinfo;
-	apPreHeader_t *ap_buf;
+   struct avm_pa_pid_hwinfo *hwinfo;
+   apPreHeader_t *ap_buf;
 
-	hwinfo = avm_pa_pid_get_hwinfo(pid_handle);
-	if (!hwinfo) {
-	   AVM_PA_FUSIV_TRC(KERN_ERR "avm_pa_fusiv_try_to_accelerate: no hw info for pid %u\n", pid_handle);
-	   return AVM_PA_RX_BYPASS;
-	}
+   hwinfo = avm_pa_pid_get_hwinfo(pid_handle);
+   if (!hwinfo) {
+      AVM_PA_FUSIV_TRC(KERN_ERR
+                       "avm_pa_fusiv_try_to_accelerate: no hw info for pid %u\n",
+                       pid_handle);
+      return AVM_PA_RX_BYPASS;
+   }
 
-	ap_buf = (apPreHeader_t *)(translateMbuf2Apbuf(skb, 0));
-	ap_buf->flags1 = 1 << AP_FLAG1_IS_ETH_BIT;
-	ap_buf->specInfoElement = pid_handle;
-	ap_buf->flags2 = 0;
-	dev_kfree_skb_any(skb);
+   /* == AVM/UGA 20140707 no HW acceleration for ingress WLAN/PERI AP pkts ==
+    * Workaround for trouble-free telephony.
+    * AVM PA rate throttling is not working for ingres WLAN pkts because they
+    * are not seen/counted by it atm.
+    * Thus, we fallback to SW acceleration which sees/counts pkts
+    * appropriately so throttling works.
+    */
+#if 1
+   if (hwinfo->apId == PERI_ID)
+      return AVM_PA_RX_BYPASS;
+#endif
 
-	AVM_PA_FUSIV_TRC("avm_pa_fusiv_try_to_accelerate: apClassify apId %u\n", hwinfo->apId);
-	apClassify(hwinfo->apId, ap_buf, (void *)pkt_from_ap);
-	return AVM_PA_RX_STOLEN;
+   ap_buf = (apPreHeader_t *) (translateMbuf2Apbuf(skb, 0));
+   if (!ap_buf) {
+      return AVM_PA_RX_BYPASS;
+   }
+   ap_buf->flags1 = 1 << AP_FLAG1_IS_ETH_BIT;
+   ap_buf->specInfoElement = pid_handle;
+   ap_buf->flags2 = 0;
+   dev_kfree_skb_any(skb);
+
+   AVM_PA_FUSIV_TRC("avm_pa_fusiv_try_to_accelerate: apClassify apId %u\n",
+                    hwinfo->apId);
+   if (apClassify(hwinfo->apId, ap_buf, (void *) pkt_from_ap) != SIM_OK) {
+      putCluster(ap_buf);
+   }
+   return AVM_PA_RX_STOLEN;
 }
 
-int avm_pa_fusiv_alloc_rx_channel(avm_pid_handle pid_handle) {
+int avm_pa_fusiv_alloc_rx_channel(avm_pid_handle pid_handle)
+{
 
-	wlan_pkt_from_ap_ptr = pkt_from_ap;
+   wlan_pkt_from_ap_ptr = pkt_from_ap;
 
-	return 0;
+   return 0;
 }
 
-int avm_pa_fusiv_alloc_tx_channel(avm_pid_handle pid_handle) {
+int avm_pa_fusiv_alloc_tx_channel(avm_pid_handle pid_handle)
+{
 
-	apBridgeTable(1, 0xCC, 0xff);
+   apBridgeTable(1, 0xCC, 0xff);
 
-	return 0;
+   return 0;
 }
 
-
 /*------------------------------------------------------------------------------------------*\
 \*------------------------------------------------------------------------------------------*/
 
-static int __init avm_pa_fusiv_init(void) {
-	AVM_PA_FUSIV_DBG("[%s] start \n", __func__);
+static int __init avm_pa_fusiv_init(void)
+{
+   AVM_PA_FUSIV_DBG("[%s] start \n", __func__);
 
-    memset( &fusiv_session_array[0], 0 , sizeof( struct avm_pa_fusiv_session ) * CONFIG_AVM_PA_MAX_SESSION );
+   memset(&fusiv_session_array[0], 0,
+          sizeof(struct avm_pa_fusiv_session) * CONFIG_AVM_PA_MAX_SESSION);
 
-    avm_pa_register_hardware_pa( &avm_pa_fusiv );
+   avm_pa_register_hardware_pa(&avm_pa_fusiv);
 
-#ifdef CONFIG_FUSIV_KERNEL_APSTATISTICS_PER_INTERFACE
-	setup_timer(&statistics_timer, avm_pa_check_stat, 0 );
-    mod_timer(&statistics_timer, jiffies + HZ * AVM_PA_FUSIV_STAT_POLLING_TIME - 1);
+#if defined(CONFIG_FUSIV_VX180) && defined(CONFIG_FUSIV_KERNEL_APSTATISTICS_PER_INTERFACE)
+   setup_timer(&statistics_timer, avm_pa_check_stat, 0);
+   mod_timer(&statistics_timer,
+             jiffies + HZ * AVM_PA_FUSIV_STAT_POLLING_TIME - 1);
 #endif
 
-	AVM_PA_FUSIV_DBG("[%s] init complete \n", __func__);
+   AVM_PA_FUSIV_DBG("[%s] init complete \n", __func__);
 
-	return 0;
+   return 0;
 }
 
-static void __exit avm_pa_fusiv_exit(void) {
-	AVM_PA_FUSIV_DBG("[%s] start \n", __func__);
+static void __exit avm_pa_fusiv_exit(void)
+{
+   AVM_PA_FUSIV_DBG("[%s] start \n", __func__);
 
-#ifdef CONFIG_FUSIV_KERNEL_APSTATISTICS_PER_INTERFACE
-    del_timer(&statistics_timer);
+#if defined(CONFIG_FUSIV_VX180) && defined(CONFIG_FUSIV_KERNEL_APSTATISTICS_PER_INTERFACE)
+   del_timer(&statistics_timer);
 #endif
 
-    avm_pa_register_hardware_pa( 0 );
+   avm_pa_register_hardware_pa(0);
 
-	AVM_PA_FUSIV_DBG("[%s] exit complete \n", __func__);
+   AVM_PA_FUSIV_DBG("[%s] exit complete \n", __func__);
 }
 
 module_init(avm_pa_fusiv_init);
@@ -1002,11 +1409,10 @@
 
 #undef unix
 struct module __this_module
-__attribute__((section(".gnu.linkonce.this_module"))) = {
-    .name = "avm_pa_fusiv",
-	.init = init_module,
+   __attribute__ ((section(".gnu.linkonce.this_module"))) = {
+   .name = "avm_pa_fusiv",.init = init_module,
 #ifdef CONFIG_MODULE_UNLOAD
-	.exit = cleanup_module,
+      .exit = cleanup_module,
 #endif
 };
 
