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

    diff -durN --no-dereference -x fusiv_src 3490.06.20 7320.06.30 > 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/arch/mips/mach-infineon/common/ifxmips_interrupt.c
+++ linux-2.6.32/arch/mips/mach-infineon/common/ifxmips_interrupt.c
@@ -1187,14 +1187,8 @@
     if (is_fixup) {
         return MIPS_BE_FIXUP;
     } else {
-#ifdef CONFIG_IFX_PCI
-        printk(KERN_ERR "[%s] addr=%pF (MIPS_BE_DISCARD)\n", __FUNCTION__, (void *)regs->cp0_epc);
-        printk(KERN_INFO "Ignored Bus Error!\n");
-        return MIPS_BE_DISCARD;
-#else
         printk(KERN_INFO "Fatal Bus Error!\n");
         return MIPS_BE_FATAL;
-#endif
     }
 }
 
--- linux-2.6.32/arch/mips/Makefile.ifx
+++ linux-2.6.32/arch/mips/Makefile.ifx
@@ -8,8 +8,9 @@
 cflags-$(CONFIG_AMAZON_SE)	+= -Iarch/mips/include/asm/mach-infineon
 load-$(CONFIG_AMAZON_SE)	+= 0xFFFFFFFF80002000
 
+# AR9: no-dsp: lbux and friends might crash - if access via busmaster 
 core-$(CONFIG_AR9)	+= arch/mips/mach-infineon/common/ arch/mips/mach-infineon/ar9/
-cflags-$(CONFIG_AR9)	+= -Iarch/mips/include/asm/mach-infineon
+cflags-$(CONFIG_AR9)	+= -Iarch/mips/include/asm/mach-infineon -mno-dsp
 load-$(CONFIG_AR9)	+= 0xFFFFFFFF80002000
 
 core-$(CONFIG_VR9)	+= arch/mips/mach-infineon/common/ arch/mips/mach-infineon/vr9/
--- linux-2.6.32/.config
+++ linux-2.6.32/.config
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
 # Linux kernel version: 2.6.32.61
-# Wed Jun  4 14:01:11 2014
+# Mon May 26 12:30:24 2014
 #
 CONFIG_MIPS=y
 
@@ -58,30 +58,30 @@
 # CONFIG_MACH_QCA955x is not set
 # CONFIG_MACH_HORNET is not set
 # CONFIG_DANUBE is not set
-CONFIG_IFX_DMA_DESCRIPTOR_NUMBER=128
+CONFIG_IFX_DMA_DESCRIPTOR_NUMBER=64
 CONFIG_NAPI_ENABLED=y
 # CONFIG_DMA_HW_POLL_DISABLED is not set
 # CONFIG_AMAZON_SE is not set
-# CONFIG_AR9 is not set
-CONFIG_IFX_CLOCK_CHANGE=y
-CONFIG_VR9=y
+CONFIG_AR9=y
 
 #
-# VR9 Boards
+# AR9 Boards
 #
-# CONFIG_VR9_REF_BOARD is not set
-CONFIG_VR9_AVM_FRITZ_BOX=y
-# CONFIG_LTQ_RT288 is not set
+# CONFIG_AR9_REF_BOARD is not set
+# CONFIG_AR9_CUSTOM_BOARD is not set
+CONFIG_AR9_AVM_FRITZ_BOX=y
+# CONFIG_IFX_GW188 is not set
+# CONFIG_LTQ_VB300 is not set
 
 #
 # Extra Configuration
 #
-CONFIG_DMA_PACKET_ARBITRATION_ENABLED=y
-# CONFIG_GRX_25M_MODEL is not set
+CONFIG_IFX_CLOCK_CHANGE=y
+# CONFIG_VR9 is not set
 # CONFIG_HN1 is not set
 # CONFIG_AR10 is not set
-CONFIG_AR9VR9_C55_MEMORY_SIZE=0x0
-CONFIG_AR9VR9_C55_MEMORY_START=0x0
+CONFIG_AR9VR9_C55_MEMORY_SIZE=0x80
+CONFIG_AR9VR9_C55_MEMORY_START=0xFC0000
 # CONFIG_AR9VR9_AVM_CPUFREQ is not set
 # CONFIG_AR9VR9_AVM_CPUIDLE is not set
 # CONFIG_ALCHEMY_GPIO_INDIRECT is not set
@@ -90,6 +90,7 @@
 # CONFIG_ARCH_HAS_ILOG2_U64 is not set
 # CONFIG_MIPS_FUSIV is not set
 # CONFIG_MACH_ATHEROS is not set
+CONFIG_ARCH_SUPPORTS_OPROFILE=y
 CONFIG_GENERIC_FIND_NEXT_BIT=y
 CONFIG_GENERIC_HWEIGHT=y
 CONFIG_GENERIC_CALIBRATE_DELAY=y
@@ -114,7 +115,7 @@
 # CONFIG_MIPS_MACHINE is not set
 # CONFIG_IMAGE_CMDLINE_HACK is not set
 # CONFIG_NO_IOPORT is not set
-CONFIG_CPU_HAS_DSP_ASE=y
+# CONFIG_CPU_HAS_DSP_ASE is not set
 CONFIG_CPU_BIG_ENDIAN=y
 # CONFIG_CPU_LITTLE_ENDIAN is not set
 CONFIG_SYS_SUPPORTS_BIG_ENDIAN=y
@@ -176,23 +177,22 @@
 CONFIG_THREAD_SIZE_ORDER=2
 CONFIG_CPU_HAS_PREFETCH=y
 # CONFIG_AVM_WP is not set
-# CONFIG_MIPS_MT_DISABLED is not set
+CONFIG_MIPS_MT_DISABLED=y
 # CONFIG_MIPS_MT_SMP is not set
-CONFIG_MIPS_MT_SMTC=y
+# CONFIG_MIPS_MT_SMTC is not set
 CONFIG_MIPS_MT=y
 CONFIG_SYS_SUPPORTS_MULTITHREADING=y
-CONFIG_MIPS_MT_FPAFF=y
-# CONFIG_MIPS_VPE_LOADER is not set
-CONFIG_PERFCTRS=y
-CONFIG_MTSCHED=y
-# CONFIG_MIPS_MT_SMTC_IM_BACKSTOP is not set
-# CONFIG_MIPS_MT_SMTC_IRQAFF is not set
+CONFIG_MIPS_VPE_LOADER=y
+# CONFIG_IFX_VPE_EXT is not set
+# CONFIG_PERFCTRS is not set
+# CONFIG_MTSCHED is not set
+CONFIG_MIPS_VPE_LOADER_TOM=y
+# CONFIG_MIPS_VPE_APSP_API is not set
 CONFIG_CPU_MIPSR2_IRQ_VI=y
 CONFIG_CPU_MIPSR2_IRQ_EI=y
 CONFIG_CPU_HAS_SYNC=y
 CONFIG_GENERIC_HARDIRQS=y
 CONFIG_GENERIC_IRQ_PROBE=y
-CONFIG_IRQ_PER_CPU=y
 CONFIG_ARCH_FLATMEM_ENABLE=y
 CONFIG_ARCH_POPULATES_NODE_MAP=y
 CONFIG_SELECT_MEMORY_MODEL=y
@@ -208,14 +208,9 @@
 CONFIG_VIRT_TO_BUS=y
 CONFIG_HAVE_MLOCK=y
 CONFIG_HAVE_MLOCKED_PAGE_BIT=y
-CONFIG_KSM=y
+# CONFIG_KSM is not set
 CONFIG_DEFAULT_MMAP_MIN_ADDR=4096
-# CONFIG_AVM_LOW_MEMORY_STRATEGY is not set
-CONFIG_SMP=y
-CONFIG_SMP_UP=y
-CONFIG_SYS_SUPPORTS_SMP=y
-CONFIG_NR_CPUS_DEFAULT_8=y
-CONFIG_NR_CPUS=2
+CONFIG_AVM_LOW_MEMORY_STRATEGY=y
 CONFIG_TICK_ONESHOT=y
 CONFIG_NO_HZ=y
 CONFIG_HIGH_RES_TIMERS=y
@@ -228,7 +223,6 @@
 # CONFIG_HZ_1000 is not set
 # CONFIG_HZ_1024 is not set
 CONFIG_SYS_SUPPORTS_100HZ=y
-CONFIG_SYS_SUPPORTS_250HZ=y
 CONFIG_SYS_SUPPORTS_1000HZ=y
 CONFIG_HZ=100
 CONFIG_PREEMPT_NONE=y
@@ -245,7 +239,7 @@
 # General setup
 #
 CONFIG_EXPERIMENTAL=y
-CONFIG_LOCK_KERNEL=y
+CONFIG_BROKEN_ON_SMP=y
 CONFIG_INIT_ENV_ARG_LIMIT=32
 CONFIG_LOCALVERSION=""
 # CONFIG_LOCALVERSION_AUTO is not set
@@ -257,7 +251,7 @@
 CONFIG_BSD_PROCESS_ACCT=y
 CONFIG_BSD_PROCESS_ACCT_V3=y
 # CONFIG_TASKSTATS is not set
-# CONFIG_AUDIT is not set
+CONFIG_AUDIT=y
 
 #
 # RCU Subsystem
@@ -276,22 +270,20 @@
 # CONFIG_NAMESPACES is not set
 CONFIG_BLK_DEV_INITRD=y
 CONFIG_INITRAMFS_SOURCE=""
-# CONFIG_RD_GZIP is not set
+CONFIG_RD_GZIP=y
 # CONFIG_RD_BZIP2 is not set
 # CONFIG_RD_LZMA is not set
-# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
+CONFIG_CC_OPTIMIZE_FOR_SIZE=y
 CONFIG_SYSCTL=y
 CONFIG_ANON_INODES=y
 CONFIG_EMBEDDED=y
 CONFIG_SYSCTL_SYSCALL=y
-CONFIG_KALLSYMS=y
-CONFIG_KALLSYMS_ALL=y
-CONFIG_KALLSYMS_EXTRA_PASS=y
+# CONFIG_KALLSYMS is not set
 CONFIG_HOTPLUG=y
 CONFIG_PRINTK=y
-CONFIG_BUG=y
+# CONFIG_BUG is not set
 CONFIG_ELF_CORE=y
-# CONFIG_PCSPKR_PLATFORM is not set
+CONFIG_PCSPKR_PLATFORM=y
 CONFIG_BASE_FULL=y
 CONFIG_FUTEX=y
 CONFIG_EPOLL=y
@@ -314,8 +306,8 @@
 CONFIG_AVM_SIMPLE_PROFILING=y
 # CONFIG_AVM_SIMPLE_PROFILING_YIELD is not set
 CONFIG_HAVE_OPROFILE=y
-CONFIG_USE_GENERIC_SMP_HELPERS=y
-# CONFIG_AVM_ARCH_STATIC_WLAN_MEMORY is not set
+CONFIG_AVM_ARCH_STATIC_WLAN_MEMORY=y
+CONFIG_AVM_ARCH_STATIC_WLAN_MEMORY_SIZE=392
 
 #
 # GCOV-based kernel profiling
@@ -332,7 +324,6 @@
 # CONFIG_MODULE_FORCE_UNLOAD is not set
 # CONFIG_MODVERSIONS is not set
 # CONFIG_MODULE_SRCVERSION_ALL is not set
-CONFIG_STOP_MACHINE=y
 CONFIG_BLOCK=y
 CONFIG_LBDAF=y
 # CONFIG_BLK_DEV_BSG is not set
@@ -360,29 +351,22 @@
 # CONFIG_ATH_HAS_PCI_RC2 is not set
 CONFIG_PCI=y
 CONFIG_PCI_DOMAINS=y
-CONFIG_PCIEPORTBUS=y
-CONFIG_PCIEAER=y
-# CONFIG_PCIE_ECRC is not set
-# CONFIG_PCIEAER_INJECT is not set
-CONFIG_IFX_PCIE=y
-CONFIG_IFX_PCIE_PHY_36MHZ_MODE=y
-# CONFIG_IFX_PCIE_PHY_36MHZ_SSC_MODE is not set
-# CONFIG_IFX_PCIE_PHY_25MHZ_MODE is not set
-# CONFIG_IFX_PCIE_PHY_100MHZ_MODE is not set
-CONFIG_IFX_PCIE_1ST_CORE=y
-CONFIG_IFX_PCIE_HW_SWAP=y
-# CONFIG_IFX_PCIE_INBOUND_NO_HW_SWAP is not set
-# CONFIG_IFX_PCIE_VR9_A11_HRST is not set
-# CONFIG_PCIEASPM is not set
-CONFIG_ARCH_SUPPORTS_MSI=y
-# CONFIG_PCI_MSI is not set
+# CONFIG_PCIEPORTBUS is not set
+# CONFIG_ARCH_SUPPORTS_MSI is not set
 CONFIG_PCI_LEGACY=y
 # CONFIG_PCI_INIT_IN_MONITOR is not set
 # CONFIG_PCI_DEBUG is not set
 # CONFIG_PCI_STUB is not set
 # CONFIG_PCI_DISABLE_COMMON_QUIRKS is not set
 # CONFIG_PCI_IOV is not set
-# CONFIG_IFX_PCI is not set
+CONFIG_IFX_PCI=y
+CONFIG_IFX_PCI_HW_SWAP=y
+CONFIG_IFX_PCI_INTERNAL_CLK_SRC_33=y
+# CONFIG_IFX_PCI_INTERNAL_CLK_SRC_60 is not set
+# CONFIG_IFX_PCI_EXTERNAL_CLK_SRC is not set
+CONFIG_IFX_PCI_CLOCK_DELAY_NANO_SECONDS=1
+CONFIG_IFX_PCI_CLOCK_DELAY_TENTH_NANO_SECOND=0
+# CONFIG_IFX_DUAL_MINI_PCI is not set
 CONFIG_MMU=y
 # CONFIG_PCCARD is not set
 # CONFIG_HOTPLUG_PCI is not set
@@ -399,6 +383,8 @@
 #
 # Power management options
 #
+CONFIG_ARCH_HIBERNATION_POSSIBLE=y
+# CONFIG_ARCH_SUSPEND_POSSIBLE is not set
 # CONFIG_PM is not set
 # CONFIG_CPU_FREQ is not set
 # CONFIG_CPU_IDLE is not set
@@ -535,8 +521,7 @@
 CONFIG_BRIDGE=y
 # CONFIG_BRIDGE_SNOOPING is not set
 # CONFIG_NET_DSA is not set
-CONFIG_VLAN_8021Q=y
-# CONFIG_VLAN_8021Q_GVRP is not set
+# CONFIG_VLAN_8021Q is not set
 # CONFIG_DECNET is not set
 CONFIG_LLC=y
 # CONFIG_LLC2 is not set
@@ -633,9 +618,7 @@
 # CONFIG_DEVTMPFS is not set
 CONFIG_STANDALONE=y
 CONFIG_PREVENT_FIRMWARE_BUILD=y
-CONFIG_FW_LOADER=y
-# CONFIG_FIRMWARE_IN_KERNEL is not set
-CONFIG_EXTRA_FIRMWARE=""
+# CONFIG_FW_LOADER is not set
 # CONFIG_DEBUG_DRIVER is not set
 # CONFIG_DEBUG_DEVRES is not set
 # CONFIG_SYS_HYPERVISOR is not set
@@ -727,21 +710,7 @@
 # CONFIG_MTD_ATH_FLASH is not set
 # CONFIG_MTD_AR7100_SPI_FLASH is not set
 # CONFIG_MTD_AR9100_PARALLEL_FLASH is not set
-CONFIG_MTD_NAND=y
-CONFIG_MTD_NAND_VERIFY_WRITE=y
-# CONFIG_MTD_NAND_ECC_SMC is not set
-# CONFIG_MTD_NAND_MUSEUM_IDS is not set
-CONFIG_MTD_NAND_IDS=y
-# CONFIG_MTD_NAND_DISKONCHIP is not set
-# CONFIG_MTD_NAND_CAFE is not set
-# CONFIG_MTD_NAND_NANDSIM is not set
-# CONFIG_MTD_NAND_PLATFORM is not set
-# CONFIG_MTD_ALAUDA is not set
-# CONFIG_MTD_NAND_COMPLETE_AVM is not set
-CONFIG_MTD_IFX_NAND_LATCH_ENABLE=y
-# CONFIG_MTD_IFX_NAND is not set
-CONFIG_MTD_IFX_HSNAND=y
-CONFIG_MTD_IFX_HSNAND_FLASH_SIZE=4
+# CONFIG_MTD_NAND is not set
 # CONFIG_MTD_ONENAND is not set
 
 #
@@ -840,11 +809,11 @@
 # CONFIG_ARCNET is not set
 # CONFIG_PHYLIB is not set
 CONFIG_NET_ETHERNET=y
-CONFIG_MII=y
+CONFIG_MII=n
 CONFIG_AVM_CPMAC=y
 CONFIG_AVM_CPMAC_NUM_RX_BUFFERS=256
 CONFIG_AVM_CPMAC_SWITCH=y
-CONFIG_AVM_SCATTER_GATHER=y
+# CONFIG_AVM_SCATTER_GATHER is not set
 # CONFIG_AVMNET_DEBUG is not set
 # CONFIG_AVMNET_DEBUG_HAL is not set
 # CONFIG_AX88796 is not set
@@ -905,10 +874,12 @@
 # CONFIG_ATHRS27_PHY is not set
 # CONFIG_AR8033_PHY is not set
 CONFIG_LANTIQ_11G_PHY=y
-CONFIG_WLAN_OFFLOAD_PHY=y
+# CONFIG_WLAN_OFFLOAD_PHY is not set
 # CONFIG_NETDEV_10000 is not set
 # CONFIG_TR is not set
-# CONFIG_WLAN is not set
+CONFIG_WLAN=y
+# CONFIG_WLAN_PRE80211 is not set
+# CONFIG_WLAN_80211 is not set
 
 #
 # Enable WiMAX (Networking options) to see the WiMAX drivers
@@ -953,8 +924,10 @@
 # CONFIG_ATM_SOLOS is not set
 # CONFIG_IFX_ATM is not set
 # CONFIG_IFX_PTM is not set
-# CONFIG_IFX_ADTRAN_PTM is not set
 CONFIG_IFX_ETHSW_API=y
+# CONFIG_BOTH_INTERFACE is not set
+CONFIG_INTERNAL_AR9=y
+# CONFIG_EXTERNAL_T3G is not set
 
 #
 # IFX_ETHSW_API
@@ -967,7 +940,6 @@
 # CONFIG_LTQ_WOL is not set
 # CONFIG_IFX_ETHSW_API_COC is not set
 # CONFIG_IFX_ETHSW_API_COC_PMCU is not set
-# CONFIG_GPHY_DRIVER is not set
 CONFIG_IFX_PPA_NAPI_ENABLE=y
 CONFIG_IFX_PPA=y
 CONFIG_IFX_PPA_AVM_USAGE=y
@@ -980,14 +952,16 @@
 CONFIG_IFX_PPA_QOS_WFQ=y
 CONFIG_IFX_PPA_QOS_RATE_SHAPING=y
 CONFIG_IFX_PPA_DATAPATH=m
-# CONFIG_IFX_PPA_A5 is not set
+CONFIG_IFX_PPA_A5=y
 # CONFIG_IFX_PPA_D5 is not set
-CONFIG_IFX_PPA_E5=y
-# CONFIG_IFX_PPE_E5_OFFCHIP_BONDING is not set
+# CONFIG_IFX_PPA_E5 is not set
 CONFIG_IFX_PPA_IPv6_ENABLE=y
-CONFIG_PTM_VECTORING=y
-# CONFIG_IFX_VECTOR_TIMER_CHECK is not set
-# CONFIG_IFX_7PORT_SWITCH is not set
+# CONFIG_PTM_VECTORING is not set
+# CONFIG_IFX_3PORT_SWITCH is not set
+# CONFIG_MII1_AUTONEG is not set
+# CONFIG_MII1_RGMII_MODE_100MB is not set
+# CONFIG_MII1_RGMII_MODE is not set
+CONFIG_MII_SETUP_AVMNET=y
 CONFIG_IFX_ETH_FRAMEWORK=y
 # CONFIG_FDDI is not set
 # CONFIG_HIPPI is not set
@@ -1056,7 +1030,10 @@
 #
 # Userland interfaces
 #
-# CONFIG_INPUT_MOUSEDEV is not set
+CONFIG_INPUT_MOUSEDEV=y
+# CONFIG_INPUT_MOUSEDEV_PSAUX is not set
+CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024
+CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
 # CONFIG_INPUT_JOYDEV is not set
 # CONFIG_INPUT_EVDEV is not set
 # CONFIG_INPUT_EVBUG is not set
@@ -1108,7 +1085,6 @@
 CONFIG_SERIAL_AVM_ASC=y
 CONFIG_SERIAL_AVM_ASC_CONSOLE=y
 # CONFIG_SERIAL_IFX_ASC is not set
-# CONFIG_SERIAL_IFX_USIF_UART is not set
 CONFIG_UNIX98_PTYS=y
 # CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
 CONFIG_LEGACY_PTYS=y
@@ -1151,20 +1127,17 @@
 CONFIG_AVM_PIGLET_DECT=y
 CONFIG_UBIK2=n
 CONFIG_UBIK2_DEVELOPMENT_SUPPORT=0
-CONFIG_UBIK2_MSEC_PER_IRQ=4
+CONFIG_UBIK2_MSEC_PER_IRQ=8
 CONFIG_IFX_PMCU=y
-# CONFIG_IFX_CPUFREQ is not set
+CONFIG_IFX_CPUFREQ=y
 CONFIG_IFX_PMU=y
-CONFIG_IFX_PMU_POWER_GATING=y
 CONFIG_IFX_GPIO=y
 CONFIG_IFX_RCU=y
 # CONFIG_IFX_SI is not set
 # CONFIG_IFX_LEDC is not set
 CONFIG_IFX_WDT=y
+CONFIG_IFXMIPS_DSL_CPE_MEI=y
 CONFIG_DSL_MEI_CPE_DRV=y
-# CONFIG_IFX_PMON is not set
-# CONFIG_IFX_DCDC is not set
-CONFIG_IFX_TS=y
 CONFIG_I2C=y
 CONFIG_I2C_BOARDINFO=y
 CONFIG_I2C_COMPAT=y
@@ -1243,10 +1216,9 @@
 CONFIG_SPI_BITBANG=y
 CONFIG_IFX_SPI=y
 # CONFIG_IFX_SPI_DEBUG is not set
-# CONFIG_IFX_SPI_ASYNCHRONOUS is not set
+CONFIG_IFX_SPI_ASYNCHRONOUS=y
 CONFIG_IFX_SPI_FLASH=y
 # CONFIG_IFX_SPI_AT45_FLASH is not set
-# CONFIG_IFX_USIF_SPI is not set
 
 #
 # SPI Protocol Masters
@@ -1337,7 +1309,7 @@
 # CONFIG_USB_OTG is not set
 # CONFIG_USB_OTG_WHITELIST is not set
 # CONFIG_USB_OTG_BLACKLIST_HUB is not set
-# CONFIG_USB_MON is not set
+CONFIG_USB_MON=n
 # CONFIG_USB_WUSB is not set
 # CONFIG_USB_WUSB_CBAF is not set
 
@@ -1345,8 +1317,7 @@
 # USB Host Controller Drivers
 #
 # CONFIG_USB_C67X00_HCD is not set
-CONFIG_USB_XHCI_HCD=n
-# CONFIG_USB_XHCI_HCD_DEBUGGING is not set
+# CONFIG_USB_XHCI_HCD is not set
 # CONFIG_USB_EHCI_HCD is not set
 # CONFIG_USB_OXU210HP_HCD is not set
 # CONFIG_USB_ISP116X_HCD is not set
@@ -1368,12 +1339,11 @@
 CONFIG_USB_HOST_IFX_UNALIGNED_ADJ=y
 # CONFIG_USB_HOST_IFX_UNALIGNED_CHK is not set
 # CONFIG_USB_HOST_IFX_UNALIGNED_NONE is not set
-CONFIG_USB_HOST_IFX_AVM_YIELD=y
 
 #
 # USB Device Class drivers
 #
-CONFIG_USB_ACM=n
+# CONFIG_USB_ACM is not set
 CONFIG_USB_PRINTER=n
 # CONFIG_USB_WDM is not set
 # CONFIG_USB_TMC is not set
@@ -1418,7 +1388,7 @@
 # CONFIG_USB_SERIAL_CH341 is not set
 # CONFIG_USB_SERIAL_WHITEHEAT is not set
 # CONFIG_USB_SERIAL_DIGI_ACCELEPORT is not set
-CONFIG_USB_SERIAL_CP210X=n
+# CONFIG_USB_SERIAL_CP210X is not set
 # CONFIG_USB_SERIAL_CYPRESS_M8 is not set
 # CONFIG_USB_SERIAL_EMPEG is not set
 CONFIG_USB_SERIAL_FTDI_SIO=n
@@ -1609,18 +1579,7 @@
 # CONFIG_OCFS2_FS is not set
 # CONFIG_BTRFS_FS is not set
 # CONFIG_NILFS2_FS is not set
-CONFIG_YAFFS_FS=y
-CONFIG_YAFFS_YAFFS1=y
-# CONFIG_YAFFS_9BYTE_TAGS is not set
-# CONFIG_YAFFS_DOES_ECC is not set
-CONFIG_YAFFS_YAFFS2=y
-CONFIG_YAFFS_AUTO_YAFFS2=y
-CONFIG_YAFFS_DISABLE_TAGS_ECC=y
-# CONFIG_YAFFS_ALWAYS_CHECK_CHUNK_ERASED is not set
-CONFIG_YAFFS_EMPTY_LOST_AND_FOUND=y
-# CONFIG_YAFFS_DISABLE_BLOCK_REFRESHING is not set
-# CONFIG_YAFFS_DISABLE_BACKGROUND is not set
-CONFIG_YAFFS_XATTR=y
+# CONFIG_YAFFS_FS is not set
 CONFIG_FILE_LOCKING=y
 CONFIG_FSNOTIFY=y
 # CONFIG_DNOTIFY is not set
@@ -1674,7 +1633,7 @@
 # CONFIG_BEFS_FS is not set
 # CONFIG_BFS_FS is not set
 # CONFIG_EFS_FS is not set
-CONFIG_JFFS2_FS=n
+CONFIG_JFFS2_FS=y
 CONFIG_JFFS2_FS_DEBUG=0
 CONFIG_JFFS2_FS_WRITEBUFFER=y
 # CONFIG_JFFS2_FS_WBUF_VERIFY is not set
@@ -1778,25 +1737,23 @@
 CONFIG_ENABLE_MUST_CHECK=y
 CONFIG_FRAME_WARN=1024
 CONFIG_MAGIC_SYSRQ=y
-# CONFIG_STRIP_ASM_SYMS is not set
+CONFIG_STRIP_ASM_SYMS=y
 CONFIG_UNUSED_SYMBOLS=y
 # CONFIG_DEBUG_FS is not set
 # CONFIG_HEADERS_CHECK is not set
 CONFIG_DEBUG_KERNEL=y
 # CONFIG_DEBUG_SHIRQ is not set
-CONFIG_DETECT_SOFTLOCKUP=y
-CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC=y
-CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC_VALUE=1
+# CONFIG_DETECT_SOFTLOCKUP is not set
 # CONFIG_DETECT_HUNG_TASK is not set
 # CONFIG_SCHED_DEBUG is not set
 # CONFIG_SCHEDSTATS is not set
 # CONFIG_TIMER_STATS is not set
 # CONFIG_DEBUG_OBJECTS is not set
 # CONFIG_DEBUG_SLAB is not set
-CONFIG_DEBUG_SLAB_DOUBLE_FREE=y
+# CONFIG_DEBUG_SLAB_DOUBLE_FREE is not set
 # CONFIG_DEBUG_RT_MUTEXES is not set
 # CONFIG_RT_MUTEX_TESTER is not set
-CONFIG_DEBUG_SPINLOCK=y
+# CONFIG_DEBUG_SPINLOCK is not set
 # CONFIG_DEBUG_MUTEXES is not set
 # CONFIG_DEBUG_LOCK_ALLOC is not set
 # CONFIG_PROVE_LOCKING is not set
@@ -1833,9 +1790,8 @@
 # CONFIG_KGDB is not set
 CONFIG_CMDLINE=""
 # CONFIG_DEBUG_STACK_USAGE is not set
-# CONFIG_SMTC_IDLE_HOOK_DEBUG is not set
 # CONFIG_RUNTIME_DEBUG is not set
-CONFIG_BDI_SWITCH=y
+# CONFIG_BDI_SWITCH is not set
 
 #
 # Security options
@@ -1847,6 +1803,7 @@
 CONFIG_SECURITY_NETWORK=y
 # CONFIG_SECURITY_PATH is not set
 # CONFIG_SECURITY_FILE_CAPABILITIES is not set
+# CONFIG_SECURITY_SELINUX is not set
 # CONFIG_SECURITY_TOMOYO is not set
 CONFIG_CRYPTO=y
 
@@ -1963,10 +1920,12 @@
 CONFIG_CRC32=y
 # CONFIG_CRC7 is not set
 CONFIG_LIBCRC32C=n
+CONFIG_AUDIT_GENERIC=y
 CONFIG_ZLIB_INFLATE=y
 CONFIG_ZLIB_DEFLATE=y
 CONFIG_LZO_COMPRESS=n
 CONFIG_LZO_DECOMPRESS=n
+CONFIG_DECOMPRESS_GZIP=y
 # CONFIG_TEXTSEARCH is not set
 # CONFIG_TEXTSEARCH_KMP is not set
 # CONFIG_TEXTSEARCH_BM is not set
--- 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
+#           Do 9. Feb 08:56:41 CET 2017
 #############################################
 
 #############################################
@@ -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/dect_io/init_dect_io
+++ linux-2.6.32/drivers/char/dect_io/init_dect_io
@@ -9,7 +9,7 @@
 
 for i in `find . -name Makefile.$KERNEL_CLASS` ; do
     dest=${i%.$KERNEL_CLASS}
-    source="`pwd`/$i"
+    source="${i##*/}"
     rm -f $dest
     ln -fvs $source $dest
 done
--- linux-2.6.32/drivers/char/flash_update/init_flash_update
+++ linux-2.6.32/drivers/char/flash_update/init_flash_update
@@ -9,7 +9,7 @@
 
 for i in `find . -name Makefile.$KERNEL_CLASS` ; do
     dest=${i%.$KERNEL_CLASS}
-    source="`pwd`/$i"
+    source="${i##*/}"
     rm -f $dest
     ln -fvs $source $dest
 done
--- 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;
-    }
-    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;
+\*--------------------------------------------------------------------------------*/
+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++;
+    }
+		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;
+            }
+				if(count >= 2) {
+					checksum[id].readmask = val2;
+				}
             }
-            while(*crashp && (*crashp != ',')) crashp++;        
-            if(*crashp == ',') crashp++;
+			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/char/ubik2/Kconfig
+++ linux-2.6.32/drivers/char/ubik2/Kconfig
@@ -0,0 +1,4 @@
+config UBIK2_ISDNSTACK_ON_CPU
+    int
+	default 0
+
--- linux-2.6.32/drivers/char/ubik2/linux_pcmlink_ul.h
+++ linux-2.6.32/drivers/char/ubik2/linux_pcmlink_ul.h
@@ -4,11 +4,10 @@
 #define __linux_pcmlink_ul_h__
 
 #include <linux/types.h> 
-/*--------------------------------------------------------------------------------*\
-\*--------------------------------------------------------------------------------*/
-enum _logic_chan_ll {
-   logic_chan_isdn = 0
-};
+#include <linux/module.h> 
+#include <linux/sched.h> 
+#include <linux/interrupt.h>
+#include <linux/slab.h> 
 
 /*------------------------------------------------------------------------------------------*\
 \*------------------------------------------------------------------------------------------*/
@@ -35,7 +34,7 @@
 #define PCMLINK_MAX_DYNHW_CHAN      3
 /*-------------------------------------------------------------------------------------*\
 \*-------------------------------------------------------------------------------------*/
-enum _chan_message_voip_config{
+enum _chan_message_voip_config {
     voip_chanx_off           = 0,
     voip_chanx_8khz          = 1,
     voip_chanx_8khz_only_rcv = 2
@@ -93,8 +92,8 @@
 #define PCMBUS_MAX_AUDIOCHAN(a) ((((a)->SupportFlag) >> 26) & 0x03)
 #define PCMBUS_MAX_ECCHAN(a)    ((((a)->SupportFlag) >> 22) & 0x0F)
 #define PCMBUS_MAX_CODECCHAN(a) ((((a)->SupportFlag) >> 17) & 0x1F)
-#define PCMBUS_MAX_TECHAN(a)    ((((a)->SupportFlag) >> 13) & 0x0F)
-#define PCMBUS_MAX_NTCHAN(a)    ((((a)->SupportFlag) >>  9) & 0x0F)
+#define PCMBUS_MAX_NTCHAN(a)    ((((a)->SupportFlag) >> 13) & 0x0F)
+#define PCMBUS_MAX_TECHAN(a)    ((((a)->SupportFlag) >>  9) & 0x0F)
 #define PCMBUS_MAX_DECTCHAN(a)  ((((a)->SupportFlag) >>  5) & 0x0F)
 #define PCMBUS_MAX_SLICCHAN(a)  ((((a)->SupportFlag) >>  2) & 0x07)
 #define PCMBUS_MAX_POTSCHAN(a)  ((((a)->SupportFlag) >>  1) & 0x01)
@@ -174,14 +173,21 @@
 void pcmlink_ul_dspfwversion_pcmrouter(struct _chan_configmsg_dsptomips **fwversion);
 
 /*--------------------------------------------------------------------------------*\
+ * nur fuer ISDN-Treiber: liefere Codecnames (TDM-Bus abhaengig)
+\*--------------------------------------------------------------------------------*/
+int pcmlink_ul_codectdmbus(char *table[], unsigned int maxentries);
+
+/*--------------------------------------------------------------------------------*\
  * nur fuer dect-Treiber:
  * maxslotlen: liefert maximale Slotlaenge
  * p[maxdectslots] : Pointertabelle: hier Daten hineinschreiben/lesen - Pointer nicht modifizieren!
  * Achtung es muessen immer auch die (Dummy-)Daten fuer Tx komplett geschrieben werden!
  * Returnwert: Handle
+ *
+ * Returnwert der RxTxCallback: 0 success, 1 fehlerhafte Daten detektiert
 \*--------------------------------------------------------------------------------*/
 void *pcmlink_ul_register_dectcontrol(unsigned int *maxslotlen, unsigned int *maxdectslots,
-                                      void RxTxCallback(unsigned char **p_rx, unsigned char **p_tx));
+                                      int RxTxCallback(unsigned char **p_rx, unsigned char **p_tx));
 
 /*--------------------------------------------------------------------------------*\
  * nur fuer dect-Treiber:
@@ -204,12 +210,14 @@
  *              ptxslottab[]: Slotzeigertabelle fuer zum PCM-Bus zu verschickende Daten - 
  *                            im Aufruf zu fuellen 
  *              slotlen:      Laenge der Daten pro Slot in Byte
+ *              flag:         0x0: alles ok
+ *                            0x1: trigger too late erkannt (CELT-Resync-notwendig)  
  *
  *  Returnparameter: Slothandle            
  *              NULL: falls Slots bereits belegt/Konflikte mit vergebenen Slots/der Isdn-Treiber nicht laeuft
 \*--------------------------------------------------------------------------------*/
 void *pcmlink_ul_openslots(void *linkhandle, void *ref, 
-                           void (*RxTxCallback)(void *ref, short slotentries, unsigned char *prxslottab[], unsigned char *ptxslottab[], size_t slotlen),
+                           void (*RxTxCallback)(void *ref, short slotentries, unsigned char *prxslottab[], unsigned char *ptxslottab[], size_t slotlen, unsigned int flag),
                            unsigned int transp_flag
                           );
 
@@ -279,5 +287,300 @@
  * Meldet HwChannel-Support am PCM-Router ab
 \*--------------------------------------------------------------------------------*/
 void pcmlink_ul_release_dynhwchannel_control(void *handle);
+
+/*--------------------------------------------------------------------------------*\
+\*--------------------------------------------------------------------------------*/
+enum _pcmlink_status_operation {
+    slic_check,
+    slic_status,
+    slic_frequency,
+    slic_coefficients,
+    set_hw_cross,
+    unset_hw_cross,
+    hw_cross_noavail,
+	codecs_onoff,
+    dect_slotlen,
+    slot_mute,
+};
+/*--------------------------------------------------------------------------------*\
+ * slic_check:         ret: Anzahl der Slics (falls so ermittelbar)
+ * slic_status:        arg1: Slot
+ *                     arg2: veroderte Bits (s.u. SLIC_CODEC_... )
+ * slic_frequency:     Setze Slic-Klingelfrequenz arg1: Frequenz 
+ * slic_coefficients:  arg1: Koeffizienten-Index
+ * set_hw_cross: arg1 = ulchan1
+ *				 arg2 = ulchan2
+ *				 ret: -1 Hw-Cross Einstellungen muessen nach "alter" registerbasierter Loesung erfolgen
+ *				 0: ok
+ *				 1: dieser Channel kann nicht per HWCross geschaltet werden
+ * unset_hw_cross:   arg1 = ulchan1 (ret s.o.)
+ * hw_cross_noavail: ret: 0 Anbindung ist Hw-Cross-faehig
+ * codecs_onoff: arg1 ulchan arg2 veroderbar Bit0: rx Bit1 tx
+ * Hw-abhaengiger Support: 
+ * slic_check          pef
+ * slic_status         pef, adsp
+ * slic_frequency      pef( 25 Hz, 50 Hz), adsp (fast beliebige Frequenz)
+ * slic_coefficients:  pef (Koeffizienten-Index 0: 3 dB 1: 0 dB)
+\*--------------------------------------------------------------------------------*/
+#define SLIC_CODEC_POWERDOWN                                 0x0000
+#define SLIC_CODEC_POWERUP                                   0x0001
+#define SLIC_CODEC_RING                                      0x0002
+#define SLIC_CODEC_CLIP                                      0x0004
+#define SLIC_CODEC_POLREV                                    0x0008
+
+/*--------------------------------------------------------------------------------*\
+ * generelle Funktion fuer ISDN-Treiber um Stati abzufragen/setzen
+ * Diese Funktion soll langfristig das Setzen von Registern abloesen
+ * Returnwert: Operations-spezifisch
+ *			   generell: < 0 nicht supported 
+\*--------------------------------------------------------------------------------*/
+int pcmlink_ul_status(enum _pcmlink_status_operation operation, unsigned int arg1, unsigned int arg2);
+
+#include <linux/version.h>
+#include <linux/spinlock.h>
+#if defined(CONFIG_AVM_IPI_YIELD)
+#include <asm/yield_context.h>
+#include <linux/simple_mempool.h>
+#endif/*--- #if defined(CONFIG_AVM_IPI_YIELD) ---*/
+
+#if defined(CONFIG_AVM_IPI_YIELD)
+/*--------------------------------------------------------------------------------*\
+\*--------------------------------------------------------------------------------*/
+static inline void pcmlink_ul_lock_init(spinlock_t *lock) {
+  yield_spin_lock_init(lock);
+}
+/*--------------------------------------------------------------------------------*\
+ * Speziallock: ist auch aus non-Linux-TC-Kontext aufrufbar 
+ * (soweit von Hardware unterstuetzt)
+ * wenn flags == NULL: keine Irqs sperren
+\*--------------------------------------------------------------------------------*/
+static inline void pcmlink_ul_lock(spinlock_t *lock, unsigned long *flags) {
+    if(flags) {
+        yield_spin_lock_irqsave(lock, *flags);
+    } else {
+        yield_spin_lock(lock);
+    }
+}
+/*--------------------------------------------------------------------------------*\
+ * wenn flags == NULL: keine Irqs restoren 
+\*--------------------------------------------------------------------------------*/
+static inline void pcmlink_ul_unlock(spinlock_t *lock, unsigned long *flags) {
+    if(flags) {
+        yield_spin_unlock_irqrestore(lock, *flags);
+    } else {
+        yield_spin_unlock(lock);
+    }
+}
+/*--------------------------------------------------------------------------------*\
+\*--------------------------------------------------------------------------------*/
+static inline int pcmlink_ul_yieldcontext(void) {
+    return !yield_is_linux_context();
+}
+/*--------------------------------------------------------------------------------*\
+\*--------------------------------------------------------------------------------*/
+static inline int pcmlink_ul_assert_on_yield_context(void) {
+    if(pcmlink_ul_yieldcontext()) {
+        printk(KERN_ERR"\nGREAT-ERROR: Do not use in Yield-Context pc=%pS ra=%pS\n", (void *)_THIS_IP_, (void *)_RET_IP_);
+        return 1;
+    }
+    return 0;
+}
+/*--------------------------------------------------------------------------------*\
+\*--------------------------------------------------------------------------------*/
+static inline void *pcmlink_ul_malloc(void *memhandle, unsigned int size) {
+    return simplemempool_alloc(memhandle, size, 0, (void *)_RET_IP_);
+}
+/*--------------------------------------------------------------------------------*\
+\*--------------------------------------------------------------------------------*/
+static inline void *pcmlink_ul_zalloc(void *memhandle, unsigned int size) {
+    return simplemempool_alloc(memhandle, size, 1, (void *)_RET_IP_);
+}
+/*--------------------------------------------------------------------------------*\
+\*--------------------------------------------------------------------------------*/
+static inline void pcmlink_ul_mfree(void *memhandle, void *ptr) {
+    simplemempool_free(memhandle, ptr, (void *)_RET_IP_);
+}
+/*--------------------------------------------------------------------------------*\
+\*--------------------------------------------------------------------------------*/
+static inline void pcmlink_ul_wake_up_interruptible(wait_queue_head_t *q){
+    yield_wake_up_interruptible(q);
+}
+/*--------------------------------------------------------------------------------*\
+\*--------------------------------------------------------------------------------*/
+static inline void pcmlink_ul_wake_up(wait_queue_head_t *q){
+    yield_wake_up(q);
+}
+/*--------------------------------------------------------------------------------*\
+\*--------------------------------------------------------------------------------*/
+static inline bool pcmlink_ul_schedule_work(struct work_struct *work) {
+    return yield_schedule_work(work);
+}
+/*--------------------------------------------------------------------------------*\
+\*--------------------------------------------------------------------------------*/
+static inline bool pcmlink_ul_queue_work_on(int cpu, struct workqueue_struct *wq, struct work_struct *work){
+    return yield_queue_work_on(cpu, wq, work);
+}
+/*--------------------------------------------------------------------------------*\
+\*--------------------------------------------------------------------------------*/
+static inline bool pcmlink_ul_schedule_delayed_work(struct delayed_work *dwork, unsigned long delay) {
+    return yield_schedule_delayed_work(dwork, delay);
+}
+/*--------------------------------------------------------------------------------*\
+\*--------------------------------------------------------------------------------*/
+static inline void pcmlink_ul_tasklet_hi_schedule(struct tasklet_struct *t) {
+    yield_tasklet_hi_schedule(t);
+}
+/*--------------------------------------------------------------------------------*\
+\*--------------------------------------------------------------------------------*/
+static inline bool pcmlink_ul_try_module_get(struct module *module) {
+    return yield_try_module_get(module);
+}
+/*--------------------------------------------------------------------------------*\
+\*--------------------------------------------------------------------------------*/
+static inline void pcmlink_ul_module_put(struct module *module) {
+    yield_module_put(module);
+}
+/*--------------------------------------------------------------------------------*\
+\*--------------------------------------------------------------------------------*/
+static inline void *pcmlink_ul_alloc_init(char *pool_name, unsigned int pool_size){
+    return simplemempool_alloc_init(pool_name, pool_size);
+}
+/*--------------------------------------------------------------------------------*\
+\*--------------------------------------------------------------------------------*/
+static inline void pcmlink_ul_alloc_exit(void *pmp){
+    simplemempool_alloc_exit(pmp);
+}
+
+#else /*--- #if defined(CONFIG_AVM_IPI_YIELD) ---*/
+/*--------------------------------------------------------------------------------*\
+\*--------------------------------------------------------------------------------*/
+static inline void pcmlink_ul_lock_init(spinlock_t *lock) {
+  spin_lock_init(lock);
+}
+/*--------------------------------------------------------------------------------*\
+ * Speziallock: ist auch aus non-Linux-TC-Kontext aufrufbar 
+ * (soweit von Hardware unterstuetzt)
+ * wenn flags == NULL: keine Irqs sperren
+\*--------------------------------------------------------------------------------*/
+static inline void pcmlink_ul_lock(spinlock_t *lock, unsigned long *flags) {
+    if(flags) {
+        spin_lock_irqsave(lock, *flags);
+    } else {
+        spin_lock(lock);
+    }
+}
+/*--------------------------------------------------------------------------------*\
+ * wenn flags == NULL: keine Irqs restoren 
+\*--------------------------------------------------------------------------------*/
+static inline void pcmlink_ul_unlock(spinlock_t *lock, unsigned long *flags) {
+    if(flags) {
+        spin_unlock_irqrestore(lock, *flags);
+    } else {
+        spin_unlock(lock);
+    }
+}
+/*--------------------------------------------------------------------------------*\
+\*--------------------------------------------------------------------------------*/
+static inline int pcmlink_ul_yieldcontext(void) {
+    return 0;
+}
+/*--------------------------------------------------------------------------------*\
+\*--------------------------------------------------------------------------------*/
+static inline int pcmlink_ul_assert_on_yield_context(void) {
+    return 0;
+}
+/*--------------------------------------------------------------------------------*\
+\*--------------------------------------------------------------------------------*/
+static inline void *pcmlink_ul_malloc(void *dummy __maybe_unused, unsigned int size) {
+    return kmalloc(size, GFP_ATOMIC);
+}
+/*--------------------------------------------------------------------------------*\
+\*--------------------------------------------------------------------------------*/
+static inline void *pcmlink_ul_zalloc(void *dummy __maybe_unused, unsigned int size) {
+    return kzalloc(size, GFP_ATOMIC);
+}
+/*--------------------------------------------------------------------------------*\
+\*--------------------------------------------------------------------------------*/
+static inline void pcmlink_ul_mfree(void *dummy __maybe_unused, void *ptr) {
+    kfree(ptr);
+}
+/*--------------------------------------------------------------------------------*\
+\*--------------------------------------------------------------------------------*/
+static inline void pcmlink_ul_wake_up_interruptible(wait_queue_head_t *q){
+    wake_up_interruptible(q);
+}
+/*--------------------------------------------------------------------------------*\
+\*--------------------------------------------------------------------------------*/
+static inline void pcmlink_ul_wake_up(wait_queue_head_t *q){
+    wake_up(q);
+}
+/*--------------------------------------------------------------------------------*\
+\*--------------------------------------------------------------------------------*/
+static inline bool pcmlink_ul_schedule_work(struct work_struct *work) {
+    return schedule_work(work);
+}
+/*--------------------------------------------------------------------------------*\
+\*--------------------------------------------------------------------------------*/
+static inline bool pcmlink_ul_queue_work_on(int cpu, struct workqueue_struct *wq, struct work_struct *work){
+    return queue_work_on(cpu, wq, work);
+}
+/*--------------------------------------------------------------------------------*\
+\*--------------------------------------------------------------------------------*/
+static inline bool pcmlink_ul_schedule_delayed_work(struct delayed_work *dwork, unsigned long delay) {
+    return schedule_delayed_work(dwork, delay);
+}
+/*--------------------------------------------------------------------------------*\
+\*--------------------------------------------------------------------------------*/
+static inline void pcmlink_ul_tasklet_hi_schedule(struct tasklet_struct *t) {
+    tasklet_hi_schedule(t);
+}
+/*--------------------------------------------------------------------------------*\
+\*--------------------------------------------------------------------------------*/
+static inline bool pcmlink_ul_try_module_get(struct module *module) {
+    return try_module_get(module);
+}
+/*--------------------------------------------------------------------------------*\
+\*--------------------------------------------------------------------------------*/
+static inline void pcmlink_ul_module_put(struct module *module) {
+    module_put(module);
+}
+/*--------------------------------------------------------------------------------*\
+ * nur dummy - aber handle zurueckliefern
+\*--------------------------------------------------------------------------------*/
+static inline void *pcmlink_ul_alloc_init(char *pool_name __maybe_unused, unsigned int pool_size __maybe_unused){
+    return kmalloc(4, GFP_KERNEL);
+}
+/*--------------------------------------------------------------------------------*\
+ * nur dummy
+\*--------------------------------------------------------------------------------*/
+static inline void pcmlink_ul_alloc_exit(void *pmp){
+    kfree(pmp);
+}
+#endif/*--- #else  ---*//*--- #if defined(CONFIG_AVM_IPI_YIELD) ---*/
+
+/*--------------------------------------------------------------------------------*\
+ * Registriert die DECT-Slot-Callback fuer den DECT-Daten-Pfad (non-PCM)
+ * ref: private Data (!=NULL)
+ * DECTSlotIngressCallback: Callback Daten zum Stub
+ * DECTSlotEgressCallback:  Callback Daten vom Stub
+ *
+ * Return-Parameter: > = Laenge der Daten pro Slot in Byte
+ *                       sonst Fehler
+ * Callbacks mit folgenden Parametern:
+ *          ref:            private Data
+ *          slot:           beginnend mit 1 !
+ *          ingress_data:   Pointer auf Daten zum DECT-Stub (umkopieren erforderlich)
+ *          eggress_data:   hier die Daten reinkopieren
+ * 
+ * Format der Daten: bei G722 alle 16 Bit Werte verdoppelt ( 128 kBit)
+\*--------------------------------------------------------------------------------*/
+int Register_DECTSlot_Callback(void *ref,
+                               void (*DECTSlotIngressCallback)(void *ref, unsigned int dectslot, const unsigned short *ingress_data),
+                               void (*DECTSlotEgressCallback)(void *ref, unsigned int dectslot, const unsigned short *egress_data));
+
+/*--------------------------------------------------------------------------------*\
+ * DECT-Slot-Callbacks abmelden
+\*--------------------------------------------------------------------------------*/
+void Release_DECTSlot_Callback(void *ref);
 #endif/*--- #if defined(__KERNEL__) ---*/
 #endif/*--- #ifndef __linux_pcmlink_ul_h__ ---*/
--- linux-2.6.32/drivers/isdn/avm_dect/init_avm_dect
+++ linux-2.6.32/drivers/isdn/avm_dect/init_avm_dect
@@ -9,7 +9,7 @@
 
 for i in `find . -name Makefile.$KERNEL_CLASS` ; do
     dest=${i%.$KERNEL_CLASS}
-    source="`pwd`/$i"
+    source="${i##*/}"
     rm -f $dest
     ln -fvs $source $dest
 done
--- linux-2.6.32/drivers/isdn/isdn_fon5/init_isdn
+++ linux-2.6.32/drivers/isdn/isdn_fon5/init_isdn
@@ -9,7 +9,7 @@
 
 for i in `find . -name Makefile.$KERNEL_CLASS` ; do
     dest=${i%.$KERNEL_CLASS}
-    source="`pwd`/$i"
+    source="${i##*/}"
     rm -f $dest
     ln -fvs $source $dest
 done
--- linux-2.6.32/drivers/mtd/maps/plat-nor.c
+++ linux-2.6.32/drivers/mtd/maps/plat-nor.c
@@ -92,22 +92,53 @@
 	return plat_nor_mtd_map_read(map, ofs ^0x02);
 }
 
+/*--------------------------------------------------------------------------------*\
+\*--------------------------------------------------------------------------------*/
+static inline void copy_u8vals(u16 data, u8 *val1, u8 *val2) {
+#ifdef __BIG_ENDIAN
+        if(val1) *val1 = (unsigned char)(data >> 8);
+        if(val2) *val2 = (unsigned char)(data & 0xFF);
+#endif 
+#ifdef __LITTLE_ENDIAN
+        if(val1) *val1 = (unsigned char)(data & 0xFF);
+        if(val2) *val2 = (unsigned char)(data >> 8);
+#endif
+}
+
 /*------------------------------------------------------------------------------------------*\
 \*------------------------------------------------------------------------------------------*/
 static void plat_nor_mtd_map_copy_from(struct map_info *map, void *to, unsigned long from, ssize_t len) {
+    u16 *src;
+    u8  *dest8;
+    u16 data;
 
-    unsigned char *src, *dest;
-    
-    src  = (unsigned char *)(from + map->virt);
-    dest = (unsigned char *)to;
+    src   = (u16 *)(from + map->virt);
+    dest8 = (unsigned char*)to;
 
     ifx_enable_ebu();
-    
-    memcpy(dest, src, len);
+    if ((unsigned long)src & 0x1) {
+        u16* ptr;
 
+        ptr = (u16*)(((unsigned long)src) & ~0x1);
+        data = *ptr;
+        src = ptr + 1;
+
+        copy_u8vals(data, NULL, dest8);
+        dest8++, len-= 1;
+    }
+    while (len > 1) {
+        data = *src++;
+        copy_u8vals(data, dest8, dest8 + 1);
+        dest8 += 2, len -= 2;
+    }
+    if (len > 0) {
+        data = *src;
+        copy_u8vals(data, dest8, NULL);
+    }
     ifx_disable_ebu();
 }
 
+
 /*------------------------------------------------------------------------------------------*\
 \*------------------------------------------------------------------------------------------*/
 static void plat_nor_mtd_map_copy_to(struct map_info *map, unsigned long to, const void *from, ssize_t len) {
--- 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;
-
-                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);
+                hsnand->ecc_error = no_error;
+                if (likely(hsnand->enable_hwecc == chip_enable_hwecc)) {
+
+                    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);
-
-        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);         
+#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);
+    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);
-
-        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);         
+#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);         
 
 #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/net/avm_cpmac/configs/avmnet_hw_config.h
+++ linux-2.6.32/drivers/net/avm_cpmac/configs/avmnet_hw_config.h
@@ -62,6 +62,11 @@
 #include "config_HW214.h"
 #endif
 
+#if (defined(CONFIG_MACH_ATHEROS) && defined(CONFIG_MACH_QCA953x)) || (defined(CONFIG_ATH79) && defined(CONFIG_SOC_QCA953X))
+#include "config_HW215.h"
+#include "config_HW216.h"
+#endif
+
 #ifndef NUM_ENTITY
 #if defined(NUM_ENTITY)
 #  undef NUM_ENTITY
@@ -307,6 +312,23 @@
         .avm_devices = avmnet_hw214_avm_devices
     },
 #endif /*--- #if defined(CONFIG_MACH_QCA955x) ---*/
+#if (defined(CONFIG_MACH_ATHEROS) && defined(CONFIG_MACH_QCA953x)) || (defined(CONFIG_ATH79) && defined(CONFIG_SOC_QCA953X))
+    {
+        // 310 II
+        .hw_id = 215,
+        .config = &avmnet_HW215,
+        .nr_avm_devices = NUM_ENTITY( avmnet_hw215_avm_devices ),
+        .avm_devices = avmnet_hw215_avm_devices
+    },
+    {
+        // Repeater AC 1160
+        .hw_id = 216,
+        .config = &avmnet_HW216,
+        .nr_avm_devices = NUM_ENTITY( avmnet_hw216_avm_devices ),
+        .avm_devices = avmnet_hw216_avm_devices
+    },
+
+#endif /*--- #if (defined(CONFIG_MACH_ATHEROS) && defined(CONFIG_MACH_QCA953x)) || (defined(CONFIG_ATH79) && defined(CONFIG_SOC_QCA953X)) ---*/
 };
 
 #endif
--- /dev/null
+++ linux-2.6.32/drivers/net/avm_cpmac/configs/config_HW215.h
@@ -0,0 +1,127 @@
+#if !defined(__AVM_NET_CFG_ATHEROS_HW215)
+#define __AVM_NET_CFG_ATHEROS_HW215
+
+#include <avmnet_module.h>
+#include <avmnet_config.h>
+#include "../switch/atheros/atheros_mac.h"
+#include "../phy/avmnet_ar803x.h"
+#include "../phy/avmnet_ar8326.h"
+
+#include <atheros.h>
+
+extern avmnet_module_t hw215_gmac1, hw215_ath_switch, hw215_module_eth0;
+
+avmnet_device_t avmnet_hw215_avm_device_0 ____cacheline_aligned =
+{
+   .device            = NULL,
+   .device_name       = "eth0",
+   .external_port_no  = 0,
+   .device_ops        = {
+                          /*--- .ndo_get_stats        = athr_gmac_get_stats, ---*/
+                          .ndo_open             = avmnet_netdev_open,
+                          .ndo_stop             = avmnet_netdev_stop,
+                          /*--- .ndo_do_ioctl         = athr_gmac_do_ioctl, ---*/
+                          .ndo_tx_timeout       = athr_gmac_tx_timeout,
+                          .ndo_start_xmit       = athr_gmac_hard_start
+                        },
+   .mac_module        = &hw215_gmac1,
+   .vlanID            = 1, // GMAC1, SW MAC 1
+   .sizeof_priv       = sizeof(avmnet_netdev_priv_t),
+   .device_setup      = athr_gmac_setup_eth,
+   .device_setup_priv = athr_gmac_setup_eth_priv,
+};
+
+avmnet_device_t *avmnet_hw215_avm_devices[] = {
+    &avmnet_hw215_avm_device_0
+}; 
+
+avmnet_module_t avmnet_HW215 ____cacheline_aligned =
+{
+    .name           = "athmac",
+    .type           = avmnet_modtype_switch,
+    .priv           = NULL,
+    .initdata       = { .mac = { .flags = 0 }},
+
+    .init           = athmac_init,
+    .setup          = athmac_setup,
+    .exit           = athmac_exit,
+    
+    .parent         = NULL,
+    .num_children   = 1,
+    .children       = { &hw215_gmac1 }
+};
+
+avmnet_module_t hw215_gmac1 ____cacheline_aligned =
+{
+    .name           = "gmac1",
+    .type           = avmnet_modtype_switch,
+    .priv           = NULL,
+    .initdata.mac   = {  .flags = AVMNET_CONFIG_FLAG_BASEADDR
+                                | AVMNET_CONFIG_FLAG_IRQ
+                                | AVMNET_CONFIG_FLAG_SWITCHPORT,
+                         .base_addr = ATH_GE1_BASE, 
+                         .irq = ATH_CPU_IRQ_GE1, 
+                         .mac_nr = 1
+                      },
+
+    .init           = athmac_gmac_init,
+    .setup          = athmac_gmac_setup,
+    .exit           = athmac_gmac_exit,
+
+    .reg_read       = athmac_reg_read,
+    .reg_write      = athmac_reg_write,
+    .lock           = athmac_lock,
+    .unlock         = athmac_unlock,
+    .status_changed = athmac_status_changed,
+    .poll           = athmac_poll,
+    .set_status     = athgmac_set_status,
+    .setup_irq      = athmac_setup_irq,
+
+    .parent         = &avmnet_HW215,
+    .num_children   = 1,
+    .children       = { &hw215_ath_switch },
+};
+
+avmnet_module_t hw215_ath_switch ____cacheline_aligned =
+{
+    .name           = "ar8326",
+    .type           = avmnet_modtype_switch,
+    .priv           = NULL,
+    .initdata       = { .swi = { .flags = AVMNET_CONFIG_FLAG_IRQ, .irq = ATH_MISC_IRQ_ENET_LINK }},
+
+    .init           = avmnet_ar8326_init,
+    .setup          = avmnet_ar8326_setup,
+    .exit           = avmnet_ar8326_exit,
+
+    .reg_read       = avmnet_s27_rd_phy,
+    .reg_write      = avmnet_s27_wr_phy,
+    .lock           = avmnet_s27_lock,
+    .unlock         = avmnet_s27_unlock,
+    .status_changed = avmnet_ar8326_status_changed,
+    .poll           = avmnet_ar8326_status_poll,
+    .set_status     = avmnet_ar8326_set_status,
+    .setup_irq      = avmnet_ar8326_setup_interrupt,
+
+    .parent         = &hw215_gmac1,
+    .num_children   = 1,
+    .children       = { &hw215_module_eth0 }
+};
+
+avmnet_module_t hw215_module_eth0 ____cacheline_aligned =
+{
+    .name           = "ar803x0",
+    .device_id      = &avmnet_hw215_avm_device_0,
+    .type           = avmnet_modtype_phy,
+    .priv           = NULL,
+    .initdata.phy   = { .flags = AVMNET_CONFIG_FLAG_MDIOADDR | AVMNET_CONFIG_FLAG_INTERNAL, .mdio_addr = 0 },
+
+     AR803X_STDFUNCS,
+    
+    .ethtool_ops    = AR803X_ETHOPS,
+
+    .parent         = &hw215_ath_switch,
+    .num_children   = 0,
+    .children       = {}
+};
+
+#endif
--- /dev/null
+++ linux-2.6.32/drivers/net/avm_cpmac/configs/config_HW216.h
@@ -0,0 +1,127 @@
+#if !defined(__AVM_NET_CFG_ATHEROS_HW216)
+#define __AVM_NET_CFG_ATHEROS_HW216
+
+#include <avmnet_module.h>
+#include <avmnet_config.h>
+#include "../switch/atheros/atheros_mac.h"
+#include "../phy/avmnet_ar803x.h"
+#include "../phy/avmnet_ar8326.h"
+
+#include <atheros.h>
+
+extern avmnet_module_t hw216_gmac1, hw216_ath_switch, hw216_module_eth0;
+
+avmnet_device_t avmnet_hw216_avm_device_0 ____cacheline_aligned =
+{
+   .device            = NULL,
+   .device_name       = "eth0",
+   .external_port_no  = 0,
+   .device_ops        = {
+                          /*--- .ndo_get_stats        = athr_gmac_get_stats, ---*/
+                          .ndo_open             = avmnet_netdev_open,
+                          .ndo_stop             = avmnet_netdev_stop,
+                          /*--- .ndo_do_ioctl         = athr_gmac_do_ioctl, ---*/
+                          .ndo_tx_timeout       = athr_gmac_tx_timeout,
+                          .ndo_start_xmit       = athr_gmac_hard_start
+                        },
+   .mac_module        = &hw216_gmac1,
+   .vlanID            = 1, // GMAC1, SW MAC 1
+   .sizeof_priv       = sizeof(avmnet_netdev_priv_t),
+   .device_setup      = athr_gmac_setup_eth,
+   .device_setup_priv = athr_gmac_setup_eth_priv,
+};
+
+avmnet_device_t *avmnet_hw216_avm_devices[] = {
+    &avmnet_hw216_avm_device_0
+}; 
+
+avmnet_module_t avmnet_HW216 ____cacheline_aligned =
+{
+    .name           = "athmac",
+    .type           = avmnet_modtype_switch,
+    .priv           = NULL,
+    .initdata       = { .mac = { .flags = 0 }},
+
+    .init           = athmac_init,
+    .setup          = athmac_setup,
+    .exit           = athmac_exit,
+    
+    .parent         = NULL,
+    .num_children   = 1,
+    .children       = { &hw216_gmac1 }
+};
+
+avmnet_module_t hw216_gmac1 ____cacheline_aligned =
+{
+    .name           = "gmac1",
+    .type           = avmnet_modtype_switch,
+    .priv           = NULL,
+    .initdata.mac   = {  .flags = AVMNET_CONFIG_FLAG_BASEADDR
+                                | AVMNET_CONFIG_FLAG_IRQ
+                                | AVMNET_CONFIG_FLAG_SWITCHPORT,
+                         .base_addr = ATH_GE1_BASE, 
+                         .irq = ATH_CPU_IRQ_GE1, 
+                         .mac_nr = 1
+                      },
+
+    .init           = athmac_gmac_init,
+    .setup          = athmac_gmac_setup,
+    .exit           = athmac_gmac_exit,
+
+    .reg_read       = athmac_reg_read,
+    .reg_write      = athmac_reg_write,
+    .lock           = athmac_lock,
+    .unlock         = athmac_unlock,
+    .status_changed = athmac_status_changed,
+    .poll           = athmac_poll,
+    .set_status     = athgmac_set_status,
+    .setup_irq      = athmac_setup_irq,
+
+    .parent         = &avmnet_HW216,
+    .num_children   = 1,
+    .children       = { &hw216_ath_switch },
+};
+
+avmnet_module_t hw216_ath_switch ____cacheline_aligned =
+{
+    .name           = "ar8326",
+    .type           = avmnet_modtype_switch,
+    .priv           = NULL,
+    .initdata       = { .swi = { .flags = AVMNET_CONFIG_FLAG_IRQ, .irq = ATH_MISC_IRQ_ENET_LINK }},
+
+    .init           = avmnet_ar8326_init,
+    .setup          = avmnet_ar8326_setup,
+    .exit           = avmnet_ar8326_exit,
+
+    .reg_read       = avmnet_s27_rd_phy,
+    .reg_write      = avmnet_s27_wr_phy,
+    .lock           = avmnet_s27_lock,
+    .unlock         = avmnet_s27_unlock,
+    .status_changed = avmnet_ar8326_status_changed,
+    .poll           = avmnet_ar8326_status_poll,
+    .set_status     = avmnet_ar8326_set_status,
+    .setup_irq      = avmnet_ar8326_setup_interrupt,
+
+    .parent         = &hw216_gmac1,
+    .num_children   = 1,
+    .children       = { &hw216_module_eth0 }
+};
+
+avmnet_module_t hw216_module_eth0 ____cacheline_aligned =
+{
+    .name           = "ar803x0",
+    .device_id      = &avmnet_hw216_avm_device_0,
+    .type           = avmnet_modtype_phy,
+    .priv           = NULL,
+    .initdata.phy   = { .flags = AVMNET_CONFIG_FLAG_MDIOADDR | AVMNET_CONFIG_FLAG_INTERNAL, .mdio_addr = 0 },
+
+     AR803X_STDFUNCS,
+    
+    .ethtool_ops    = AR803X_ETHOPS,
+
+    .parent         = &hw216_ath_switch,
+    .num_children   = 0,
+    .children       = {}
+};
+
+#endif
--- linux-2.6.32/drivers/net/avm_cpmac/phy/avmnet_ar8326.c
+++ linux-2.6.32/drivers/net/avm_cpmac/phy/avmnet_ar8326.c
@@ -414,7 +414,7 @@
     value = avmnet_athrs27_reg_read(this, S27_OPMODE_REG0);
     avmnet_athrs27_reg_write(this, S27_OPMODE_REG0, value | S27_MAC0_MAC_GMII_EN);  /* Set GMII mode */
 
-    if (soc_is_ar934x()) {
+    if (soc_is_ar934x() || soc_is_qca9531()) {
         value = avmnet_athrs27_reg_read(this, S27_FLD_MASK_REG);
         // send unknown uni-, broad- and multicast frames to CPU port
         avmnet_athrs27_reg_write(this, S27_FLD_MASK_REG, value | ((1<<25) | (1<<16) | 0x1));
--- linux-2.6.32/drivers/net/avm_cpmac/phy/avmnet_ar8326.h
+++ linux-2.6.32/drivers/net/avm_cpmac/phy/avmnet_ar8326.h
@@ -4,6 +4,7 @@
 #if LINUX_VERSION_CODE < KERNEL_VERSION(3, 10, 0)
 #define soc_is_ar934x   is_ar934x
 #define soc_is_qca955x  is_qca955x
+#define soc_is_qca9531  is_qca9531
 #define MISC_BIT_ENET_LINK RST_MISC_INTERRUPT_MASK_S26_MAC_INT_MASK_LSB
 #endif
 
--- linux-2.6.32/drivers/net/avm_cpmac/switch/atheros/atheros_gmac.c
+++ linux-2.6.32/drivers/net/avm_cpmac/switch/atheros/atheros_gmac.c
@@ -1690,7 +1690,7 @@
     }
 
 #if ! defined(CONFIG_MACH_AR724x) && ! defined(CONFIG_SOC_AR724X)
-    if (soc_is_ar934x() || soc_is_qca955x()) {
+    if (soc_is_ar934x() || soc_is_qca955x() || soc_is_qca9531()) {
         ath_reg_rmw_set(SWITCH_CLOCK_SPARE_ADDRESS, (1 << 6));      /*--- MDIO_CLK = 100MHz ---*/
     }
 #endif
--- linux-2.6.32/drivers/net/avm_cpmac/switch/atheros/atheros_mac.h
+++ linux-2.6.32/drivers/net/avm_cpmac/switch/atheros/atheros_mac.h
@@ -27,6 +27,7 @@
 #if LINUX_VERSION_CODE < KERNEL_VERSION(3, 10, 0)
 #define soc_is_ar934x   is_ar934x
 #define soc_is_qca955x  is_qca955x
+#define soc_is_qca9531  is_qca9531
 #endif
 
 #define GMAC_MAX_ETH_DEVS 6
--- linux-2.6.32/drivers/net/avm_cpmac/switch/ifx/ar10/ifxmips_ppa_datapath_ar10_a5.c
+++ linux-2.6.32/drivers/net/avm_cpmac/switch/ifx/ar10/ifxmips_ppa_datapath_ar10_a5.c
@@ -1660,20 +1660,17 @@
 	ASSERT((reg_desc.dataptr & (DMA_TX_ALIGNMENT - 1)) == 0,
 			"reg_desc.dataptr (0x%#x) must be 8 DWORDS aligned",
 			reg_desc.dataptr);
-	skb_to_free = get_skb_pointer(reg_desc.dataptr);
-	dev_kfree_skb_any(skb_to_free);
+	free_skb_clear_dataptr(&reg_desc);
 	put_skb_to_dbg_pool(skb);
 
     /*  detach from protocol    */
     skb_to_free = skb;
-    if( (skb = skb_break_away_from_protocol(skb)) == NULL) {
+    if( (skb = skb_break_away_from_protocol_avm(skb)) == NULL) {
         skb = skb_to_free;
 		ret = -ENOMEM;
 		goto ALLOC_SKB_TX_FAIL;
     }
 
-    dev_kfree_skb_any(skb_to_free);
-
     put_skb_to_dbg_pool(skb);
 #if defined(DEBUG_MIRROR_PROC) && DEBUG_MIRROR_PROC
 	if (g_mirror_netdev != NULL) {
@@ -1805,7 +1802,6 @@
 	unsigned long sys_flag;
 	volatile struct tx_descriptor *desc;
 	struct tx_descriptor reg_desc;
-	struct sk_buff *skb_to_free;
 
 	if (((uni_cell_header->pti == ATM_PTI_SEGF5
 			|| uni_cell_header->pti == ATM_PTI_E2EF5)
@@ -1860,8 +1856,7 @@
 	ASSERT((reg_desc.dataptr & (DMA_TX_ALIGNMENT - 1)) == 0,
 			"reg_desc.dataptr (0x%#x) must be 8 DWORDS aligned",
 			reg_desc.dataptr);
-	skb_to_free = get_skb_pointer(reg_desc.dataptr);
-	dev_kfree_skb_any(skb_to_free);
+	free_skb_clear_dataptr(&reg_desc);
 	put_skb_to_dbg_pool(skb);
 
 	/*  setup descriptor    */
@@ -2154,17 +2149,15 @@
 
     /*  free previous skb   */
     ASSERT((reg_desc.dataptr & 31) == 0, "reg_desc.dataptr (0x%#x) must be 8 DWORDS aligned", reg_desc.dataptr);
-    skb_to_free = get_skb_pointer(reg_desc.dataptr);
-    dev_kfree_skb_any(skb_to_free);
+    free_skb_clear_dataptr(&reg_desc);
 
     /*  detach from protocol    */
     skb_to_free = skb;
-    if( (skb = skb_break_away_from_protocol(skb)) == NULL) {
+    if( (skb = skb_break_away_from_protocol_avm(skb)) == NULL) {
         skb = skb_to_free;
 		goto ALLOC_SKB_TX_FAIL;
     }
 
-    dev_kfree_skb_any(skb_to_free);
     put_skb_to_dbg_pool(skb);
 
 #if defined(DEBUG_MIRROR_PROC) && DEBUG_MIRROR_PROC
@@ -3502,7 +3495,6 @@
         volatile struct tx_descriptor *desc =
                 &CPU_TO_WAN_SWAP_DESC_BASE[g_cpu_to_wan_swap_desc_pos];
         struct tx_descriptor reg_desc = { 0 };
-        struct sk_buff *skb_to_free;
 
         dbg("CPU_TO_WAN_SWAP_SIG");
         while (desc->own == 0) {
@@ -3519,9 +3511,7 @@
                 g_cpu_to_wan_swap_desc_pos = 0;
 
             /*  free previous skb   */
-            skb_to_free = get_skb_pointer(desc->dataptr);
-            if (skb_to_free != NULL)
-                dev_kfree_skb_any(skb_to_free);
+            free_skb_clear_dataptr(desc);
             put_skb_to_dbg_pool(new_skb);
 
             /*  update descriptor   */
@@ -3740,7 +3730,6 @@
     unsigned long sys_flag;
     volatile struct tx_descriptor *desc;
     struct tx_descriptor reg_desc;
-    struct sk_buff *skb_to_free;
     int byteoff;
     int conn;
 
@@ -3843,8 +3832,7 @@
     else
         dma_alignment_atm_bad_count++;
 
-    skb_to_free = get_skb_pointer(reg_desc.dataptr);
-    dev_kfree_skb_any(skb_to_free);
+    free_skb_clear_dataptr(&reg_desc);
     put_skb_to_dbg_pool(skb);
 
     /*  update descriptor   */
@@ -5555,10 +5543,14 @@
 
 static INLINE void free_dma(void) {
     volatile struct tx_descriptor *p;
-    struct sk_buff *skb_to_free;
     unsigned int i;
 
     printk(KERN_ERR "[%s] g_eth_wan_mode = %d, g_wanqos_en=%d\n", __func__, g_eth_wan_mode, g_wanqos_en );
+
+	dma_device_unregister(g_dma_device_ppe);
+	dma_device_release(g_dma_device_ppe);
+	g_dma_device_ppe = NULL;
+
     if ( g_eth_wan_mode == 0 || g_wanqos_en )
     {
         // can be cleared here (CPU -> Shared-Mem)
@@ -5566,8 +5558,7 @@
         p = (volatile struct tx_descriptor *)CPU_TO_WAN_TX_DESC_BASE;
         for ( i = 0; i < CPU_TO_WAN_TX_DESC_NUM; i++ )
         {
-            skb_to_free = get_skb_pointer(p->dataptr);
-            dev_kfree_skb_any(skb_to_free);
+        	free_skb_clear_dataptr(p);
             p++;
         }
 
@@ -5576,8 +5567,7 @@
         p = (volatile struct tx_descriptor *)DSL_WAN_TX_DESC_BASE(0);
         for ( i = 0; i < WAN_TX_DESC_NUM_TOTAL; i++ )
         {
-            skb_to_free = get_skb_pointer(g_eth_wan_mode == 0 ? p->dataptr << 2 : p->dataptr);
-            dev_kfree_skb_any(skb_to_free);
+        	free_skb_clear_dataptr_shift(p, ((g_eth_wan_mode == 0) ? 2 : 0));
             p++;
         }
     }
@@ -5593,8 +5583,7 @@
         p = (volatile struct tx_descriptor *)CPU_TO_WAN_SWAP_DESC_BASE;
         for ( i = 0; i < CPU_TO_WAN_SWAP_DESC_NUM; i++ )
         {
-            skb_to_free = get_skb_pointer(p->dataptr);
-            dev_kfree_skb_any(skb_to_free);
+        	free_skb_clear_dataptr(p);
             p++;
         }
     }
@@ -5607,8 +5596,7 @@
         p = (volatile struct tx_descriptor *)WAN_RX_DESC_BASE(0);
         for ( i = 0; i < WAN_RX_DESC_NUM(0); i++ )
         {
-            skb_to_free = get_skb_pointer(p->dataptr);
-            dev_kfree_skb_any(skb_to_free);
+        	free_skb_clear_dataptr(p);
             p++;
         }
 
@@ -5617,8 +5605,7 @@
         p = (volatile struct tx_descriptor *)WAN_RX_DESC_BASE(1);
         for ( i = 0; i < WAN_RX_DESC_NUM(1); i++ )
         {
-            skb_to_free = get_skb_pointer(p->dataptr << 2);
-            dev_kfree_skb_any(skb_to_free);
+        	free_skb_clear_dataptr_shift(p, 2);
             p++;
         }
     }
@@ -5633,8 +5620,7 @@
         if ( g_eth_wan_mode != 0 && !g_wanqos_en )
             break;
 #endif
-        skb_to_free = get_skb_pointer(p->dataptr);
-        dev_kfree_skb_any(skb_to_free);
+        free_skb_clear_dataptr(p);
         p++;
     }
 
@@ -5644,8 +5630,7 @@
     p = (volatile struct tx_descriptor *)DMA_RX_CH2_DESC_BASE;
     for ( i = 0; i < DMA_RX_CH2_DESC_NUM; i++ )
     {
-        skb_to_free = get_skb_pointer(p->dataptr);
-        dev_kfree_skb_any(skb_to_free);
+    	free_skb_clear_dataptr(p);
         p++;
     }
 #endif
@@ -5658,15 +5643,11 @@
         p = (volatile struct tx_descriptor *)DMA_TX_CH1_DESC_BASE;
         for ( i = 0; i < DMA_TX_CH1_DESC_NUM; i++ )
         {
-            skb_to_free = get_skb_pointer(p->dataptr);
-            dev_kfree_skb_any(skb_to_free);
+            free_skb_clear_dataptr(p);
             p++;
         }
     }
 
-	dma_device_unregister(g_dma_device_ppe);
-	dma_device_release(g_dma_device_ppe);
-	g_dma_device_ppe = NULL;
 
 #if defined(DEBUG_SKB_SWAP) && DEBUG_SKB_SWAP
     for ( i = 0; i < NUM_ENTITY(g_dbg_skb_swap_pool); i++ )
--- linux-2.6.32/drivers/net/avm_cpmac/switch/ifx/ar10/ifxmips_ppa_hal_ar10_a5.h
+++ linux-2.6.32/drivers/net/avm_cpmac/switch/ifx/ar10/ifxmips_ppa_hal_ar10_a5.h
@@ -314,7 +314,9 @@
 /*
  *  Helper Macro
  */
-#define NUM_ENTITY(x)                           (sizeof(x) / sizeof(*(x)))
+#ifndef NUM_ENTITY
+#define NUM_ENTITY ARRAY_SIZE
+#endif
 #define BITSIZEOF_UINT32                        (sizeof(uint32_t) * 8)
 #define BITSIZEOF_UINT16                        (sizeof(uint16_t) * 8)
 
--- linux-2.6.32/drivers/net/avm_cpmac/switch/ifx/ar9/ifxmips_ppa_datapath_ar9_a5.c
+++ linux-2.6.32/drivers/net/avm_cpmac/switch/ifx/ar9/ifxmips_ppa_datapath_ar9_a5.c
@@ -240,8 +240,6 @@
 
 #define ENABLE_LED_FRAMEWORK                    0
 
-#define ENABLE_NO_DELAY_ATM_SKB_FREE            1
-
 #define ENABLE_CONFIGURABLE_DSL_VLAN            1
 
 #if defined(CONFIG_IFX_PPA_DIRECTPATH_TX_QUEUE_SIZE)
@@ -1410,16 +1408,12 @@
 static INLINE struct sk_buff *alloc_skb_rx(void);
 static struct sk_buff *alloc_skb_tx_aligned(struct sk_buff *, int);
 static INLINE struct sk_buff *alloc_skb_tx(int);
-static struct sk_buff* skb_break_away_from_protocol(struct sk_buff *);
 static INLINE void __get_skb_from_dbg_pool(struct sk_buff *, const char *, unsigned int);
 #define get_skb_from_dbg_pool(skb)  __get_skb_from_dbg_pool(skb, __FUNCTION__, __LINE__)
-static INLINE struct sk_buff *__get_skb_pointer(unsigned int, const char *, unsigned int);
-#define get_skb_pointer(dataptr)    __get_skb_pointer(dataptr, __FUNCTION__, __LINE__)
 static INLINE void __put_skb_to_dbg_pool(struct sk_buff *, const char *, unsigned int);
 #define put_skb_to_dbg_pool(skb)    __put_skb_to_dbg_pool(skb, __FUNCTION__, __LINE__)
 static struct sk_buff* atm_alloc_tx(struct atm_vcc *, unsigned int);
 static INLINE void atm_free_tx_skb_vcc(struct sk_buff *skb);
-static INLINE void atm_free_tx_skb_vcc_delayed(struct sk_buff *skb);
 
 /*
  *  Mailbox handler
@@ -2183,11 +2177,9 @@
         return -EBUSY;
     }
 
-#if defined(ENABLE_NO_DELAY_ATM_SKB_FREE) && ENABLE_NO_DELAY_ATM_SKB_FREE
     skb_get(skb);
     atm_free_tx_skb_vcc(skb);
     ATM_SKB(skb)->vcc = NULL;
-#endif
 
     conn = find_vcc(vcc);
     if ( conn < 0 )
@@ -2328,10 +2320,6 @@
         /*  write back to physical memory   */
         dma_cache_wback((u32)skb->data - byteoff - sizeof(struct sk_buff *), skb->len + byteoff + sizeof(struct sk_buff *));
 #endif
-#if !defined(ENABLE_NO_DELAY_ATM_SKB_FREE) || !ENABLE_NO_DELAY_ATM_SKB_FREE
-        /*  before putting in TX queue, do something to prevent atm_may_send fail   */
-        atomic_sub(skb->truesize, &sk_atm(vcc)->sk_wmem_alloc);
-#endif
 		dma_alignment_atm_good_count++;
 #if defined(CONFIG_AVMNET_DEBUG) 
 		if ( g_dbg_datapath & DBG_ENABLE_MASK_DEBUG_ALIGNMENT )
@@ -2358,13 +2346,15 @@
 
     /*  free previous skb   */
     ASSERT((reg_desc.dataptr & (DMA_TX_ALIGNMENT - 1)) == 0, "reg_desc.dataptr (0x%#x) must be 8 DWORDS aligned", reg_desc.dataptr);
-    skb_to_free = get_skb_pointer(reg_desc.dataptr);
-    atm_free_tx_skb_vcc_delayed(skb_to_free);
+	free_skb_clear_dataptr(&reg_desc);
 
     /*  detach from protocol    */
     skb_to_free = skb;
-    skb = skb_break_away_from_protocol(skb);
-    dev_kfree_skb_any(skb_to_free);
+
+    if( (skb = skb_break_away_from_protocol_avm(skb)) == NULL) {
+        skb = skb_to_free;
+		goto ALLOC_SKB_TX_FAIL;
+    }
 
     put_skb_to_dbg_pool(skb);
 
@@ -2440,11 +2430,7 @@
     if ( vcc->qos.aal == ATM_AAL5 )
         g_atm_priv_data.wtx_drop_pdu++;
     UPDATE_VCC_STAT(conn, tx_dropped, 1);
-#if defined(ENABLE_NO_DELAY_ATM_SKB_FREE) && ENABLE_NO_DELAY_ATM_SKB_FREE
     atm_free_tx_skb_vcc(skb);
-#else
-    atm_free_tx_skb_vcc_delayed(skb);
-#endif
     return ret;
 }
 
@@ -2510,8 +2496,8 @@
 
     /*  free previous skb   */
     ASSERT((reg_desc.dataptr & (DMA_TX_ALIGNMENT - 1)) == 0, "reg_desc.dataptr (0x%#x) must be 8 DWORDS aligned", reg_desc.dataptr);
-    skb_to_free = get_skb_pointer(reg_desc.dataptr);
-    atm_free_tx_skb_vcc_delayed(skb_to_free);
+
+	free_skb_clear_dataptr(&reg_desc);
     put_skb_to_dbg_pool(skb);
 
     /*  setup descriptor    */
@@ -2771,13 +2757,15 @@
 
     /*  free previous skb   */
     ASSERT((reg_desc.dataptr & (DMA_TX_ALIGNMENT - 1)) == 0, "reg_desc.dataptr (0x%#x) must be 8 DWORDS aligned", reg_desc.dataptr);
-    skb_to_free = get_skb_pointer(reg_desc.dataptr);
-    dev_kfree_skb_any(skb_to_free);
+
+    free_skb_clear_dataptr(desc);
 
     /*  detach from protocol    */
     skb_to_free = skb;
-    skb = skb_break_away_from_protocol(skb);
-    dev_kfree_skb_any(skb_to_free);
+    if( (skb = skb_break_away_from_protocol_avm(skb)) == NULL) {
+        skb = skb_to_free;
+		goto ALLOC_SKB_TX_FAIL;
+    }
 
     put_skb_to_dbg_pool(skb);
 
@@ -3933,36 +3921,6 @@
     }
 }
 
-static INLINE void atm_free_tx_skb_vcc_delayed(struct sk_buff *skb)
-{
-#if !defined(ENABLE_NO_DELAY_ATM_SKB_FREE) || !ENABLE_NO_DELAY_ATM_SKB_FREE
-    struct atm_vcc* vcc;
-    int i;
-
-    ASSERT((u32)skb > 0x80000000, "atm_free_tx_skb_vcc: skb = %08X", (u32)skb);
-
-    vcc = ATM_SKB(skb)->vcc;
-
-    if ( (unsigned int)vcc >= KSEG0 && (unsigned int)vcc->pop >= KSEG0 )
-    {
-        for ( i = 0; i < ATM_PORT_NUMBER; i++ )
-            if ( vcc->dev == g_atm_priv_data.port[i].dev )
-                break;
-
-        if ( i < ATM_PORT_NUMBER && find_vcc(vcc) >= 0 )
-        {
-            ASSERT(atomic_read(&skb->users) != 0, "atm_free_tx_skb_vcc(vcc->pop): skb->users == 0, skb = %08X", (u32)skb);
-            atomic_add(skb->truesize, &sk_atm(vcc)->sk_wmem_alloc);
-            vcc->pop(vcc, skb);
-            return;
-        }
-    }
-#endif
-
-    //  Else
-    ASSERT(atomic_read(&skb->users) != 0, "atm_free_tx_skb_vcc(dev_kfree_skb_any): skb->users == 0, skb = %08X", (u32)skb);
-    dev_kfree_skb_any(skb);
-}
 
 static irqreturn_t mailbox0_irq_handler(int irq, void *dev_id)
 {
@@ -4093,9 +4051,7 @@
                 g_cpu_to_wan_swap_desc_pos = 0;
 
             /*  free previous skb   */
-            skb_to_free = get_skb_pointer(desc->dataptr);
-            if ( skb_to_free != NULL )
-                dev_kfree_skb_any(skb_to_free);
+            free_skb_clear_dataptr(desc);
             put_skb_to_dbg_pool(new_skb);
 
             /*  update descriptor   */
@@ -4492,8 +4448,7 @@
 	else
 		dma_alignment_atm_bad_count++;
 
-	skb_to_free = get_skb_pointer(reg_desc.dataptr);
-	dev_kfree_skb_any(skb_to_free);
+	free_skb_clear_dataptr(&reg_desc);
 	put_skb_to_dbg_pool(skb);
 
 	/*  update descriptor   */
@@ -6626,21 +6581,23 @@
     struct sk_buff *skb_to_free;
     int i;
 
+    dma_device_unregister(g_dma_device_ppe);
+    dma_device_release(g_dma_device_ppe);
+    g_dma_device_ppe = NULL;
+
     if ( g_eth_wan_mode == 0 || g_wanqos_en )
     {
         p = (volatile struct tx_descriptor *)CPU_TO_WAN_TX_DESC_BASE;
         for ( i = 0; i < CPU_TO_WAN_TX_DESC_NUM; i++ )
         {
-            skb_to_free = get_skb_pointer(p->dataptr);
-            dev_kfree_skb_any(skb_to_free);
+            free_skb_clear_dataptr(p);
             p++;
         }
 
         p = (volatile struct tx_descriptor *)DSL_WAN_TX_DESC_BASE(0);
         for ( i = 0; i < WAN_TX_DESC_NUM_TOTAL; i++ )
         {
-            skb_to_free = get_skb_pointer(g_eth_wan_mode == 0 ? p->dataptr << 2 : p->dataptr);
-            dev_kfree_skb_any(skb_to_free);
+            free_skb_clear_dataptr_shift(p, (g_eth_wan_mode == 0)?2:0 );
             p++;
         }
     }
@@ -6650,16 +6607,14 @@
         p = (volatile struct tx_descriptor *)WAN_RX_DESC_BASE(0);
         for ( i = 0; i < WAN_RX_DESC_NUM(0); i++ )
         {
-            skb_to_free = get_skb_pointer(p->dataptr);
-            dev_kfree_skb_any(skb_to_free);
+            free_skb_clear_dataptr(p);
             p++;
         }
 
         p = (volatile struct tx_descriptor *)WAN_RX_DESC_BASE(1);
         for ( i = 0; i < WAN_RX_DESC_NUM(1); i++ )
         {
-            skb_to_free = get_skb_pointer(p->dataptr << 2);
-            dev_kfree_skb_any(skb_to_free);
+            free_skb_clear_dataptr_shift(p, 2);
             p++;
         }
     }
@@ -6667,16 +6622,14 @@
     p = (volatile struct tx_descriptor *)DMA_RX_CH1_DESC_BASE;
     for ( i = 0; i < DMA_RX_CH1_DESC_NUM; i++ )
     {
-        skb_to_free = get_skb_pointer(p->dataptr);
-        dev_kfree_skb_any(skb_to_free);
+        free_skb_clear_dataptr(p);
         p++;
     }
 
     p = (volatile struct tx_descriptor *)DMA_RX_CH2_DESC_BASE;
     for ( i = 0; i < DMA_RX_CH2_DESC_NUM; i++ )
     {
-        skb_to_free = get_skb_pointer(p->dataptr);
-        dev_kfree_skb_any(skb_to_free);
+        free_skb_clear_dataptr(p);
         p++;
     }
 
@@ -6685,15 +6638,11 @@
         p = (volatile struct tx_descriptor *)DMA_TX_CH1_DESC_BASE;
         for ( i = 0; i < DMA_TX_CH1_DESC_NUM; i++ )
         {
-            skb_to_free = get_skb_pointer(p->dataptr);
-            dev_kfree_skb_any(skb_to_free);
+        	free_skb_clear_dataptr(p);
             p++;
         }
     }
 
-    dma_device_unregister(g_dma_device_ppe);
-    dma_device_release(g_dma_device_ppe);
-    g_dma_device_ppe = NULL;
 
 #if defined(DEBUG_SKB_SWAP) && DEBUG_SKB_SWAP
     for ( i = 0; i < NUM_ENTITY(g_dbg_skb_swap_pool); i++ )
--- linux-2.6.32/drivers/net/avm_cpmac/switch/ifx/common/ifxmips_ppa_datapath_common.h
+++ linux-2.6.32/drivers/net/avm_cpmac/switch/ifx/common/ifxmips_ppa_datapath_common.h
@@ -184,11 +184,26 @@
 /*
  *  Buffer Management
  */
-static struct sk_buff* skb_break_away_from_protocol(struct sk_buff *);
+static struct sk_buff* skb_break_away_from_protocol_avm(struct sk_buff *);
+
 static INLINE void __get_skb_from_dbg_pool(struct sk_buff *, const char *, unsigned int);
 #define get_skb_from_dbg_pool(skb)  __get_skb_from_dbg_pool(skb, __FUNCTION__, __LINE__)
-static INLINE struct sk_buff *__get_skb_pointer(unsigned int, const char *, unsigned int);
-#define get_skb_pointer(dataptr)    __get_skb_pointer(dataptr, __FUNCTION__, __LINE__)
+
+static INLINE void __free_skb_clear_dataptr( unsigned int dataptr, const char *func_name, unsigned int line_num);
+
+#define free_skb_clear_dataptr(descr)   \
+	do { \
+		smp_mb(); \
+		__free_skb_clear_dataptr((descr)->dataptr, __FUNCTION__, __LINE__); \
+	} while(0)
+
+#define free_skb_clear_dataptr_shift(descr, shift)    \
+	do { \
+		smp_mb(); \
+		__free_skb_clear_dataptr((((descr)->dataptr) << (shift)), __FUNCTION__, __LINE__); \
+	} while(0)
+
+
 static INLINE void __put_skb_to_dbg_pool(struct sk_buff *, const char *, unsigned int);
 #define put_skb_to_dbg_pool(skb)    __put_skb_to_dbg_pool(skb, __FUNCTION__, __LINE__)
 
@@ -3686,8 +3701,7 @@
 	ASSERT((reg_desc.dataptr & (DMA_TX_ALIGNMENT - 1)) == 0,
 			"reg_desc.dataptr (0x%#x) must be 8 DWORDS aligned",
 			reg_desc.dataptr);
-	skb_to_free = get_skb_pointer(reg_desc.dataptr);
-	dev_kfree_skb_any(skb_to_free);
+	free_skb_clear_dataptr(&reg_desc);
 	put_skb_to_dbg_pool(skb);
 
 	/*  setup descriptor    */
@@ -5999,39 +6013,25 @@
 /*------------------------------------------------------------------------------------------*\
 \*------------------------------------------------------------------------------------------*/
 
-static struct sk_buff* skb_break_away_from_protocol(struct sk_buff *skb) {
-	struct sk_buff *new_skb;
-
-	if (skb_shared(skb)) {
-		// destructor is NULL after skb_clone
-		new_skb = skb_clone(skb, GFP_ATOMIC);
-		if (new_skb == NULL)
-			return NULL;
-	} else
-		new_skb = skb_get(skb);
+static struct sk_buff* skb_break_away_from_protocol_avm(struct sk_buff *skb) {
+	skb = skb_share_check(skb, GFP_ATOMIC);
+	if (skb == NULL)
+		return NULL;
 
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,32)
-	dst_release(new_skb->dst);
-	new_skb->dst = NULL;
-#else
-	skb_dst_drop(new_skb);
-#endif
+	skb_dst_drop(skb);
 #ifdef CONFIG_XFRM
-	secpath_put(new_skb->sp);
-	new_skb->sp = NULL;
+	secpath_put(skb->sp);
+	skb->sp = NULL;
 #endif
 	/*
-	 *  ccb: why does lantiq not use skb_orphan?
+	 *  ccb: use orphan instead of lantiq concept
 	 */
-    if ( new_skb->destructor )
-    {
-        WARN_ON(in_irq());
-        new_skb->destructor(new_skb);
-        new_skb->destructor = NULL;
-    }
-	return new_skb;
+	skb_orphan(skb);
+	return skb;
 }
 
+/*------------------------------------------------------------------------------------------*\
+\*------------------------------------------------------------------------------------------*/
 static INLINE void __get_skb_from_dbg_pool(
 		struct sk_buff *skb __attribute__((unused)),
 		const char *func_name __attribute__((unused)),
@@ -6050,20 +6050,61 @@
 #endif
 }
 
-static INLINE struct sk_buff *__get_skb_pointer(unsigned int dataptr, const char *func_name, unsigned int line_num)
-{
+/*------------------------------------------------------------------------------------------*\
+\*------------------------------------------------------------------------------------------*/
+static INLINE void __put_skb_to_dbg_pool(struct sk_buff *skb __attribute__((unused)),
+		const char *func_name __attribute__((unused)), unsigned int line_num __attribute__((unused))) {
+#if defined(DEBUG_SKB_SWAP) && DEBUG_SKB_SWAP
+	int i;
+
+	for ( i = 0; i < NUM_ENTITY(g_dbg_skb_swap_pool) && g_dbg_skb_swap_pool[i] != NULL; i++ );
+	if ( i == NUM_ENTITY(g_dbg_skb_swap_pool) )
+	{
+		err("%s:%d: g_dbg_skb_swap_pool overrun", func_name, line_num);
+	}
+	else
+	g_dbg_skb_swap_pool[i] = skb;
+#endif
+}
+
+/*------------------------------------------------------------------------------------------*\
+\*------------------------------------------------------------------------------------------*/
+
+
+static INLINE struct sk_buff **dmadataptr_to_skbptr(unsigned int dataptr){
     unsigned int skb_dataptr;
+
+    skb_dataptr = (dataptr - 4) | KSEG1;
+    return (struct sk_buff **)skb_dataptr;
+}
+
+/*------------------------------------------------------------------------------------------*\
+\*------------------------------------------------------------------------------------------*/
+
+
+static INLINE void __free_skb_clear_dataptr(unsigned int dataptr, const char *func_name, unsigned int line_num) {
+    struct sk_buff **skbp;
     struct sk_buff *skb;
 
-    //  usually, CPE memory is less than 256M bytes
-    //  so NULL means invalid pointer
+
+    /*
+     * usually, CPE memory is less than 256M bytes
+     * so NULL means invalid pointer
+     */
     if ( dataptr == 0 ) {
-        dbg("dataptr is 0, it's supposed to be invalid pointer");
-        return NULL;
+        DBG_SKB_FREE("dataptr is 0, caller=%s at line %d\n", func_name, line_num);
+        return;
     }
 
-    skb_dataptr = (dataptr - 4) | KSEG1;
-    skb = *(struct sk_buff **)skb_dataptr;
+    skbp = dmadataptr_to_skbptr( dataptr );
+    skb = *skbp;
+    if (!skb){
+        DBG_SKB_FREE("implicit skb at dma dataptr %#x is 0, caller=%s at line %d\n", dataptr, func_name, line_num);
+    	return;
+    }
+    *skbp = NULL;
+
+    dev_kfree_skb_any(skb);
 
     __get_skb_from_dbg_pool(skb, func_name, line_num);
 
@@ -6074,23 +6115,15 @@
 			func_name, line_num, (unsigned int)skb, (unsigned int)skb->data, dataptr
 			);
 
-    return skb;
+	smp_mb();
+
+    return;
 }
 
+/*------------------------------------------------------------------------------------------*\
+\*------------------------------------------------------------------------------------------*/
+
 
-static INLINE void __put_skb_to_dbg_pool(struct sk_buff *skb __attribute__((unused)),
-		const char *func_name __attribute__((unused)), unsigned int line_num __attribute__((unused))) {
-#if defined(DEBUG_SKB_SWAP) && DEBUG_SKB_SWAP
-	int i;
 
-	for ( i = 0; i < NUM_ENTITY(g_dbg_skb_swap_pool) && g_dbg_skb_swap_pool[i] != NULL; i++ );
-	if ( i == NUM_ENTITY(g_dbg_skb_swap_pool) )
-	{
-		err("%s:%d: g_dbg_skb_swap_pool overrun", func_name, line_num);
-	}
-	else
-	g_dbg_skb_swap_pool[i] = skb;
-#endif
-}
 
 #endif // #ifndef _IFXMIPS_PPA_DATAPATH_COMMON
--- linux-2.6.32/drivers/net/avm_cpmac/switch/ifx/common/swi_ifx_common.h
+++ linux-2.6.32/drivers/net/avm_cpmac/switch/ifx/common/swi_ifx_common.h
@@ -37,6 +37,8 @@
 
 #define INIT_HW                                 1
 
+#define ENABLE_DBG_SKB_FREE						1
+
 #if defined(CONFIG_AVMNET_DEBUG) 
 #define DEBUG_DUMP_INIT                         0
 #define DEBUG_DUMP_SKB                          1
@@ -75,6 +77,12 @@
   #define ENABLE_DBG_PROC                       0
 #endif
 
+#if defined(ENABLE_DBG_SKB_FREE) && ENABLE_DBG_SKB_FREE
+#define DBG_SKB_FREE(format, arg...)                     do { printk(KERN_ERR format "\n", ##arg); } while ( 0 )
+#else
+#define DBG_SKB_FREE(format, arg...)
+#endif
+
 #if defined(ENABLE_DBG_PROC) && ENABLE_DBG_PROC
 #define err(format, arg...)                     do { if ( unlikely(g_dbg_datapath & DBG_ENABLE_MASK_ERR) ) printk(KERN_ERR __FILE__ ":%d:%s: " format "\n", __LINE__, __FUNCTION__, ##arg); } while ( 0 )
 #else
--- linux-2.6.32/drivers/net/avm_cpmac/switch/ifx/vr9/ifxmips_ppa_datapath_vr9_a5.c
+++ linux-2.6.32/drivers/net/avm_cpmac/switch/ifx/vr9/ifxmips_ppa_datapath_vr9_a5.c
@@ -849,7 +849,7 @@
 static INLINE void clear_local_variables(void);
 static INLINE void init_communication_data_structures(int);
 static INLINE int alloc_dma(void);
-static INLINE void free_dma(void);
+static void free_dma(void);
 
 /*
  *  DSL Data Led help function
@@ -1675,18 +1675,16 @@
 	ASSERT((reg_desc.dataptr & (DMA_TX_ALIGNMENT - 1)) == 0,
 			"reg_desc.dataptr (0x%#x) must be 8 DWORDS aligned",
 			reg_desc.dataptr);
-	skb_to_free = get_skb_pointer(reg_desc.dataptr);
-	dev_kfree_skb_any(skb_to_free);
+	free_skb_clear_dataptr(&reg_desc);
 	put_skb_to_dbg_pool(skb);
 
     /*  detach from protocol    */
     skb_to_free = skb;
-    if( (skb = skb_break_away_from_protocol(skb)) == NULL) {
+    if( (skb = skb_break_away_from_protocol_avm(skb)) == NULL) {
         skb = skb_to_free;
 		ret = -ENOMEM;
 		goto ALLOC_SKB_TX_FAIL;
     }
-    dev_kfree_skb_any(skb_to_free);
 
     put_skb_to_dbg_pool(skb);
 #if defined(DEBUG_MIRROR_PROC) && DEBUG_MIRROR_PROC
@@ -1788,7 +1786,6 @@
 	unsigned long sys_flag;
 	volatile struct tx_descriptor *desc;
 	struct tx_descriptor reg_desc;
-	struct sk_buff *skb_to_free;
 
 	if (((uni_cell_header->pti == ATM_PTI_SEGF5
 			|| uni_cell_header->pti == ATM_PTI_E2EF5)
@@ -1843,8 +1840,7 @@
 	ASSERT((reg_desc.dataptr & (DMA_TX_ALIGNMENT - 1)) == 0,
 			"reg_desc.dataptr (0x%#x) must be 8 DWORDS aligned",
 			reg_desc.dataptr);
-	skb_to_free = get_skb_pointer(reg_desc.dataptr);
-	dev_kfree_skb_any(skb_to_free);
+	free_skb_clear_dataptr(&reg_desc);
 	put_skb_to_dbg_pool(skb);
 
 	/*  setup descriptor    */
@@ -2178,16 +2174,14 @@
 
     /*  free previous skb   */
     ASSERT((reg_desc.dataptr & (DMA_ALIGNMENT - 1)) == 0, "reg_desc.dataptr (0x%#x) must be 8 DWORDS aligned", reg_desc.dataptr);
-    skb_to_free = get_skb_pointer(reg_desc.dataptr);
-    dev_kfree_skb_any(skb_to_free);
+    free_skb_clear_dataptr(&reg_desc);
 
     /*  detach from protocol    */
     skb_to_free = skb;
-    if( (skb = skb_break_away_from_protocol(skb)) == NULL) {
+    if( (skb = skb_break_away_from_protocol_avm(skb)) == NULL) {
         skb = skb_to_free;
 		goto ALLOC_SKB_TX_FAIL;
     }
-    dev_kfree_skb_any(skb_to_free);
 
     put_skb_to_dbg_pool(skb);
 
@@ -3598,7 +3592,6 @@
         volatile struct tx_descriptor *desc =
                 &CPU_TO_WAN_SWAP_DESC_BASE[g_cpu_to_wan_swap_desc_pos];
         struct tx_descriptor reg_desc = { 0 };
-        struct sk_buff *skb_to_free;
 
         dbg("CPU_TO_WAN_SWAP_SIG");
         while (desc->own == 0) {
@@ -3615,9 +3608,7 @@
                 g_cpu_to_wan_swap_desc_pos = 0;
 
             /*  free previous skb   */
-            skb_to_free = get_skb_pointer(desc->dataptr);
-            if (skb_to_free != NULL)
-                dev_kfree_skb_any(skb_to_free);
+            free_skb_clear_dataptr(desc);
             put_skb_to_dbg_pool(new_skb);
 
             /*  update descriptor   */
@@ -3847,7 +3838,6 @@
 	unsigned long sys_flag;
 	volatile struct tx_descriptor *desc;
 	struct tx_descriptor reg_desc;
-	struct sk_buff *skb_to_free;
 	int byteoff;
 	int conn;
 
@@ -3954,8 +3944,7 @@
 	else
 		dma_alignment_atm_bad_count++;
 
-	skb_to_free = get_skb_pointer(reg_desc.dataptr);
-	dev_kfree_skb_any(skb_to_free);
+	free_skb_clear_dataptr(&reg_desc);
 	put_skb_to_dbg_pool(skb);
 
 	/*  update descriptor   */
@@ -5669,26 +5658,30 @@
 	ALLOC_SKB_POOL_FAIL: return ret;
 }
 
-static INLINE void free_dma(void) {
+static void free_dma(void) {
     volatile struct tx_descriptor *p;
-    struct sk_buff *skb_to_free;
     int i;
 
+    // first do dma_device unregister (which removes many skb's) and sets
+    // pch->opt[i]=NULL
+    dma_device_unregister(g_dma_device_ppe);
+	dma_device_release(g_dma_device_ppe);
+	g_dma_device_ppe = NULL;
+
+    // after that we can walk through the channels and clear remaining skbs
     if ( g_eth_wan_mode == 0 || g_wanqos_en )
     {
         p = (volatile struct tx_descriptor *)CPU_TO_WAN_TX_DESC_BASE;
         for ( i = 0; i < CPU_TO_WAN_TX_DESC_NUM; i++ )
         {
-            skb_to_free = get_skb_pointer(p->dataptr);
-            dev_kfree_skb_any(skb_to_free);
+            free_skb_clear_dataptr(p);
             p++;
         }
 
         p = (volatile struct tx_descriptor *)DSL_WAN_TX_DESC_BASE(0);
         for ( i = 0; i < WAN_TX_DESC_NUM_TOTAL; i++ )
         {
-            skb_to_free = get_skb_pointer(g_eth_wan_mode == 0 ? p->dataptr << 2 : p->dataptr);
-            dev_kfree_skb_any(skb_to_free);
+            free_skb_clear_dataptr_shift(p, (g_eth_wan_mode == 0)?2:0 );
             p++;
         }
     }
@@ -5698,8 +5691,7 @@
         p = (volatile struct tx_descriptor *)CPU_TO_WAN_SWAP_DESC_BASE;
         for ( i = 0; i < CPU_TO_WAN_SWAP_DESC_NUM; i++ )
         {
-            skb_to_free = get_skb_pointer(p->dataptr);
-            dev_kfree_skb_any(skb_to_free);
+            free_skb_clear_dataptr(p);
             p++;
         }
     }
@@ -5709,16 +5701,14 @@
         p = (volatile struct tx_descriptor *)WAN_RX_DESC_BASE(0);
         for ( i = 0; i < WAN_RX_DESC_NUM(0); i++ )
         {
-            skb_to_free = get_skb_pointer(p->dataptr);
-            dev_kfree_skb_any(skb_to_free);
+            free_skb_clear_dataptr(p);
             p++;
         }
 
         p = (volatile struct tx_descriptor *)WAN_RX_DESC_BASE(1);
         for ( i = 0; i < WAN_RX_DESC_NUM(1); i++ )
         {
-            skb_to_free = get_skb_pointer(p->dataptr << 2);
-            dev_kfree_skb_any(skb_to_free);
+            free_skb_clear_dataptr_shift(p, 2);
             p++;
         }
     }
@@ -5730,8 +5720,7 @@
         if ( g_eth_wan_mode != 0 && !g_wanqos_en )
             break;
 #endif
-        skb_to_free = get_skb_pointer(p->dataptr);
-        dev_kfree_skb_any(skb_to_free);
+        free_skb_clear_dataptr(p);
         p++;
     }
 
@@ -5739,8 +5728,7 @@
     p = (volatile struct tx_descriptor *)DMA_RX_CH2_DESC_BASE;
     for ( i = 0; i < DMA_RX_CH2_DESC_NUM; i++ )
     {
-        skb_to_free = get_skb_pointer(p->dataptr);
-        dev_kfree_skb_any(skb_to_free);
+        free_skb_clear_dataptr(p);
         p++;
     }
 #endif
@@ -5750,15 +5738,11 @@
         p = (volatile struct tx_descriptor *)DMA_TX_CH1_DESC_BASE;
         for ( i = 0; i < DMA_TX_CH1_DESC_NUM; i++ )
         {
-            skb_to_free = get_skb_pointer(p->dataptr);
-            dev_kfree_skb_any(skb_to_free);
+            free_skb_clear_dataptr(p);
             p++;
         }
     }
 
-	dma_device_unregister(g_dma_device_ppe);
-	dma_device_release(g_dma_device_ppe);
-	g_dma_device_ppe = NULL;
 
 #if defined(DEBUG_SKB_SWAP) && DEBUG_SKB_SWAP
     for ( i = 0; i < NUM_ENTITY(g_dbg_skb_swap_pool); i++ )
@@ -6699,7 +6683,6 @@
     vcc_map_skb_prio_qos_queue = NULL;
     vcc_set_nr_qos_queues = NULL;
 
-
 	free_dma();
 
 	clear_share_buffer();
--- linux-2.6.32/drivers/net/avm_cpmac/switch/ifx/vr9/ifxmips_ppa_datapath_vr9_e5.c
+++ linux-2.6.32/drivers/net/avm_cpmac/switch/ifx/vr9/ifxmips_ppa_datapath_vr9_e5.c
@@ -1209,17 +1209,14 @@
 			skb->len + byteoff + sizeof(struct sk_buff *));
 
 	/*  free previous skb   */
-	skb_to_free = get_skb_pointer(desc->dataptr);
-	if (skb_to_free != NULL)
-		dev_kfree_skb_any(skb_to_free); // hier stuerzt es ab (Unhandled kernel unaligned access)
+	free_skb_clear_dataptr(desc);
 
 	/*  detach from protocol    */
 	skb_to_free = skb;
-    if( (skb = skb_break_away_from_protocol(skb)) == NULL) {
+    if( (skb = skb_break_away_from_protocol_avm(skb)) == NULL) {
         skb = skb_to_free;
 		goto ALLOC_SKB_TX_FAIL;
     }
-	dev_kfree_skb_any(skb_to_free);
 
 	put_skb_to_dbg_pool(skb);
 
@@ -1561,16 +1558,14 @@
 
     /*  free previous skb   */
     ASSERT((reg_desc.dataptr & 31) == 0, "reg_desc.dataptr (0x%#x) must be 8 DWORDS aligned", reg_desc.dataptr);
-    skb_to_free = get_skb_pointer(reg_desc.dataptr);
-    dev_kfree_skb_any(skb_to_free);
+    free_skb_clear_dataptr(&reg_desc);
 
     /*  detach from protocol    */
     skb_to_free = skb;
-    if( (skb = skb_break_away_from_protocol(skb)) == NULL) {
+    if( (skb = skb_break_away_from_protocol_avm(skb)) == NULL) {
         skb = skb_to_free;
 		goto ALLOC_SKB_TX_FAIL;
     }
-    dev_kfree_skb_any(skb_to_free);
 
     put_skb_to_dbg_pool(skb);
 
@@ -2077,7 +2072,6 @@
 		struct sk_buff *new_skb;
 		volatile struct tx_descriptor *desc = &CPU_TO_WAN_SWAP_DESC_BASE[g_cpu_to_wan_swap_desc_pos];
 		struct tx_descriptor reg_desc = { 0 };
-		struct sk_buff *skb_to_free;
 
 #if defined(CONFIG_AVMNET_DEBUG) 
 		if ( g_dbg_datapath & DBG_ENABLE_MASK_DEBUG_MAILBOX )
@@ -2097,9 +2091,7 @@
 				g_cpu_to_wan_swap_desc_pos = 0;
 
 			/*  free previous skb   */
-			skb_to_free = get_skb_pointer(desc->dataptr);
-			if (skb_to_free != NULL)
-				dev_kfree_skb_any(skb_to_free);
+			free_skb_clear_dataptr(desc);
 			put_skb_to_dbg_pool(new_skb);
 
 			/*  update descriptor   */
@@ -4431,9 +4423,12 @@
 static INLINE void free_dma(void)
 {
     volatile struct tx_descriptor *p;
-    struct sk_buff *skb_to_free;
     int i;
 
+    dma_device_unregister(g_dma_device_ppe);
+	dma_device_release(g_dma_device_ppe);
+	g_dma_device_ppe = NULL;
+
     if ( g_eth_wan_mode == 0 || g_wanqos_en )
     {
         if ( g_eth_wan_mode == 0 && g_dsl_bonding )
@@ -4443,16 +4438,14 @@
                 p = (volatile struct tx_descriptor *)E1_FRAG_RX_DESC_BASE(0);
                 for ( i = 0; i < E1_FRAG_RX_DESC_NUM; i++ )
                 {
-                    skb_to_free = get_skb_pointer(p->dataptr);
-                    dev_kfree_skb_any(skb_to_free);
+                    free_skb_clear_dataptr(p);
                     p++;
                 }
 
                 p = (volatile struct tx_descriptor *)B1_RX_LINK_LIST_DESC_BASE;
                 for ( i = 0; i < B1_RX_LINK_LIST_DESC_NUM; i++ )
                 {
-                    skb_to_free = get_skb_pointer(p->dataptr);
-                    dev_kfree_skb_any(skb_to_free);
+                    free_skb_clear_dataptr(p);
                     p++;
                 }
             }
@@ -4462,8 +4455,7 @@
             p = (volatile struct tx_descriptor *)CPU_TO_WAN_TX_DESC_BASE;
             for ( i = 0; i < CPU_TO_WAN_TX_DESC_NUM; i++ )
             {
-                skb_to_free = get_skb_pointer(p->dataptr);
-                dev_kfree_skb_any(skb_to_free);
+                free_skb_clear_dataptr(p);
                 p++;
             }
         }
@@ -4473,8 +4465,7 @@
             p = (volatile struct tx_descriptor *)WAN_TX_DESC_BASE(0);
             for ( i = 0; i < WAN_TX_DESC_NUM_TOTAL; i++ )
             {
-                skb_to_free = get_skb_pointer(p->dataptr);
-                dev_kfree_skb_any(skb_to_free);
+                free_skb_clear_dataptr(p);
                 p++;
             }
         }
@@ -4484,8 +4475,7 @@
             p = (volatile struct tx_descriptor *)CPU_TO_WAN_SWAP_DESC_BASE;
             for ( i = 0; i < CPU_TO_WAN_SWAP_DESC_NUM; i++ )
             {
-                skb_to_free = get_skb_pointer(p->dataptr);
-                dev_kfree_skb_any(skb_to_free);
+                free_skb_clear_dataptr(p);
                 p++;
             }
         }
@@ -4501,8 +4491,7 @@
             if ( g_eth_wan_mode != 0 && !g_wanqos_en )
                 break;
   #endif
-            skb_to_free = get_skb_pointer(p->dataptr);
-            dev_kfree_skb_any(skb_to_free);
+            free_skb_clear_dataptr(p);
             p++;
         }
     }
@@ -4512,8 +4501,7 @@
     p = (volatile struct tx_descriptor *)DMA_RX_CH2_DESC_BASE;
     for ( i = 0; i < DMA_RX_CH2_DESC_NUM; i++ )
     {
-        skb_to_free = get_skb_pointer(p->dataptr);
-        dev_kfree_skb_any(skb_to_free);
+        free_skb_clear_dataptr(p);
         p++;
     }
 #endif
@@ -4523,16 +4511,11 @@
         p = (volatile struct tx_descriptor *)DMA_TX_CH1_DESC_BASE;
         for ( i = 0; i < DMA_TX_CH1_DESC_NUM; i++ )
         {
-            skb_to_free = get_skb_pointer(p->dataptr);
-            dev_kfree_skb_any(skb_to_free);
+            free_skb_clear_dataptr(p);
             p++;
         }
     }
 
-	// AVM: we do this in dma_shutdown_gracefully
-	dma_device_unregister(g_dma_device_ppe);
-	dma_device_release(g_dma_device_ppe);
-	g_dma_device_ppe = NULL;
 
 #if defined(DEBUG_SKB_SWAP) && DEBUG_SKB_SWAP
     for ( i = 0; i < NUM_ENTITY(g_dbg_skb_swap_pool); i++ )
--- linux-2.6.32/drivers/serial/serial_avm_asc.c
+++ linux-2.6.32/drivers/serial/serial_avm_asc.c
@@ -15,6 +15,7 @@
 #define WORKAROUND_ACK_TIR_ON_ENTRY
 #define WORKAROUND_ACK_RIR_ON_ENTRY
 #define WORKAROUND_GEN_MISSING_ENABLE_TX_IRQ
+#define WORKAROUND_GEN_MISSING_TX_IRQ
 #include <asm/io.h>
 #include <asm/irq.h>
 #include <asm/addrspace.h>
@@ -45,18 +46,12 @@
 	struct ifx_asc_port_priv *priv = (struct ifx_asc_port_priv *)port_priv_data->port_specificdata;
     ifx_asc_reg_t *asc_reg = priv->base;
 
-	unsigned int fifocnt;
-	fifocnt = (asc_reg->asc_fstat & ASCFSTAT_TXFREEMASK) >> ASCFSTAT_TXFREEOFF;
-	if (( fifocnt == 0 ) && !(asc_reg->asc_irnicr & IFX_ASC_IRQ_LINE_TIR) ){
-#if defined(WORKAROUND_GEN_MISSING_ENABLE_TX_IRQ)
-        asc_reg->asc_irnicr |= IFX_ASC_IRQ_LINE_TIR;
-#endif
-        tx_bugfix_count_enable ++;
-	}
+	unsigned int fifofree;
+	fifofree = (asc_reg->asc_fstat & ASCFSTAT_TXFREEMASK) >> ASCFSTAT_TXFREEOFF;
 
     asc_reg->asc_irnen |= IFX_ASC_IRQ_LINE_TIR;
 
-	if (( fifocnt == 0 ) && !(asc_reg->asc_irnicr & IFX_ASC_IRQ_LINE_TIR) ){
+	if ( fifofree && !(asc_reg->asc_irnicr & IFX_ASC_IRQ_LINE_TIR) ){
 #if defined(WORKAROUND_GEN_MISSING_ENABLE_TX_IRQ)
         asc_reg->asc_irnicr |= IFX_ASC_IRQ_LINE_TIR;
 #endif
@@ -257,7 +252,7 @@
 
 	if (uart_circ_empty(xmit)) {
 		uart_avm_stop_tx(port);
-    } else if ((( asc_reg->asc_fstat & ASCFSTAT_TXFREEMASK ) >> ASCFSTAT_TXFREEOFF ) == 0 ) {
+    } else if ((( asc_reg->asc_fstat & ASCFSTAT_TXFREEMASK ) >> ASCFSTAT_TXFREEOFF )) {
 
         mb();
 
--- 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
@@ -370,8 +382,6 @@
 
 #define AVM_PA_PRIOACK_THRESH_PKTS   40   /* wait for X packets to do the TCP-ACK check */
 #define AVM_PA_PRIOACK_RATIO         70   /* % of packets have to be TCP-ACKs for positive check */
-#define AVM_PA_PRIOACK_PACKET_SIZE   120  /* packet-size to recognize a packet as TCP-ACK */
-#define AVM_PA_PRIOACK_PRIORITY      4    /* priority for TCP-ACK packets */
 
 /* ------------------------------------------------------------------------ */
 
@@ -390,10 +400,14 @@
                               tx_channel_activated:1,
                               rx_channel_stopped:1,
    /* prioack handling */
-                              prioack_enabled:1;
+                              prioack_enabled:1,
+                              tget_enabled:1; /* tget = turbo HTTP-GET */
    unsigned int               prioack_priority;
    unsigned                   prioack_acks;
    unsigned                   prioack_accl_acks;
+   unsigned int               tget_priority;
+   unsigned                   tgets;
+   unsigned                   tget_accl;
    
    /* stats */
    u32                        tx_pkts;
@@ -511,7 +525,6 @@
    unsigned                  tok_rate[TOK_SAMLES];
    unsigned                  tok_pps[TOK_SAMLES];
    unsigned long             tok_overlimit[TOK_SAMLES];
-   unsigned                  prioack_packet_size;
    unsigned                  prioack_thresh_packets;
    unsigned                  prioack_ratio;
    struct avm_hardware_pa    hardware_pa;
@@ -551,7 +564,6 @@
    .ewma_log = AVM_PA_EST_DEFAULT_EWMA_LOG,
    .cputime_est_idx = AVM_PA_CPUTIME_EST_DEFAULT_IDX,
    .cputime_ewma_log = AVM_PA_CPUTIME_EST_DEFAULT_EWMA_LOG,
-   .prioack_packet_size = AVM_PA_PRIOACK_PACKET_SIZE,
    .prioack_thresh_packets = AVM_PA_PRIOACK_THRESH_PKTS,
    .prioack_ratio = AVM_PA_PRIOACK_RATIO,
 };
@@ -1919,9 +1931,25 @@
    struct avm_pa_pkt_info *info = AVM_PKT_INFO(pkt);
 
    if (egress->not_local) {
-      if (pid->prioack_enabled && info->match.ack_only) {
-         egress->tcpack_pkts++;
-         pkt->priority =  pid->prioack_priority;
+      if (pid->prioack_enabled) {
+         if (info->match.ack_only) {
+            egress->tcpack_pkts++;
+            pkt->priority =  pid->prioack_priority;
+#if AVM_PA_TRACE
+            if (ctx->dbgprioacktrace)
+                pa_printk(KERN_DEBUG, "avm_pa: %lu - _pa_transmit(%s), reset tcpack prio to 0x%X\n",
+                          pkt->uniq_id & 0xffffff, pid->cfg.name, pkt->priority);
+#endif
+         } else if (pid->tget_enabled && (info->match.pkttype & AVM_PA_PKTTYPE_PROTO_MASK) == IPPROTO_TCP && egress->tx_pkts < ctx->prioack_thresh_packets) {
+            pkt->priority =  pid->tget_priority;
+#if AVM_PA_TRACE
+            if (ctx->dbgprioack)
+                pa_printk(KERN_DEBUG, "avm_pa: %lu - _pa_transmit(%s), reset tget prio to 0x%X\n",
+                          pkt->uniq_id & 0xffffff, pid->cfg.name, pkt->priority);
+#endif
+         } else {
+            pkt->priority = egress->output.priority;
+         }
       } else  {
          pkt->priority = egress->output.priority;
       }
@@ -1966,8 +1994,8 @@
       skb_set_network_header(pkt, egress->push_l2_len);
 #if AVM_PA_TRACE
       if (ctx->dbgtrace)
-         pa_printk(KERN_DEBUG, "avm_pa: %lu - _pa_transmit(%s)\n",
-                               pkt->uniq_id & 0xffffff, pid->cfg.name);
+         pa_printk(KERN_DEBUG, "avm_pa: %lu - _pa_transmit(%s), prio=0x%X, info->match.ack_only=%d\n",
+                               pkt->uniq_id & 0xffffff, pid->cfg.name, pkt->priority, info->match.ack_only);
 #endif
       (*pid->cfg.tx_func)(pid->cfg.tx_arg, pkt);
    } else {
@@ -2387,6 +2415,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 +2423,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 +2624,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;
 }
@@ -2917,6 +2950,12 @@
          if (pid->prioack_enabled) {
             /*--- prompt = "ack prio pkts"; ---*/
             snprintf(buf, sizeof(buf), "%u (accl acks %u)", pid->prioack_acks, pid->prioack_accl_acks);
+            (*fprintffunc)(arg, "%-10s: %s\n", prompt, buf);
+         }
+         if (pid->tget_enabled) {
+            /*--- prompt = "ack prio pkts"; ---*/
+            snprintf(buf, sizeof(buf), "%u (accl %u)", pid->tgets, pid->tget_accl);
+            (*fprintffunc)(arg, "%-10s: %s\n", prompt, buf);
          }
       } else {
          prompt = "Dest";
@@ -3609,8 +3648,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;
@@ -3918,10 +3959,12 @@
    struct avm_pa_vpid *evpid;
    struct ethhdr *ethh;
    unsigned int orig_packet_prio;
+   unsigned int set_tget_prio;
    unsigned negress;
    int headroom;
    char buf[64];
    u32 hash; /* not used uninitialized */
+   int do_tget = 0;
 
 #if AVM_PA_TRACE
    if (ctx->dbgtrace) {
@@ -3940,25 +3983,33 @@
    
    if (!sk) {
       if (epid->prioack_enabled) {
+         int is_tcp = ((info->match.pkttype & AVM_PA_PKTTYPE_PROTO_MASK) == IPPROTO_TCP) ? 1 : 0;
          if (ctx->dbgprioacktrace) {
-            printk(KERN_DEBUG "avm_pa_pid_snoop_transmit: info->match.syn=%d, info->match.ack_only=%d, PKT_LEN(pkt)=%d, pkt->priority=%x\n", 
-                   info->match.syn, info->match.ack_only, PKT_LEN(pkt), pkt->priority);
+            printk(KERN_DEBUG "avm_pa_pid_snoop_transmit: info->match.syn=%d, info->match.ack_only=%d, is_tcp=%d, pid->tget_enabled=%d, epid->tget_priority=0x%X, PKT_LEN(pkt)=%d, pkt->priority=%x\n", 
+                   info->match.syn, info->match.ack_only, is_tcp, epid->tget_enabled, epid->tget_priority, PKT_LEN(pkt), pkt->priority);
          }
          if (info->match.syn || info->match.fin || info->match.ack_only) {
-            epid->prioack_acks++;
             /* change TCP-Ack priority */
+            epid->prioack_acks++;
             if (pkt->priority > epid->prioack_priority) {
                pkt->priority = epid->prioack_priority;
                epid->prioack_accl_acks++;
                if (ctx->dbgprioacktrace) {
-                  printk(KERN_DEBUG "avm_pa_pid_snoop_transmit: reset priority to=%x\n", pkt->priority);
+                  printk(KERN_DEBUG "avm_pa_pid_snoop_transmit: reset tcpack priority to=%x\n", pkt->priority);
                }
             } 
+         } else if (is_tcp && epid->tget_enabled) {
+            /* change TCP-GET priority */
+            //epid->tgets ++;
+            if (info->can_be_accelerated && pkt->priority > epid->tget_priority) {
+               set_tget_prio = epid->tget_priority;
+               do_tget = 1;
+            } 
          }
       }
    }
    if (ctx->dbgprioacktrace && epid->prioack_enabled) 
-        printk(KERN_DEBUG "avm_pa_pid_snoop_transmit: priority=%x\n", pkt->priority);
+        printk(KERN_DEBUG "avm_pa_pid_snoop_transmit: priority=%x, epid->tget_enabled=%d, info->can_be_accelerated=%d\n", pkt->priority, epid->tget_enabled, info->can_be_accelerated);
 
    if (!info->can_be_accelerated) {
       ctx->stats.tx_bypass++;
@@ -4025,6 +4076,23 @@
             return AVM_PA_TX_ERROR_SESSION;
          }
       }
+
+      if (do_tget) {
+         if (ctx->dbgprioack) {
+            printk(KERN_DEBUG "avm_pa_pid_snoop_transmit: info->match.syn=%d, info->match.ack_only=%d, pid->tget_enabled=%d, PKT_LEN(pkt)=%d, pkt->priority=%x\n", 
+                   info->match.syn, info->match.ack_only, epid->tget_enabled, PKT_LEN(pkt), pkt->priority);
+         }
+         /* change TCP-GET priority */
+         epid->tgets ++;
+         if (pkt->priority > set_tget_prio) {
+            pkt->priority = set_tget_prio;
+            //epid->tget_accl++;
+            if (ctx->dbgprioack) {
+               printk(KERN_DEBUG "avm_pa_pid_snoop_transmit: reset tget priority to=%x\n", pkt->priority);
+            }
+         } 
+      }
+      
       /* Session State: CREATE */
       session->ingress_pid_handle = info->ingress_pid_handle;
       session->ingress_vpid_handle = info->ingress_vpid_handle;
@@ -4334,6 +4402,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;
@@ -4415,7 +4485,7 @@
                              pid->cfg.name,
                              pidflags2str(pid->ecfg.flags, buf, sizeof(buf)));
          if (pid->prioack_enabled)
-            (*fprintffunc)(arg, " ack prio 0x%x\n", pid->prioack_priority);
+            (*fprintffunc)(arg, " ack prio 0x%x (tget=%d, tget prio 0x%x)\n", pid->prioack_priority, pid->tget_enabled, pid->tget_priority);
          else
             (*fprintffunc)(arg, "\n");
       } else {
@@ -4430,7 +4500,7 @@
                              PA_PID(ctx, pid->ingress_pid_handle)->cfg.name,
                              pidflags2str(pid->ecfg.flags, buf, sizeof(buf)));
          if (pid->prioack_enabled)
-            (*fprintffunc)(arg, " ack prio 0x%x\n", pid->prioack_priority);
+            (*fprintffunc)(arg, " ack prio 0x%x (tget=%d, tget prio 0x%x)\n", pid->prioack_priority, pid->tget_enabled, pid->tget_priority);
          else
             (*fprintffunc)(arg, "\n");
       }
@@ -4608,6 +4678,8 @@
    }
    pid->prioack_enabled = enable ? 1 : 0;
    pid->prioack_priority = prio;
+   pid->tget_enabled = pid->prioack_enabled;
+   pid->tget_priority = prio-1;
    return 0;
 }
 EXPORT_SYMBOL(avm_pa_pid_activate_tcpackprio);
@@ -6099,7 +6171,6 @@
   
    seq_printf(seq, "Packet Threshold : %u\n",ctx->prioack_thresh_packets);
    seq_printf(seq, "Ratio            : %u\n",ctx->prioack_ratio);
-   seq_printf(seq, "ACK Size         : %u\n",ctx->prioack_packet_size);
    
    for (n=1; n < CONFIG_AVM_PA_MAX_PID; n++) {
       struct avm_pa_pid *pid = PA_PID(ctx, n);
@@ -6107,6 +6178,10 @@
       seq_printf(seq, "PID%d: ACK Priority     : %x\n",pid->pid_handle, pid->prioack_priority);
       seq_printf(seq, "PID%d: Detected ACKs    : %u\n",pid->pid_handle, pid->prioack_acks);
       seq_printf(seq, "PID%d: Accelerated ACKs : %u\n",pid->pid_handle, pid->prioack_accl_acks);
+      if (!pid->tget_enabled) continue;
+      seq_printf(seq, "PID%d: TGET Priority    : %x\n",pid->pid_handle, pid->tget_priority);
+      seq_printf(seq, "PID%d: Detected GETs    : %u\n",pid->pid_handle, pid->tgets);
+      seq_printf(seq, "PID%d: Accelerated GETs : %u\n",pid->pid_handle, pid->tget_accl);
    }
 
    return 0;
@@ -6551,6 +6626,8 @@
                   struct avm_pa_pid *pid = PA_PID(ctx, AVM_PA_DEVINFO(dev)->pid_handle);
                   pid->prioack_enabled = 1;
                   pid->prioack_priority = simple_strtoul(argv[3], 0, 10);
+                  pid->tget_enabled = 1;
+                  pid->tget_priority = pid->prioack_priority-1;
                   dev_put(dev);
                }
             }
@@ -6561,12 +6638,47 @@
                   struct avm_pa_pid *pid = PA_PID(ctx, AVM_PA_DEVINFO(dev)->pid_handle);
                   pid->prioack_enabled = 0;
                   pid->prioack_priority = 0;
+                  pid->tget_enabled = 0;
+                  pid->tget_priority = 0;
                   dev_put(dev);
                }
+            } else {
+               int n;
+               for (n=1; n < CONFIG_AVM_PA_MAX_PID; n++) {
+                  struct avm_pa_pid *pid = PA_PID(ctx, n);
+                  pid->prioack_enabled = 0;
+                  pid->prioack_priority = 0;
+                  pid->tget_enabled = 0;
+                  pid->tget_priority = 0;
+               }
+            }
+         } else if (strcmp(argv[1], "tgetenable") == 0) {
+            if (argv[2] && argv[3]) {
+               struct net_device *dev = dev_get_by_name(&init_net, argv[2]);
+               if (dev) {
+                  struct avm_pa_pid *pid = PA_PID(ctx, AVM_PA_DEVINFO(dev)->pid_handle);
+                  pid->tget_enabled = 1;
+                  pid->tget_priority = simple_strtoul(argv[3], 0, 10);
+                  dev_put(dev);
+               }
+            }
+         } else if (strcmp(argv[1], "tgetdisable") == 0) {
+            if (argv[2]) {
+               struct net_device *dev = dev_get_by_name(&init_net, argv[2]);
+               if (dev) {
+                  struct avm_pa_pid *pid = PA_PID(ctx, AVM_PA_DEVINFO(dev)->pid_handle);
+                  pid->tget_enabled = 0;
+                  pid->tget_priority = 0;
+                  dev_put(dev);
+               }
+            } else {
+               int n;
+               for (n=1; n < CONFIG_AVM_PA_MAX_PID; n++) {
+                  struct avm_pa_pid *pid = PA_PID(ctx, n);
+                  pid->tget_enabled = 0;
+                  pid->tget_priority = 0;
+               }
             }
-         } else if (strcmp(argv[1], "psize") == 0) {
-            if (argv[2]) val = simple_strtoul(argv[2], 0, 10);
-            if (val) ctx->prioack_packet_size = val;
          } else if (strcmp(argv[1], "pthresh") == 0) {
             if (argv[2]) val = simple_strtoul(argv[2], 0, 10);
             if (val) ctx->prioack_thresh_packets = val;
--- 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)
+{
+
+   struct sk_buff *skb;
+   apNewBridgeEntry_t *ap_bridge_entry;
+
+   AVM_PA_FUSIV_TRC("call handle_fp_bridge_pkt\n");
 
-void handle_fp_bridge_pkt(apPreHeader_t *apBuf, struct net_device *dev) {
+   ap_bridge_entry = (apNewBridgeEntry_t *)(apBuf->matchedEntryAddr);
+
+   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)
+{
+
+   struct sk_buff *skb;
+   apFlowEntry_t *flow;
+
+   AVM_PA_FUSIV_TRC("call handle_fp_route_pkt\n");
+
+   flow = (apFlowEntry_t *)(apBuf->matchedEntryAddr);
+
+   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);
+   }
 
-	struct sk_buff *skb;
-    apNewBridgeEntry_t *ap_bridge_entry;
-	
-	AVM_PA_FUSIV_TRC("call handle_fp_bridge_pkt\n");
-
-	ap_bridge_entry = (apNewBridgeEntry_t *)(PHYS_TO_K1(apBuf->matchedEntryAddr));
-
-	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 (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);
-		   
-	   }
-	}
-}
-
-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");
-
-	flow = (apFlowEntry_t *)(PHYS_TO_K1(apBuf->matchedEntryAddr));
-
-	if (flow && flow->userHandle) {
-	   struct avm_pa_fusiv_session *fusiv_session = 
-		  (struct avm_pa_fusiv_session *) (flow->userHandle);
-
-	   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 && 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;
+
+   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;
+
+   /* == 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
+
+   memset(&bridgeEntry, 0, sizeof(bridgeEntry));
+
+   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);
+
+   rc = apAddBridgeEntry(1, hash, &bridgeEntry, &newBridgeEntry);
+
+   if (rc != 0) {
+      AVM_PA_FUSIV_DBG("apAddBridgeEntry returned %d\n", rc);
+      return res;
+   }
 
-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 );
-
-	memset(&bridgeEntry, 0, sizeof (bridgeEntry));
-
-	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);
-
-	rc = apAddBridgeEntry(1, hash, &bridgeEntry, &newBridgeEntry);
-
-	if (rc != 0) {
-	   AVM_PA_FUSIV_DBG("apAddBridgeEntry returned %d\n", rc);
-	   return res;
-	}
-
-	AVM_PA_FUSIV_DBG("apAddBridgeEntry successful hash %u\n", hash);
-
-	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;
-
-	// 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;
+   AVM_PA_FUSIV_DBG("apAddBridgeEntry successful hash %u\n", hash);
+
+   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];
+
+   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);
+
+   if (ingress_hw == 0 || egress_hw == 0)
+      return res;
+
+   proto = avm_session->ingress.pkttype & AVM_PA_PKTTYPE_PROTO_MASK;
 
-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 );
-
-	proto = avm_session->ingress.pkttype & AVM_PA_PKTTYPE_PROTO_MASK;
-
-	memset(&flow, 0, sizeof(flow));
-	flow.entryType = AP_TCP_UDP_ENTRY;
-
-	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;
-	   }
-	}
-
-	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;
-	   }
-	}
-
-	/* 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);
-	}
-
-#if 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) {
-	   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);
-	}
-
-	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);
+   memset(&flow, 0, sizeof(flow));
+#ifdef CONFIG_FUSIV_VX180
+   flow.entryType = AP_TCP_UDP_ENTRY;
+#endif
+
+   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.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;
+      }
+   }
+
+   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;
+#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;
+      }
+   }
+
+   /*
+    * 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.userHandle = (unsigned int)&fusiv_session_array[ avm_session->session_handle ];
-	flow.operations |= (0x1 << AP_ROUTE_VALID_BIT);
-
-	flowhash = apCalculateHash(ingress_hw->apId, &flow);
-
-	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;
-	}
-
-	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;
-
-    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);
-
-	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];
-
-	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 );
-
-	proto = avm_session->ingress.pkttype & AVM_PA_PKTTYPE_PROTO_MASK;
-
-	memset(&flow, 0, sizeof(flow));
-
-	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;
-	}
-
-	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;
-	   }
-	}
-
-	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;
-	   }
-	}
-
-	/* 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);
-	}
-
-#if CONFIG_FUSIV_KERNEL_APSTATISTICS_PER_INTERFACE
-	memset(&flow.apStatistics, 0, sizeof(apStatistics_t));
-    memset(&new_session.prevStat, 0, sizeof(apStatistics_t));
-#endif
-
-	priority = avm_session->egress[0].output.priority;
-	priority = (priority & TC_H_MIN_MASK);
-	if (priority > 7) priority = 7;
-
-	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);
-
-	flowhash = apIpv6CalculateHash(ingress_hw->apId, &flow);
-
-	rc = apIpv6AddFlowEntry(ingress_hw->apId, flowhash, &flow, &newflow);
-
-	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;
-
-    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);
-
-	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;
-
-    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;
-	}
-
-	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 ((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);
-
-	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;
+      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);
+
+   flowhash = apCalculateHash(ingress_hw->apId, &flow);
+
+   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;
+   }
+
+   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;
+
+#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);
+
+   // 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);
+
+   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];
+
+   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);
+
+   if (ingress_hw == 0 || egress_hw == 0)
+      return res;
+
+   if (ingress_hw->apId == PERI_ID || egress_hw->apId == PERI_ID)
+      return res;
+
+   proto = avm_session->ingress.pkttype & AVM_PA_PKTTYPE_PROTO_MASK;
+
+   memset(&flow, 0, sizeof(flow));
+
+#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
+
+   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;
+      }
+   }
+
+   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;
+
+#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;
+      }
+   }
+
+   /*
+    * 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
+
+   priority = avm_session->egress[0].output.priority;
+   priority = (priority & TC_H_MIN_MASK);
+   if (priority > 7)
+      priority = 7;
+
+   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);
+
+   flowhash = apIpv6CalculateHash(ingress_hw->apId, &flow);
+
+   rc = apIpv6AddFlowEntry(ingress_hw->apId, flowhash, &flow, &newflow);
+
+   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;
+
+   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;
+   }
+
+   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 ((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);
+
+   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);
+#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);
-
-    // 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;
+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);
+
+   // 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);
+         apNewBridgeEntry_t *flowp = session_to_remove.bridgeFlow;
+
+         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 {
-        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
+            ("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;
-
-	  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->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");
+      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 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) {
+#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
 };
 
