initial merge of infineon code for amazon, pci is still broken a bit. a big thank...
authorJohn Crispin <john@openwrt.org>
Mon, 23 Jul 2007 22:10:11 +0000 (22:10 +0000)
committerJohn Crispin <john@openwrt.org>
Mon, 23 Jul 2007 22:10:11 +0000 (22:10 +0000)
SVN-Revision: 8137

47 files changed:
target/linux/amazon-2.6/Makefile [new file with mode: 0644]
target/linux/amazon-2.6/base-files/default/etc/config/network [new file with mode: 0644]
target/linux/amazon-2.6/config/default [new file with mode: 0644]
target/linux/amazon-2.6/files/arch/mips/amazon/Kconfig [new file with mode: 0644]
target/linux/amazon-2.6/files/arch/mips/amazon/Makefile [new file with mode: 0644]
target/linux/amazon-2.6/files/arch/mips/amazon/dma-core.c [new file with mode: 0644]
target/linux/amazon-2.6/files/arch/mips/amazon/dma-core.h [new file with mode: 0644]
target/linux/amazon-2.6/files/arch/mips/amazon/interrupt.c [new file with mode: 0644]
target/linux/amazon-2.6/files/arch/mips/amazon/pci.c [new file with mode: 0644]
target/linux/amazon-2.6/files/arch/mips/amazon/prom.c [new file with mode: 0644]
target/linux/amazon-2.6/files/arch/mips/amazon/setup.c [new file with mode: 0644]
target/linux/amazon-2.6/files/drivers/atm/amazon_tpe.c [new file with mode: 0644]
target/linux/amazon-2.6/files/drivers/char/admmod.c [new file with mode: 0644]
target/linux/amazon-2.6/files/drivers/char/amazon_mei.c [new file with mode: 0644]
target/linux/amazon-2.6/files/drivers/char/amazon_wdt.c [new file with mode: 0644]
target/linux/amazon-2.6/files/drivers/char/ifx_ssc.c [new file with mode: 0644]
target/linux/amazon-2.6/files/drivers/mtd/maps/amazon.c [new file with mode: 0644]
target/linux/amazon-2.6/files/drivers/net/amazon_sw.c [new file with mode: 0644]
target/linux/amazon-2.6/files/drivers/serial/amazon_asc.c [new file with mode: 0644]
target/linux/amazon-2.6/files/include/asm-mips/amazon/adm6996.h [new file with mode: 0644]
target/linux/amazon-2.6/files/include/asm-mips/amazon/amazon.h [new file with mode: 0644]
target/linux/amazon-2.6/files/include/asm-mips/amazon/amazon_dma.h [new file with mode: 0644]
target/linux/amazon-2.6/files/include/asm-mips/amazon/amazon_mei.h [new file with mode: 0644]
target/linux/amazon-2.6/files/include/asm-mips/amazon/amazon_mei_app.h [new file with mode: 0644]
target/linux/amazon-2.6/files/include/asm-mips/amazon/amazon_mei_app_ioctl.h [new file with mode: 0644]
target/linux/amazon-2.6/files/include/asm-mips/amazon/amazon_mei_ioctl.h [new file with mode: 0644]
target/linux/amazon-2.6/files/include/asm-mips/amazon/amazon_sw.h [new file with mode: 0644]
target/linux/amazon-2.6/files/include/asm-mips/amazon/amazon_tpe.h [new file with mode: 0644]
target/linux/amazon-2.6/files/include/asm-mips/amazon/amazon_wdt.h [new file with mode: 0644]
target/linux/amazon-2.6/files/include/asm-mips/amazon/atm_defines.h [new file with mode: 0644]
target/linux/amazon-2.6/files/include/asm-mips/amazon/atm_mib.h [new file with mode: 0644]
target/linux/amazon-2.6/files/include/asm-mips/amazon/ifx_peripheral_definitions.h [new file with mode: 0644]
target/linux/amazon-2.6/files/include/asm-mips/amazon/ifx_ssc.h [new file with mode: 0644]
target/linux/amazon-2.6/files/include/asm-mips/amazon/ifx_ssc_defines.h [new file with mode: 0644]
target/linux/amazon-2.6/files/include/asm-mips/amazon/irq.h [new file with mode: 0644]
target/linux/amazon-2.6/files/include/asm-mips/amazon/model.h [new file with mode: 0644]
target/linux/amazon-2.6/files/include/asm-mips/amazon/port.h [new file with mode: 0644]
target/linux/amazon-2.6/files/include/asm-mips/amazon/serial.h [new file with mode: 0644]
target/linux/amazon-2.6/files/include/asm-mips/mach-amazon/irq.h [new file with mode: 0644]
target/linux/amazon-2.6/files/include/asm-mips/mach-amazon/mangle-port.h [new file with mode: 0644]
target/linux/amazon-2.6/image/Makefile [new file with mode: 0644]
target/linux/amazon-2.6/patches/100-board.patch [new file with mode: 0644]
target/linux/amazon-2.6/patches/110-char_drivers.patch [new file with mode: 0644]
target/linux/amazon-2.6/patches/130-mtd_drivers.patch [new file with mode: 0644]
target/linux/amazon-2.6/patches/140-net_drivers.patch [new file with mode: 0644]
target/linux/amazon-2.6/patches/150-serial_driver.patch [new file with mode: 0644]
target/linux/amazon-2.6/patches/160-cfi-swap.patch [new file with mode: 0644]

diff --git a/target/linux/amazon-2.6/Makefile b/target/linux/amazon-2.6/Makefile
new file mode 100644 (file)
index 0000000..1967d52
--- /dev/null
@@ -0,0 +1,25 @@
+# 
+# Copyright (C) 2006 OpenWrt.org
+#
+# This is free software, licensed under the GNU General Public License v2.
+# See /LICENSE for more information.
+#
+include $(TOPDIR)/rules.mk
+
+ARCH:=mips
+BOARD:=amazon
+BOARDNAME:=Infineon Amazon
+FEATURES:=squashfs jffs2 broken
+
+define Target/Description
+       Build firmware images for Infineon Amazon boards
+endef
+
+KERNELNAME:="uImage"
+
+include $(INCLUDE_DIR)/kernel-build.mk
+
+# include the profiles
+-include profiles/*.mk
+
+$(eval $(call BuildKernel))
diff --git a/target/linux/amazon-2.6/base-files/default/etc/config/network b/target/linux/amazon-2.6/base-files/default/etc/config/network
new file mode 100644 (file)
index 0000000..72e39f8
--- /dev/null
@@ -0,0 +1,14 @@
+# Copyright (C) 2006 OpenWrt.org
+
+config interface loopback
+       option ifname   lo
+       option proto    static
+       option ipaddr   127.0.0.1
+       option netmask  255.0.0.0
+
+config interface lan
+       option ifname   eth1
+       option type     bridge
+       option proto    static
+       option ipaddr   192.168.1.1
+       option netmask  255.255.255.0
diff --git a/target/linux/amazon-2.6/config/default b/target/linux/amazon-2.6/config/default
new file mode 100644 (file)
index 0000000..2229e63
--- /dev/null
@@ -0,0 +1,211 @@
+CONFIG_32BIT=y
+# CONFIG_64BIT is not set
+# CONFIG_64BIT_PHYS_ADDR is not set
+CONFIG_AMAZON=y
+CONFIG_AMAZON_ASC_UART=y
+CONFIG_AMAZON_MTD=y
+CONFIG_AMAZON_NET_SW=y
+CONFIG_AMAZON_PCI=y
+CONFIG_AMAZON_WDT=y
+# CONFIG_ARCH_HAS_ILOG2_U32 is not set
+# CONFIG_ARCH_HAS_ILOG2_U64 is not set
+# CONFIG_ATM is not set
+# CONFIG_ATMEL is not set
+CONFIG_BASE_SMALL=0
+# CONFIG_BCM43XX is not set
+CONFIG_BITREVERSE=y
+# CONFIG_BT is not set
+CONFIG_CMDLINE="console=ttyS0,115200 rootfstype=squashfs,jffs2 init=/bin/sh"
+CONFIG_CPU_BIG_ENDIAN=y
+CONFIG_CPU_HAS_LLSC=y
+CONFIG_CPU_HAS_PREFETCH=y
+CONFIG_CPU_HAS_SYNC=y
+# CONFIG_CPU_LITTLE_ENDIAN is not set
+CONFIG_CPU_MIPS32=y
+CONFIG_CPU_MIPS32_R1=y
+# CONFIG_CPU_MIPS32_R2 is not set
+# CONFIG_CPU_MIPS64_R1 is not set
+# CONFIG_CPU_MIPS64_R2 is not set
+CONFIG_CPU_MIPSR1=y
+# CONFIG_CPU_NEVADA is not set
+# CONFIG_CPU_R10000 is not set
+# CONFIG_CPU_R3000 is not set
+# CONFIG_CPU_R4300 is not set
+# CONFIG_CPU_R4X00 is not set
+# CONFIG_CPU_R5000 is not set
+# CONFIG_CPU_R5432 is not set
+# CONFIG_CPU_R6000 is not set
+# CONFIG_CPU_R8000 is not set
+# CONFIG_CPU_RM7000 is not set
+# CONFIG_CPU_RM9000 is not set
+# CONFIG_CPU_SB1 is not set
+CONFIG_CPU_SUPPORTS_32BIT_KERNEL=y
+CONFIG_CPU_SUPPORTS_HIGHMEM=y
+# CONFIG_CPU_TX39XX is not set
+# CONFIG_CPU_TX49XX is not set
+# CONFIG_CPU_VR41XX is not set
+# CONFIG_DDB5477 is not set
+# CONFIG_DM9000 is not set
+CONFIG_DMA_NEED_PCI_MAP_STATE=y
+CONFIG_DMA_NONCOHERENT=y
+CONFIG_EARLY_PRINTK=y
+CONFIG_FS_POSIX_ACL=y
+CONFIG_GENERIC_FIND_NEXT_BIT=y
+# CONFIG_GENERIC_GPIO is not set
+# CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ is not set
+# CONFIG_GEN_RTC is not set
+CONFIG_HAS_IOMEM=y
+CONFIG_HAS_IOPORT=y
+CONFIG_HAVE_STD_PC_SERIAL_PORT=y
+# CONFIG_HERMES is not set
+# CONFIG_HOSTAP is not set
+CONFIG_HW_HAS_PCI=y
+CONFIG_HW_RANDOM=y
+# CONFIG_I2C is not set
+# CONFIG_IDE is not set
+CONFIG_INITRAMFS_SOURCE=""
+# CONFIG_IPW2100 is not set
+# CONFIG_IPW2200 is not set
+CONFIG_IRQ_CPU=y
+CONFIG_JFFS2_FS_DEBUG=0
+CONFIG_KALLSYMS=y
+# CONFIG_KALLSYMS_EXTRA_PASS is not set
+# CONFIG_MACH_DECSTATION is not set
+# CONFIG_MACH_JAZZ is not set
+# CONFIG_MACH_VR41XX is not set
+CONFIG_MIPS=y
+# CONFIG_MIPS_ATLAS is not set
+# CONFIG_MIPS_BOSPORUS is not set
+# CONFIG_MIPS_COBALT is not set
+# CONFIG_MIPS_DB1000 is not set
+# CONFIG_MIPS_DB1100 is not set
+# CONFIG_MIPS_DB1200 is not set
+# CONFIG_MIPS_DB1500 is not set
+# CONFIG_MIPS_DB1550 is not set
+# CONFIG_MIPS_EV64120 is not set
+CONFIG_MIPS_L1_CACHE_SHIFT=5
+# CONFIG_MIPS_MALTA is not set
+# CONFIG_MIPS_MIRAGE is not set
+# CONFIG_MIPS_MTX1 is not set
+CONFIG_MIPS_MT_DISABLED=y
+# CONFIG_MIPS_MT_SMP is not set
+# CONFIG_MIPS_MT_SMTC is not set
+# CONFIG_MIPS_PB1000 is not set
+# CONFIG_MIPS_PB1100 is not set
+# CONFIG_MIPS_PB1200 is not set
+# CONFIG_MIPS_PB1500 is not set
+# CONFIG_MIPS_PB1550 is not set
+# CONFIG_MIPS_SEAD is not set
+# CONFIG_MIPS_SIM is not set
+# CONFIG_MIPS_VPE_LOADER is not set
+# CONFIG_MIPS_XXS1500 is not set
+# CONFIG_MOMENCO_JAGUAR_ATX is not set
+# CONFIG_MOMENCO_OCELOT is not set
+# CONFIG_MOMENCO_OCELOT_3 is not set
+# CONFIG_MOMENCO_OCELOT_C is not set
+# CONFIG_MOMENCO_OCELOT_G is not set
+CONFIG_MTD=y
+# CONFIG_MTD_ABSENT is not set
+CONFIG_MTD_AMAZON_BUS_WIDTH_16=y
+# CONFIG_MTD_AMAZON_BUS_WIDTH_32 is not set
+# CONFIG_MTD_AMAZON_BUS_WIDTH_8 is not set
+# CONFIG_MTD_AMAZON_FLASH_SIZE_16 is not set
+# CONFIG_MTD_AMAZON_FLASH_SIZE_2 is not set
+CONFIG_MTD_AMAZON_FLASH_SIZE_4=y
+# CONFIG_MTD_AMAZON_FLASH_SIZE_8 is not set
+CONFIG_MTD_BLKDEVS=y
+CONFIG_MTD_BLOCK=y
+# CONFIG_MTD_BLOCK2MTD is not set
+CONFIG_MTD_CFI=y
+CONFIG_MTD_CFI_ADV_OPTIONS=y
+CONFIG_MTD_CFI_AMDSTD=y
+# CONFIG_MTD_CFI_BE_BYTE_SWAP is not set
+# CONFIG_MTD_CFI_GEOMETRY is not set
+CONFIG_MTD_CFI_I1=y
+CONFIG_MTD_CFI_I2=y
+# CONFIG_MTD_CFI_I4 is not set
+# CONFIG_MTD_CFI_I8 is not set
+# CONFIG_MTD_CFI_INTELEXT is not set
+# CONFIG_MTD_CFI_LE_BYTE_SWAP is not set
+CONFIG_MTD_CFI_NOSWAP=y
+# CONFIG_MTD_CFI_STAA is not set
+CONFIG_MTD_CFI_UTIL=y
+CONFIG_MTD_CHAR=y
+# CONFIG_MTD_CMDLINE_PARTS is not set
+CONFIG_MTD_COMPLEX_MAPPINGS=y
+# CONFIG_MTD_CONCAT is not set
+# CONFIG_MTD_DEBUG is not set
+# CONFIG_MTD_DOC2000 is not set
+# CONFIG_MTD_DOC2001 is not set
+# CONFIG_MTD_DOC2001PLUS is not set
+CONFIG_MTD_GEN_PROBE=y
+# CONFIG_MTD_JEDECPROBE is not set
+CONFIG_MTD_MAP_BANK_WIDTH_1=y
+# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set
+CONFIG_MTD_MAP_BANK_WIDTH_2=y
+# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set
+CONFIG_MTD_MAP_BANK_WIDTH_4=y
+# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set
+# CONFIG_MTD_MTDRAM is not set
+# CONFIG_MTD_OBSOLETE_CHIPS is not set
+# CONFIG_MTD_ONENAND is not set
+# CONFIG_MTD_OTP is not set
+CONFIG_MTD_PARTITIONS=y
+# CONFIG_MTD_PCI is not set
+# CONFIG_MTD_PHRAM is not set
+CONFIG_MTD_PHYSMAP=y
+CONFIG_MTD_PHYSMAP_BANKWIDTH=0
+CONFIG_MTD_PHYSMAP_LEN=0x0
+CONFIG_MTD_PHYSMAP_START=0x0
+# CONFIG_MTD_PLATRAM is not set
+# CONFIG_MTD_PMC551 is not set
+# CONFIG_MTD_RAM is not set
+CONFIG_MTD_REDBOOT_DIRECTORY_BLOCK=-3
+CONFIG_MTD_REDBOOT_PARTS=y
+CONFIG_MTD_REDBOOT_PARTS_READONLY=y
+# CONFIG_MTD_REDBOOT_PARTS_UNALLOCATED is not set
+# CONFIG_MTD_ROM is not set
+# CONFIG_MTD_SLRAM is not set
+# CONFIG_NET_PCI is not set
+CONFIG_NET_SCH_FIFO=y
+# CONFIG_NET_VENDOR_3COM is not set
+# CONFIG_PAGE_SIZE_16KB is not set
+CONFIG_PAGE_SIZE_4KB=y
+# CONFIG_PAGE_SIZE_64KB is not set
+# CONFIG_PAGE_SIZE_8KB is not set
+# CONFIG_PCIPCWATCHDOG is not set
+# CONFIG_PMC_YOSEMITE is not set
+# CONFIG_PNPACPI is not set
+# CONFIG_PNX8550_JBS is not set
+# CONFIG_PNX8550_STB810 is not set
+# CONFIG_PRISM54 is not set
+# CONFIG_RTC is not set
+CONFIG_RWSEM_GENERIC_SPINLOCK=y
+CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER=y
+# CONFIG_SERIAL_8250 is not set
+# CONFIG_SGI_IP22 is not set
+# CONFIG_SGI_IP27 is not set
+# CONFIG_SGI_IP32 is not set
+# CONFIG_SIBYTE_BIGSUR is not set
+# CONFIG_SIBYTE_CARMEL is not set
+# CONFIG_SIBYTE_CRHINE is not set
+# CONFIG_SIBYTE_CRHONE is not set
+# CONFIG_SIBYTE_LITTLESUR is not set
+# CONFIG_SIBYTE_PTSWARM is not set
+# CONFIG_SIBYTE_RHONE is not set
+# CONFIG_SIBYTE_SENTOSA is not set
+# CONFIG_SIBYTE_SWARM is not set
+# CONFIG_SOFT_WATCHDOG is not set
+# CONFIG_SPARSEMEM_STATIC is not set
+CONFIG_SYSVIPC_SYSCTL=y
+CONFIG_SYS_HAS_CPU_MIPS32_R1=y
+CONFIG_SYS_HAS_EARLY_PRINTK=y
+CONFIG_SYS_SUPPORTS_32BIT_KERNEL=y
+CONFIG_SYS_SUPPORTS_ARBIT_HZ=y
+CONFIG_SYS_SUPPORTS_BIG_ENDIAN=y
+# CONFIG_TOSHIBA_JMR3927 is not set
+# CONFIG_TOSHIBA_RBTX4927 is not set
+# CONFIG_TOSHIBA_RBTX4938 is not set
+CONFIG_TRAD_SIGNALS=y
+# CONFIG_UNUSED_SYMBOLS is not set
+# CONFIG_USB is not set
diff --git a/target/linux/amazon-2.6/files/arch/mips/amazon/Kconfig b/target/linux/amazon-2.6/files/arch/mips/amazon/Kconfig
new file mode 100644 (file)
index 0000000..179e35e
--- /dev/null
@@ -0,0 +1,63 @@
+# copyright 2007 john crispin <blogic@openwrt.org>
+
+menu "Amazon built-in"
+
+config AMAZON_ASC_UART
+       bool "Amazon asc uart"
+       select SERIAL_CORE
+       select SERIAL_CORE_CONSOLE
+       default y
+
+config AMAZON_PCI
+       bool "Amazon PCI support"
+       default y
+       select HW_HAS_PCI
+       select PCI
+
+config AMAZON_NET_SW
+       bool "Amazon network"
+       default y
+
+config AMAZON_WDT
+       bool "Amazon watchdog timer"
+       default y
+
+config AMAZON_MTD
+       bool "Amazon MTD map"
+       default y
+
+choice 
+       prompt "Flash Size"
+       depends on AMAZON_MTD
+
+config MTD_AMAZON_FLASH_SIZE_2
+       bool "2MB"
+
+config MTD_AMAZON_FLASH_SIZE_4
+       bool "4MB"
+
+config MTD_AMAZON_FLASH_SIZE_8
+       bool "8MB"
+
+config MTD_AMAZON_FLASH_SIZE_16
+       bool "16MB"
+
+endchoice
+
+choice 
+       prompt "Bus Width"
+       depends on AMAZON_MTD
+
+config MTD_AMAZON_BUS_WIDTH_8
+       bool "8-bit"
+
+config MTD_AMAZON_BUS_WIDTH_16
+       bool "16-bit"
+
+config MTD_AMAZON_BUS_WIDTH_32
+       bool "32-bit"
+
+endchoice
+
+
+endmenu
diff --git a/target/linux/amazon-2.6/files/arch/mips/amazon/Makefile b/target/linux/amazon-2.6/files/arch/mips/amazon/Makefile
new file mode 100644 (file)
index 0000000..9cdc100
--- /dev/null
@@ -0,0 +1,9 @@
+#
+#  Copyright 2007 openwrt.org
+#       John Crispin <blogic@openwrt.org>
+#
+# Makefile for Infineon Amazon
+#
+obj-y := dma-core.o interrupt.o prom.o setup.o
+obj-$(CONFIG_PCI) += pci.o
+
diff --git a/target/linux/amazon-2.6/files/arch/mips/amazon/dma-core.c b/target/linux/amazon-2.6/files/arch/mips/amazon/dma-core.c
new file mode 100644 (file)
index 0000000..242bc77
--- /dev/null
@@ -0,0 +1,1455 @@
+/*
+ *   This program is free software; you can redistribute it and/or modify
+ *   it under the terms of the GNU General Public License as published by
+ *   the Free Software Foundation; either version 2 of the License, or
+ *   (at your option) any later version.
+ *
+ *   This program is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with this program; if not, write to the Free Software
+ *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
+ */
+//-----------------------------------------------------------------------
+/*
+ * Description:
+ *     Driver for Infineon Amazon DMA
+ */
+//-----------------------------------------------------------------------
+/* Author:     Wu Qi Ming[Qi-Ming.Wu@infineon.com]
+ * Created:    7-April-2004
+ */
+//-----------------------------------------------------------------------
+/* History
+ * Last changed on: 4-May-2004
+ * Last changed by: <peng.liu@infineon.com>
+ * Reason: debug
+ */
+//----------------------------------------------------------------------- 
+/* Last changed on: 03-Dec-2004
+ * Last changed by: peng.liu@infineon.com
+ * Reason: recover from TPE bug 
+ */
+
+//000004:fchang 2005/6/2 Modified by Linpeng as described below
+//----------------------------------------------------------------------- 
+/* Last changed on: 28-Jan-2004
+ * Last changed by: peng.liu@infineon.com
+ * Reason: 
+ * - handle "out of memory" bug
+ */
+//000003:tc.chen 2005/06/16 fix memory leak when Tx buffer full (heaving traffic).
+//507261:tc.chen 2005/07/26 re-organize code address map to improve performance.
+
+#if defined(CONFIG_MODVERSIONS) && !defined(MODVERSIONS)
+#define MODVERSIONS
+#endif
+
+#if defined(MODVERSIONS) && !defined(__GENKSYMS__)
+#include <linux/modversions.h>
+#endif
+
+#ifndef EXPORT_SYMTAB
+#define EXPORT_SYMTAB                  /* need this one 'cause we export symbols */
+#endif
+
+#undef DMA_NO_POLLING
+
+/* no TX interrupt handling */
+#define NO_TX_INT
+/* need for DMA workaround */
+#undef AMAZON_DMA_TPE_AAL5_RECOVERY
+
+#ifdef AMAZON_DMA_TPE_AAL5_RECOVERY
+#define MAX_SYNC_FAILS 1000000 // 000004:fchang
+unsigned int dma_sync_fails = 0;
+unsigned int total_dma_tpe_reset = 0;
+int (*tpe_reset) (void);
+int (*tpe_start) (void);
+int (*tpe_inject) (void);
+#endif                                                 // AMAZON_DMA_TPE_AAL5_RECOVERY
+
+
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/sched.h>
+#include <linux/kernel.h>
+#include <linux/slab.h>
+#include <linux/string.h>
+#include <linux/timer.h>
+#include <linux/fs.h>
+#include <linux/errno.h>
+#include <linux/proc_fs.h>
+#include <linux/stat.h>
+#include <linux/mm.h>
+#include <linux/tty.h>
+#include <linux/selection.h>
+#include <linux/kmod.h>
+#include <linux/vmalloc.h>
+#include <linux/interrupt.h>
+#include <linux/delay.h>
+#include <asm/uaccess.h>
+#include <linux/errno.h>
+#include <asm/io.h>
+
+#include <asm/amazon/amazon.h>
+#include <asm/amazon/irq.h>
+#include <asm/amazon/amazon_dma.h>
+#include "dma-core.h"
+
+#define AMAZON_DMA_EMSG(fmt, args...) printk( KERN_ERR  "%s: " fmt,__FUNCTION__, ## args)
+
+static irqreturn_t dma_interrupt(int irq, void *dev_id);
+extern void mask_and_ack_amazon_irq(unsigned int irq_nr);
+
+/***************************************** global data *******************************************/
+u64 *g_desc_list;
+dev_list *g_current_dev = NULL;
+dev_list *g_head_dev = NULL;
+dev_list *g_tail_dev = NULL;
+channel_info g_log_chan[CHAN_TOTAL_NUM + 1];
+struct proc_dir_entry *g_amazon_dma_dir;
+static u8 rx_chan_list_len = 0;
+static u8 tx_chan_list_len = 0;
+static int rx_chan_list[RX_CHAN_NUM + 1];
+static int tx_chan_list[TX_CHAN_NUM + 1];
+static u32 comb_isr_mask[CHAN_TOTAL_NUM];
+
+static inline int is_rx_chan(int chan_no)
+/*judge if this is an rx channel*/
+{
+       int result = 0;
+       if (chan_no < RX_CHAN_NUM)
+               result = 1;
+       return result;
+}
+
+/* Ugly, Channel ON register is badly mapped to channel no. */
+static u8 ch_on_mapping[CHAN_TOTAL_NUM] =
+       { 0, 1, 2, 3, 6, 7, 10, 4, 5, 8, 9, 11 };
+
+/* Brief:      check wether the chan_no is legal
+ * Parameter:          chan_no: logical channel number
+ * Return:     0 if is not valid
+ *             1 if is valid
+ */
+static inline int is_valid_dma_ch(int chan_no)
+{
+       return ((chan_no >= 0) && (chan_no < CHAN_TOTAL_NUM));
+}
+
+/* Brief:      check whether a channel is open through Channel ON register
+ * Parameter:  chan_no: logical channel number
+ * Return:     1 channel is open
+ *             0 not yet
+ *             EINVAL: invalid parameter
+ */
+static inline int is_channel_open(int chan_no)
+{
+       return (AMAZON_DMA_REG32(AMAZON_DMA_CH_ON) &
+                       (1 << ch_on_mapping[chan_no]));
+}
+
+/* Brief: add a list entry
+ * Description: 
+ *     always add to the tail and no redundancy allowed. (i.e. entries are unique)
+ *     0       : entry deleted
+ *     <0      : not deleted (due to not unique)
+ */
+static inline int _add_list_entry(int *list, int size_of_list, int entry)
+{
+       int i;
+       for (i = 0; i < size_of_list; i++) {
+               if (list[i] == entry)
+                       break;
+               if (list[i] < 0) {
+                       list[i] = entry;
+                       return 0;
+               }
+       }
+       return -1;
+}
+
+/* Brief: delete a list entry
+ * Description:
+ *     find the entry and remove it. shift all entries behind it one step forward if necessary\
+ * Return:
+ *     0       : entry deleted
+ *     <0      : not deleted (due to not found?)
+ */
+static inline int _delete_list_entry(int *list, int size_of_list,
+                                                                        int entry)
+{
+       int i, j;
+       for (i = 0; i < size_of_list; i++) {
+               if (list[i] == entry) {
+                       for (j = i; j < size_of_list; j++) {
+                               list[j] = list[j + 1];
+                               if (list[j + 1] < 0) {
+                                       break;
+                               }
+                       }
+                       return 0;
+               }
+       }
+       return -1;
+}
+
+/* Brief:      enable a channel through Channel ON register
+ * Parameter:  chan_no: logical channel number
+ * Description:        
+ *     Please don't open a channel without a valid descriptor (hardware pitfall)
+ */
+static inline void open_channel(int chan_no)
+{
+       AMAZON_DMA_REG32(AMAZON_DMA_CH_ON) |= (1 << ch_on_mapping[chan_no]);
+       if (is_rx_chan(chan_no)) {
+               if (_add_list_entry(rx_chan_list, RX_CHAN_NUM, chan_no) == 0) {
+                       rx_chan_list_len++;
+               } else {
+                       AMAZON_DMA_DMSG("cannot add chan %d to open list\n", chan_no);
+               }
+       } else {
+               if (_add_list_entry(tx_chan_list, TX_CHAN_NUM, chan_no) == 0) {
+                       tx_chan_list_len++;
+               } else {
+                       AMAZON_DMA_DMSG("cannot add chan %d to open list\n", chan_no);
+               }
+       }
+}
+
+/* Brief:      disable a channel through Channel ON register
+ * Parameter:  chan_no: logical channel number
+ */
+
+static inline void close_channel(int chan_no)
+{
+       AMAZON_DMA_REG32(AMAZON_DMA_CH_ON) &= ~(1 << ch_on_mapping[chan_no]);
+       if (is_rx_chan(chan_no)) {
+               if (_delete_list_entry(rx_chan_list, RX_CHAN_NUM, chan_no) == 0) {
+                       rx_chan_list_len--;
+               } else {
+                       AMAZON_DMA_DMSG("cannot remove chan %d from open list \n",
+                                                       chan_no);
+               }
+       } else {
+               if (_delete_list_entry(tx_chan_list, TX_CHAN_NUM, chan_no) == 0) {
+                       tx_chan_list_len--;
+               } else {
+                       AMAZON_DMA_DMSG("cannot remove chan %d from open list \n",
+                                                       chan_no);
+               }
+       }
+}
+
+/* Brief: clear RX interrupt
+ */
+inline void rx_chan_clear_isr(int chan_no)
+{
+#ifdef DMA_NO_POLLING
+       AMAZON_DMA_REG32(AMAZON_DMA_CH0_ISR + chan_no * AMAZON_DMA_CH_STEP) =
+               (AMAZON_DMA_REG32
+                (AMAZON_DMA_CH0_ISR +
+                 chan_no *
+                 AMAZON_DMA_CH_STEP) & (DMA_ISR_CPT | DMA_ISR_EOP | DMA_ISR_CMDCPT
+                                                                | DMA_ISR_DURR));
+#else
+       AMAZON_DMA_REG32(AMAZON_DMA_CH0_ISR + chan_no * AMAZON_DMA_CH_STEP) =
+               (AMAZON_DMA_REG32
+                (AMAZON_DMA_CH0_ISR +
+                 chan_no *
+                 AMAZON_DMA_CH_STEP) & (DMA_ISR_CPT | DMA_ISR_EOP |
+                                                                DMA_ISR_CMDCPT));
+#endif
+}
+
+
+/* Brief:      hacking function, this will reset all descriptors back to DMA
+ */
+static void dma_reset_all_descriptors(int chan_no)
+{
+       volatile struct rx_desc *rx_desc_p = NULL;
+       int i;
+       rx_desc_p =
+               (struct rx_desc *) g_desc_list +
+               g_log_chan[chan_no].offset_from_base;
+       for (i = 0; i < g_log_chan[chan_no].desc_len; i++) {
+               rx_desc_p->status.word &=
+                       (~(DMA_DESC_SOP_SET | DMA_DESC_EOP_SET | DMA_DESC_CPT_SET));
+               rx_desc_p->status.word |=
+                       (DMA_DESC_OWN_DMA | g_log_chan[chan_no].packet_size);
+               rx_desc_p++;
+       }
+}
+
+#ifdef AMAZON_DMA_TPE_AAL5_RECOVERY
+/* Brief:      Reset DMA descriptors 
+ */
+static void amazon_dma_reset_tpe_rx(int chan_no)
+{
+       struct tx_desc *tx_desc_p = NULL;
+       int j, i = 0;
+
+       // wait until all TX channels stop transmitting
+       for (j = 9; j <= 10; j++) {
+               tx_desc_p =
+                       (struct tx_desc *) g_desc_list +
+                       g_log_chan[j].offset_from_base;
+               for (i = 0; i < g_log_chan[j].desc_len; i++) {
+                       while ((tx_desc_p->status.field.OWN != CPU_OWN)) {
+                               AMAZON_DMA_DMSG("DMA TX in progress\n");        // 000004:fchang
+                               udelay(100);
+                       }
+                       tx_desc_p++;
+               }
+       }
+
+       if (tpe_reset) {
+               total_dma_tpe_reset++;
+               AMAZON_DMA_DMSG
+                       ("\n===============resetting TPE========================== \n");
+               if ((*tpe_reset) ()) {
+                       panic("cannot reset TPE engien\n");     // 000004:fchang
+               }
+       } else {
+               panic("no tpe_reset function\n");       // 000004:fchang
+               return;
+       }
+       dma_reset_all_descriptors(chan_no);
+       rx_chan_clear_isr(chan_no);
+       mb();
+
+       // send EoP
+       if (tpe_inject) {
+               if ((*tpe_inject) ()) {
+                       panic("cannot inject a cell\n");        // 000004:fchang
+               }
+       } else {
+               AMAZON_DMA_EMSG("no tpe_inject function\n");
+               return;
+       }
+       mb();
+       while (1) {
+               if (AMAZON_DMA_REG32
+                       (AMAZON_DMA_CH0_ISR +
+                        chan_no * AMAZON_DMA_CH_STEP) & (DMA_ISR_CPT)) {
+                       rx_chan_clear_isr(chan_no);
+                       mb();
+                       dma_reset_all_descriptors(chan_no);
+                       if (g_log_chan[chan_no].current_desc ==
+                               (g_log_chan[chan_no].desc_len - 1)) {
+                               g_log_chan[chan_no].current_desc = 0;
+                       } else {
+                               g_log_chan[chan_no].current_desc++;
+                       }
+                       break;
+               }
+               mdelay(1);
+       }
+       mb();
+#if 0
+       AMAZON_DMA_REG32(AMAZON_DMA_CH_ON) &= ~(1 << ch_on_mapping[chan_no]);
+       while (AMAZON_DMA_REG32(AMAZON_DMA_CH_ON) &
+                  (1 << ch_on_mapping[chan_no])) {
+               printk("TPE channel still on\n");
+               mdelay(1);
+       }
+
+       // AMAZON_DMA_REG32(AMAZON_DMA_CH_RST) = (1<<chan_no);
+       mb();
+       AMAZON_DMA_REG32(AMAZON_DMA_CH0_MSK + chan_no * AMAZON_DMA_CH_STEP) =
+               0x32;
+       mb();
+       rx_chan_clear_isr(chan_no);
+       dma_reset_all_descriptors(chan_no);
+       mb();
+       AMAZON_DMA_REG32(AMAZON_DMA_CH_ON) |= (1 << ch_on_mapping[chan_no]);
+       // g_log_chan[chan_no].current_desc=0;
+       mb();
+       mdelay(1);
+#endif
+       if (tpe_start) {
+               (*tpe_start) ();
+       } else {
+               AMAZON_DMA_EMSG("cannot restart TPE engien\n");
+       }
+}
+#endif                                                 // AMAZON_DMA_TPE_AAL5_RECOVERY
+
+
+/* Brief:      RX channel interrupt handler 
+ * Parameter:  RX channel no
+ * Description: the interrupt handler for each RX channel
+ *             1. check descriptor, clear ISR if no incoming packet
+ *             2. inform upper layer to receive packet (and update descriptors)
+ */
+inline void rx_chan_intr_handler(int chan_no)
+{
+       volatile struct rx_desc *rx_desc_p = NULL;
+
+       /* fetch the current descriptor */
+       rx_desc_p =
+               (struct rx_desc *) g_desc_list +
+               g_log_chan[chan_no].offset_from_base +
+               g_log_chan[chan_no].current_desc;
+
+       g_log_chan[chan_no].dma_dev->current_rx_chan =
+               chan_no - g_log_chan[chan_no].dma_dev->logic_rx_chan_base;
+
+       // workaround for DMA pitfall: complete bit set happends before the
+       // other two bits (own,eop) are ready
+       if ((rx_desc_p->status.field.EoP != 1)
+               || (rx_desc_p->status.field.OWN != CPU_OWN)
+               || (rx_desc_p->status.field.data_length ==
+                       g_log_chan[chan_no].packet_size)) {
+#ifdef AMAZON_DMA_TPE_AAL5_RECOVERY
+               if (chan_no == 4 || chan_no == 5) {
+                       dma_sync_fails++;
+                       if (dma_sync_fails > MAX_SYNC_FAILS) {
+                               // detect bug
+                               rx_desc_p0 =
+                                       (struct rx_desc *) g_desc_list +
+                                       g_log_chan[chan_no].offset_from_base;
+                               rx_desc_p1 =
+                                       (struct rx_desc *) g_desc_list +
+                                       g_log_chan[chan_no].offset_from_base + 1;
+                               if ((rx_desc_p0->status.field.OWN == CPU_OWN
+                                        && rx_desc_p0->status.field.EoP != 1)
+                                       && (rx_desc_p1->status.field.OWN == CPU_OWN
+                                               && rx_desc_p1->status.field.EoP != 1)) {
+                                       amazon_dma_reset_tpe_rx(chan_no);
+                                       dma_sync_fails = 0;
+                                       return;
+                               }
+                               dma_sync_fails = 0;
+                               AMAZON_DMA_DMSG("too many times ch:%d\n", chan_no);     // 000004:fchang
+                               return;
+                       }
+                       udelay(10);                     // 000004:fchang
+               }
+#endif                                                 // //AMAZON_DMA_TPE_AAL5_RECOVERY
+               return;
+       }
+
+       /* inform the upper layer to receive the packet */
+       g_log_chan[chan_no].intr_handler(g_log_chan[chan_no].dma_dev, RCV_INT);
+       /* check the next descriptor, if still contains the incoming packet,
+          then do not clear the interrupt status */
+       rx_desc_p =
+               (struct rx_desc *) g_desc_list +
+               g_log_chan[chan_no].offset_from_base +
+               g_log_chan[chan_no].current_desc;
+       if (!
+               ((rx_desc_p->status.field.OWN == CPU_OWN)
+                && (rx_desc_p->status.field.C == 1))) {
+               rx_chan_clear_isr(chan_no);
+       }
+}
+
+
+/* Brief:      TX channel interrupt handler 
+ * Parameter:  TX channel no
+ * Description: the interrupt handler for each TX channel
+ * 1. check all the descripters,if any of them had transmitted a packet, then free buffer
+ * because we cannot garantee the which one has already transmitted out, we have to go through all the descriptors here
+ * 2. clear the interrupt status bit
+ */
+inline void tx_chan_intr_handler(int chan_no)
+{
+       struct tx_desc *tx_desc_p = NULL;
+       int i = 0;
+
+       tx_desc_p =
+               (struct tx_desc *) g_desc_list +
+               g_log_chan[chan_no].offset_from_base;
+
+       for (i = 0; i < g_log_chan[chan_no].desc_len; i++) {
+               if ((tx_desc_p->status.field.OWN == CPU_OWN)
+                       && (tx_desc_p->status.field.C == 1)) {
+                       /* if already transmitted, then free the buffer */
+                       g_log_chan[chan_no].
+                               buffer_free((u8 *) __va(tx_desc_p->Data_Pointer),
+                                                       g_log_chan[chan_no].opt[i]);
+                       tx_desc_p->status.field.C = 0;
+                       /* inform the upper layer about the completion of the
+                          transmitted packet, the upper layer may want to free the
+                          packet */
+                       g_log_chan[chan_no].intr_handler(g_log_chan[chan_no].dma_dev,
+                                                                                        TRANSMIT_CPT_INT);
+               }
+               tx_desc_p++;
+       }
+
+       /* after all these operations, clear the interrupt status bit */
+       AMAZON_DMA_REG32(AMAZON_DMA_CH0_ISR + chan_no * AMAZON_DMA_CH_STEP) =
+               (AMAZON_DMA_REG32
+                (AMAZON_DMA_CH0_ISR +
+                 chan_no *
+                 AMAZON_DMA_CH_STEP) & (DMA_ISR_CPT | DMA_ISR_EOP |
+                                                                DMA_ISR_CMDCPT));
+}
+
+/*     Brief:  DMA interrupt handler
+ */
+static irqreturn_t dma_interrupt(int irq, void *dev_id)
+{
+       int i = 0;
+       int chan_no;
+       u32 isr = 0;
+#ifdef NO_TX_INT                               // 000004:fchang
+       static int cnt = 0;                     // 000004:fchang
+#endif                                                 // 000004:fchang
+       while ((isr =
+                       AMAZON_DMA_REG32(AMAZON_DMA_COMB_ISR)) & (COMB_ISR_RX_MASK |
+                                                                                                         COMB_ISR_TX_MASK)) {
+               if (isr & COMB_ISR_RX_MASK) {
+                       // RX Channels: start WFQ algorithm
+                       chan_no = CHAN_TOTAL_NUM;
+                       for (i = 0; i < RX_CHAN_NUM; i++) {
+                               if ((isr & (comb_isr_mask[i]))
+                                       && (g_log_chan[i].weight > 0)) {
+                                       if (g_log_chan[chan_no].weight < g_log_chan[i].weight) {
+                                               chan_no = i;
+                                       }
+                               }
+                       }
+                       if (chan_no < CHAN_TOTAL_NUM) {
+                               rx_chan_intr_handler(chan_no);
+                       } else {
+                               for (i = 0; i < RX_CHAN_NUM; i++) {
+                                       g_log_chan[i].weight = g_log_chan[i].default_weight;
+                               }
+                       }
+               }
+#ifdef NO_TX_INT
+               cnt++;
+               if (cnt == 10) {
+                       cnt = 0;
+                       for (i = 0; i < tx_chan_list_len; i++) {
+                               if (AMAZON_DMA_REG32
+                                       (AMAZON_DMA_CH0_ISR +
+                                        tx_chan_list[i] *
+                                        AMAZON_DMA_CH_STEP) & (DMA_ISR_CPT | DMA_ISR_EOP)) {
+                                       tx_chan_intr_handler(tx_chan_list[i]);
+                               }
+                       }
+               }
+#else
+               if (isr & COMB_ISR_TX_MASK) {
+                       // TX channels: RR
+                       for (i = 0; i < tx_chan_list_len; i++) {
+                               if (isr & (comb_isr_mask[tx_chan_list[i]])) {
+                                       tx_chan_intr_handler(tx_chan_list[i]);
+                               }
+                       }
+               }
+#endif
+       }                                                       // while 
+       return IRQ_HANDLED;
+}
+
+
+/*     Brief:  read a packet from DMA RX channel
+ *     Parameter:
+ *     Return: packet length
+ *     Description:
+ *             This is called back in a context of DMA interrupt
+ *             1. prepare new descriptor
+ *             2. read data
+ *             3. update WFQ weight
+ */
+//507261:tc.chen int dma_device_read(struct dma_device_info* dma_dev, u8** dataptr, void** opt)
+int asmlinkage dma_device_read(struct dma_device_info *dma_dev,
+                                                          u8 ** dataptr, void **opt)
+{
+       u8 *buf;
+       int len;
+       int chan_no = 0;
+       int byte_offset = 0;
+
+       struct rx_desc *rx_desc_p;
+       void *p = NULL;
+       int current_desc;
+
+       chan_no = dma_dev->logic_rx_chan_base + dma_dev->current_rx_chan;
+       current_desc = g_log_chan[chan_no].current_desc;
+       rx_desc_p =
+               (struct rx_desc *) (g_desc_list +
+                                                       g_log_chan[chan_no].offset_from_base +
+                                                       current_desc);
+       buf = (u8 *) __va(rx_desc_p->Data_Pointer);     /* extract the virtual
+                                                                                                  address of the data
+                                                                                                  pointer */
+       len = rx_desc_p->status.field.data_length;      /* extract the data length */
+#ifndef        CONFIG_MIPS_UNCACHED
+       dma_cache_inv((unsigned long) buf, len);
+#endif                                                 // CONFIG_MIPS_UNCACHED
+       *(u32 *) dataptr = (u32) buf;
+       if (opt) {
+               *(int *) opt = (int) g_log_chan[chan_no].opt[current_desc];     /* read 
+                                                                                                                                          out 
+                                                                                                                                          the 
+                                                                                                                                          opt 
+                                                                                                                                          information */
+       }
+
+       buf =
+               (u8 *) g_log_chan[chan_no].buffer_alloc(g_log_chan[chan_no].
+                                                                                               packet_size, &byte_offset,
+                                                                                               &p);
+       // should check null!!!!
+       if (buf == NULL || p == NULL) {
+               *(u32 *) dataptr = 0;
+               *(int *) opt = 0;
+               len = 0;
+       } else {
+               g_log_chan[chan_no].opt[current_desc] = p;
+               /* reduce the weight for WFQ algorithm */
+               g_log_chan[chan_no].weight -= len;
+               rx_desc_p->Data_Pointer = (u32) CPHYSADDR((u32) buf);
+       }
+       if (current_desc == g_log_chan[chan_no].desc_len - 1) {
+               current_desc = 0;
+       } else {
+               current_desc++;
+       }
+       g_log_chan[chan_no].current_desc = current_desc;
+
+       rx_desc_p->status.word = DMA_DESC_OWN_DMA
+               | (byte_offset << DMA_DESC_BYTEOFF_SHIFT)
+               | g_log_chan[chan_no].packet_size;
+       return len;
+}
+
+/*     Brief:  write a packet through DMA RX channel to peripheral
+ *     Parameter:
+ *     Return: packet length
+ *     Description:
+ *
+ */
+u64 dma_tx_drop = 0;
+//507261:tc.chen int dma_device_write(struct dma_device_info* dma_dev, u8* dataptr, int len,void* opt)
+int asmlinkage dma_device_write(struct dma_device_info *dma_dev,
+                                                               u8 * dataptr, int len, void *opt)
+{
+       int chan_no = 0;
+       struct tx_desc *tx_desc_p;
+
+       int byte_offset = 0;
+       int current_desc;
+       static int cnt = 0;                     // 000004:fchang
+
+       unsigned long flag;
+       local_irq_save(flag);
+
+       chan_no = dma_dev->logic_tx_chan_base + dma_dev->current_tx_chan;
+       current_desc = g_log_chan[chan_no].current_desc;
+       tx_desc_p =
+               (struct tx_desc *) (g_desc_list +
+                                                       g_log_chan[chan_no].offset_from_base +
+                                                       current_desc);
+       // 000003:tc.chen if(tx_desc_p->status.field.OWN==DMA_OWN){
+       if (tx_desc_p->status.field.OWN == DMA_OWN || tx_desc_p->status.field.C == 1) { // 000003:tc.chen
+               AMAZON_DMA_DMSG("no TX desc for CPU, drop packet\n");
+               dma_tx_drop++;
+               g_log_chan[chan_no].intr_handler(dma_dev, TX_BUF_FULL_INT);
+               local_irq_restore(flag);
+               return 0;
+       }
+       g_log_chan[chan_no].opt[current_desc] = opt;
+
+       /* byte offset----to adjust the starting address of the data buffer,
+          should be multiple of the burst length. */
+       byte_offset =
+               ((u32) CPHYSADDR((u32) dataptr)) % (g_log_chan[chan_no].burst_len *
+                                                                                       4);
+#ifndef        CONFIG_MIPS_UNCACHED
+       dma_cache_wback((unsigned long) dataptr, len);
+       wmb();
+#endif                                                 // CONFIG_MIPS_UNCACHED
+
+       tx_desc_p->Data_Pointer = (u32) CPHYSADDR((u32) dataptr) - byte_offset;
+       wmb();
+       tx_desc_p->status.word = DMA_DESC_OWN_DMA
+               | DMA_DESC_SOP_SET
+               | DMA_DESC_EOP_SET | (byte_offset << DMA_DESC_BYTEOFF_SHIFT)
+               | len;
+       wmb();
+       if (is_channel_open(chan_no) == 0) {
+               // turn on if necessary
+               open_channel(chan_no);
+       }
+#ifdef DMA_NO_POLLING
+       if ((AMAZON_DMA_REG32
+                (AMAZON_DMA_CH0_ISR +
+                 chan_no * AMAZON_DMA_CH_STEP) & (DMA_ISR_DURR | DMA_ISR_CPT)) ==
+               (DMA_ISR_DURR)) {
+               // clear DURR if (CPT is AND set and DURR is set)
+               AMAZON_DMA_REG32(AMAZON_DMA_CH0_ISR +
+                                                chan_no * AMAZON_DMA_CH_STEP) = DMA_ISR_DURR;
+       }
+#endif
+
+       if (current_desc == (g_log_chan[chan_no].desc_len - 1)) {
+               current_desc = 0;
+       } else {
+               current_desc++;
+       }
+
+
+       g_log_chan[chan_no].current_desc = current_desc;
+       tx_desc_p =
+               (struct tx_desc *) (g_desc_list +
+                                                       g_log_chan[chan_no].offset_from_base +
+                                                       current_desc);
+       // 000003:tc.chen if(tx_desc_p->status.field.OWN==DMA_OWN){
+       if (tx_desc_p->status.field.OWN == DMA_OWN || tx_desc_p->status.field.C == 1) { // 000003:tc.chen
+               g_log_chan[chan_no].intr_handler(dma_dev, TX_BUF_FULL_INT);
+       }
+#ifdef NO_TX_INT
+//000004:fchang Start
+       cnt++;
+       if (cnt == 5) {
+               cnt = 0;
+               tx_chan_intr_handler(chan_no);
+       }
+//000004:fchang End
+#endif
+       local_irq_restore(flag);        // 000004:fchang
+       return len;
+}
+
+
+
+int desc_list_proc_read(char *buf, char **start, off_t offset,
+                                               int count, int *eof, void *data)
+{
+       int i;
+       u32 *p = (u32 *) g_desc_list;
+       int len = 0;
+       len += sprintf(buf + len, "descriptor list:\n");
+       for (i = 0; i < 120; i++) {
+               len += sprintf(buf + len, "%d\n", i);
+               len += sprintf(buf + len, "%08x\n", *(p + i * 2 + 1));
+               len += sprintf(buf + len, "%08x\n", *(p + i * 2));
+
+       }
+
+       return len;
+
+}
+
+int channel_weight_proc_read(char *buf, char **start, off_t offset,
+                                                        int count, int *eof, void *data)
+{
+
+       // int i=0;
+       int len = 0;
+       len += sprintf(buf + len, "Qos dma channel weight list\n");
+       len +=
+               sprintf(buf + len,
+                               "channel_num default_weight current_weight device Tx/Rx\n");
+       len +=
+               sprintf(buf + len,
+                               "     0      %08x        %08x      Switch   Rx0\n",
+                               g_log_chan[0].default_weight, g_log_chan[0].weight);
+       len +=
+               sprintf(buf + len,
+                               "     1      %08x        %08x      Switch   Rx1\n",
+                               g_log_chan[1].default_weight, g_log_chan[1].weight);
+       len +=
+               sprintf(buf + len,
+                               "     2      %08x        %08x      Switch   Rx2\n",
+                               g_log_chan[2].default_weight, g_log_chan[2].weight);
+       len +=
+               sprintf(buf + len,
+                               "     3      %08x        %08x      Switch   Rx3\n",
+                               g_log_chan[3].default_weight, g_log_chan[3].weight);
+       len +=
+               sprintf(buf + len,
+                               "     4      %08x        %08x      Switch   Tx0\n",
+                               g_log_chan[4].default_weight, g_log_chan[4].weight);
+       len +=
+               sprintf(buf + len,
+                               "     5      %08x        %08x      Switch   Tx1\n",
+                               g_log_chan[5].default_weight, g_log_chan[5].weight);
+       /* 
+          len+=sprintf(buf+len," 6 %08x %08x TPE
+          Rx0\n",g_log_chan[6].default_weight, g_log_chan[6].weight);
+          len+=sprintf(buf+len," 7 %08x %08x TPE
+          Rx0\n",g_log_chan[7].default_weight, g_log_chan[7].weight);
+          len+=sprintf(buf+len," 8 %08x %08x TPE
+          Tx0\n",g_log_chan[8].default_weight, g_log_chan[8].weight);
+          len+=sprintf(buf+len," 9 %08x %08x TPE
+          Rx0\n",g_log_chan[9].default_weight, g_log_chan[9].weight);
+          len+=sprintf(buf+len," 10 %08x %08x DPLUS
+          Rx0\n",g_log_chan[10].default_weight, g_log_chan[10].weight);
+          len+=sprintf(buf+len," 11 %08x %08x DPLUS
+          Rx0\n",g_log_chan[11].default_weight, g_log_chan[11].weight); */
+       return len;
+}
+
+int dma_register_proc_read(char *buf, char **start, off_t offset,
+                                                  int count, int *eof, void *data)
+{
+       dev_list *temp_dev;
+       int len = 0;;
+
+       len += sprintf(buf + len, "amazon dma driver\n");
+       len += sprintf(buf + len, "version 1.0\n");
+       len += sprintf(buf + len, "devices registered:\n");
+       for (temp_dev = g_head_dev; temp_dev; temp_dev = temp_dev->next) {
+               len += sprintf(buf + len, "%s ", temp_dev->dev->device_name);
+       }
+       len += sprintf(buf + len, "\n");
+       len += sprintf(buf + len, "CH_ON=%08x\n", AMAZON_DMA_REG32(AMAZON_DMA_CH_ON));
+       len += sprintf(buf + len, "CH_RST=%08x\n", AMAZON_DMA_REG32(AMAZON_DMA_CH_RST));
+       len += sprintf(buf + len, "CH0_ISR=%08x\n",     AMAZON_DMA_REG32(AMAZON_DMA_CH0_ISR));
+       len += sprintf(buf + len, "CH1_ISR=%08x\n",     AMAZON_DMA_REG32(AMAZON_DMA_CH1_ISR));
+       len += sprintf(buf + len, "CH2_ISR=%08x\n",     AMAZON_DMA_REG32(AMAZON_DMA_CH2_ISR));
+       len += sprintf(buf + len, "CH3_ISR=%08x\n",     AMAZON_DMA_REG32(AMAZON_DMA_CH3_ISR));
+       len += sprintf(buf + len, "CH4_ISR=%08x\n",     AMAZON_DMA_REG32(AMAZON_DMA_CH4_ISR));
+       len += sprintf(buf + len, "CH5_ISR=%08x\n",     AMAZON_DMA_REG32(AMAZON_DMA_CH5_ISR));
+       len += sprintf(buf + len, "CH6_ISR=%08x\n",     AMAZON_DMA_REG32(AMAZON_DMA_CH6_ISR));
+       len += sprintf(buf + len, "CH7_ISR=%08x\n", AMAZON_DMA_REG32(AMAZON_DMA_CH7_ISR));
+       len +=          sprintf(buf + len, "CH8_ISR=%08x\n",
+                               AMAZON_DMA_REG32(AMAZON_DMA_CH8_ISR));
+       len +=
+               sprintf(buf + len, "CH9_ISR=%08x\n",
+                               AMAZON_DMA_REG32(AMAZON_DMA_CH9_ISR));
+       len +=
+               sprintf(buf + len, "CH10_ISR=%08x\n",
+                               AMAZON_DMA_REG32(AMAZON_DMA_CH10_ISR));
+       len +=
+               sprintf(buf + len, "CH11_ISR=%08x\n",
+                               AMAZON_DMA_REG32(AMAZON_DMA_CH11_ISR));
+       len +=
+               sprintf(buf + len, "LCH0_MSK=%08x\n",
+                               AMAZON_DMA_REG32(AMAZON_DMA_CH0_MSK));
+       len +=
+               sprintf(buf + len, "LCH1_MSK=%08x\n",
+                               AMAZON_DMA_REG32(AMAZON_DMA_CH1_MSK));
+       len +=
+               sprintf(buf + len, "LCH2_MSK=%08x\n",
+                               AMAZON_DMA_REG32(AMAZON_DMA_CH2_MSK));
+       len +=
+               sprintf(buf + len, "LCH3_MSK=%08x\n",
+                               AMAZON_DMA_REG32(AMAZON_DMA_CH3_MSK));
+       len +=
+               sprintf(buf + len, "LCH4_MSK=%08x\n",
+                               AMAZON_DMA_REG32(AMAZON_DMA_CH4_MSK));
+       len +=
+               sprintf(buf + len, "LCH5_MSK=%08x\n",
+                               AMAZON_DMA_REG32(AMAZON_DMA_CH5_MSK));
+       len +=
+               sprintf(buf + len, "LCH6_MSK=%08x\n",
+                               AMAZON_DMA_REG32(AMAZON_DMA_CH6_MSK));
+       len +=
+               sprintf(buf + len, "LCH7_MSK=%08x\n",
+                               AMAZON_DMA_REG32(AMAZON_DMA_CH7_MSK));
+       len +=
+               sprintf(buf + len, "LCH8_MSK=%08x\n",
+                               AMAZON_DMA_REG32(AMAZON_DMA_CH8_MSK));
+       len +=
+               sprintf(buf + len, "LCH9_MSK=%08x\n",
+                               AMAZON_DMA_REG32(AMAZON_DMA_CH9_MSK));
+       len +=
+               sprintf(buf + len, "LCH10_MSK=%08x\n",
+                               AMAZON_DMA_REG32(AMAZON_DMA_CH10_MSK));
+       len +=
+               sprintf(buf + len, "LCH11_MSK=%08x\n",
+                               AMAZON_DMA_REG32(AMAZON_DMA_CH11_MSK));
+       len +=
+               sprintf(buf + len, "Desc_BA=%08x\n",
+                               AMAZON_DMA_REG32(AMAZON_DMA_Desc_BA));
+       len +=
+               sprintf(buf + len, "LCH0_DES_LEN=%08x\n",
+                               AMAZON_DMA_REG32(AMAZON_DMA_CH0_DES_LEN));
+       len +=
+               sprintf(buf + len, "LCH1_DES_LEN=%08x\n",
+                               AMAZON_DMA_REG32(AMAZON_DMA_CH1_DES_LEN));
+       len +=
+               sprintf(buf + len, "LCH2_DES_LEN=%08x\n",
+                               AMAZON_DMA_REG32(AMAZON_DMA_CH2_DES_LEN));
+       len +=
+               sprintf(buf + len, "LCH3_DES_LEN=%08x\n",
+                               AMAZON_DMA_REG32(AMAZON_DMA_CH3_DES_LEN));
+       len +=
+               sprintf(buf + len, "LCH4_DES_LEN=%08x\n",
+                               AMAZON_DMA_REG32(AMAZON_DMA_CH4_DES_LEN));
+       len +=
+               sprintf(buf + len, "LCH5_DES_LEN=%08x\n",
+                               AMAZON_DMA_REG32(AMAZON_DMA_CH5_DES_LEN));
+       len +=
+               sprintf(buf + len, "LCH6_DES_LEN=%08x\n",
+                               AMAZON_DMA_REG32(AMAZON_DMA_CH6_DES_LEN));
+       len +=
+               sprintf(buf + len, "LCH7_DES_LEN=%08x\n",
+                               AMAZON_DMA_REG32(AMAZON_DMA_CH7_DES_LEN));
+       len +=
+               sprintf(buf + len, "LCH8_DES_LEN=%08x\n",
+                               AMAZON_DMA_REG32(AMAZON_DMA_CH8_DES_LEN));
+       len +=
+               sprintf(buf + len, "LCH9_DES_LEN=%08x\n",
+                               AMAZON_DMA_REG32(AMAZON_DMA_CH9_DES_LEN));
+       len +=
+               sprintf(buf + len, "LCH10_DES_LEN=%08x\n",
+                               AMAZON_DMA_REG32(AMAZON_DMA_CH10_DES_LEN));
+       len +=
+               sprintf(buf + len, "LCH11_DES_LEN=%08x\n",
+                               AMAZON_DMA_REG32(AMAZON_DMA_CH11_DES_LEN));
+       len +=
+               sprintf(buf + len, "LCH1_DES_OFST=%08x\n",
+                               AMAZON_DMA_REG32(AMAZON_DMA_CH1_DES_OFST));
+       len +=
+               sprintf(buf + len, "LCH2_DES_OFST=%08x\n",
+                               AMAZON_DMA_REG32(AMAZON_DMA_CH2_DES_OFST));
+       len +=
+               sprintf(buf + len, "LCH3_DES_OFST=%08x\n",
+                               AMAZON_DMA_REG32(AMAZON_DMA_CH3_DES_OFST));
+       len +=
+               sprintf(buf + len, "LCH4_DES_OFST=%08x\n",
+                               AMAZON_DMA_REG32(AMAZON_DMA_CH4_DES_OFST));
+       len +=
+               sprintf(buf + len, "LCH5_DES_OFST=%08x\n",
+                               AMAZON_DMA_REG32(AMAZON_DMA_CH5_DES_OFST));
+       len +=
+               sprintf(buf + len, "LCH6_DES_OFST=%08x\n",
+                               AMAZON_DMA_REG32(AMAZON_DMA_CH6_DES_OFST));
+       len +=
+               sprintf(buf + len, "LCH7_DES_OFST=%08x\n",
+                               AMAZON_DMA_REG32(AMAZON_DMA_CH7_DES_OFST));
+       len +=
+               sprintf(buf + len, "LCH8_DES_OFST=%08x\n",
+                               AMAZON_DMA_REG32(AMAZON_DMA_CH8_DES_OFST));
+       len +=
+               sprintf(buf + len, "LCH9_DES_OFST=%08x\n",
+                               AMAZON_DMA_REG32(AMAZON_DMA_CH9_DES_OFST));
+       len +=
+               sprintf(buf + len, "LCH10_DES_OFST=%08x\n",
+                               AMAZON_DMA_REG32(AMAZON_DMA_CH10_DES_OFST));
+       len +=
+               sprintf(buf + len, "LCH11_DES_OFST=%08x\n",
+                               AMAZON_DMA_REG32(AMAZON_DMA_CH11_DES_OFST));
+       len +=
+               sprintf(buf + len, "AMAZON_DMA_SW_BL=%08x\n",
+                               AMAZON_DMA_REG32(AMAZON_DMA_SW_BL));
+       len +=
+               sprintf(buf + len, "AMAZON_DMA_TPE_BL=%08x\n",
+                               AMAZON_DMA_REG32(AMAZON_DMA_TPE_BL));
+       len +=
+               sprintf(buf + len, "DPlus2FPI_BL=%08x\n",
+                               AMAZON_DMA_REG32(AMAZON_DMA_DPlus2FPI_BL));
+       len +=
+               sprintf(buf + len, "GRX_BUF_LEN=%08x\n",
+                               AMAZON_DMA_REG32(AMAZON_DMA_GRX_BUF_LEN));
+       len +=
+               sprintf(buf + len, "DMA_ECON_REG=%08x\n",
+                               AMAZON_DMA_REG32(AMAZON_DMA_DMA_ECON_REG));
+       len +=
+               sprintf(buf + len, "POLLING_REG=%08x\n",
+                               AMAZON_DMA_REG32(AMAZON_DMA_POLLING_REG));
+       len +=
+               sprintf(buf + len, "CH_WGT=%08x\n",
+                               AMAZON_DMA_REG32(AMAZON_DMA_CH_WGT));
+       len +=
+               sprintf(buf + len, "TX_WGT=%08x\n",
+                               AMAZON_DMA_REG32(AMAZON_DMA_TX_WGT));
+       len +=
+               sprintf(buf + len, "DPlus2FPI_CLASS=%08x\n",
+                               AMAZON_DMA_REG32(AMAZON_DMA_DPLus2FPI_CLASS));
+       len +=
+               sprintf(buf + len, "COMB_ISR=%08x\n",
+                               AMAZON_DMA_REG32(AMAZON_DMA_COMB_ISR));
+#ifdef AMAZON_DMA_TPE_AAL5_RECOVERY
+       len += sprintf(buf + len, "TPE fails:%u\n", total_dma_tpe_reset);       // 000004:fchang
+#endif
+       return len;
+}
+
+/*     Brief:  initialize DMA registers
+ *     Description:
+ */
+static void dma_chip_init(void)
+{
+       int i;
+       for (i = 0; i < CHAN_TOTAL_NUM; i++) {
+               AMAZON_DMA_REG32(AMAZON_DMA_CH1_DES_OFST +
+                                                i * AMAZON_DMA_CH_STEP) = DEFAULT_OFFSET;
+       }
+#ifdef DMA_NO_POLLING
+       AMAZON_DMA_REG32(AMAZON_DMA_POLLING_REG) = 0;
+#else
+       // enable poll mode and set polling counter
+       AMAZON_DMA_REG32(AMAZON_DMA_POLLING_REG) = DMA_POLLING_CNT | DMA_POLLING_ENABLE;
+#endif
+       // to enable DMA drop
+       AMAZON_DMA_REG32(AMAZON_DMA_GRX_BUF_LEN) = 0x10000;
+}
+
+int insert_dev_list(dev_list * dev)
+{
+       dev_list *temp_dev;
+       if (g_head_dev == NULL) {
+               g_head_dev = dev;
+               g_tail_dev = dev;
+               dev->prev = NULL;
+               dev->next = NULL;
+       } else {
+               for (temp_dev = g_head_dev; temp_dev; temp_dev = temp_dev->next) {
+                       if (temp_dev->weight < dev->weight) {
+                               if (temp_dev->prev)
+                                       temp_dev->prev->next = dev;
+
+                               dev->prev = temp_dev->prev;
+                               dev->next = temp_dev;
+                               temp_dev->prev = dev;
+                               if (temp_dev == g_head_dev)
+                                       g_head_dev = dev;
+                               break;
+                       }
+               }
+
+               if (!temp_dev) {
+                       g_tail_dev->next = dev;
+                       dev->prev = g_tail_dev;
+                       dev->next = NULL;
+                       g_tail_dev = dev;
+               }
+
+       }
+
+       return 1;
+}
+
+u8 *common_buffer_alloc(int len, int *byte_offset, void **opt)
+{
+       u8 *buffer = (u8 *) kmalloc(len * sizeof(u8), GFP_KERNEL);
+       *byte_offset = 0;
+       return buffer;
+
+}
+
+int common_buffer_free(u8 * dataptr, void *opt)
+{
+       if (dataptr)
+               kfree(dataptr);
+       return 0;
+}
+
+
+int register_dev(struct dma_device_info *dma_dev)
+{
+       int i, j, temp;
+       int burst_reg = 0;
+       u8 *buffer;
+       void *p = NULL;
+       int byte_offset = 0;
+
+       struct rx_desc *rx_desc_p;
+       struct tx_desc *tx_desc_p;
+       if (strcmp(dma_dev->device_name, "switch1") == 0) {
+               AMAZON_DMA_REG32(AMAZON_DMA_CH_RST) = SWITCH1_RST_MASK; // resest
+                                                                                                                               // channel 
+                                                                                                                               // 1st 
+               AMAZON_DMA_REG32(AMAZON_DMA_DMA_ECON_REG) |= 0x3;       // endian
+                                                                                                                       // conversion
+                                                                                                                       // for Switch
+               burst_reg = AMAZON_DMA_SW_BL;
+               dma_dev->logic_rx_chan_base = switch_rx_chan_base;
+               dma_dev->logic_tx_chan_base = switch_tx_chan_base;
+       }
+
+       else if (strcmp(dma_dev->device_name, "switch2") == 0) {
+               AMAZON_DMA_REG32(AMAZON_DMA_CH_RST) = SWITCH2_RST_MASK; // resest
+                                                                                                                               // channel 
+                                                                                                                               // 1st
+               AMAZON_DMA_REG32(AMAZON_DMA_DMA_ECON_REG) |= 0x3;       // endian
+                                                                                                                       // conversion
+                                                                                                                       // for Switch
+               burst_reg = AMAZON_DMA_SW_BL;
+               dma_dev->logic_rx_chan_base = switch2_rx_chan_base;
+               dma_dev->logic_tx_chan_base = switch2_tx_chan_base;
+
+       } else if (strcmp(dma_dev->device_name, "TPE") == 0) {
+               AMAZON_DMA_REG32(AMAZON_DMA_CH_RST) = TPE_RST_MASK;     // resest
+                                                                                                                       // channel 1st 
+                                                                                                                       // 
+               burst_reg = AMAZON_DMA_TPE_BL;
+               dma_dev->logic_rx_chan_base = TPE_rx_chan_base;
+               dma_dev->logic_tx_chan_base = TPE_tx_chan_base;
+       }
+
+       else if (strcmp(dma_dev->device_name, "DPlus") == 0) {
+               AMAZON_DMA_REG32(AMAZON_DMA_CH_RST) = DPlus2FPI_RST_MASK;       // resest 
+                                                                                                                                       // channel 
+                                                                                                                                       // 1st
+               dma_dev->logic_rx_chan_base = DPLus2FPI_rx_chan_base;
+               dma_dev->logic_tx_chan_base = DPLus2FPI_tx_chan_base;
+
+       }
+
+       i = 0;
+       for (temp = dma_dev->tx_burst_len; temp > 2; temp /= 2) {
+               i += 1;
+       }
+
+
+       AMAZON_DMA_REG32(burst_reg) = i << 1;
+       i = 0;
+       for (temp = dma_dev->rx_burst_len; temp > 2; temp /= 2) {
+               i += 1;
+       }
+       AMAZON_DMA_REG32(burst_reg) += i;
+
+       for (i = 0; i < dma_dev->num_rx_chan; i++) {
+
+               temp = dma_dev->logic_rx_chan_base + i;
+               g_log_chan[temp].dma_dev = dma_dev;
+               g_log_chan[temp].weight = dma_dev->rx_chan[i].weight;
+               g_log_chan[temp].default_weight = dma_dev->rx_chan[i].weight;
+               g_log_chan[temp].current_desc = 0;
+               g_log_chan[temp].desc_ofst = DEFAULT_OFFSET;
+               g_log_chan[temp].desc_len = dma_dev->rx_chan[i].desc_num;
+               g_log_chan[temp].offset_from_base = temp * DEFAULT_OFFSET;
+               g_log_chan[temp].packet_size = dma_dev->rx_chan[i].packet_size;
+
+               AMAZON_DMA_REG32(AMAZON_DMA_CH0_DES_LEN + temp * AMAZON_DMA_CH_STEP) = dma_dev->rx_chan[i].desc_num;
+               // enable interrupt mask
+               if (temp == 4 || temp == 5) {
+                       AMAZON_DMA_REG32(AMAZON_DMA_CH0_MSK + temp * AMAZON_DMA_CH_STEP) = 0x32;
+               } else {
+                       AMAZON_DMA_REG32(AMAZON_DMA_CH0_MSK + temp * AMAZON_DMA_CH_STEP) = 0x36;
+               }
+               strcpy(g_log_chan[temp].device_name, dma_dev->device_name);
+               g_log_chan[temp].burst_len = dma_dev->rx_burst_len;
+               g_log_chan[temp].control = dma_dev->rx_chan[i].control;
+
+
+               /* specify the buffer allocation and free method */
+               if (dma_dev->buffer_alloc)
+                       g_log_chan[temp].buffer_alloc = dma_dev->buffer_alloc;
+               else
+                       g_log_chan[temp].buffer_alloc = common_buffer_alloc;
+
+               if (dma_dev->buffer_free)
+                       g_log_chan[temp].buffer_free = dma_dev->buffer_free;
+               else
+                       g_log_chan[temp].buffer_free = common_buffer_free;
+
+               if (dma_dev->intr_handler)
+                       g_log_chan[temp].intr_handler = dma_dev->intr_handler;
+               else
+                       g_log_chan[temp].intr_handler = NULL;
+
+               for (j = 0; j < g_log_chan[temp].desc_len; j++) {
+                       rx_desc_p = (struct rx_desc *) (g_desc_list + g_log_chan[temp].offset_from_base + j);
+                       rx_desc_p->status.word = 0;
+                       rx_desc_p->status.field.data_length = g_log_chan[temp].packet_size;
+                       buffer = (u8 *) g_log_chan[temp].buffer_alloc(g_log_chan[temp].packet_size, &byte_offset, &p);
+                       rx_desc_p->Data_Pointer = (u32) CPHYSADDR((u32) buffer);
+                       rx_desc_p->status.field.byte_offset = byte_offset;
+                       /* fix me, should check if the addresss comply with the burst
+                          lenght requirment */
+                       g_log_chan[temp].opt[j] = p;
+                       rx_desc_p->status.field.OWN = DMA_OWN;
+
+               }
+               /* open or close the channel */
+               if (g_log_chan[temp].control)
+                       open_channel(temp);
+               else
+                       close_channel(temp);
+       }
+
+       for (i = 0; i < dma_dev->num_tx_chan; i++) {
+               temp = dma_dev->logic_tx_chan_base + i;
+               g_log_chan[temp].dma_dev = dma_dev;
+               g_log_chan[temp].weight = dma_dev->tx_chan[i].weight;
+               g_log_chan[temp].default_weight = dma_dev->tx_chan[i].weight;
+               g_log_chan[temp].current_desc = 0;
+               g_log_chan[temp].desc_ofst = DEFAULT_OFFSET;
+               g_log_chan[temp].desc_len = dma_dev->tx_chan[i].desc_num;
+               g_log_chan[temp].offset_from_base = temp * DEFAULT_OFFSET;
+               g_log_chan[temp].packet_size = dma_dev->tx_chan[i].packet_size;
+
+               AMAZON_DMA_REG32(AMAZON_DMA_CH0_DES_LEN + temp * AMAZON_DMA_CH_STEP) = dma_dev->tx_chan[i].desc_num;
+               // enable interrupt mask
+#ifdef NO_TX_INT
+               AMAZON_DMA_REG32(AMAZON_DMA_CH0_MSK + temp * AMAZON_DMA_CH_STEP) = 0x3e;
+#else
+               AMAZON_DMA_REG32(AMAZON_DMA_CH0_MSK + temp * AMAZON_DMA_CH_STEP) = 0x36;
+#endif
+
+               strcpy(g_log_chan[temp].device_name, dma_dev->device_name);
+               g_log_chan[temp].burst_len = dma_dev->tx_burst_len;
+               g_log_chan[temp].control = dma_dev->tx_chan[i].control;
+
+               if (dma_dev->buffer_alloc)
+                       g_log_chan[temp].buffer_alloc = dma_dev->buffer_alloc;
+               else
+                       g_log_chan[temp].buffer_alloc = common_buffer_alloc;
+
+               if (dma_dev->buffer_free)
+                       g_log_chan[temp].buffer_free = dma_dev->buffer_free;
+               else
+                       g_log_chan[temp].buffer_free = common_buffer_free;
+
+               if (dma_dev->intr_handler)
+                       g_log_chan[temp].intr_handler = dma_dev->intr_handler;
+               else
+                       g_log_chan[temp].intr_handler = NULL;
+
+               for (j = 0; j < g_log_chan[temp].desc_len; j++) {
+
+                       tx_desc_p =
+                               (struct tx_desc *) (g_desc_list +
+                                                                       g_log_chan[temp].offset_from_base + j);
+                       tx_desc_p->status.word = 0;
+                       tx_desc_p->status.field.data_length =
+                               g_log_chan[temp].packet_size;
+                       tx_desc_p->status.field.OWN = CPU_OWN;
+
+               }
+               /* workaround DMA pitfall, we never turn on channel if we don't
+                  have proper descriptors */
+               if (!g_log_chan[temp].control) {
+                       close_channel(temp);
+               }
+
+       }
+
+       return 0;
+}
+
+int dma_device_register(struct dma_device_info *dma_dev)
+{
+       dev_list *temp_dev;
+       temp_dev = (dev_list *) kmalloc(sizeof(dev_list), GFP_KERNEL);
+       temp_dev->dev = dma_dev;
+       temp_dev->weight = dma_dev->weight;
+       insert_dev_list(temp_dev);
+       /* check whether this is a known device */
+       if ((strcmp(dma_dev->device_name, "switch1") == 0)
+               || (strcmp(dma_dev->device_name, "TPE") == 0)
+               || (strcmp(dma_dev->device_name, "switch2") == 0)
+               || (strcmp(dma_dev->device_name, "DPlus") == 0)) {
+               register_dev(dma_dev);
+       }
+
+       return 0;
+}
+
+
+int unregister_dev(struct dma_device_info *dma_dev)
+{
+       int i, j, temp;
+       u8 *buffer;
+       struct rx_desc *rx_desc_p;
+
+       for (i = 0; i < dma_dev->num_rx_chan; i++) {
+               temp = dma_dev->logic_rx_chan_base + i;
+               close_channel(temp);
+               for (j = 0; j < g_log_chan[temp].desc_len; j++) {
+                       rx_desc_p =
+                               (struct rx_desc *) (g_desc_list +
+                                                                       g_log_chan[temp].offset_from_base + j);
+                       buffer = (u8 *) __va(rx_desc_p->Data_Pointer);
+                       g_log_chan[temp].buffer_free(buffer, g_log_chan[temp].opt[j]);
+               }
+       }
+       for (i = 0; i < dma_dev->num_tx_chan; i++) {
+               temp = dma_dev->logic_tx_chan_base + i;
+               close_channel(temp);
+       }
+       return 0;
+}
+
+int dma_device_unregister(struct dma_device_info *dev)
+{
+       dev_list *temp_dev;
+       for (temp_dev = g_head_dev; temp_dev; temp_dev = temp_dev->next) {
+               if (strcmp(dev->device_name, temp_dev->dev->device_name) == 0) {
+                       if ((strcmp(dev->device_name, "switch1") == 0)
+                               || (strcmp(dev->device_name, "TPE") == 0)
+                               || (strcmp(dev->device_name, "switch2") == 0)
+                               || (strcmp(dev->device_name, "DPlus") == 0))
+                               unregister_dev(dev);
+                       if (temp_dev == g_head_dev) {
+                               g_head_dev = temp_dev->next;
+                               kfree(temp_dev);
+                       } else {
+                               if (temp_dev == g_tail_dev)
+                                       g_tail_dev = temp_dev->prev;
+                               if (temp_dev->prev)
+                                       temp_dev->prev->next = temp_dev->next;
+                               if (temp_dev->next)
+                                       temp_dev->next->prev = temp_dev->prev;
+                               kfree(temp_dev);
+                       }
+                       break;
+               }
+
+       }
+       return 0;
+}
+
+void dma_device_update_rx(struct dma_device_info *dma_dev)
+{
+       int i, temp;
+       for (i = 0; i < dma_dev->num_rx_chan; i++) {
+               temp = dma_dev->logic_rx_chan_base + i;
+               g_log_chan[temp].control = dma_dev->rx_chan[i].control;
+
+               if (g_log_chan[temp].control)
+                       open_channel(temp);
+               else
+                       close_channel(temp);
+       }
+
+}
+
+void dma_device_update_tx(struct dma_device_info *dma_dev)
+{
+       int i, temp;
+       for (i = 0; i < dma_dev->num_tx_chan; i++) {
+               temp = dma_dev->logic_tx_chan_base + i;
+               g_log_chan[temp].control = dma_dev->tx_chan[i].control;
+               if (g_log_chan[temp].control) {
+                       /* we turn on channel when send out the very first packet */
+                       // open_channel(temp);
+               } else
+                       close_channel(temp);
+       }
+}
+
+int dma_device_update(struct dma_device_info *dma_dev)
+{
+       dma_device_update_rx(dma_dev);
+       dma_device_update_tx(dma_dev);
+       return 0;
+}
+
+static int dma_open(struct inode *inode, struct file *file)
+{
+       return 0;
+}
+
+static int dma_release(struct inode *inode, struct file *file)
+{
+       /* release the resources */
+       return 0;
+}
+
+static int dma_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg)
+{
+       int value = 0;
+       int result = 0;
+       int chan_no = 0;
+
+       switch (cmd) {
+       case 0:                                 /* get register value */
+               break;
+       case 1:                                 /* return channel weight */
+               chan_no = *((int *) arg);
+               *((int *) arg + 1) = g_log_chan[chan_no].default_weight;
+               break;
+       case 2:                                 /* set channel weight */
+               chan_no = *((int *) arg);
+               value = *((int *) arg + 1);
+               printk("new weight=%08x\n", value);
+               g_log_chan[chan_no].default_weight = value;
+               break;
+       default:
+               break;
+       }
+       return result;
+}
+
+
+static struct file_operations dma_fops = {
+  owner:THIS_MODULE,
+  open:dma_open,
+  release:dma_release,
+  ioctl:dma_ioctl,
+};
+
+static int dma_init(void)
+{
+       int result = 0;
+       int i;
+       printk("initialising dma core\n");
+       result = register_chrdev(DMA_MAJOR, "dma-core", &dma_fops);
+       if (result) {
+               AMAZON_DMA_EMSG("cannot register device dma-core!\n");
+               return result;
+       }
+       result = request_irq(AMAZON_DMA_INT, dma_interrupt, SA_INTERRUPT, "dma-core", (void *) &dma_interrupt);
+       if (result) {
+               AMAZON_DMA_EMSG("error, cannot get dma_irq!\n");
+               free_irq(AMAZON_DMA_INT, (void *) &dma_interrupt);
+               return -EFAULT;
+       }
+
+       g_desc_list = (u64 *) KSEG1ADDR(__get_free_page(GFP_DMA));
+
+       if (g_desc_list == NULL) {
+               AMAZON_DMA_EMSG("no memory for desriptor\n");
+               return -ENOMEM;
+       }
+       memset(g_desc_list, 0, PAGE_SIZE);
+       AMAZON_DMA_REG32(AMAZON_DMA_Desc_BA) = (u32) CPHYSADDR((u32) g_desc_list);
+       g_amazon_dma_dir = proc_mkdir("amazon_dma", NULL);
+       create_proc_read_entry("dma_register", 0, g_amazon_dma_dir, dma_register_proc_read, NULL);
+       create_proc_read_entry("g_desc_list", 0, g_amazon_dma_dir, desc_list_proc_read, NULL);
+       create_proc_read_entry("channel_weight", 0, g_amazon_dma_dir, channel_weight_proc_read, NULL);
+
+       dma_chip_init();
+       for (i = 0; i < (RX_CHAN_NUM + 1); i++) {
+               rx_chan_list[i] = -1;
+       }
+       for (i = 0; i < (TX_CHAN_NUM + 1); i++) {
+               tx_chan_list[i] = -1;
+       }
+
+       for (i = 0; i < CHAN_TOTAL_NUM; i++) {
+               comb_isr_mask[i] = 0x80000000 >> (i);
+       }
+
+       g_log_chan[CHAN_TOTAL_NUM].weight = 0;
+       printk("initialising dma core ... done\n");
+
+       return 0;
+}
+
+arch_initcall(dma_init);
+
+
+void dma_cleanup(void)
+{
+       dev_list *temp_dev;
+
+       unregister_chrdev(DMA_MAJOR, "dma-core");
+       for (temp_dev = g_head_dev; temp_dev; temp_dev = temp_dev->next) {
+               kfree(temp_dev);
+       }
+       free_page(KSEG0ADDR((unsigned long) g_desc_list));
+       remove_proc_entry("channel_weight", g_amazon_dma_dir);
+       remove_proc_entry("dma_list", g_amazon_dma_dir);
+       remove_proc_entry("dma_register", g_amazon_dma_dir);
+       remove_proc_entry("amazon_dma", NULL);
+       /* release the resources */
+       free_irq(AMAZON_DMA_INT, (void *) &dma_interrupt);
+}
+
+EXPORT_SYMBOL(dma_device_register);
+EXPORT_SYMBOL(dma_device_unregister);
+EXPORT_SYMBOL(dma_device_read);
+EXPORT_SYMBOL(dma_device_write);
+EXPORT_SYMBOL(dma_device_update);
+EXPORT_SYMBOL(dma_device_update_rx);
+
+MODULE_LICENSE("GPL");
diff --git a/target/linux/amazon-2.6/files/arch/mips/amazon/dma-core.h b/target/linux/amazon-2.6/files/arch/mips/amazon/dma-core.h
new file mode 100644 (file)
index 0000000..cb3d456
--- /dev/null
@@ -0,0 +1,69 @@
+#ifndef DMA_CORE_H 
+#define DMA_CORE_H 
+
+#define AMAZON_DMA_REG32(reg_num)  *((volatile u32*)(reg_num))
+#define AMAZON_DMA_CH_STEP            4
+
+#define COMB_ISR_RX_MASK 0xfe000000
+#define COMB_ISR_TX_MASK 0x01f00000
+
+
+#define DMA_OWN   1
+#define CPU_OWN   0   
+#define DMA_MAJOR 250
+
+//Descriptors
+#define DMA_DESC_OWN_CPU               0x0
+#define DMA_DESC_OWN_DMA               0x80000000
+#define DMA_DESC_CPT_SET               0x40000000
+#define DMA_DESC_SOP_SET               0x20000000
+#define DMA_DESC_EOP_SET               0x10000000
+
+#define switch_rx_chan_base 0
+#define switch_tx_chan_base 7
+#define switch2_rx_chan_base 2
+#define switch2_tx_chan_base 8
+#define TPE_rx_chan_base    4
+#define TPE_tx_chan_base    9
+#define DPLus2FPI_rx_chan_base  6
+#define DPLus2FPI_tx_chan_base  11 
+
+#define RX_CHAN_NUM 7
+#define TX_CHAN_NUM 5
+#define CHAN_TOTAL_NUM       (RX_CHAN_NUM+TX_CHAN_NUM)
+#define DEFAULT_OFFSET 20
+#define DESCRIPTOR_SIZE 8
+
+typedef struct dev_list{
+   struct dma_device_info* dev;
+   int weight;
+   struct dev_list* prev;
+   struct dev_list* next;
+}dev_list; 
+
+typedef struct channel_info{
+   char device_name[16];
+   int occupied;
+   enum attr_t attr;  
+   int current_desc;
+   int weight;
+   int default_weight;
+   int desc_num;
+   int burst_len;
+   int desc_len;
+   int desc_ofst;
+   int packet_size;
+   int offset_from_base;
+   int control;
+   void* opt[DEFAULT_OFFSET];
+   u8* (*buffer_alloc)(int len,int* offset, void** opt);
+   int (*buffer_free)(u8* dataptr,void* opt);
+   int (*intr_handler)(struct dma_device_info* info,int status);
+
+   struct dma_device_info* dma_dev;
+}channel_info;
+
+
+
+#endif
+
diff --git a/target/linux/amazon-2.6/files/arch/mips/amazon/interrupt.c b/target/linux/amazon-2.6/files/arch/mips/amazon/interrupt.c
new file mode 100644 (file)
index 0000000..6702ecf
--- /dev/null
@@ -0,0 +1,238 @@
+/*
+ *  Gary Jennejohn (C) 2003 <gj@denx.de>
+ *  Copyright (C) 2007 Felix Fietkau <nbd@openwrt.org>
+ *
+ *  This program is free software; you can distribute it and/or modify it
+ *  under the terms of the GNU General Public License (Version 2) as
+ *  published by the Free Software Foundation.
+ *
+ *  This program is distributed in the hope it will be useful, but WITHOUT
+ *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ *  for more details.
+ *
+ *  You should have received a copy of the GNU General Public License along
+ *  with this program; if not, write to the Free Software Foundation, Inc.,
+ *  59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
+ *
+ * Routines for generic manipulation of the interrupts found on the 
+ * AMAZON boards.
+ */
+
+#include <linux/init.h>
+#include <linux/sched.h>
+#include <linux/slab.h>
+#include <linux/interrupt.h>
+#include <linux/kernel_stat.h>
+#include <linux/module.h>
+
+#include <asm/amazon/amazon.h>
+#include <asm/amazon/irq.h>
+#include <asm/bootinfo.h>
+#include <asm/irq_cpu.h>
+#include <asm/irq.h>
+#include <asm/time.h>
+
+static void amazon_disable_irq(unsigned int irq_nr)
+{
+       /* have to access the correct register here */
+       if (irq_nr <= INT_NUM_IM0_IRL11 && irq_nr >= INT_NUM_IM0_IRL0)
+               /* access IM0 DMA channels */
+               *AMAZON_ICU_IM0_IER &= (~(AMAZON_DMA_H_MASK));
+       else if (irq_nr <= INT_NUM_IM0_IRL31 && irq_nr >= INT_NUM_IM0_IRL12)
+               /* access IM0 except DMA*/
+               *AMAZON_ICU_IM0_IER &= (~AMAZON_ICU_IM0_IER_IR(irq_nr));
+       else if (irq_nr <= INT_NUM_IM1_IRL31 && irq_nr >= INT_NUM_IM1_IRL0)
+               /* access IM1 */
+               *AMAZON_ICU_IM1_IER &= (~AMAZON_ICU_IM1_IER_IR(irq_nr - INT_NUM_IM1_IRL0));
+       else if (irq_nr <= INT_NUM_IM2_IRL31 && irq_nr >= INT_NUM_IM2_IRL0)
+               /* access IM2 */
+               *AMAZON_ICU_IM2_IER &= (~AMAZON_ICU_IM2_IER_IR(irq_nr - INT_NUM_IM2_IRL0));
+       else if (irq_nr <= INT_NUM_IM3_IRL31 && irq_nr >= INT_NUM_IM3_IRL0)
+               /* access IM3 */
+               *AMAZON_ICU_IM3_IER &= (~AMAZON_ICU_IM3_IER_IR((irq_nr - INT_NUM_IM3_IRL0)));
+       else if (irq_nr <= INT_NUM_IM4_IRL31 && irq_nr >= INT_NUM_IM4_IRL0)
+               /* access IM4 */
+               *AMAZON_ICU_IM4_IER &= (~AMAZON_ICU_IM4_IER_IR((irq_nr - INT_NUM_IM4_IRL0)));
+}
+
+static void amazon_mask_and_ack_irq(unsigned int irq_nr)
+{
+       /* have to access the correct register here */
+       if (irq_nr <= INT_NUM_IM0_IRL11 && irq_nr >= INT_NUM_IM0_IRL0) {
+               /* access IM0 DMA channels */
+               *AMAZON_ICU_IM0_IER &= (~(AMAZON_DMA_H_MASK)); /* mask */
+               *AMAZON_ICU_IM0_ISR = AMAZON_DMA_H_MASK; /* ack */
+       } else if (irq_nr <= INT_NUM_IM0_IRL31 && irq_nr >= INT_NUM_IM0_IRL12) {
+               /* access IM0 except DMA */
+               *AMAZON_ICU_IM0_IER &= ~AMAZON_ICU_IM0_IER_IR(irq_nr - INT_NUM_IM0_IRL0); /* mask */
+               *AMAZON_ICU_IM0_ISR = AMAZON_ICU_IM0_ISR_IR(irq_nr - INT_NUM_IM0_IRL0); /* ack */
+       } else if (irq_nr <= INT_NUM_IM1_IRL31 && irq_nr >= INT_NUM_IM1_IRL0) {
+               /* access IM1 */
+               *AMAZON_ICU_IM1_IER &= ~AMAZON_ICU_IM1_IER_IR(irq_nr - INT_NUM_IM1_IRL0); /* mask */
+               *AMAZON_ICU_IM1_ISR = AMAZON_ICU_IM1_ISR_IR(irq_nr - INT_NUM_IM1_IRL0); /* ack */
+       } else if (irq_nr <= INT_NUM_IM2_IRL31 && irq_nr >= INT_NUM_IM2_IRL0) {
+               /* access IM2 */
+               *AMAZON_ICU_IM2_IER &= ~AMAZON_ICU_IM2_IER_IR(irq_nr - INT_NUM_IM2_IRL0); /* mask */
+               *AMAZON_ICU_IM2_ISR = AMAZON_ICU_IM2_ISR_IR(irq_nr - INT_NUM_IM2_IRL0); /* ack */
+       } else if (irq_nr <= INT_NUM_IM3_IRL31 && irq_nr >= INT_NUM_IM3_IRL0) {
+               /* access IM3 */
+               *AMAZON_ICU_IM3_IER &= ~AMAZON_ICU_IM3_IER_IR(irq_nr - INT_NUM_IM3_IRL0); /* mask */
+               *AMAZON_ICU_IM3_ISR = AMAZON_ICU_IM3_ISR_IR(irq_nr - INT_NUM_IM3_IRL0); /* ack */
+       } else if (irq_nr <= INT_NUM_IM4_IRL31 && irq_nr >= INT_NUM_IM4_IRL0) {
+               *AMAZON_ICU_IM4_IER &= ~AMAZON_ICU_IM4_IER_IR(irq_nr - INT_NUM_IM4_IRL0); /* mask */
+               *AMAZON_ICU_IM4_ISR = AMAZON_ICU_IM4_ISR_IR(irq_nr - INT_NUM_IM4_IRL0); /* ack */
+       }
+}
+
+static void amazon_enable_irq(unsigned int irq_nr)
+{
+       /* have to access the correct register here */
+       if (irq_nr <= INT_NUM_IM0_IRL11 && irq_nr >= INT_NUM_IM0_IRL0)
+               /* access IM0 DMA*/
+               *AMAZON_ICU_IM0_IER |= AMAZON_DMA_H_MASK;
+       else if (irq_nr <= INT_NUM_IM0_IRL31 && irq_nr >= INT_NUM_IM0_IRL12)
+               /* access IM0 except DMA*/
+               *AMAZON_ICU_IM0_IER |= AMAZON_ICU_IM0_IER_IR(irq_nr - INT_NUM_IM0_IRL0);
+       else if (irq_nr <= INT_NUM_IM1_IRL31 && irq_nr >= INT_NUM_IM1_IRL0)
+               /* access IM1 */
+               *AMAZON_ICU_IM1_IER |= AMAZON_ICU_IM1_IER_IR(irq_nr - INT_NUM_IM1_IRL0);
+       else if (irq_nr <= INT_NUM_IM2_IRL31 && irq_nr >= INT_NUM_IM2_IRL0)
+               /* access IM2 */
+               *AMAZON_ICU_IM2_IER |= AMAZON_ICU_IM2_IER_IR(irq_nr - INT_NUM_IM2_IRL0);
+       else if (irq_nr <= INT_NUM_IM3_IRL31 && irq_nr >= INT_NUM_IM3_IRL0)
+               /* access IM3 */
+               *AMAZON_ICU_IM3_IER |= AMAZON_ICU_IM3_IER_IR((irq_nr - INT_NUM_IM3_IRL0));
+       else if (irq_nr <= INT_NUM_IM4_IRL31 && irq_nr >= INT_NUM_IM4_IRL0)
+               /* access IM4 */
+               *AMAZON_ICU_IM4_IER |= AMAZON_ICU_IM4_IER_IR((irq_nr - INT_NUM_IM4_IRL0));
+}
+
+static unsigned int amazon_startup_irq(unsigned int irq)
+{
+       amazon_enable_irq(irq);
+       return 0;
+}
+
+static void amazon_end_irq(unsigned int irq)
+{
+       if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS))) {
+               amazon_enable_irq(irq);
+       }
+}
+
+static struct hw_interrupt_type amazon_irq_type = {
+       "AMAZON",
+       .startup = amazon_startup_irq,
+       .enable = amazon_enable_irq,
+       .disable = amazon_disable_irq,
+       .unmask = amazon_enable_irq,
+       .ack = amazon_mask_and_ack_irq,
+       .mask = amazon_disable_irq,
+       .mask_ack = amazon_mask_and_ack_irq,
+       .end = amazon_end_irq
+};
+
+/* Cascaded interrupts from IM0 */
+static inline void amazon_hw0_irqdispatch(void)
+{
+       u32 irq;
+                                                                                                                                                                                                
+       irq = (*AMAZON_ICU_IM_VEC) & AMAZON_ICU_IM0_VEC_MASK;
+       if (irq <= 11 && irq >= 0) {
+               //DMA fixed to IM0_IRL0
+               irq = 0;
+       }
+       do_IRQ(irq + INT_NUM_IM0_IRL0);
+}
+                                                                                                         
+/* Cascaded interrupts from IM1 */
+static inline void amazon_hw1_irqdispatch(void)
+{
+       u32 irq;
+
+       irq = ((*AMAZON_ICU_IM_VEC) & AMAZON_ICU_IM1_VEC_MASK) >> 5;
+       do_IRQ(irq + INT_NUM_IM1_IRL0);
+}
+
+/* Cascaded interrupts from IM2 */
+static inline void amazon_hw2_irqdispatch(void)
+{
+       u32 irq;
+                                                                                                                                                                                                
+       irq = ((*AMAZON_ICU_IM_VEC) & AMAZON_ICU_IM2_VEC_MASK) >> 10;
+       do_IRQ(irq + INT_NUM_IM2_IRL0);
+}
+
+/* Cascaded interrupts from IM3 */
+static inline void amazon_hw3_irqdispatch(void)
+{
+       u32 irq;
+
+       irq = ((*AMAZON_ICU_IM_VEC) & AMAZON_ICU_IM3_VEC_MASK) >> 15;
+       do_IRQ(irq + INT_NUM_IM3_IRL0);
+}
+
+/* Cascaded interrupts from IM4 */
+static inline void amazon_hw4_irqdispatch(void)
+{
+       u32 irq;
+
+       irq = ((*AMAZON_ICU_IM_VEC) & AMAZON_ICU_IM4_VEC_MASK) >> 20;
+       do_IRQ(irq + INT_NUM_IM4_IRL0);
+}
+
+asmlinkage void plat_irq_dispatch(void)
+{
+       unsigned int pending = read_c0_status() & read_c0_cause() & ST0_IM;
+       if (pending & CAUSEF_IP7){
+               do_IRQ(MIPS_CPU_TIMER_IRQ);
+       }
+       else if (pending & CAUSEF_IP2)
+               amazon_hw0_irqdispatch();
+       else if (pending & CAUSEF_IP3)
+               amazon_hw1_irqdispatch();
+       else if (pending & CAUSEF_IP4)
+               amazon_hw2_irqdispatch();
+       else if (pending & CAUSEF_IP5)
+               amazon_hw3_irqdispatch();
+       else if (pending & CAUSEF_IP6)
+               amazon_hw4_irqdispatch();
+       else
+               printk("Spurious IRQ: CAUSE=0x%08x\n", read_c0_status());
+}
+
+static struct irqaction cascade = {
+       .handler        = no_action,
+       .flags          = SA_INTERRUPT,
+       .name           = "cascade",
+};
+
+
+/* Function for careful CP0 interrupt mask access */
+
+void __init arch_init_irq(void)
+{
+       int i;
+
+       /* mask all interrupt sources */
+       *AMAZON_ICU_IM0_IER = 0;
+       *AMAZON_ICU_IM1_IER = 0;
+       *AMAZON_ICU_IM2_IER = 0;
+       *AMAZON_ICU_IM3_IER = 0;
+       *AMAZON_ICU_IM4_IER = 0;
+
+       mips_cpu_irq_init();
+
+       /* set up irq cascade */
+       for (i = 2; i <= 6; i++) {
+               setup_irq(i, &cascade);
+       }
+
+       for (i = INT_NUM_IRQ0; i <= INT_NUM_IM4_IRL31; i++) {
+               irq_desc[i].status      = IRQ_DISABLED;
+               irq_desc[i].action      = 0;
+               irq_desc[i].depth       = 1;
+               set_irq_chip(i, &amazon_irq_type);
+       }
+}
diff --git a/target/linux/amazon-2.6/files/arch/mips/amazon/pci.c b/target/linux/amazon-2.6/files/arch/mips/amazon/pci.c
new file mode 100644 (file)
index 0000000..ab305a9
--- /dev/null
@@ -0,0 +1,293 @@
+/*
+ *  Carsten Langgaard, carstenl@mips.com
+ *  Copyright (C) 1999, 2000 MIPS Technologies, Inc.  All rights reserved.
+ *  Copyright (C) 2007 Felix Fietkau <nbd@openwrt.org>
+ *
+ *  This program is free software; you can distribute it and/or modify it
+ *  under the terms of the GNU General Public License (Version 2) as
+ *  published by the Free Software Foundation.
+ *
+ *  This program is distributed in the hope it will be useful, but WITHOUT
+ *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ *  for more details.
+ *
+ *  You should have received a copy of the GNU General Public License along
+ *  with this program; if not, write to the Free Software Foundation, Inc.,
+ *  59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
+ */
+
+/* FIXME: convert nasty volatile register derefs to readl/writel calls */
+
+#include <linux/types.h>
+#include <linux/pci.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/delay.h>
+#include <asm/io.h>
+#include <asm/paccess.h>
+#include <asm/amazon/irq.h>
+#include <asm/amazon/amazon.h>
+
+#define AMAZON_PCI_REG32( addr )                 (*(volatile u32 *)(addr))
+#ifndef AMAZON_PCI_MEM_BASE
+#define AMAZON_PCI_MEM_BASE    0xb2000000
+#endif
+#define AMAZON_PCI_MEM_SIZE    0x00400000
+#define AMAZON_PCI_IO_BASE     0xb2400000
+#define AMAZON_PCI_IO_SIZE     0x00002000
+
+#define AMAZON_PCI_CFG_BUSNUM_SHF 16
+#define AMAZON_PCI_CFG_DEVNUM_SHF 11
+#define AMAZON_PCI_CFG_FUNNUM_SHF 8
+
+#define PCI_ACCESS_READ  0
+#define PCI_ACCESS_WRITE 1
+
+static inline u32 amazon_r32(u32 addr)
+{
+       u32 *ptr = (u32 *) addr;
+       return __raw_readl(ptr);
+}
+
+static inline void amazon_w32(u32 addr, u32 val)
+{
+       u32 *ptr = (u32 *) addr;
+       __raw_writel(val, ptr);
+}
+
+
+static struct resource pci_io_resource = {
+       .name = "io pci IO space",
+#if 0
+       .start = AMAZON_PCI_IO_BASE,
+       .end = AMAZON_PCI_IO_BASE + AMAZON_PCI_IO_SIZE - 1,
+#endif
+       .start = 0,
+       .end = AMAZON_PCI_IO_SIZE - 1,
+       .flags = IORESOURCE_IO
+};
+
+static struct resource pci_mem_resource = {
+       .name = "ext pci memory space",
+       .start = AMAZON_PCI_MEM_BASE,
+       .end = AMAZON_PCI_MEM_BASE + AMAZON_PCI_MEM_SIZE - 1,
+       .flags = IORESOURCE_MEM
+};
+
+static inline u32 amazon_pci_swap(u32 val)
+{
+#ifdef CONFIG_AMAZON_PCI_HW_SWAP
+       return swab32(val);
+#else
+       return val;
+#endif
+}
+
+static int amazon_pci_config_access(unsigned char access_type,
+       struct pci_bus *bus, unsigned int devfn, unsigned int where, u32 *data)
+{
+       unsigned long flags;
+       u32 pci_addr;
+       u32 val;
+       int ret;
+   
+       /* Amazon support slot from 0 to 15 */
+       /* devfn 0 & 0x20 is itself */
+       if ((bus != 0) || (devfn == 0) || (devfn == 0x20))
+               return 1;
+
+       pci_addr=AMAZON_PCI_CFG_BASE |
+               bus->number << AMAZON_PCI_CFG_BUSNUM_SHF |
+               devfn << AMAZON_PCI_CFG_FUNNUM_SHF |
+               (where & ~0x3);
+    
+       local_irq_save(flags);
+       if (access_type == PCI_ACCESS_WRITE) {
+               val = amazon_pci_swap(*data);
+               ret = put_dbe(val, (u32 *)pci_addr);
+       } else {
+               ret = get_dbe(val, (u32 *)pci_addr);
+               *data = amazon_pci_swap(val);
+       }
+
+       amazon_w32(PCI_MODE, amazon_r32(PCI_MODE) & (~(1<<PCI_MODE_cfgok_bit)));
+       amazon_w32(STATUS_COMMAND_ADDR, amazon_r32(STATUS_COMMAND_ADDR));
+       amazon_w32(PCI_MODE, amazon_r32(PCI_MODE) | (~(1<<PCI_MODE_cfgok_bit)));
+       local_irq_restore(flags);
+
+       return ret; 
+}
+
+
+static int amazon_pci_read(struct pci_bus *bus, unsigned int devfn, int where, int size, u32 *val)
+{
+       u32 data = 0;
+       int ret = PCIBIOS_SUCCESSFUL;
+
+       if (amazon_pci_config_access(PCI_ACCESS_READ, bus, devfn, where, &data)) {
+               data = ~0;
+               ret = -1;
+       }
+
+       switch (size) {
+               case 1:
+                       *((u8 *) val) = (data >> ((where & 3) << 3)) & 0xff;
+                       break;
+               case 2:
+                       *((u16 *) val) = (data >> ((where & 3) << 3)) & 0xffff;
+                       break;
+               case 4:
+                       *val = data;
+                       break;
+               default:
+                       return -1;
+       }
+
+       return ret;
+}
+
+
+static int amazon_pci_write(struct pci_bus *bus, unsigned int devfn, int where, int size, u32 val)
+{
+       if (size != 4) {
+               u32 data;
+
+               if (amazon_pci_config_access(PCI_ACCESS_READ, bus, devfn, where, &data))
+                       return -1;
+
+               if (size == 1)
+                       val = (data & ~(0xff << ((where & 3) << 3))) | (val << ((where & 3) << 3));
+               else if (size == 2)
+                       val = (data & ~(0xffff << ((where & 3) << 3))) | (val << ((where & 3) << 3));
+               else
+                       return -1;
+       }
+
+       if (amazon_pci_config_access(PCI_ACCESS_WRITE, bus, devfn, where, &val))
+              return -1;
+
+       return PCIBIOS_SUCCESSFUL;
+}
+
+static struct pci_ops amazon_pci_ops = {
+       amazon_pci_read,
+       amazon_pci_write
+};
+
+static struct pci_controller amazon_pci_controller = {
+       .pci_ops = &amazon_pci_ops,
+       .mem_resource = &pci_mem_resource,
+       .io_resource = &pci_io_resource
+};
+
+int __init pcibios_map_irq(struct pci_dev *dev, u8 slot, u8 pin)
+{
+       switch (slot) {
+               case 13:
+                       /* IDSEL = AD29 --> USB Host Controller */
+                       return INT_NUM_IM2_IRL15;
+               case 14:
+                       /* IDSEL = AD30 --> mini PCI connector */
+                       return INT_NUM_IM2_IRL14;
+               default:
+                       printk("Warning: no IRQ found for PCI device in slot %d, pin %d\n", slot, pin);
+                       return 0;
+       }
+}
+
+int pcibios_plat_dev_init(struct pci_dev *dev)
+{
+       switch(dev->irq) {
+               case INT_NUM_IM2_IRL15:
+                       /* 
+                        * IDSEL = AD29 --> USB Host Controller
+                        * PCI_INTA/B/C--GPIO Port0.2--EXIN3
+                        * IN/ALT0:1 ALT1:0
+                        * PULL UP
+                        */
+                       (*AMAZON_GPIO_P0_DIR) = (*AMAZON_GPIO_P0_DIR) & 0xfffffffb;
+                       (*AMAZON_GPIO_P0_ALTSEL0) = (*AMAZON_GPIO_P0_ALTSEL0)| 4;
+                       (*AMAZON_GPIO_P0_ALTSEL1) = (*AMAZON_GPIO_P0_ALTSEL1)& 0xfffffffb;
+                       (*AMAZON_GPIO_P0_PUDSEL) =  (*AMAZON_GPIO_P0_PUDSEL) | 4;
+                       (*AMAZON_GPIO_P0_PUDEN) = (*AMAZON_GPIO_P0_PUDEN) | 4;
+                       //External Interrupt Node
+                       (*AMAZON_ICU_EXTINTCR) = (*AMAZON_ICU_EXTINTCR)|0x6000; /* Low Level triggered */
+                       (*AMAZON_ICU_IRNEN) = (*AMAZON_ICU_IRNEN)|0x8;
+                       pci_write_config_byte(dev, PCI_INTERRUPT_LINE, dev->irq);
+                       break;
+               case INT_NUM_IM2_IRL14:
+                       /* 
+                        * IDSEL = AD30 --> mini PCI connector 
+                        * PCI_INTA--GPIO Port0.1--EXIN2
+                        * IN/ALT0:1 ALT1:0
+                        * PULL UP
+                        */
+                       (*AMAZON_GPIO_P0_DIR) = (*AMAZON_GPIO_P0_DIR) & 0xfffffffd;
+                       (*AMAZON_GPIO_P0_ALTSEL0) = (*AMAZON_GPIO_P0_ALTSEL0)| 2;
+                       (*AMAZON_GPIO_P0_ALTSEL1) = (*AMAZON_GPIO_P0_ALTSEL1)& 0xfffffffd;
+                       (*AMAZON_GPIO_P0_PUDSEL) =  (*AMAZON_GPIO_P0_PUDSEL) | 2;
+                       (*AMAZON_GPIO_P0_PUDEN) = (*AMAZON_GPIO_P0_PUDEN) | 2;
+                       //External Interrupt Node
+                       (*AMAZON_ICU_EXTINTCR) = (*AMAZON_ICU_EXTINTCR)|0x600;
+                       (*AMAZON_ICU_IRNEN) = (*AMAZON_ICU_IRNEN)|0x4;
+                       pci_write_config_byte(dev, PCI_INTERRUPT_LINE, dev->irq);
+                       break;
+               default:
+                       return 1;
+       }
+       return 0;
+}
+
+int amazon_pci_init(void)
+{
+       u32 temp_buffer;
+
+#ifdef CONFIG_AMAZON_PCI_HW_SWAP
+       AMAZON_PCI_REG32(IRM) = AMAZON_PCI_REG32(IRM) | (1<<27) | (1<<28);
+       wmb();
+#endif
+
+       AMAZON_PCI_REG32(CLOCK_CONTROL) = AMAZON_PCI_REG32(CLOCK_CONTROL) | (1<<ARB_CTRL_bit);
+       amazon_w32(PCI_MODE, amazon_r32(PCI_MODE) & (~(1<<PCI_MODE_cfgok_bit)));
+
+       AMAZON_PCI_REG32(STATUS_COMMAND_ADDR) = AMAZON_PCI_REG32(STATUS_COMMAND_ADDR) | (1<<BUS_MASTER_ENABLE_BIT) |(1<<MEM_SPACE_ENABLE_BIT);
+
+       temp_buffer = AMAZON_PCI_REG32(PCI_ARB_CTRL_STATUS_ADDR);
+       temp_buffer = temp_buffer | (1<< INTERNAL_ARB_ENABLE_BIT);
+       temp_buffer = temp_buffer & ~(3<< PCI_MASTER0_REQ_MASK_2BITS);
+       temp_buffer = temp_buffer & ~(3<< PCI_MASTER0_GNT_MASK_2BITS);
+
+       /* flash */
+       temp_buffer = temp_buffer & ~(3<< PCI_MASTER1_REQ_MASK_2BITS);
+       temp_buffer = temp_buffer & ~(3<< PCI_MASTER1_GNT_MASK_2BITS);
+
+       /* external master */
+       temp_buffer = temp_buffer & ~(3<< PCI_MASTER2_REQ_MASK_2BITS);
+       temp_buffer = temp_buffer & ~(3<< PCI_MASTER2_GNT_MASK_2BITS);
+
+       AMAZON_PCI_REG32(PCI_ARB_CTRL_STATUS_ADDR) = temp_buffer;
+       wmb();
+
+       AMAZON_PCI_REG32(FPI_ADDRESS_MAP_0) = 0xb2000000;
+       AMAZON_PCI_REG32(FPI_ADDRESS_MAP_1) = 0xb2100000;
+       AMAZON_PCI_REG32(FPI_ADDRESS_MAP_2) = 0xb2200000;
+       AMAZON_PCI_REG32(FPI_ADDRESS_MAP_3) = 0xb2300000;
+       AMAZON_PCI_REG32(FPI_ADDRESS_MAP_4) = 0xb2400000;
+       AMAZON_PCI_REG32(FPI_ADDRESS_MAP_5) = 0xb2500000;
+       AMAZON_PCI_REG32(FPI_ADDRESS_MAP_6) = 0xb2600000;
+       AMAZON_PCI_REG32(FPI_ADDRESS_MAP_7) = 0xb2700000;
+          
+       AMAZON_PCI_REG32(BAR11_MASK) = 0x0f000008;
+       AMAZON_PCI_REG32(PCI_ADDRESS_MAP_11) = 0x0;
+       AMAZON_PCI_REG32(BAR1_ADDR) = 0x0;
+       amazon_w32(PCI_MODE, amazon_r32(PCI_MODE) | (~(1<<PCI_MODE_cfgok_bit)));
+       //use 8 dw burse length
+       AMAZON_PCI_REG32(FPI_BURST_LENGTH) = 0x303;
+
+       set_io_port_base(ioremap(AMAZON_PCI_IO_BASE, AMAZON_PCI_IO_SIZE));
+       register_pci_controller(&amazon_pci_controller);
+       return 0;
+}
+arch_initcall(amazon_pci_init);
diff --git a/target/linux/amazon-2.6/files/arch/mips/amazon/prom.c b/target/linux/amazon-2.6/files/arch/mips/amazon/prom.c
new file mode 100644 (file)
index 0000000..d60c3fa
--- /dev/null
@@ -0,0 +1,61 @@
+/*
+ * copyright 2007 john crispin <blogic@openwrt.org> 
+ */
+#include <linux/init.h>
+#include <linux/string.h>
+#include <linux/ctype.h>
+#include <linux/kernel.h>
+#include <linux/mm.h>
+#include <linux/bootmem.h>
+#include <linux/ioport.h>
+#include <asm/bootinfo.h>
+#include <asm/amazon/amazon.h>
+#include <asm/amazon/irq.h>
+#include <asm/amazon/model.h>
+#include <asm/cpu.h>
+
+void prom_putchar(char c)
+{
+       /* Wait for FIFO to empty */
+       while (((*AMAZON_ASC_FSTAT) >> 8) != 0x00) ;
+       /* Crude cr/nl handling is better than none */
+       if(c == '\n')
+               *AMAZON_ASC_TBUF=('\r');
+       *AMAZON_ASC_TBUF=(c);
+}
+
+void prom_printf(const char * fmt, ...)
+{
+       va_list args;
+       int l;
+       char *p, *buf_end;
+       char buf[1024]; 
+
+       va_start(args, fmt);
+       l = vsprintf(buf, fmt, args); /* hopefully i < sizeof(buf) */
+       va_end(args);
+       buf_end = buf + l;
+       
+       for (p = buf; p < buf_end; p++)
+               prom_putchar(*p);
+}
+
+
+void __init prom_init(void)
+{
+       mips_machgroup = MACH_GROUP_INFINEON;
+       mips_machtype = MACH_INFINEON_AMAZON;
+
+       strcpy(&(arcs_cmdline[0]), "console=ttyS0,115200 rootfstype=squashfs,jffs2 init=/etc/preinit");
+       
+       add_memory_region(0x00000000, 0x1000000, BOOT_MEM_RAM);
+}
+
+void prom_free_prom_memory(void)
+{
+}
+
+const char *get_system_type(void)
+{
+       return BOARD_SYSTEM_TYPE;
+}
diff --git a/target/linux/amazon-2.6/files/arch/mips/amazon/setup.c b/target/linux/amazon-2.6/files/arch/mips/amazon/setup.c
new file mode 100644 (file)
index 0000000..4cd3b9b
--- /dev/null
@@ -0,0 +1,216 @@
+/*
+ *      Copyright (C) 2004 Peng Liu <peng.liu@infineon.com>
+ *      Copyright (C) 2007 John Crispin <blogic@openwrt.org>
+ *      Copyright (C) 2007 Felix Fietkau <nbd@openwrt.org>
+ *      
+ *   This program is free software; you can redistribute it and/or modify
+ *   it under the terms of the GNU General Public License as published by
+ *   the Free Software Foundation; either version 2 of the License, or
+ *   (at your option) any later version.
+ *
+ *   This program is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with this program; if not, write to the Free Software
+ *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
+ *
+ */
+#include <linux/init.h>
+#include <linux/sched.h>
+#include <linux/module.h>
+#include <linux/interrupt.h>
+#include <linux/delay.h>
+
+#include <asm/reboot.h>
+#include <asm/system.h>
+#include <asm/time.h>
+#include <asm/cpu.h>
+#include <asm/bootinfo.h>
+#include <asm/irq.h>
+#include <asm/mipsregs.h>
+#include <asm/amazon/amazon.h>
+#include <asm/amazon/irq.h>
+#include <asm/amazon/model.h>
+
+extern void prom_printf(const char * fmt, ...);
+static void amazon_reboot_setup(void);
+
+/* the CPU clock rate - lifted from u-boot */
+unsigned int amazon_get_cpu_hz(void)
+{
+       /*-----------------------------------*/
+       /**CGU CPU Clock Reduction Register***/ 
+       /*-----------------------------------*/
+       switch((*AMAZON_CGU_CPUCRD) & 0x3){
+               case 0:
+                       /*divider ration 1/1, 235 MHz clock */
+                       return 235000000;
+               case 1:
+                       /*divider ration 2/3, 235 MHz clock, clock not accurate, here */
+                       return 150000000;
+               case 2:
+                       /*divider ration 1/2, 235 MHz clock */
+                       return 117500000;
+               default:
+                       /*divider ration 1/4, 235 MHz clock */
+                       return 58750000;
+       }
+}
+
+/* the FPI clock rate - lifted from u-boot */
+unsigned int amazon_get_fpi_hz(void)
+{
+       unsigned int  clkCPU;
+       clkCPU = amazon_get_cpu_hz();
+
+       /*-------------------------------------*/
+       /***CGU Clock Divider Select Register***/
+       /*-------------------------------------*/
+       switch ((*AMAZON_CGU_DIV) & 0x3)
+       {
+               case 1:
+                       return clkCPU >> 1;
+               case 2:
+                       return clkCPU >> 2;
+               default:
+                       return clkCPU;
+               /* '11' is reserved */
+       }
+}
+
+/* get the CPU version number  - based on sysLib.c from VxWorks sources */
+/* this doesn't really belong here, but it's a convenient location */
+unsigned int amazon_get_cpu_ver(void)
+{
+       static unsigned int cpu_ver = 0;
+       if (cpu_ver == 0)
+               cpu_ver = *AMAZON_MCD_CHIPID & 0xFFFFF000;
+       return cpu_ver;
+}
+
+void amazon_time_init(void)
+{
+       mips_hpt_frequency = amazon_get_cpu_hz()/2;
+       printk("mips_hpt_frequency:%d\n",mips_hpt_frequency);
+}
+
+extern int hr_time_resolution;
+
+/* ISR GPTU Timer 6 for high resolution timer */
+static void amazon_timer6_interrupt(int irq, void *dev_id)
+{
+       timer_interrupt(AMAZON_TIMER6_INT, NULL);
+}
+
+static struct irqaction hrt_irqaction = {
+       .handler = amazon_timer6_interrupt,
+       .flags = SA_INTERRUPT,
+       .name = "hrt",
+};
+
+/*
+ * THe CPU counter for System timer, set to HZ
+ * GPTU Timer 6 for high resolution timer, set to hr_time_resolution
+ * Also misuse this routine to print out the CPU type and clock.
+ */
+void __init plat_timer_setup(struct irqaction *irq)
+{
+       /* cpu counter for timer interrupts */
+       setup_irq(MIPS_CPU_TIMER_IRQ, irq);
+
+#if 0
+       /* to generate the first CPU timer interrupt */
+       write_c0_compare(read_c0_count() + amazon_get_cpu_hz()/(2*HZ));
+#endif
+
+       /* enable the timer in the PMU */
+       *(AMAZON_PMU_PWDCR) = (*(AMAZON_PMU_PWDCR))| AMAZON_PMU_PWDCR_GPT|AMAZON_PMU_PWDCR_FPI;
+       /* setup the GPTU for timer tick  f_fpi == f_gptu*/
+       *(AMAZON_GPTU_CLC) = 0x100;
+
+       *(AMAZON_GPTU_CAPREL) = 0xffff;
+       *(AMAZON_GPTU_T6CON) = 0x80C0;
+       //setup_irq(AMAZON_TIMER6_INT,&hrt_irqaction);
+
+#if 0
+#ifdef CONFIG_HIGH_RES_TIMERS
+       /* GPTU timer 6 */
+       int retval;
+       if ( hr_time_resolution > 200000000 || hr_time_resolution < 40) {
+               prom_printf("hr_time_resolution is out of range, HIGH_RES_TIMER is diabled.\n");
+               return;
+       }
+       
+       /* enable the timer in the PMU */
+        *(AMAZON_PMU_PWDCR) = (*(AMAZON_PMU_PWDCR))| AMAZON_PMU_PWDCR_GPT|AMAZON_PMU_PWDCR_FPI;
+       /* setup the GPTU for timer tick  f_fpi == f_gptu*/
+       *(AMAZON_GPTU_CLC) = 0x100;
+
+       *(AMAZON_GPTU_CAPREL) = 0xffff;
+       *(AMAZON_GPTU_T6CON) = 0x80C0;
+       
+       retval = setup_irq(AMAZON_TIMER6_INT,&hrt_irqaction);
+       if (retval){
+               prom_printf("reqeust_irq failed %d. HIGH_RES_TIMER is diabled\n",AMAZON_TIMER6_INT);            
+       }
+#endif //CONFIG_HIGH_RES_TIMERS                
+#endif
+}
+
+void __init plat_mem_setup(void)
+{      
+       u32 chipid = 0;
+       u32 part_no = 0;
+       
+       chipid = *(AMAZON_MCD_CHIPID);
+       part_no = AMAZON_MCD_CHIPID_PART_NUMBER_GET(chipid);
+       
+       if(part_no == AMAZON_CHIPID_YANGTSE){
+               prom_printf("Yangtse Version\n");       
+       } else if (part_no == AMAZON_CHIPID_STANDARD) {
+               prom_printf(SYSTEM_MODEL_NAME "\n");
+       } else {
+               prom_printf("unknown version %8x\n",part_no);
+       }
+       
+       amazon_reboot_setup();
+       board_time_init = amazon_time_init;
+
+       //stop reset TPE and DFE
+       *(AMAZON_RST_REQ) = 0x0;
+       //clock
+       *(AMAZON_PMU_PWDCR) = 0x3fff;
+       //reenable trace capability
+       part_no = *(AMAZON_BCU_ECON);
+}
+
+static void amazon_machine_restart(char *command)
+{
+    local_irq_disable();
+    *AMAZON_RST_REQ = AMAZON_RST_ALL;
+    for (;;) ;
+}
+
+static void amazon_machine_halt(void)
+{
+    printk(KERN_NOTICE "System halted.\n");
+    local_irq_disable();
+    for (;;) ;
+}
+
+static void amazon_machine_power_off(void)
+{
+       printk(KERN_NOTICE "Please turn off the power now.\n");
+    local_irq_disable();
+    for (;;) ;
+}
+
+static void amazon_reboot_setup(void)
+{
+       _machine_restart = amazon_machine_restart;
+       _machine_halt = amazon_machine_halt;
+       pm_power_off = amazon_machine_power_off;
+}
diff --git a/target/linux/amazon-2.6/files/drivers/atm/amazon_tpe.c b/target/linux/amazon-2.6/files/drivers/atm/amazon_tpe.c
new file mode 100644 (file)
index 0000000..cf3e407
--- /dev/null
@@ -0,0 +1,3074 @@
+/*
+ *   This program is free software; you can redistribute it and/or modify
+ *   it under the terms of the GNU General Public License as published by
+ *   the Free Software Foundation; either version 2 of the License, or
+ *   (at your option) any later version.
+ *
+ *   This program is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with this program; if not, write to the Free Software
+ *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
+ */
+//-----------------------------------------------------------------------
+/*
+ * Description:
+ *     Driver for Infineon Amazon TPE
+ */
+//-----------------------------------------------------------------------
+/* Author:     peng.liu@infineon.com
+ * Created:    12-April-2004
+ */
+//-----------------------------------------------------------------------
+/* History
+ * Last changed on: 13 Oct. 2004
+ * Last changed by: peng.liu@infineon.com
+ * Last changed on: 28 Jan. 2004
+ * Last changed by: peng.liu@infineon.com
+ * Last changed Reason:
+ *     - AAL5R may send more bytes than expected in MFL (so far, confirmed as 64 bytes)
+ */
+// 507261:tc.chen 2005/07/26 re-organize code address map to improve performance.
+// 507281:tc.chen 2005/07/28 fix f4 segment isssue
+/* 511045:linmars 2005/11/04 from Liu.Peng: change NRT_VBR bandwidth calculation based on scr instead of pcr */
+#ifndef __KERNEL__
+#define __KERNEL__
+#endif 
+#ifndef EXPORT_SYMTAB
+#define EXPORT_SYMTAB
+#endif
+
+/*TPE level loopback, bypass AWARE DFE */
+#undef TPE_LOOPBACK
+
+/* enable debug options */                     
+#undef AMAZON_ATM_DEBUG
+
+/* enable rx error packet analysis */
+#undef AMAZON_ATM_DEBUG_RX
+
+/* test AAL5 Interrupt */
+#undef  AMAZON_TPE_TEST_AAL5_INT
+
+/* dump packet */
+#undef AMAZON_TPE_DUMP
+
+/* read ARC register*/
+/* this register is located in side DFE module*/
+#undef AMAZON_TPE_READ_ARC
+
+/* software controlled reassembly */
+#undef AMAZON_TPE_SCR
+
+/* recovery from AAL5 bug */
+#undef AMAZON_TPE_AAL5_RECOVERY
+
+#if defined(AMAZON_TPE_READ_ARC) || defined(AMAZON_TPE_AAL5_RECOVERY)
+#define ALPHAEUS_BASE_ADDR     0x31c00
+#define A_CFG_ADDR             (ALPHAEUS_BASE_ADDR+0x04)
+#define AR_CB0_STATUS_ADDR             (ALPHAEUS_BASE_ADDR+0x2c)
+#define AR_CB1_STATUS_ADDR             (ALPHAEUS_BASE_ADDR+0x30)
+#define AT_CELL0_ADDR          (ALPHAEUS_BASE_ADDR+0x90)
+#define AR_CELL0_ADDR          (ALPHAEUS_BASE_ADDR+0x1a0)
+#define AR_CD_CNT0_ADDR                (ALPHAEUS_BASE_ADDR+0x1c8)
+#endif
+
+#include <linux/module.h>
+#include <linux/config.h>
+#include <linux/init.h>
+#include <linux/kernel.h> 
+#include <linux/slab.h>  
+#include <linux/fs.h> 
+#include <linux/types.h>
+#include <linux/errno.h>  
+#include <linux/time.h>
+#include <linux/atm.h>
+#include <linux/atmdev.h>
+#include <linux/netdevice.h>
+#include <asm/byteorder.h>
+#include <asm/io.h>
+#include <asm/uaccess.h>
+#include <asm/system.h>
+#include <asm/atomic.h>
+#include <asm/bitops.h>
+#include <asm/system.h>
+
+#include <asm/amazon/amazon.h>
+#include <asm/amazon/irq.h>
+
+#include <linux/in.h>
+#include <linux/netdevice.h> 
+#include <linux/etherdevice.h> 
+#include <linux/ip.h>
+#include <linux/tcp.h> 
+#include <linux/skbuff.h>
+#include <linux/in6.h>
+#include <linux/delay.h>
+#include <asm/amazon/atm_defines.h>
+#include <asm/amazon/amazon_dma.h>
+#include <asm/amazon/amazon_tpe.h>
+
+#if defined(AMAZON_TPE_READ_ARC) || defined(AMAZON_TPE_AAL5_RECOVERY)
+#include <asm/amazon/amazon_mei.h>
+#include <asm/amazon/amazon_mei_app.h>
+#endif
+
+#define AMAZON_TPE_EMSG(fmt, args...) printk( KERN_ERR  "%s: " fmt,__FUNCTION__, ## args)
+
+/***************************************** External Functions *******************************************/
+extern unsigned int amazon_get_fpi_hz(void);
+extern void mask_and_ack_amazon_irq(unsigned int irq_nr);
+extern void amz_push_oam(unsigned char *);
+
+//amazon_mei.c
+#if defined(AMAZON_TPE_READ_ARC) || defined(AMAZON_TPE_AAL5_RECOVERY)
+extern MEI_ERROR meiDebugRead(u32 srcaddr, u32 *databuff, u32 databuffsize);
+extern MEI_ERROR meiDebugWrite(u32 destaddr, u32 *databuff, u32 databuffsize);
+#endif
+
+/***************************************** Internal Functions *******************************************/
+int amazon_atm_read_procmem(char *buf, char **start, off_t offset,int count, int *eof, void *data);
+/***************************************** Global Data *******************************************/
+amazon_atm_dev_t g_atm_dev;            //device data
+static struct tq_struct swex_start_task;       //BH task
+static struct tq_struct swex_complete_task;    //BH task
+#ifdef AMAZON_TPE_SCR
+static struct tq_struct a5r_task;              //BH task
+#endif
+static struct dma_device_info  g_dma_dev;      //for DMA
+static struct atm_dev * amazon_atm_devs[AMAZON_ATM_PORT_NUM];
+static struct oam_last_activity g_oam_time_stamp[AMAZON_ATM_MAX_VCC_NUM];
+static u8 g_oam_cell[AMAZON_AAL0_SDU+4];       //for OAM cells
+#ifdef AMAZON_CHECK_LINK
+static int adsl_link_status;                   //ADSL link status, 0:down, 1:up
+#endif //AMAZON_CHECK_LINK
+/***************************************** Module Parameters *************************************/
+// Parameter Definition for module
+static int port_enable0 = 1;                           // Variable for parameter port_enable0
+static int port_enable1 = 0;                           // Variable for parameter port_enable1
+static int port_max_conn0 = 15;                                // Variable for parameter port_max_conn0
+static int port_max_conn1 = 0;                         // Variable for parameter port_max_conn1
+static int port_cell_rate_up0 = 7500;                  // Variable for parameter port_cell_rate_up0
+static int port_cell_rate_up1 = 7500;                  // Variable for parameter port_cell_rate_up1
+
+
+static int qsb_tau = 1;                                        // Variable for parameter qsb_tau
+static int qsb_srvm = 0xf;                             // Variable for parameter qsb_srvm
+static int qsb_tstep = 4 ;                             // Variable for parameter qsb_tstep
+
+static int cbm_nrt = 3900;                             // Variable for parameter cbm_nrt
+static int cbm_clp0 =3500;                             // Variable for parameter cbm_clp0
+static int cbm_clp1 =3200;                             // Variable for parameter cbm_clp1
+static int cbm_free_cell_no = AMAZON_ATM_FREE_CELLS;   // Variable for parameter cbm_free_cell_no
+
+static int a5_fill_pattern = 0x7e;                     // Variable for parameter a5_fill_pattern '~'
+static int a5s_mtu = 0x700;                            // mtu for tx
+static int a5r_mtu = 0x700;                            // mtu for rx
+
+static int oam_q_threshold =   64;                     // oam queue threshold, minium value 64
+static int rx_q_threshold =    1000;                   // rx queue threshold, minium value 64
+static int tx_q_threshold =    800;                    // tx queue threshold, minium value 64
+
+MODULE_PARM(port_max_conn0, "i");
+MODULE_PARM_DESC(port_max_conn0, "Maximum atm connection for port #0");
+MODULE_PARM(port_max_conn1, "i");
+MODULE_PARM_DESC(port_max_conn1, "Maximum atm connection for port #1");
+MODULE_PARM(port_enable0, "i");
+MODULE_PARM_DESC(port_enable0, "0 -> port disabled, 1->port enabled");
+MODULE_PARM(port_enable1, "i");
+MODULE_PARM_DESC(port_enable1, "0 -> port disabled, 1->port enabled");
+MODULE_PARM(port_cell_rate_up0, "i");
+MODULE_PARM_DESC(port_cell_rate_up0, "ATM port upstream rate in cells/s");
+MODULE_PARM(port_cell_rate_up1, "i");
+MODULE_PARM_DESC(port_cell_rate_up1, "ATM port upstream rate in cells/s");
+
+MODULE_PARM(qsb_tau,"i");
+MODULE_PARM_DESC(qsb_tau, "Cell delay variation. value must be > 0");
+MODULE_PARM(qsb_srvm, "i");
+MODULE_PARM_DESC(qsb_srvm, "Maximum burst size");
+MODULE_PARM(qsb_tstep, "i");
+MODULE_PARM_DESC(qsb_tstep, "n*32 cycles per sbs cycles n=1,2,4");
+
+MODULE_PARM(cbm_nrt, "i");
+MODULE_PARM_DESC(cbm_nrt, "Non real time threshold for cell buffer");
+MODULE_PARM(cbm_clp0, "i");
+MODULE_PARM_DESC(cbm_clp0, "Threshold for cells with cell loss priority 0");
+MODULE_PARM(cbm_clp1, "i");
+MODULE_PARM_DESC(cbm_clp1, "Threshold for cells with cell loss priority 1");
+MODULE_PARM(cbm_free_cell_no, "i");
+MODULE_PARM_DESC(cbm_free_cell_no, "Number of cells in the cell buffer manager");
+
+MODULE_PARM(a5_fill_pattern, "i");
+MODULE_PARM_DESC(a5_fill_pattern, "filling pattern (PAD) for aal5 frames");
+MODULE_PARM(a5s_mtu, "i");
+MODULE_PARM_DESC(a5s_mtu, "max. SDU for upstream");
+MODULE_PARM(a5r_mtu, "i");
+MODULE_PARM_DESC(a5r_mtu, "max. SDU for downstream");                                                                               
+
+MODULE_PARM(oam_q_threshold, "i");
+MODULE_PARM_DESC(oam_q_threshold, "oam queue threshold");
+
+MODULE_PARM(rx_q_threshold, "i");
+MODULE_PARM_DESC(rx_q_threshold, "downstream/rx queue threshold");
+
+MODULE_PARM(tx_q_threshold, "i");
+MODULE_PARM_DESC(tx_q_threshold, "upstream/tx queue threshold");
+
+/***************************************** local functions *************************************/
+/* Brief: valid QID
+ * Return: 1 if valid
+ *        0 if not
+ */
+static inline int valid_qid(int qid)
+{
+       return ( (qid>0) && (qid<AMAZON_ATM_MAX_QUEUE_NUM));
+}
+
+/*
+ * Brief: align to 16 bytes boundary 
+ * Parameter:
+ *     skb
+ * Description:
+ *     use skb_reserve to adjust the data pointer
+ *     don't change head pointer
+ *     pls allocate extrac 16 bytes before call this function
+ */
+static void inline alloc_align_16(struct sk_buff * skb)
+{
+       if ( ( ((u32) (skb->data)) & 15) != 0){
+               AMAZON_TPE_DMSG("need to adjust the alignment manually\n");
+               skb_reserve(skb, 16 - (((u32) (skb->data)) & 15) );
+       }
+
+}
+
+/*
+ * Brief: initialize the device according to the module paramters
+ * Return: not NULL    -       ok
+ *        NULL         -       fails
+ * Description: arrange load parameters and call the hardware initialization routines
+ */
+static void atm_init_parameters(amazon_atm_dev_t *dev)
+{
+       //port setting
+       dev->ports[0].enable = port_enable0;
+       dev->ports[0].max_conn = port_max_conn0;
+       dev->ports[0].tx_max_cr = port_cell_rate_up0;
+       if (port_enable1){
+               dev->ports[1].enable = port_enable1;
+               dev->ports[1].max_conn = port_max_conn1;
+               dev->ports[1].tx_max_cr = port_cell_rate_up1;
+       }
+
+       //aal5
+       dev->aal5.padding_byte = a5_fill_pattern;
+       dev->aal5.tx_max_sdu = a5s_mtu;
+       dev->aal5.rx_max_sdu = a5r_mtu;
+
+       //cbm
+       dev->cbm.nrt_thr = cbm_nrt;
+       dev->cbm.clp0_thr = cbm_clp0;
+       dev->cbm.clp1_thr = cbm_clp1;
+       dev->cbm.free_cell_cnt = cbm_free_cell_no;
+
+       //qsb
+       dev->qsb.tau = qsb_tau;
+       dev->qsb.tstepc =qsb_tstep;
+       dev->qsb.sbl = qsb_srvm;
+       
+       //allocate on the fly
+       dev->cbm.mem_addr = NULL;
+       dev->cbm.qd_addr = NULL;
+}
+
+
+/*     Brief:          Find QID for VCC
+ *     Parameters:     vcc     - VCC data structure
+ *     Return Value:   -EINVAL         - VCC not found
+ *                     qid             - QID for this VCC
+ *     Description:
+ *     This function returns the QID of a given VCC
+ */
+static int amazon_atm_get_queue(struct atm_vcc* vcc)
+{
+       int     i;
+       for (i=0;i<AMAZON_ATM_MAX_QUEUE_NUM;i++) {
+               if (g_atm_dev.queues[i].vcc == vcc) return i;
+       }
+       return -EINVAL;
+}
+
+
+/*
+ *     Brief:          Find QID for VPI/VCI
+ *     Parameters:     vpi     - VPI to found
+ *                     vci     - VCI to found
+ *
+ *     Return Value:   -EINVAL         - VPI/VCI not found
+ *                     qid             - QID for this VPI/VCI
+ *
+ *     Description:
+ *     This function returns the QID for a given VPI/VCI. itf doesn't matter
+ */
+static int amazon_atm_find_vpivci(u8 vpi, u16 vci)
+{
+       int     i;
+       struct atm_vcc * vcc;
+       for (i=0;i<AMAZON_ATM_MAX_QUEUE_NUM;i++) {
+               if ( (vcc = g_atm_dev.queues[i].vcc)!= NULL) {
+                       if ((vcc->vpi == vpi) && (vcc->vci == vci)) return i;
+               }
+       }
+       return -EINVAL;
+}
+
+/*     Brief:          Find QID for VPI
+ *     Parameters:     vpi     - VPI to found
+ *     Return Value:   -EINVAL         - VPI not found
+ *                     qid             - QID for this VPI
+ *
+ *     Description:
+ *     This function returns the QID for a given VPI. itf and VCI don't matter
+ */
+static int amazon_atm_find_vpi(u8 vpi)
+{
+       int     i;
+       for (i=0;i<AMAZON_ATM_MAX_QUEUE_NUM;i++) {
+               if ( g_atm_dev.queues[i].vcc!= NULL) {
+                       if (g_atm_dev.queues[i].vcc->vpi == vpi) return i;
+               }
+       }
+       return -EINVAL;
+}
+
+/*
+ *     Brief:          Clears QID entries for VCC
+ *
+ *     Parameters:     vcc     - VCC to found
+ *
+ *     Description:
+ *     This function searches for the given VCC and sets it to NULL if found.
+ */
+static inline void amazon_atm_clear_vcc(int i)
+{
+       g_atm_dev.queues[i].vcc = NULL;
+       g_atm_dev.queues[i].free = 1;
+}
+
+
+/*
+ * Brief:      dump skb data
+ */
+static inline void dump_skb(u32 len, char * data)
+{
+#ifdef AMAZON_TPE_DUMP
+       int i;
+       for(i=0;i<len;i++){     
+               printk("%2.2x ",(u8)(data[i]));
+               if (i % 16 == 15)
+                       printk("\n");
+       }
+       printk("\n");
+#endif
+}
+
+/*
+ * Brief:      dump queue descriptor
+ */
+static inline void dump_qd(int qid)
+{
+#ifdef AMAZON_TPE_DUMP
+       u8 * qd_addr;
+       if (valid_qid(qid) != 1) return;
+       qd_addr = (u8 *) KSEG1ADDR((unsigned long)g_atm_dev.cbm.qd_addr);
+       AMAZON_TPE_EMSG("qid: %u [%8x][%8x][%8x][%8x]\n", qid
+               ,readl(qd_addr+qid*CBM_QD_SIZE+0x0)
+               ,readl(qd_addr+qid*CBM_QD_SIZE+0x4)
+               ,readl(qd_addr+qid*CBM_QD_SIZE+0x8)
+               ,readl(qd_addr+qid*CBM_QD_SIZE+0xc));
+#endif
+}
+
+/*
+ * Brief:      release TX skbuff
+ */
+static inline void amazon_atm_free_tx_skb_vcc(struct atm_vcc *vcc, struct sk_buff *skb)
+{
+       if ( vcc->pop != NULL) {
+               vcc->pop(vcc, skb);
+        } else {
+               dev_kfree_skb_any(skb);
+        }
+}
+/*
+ * Brief:      release TX skbuff
+ */
+static inline void amazon_atm_free_tx_skb(struct sk_buff *skb)
+{
+       struct atm_vcc* vcc = ATM_SKB(skb)->vcc;
+       if (vcc!=NULL){
+               amazon_atm_free_tx_skb_vcc(vcc,skb);
+       } else {
+               dev_kfree_skb_any(skb);//fchang:Added
+       }
+}
+
+/* Brief:      divide by 64 and round up
+ */
+static inline u32 divide_by_64_round_up(int input)
+{
+       u32 tmp1;
+       tmp1 = (u32) input;
+        tmp1 = (tmp1%64)?(tmp1/64 + 1): (tmp1/64);
+        if (tmp1 == 0) tmp1 = 1;
+       return tmp1;
+}
+
+/*
+ * Brief:      statistics
+ */
+#ifdef AMAZON_ATM_DEBUG
+static inline void queue_statics(int qid, qs_t idx)
+{
+       if (valid_qid(qid)){
+               g_atm_dev.queues[qid].qs[idx]++;
+       }
+}
+#else  //not AMAZON_ATM_DEBUG
+static inline void queue_statics(int qid, qs_t idx){}
+#endif //AMAZON_ATM_DEBUG              
+
+
+/*     Brief:  set dma tx full, i.e. there is no available descriptors
+ */
+static void inline atm_dma_full(void)
+{
+       AMAZON_TPE_DMSG("ch0 is full\n");
+       atomic_set(&g_atm_dev.dma_tx_free_0,0);
+}
+
+/*
+ *     Brief   set dma tx free (at least one descript is available)
+ */
+inline static void atm_dma_free(void)
+{
+       AMAZON_TPE_DMSG("ch0 is free\n");
+       atomic_set(&g_atm_dev.dma_tx_free_0,1);
+}
+
+
+/*     Brief:          return the status of DMA TX descriptors
+ *     Parameters:     TX channel  (DMA_TX_CH0, TX_CH1)
+ *     Return:
+ *             1:      there are availabel TX descriptors
+ *             0:      no available
+ *     Description:
+ *
+ */
+inline int dma_may_send(int ch)
+{
+       if (atomic_read(&g_atm_dev.dma_tx_free_0)){
+               return 1;
+       }
+       return 0;
+}
+
+/******************************* global functions *********************************/ 
+/*
+ *     Brief:          SWIE Cell Extraction Start Routine
+ *                     and task routine for swex_complete_task
+ *     Parameters:     irq_stat        - interrupt status
+ *
+ *     Description:
+ *     This is the routine for extracting cell. It will schedule itself if the hardware is busy.
+ *     This routine runs in interrupt context
+ */
+void amazon_atm_swex(void * irq_stat)
+{
+       u32 ex_stat=0;
+       u32 addr;
+       // Read extraction status register
+       ex_stat = readl(CBM_HWEXSTAT0_ADDR);
+
+       // Check if extraction/insertion is in progress 
+       if ( (ex_stat & CBM_EXSTAT_SCB) || (ex_stat & CBM_EXSTAT_FB) || (test_and_set_bit(SWIE_LOCK, &(g_atm_dev.swie.lock))!=0)) {
+               AMAZON_TPE_DMSG(" extraction in progress. Will wait\n");
+               swex_start_task.data = irq_stat;
+               queue_task(&swex_start_task, &tq_immediate);
+               mark_bh(IMMEDIATE_BH);
+       }else {
+               // Extract QID
+               g_atm_dev.swie.qid = (((u32)irq_stat) >> 24);
+               AMAZON_TPE_DMSG("extracting from qid=%u\n",g_atm_dev.swie.qid);
+               //read status word
+               addr = KSEG1ADDR((unsigned long)g_atm_dev.cbm.qd_addr);
+               addr = readl((addr + g_atm_dev.swie.qid * 0x10 + 4) & 0xFFFFFFC0);
+               addr = KSEG1ADDR(addr);
+               g_atm_dev.swie.sw = readl(addr+52)&SWIE_ADDITION_DATA_MASK;
+               AMAZON_TPE_DMSG("cell addition word: %8x \n", g_atm_dev.swie.sw);
+               
+               // Start extraction
+               AMAZON_WRITE_REGISTER_L(g_atm_dev.swie.qid | SWIE_CBM_PID_SUBADDR, CBM_HWEXPAR0_ADDR);
+               AMAZON_WRITE_REGISTER_L(SWIE_CBM_SCE0, CBM_HWEXCMD_ADDR);
+       }
+}
+#ifdef AMAZON_TPE_SCR
+u32 g_a5r_wait=0;
+/*
+ *     Brief:          AAL5 Packet Extraction Routine  and task routine for a5r_task
+ *     Parameters:     irq_stat        - interrupt status
+ *
+ *     Description:
+ *     This is the routine for extracting frame. It will schedule itself if the hardware is busy.
+ *     This routine runs in interrupt context
+ */
+void amazon_atm_a5r(void* qid)
+{
+       volatile u32 ex_stat=0;
+       u32 addr;
+       u32 a5r_wait=0;
+
+       ex_stat = readl(CBM_HWEXSTAT0_ADDR);
+#if 0
+       // Check if extraction/insertion is in progress 
+       if ( (ex_stat & CBM_EXSTAT_SCB) || (ex_stat & CBM_EXSTAT_FB) ) {
+               AMAZON_TPE_DMSG(" extraction in progress. Will wait\n");
+               a5r_task.data = qid;
+               queue_task(&a5r_task, &tq_immediate);
+               mark_bh(IMMEDIATE_BH);
+       }else {
+               AMAZON_TPE_DMSG("extracting from qid=%u\n",(u8)qid);
+               // Start extraction
+               AMAZON_WRITE_REGISTER_L(((u8)qid) | CBM_HWEXPAR_PN_A5, CBM_HWEXPAR0_ADDR);
+               AMAZON_WRITE_REGISTER_L(CBM_HWEXCMD_FE0, CBM_HWEXCMD_ADDR);
+       }
+#else
+       //while ( (ex_stat & CBM_EXSTAT_SCB) || (ex_stat & CBM_EXSTAT_FB) ) {
+       while ( ex_stat != 0x80){
+               a5r_wait++;
+               ex_stat = readl(CBM_HWEXSTAT0_ADDR);
+#if    0
+               if (a5r_wait >= 0xffffff){
+                       a5r_wait=0;
+                       printk(".");
+               }
+#endif
+       }
+       if (a5r_wait > g_a5r_wait){
+               g_a5r_wait = a5r_wait;
+       }
+       AMAZON_WRITE_REGISTER_L(((u8)qid) | CBM_HWEXPAR_PN_A5, CBM_HWEXPAR0_ADDR);
+       AMAZON_WRITE_REGISTER_L(CBM_HWEXCMD_FE0, CBM_HWEXCMD_ADDR);
+#endif
+}
+
+#endif //AMAZON_TPE_SCR
+
+/*     Brief:  Handle F4/F5 OAM cell
+ *     Return:
+ *             0       ok
+ *             <0      fails
+ */
+static int inline amazon_handle_oam_cell(void *data, u8 vpi, u16 vci,u32 status)
+{
+       struct atm_vcc*         vcc=NULL;
+       int qid;
+       if (!status&SWIE_EOAM_MASK){
+               AMAZON_TPE_EMSG("unknown cell received, discarded\n");
+               goto amazon_handle_oam_cell_err_exit;
+       }else if (status&SWIE_ECRC10ERROR_MASK){
+               AMAZON_TPE_EMSG("CRC-10 Error Status:%8x, discarded\n", status);
+               goto amazon_handle_oam_cell_err_exit;
+       }else{
+               if(status & (SWIE_EVCI3_MASK |SWIE_EVCI4_MASK)){
+                       //F4 level (VPI) OAM, Assume duplex
+                       qid = amazon_atm_find_vpi(vpi)+CBM_RX_OFFSET;
+               }else if (status & (SWIE_EPTI4_MASK|SWIE_EPTI5_MASK)){
+                       //F5 level (VCI) OAM, Assume duplex
+                       qid = amazon_atm_find_vpivci(vpi,vci)+CBM_RX_OFFSET;                    
+               }else{
+                       qid = -1;
+                       AMAZON_TPE_EMSG("non-F4/F5 OAM cells?, discarded\n");
+                       goto amazon_handle_oam_cell_err_exit;
+               }
+       }
+       if (valid_qid(qid) && ((vcc = g_atm_dev.queues[qid].vcc)!=NULL)){
+               //TODO, should we do this for ALL OAM types? (Actually only User and CC)
+               g_atm_dev.queues[qid].access_time=xtime;
+               if (vcc->push_oam){
+                       (*vcc->push_oam)(vcc,data);
+               }else{
+                       amz_push_oam(data);
+               }
+       }else{
+               AMAZON_TPE_EMSG("no VCC yet\n");
+               goto amazon_handle_oam_cell_err_exit;
+       }
+       return 0;
+amazon_handle_oam_cell_err_exit:       
+       dump_skb(AMAZON_AAL0_SDU,(char *)data); 
+       return -1;
+}
+
+/*     Brief:  SWIE Cell Extraction Finish Routine 
+ *             and task routine for swex_complete_task
+ *     Description:
+ *     1.Allocate a buffer of type struct sk_buff
+ *     2.Copy the data from the temporary memory to this buffer
+ *     3.Push the data to upper layer
+ *     4.Update the statistical data if necessary
+ *     5.Release the temporary data
+
+ */
+void amazon_atm_swex_push(void * data)
+{
+       struct atm_vcc*         vcc=NULL;
+       struct sk_buff*         skb=NULL;
+       struct amazon_atm_cell_header * cell_header;
+       u32 status;
+       int qid;
+       if (!data){
+               AMAZON_TPE_EMSG("data is NULL\n");
+               return;
+       }
+       qid = ((u8*)data)[AMAZON_AAL0_SDU];
+       status = ((u32*)data)[ATM_AAL0_SDU/4];
+       cell_header = (struct amazon_atm_cell_header *) data;
+       if (valid_qid(qid) != 1){
+               AMAZON_TPE_EMSG("error qid: %u\n",qid);
+               AMAZON_TPE_EMSG("unknown cells recieved\n");
+       }else if (qid == AMAZON_ATM_OAM_Q_ID){
+               //OAM or RM or OTHER cell
+               //Find real connection
+               
+#ifdef IKOS_MINI_BOOT  
+               //for OAM loop back test
+               dump_skb(56,(char *)data);
+               //kfree(data);  using g_oam_cell
+               return;
+#endif //IKOS_MINI_BOOT                                
+#ifdef TPE_LOOPBACK                                    
+               amz_push_oam(data);
+               return;
+#endif//TPE_LOOPBACK
+               int ret = 0;
+               ret = amazon_handle_oam_cell(data,cell_header->bit.vpi,cell_header->bit.vci,status);
+               if (ret == 0)
+                                       return;
+                               }else{
+               //should be normal AAL0 cells
+               // Get VCC
+               vcc = g_atm_dev.queues[qid].vcc;
+               if (vcc != NULL) {
+                       AMAZON_TPE_DMSG("push to upper layer\n");
+                       skb = dev_alloc_skb(AMAZON_AAL0_SDU);
+                       if (skb != NULL) {
+                               //skb->dev=vcc->dev;
+                               memcpy(skb_put(skb, AMAZON_AAL0_SDU), data, AMAZON_AAL0_SDU);
+                               skb->stamp = xtime;
+                               ATM_SKB(skb)->vcc = vcc;
+                               (*g_atm_dev.queues[qid].push)(vcc,skb,0);
+                       }else{
+                               AMAZON_TPE_EMSG(" No memory left for incoming AAL0 cell! Cell discarded!\n");
+                               //inform the upper layer
+                               (*g_atm_dev.queues[qid].push)(vcc,skb,-ENOMEM);
+                               atomic_inc(&vcc->stats->rx_drop);
+                       }
+               }else{
+                       AMAZON_TPE_EMSG("invalid qid %u\n",qid);
+               }
+       }
+       //kfree(data);  using g_oam_cell
+}
+
+/*
+ *     Brief:          Interrupt handler for software cell extraction (done)
+ *     Parameters:     irq     - CPPN for this interrupt
+ *                     data    - Device ID for this interrupt
+ *                     regs    - Register file
+ *
+ *     Description:
+ *     When a software extraction is finished this interrupt is issued.
+ *     It reads the cell data and sends it to the ATM stack.
+ */
+void amazon_atm_swex_isr(int irq, void *data, struct pt_regs *regs)
+{
+       u32 * cell = NULL;
+       int i;
+       //ATM_AAL0 SDU + QID
+       AMAZON_TPE_DMSG("SWIE extraction done\n");
+       cell = (u32 *) g_oam_cell;
+       if (cell != NULL){
+               //convert to host byte order from big endian
+               for(i=0;i<ATM_AAL0_SDU;i+=4){
+                       cell[i/4]=readl(SWIE_ECELL_ADDR+i);     
+               }
+               cell[ATM_AAL0_SDU/4]= g_atm_dev.swie.sw;
+               ((u8*)cell)[AMAZON_AAL0_SDU] = g_atm_dev.swie.qid;
+#ifdef IKOS_MINI_BOOT
+       for(i=0;i<ATM_AAL0_SDU;i+=4){
+               AMAZON_TPE_DMSG("[%2x][%2x][%2x][%2x]\n",
+                       ((char*)cell)[i],
+                       ((char*)cell)[i+1],
+                       ((char*)cell)[i+2],
+                       ((char*)cell)[i+3]
+                       );
+       }
+       AMAZON_TPE_DMSG("qid: %u\n", ((u8*)cell)[AMAZON_AAL0_SDU]);
+       amazon_atm_swex_push((void *) cell);
+#else //not IKOS_MINI_BOOT
+       swex_complete_task.data = cell;
+       queue_task(&swex_complete_task,&tq_immediate);
+       mark_bh(IMMEDIATE_BH);
+#endif //not IKOS_MINI_BOOT
+       }else{
+               AMAZON_TPE_EMSG("no memory for receiving AAL0 cell\n");
+       }
+       
+       /* release the lock and check */
+       if (test_and_clear_bit(SWIE_LOCK,&(g_atm_dev.swie.lock)) == 0){
+               AMAZON_TPE_EMSG("swie lock is already released\n");
+       }
+       wake_up(&g_atm_dev.swie.sleep);
+}
+/*     Brief:          Interrupt handler for software cell insertion
+ *
+ *     Parameters:     irq     - CPPN for this interrupt
+ *                     data    - Device ID for this interrupt
+ *                     regs    - Register file
+ *
+ *     Description:
+ *     When a software insertion is finished this interrupt is issued.
+ *     The only purpose is to release the semaphore and read the status register.
+ */
+void amazon_atm_swin_isr(int irq, void *data, struct pt_regs *regs)
+{
+       AMAZON_TPE_DMSG("SWIE insertion done\n");
+       /* release the lock and check */
+       if (test_and_clear_bit(SWIE_LOCK,&(g_atm_dev.swie.lock)) == 0){
+               AMAZON_TPE_EMSG("swie lock is already released");
+       }
+       // Release semaphore
+       up(&g_atm_dev.swie.in_sem);
+
+}
+/*     Brief:          Interrupt handler for software cell insertion & extraction
+ *     Parameters:     irq     - CPPN for this interrupt
+ *                     data    - Device ID for this interrupt
+ *                     regs    - Register file
+ *     Description:
+ *     When a software insertion or extractionis finished this interrupt is issued.
+ */
+void amazon_atm_swie_isr(int irq, void *data, struct pt_regs *regs)
+{
+       u32     status=0;
+       // Read status register
+       status = readl(SWIE_ISTAT_ADDR);
+       AMAZON_TPE_DMSG("insertion status: %8x\n", status);
+       if (status & SWIE_ISTAT_DONE){
+               //clear interrupt in peripheral and ICU
+               AMAZON_WRITE_REGISTER_L(SRC_TOS_MIPS | SRC_CLRR|SRC_SRE_ENABLE | AMAZON_SWIE_INT, SWIE_ISRC_ADDR);
+               mask_and_ack_amazon_irq(AMAZON_SWIE_INT);
+               
+               amazon_atm_swin_isr(irq,data,regs);
+       }
+       status = readl(SWIE_ESTAT_ADDR);
+       AMAZON_TPE_DMSG("extraction status: %8x\n", status);
+       if (status & SWIE_ESTAT_DONE){
+               //clear interrupt
+               AMAZON_WRITE_REGISTER_L(SRC_TOS_MIPS | SRC_CLRR|SRC_SRE_ENABLE | AMAZON_SWIE_INT, SWIE_ESRC_ADDR);
+               mask_and_ack_amazon_irq(AMAZON_SWIE_INT);
+               
+               amazon_atm_swex_isr(irq,data,regs);
+       }
+       //clear interrupt in ICU
+}
+/*
+ *     Brief:          Insert ATM cell into CBM
+ *     Parameters:     queue   - Target queue
+ *                     cell    - Pointer to cell data
+ *     Return Value:   EBUSY           - CBM is busy
+ *                     0               - OK, cell inserted
+ *     Description:
+ *     This function inserts a cell into the CBM using the software insertion
+ *     method. The format of the cell should be
+ *     Little Endian (address starting from 0)
+ *             H3, H2, H1, H0, P3, P2, P1, P0, P7, P6, P5, P4, ..., P47, P46, P45, P44
+ *     Big Endian (address starting from 0)
+ *             H0, H1, H2, H3, P0, P1, P2, P3, P4, P5, P6, P7, ..., P44, P45, P46, P47
+ *     This function does not free memory!!!
+ */
+int amazon_atm_swin(u8 queue, void* cell)
+{
+       u32     status=0;
+       int i;
+       // Read status register
+       status = readl(SWIE_ISTAT_ADDR);
+       AMAZON_TPE_DMSG(" SWIE status=0x%08x\n",status);
+
+       AMAZON_TPE_DMSG(" Inserting cell qid=%u\n",queue);
+       
+#ifdef AMAZON_CHECK_LINK
+       if (adsl_link_status == 0){
+               return -EFAULT; 
+       }
+#endif //AMAZON_CHECK_LINK
+
+       // Get semaphore (if possible)
+       if (down_interruptible(&g_atm_dev.swie.in_sem)) {
+               return -ERESTARTSYS;
+       }
+       /* try to set lock */
+       wait_event_interruptible(g_atm_dev.swie.sleep,(test_and_set_bit(SWIE_LOCK,&(g_atm_dev.swie.lock)) == 0));
+       if (signal_pending(current)){
+               return -ERESTARTSYS; 
+       }
+
+       // Store cell in CBM memory
+       for(i=0;i<ATM_AAL0_SDU;i+=4){
+               AMAZON_WRITE_REGISTER_L(((u32*)cell)[i/4],SWIE_ICELL_ADDR+i);
+       }
+       //Store queue id
+       AMAZON_WRITE_REGISTER_L((u32) queue,SWIE_IQID_ADDR);
+
+       //Start SWIE
+       AMAZON_WRITE_REGISTER_L(SWIE_ICMD_START,SWIE_ICMD_ADDR);
+       
+       return 0;
+}
+
+#ifdef AMAZON_ATM_DEBUG
+/*
+ *     Brief:          Interrupt handler for HTU
+ *
+ *     Parameters:     irq     - CPPN for this interrupt
+ *                     data    - Device ID for this interrupt
+ *                     regs    - Register file
+ *
+ */
+void amazon_atm_htu_isr(int irq, void *data, struct pt_regs *regs)
+{
+       u32     irq_stat=0;
+
+       // Read interrupt status register
+       irq_stat = readl(HTU_ISR0_ADDR);
+       AMAZON_TPE_DMSG("HTU status: %8x\n",irq_stat);
+       //Clear interrupt in CBM and ICU
+       AMAZON_WRITE_REGISTER_L(SRC_CLRR|SRC_TOS_MIPS | SRC_SRE_ENABLE | AMAZON_HTU_INT, HTU_SRC0_ADDR);
+       mask_and_ack_amazon_irq(AMAZON_HTU_INT);        
+       // Check if Any Cell Arrived
+       if (irq_stat & (HTU_ISR_NE | HTU_ISR_PNE) ) {
+               AMAZON_TPE_EMSG("INFNOENTRY %8x\n", readl(HTU_INFNOENTRY_ADDR));                
+       }else if (irq_stat & (HTU_ISR_TORD|HTU_ISR_PT)){
+               AMAZON_TPE_EMSG("Time Out %8x\n", readl(HTU_INFTIMEOUT_ADDR));
+       }else if (irq_stat & HTU_ISR_IT){
+               AMAZON_TPE_EMSG("Interrupt Test\n");
+       }else if (irq_stat & HTU_ISR_OTOC){
+               AMAZON_TPE_EMSG("Overflow of Time Out Counter\n");
+       }else if (irq_stat & HTU_ISR_ONEC){
+               AMAZON_TPE_EMSG("Overflow of No Entry Counter\n");
+       }else{
+               AMAZON_TPE_EMSG("unknown HTU interrupt occurs %8x\n", irq_stat);
+       }
+
+}
+#endif //AMAZON_ATM_DEBUG
+
+#ifdef AMAZON_TPE_TEST_AAL5_INT
+/*
+ *     Brief:          Interrupt handler for AAL5
+ *
+ *     Parameters:     irq     - CPPN for this interrupt
+ *                     data    - Device ID for this interrupt
+ *                     regs    - Register file
+ *
+ */
+void amazon_atm_aal5_isr(int irq, void *data, struct pt_regs *regs)
+{
+       volatile u32 irq_stat=0;
+
+       // Read interrupt status register
+       irq_stat = readl(AAL5_SISR0_ADDR);
+       if (irq_stat){
+               AMAZON_TPE_EMSG("A5S status: %8x\n",irq_stat);
+               //Clear interrupt in CBM and ICU
+               AMAZON_WRITE_REGISTER_L(SRC_CLRR|SRC_TOS_MIPS | SRC_SRE_ENABLE | AMAZON_AAL5_INT, AAL5_SSRC0_ADDR);
+               mask_and_ack_amazon_irq(AMAZON_AAL5_INT);       
+       }
+       irq_stat = readl(AAL5_RISR0_ADDR);
+       if (irq_stat){
+               AMAZON_TPE_EMSG("A5R status: %8x\n",irq_stat);
+               //Clear interrupt in CBM and ICU
+               AMAZON_WRITE_REGISTER_L(SRC_CLRR|SRC_TOS_MIPS | SRC_SRE_ENABLE | AMAZON_AAL5_INT, AAL5_RSRC0_ADDR);
+               mask_and_ack_amazon_irq(AMAZON_AAL5_INT);       
+       }
+}
+#endif //AMAZON_TPE_TEST_AAL5_INT
+
+/*
+ *     Brief:          Interrupt handler for CBM
+ *
+ *     Parameters:     irq     - CPPN for this interrupt
+ *                     data    - Device ID for this interrupt
+ *                     regs    - Register file
+ *
+ *     Description:
+ *     This is the MIPS interrupt handler for the CBM. It processes incoming cells
+ *     for SWIE queues.
+ */
+void amazon_atm_cbm_isr(int irq, void *data, struct pt_regs *regs)
+{
+       u32     irq_stat=0;
+       u8 qid=0;
+
+       // Read interrupt status register
+       while ( (irq_stat = readl(CBM_INTINF0_ADDR))){
+               AMAZON_TPE_DMSG("CBM INT status: %8x\n",irq_stat);
+               //Clear interrupt in CBM and ICU
+               AMAZON_WRITE_REGISTER_L(SRC_CLRR|SRC_TOS_MIPS | SRC_SRE_ENABLE | AMAZON_CBM_INT, CBM_SRC0_ADDR);
+               qid = (u8) ((irq_stat & CBM_INTINF0_QID_MASK)>>CBM_INTINF0_QID_SHIFT);
+#ifdef AMAZON_TPE_SCR  
+               if (irq_stat & CBM_INTINF0_EF){
+                       amazon_atm_a5r((void*)qid);
+               }
+#endif
+               // Check if Any Cell Arrived
+               if (irq_stat & CBM_INTINF0_ACA) {
+                       amazon_atm_swex((void *)irq_stat);              
+               }
+               //TX AAL5 PDU discard
+               if (irq_stat & CBM_INTINF0_OPF){
+                       if ( (qid) < CBM_RX_OFFSET ){
+                               g_atm_dev.mib_counter.tx_drop++;
+                       }
+                       queue_statics(qid, QS_HW_DROP);
+               }
+               if (irq_stat & (CBM_INTINF0_ERR|CBM_INTINF0_Q0E|CBM_INTINF0_Q0I|CBM_INTINF0_RDE)){
+                       AMAZON_TPE_EMSG("CBM INT status: %8x\n",irq_stat);
+                       if (irq_stat & CBM_INTINF0_ERR){
+                               AMAZON_TPE_EMSG("CBM Error: FPI Bus Error\n");
+                       }
+                       if (irq_stat & CBM_INTINF0_Q0E){
+                               AMAZON_TPE_EMSG("CBM Error: Queue 0 Extract\n");
+                       }
+                       if (irq_stat & CBM_INTINF0_Q0I){
+                               AMAZON_TPE_EMSG("CBM Error: Queue 0 Extract\n");
+                       }
+                       if (irq_stat & CBM_INTINF0_RDE){
+                               AMAZON_TPE_EMSG("CBM Error: Read Empty Queue %u\n",qid);
+                               dump_qd(qid);
+                       }
+               }               
+       }
+       mask_and_ack_amazon_irq(AMAZON_CBM_INT);
+}
+
+/*     Brief:  check the status word after AAL SDU after reassembly
+ */
+static inline void check_aal5_error(u8 stw0, u8 stw1, int qid)
+{
+       if (stw0 & AAL5_STW0_MFL){
+               AMAZON_TPE_DMSG("Maximum Frame Length\n");
+               g_atm_dev.queues[qid].aal5VccOverSizedSDUs++;
+       } 
+       if (stw0 & AAL5_STW0_CRC){
+               AMAZON_TPE_DMSG("CRC\n");
+               g_atm_dev.queues[qid].aal5VccCrcErrors++;
+       }
+#ifdef AMAZON_ATM_DEBUG_RX
+       AMAZON_TPE_EMSG("qid:%u stw0:%8x stw1:%8x\n",qid,stw0,stw1);
+#endif
+}
+
+/* Brief:      Process DMA rx data
+ * Parameters:
+       dma_dev:        pointer to the dma_device_info, provided by us when register the dma device
+ * Return:     no
+ * Description: DMA interrupt handerl with OoS support. It is called when there is some data in rx direction.
+ *
+ */
+//507261:tc.chen void atm_process_dma_rx(struct dma_device_info* dma_dev)
+void __system atm_process_dma_rx(struct dma_device_info* dma_dev)
+{
+        u8 * head=NULL;
+        u32 length=0;
+        u8 stw0=0;
+        u8 stw1=0;
+
+       struct sk_buff * skb=NULL;
+       struct atm_vcc * vcc=NULL;
+       int qid=0;
+#ifdef AMAZON_ATM_DEBUG_RX
+       static int dma_rx_dump=0;
+       static u32 seq=0;
+       
+       seq++;
+       if (dma_rx_dump>0){
+               printk("\n=========================[%u]=========================\n",seq);
+       }
+#endif 
+       length=dma_device_read(dma_dev,&head,(void**)&skb);
+       AMAZON_TPE_DMSG("receive %8p[%u] from DMA\n", head,length);
+       if (head == NULL||length<=0) {
+               AMAZON_TPE_DMSG("dma_read null \n");
+               goto error_exit;
+       }
+
+       if (length > (g_atm_dev.aal5.rx_max_sdu+64)){
+               AMAZON_TPE_EMSG("received packet too large (%u)\n",length);
+               goto error_exit;
+       }
+       //check AAL5R trail for error and qid
+       //last byte is qid
+       length--;
+       qid = (int) head[length];
+       AMAZON_TPE_DMSG("head[%u] qid %u\n",length, qid);
+       //STW0 is always 4 bytes before qid
+       length -= 4;
+       stw0 = head[length]&0xff;
+       AMAZON_TPE_DMSG("head[%u] stw0 %8x\n",length, stw0);
+       //position of STW1 depends on the BE bits
+       length = length-4 + (stw0&AAL5_STW0_BE);
+       stw1 = head[length]&0xff;
+       AMAZON_TPE_DMSG("head[%u] stw1 %8x\n",length, stw1);    
+       if ( (stw0 & AAL5_STW0_MASK) || (stw1 & AAL5_STW1_MASK) ){
+               //AAL5 Error
+               check_aal5_error(stw0, stw1,qid);               
+               goto error_exit;
+       }
+       //make data pointers consistent
+       //UU + CPI
+       length -= 2;
+       AMAZON_TPE_DMSG("packet length %u\n", length);
+
+       //error: cannot restore the qid
+       if (valid_qid(qid) != 1){
+               AMAZON_TPE_EMSG("received frame in invalid qid %u!\n", qid);
+               goto error_exit;
+       }
+       vcc = g_atm_dev.queues[qid].vcc;
+       if (vcc == NULL){
+               AMAZON_TPE_EMSG("received frame in invalid vcc, qid=%u!\n",qid);
+               goto error_exit;
+       }
+       if (skb == NULL){
+               AMAZON_TPE_EMSG("cannot restore skb pointer!\n");
+               goto error_exit;
+       }
+       skb_put(skb,length);
+       skb->stamp = xtime;
+       g_atm_dev.queues[qid].access_time=xtime;
+       if ((*g_atm_dev.queues[qid].push)(vcc,skb,0)){
+               g_atm_dev.mib_counter.rx_drop++;
+               queue_statics(qid, QS_SW_DROP);                                 
+       }else{
+               g_atm_dev.mib_counter.rx++;
+               adsl_led_flash();//joelin adsl led
+               queue_statics(qid, QS_PKT);
+               AMAZON_TPE_DMSG("push successful!\n");
+       }
+#ifdef AMAZON_ATM_DEBUG_RX
+       if (dma_rx_dump>0){
+               printk("\nOK packet [dump=%u] length=%u\n",dma_rx_dump,length);
+               dump_skb(length+7, head);
+       }
+       if (dma_rx_dump >0) dma_rx_dump--;
+#endif 
+       return ;
+error_exit:
+#ifdef AMAZON_ATM_DEBUG_RX
+       if ( (head!=NULL) && (length >0)){
+               AMAZON_TPE_EMSG("length=%u\n",length);
+               dump_skb(length+5, head);
+       }       
+       dma_rx_dump++;
+#endif 
+       g_atm_dev.mib_counter.rx_err++;
+       queue_statics(qid, QS_ERR);
+       /*
+       if (vcc){
+               (*g_atm_dev.queues[qid].push)(vcc,skb,1);       
+       }
+       */
+       if (skb != NULL) {
+               dev_kfree_skb_any(skb);
+       }
+       return;
+}
+
+/*Brief:       ISR for DMA pseudo interrupt
+ *Parameter:
+       dma_dev:        pointer to the dma_device_info, provided by us when register the dma device
+       intr_status:    
+               RCV_INT:                rx data available
+               TX_BUF_FULL_INT:        tx descriptor run out of
+               TRANSMIT_CPT_INT:       tx descriptor available again
+ *Return:
+       0 for success???
+ */
+//507261:tc.chen int amazon_atm_dma_handler(struct dma_device_info* dma_dev, int intr_status)
+int __system amazon_atm_dma_handler(struct dma_device_info* dma_dev, int intr_status)
+{
+       AMAZON_TPE_DMSG("status:%u\n",intr_status);
+       switch (intr_status) {
+               case RCV_INT:
+                       atm_process_dma_rx(dma_dev);
+                       break;
+               case TX_BUF_FULL_INT:
+                       //TX full: no descriptors
+                       atm_dma_full();
+                       break;
+               case TRANSMIT_CPT_INT:
+                       //TX free: at least one descriptor
+                       atm_dma_free();
+                       break;
+               default:
+                       AMAZON_TPE_EMSG("unknown status!\n");
+       }
+       return 0;
+}
+
+/*Brief:       free buffer for DMA tx
+ *Parameter:
+       dataptr:        pointers to data buffer
+       opt:            optional parameter, used to convey struct skb pointer, passwd in dma_device_write
+ *Return:
+       0 for success???
+ *Description:
+       called by DMA module to release data buffer after DMA tx transaction
+ *Error:
+       cannot restore skb pointer
+ */
+int amazon_atm_free_tx(u8*dataptr, void* opt)
+{
+       struct sk_buff *skb;
+       if (opt){
+               AMAZON_TPE_DMSG("free skb%8p\n",opt);
+               skb = (struct sk_buff *)opt;
+               amazon_atm_free_tx_skb(skb);
+       }else{
+               AMAZON_TPE_EMSG("BUG: cannot restore skb pointer!\n");
+       }
+       return 0;
+}
+
+/*Brief:       allocate buffer & do alignment
+ */
+inline struct sk_buff * amazon_atm_alloc_buffer(int len)
+{
+       struct sk_buff *skb;
+       skb = dev_alloc_skb(len+16);
+       if (skb){
+               //alignment requriements (4x32 bits (16 bytes) boundary)
+               alloc_align_16(skb);
+       }
+       return skb;
+}
+
+/*Brief:       allocate buffer for DMA rx
+ *Parameter:
+       len: length
+       opt: optional data to convey the skb pointer, which will be returned to me in interrupt handler,
+ *Return:
+       pointer to buffer, NULL means error?
+ *Description:
+       must make sure byte alignment
+ */
+       
+u8* amazon_atm_alloc_rx(int len, int* offset, void **opt)
+{
+       struct sk_buff *skb;
+       *offset = 0;
+       skb = amazon_atm_alloc_buffer(len);
+       if (skb){
+               AMAZON_TPE_DMSG("alloc skb->data:%8p len:%u\n",skb->data,len);
+               *(struct sk_buff**)opt = skb;
+       }else{
+               AMAZON_TPE_DMSG("no memory for receiving atm frame!\n");
+               return NULL;
+       }
+       return skb->data;
+}
+
+
+
+
+/* Brief:      Allocate kernel memory for sending a datagram.
+ * Parameters
+ *     vcc     virtual connection
+ *     size    data buffer size
+ * Return:
+ *     NULL    fail
+ *     sk_buff a pointer to a sk_buff
+ * Description:
+ *  This function can allocate our own additional memory for AAL5S inbound
+ * header (8bytes). We have to replace the protocol default one (alloc_tx in /net/atm/common.c) 
+ * when we open the device.
+ * byte alignment is done is DMA driver.
+ */
+struct sk_buff *amazon_atm_alloc_tx(struct atm_vcc *vcc,unsigned int size)
+{
+       struct sk_buff *skb;
+
+       if (!dma_may_send(DMA_TX_CH0)){
+               AMAZON_TPE_EMSG("no DMA descriptor available!\n");
+               return NULL;
+       }
+       //AAL5 inbound header space + alignment extra buffer
+       size+=8+AAL5S_INBOUND_HEADER;
+
+        if (atomic_read(&vcc->tx_inuse) && !atm_may_send(vcc,size)) {
+                AMAZON_TPE_EMSG("Sorry tx_inuse = %u, size = %u, sndbuf = %u\n",
+                    atomic_read(&vcc->tx_inuse),size,vcc->sk->sndbuf);
+                return NULL;
+        }
+
+        skb = amazon_atm_alloc_buffer(size);
+       if (skb == NULL){
+               AMAZON_TPE_EMSG("no memory\n");
+               return NULL;
+       }
+       AMAZON_TPE_DMSG("dev_alloc_skb(%u) = %x\n", skb->len, (u32)skb);
+        AMAZON_TPE_DMSG("tx_inuse %u += %u\n",atomic_read(&vcc->tx_inuse),skb->truesize);
+        atomic_add(skb->truesize+ATM_PDU_OVHD,&vcc->tx_inuse);
+
+       //reserve for AAL5 inbound header
+       skb_reserve(skb,AAL5S_INBOUND_HEADER);
+        return skb;
+}
+
+
+/* Brief:      change per queue QSB setting according to vcc qos parameters
+ * Paramters:
+ *     vcc:    atm_vcc pointer 
+ *     qid:    CBM queue id (1~15)
+ * Return:
+  */
+static inline void set_qsb(struct atm_vcc *vcc, struct atm_qos *qos, int qid)
+{
+       qsb_qptl_t      qptl;
+       qsb_qvpt_t      qvpt;
+       u32 tmp=0;
+       unsigned int qsb_clk;
+       
+       qsb_clk = amazon_get_fpi_hz()>>1;
+        
+       AMAZON_TPE_EMSG("Class=%u MAX_PCR=%u PCR=%u MIN_PCR=%u SCR=%u MBS=%u CDV=%u\n"
+               ,qos->txtp.traffic_class
+               ,qos->txtp.max_pcr
+               ,qos->txtp.pcr
+               ,qos->txtp.min_pcr
+               ,qos->txtp.scr
+               ,qos->txtp.mbs
+               ,qos->txtp.cdv
+               );
+       
+       // PCR limiter
+       if (qos->txtp.max_pcr == 0){    
+               qptl.bit.tprs = 0;                  /* 0 disables the PCR limiter */
+       }else {
+               // peak cell rate will be slightly lower than requested (maximum rate / pcr)= (qsbclock/2^3 * timestep/4)/pcr
+               tmp = (( (qsb_clk * g_atm_dev.qsb.tstepc)>>5)/ qos->txtp.max_pcr ) + 1;
+               // check if an overfow occured
+               if (tmp > QSB_TP_TS_MAX) {
+                       AMAZON_TPE_EMSG("max_pcr is too small, max_pcr:%u tprs:%u\n",qos->txtp.max_pcr, tmp);
+                       qptl.bit.tprs = QSB_TP_TS_MAX;
+               }else{
+                       qptl.bit.tprs = tmp;
+               }
+       }
+       //WFQ
+       if (qos->txtp.traffic_class == ATM_CBR  || qos->txtp.traffic_class ==ATM_VBR_RT){
+               // real time queue gets weighted fair queueing bypass
+               qptl.bit.twfq  = 0;
+       }else if (qos->txtp.traffic_class ==ATM_VBR_NRT ||qos->txtp.traffic_class ==ATM_UBR_PLUS ){
+               // wfq calculation here are based on virtual cell rates, to reduce granularity for large rates
+               // wfq factor is maximum cell rate / garenteed cell rate.
+               //qptl.bit.twfq = g_atm_dev.qsb.min_cr * QSB_WFQ_NONUBR_MAX / qos->txtp.min_pcr;
+               if (qos->txtp.min_pcr == 0) {
+                       AMAZON_TPE_EMSG("<warning> MIN_PCR should not be zero\n");
+                       qptl.bit.twfq = QSB_WFQ_NONUBR_MAX;
+               }else{
+                       tmp = QSB_GCR_MIN * QSB_WFQ_NONUBR_MAX / qos->txtp.min_pcr;             
+                       if (tmp == 0 ){
+                               qptl.bit.twfq = 1;
+                       }else if (tmp > QSB_WFQ_NONUBR_MAX){
+                               AMAZON_TPE_EMSG("min_pcr is too small, min_pcr:%u twfq:%u\n",qos->txtp.min_pcr, tmp);
+                               qptl.bit.twfq = QSB_WFQ_NONUBR_MAX;
+                       }else{
+                               qptl.bit.twfq = tmp;    
+                       }
+               }
+       }else if (qos->txtp.traffic_class == ATM_UBR){
+               // ubr bypass, twfq set to maximum value
+               qptl.bit.twfq = QSB_WFQ_UBR_BYPASS;
+       }else{
+               //tx is diabled, treated as UBR
+               AMAZON_TPE_EMSG("<warning> unsupported traffic class %u \n", qos->txtp.traffic_class);
+               qos->txtp.traffic_class = ATM_UBR;
+               qptl.bit.twfq = QSB_WFQ_UBR_BYPASS;
+       }
+       
+       //SCR Leaky Bucket Shaper VBR.0/VBR.1
+       if (qos->txtp.traffic_class ==ATM_VBR_RT || qos->txtp.traffic_class ==ATM_VBR_NRT){
+               if (qos->txtp.scr == 0){
+                       //SCR == 0 disable the shaper
+                       qvpt.bit.ts = 0;
+                       qvpt.bit.taus = 0;
+               }else{
+                       //CLP
+                       if (vcc->atm_options&ATM_ATMOPT_CLP){
+                               //CLP1
+                               qptl.bit.vbr = 1;
+                       }else{
+                               //CLP0
+                               qptl.bit.vbr = 0;
+                       }
+                       //TS and TauS
+                       tmp = (( (qsb_clk * g_atm_dev.qsb.tstepc)>>5)/ qos->txtp.scr ) + 1;
+                       if (tmp > QSB_TP_TS_MAX) {
+                               AMAZON_TPE_EMSG("scr is too small, scr:%u ts:%u\n",qos->txtp.scr, tmp);
+                               qvpt.bit.ts = QSB_TP_TS_MAX;
+                       }else{
+                               qvpt.bit.ts = tmp;
+                       }
+                       tmp = (qos->txtp.mbs - 1)*(qvpt.bit.ts - qptl.bit.tprs)/64;
+                       if (tmp > QSB_TAUS_MAX){
+                               AMAZON_TPE_EMSG("mbs is too large, mbr:%u taus:%u\n",qos->txtp.mbs, tmp);
+                               qvpt.bit.taus = QSB_TAUS_MAX;
+                       }else if (tmp == 0){
+                               qvpt.bit.taus = 1;
+                       }else{
+                               qvpt.bit.taus = tmp;
+                       }
+               }
+       }else{
+               qvpt.w0 = 0;
+       }
+       //write the QSB Queue Parameter Table (QPT)
+       AMAZON_WRITE_REGISTER_L(QSB_QPT_SET_MASK,QSB_RTM_ADDR);
+       AMAZON_WRITE_REGISTER_L(qptl.w0, QSB_RTD_ADDR);
+       AMAZON_WRITE_REGISTER_L((QSB_TABLESEL_QPT<<QSB_TABLESEL_SHIFT)
+               | QSB_RAMAC_REG_LOW
+               | QSB_WRITE
+               | qid
+               ,QSB_RAMAC_ADDR);
+       //write the QSB Queue VBR Parameter Table (QVPT)
+       AMAZON_WRITE_REGISTER_L(QSB_QVPT_SET_MASK,QSB_RTM_ADDR);
+       AMAZON_WRITE_REGISTER_L(qvpt.w0, QSB_RTD_ADDR);
+       AMAZON_WRITE_REGISTER_L((QSB_TABLESEL_QVPT<<QSB_TABLESEL_SHIFT)
+               | QSB_RAMAC_REG_LOW
+               | QSB_WRITE
+               | qid
+               ,QSB_RAMAC_ADDR);       
+       AMAZON_TPE_EMSG("tprs:%u twfq:%u ts:%u taus:%u\n",qptl.bit.tprs,qptl.bit.twfq,qvpt.bit.ts,qvpt.bit.taus);
+}
+
+/* 
+ * Brief:      create/change CBM queue descriptor
+ * Parameter:  
+ *     vcc:    atm_vcc pointer 
+ *     qid:    CBM queue id (1~15)
+ */
+static inline void set_qd(struct atm_vcc *vcc, u32 qid)
+{
+       u32 tx_config=0,rx_config=0;
+       u32 itf = (u32) vcc->itf;
+       u32 dma_qos=0;
+       u8 * qd_addr=NULL;
+               
+       tx_config|=CBM_QD_W3_WM_EN|CBM_QD_W3_CLPt;
+       //RT: check if the connection is a real time connection
+       if (vcc->qos.txtp.traffic_class == ATM_CBR || vcc->qos.txtp.traffic_class == ATM_VBR_RT){
+               tx_config|= CBM_QD_W3_RT;
+       }else{
+               tx_config|= CBM_QD_W3_AAL5; //don't set the AAL5 flag if it is a RT service
+       }
+       rx_config = tx_config;
+       
+       if(vcc->qos.aal == ATM_AAL5){   
+               //QoS: DMA QoS according to the traffic class
+               switch (vcc->qos.txtp.traffic_class){
+                       case ATM_CBR: dma_qos = CBR_DMA_QOS;break;
+                       case ATM_VBR_RT: dma_qos = VBR_RT_DMA_QOS;break;
+                       case ATM_VBR_NRT: dma_qos = VBR_NRT_DMA_QOS;break;
+                       case ATM_UBR_PLUS: dma_qos = UBR_PLUS_DMA_QOS;break;
+                       case ATM_UBR: dma_qos = UBR_DMA_QOS;break;
+               }
+       
+               //TX: upstream, AAL5(EPD or PPD), NOINT, SBid
+               tx_config |= CBM_QD_W3_DIR_UP|CBM_QD_W3_INT_NOINT|(itf&CBM_QD_W3_SBID_MASK);
+               //RX: DMA QoS, downstream, no interrupt, AAL5(EPD, PPD), NO INT, HCR
+#ifdef AMAZON_TPE_SCR
+               rx_config |= dma_qos|CBM_QD_W3_DIR_DOWN|CBM_QD_W3_INT_EOF;
+#else          
+               rx_config |= dma_qos|CBM_QD_W3_DIR_DOWN|CBM_QD_W3_INT_NOINT|CBM_QD_W3_HCR;
+#endif         
+       }else {
+               //should be AAL0        
+               //upstream, NOINT, SBid
+               tx_config |= CBM_QD_W3_DIR_UP|CBM_QD_W3_INT_NOINT|(itf&CBM_QD_W3_SBID_MASK);
+               //RX: downstream, ACA interrupt, 
+               rx_config |= CBM_QD_W3_DIR_DOWN|CBM_QD_W3_INT_ACA;
+       }
+
+       //Threshold: maximum threshold for tx/rx queue, which is adjustable in steps of 64 cells
+       tx_config |=    ( (divide_by_64_round_up(tx_q_threshold)&0xffff)<<CBM_QD_W3_THRESHOLD_SHIFT) & CBM_QD_W3_THRESHOLD_MASK;
+       rx_config |=    ( (divide_by_64_round_up(rx_q_threshold)&0xffff)<<CBM_QD_W3_THRESHOLD_SHIFT) & CBM_QD_W3_THRESHOLD_MASK;
+       
+       qd_addr = (u8*) KSEG1ADDR((unsigned long)g_atm_dev.cbm.qd_addr);
+       //TX
+       AMAZON_WRITE_REGISTER_L(tx_config, (qd_addr+qid*CBM_QD_SIZE + 0xc));
+       AMAZON_WRITE_REGISTER_L(0, (qd_addr+qid*CBM_QD_SIZE + 0x8));
+       //RX
+       AMAZON_WRITE_REGISTER_L(rx_config, (qd_addr+(qid+CBM_RX_OFFSET)*CBM_QD_SIZE + 0xc));
+       AMAZON_WRITE_REGISTER_L(0, (qd_addr+(qid+CBM_RX_OFFSET)*CBM_QD_SIZE + 0x8));
+}
+/*
+ * Brief:      add HTU table entry
+ * Parameter:  
+ *     vpi.vci:
+ *     qid:    CBM queue id (DEST is qid + CBM_RX_OFFSET)
+ *     idx:    entry id (starting from zero to 14)
+ * Return:
+ *     0:      sucessful
+ *     EIO:    HTU table entry cannot be written
+ */
+
+inline int set_htu_entry(u8 vpi, u16 vci, u8 qid, u8 idx)
+{
+       int i = 0;
+       u32 tmp1=0;
+       while ((tmp1 = readl(HTU_RAMSTAT_ADDR))!=0 && i < 1024) i++;
+       if (i > 1024)
+       {
+               AMAZON_TPE_EMSG("timeout\n");
+               return -EIO;
+       }
+       // write address register,
+       AMAZON_WRITE_REGISTER_L(idx, HTU_RAMADDR_ADDR);
+       // configure transmit queue
+       tmp1 = vpi<<24|vci<<8;
+       tmp1|=  HTU_RAMDAT1_VCON        // valid connection the entry is not validated here !!!!!!!!!!!!!!!!
+               |HTU_RAMDAT1_VCI3       // vci3 -> oam queue
+               |HTU_RAMDAT1_VCI4       // vci4 -> oam queue
+               |HTU_RAMDAT1_VCI6       // vci6 -> rm queue
+               |HTU_RAMDAT1_PTI4       // pti4 -> oam queue
+               |HTU_RAMDAT1_PTI5;      // pti5 -> oam queue
+
+       // ramdat 1 (in params & oam handling)
+       AMAZON_WRITE_REGISTER_L( tmp1, HTU_RAMDAT1_ADDR);
+       // ramdat 2 (out params & oam handling)
+       tmp1 = ((qid+CBM_RX_OFFSET)&HTU_RAMDAT2_QID_MASK)
+               |HTU_RAMDAT2_PTI6
+               |HTU_RAMDAT2_PTI7
+               |HTU_RAMDAT2_F4U
+               |HTU_RAMDAT2_F5U
+               ;
+       AMAZON_WRITE_REGISTER_L( tmp1, HTU_RAMDAT2_ADDR);
+       wmb();
+       // write HTU entry
+       AMAZON_WRITE_REGISTER_L(HTU_RAMCMD_WR, HTU_RAMCMD_ADDR);
+       return 0;
+}
+/*
+ * Brief:      add HTU table entry
+ * Parameter:  
+ *     vcc:    atm_vcc pointer
+ *     qid:    CBM queue id
+ * Return:
+ *     0:      sucessful
+ *     EIO:    HTU table entry cannot be written
+ */
+inline static int set_htu(struct atm_vcc *vcc, u32 qid)
+{
+       return set_htu_entry(vcc->vpi, vcc->vci, qid, (qid - CBM_DEFAULT_Q_OFFSET));
+}
+
+/* 
+ * Brief:      allocate a queue
+ * Return:     
+ *             <=0     no available queues
+ *             >0      qid
+ */
+static int atm_allocate_q(short itf)
+{
+       int i;
+       u32 tmp1=0;
+       int qid=0;
+       amazon_atm_port_t * dev;
+       dev = &g_atm_dev.ports[itf];
+       //find start queue id for this interface
+       for (i=0; i< itf; i++)
+       {
+               qid+= g_atm_dev.ports[i].max_conn;
+       }
+       // apply default queue offset ( oam, free cell queue, others, rm )
+       qid += CBM_DEFAULT_Q_OFFSET;
+       tmp1 = qid;
+       // search for a free queue
+       while ( (qid<tmp1+dev->max_conn)
+               && ( g_atm_dev.queues[qid].free != 1)) {
+               qid++;;
+       }
+       // if none was found, send failure message and return
+       if ( tmp1+dev->max_conn == qid)
+       {
+               return -EFAULT;
+       }
+       return qid;
+       
+}
+/* Brief:      open a aal5 or aal0 connection
+ */
+static int atm_open(struct atm_vcc *vcc, push_back_t push)
+{
+       int err=0;
+       int qid=0;
+       amazon_atm_port_t * port = & g_atm_dev.ports[vcc->itf];
+       unsigned long flags;
+       /***************** check bandwidth ******************/
+       /* 511045:linmars change ATM_VBR_NRT to use scr instead of pcr */
+       if ((vcc->qos.txtp.traffic_class==ATM_CBR&&vcc->qos.txtp.max_pcr>port->tx_rem_cr)
+       ||(vcc->qos.txtp.traffic_class==ATM_VBR_RT&&vcc->qos.txtp.max_pcr>port->tx_rem_cr)
+       ||(vcc->qos.txtp.traffic_class==ATM_VBR_NRT&&vcc->qos.txtp.scr>port->tx_rem_cr) 
+       ||(vcc->qos.txtp.traffic_class==ATM_UBR_PLUS&&vcc->qos.txtp.min_pcr>port->tx_rem_cr)
+       ) {
+                AMAZON_TPE_EMSG("not enough bandwidth left (%u) cells per seconds \n",port->tx_rem_cr);
+                return -EINVAL;
+       }
+       if ( (qid = amazon_atm_find_vpivci(vcc->vpi, vcc->vci)) >0 ){
+               AMAZON_TPE_EMSG("vpi:%u vci:%u is alreay open on queue:%u\n", vcc->vpi, vcc->vci, qid);
+               return -EADDRINUSE;
+       }
+
+       /***************** allocate entry queueID for this port *****************/
+       if ( (qid=atm_allocate_q(vcc->itf)) <= 0){
+               AMAZON_TPE_EMSG("port: %u max:%u qid: %u\n", vcc->itf, port->max_conn, qid);
+               AMAZON_TPE_EMSG("no availabel connections for this port:%u\n",vcc->itf);
+               return -EINVAL;
+       }
+       /**************QSB parameters and CBM descriptors*************/
+       set_qsb(vcc, &vcc->qos, qid);
+       set_qd(vcc, qid);
+       mb();
+       err=set_htu(vcc,qid);
+       if (err){
+               AMAZON_TPE_EMSG("set htu entry fails %u\n",err);
+               return err;
+       }
+       /************set internal mapping*************/
+       local_irq_save(flags);
+       g_atm_dev.queues[qid].free = 0;
+       g_atm_dev.queues[qid].vcc = vcc;
+       g_atm_dev.queues[qid].push = push;
+       g_atm_dev.queues[qid+CBM_RX_OFFSET].free = 0;
+       g_atm_dev.queues[qid+CBM_RX_OFFSET].vcc = vcc;
+       g_atm_dev.queues[qid+CBM_RX_OFFSET].push = push;
+       /******************reserve bandwidth**********************/
+       if (vcc->qos.txtp.traffic_class == ATM_CBR){
+               //CBR, real time connection, reserve PCR
+               port->tx_cur_cr += vcc->qos.txtp.max_pcr;
+               port->tx_rem_cr -= vcc->qos.txtp.max_pcr;
+       }else if (vcc->qos.txtp.traffic_class == ATM_VBR_RT){
+               //VBR_RT, real time connection, reserve PCR
+               port->tx_cur_cr += vcc->qos.txtp.max_pcr;
+               port->tx_rem_cr -= vcc->qos.txtp.max_pcr;
+       }else if (vcc->qos.txtp.traffic_class == ATM_VBR_NRT){
+               //VBR_NRT, reserve SCR
+               port->tx_cur_cr += vcc->qos.txtp.pcr;
+               port->tx_rem_cr -= vcc->qos.txtp.pcr;
+       }else if (vcc->qos.txtp.traffic_class == ATM_UBR_PLUS){
+               //UBR_PLUS, reserve MCR
+               port->tx_cur_cr += vcc->qos.txtp.min_pcr;
+               port->tx_rem_cr -= vcc->qos.txtp.min_pcr;
+       }
+       local_irq_restore(flags);
+       return err;
+}
+/* Brief:      Open ATM connection
+ * Parameters:         atm_vcc - Pointer to VCC data structure
+ *             vpi     - VPI value for new connection
+ *             vci     - VCI value for new connection
+ *
+ * Return:     0       - sucessful
+ *             -ENOMEM - No memory available
+ *             -EINVAL - No bandwidth/queue/ or unsupported AAL type
+ * Description:
+ *     This function opens an ATM connection on a specific device/interface
+ *
+ */
+int    amazon_atm_open(struct atm_vcc *vcc,push_back_t push)
+{
+       int err=0;
+
+       AMAZON_TPE_DMSG("vpi %u vci %u  itf %u aal %u\n"
+               ,vcc->vpi
+               ,vcc->vci
+               ,vcc->itf
+               ,vcc->qos.aal
+               );
+               
+       AMAZON_TPE_DMSG("tx cl %u bw %u mtu %u\n"
+               ,vcc->qos.txtp.traffic_class
+               ,vcc->qos.txtp.max_pcr
+               ,vcc->qos.txtp.max_sdu
+               );
+       AMAZON_TPE_DMSG("rx cl %u bw %u mtu %u\n"
+               ,vcc->qos.rxtp.traffic_class
+               ,vcc->qos.rxtp.max_pcr
+               ,vcc->qos.rxtp.max_sdu
+               );
+       if (vcc->qos.aal == ATM_AAL5 || vcc->qos.aal == ATM_AAL0){
+               err = atm_open(vcc,push);
+       }else{
+               AMAZON_TPE_EMSG("unsupported aal type %u\n", vcc->qos.aal);
+               err = -EPROTONOSUPPORT;
+       };
+       if (err == 0 ){
+               //replace the default memory allocation function with our own
+               vcc->alloc_tx = amazon_atm_alloc_tx;
+               set_bit(ATM_VF_READY,&vcc->flags);
+       }
+       return err;
+}
+
+/* Brief:      Send ATM OAM cell
+ * Parameters:         atm_vcc - Pointer to VCC data structure
+ *             skb     - Pointer to sk_buff structure, that contains the data
+ * Return:     0               - sucessful
+ *             -ENOMEM         - No memory available
+ *             -EINVAL         - Not supported
+ * Description:
+ * This function sends a cell over and ATM connection
+ * We always release the skb
+ * TODO: flags handling (ATM_OF_IMMED, ATM_OF_INRATE)
+ */
+int    amazon_atm_send_oam(struct atm_vcc *vcc, void * cell, int flags)
+{
+       int err=0;
+       int qid=0;
+       struct amazon_atm_cell_header * cell_header;
+       // Get cell header
+       cell_header = (struct amazon_atm_cell_header*) cell;
+       if ((cell_header->bit.pti == ATM_PTI_SEGF5) || (cell_header->bit.pti == ATM_PTI_E2EF5)) {
+               qid = amazon_atm_find_vpivci( cell_header->bit.vpi, cell_header->bit.vci);
+       }else if (cell_header->bit.vci == 0x3 || cell_header->bit.vci == 0x4) {
+               //507281:tc.chen qid = amazon_atm_find_vpi((int) cell_header->bit.vpi);
+               // 507281:tc.chen start
+               u8 f4_vpi;
+               f4_vpi = cell_header->bit.vpi;
+               qid = amazon_atm_find_vpi(f4_vpi );
+               // 507281:tc.chen end
+       }else{
+               //non-OAM cells, always invalid
+               qid = -EINVAL;
+       }
+       if (qid == -EINVAL) {
+               err =  -EINVAL;
+               AMAZON_TPE_EMSG("not valid AAL0 packet\n");
+       }else{
+               //send the cell using swie
+#ifdef TPE_LOOPBACK
+               err = amazon_atm_swin(AMAZON_ATM_OAM_Q_ID, cell);
+#else          
+               err = amazon_atm_swin(qid, cell);
+#endif
+       }
+       //kfree(cell);
+       return err;
+}
+
+/* Brief:      Send AAL5 frame through DMA
+ * Parameters:         vpi     - virtual path id 
+ *             vci     - virtual circuit id
+ *             clp     - cell loss priority
+ *             qid     - CBM queue to be sent to
+ *             skb     - packet to be sent
+ * Return:     0               - sucessful
+ *             -ENOMEM         - No memory available
+ *             -EINVAL         - Not supported
+ * Description:
+ * This function sends a AAL5 frame over and ATM connection
+ *     1. make sure that the data is aligned to 4x32-bit boundary
+ *     2. provide the inbound data (CPCS-UU and CPI, not used here)
+ *     3. set CLPn
+ *     4. send the frame by DMA
+ *     5. release the buffer ???
+ ** use our own allocation alloc_tx
+ ** we make sure the alignment and additional memory
+ *** we always release the skb
+
+ */
+int amazon_atm_dma_tx(u8 vpi, u16 vci, u8 clp, u8 qid, struct sk_buff *skb) 
+{
+       int err=0,need_pop=1;
+       u32 * data=NULL;
+       int nwrite=0;
+       struct sk_buff *skb_tmp;
+       u32 len=skb->len;       
+
+       //AAL5S inbound header 8 bytes
+       if (skb->len > g_atm_dev.aal5.tx_max_sdu - AAL5S_INBOUND_HEADER) {
+               AMAZON_TPE_DMSG("tx_max_sdu:%u\n",g_atm_dev.aal5.tx_max_sdu); 
+               AMAZON_TPE_DMSG("skb too large [%u]!\n",skb->len);
+               err = -EMSGSIZE;
+               goto atm_dma_tx_error_exit;
+       }
+       
+       //Check the byte alignment requirement and header space
+       if ( ( ((u32)(skb->data)%16) !=AAL5S_INBOUND_HEADER)|| (skb_headroom(skb)<AAL5S_INBOUND_HEADER)){
+               //not aligned or no space for header, fall back to memcpy
+               skb_tmp = dev_alloc_skb(skb->len+16);
+               if (skb_tmp==NULL){
+                       err = - ENOMEM;                 
+                       goto atm_dma_tx_error_exit;     
+               }
+               alloc_align_16(skb_tmp);
+               g_atm_dev.aal5.cnt_cpy++;
+               skb_reserve(skb_tmp,AAL5S_INBOUND_HEADER);
+               memcpy(skb_put(skb_tmp,skb->len), skb->data, skb->len);
+               amazon_atm_free_tx_skb(skb);
+               need_pop=0;
+               skb = skb_tmp;
+       }
+       //Provide AAL5S inbound header
+       data = (u32 *)skb_push(skb,8);
+       data[0] = __be32_to_cpu(vpi<<20|vci<<4|clp);
+       data[1] = __be32_to_cpu(g_atm_dev.aal5.padding_byte<<8|qid);
+       
+       len = skb->len;
+
+       //send through DMA
+       AMAZON_TPE_DMSG("AAL5S header 0 %8x\n", data[0]);
+       AMAZON_TPE_DMSG("AAL5S header 0 %8x\n", data[1]);
+       AMAZON_TPE_DMSG("about to call dma_write len: %u\n", len);
+       nwrite=dma_device_write( &g_dma_dev,skb->data,len,skb);
+       if (nwrite != len) {
+               //DMA descriptors full
+//             AMAZON_TPE_EMSG("AAL5 packet drop due to DMA nwrite:%u skb->len:%u\n", nwrite,len);
+               AMAZON_TPE_DMSG("AAL5 packet drop due to DMA nwrite:%u skb->len:%u\n", nwrite,len);
+               err = -EAGAIN;
+               goto atm_dma_tx_drop_exit;
+       }
+       AMAZON_TPE_DMSG("just finish call dma_write\n");
+       //release in the "dma done" call-back
+       return 0;
+atm_dma_tx_error_exit:
+       g_atm_dev.mib_counter.tx_err++; 
+       queue_statics(qid, QS_ERR);
+       goto atm_dma_tx_exit;
+       
+atm_dma_tx_drop_exit:
+       g_atm_dev.mib_counter.tx_drop++;
+       queue_statics(qid, QS_SW_DROP);
+atm_dma_tx_exit:
+       if (need_pop){
+               amazon_atm_free_tx_skb(skb);
+       }else{
+               dev_kfree_skb_any(skb);
+       }
+       return err;
+}
+
+/* Brief:      Send AAL0/AAL5 packet
+ * Parameters:         atm_vcc - Pointer to VCC data structure
+ *             skb     - Pointer to sk_buff structure, that contains the data
+ * Return:     0               - sucessful
+ *             -ENOMEM         - No memory available
+ *             -EINVAL         - Not supported
+ * Description:
+ *     See amazon_atm_dma_tx
+ */
+int    amazon_atm_send(struct atm_vcc *vcc,struct sk_buff *skb)
+{
+       int qid=0;
+       u8 clp=0;
+        int err=0;
+       u32 wm=0;
+
+       if (vcc == NULL || skb == NULL){
+               AMAZON_TPE_EMSG("invalid parameter\n");
+               return -EINVAL;
+       }
+       ATM_SKB(skb)->vcc = vcc;
+       qid = amazon_atm_get_queue(vcc);
+       if (valid_qid(qid) != 1) {
+               AMAZON_TPE_EMSG("invalid vcc!\n");
+               err = -EINVAL;
+               goto atm_send_err_exit;
+       }
+       
+       //Send AAL0 using SWIN
+       if (vcc->qos.aal == ATM_AAL0){
+#ifdef  TPE_LOOPBACK
+               err=amazon_atm_swin((qid+CBM_RX_OFFSET), skb->data);    
+#else
+               err=amazon_atm_swin(qid, skb->data);
+#endif
+               if (err){
+                       goto atm_send_err_exit;
+               }       
+               goto atm_send_exit;
+       }
+       
+       //Should be AAl5
+       //MIB counter
+       g_atm_dev.mib_counter.tx++;
+       adsl_led_flash();//joelin adsl led
+       queue_statics(qid, QS_PKT);
+
+#ifdef AMAZON_CHECK_LINK
+       //check adsl link 
+       if (adsl_link_status == 0){
+               //link down
+               AMAZON_TPE_DMSG("ADSL link down, discarded!\n");
+               err=-EFAULT;
+               goto atm_send_drop_exit;
+       }
+#endif
+       clp = (vcc->atm_options&ATM_ATMOPT_CLP)?1:0;
+       //check watermark first
+       wm = readl(CBM_WMSTAT0_ADDR);
+       if (  (wm & (1<<qid))
+           ||( (vcc->qos.txtp.traffic_class != ATM_CBR
+                &&vcc->qos.txtp.traffic_class != ATM_VBR_RT) 
+               &(wm & (CBM_WM_NRT_MASK | (clp&CBM_WM_CLP1_MASK)) ))){
+               //wm hit: discard
+               AMAZON_TPE_DMSG("watermark hit, discarded!\n");
+               err=-EFAULT;
+               goto atm_send_drop_exit;
+       }
+#ifdef  TPE_LOOPBACK
+       return amazon_atm_dma_tx(vcc->vpi, vcc->vci,clp, (qid+CBM_RX_OFFSET),skb);
+#else  
+       return amazon_atm_dma_tx(vcc->vpi, vcc->vci,clp, qid,skb);
+#endif
+
+atm_send_exit: 
+       amazon_atm_free_tx_skb_vcc(vcc,skb);    
+       return 0;
+       
+atm_send_drop_exit:
+       g_atm_dev.mib_counter.tx_drop++;
+       queue_statics(qid,QS_SW_DROP);
+atm_send_err_exit:     
+       amazon_atm_free_tx_skb_vcc(vcc,skb);
+       return err;
+}
+
+/* Brief:      Return ATM port related MIB
+ * Parameter:  interface number
+        atm_cell_ifEntry_t
+ */
+int amazon_atm_cell_mib(atm_cell_ifEntry_t* to,u32 itf)
+{
+       g_atm_dev.mib_counter.htu_unp += readl(HTU_MIBCIUP);
+       to->ifInUnknownProtos = g_atm_dev.mib_counter.htu_unp;
+#ifdef AMAZON_TPE_READ_ARC
+       u32 reg_val=0;
+       meiDebugRead((AR_CELL0_ADDR+itf*4),&reg_val,1);
+       g_atm_dev.mib_counter.rx_cells += reg_val;
+       reg_val=0;
+       meiDebugWrite((AR_CELL0_ADDR+itf*4),&reg_val,1);
+       to->ifHCInOctets_h = (g_atm_dev.mib_counter.rx_cells * 53)>>32;
+       to->ifHCInOctets_l = (g_atm_dev.mib_counter.rx_cells * 53) & 0xffff;
+       
+       meiDebugRead((AT_CELL0_ADDR+itf*4),&reg_val,1);
+       g_atm_dev.mib_counter.tx_cells += reg_val;
+       reg_val=0;
+       meiDebugWrite((AT_CELL0_ADDR+itf*4),&reg_val,1);
+       to->ifHCOutOctets_h = (g_atm_dev.mib_counter.tx_cells * 53)>>32;
+       to->ifHCOutOctets_l = (g_atm_dev.mib_counter.rx_cells * 53) & 0xffff;
+       
+       meiDebugRead((AR_CD_CNT0_ADDR+itf*4),&reg_val,1);
+       g_atm_dev.mib_counter.rx_err_cells += reg_val;
+       reg_val=0;
+       meiDebugWrite((AR_CD_CNT0_ADDR+itf*4),&reg_val,1);
+       to->ifInErrors = g_atm_dev.mib_counter.rx_err_cells;
+       
+       to->ifOutErrors = 0;
+#else
+       to->ifHCInOctets_h = 0;
+       to->ifHCInOctets_l = 0;
+       to->ifHCOutOctets_h = 0;
+       to->ifHCOutOctets_l = 0;
+       to->ifInErrors = 0;
+       to->ifOutErrors = 0;
+#endif
+       return 0;
+}
+
+/* Brief:      Return ATM AAL5 related MIB
+ * Parameter:
+        atm_aal5_ifEntry_t
+ */
+int amazon_atm_aal5_mib(atm_aal5_ifEntry_t* to)
+{
+       u32 reg_l,reg_h;
+       //AAL5R received Octets from ATM
+       reg_l = readl(AAL5_RIOL_ADDR);
+       reg_h = readl(AAL5_RIOM_ADDR);
+       g_atm_dev.mib_counter.rx_cnt_h +=reg_h;
+       if (reg_l + g_atm_dev.mib_counter.rx_cnt_l < reg_l){
+               g_atm_dev.mib_counter.rx_cnt_h++;
+       }
+       
+       g_atm_dev.mib_counter.rx_cnt_l+= reg_l;
+       //AAL5S sent Octets to ATM
+       reg_l = readl(AAL5_SOOL_ADDR);
+       reg_h = readl(AAL5_SOOM_ADDR);
+       g_atm_dev.mib_counter.tx_cnt_h +=reg_h;
+       if (reg_l + g_atm_dev.mib_counter.tx_cnt_l < reg_l){
+               g_atm_dev.mib_counter.tx_cnt_h++;
+       }
+       g_atm_dev.mib_counter.tx_cnt_l+= reg_l;
+
+
+       g_atm_dev.mib_counter.tx_ppd += readl(CBM_AAL5ODIS_ADDR);
+       g_atm_dev.mib_counter.rx_drop += readl(CBM_AAL5IDIS_ADDR);
+       
+       //store 
+       to->ifHCInOctets_h = g_atm_dev.mib_counter.rx_cnt_h;
+       to->ifHCInOctets_l = g_atm_dev.mib_counter.rx_cnt_l;
+       to->ifHCOutOctets_h = g_atm_dev.mib_counter.tx_cnt_h;
+       to->ifHCOutOctets_l = g_atm_dev.mib_counter.tx_cnt_l;
+       to->ifOutDiscards = g_atm_dev.mib_counter.tx_drop;
+       to->ifInDiscards = g_atm_dev.mib_counter.rx_drop;
+
+       //Software provided counters
+       //packets passed to higher layer
+       to->ifInUcastPkts = g_atm_dev.mib_counter.rx;
+       //packets passed from higher layer
+       to->ifOutUcastPkts = g_atm_dev.mib_counter.tx;
+       //number of wrong downstream packets
+       to->ifInErrors = g_atm_dev.mib_counter.rx_err;
+       //number of wrong upstream packets
+       to->ifOutErros = g_atm_dev.mib_counter.tx_err;
+
+       return 0;
+}
+/* Brief:      Return ATM AAL5 VCC related MIB from internale use
+ * Parameter:
+ *     qid
+ *     atm_aal5_vcc_t
+ */
+static int __amazon_atm_vcc_mib(int qid, atm_aal5_vcc_t* to)
+{
+       //aal5VccCrcErrors
+       to->aal5VccCrcErrors = g_atm_dev.queues[qid].aal5VccCrcErrors;
+       to->aal5VccOverSizedSDUs =g_atm_dev.queues[qid].aal5VccOverSizedSDUs;
+       to->aal5VccSarTimeOuts = 0; //not supported yet
+       return 0;
+}
+/* Brief:      Return ATM AAL5 VCC related MIB from vpi/vci
+ * Parameter:  atm_vcc
+ *      atm_aal5_vcc_t
+ */
+int amazon_atm_vcc_mib_x(int vpi, int vci,atm_aal5_vcc_t* to)
+{
+       int qid=0;
+       int err=0;
+       qid =  amazon_atm_find_vpivci(vpi, vci);
+       if (qid >0 ){
+               err = __amazon_atm_vcc_mib(qid,to);
+       }else{
+               return -EINVAL;
+       }
+       return err;
+}
+
+
+/* Brief:      Return ATM AAL5 VCC related MIB
+ * Parameter:  atm_vcc
+ *      atm_aal5_vcc_t
+ */
+int amazon_atm_vcc_mib(struct atm_vcc *vcc,atm_aal5_vcc_t* to)
+{
+       int qid=0;
+       int err=0;
+       qid =  amazon_atm_get_queue(vcc);
+       if (qid >0 ){
+               err = __amazon_atm_vcc_mib(qid,to);
+       }else{
+               return -EINVAL;
+       }
+       return err;
+}
+
+/* Brief:      Close ATM connection
+ * Parameters:         atm_vcc - Pointer to VCC data structure
+ * Return:     no
+ * Description:
+ * This function closes the given ATM connection
+ */
+void   amazon_atm_close(struct atm_vcc *vcc){
+       int i;
+       int qid=0;
+       u32 tmp1;
+       u8 * qd_addr;
+       unsigned long flags;
+       if (vcc == NULL){
+               AMAZON_TPE_EMSG("invalid parameter. vcc is null\n");
+               return;
+       }
+       u32 itf = (u32) vcc->itf;
+       //release bandwidth
+       if (vcc->qos.txtp.traffic_class == ATM_CBR){
+               g_atm_dev.ports[itf].tx_rem_cr += vcc->qos.txtp.max_pcr;
+               g_atm_dev.ports[itf].tx_cur_cr -= vcc->qos.txtp.max_pcr;
+       }else if (vcc->qos.txtp.traffic_class == ATM_VBR_RT){
+               g_atm_dev.ports[itf].tx_rem_cr += vcc->qos.txtp.max_pcr;
+               g_atm_dev.ports[itf].tx_cur_cr -= vcc->qos.txtp.max_pcr;
+       }else if (vcc->qos.txtp.traffic_class == ATM_VBR_NRT){
+               g_atm_dev.ports[itf].tx_rem_cr += vcc->qos.txtp.pcr;
+               g_atm_dev.ports[itf].tx_cur_cr -= vcc->qos.txtp.pcr;
+       }else if (vcc->qos.txtp.traffic_class == ATM_UBR_PLUS){
+               g_atm_dev.ports[itf].tx_rem_cr += vcc->qos.txtp.min_pcr;
+               g_atm_dev.ports[itf].tx_cur_cr -= vcc->qos.txtp.min_pcr;
+       }
+
+       qid = amazon_atm_get_queue(vcc);
+       if (qid == -EINVAL){
+               AMAZON_TPE_EMSG("unknown vcc %u.%u.%u\n", vcc->itf, vcc->vpi, vcc->vci);
+               return;
+       }
+       local_irq_save(flags);
+       //Disable HTU entry
+       i=0;
+       while ((tmp1 = readl(HTU_RAMSTAT_ADDR))!=0 && i < HTU_RAM_ACCESS_MAX) i++;
+       if (i == HTU_RAM_ACCESS_MAX){
+               AMAZON_TPE_EMSG("HTU RAM ACCESS out of time\n");
+       }
+
+       // write address register
+       AMAZON_WRITE_REGISTER_L(qid - CBM_DEFAULT_Q_OFFSET, HTU_RAMADDR_ADDR);
+       // invalidate the connection
+       AMAZON_WRITE_REGISTER_L(0, HTU_RAMDAT1_ADDR);
+       // write command
+       AMAZON_WRITE_REGISTER_L(HTU_RAMCMD_WR,HTU_RAMCMD_ADDR);
+       
+       qd_addr = (u8 *) KSEG1ADDR((unsigned long)g_atm_dev.cbm.qd_addr);
+#ifdef AMAZON_ATM_DEBUG
+       tmp1 = readl(qd_addr+qid*CBM_QD_SIZE+0x8) & 0xffff;
+       AMAZON_TPE_DMSG("TX queue has %u cells \n", tmp1);
+       tmp1 = readl( qd_addr+(qid+CBM_RX_OFFSET)*CBM_QD_SIZE+0x08)&0xffff;
+       AMAZON_TPE_DMSG("RX queue has %u cells \n", tmp1);
+#endif 
+       // set threshold of txqueue to 0
+       tmp1 = readl(qd_addr+qid*CBM_QD_SIZE+0x0c);
+       tmp1&= (~ CBM_QD_W3_THRESHOLD_MASK);
+       AMAZON_WRITE_REGISTER_L(tmp1, (qd_addr+qid*CBM_QD_SIZE+0x0c));
+       // set threshold of rxqueue to 0
+       tmp1 = readl( qd_addr+(qid+CBM_RX_OFFSET)*CBM_QD_SIZE+0x0c);
+       tmp1&= (~ CBM_QD_W3_THRESHOLD_MASK);
+       AMAZON_WRITE_REGISTER_L(tmp1,(qd_addr+(qid+CBM_RX_OFFSET)*CBM_QD_SIZE+0x0c));
+
+       //clear internal mapping
+       amazon_atm_clear_vcc(qid);
+       amazon_atm_clear_vcc(qid+CBM_RX_OFFSET);
+
+       local_irq_restore(flags);
+}
+
+
+/* Brief:      initialize internal data structure
+ */
+static void atm_constructor(amazon_atm_dev_t * dev)
+{
+       int i;
+       memset(dev,0,sizeof(amazon_atm_dev_t));
+       atm_init_parameters(dev);
+       //internal: queue "free" flag
+       for(i=1;i<AMAZON_ATM_MAX_QUEUE_NUM;i++) {
+               //dev->queues[i].vcc=NULL;
+               dev->queues[i].free = 1;
+       }
+       for(i=0;i<AMAZON_ATM_PORT_NUM;i++){
+               dev->ports[i].tx_rem_cr = dev->ports[i].tx_max_cr;
+       }
+       //MIB
+       atomic_set(&dev->dma_tx_free_0,1); //initially there should be free descriptors
+}
+
+/* Brief:      return round up base-2 logarithm
+ */
+static inline int get_log_2(u32 value)
+{
+       int i=0,j=1;
+       while (i<11){
+               if (j>=value) break;
+               j=j<<1;
+               i++;
+       }
+       AMAZON_TPE_DMSG("round up base-2 logarithm of %u is %u\n", value, i);
+       return i;
+}
+
+/* Brief:      TPE hardware initialization
+ * Parameter:  specifiy the configurations of the hardware
+ */
+static inline int atm_init_hard(amazon_atm_dev_t * dev)
+{
+       int i;
+       u32 tmp1, tmp2, tmp3;
+       u8 * mem_addr=NULL;
+       u8 * qd_addr=NULL;
+       //PMU power on the module 1st
+       *(AMAZON_PMU_PWDCR) =   (*AMAZON_PMU_PWDCR) | (AMAZON_PMU_PWDCR_TPE);
+       //Reset the module
+       *(AMAZON_RST_REQ) = (* AMAZON_RST_REQ) | (AMAZON_RST_REQ_TPE);
+       mb();
+       mdelay(100);
+       *(AMAZON_RST_REQ) = (* AMAZON_RST_REQ) & (~(AMAZON_RST_REQ_TPE));
+       mb();
+       
+       unsigned long qsb_clk = amazon_get_fpi_hz()>>1;
+       /*********allocate & arrange memory for CBM *********/
+       if (dev->cbm.mem_addr == NULL){
+               dev->cbm.allocated = 1;
+               mem_addr = (u8 *)__get_free_pages(GFP_KERNEL, get_log_2(((CBM_CELL_SIZE * dev->cbm.free_cell_cnt) >>PAGE_SHIFT) + 1));
+               if (mem_addr != NULL){ 
+                       dev->cbm.mem_addr = mem_addr;
+               } else  {
+                       goto init_no_mem;
+               }
+       }
+       if (dev->cbm.qd_addr == NULL){
+#ifdef CONFIG_USE_VENUS
+               //to work around a bug, bit15 of QDOFF address should be 1,Aug4, 2004
+               //thus, we allocate 64k memory          
+               qd_addr = (u8 *)__get_free_pages(GFP_KERNEL, 4);
+               if (qd_addr != NULL) {
+                       dev->cbm.qd_addr_free = (u8*) (((unsigned long) qd_addr));
+                       dev->cbm.qd_addr = (u8*) (((unsigned long) qd_addr) | 0x8000);
+               }else{
+                       goto init_no_mem;
+               }
+#else  //CONFIG_USE_VENUS
+               qd_addr = (u8 *)kmalloc( CBM_QD_SIZE * AMAZON_ATM_MAX_QUEUE_NUM, GFP_KERNEL);
+               if (qd_addr != NULL) {
+                       dev->cbm.qd_addr = qd_addr;
+               }else {
+                       goto init_no_mem;
+               }
+#endif //CONFIG_USE_VENUS                      
+       }
+//#ifndef CONFIG_MIPS_UNCACHED
+       mem_addr = (u8 *)KSEG1ADDR((unsigned long)dev->cbm.mem_addr);
+       qd_addr = (u8 *)KSEG1ADDR((unsigned long)dev->cbm.qd_addr);
+//#endif
+       //CBM reset cell queue memory, 64 bytes / cell
+       memset_io(mem_addr, 0, CBM_CELL_SIZE * dev->cbm.free_cell_cnt);
+       //make a link list, last 4 bytes is pointer
+       for(i=1;i<dev->cbm.free_cell_cnt;i++){
+               AMAZON_WRITE_REGISTER_L(CPHYSADDR((mem_addr + CBM_CELL_SIZE * i)),(mem_addr + CBM_CELL_SIZE * (i-1) + 0x3c));
+       }
+       //reset queue descriptor
+       memset_io(qd_addr, 0, CBM_QD_SIZE * AMAZON_ATM_MAX_QUEUE_NUM);
+       //init word 0-2 of q0 (free cell list)
+       //address of last cell
+       AMAZON_WRITE_REGISTER_L(CPHYSADDR((mem_addr + CBM_CELL_SIZE * (dev->cbm.free_cell_cnt-1))), qd_addr);
+       //address of first cell
+       AMAZON_WRITE_REGISTER_L(CPHYSADDR((mem_addr)), (qd_addr + 4));
+       //no. of free cells
+       AMAZON_WRITE_REGISTER_L(dev->cbm.free_cell_cnt,(qd_addr + 8));
+       //init q descriptor for OAM receiving
+       AMAZON_WRITE_REGISTER_L((CBM_QD_W3_INT_ACA | (divide_by_64_round_up(oam_q_threshold)&0xff)<< CBM_QD_W3_THRESHOLD_SHIFT), (qd_addr + AMAZON_ATM_OAM_Q_ID * CBM_QD_SIZE + 0x0c));
+//     AMAZON_WRITE_REGISTER_L((CBM_QD_W3_INT_ACA | (u32)oam_q_threshold<< CBM_QD_W3_THRESHOLD_SHIFT), (qd_addr + AMAZON_ATM_OAM_Q_ID * CBM_QD_SIZE + 0x0c));
+       //config CBM
+       //set offset address and threshold
+       AMAZON_WRITE_REGISTER_L(CPHYSADDR(qd_addr), CBM_QDOFF_ADDR);
+       AMAZON_WRITE_REGISTER_L(((dev->cbm.nrt_thr&CBM_THR_MASK)|CBM_WM_3_1), CBM_NRTTHR_ADDR);
+       AMAZON_WRITE_REGISTER_L(((dev->cbm.clp0_thr&CBM_THR_MASK)|CBM_WM_3_1), CBM_CLP0THR_ADDR);
+       AMAZON_WRITE_REGISTER_L(((dev->cbm.clp1_thr&CBM_THR_MASK)|CBM_WM_3_1), CBM_CLP1THR_ADDR);
+       //config interrupts
+       AMAZON_WRITE_REGISTER_L( CBM_IMR_MASK & (~(CBM_IMR_ACA|CBM_IMR_Q0E|CBM_IMR_Q0I|CBM_IMR_RDE|CBM_IMR_OPF|CBM_IMR_ERR              
+#ifdef AMAZON_ATM_DEBUG        
+                                               |CBM_IMR_DISC|CBM_IMR_QFD|CBM_IMR_NFCA|CBM_IMR_CLP1TR|CBM_IMR_CLP0TR|CBM_IMR_NRTTR|CBM_IMR_QTR
+#endif 
+#ifdef AMAZON_TPE_SCR
+                                               |CBM_IMR_EF 
+#endif
+                                                       )), CBM_IMR0_ADDR);
+       AMAZON_WRITE_REGISTER_L(SRC_CLRR|SRC_TOS_MIPS | SRC_SRE_ENABLE | AMAZON_CBM_INT, CBM_SRC0_ADDR);
+       
+       //HTU
+       //RAM entry for number of possible connections per interface
+       tmp1 = dev->ports[0].max_conn?dev->ports[0].max_conn-1:0;
+       AMAZON_WRITE_REGISTER_L(tmp1, HTU_RX0_ADDR);
+       for(i=1;i<AMAZON_ATM_PORT_NUM;i++){
+               tmp1+=dev->ports[i].max_conn;
+               AMAZON_WRITE_REGISTER_L(tmp1, HTU_RX0_ADDR + 4 * i);
+       }
+       dev->cbm.max_q_off = tmp1+1;
+       //Queue ID for OAM/RM/Other cells
+       AMAZON_WRITE_REGISTER_L (AMAZON_ATM_OAM_Q_ID, HTU_DESTOAM_ADDR);
+       AMAZON_WRITE_REGISTER_L( AMAZON_ATM_RM_Q_ID, HTU_DESTRM_ADDR);
+       AMAZON_WRITE_REGISTER_L( AMAZON_ATM_OTHER_Q_ID, HTU_DESTOTHER_ADDR);
+       //Timeout
+       AMAZON_WRITE_REGISTER_L((u32) HTUTIMEOUT, HTU_TIMEOUT_ADDR);
+#ifdef AMAZON_ATM_DEBUG
+        AMAZON_WRITE_REGISTER_L((u32) HTU_ISR_MASK 
+                               &(~(HTU_ISR_NE|HTU_ISR_TORD|HTU_ISR_OTOC|HTU_ISR_ONEC|HTU_ISR_PNE|HTU_ISR_PT)), HTU_IMR0_ADDR);
+       AMAZON_WRITE_REGISTER_L(SRC_CLRR|SRC_TOS_MIPS|SRC_SRE_ENABLE|AMAZON_HTU_INT,HTU_SRC0_ADDR);
+#endif
+       //QSB
+       //global setting, TstepC, SBL, Tau
+       //Tau
+       AMAZON_WRITE_REGISTER_L(dev->qsb.tau, QSB_TAU_ADDR);
+       //SBL
+       AMAZON_WRITE_REGISTER_L(dev->qsb.sbl, QSB_SBL_ADDR);
+       //tstep
+       AMAZON_WRITE_REGISTER_L(dev->qsb.tstepc>>1, QSB_CONFIG_ADDR);
+
+       //port settting
+       for(i=0;i<AMAZON_ATM_PORT_NUM;i++){
+               if ( (dev->ports[i].enable) && (dev->ports[i].tx_max_cr!=0) ){
+                       tmp1 = ((qsb_clk * dev->qsb.tstepc) >>1) / dev->ports[i].tx_max_cr;
+                       tmp2 = tmp1 / 64;       //integer value of Tsb
+                       tmp3 = tmp1%64 + 1;     //fractional part of Tsb
+                       //carry over to integer part (?)
+                       if (tmp3 == 64) {
+                               tmp3 = 0;
+                               tmp2++;
+                       }
+                       if (tmp2 == 0){
+                               tmp2 = 1;
+                               tmp3 = 1;
+                       }
+                       //1. set mask 2. write value to data transfer register 3. start the transfer
+                       //SCT(FracRate)
+                       AMAZON_WRITE_REGISTER_L(QSB_SET_SCT_MASK, QSB_RTM_ADDR);
+                       AMAZON_WRITE_REGISTER_L(tmp3,QSB_RTD_ADDR);
+                       AMAZON_WRITE_REGISTER_L(((QSB_TABLESEL_SCT<<QSB_TABLESEL_SHIFT)|QSB_RAMAC_REG_LOW|QSB_WRITE|i),QSB_RAMAC_ADDR);
+                       //SPT(SBV + PN + IntRage)
+                       AMAZON_WRITE_REGISTER_L(QSB_SET_SPT_MASK, QSB_RTM_ADDR);
+                       AMAZON_WRITE_REGISTER_L(QSB_SPT_SBVALID|tmp2|(i<<16),QSB_RTD_ADDR);
+                       AMAZON_WRITE_REGISTER_L(((QSB_TABLESEL_SPT<<QSB_TABLESEL_SHIFT)|QSB_RAMAC_REG_LOW|QSB_WRITE|i),QSB_RAMAC_ADDR);
+
+
+               }
+       }
+       
+       //SWIE: Setup Service Request Control Registers to enable interrupts
+       AMAZON_WRITE_REGISTER_L(SRC_CLRR|SRC_TOS_MIPS | SRC_SRE_ENABLE | AMAZON_SWIE_INT, SWIE_ISRC_ADDR);
+       AMAZON_WRITE_REGISTER_L(SRC_CLRR|SRC_TOS_MIPS | SRC_SRE_ENABLE | AMAZON_SWIE_INT, SWIE_ESRC_ADDR);
+
+       wmb();
+#ifdef AMAZON_TPE_TEST_AAL5_INT
+       AMAZON_WRITE_REGISTER_L(AAL5R_ISR_FE,AAL5_RIMR0_ADDR);
+       AMAZON_WRITE_REGISTER_L(0, AAL5_SIMR0_ADDR);
+       AMAZON_WRITE_REGISTER_L(SRC_CLRR|SRC_TOS_MIPS | SRC_SRE_ENABLE | AMAZON_AAL5_INT,AAL5_SSRC0_ADDR);
+       AMAZON_WRITE_REGISTER_L(SRC_CLRR|SRC_TOS_MIPS | SRC_SRE_ENABLE | AMAZON_AAL5_INT,AAL5_RSRC0_ADDR);
+#endif //AMAZON_TPE_TEST_AAL5_INT
+
+       AMAZON_WRITE_REGISTER_L(dev->aal5.tx_max_sdu,AAL5_SMFL_ADDR);   
+       AMAZON_WRITE_REGISTER_L(dev->aal5.rx_max_sdu,AAL5_RMFL_ADDR);
+       AMAZON_WRITE_REGISTER_L(AAL5_SCMD_MODE_POLL // enable polling mode
+                                       |AAL5_SCMD_SS
+                                       |AAL5_SCMD_AR
+                                       ,AAL5_SCMD_ADDR);
+       //start CBM
+       AMAZON_WRITE_REGISTER_L(CBM_CFG_START,CBM_CFG_ADDR);
+       wmb();
+       return 0;
+init_no_mem:
+       if (mem_addr != NULL) free_pages((unsigned long)mem_addr,get_log_2(((CBM_CELL_SIZE * dev->cbm.free_cell_cnt) >>PAGE_SHIFT) + 1));
+       
+#ifdef CONFIG_USE_VENUS        
+       //to work around a bug, bit15 of QDOFF address should be 1
+       if (qd_addr != NULL) free_pages((unsigned long)qd_addr,4);
+#else //CONFIG_USE_VENUS
+       if (qd_addr != NULL) kfree(qd_addr);    
+#endif //CONFIG_USE_VENUS      
+       return -ENOMEM;
+}
+
+/*     
+ *     Brief:  Create entry in /proc for status information
+ */
+void atm_create_proc(void)
+{
+       create_proc_read_entry("amazon_atm", 0,NULL, amazon_atm_read_procmem,(void*)PROC_ATM);
+        create_proc_read_entry("amazon_atm_mib", 0,NULL, amazon_atm_read_procmem,(void*)PROC_MIB);
+        create_proc_read_entry("amazon_atm_vcc", 0,NULL, amazon_atm_read_procmem,(void*)PROC_VCC);
+#if 0  
+       create_proc_read_entry("amazon_atm_aal5", 0,NULL, amazon_atm_read_procmem,(void*)PROC_AAL5);
+        create_proc_read_entry("amazon_atm_cbm", 0,NULL, amazon_atm_read_procmem,(void*)PROC_CBM);
+        create_proc_read_entry("amazon_atm_htu", 0,NULL, amazon_atm_read_procmem,(void*)PROC_HTU);
+        create_proc_read_entry("amazon_atm_qsb", 0,NULL, amazon_atm_read_procmem,(void*)PROC_QSB);
+        create_proc_read_entry("amazon_atm_swie", 0,NULL, amazon_atm_read_procmem,(void*)PROC_SWIE);
+#endif
+}
+
+/*
+ *     Brief:  Delete entry in /proc for status information
+ */
+void atm_delete_proc(void)
+{
+       remove_proc_entry("amazon_atm", NULL);
+        remove_proc_entry("amazon_atm_mib", NULL);
+        remove_proc_entry("amazon_atm_vcc", NULL);
+#if 0  
+       remove_proc_entry("amazon_atm_aal5", NULL);
+        remove_proc_entry("amazon_atm_cbm", NULL);
+        remove_proc_entry("amazon_atm_htu", NULL);
+        remove_proc_entry("amazon_atm_qsb", NULL);
+        remove_proc_entry("amazon_atm_swie", NULL);
+#endif 
+}
+/* Brief:      Initialize ATM module
+ * Parameters:         no
+ * Return:     &g_atm_dev - sucessful
+ *             NULL    - fails: 
+ *                     1. invalid parameter
+ *                     2. No memory available
+ * Description:
+ *  This function configure the TPE components according to the input info,
+ *     -CBM
+ *     -HTU
+ *     -QSB
+ *     -AAL5
+ *
+ */
+amazon_atm_dev_t * amazon_atm_create(void)
+{
+       int i;
+       AMAZON_TPE_DMSG("atm_init\n");
+       /************initialize global data structure****************/
+       atm_constructor(&g_atm_dev);
+       /***********allocate kernel resources****************/
+       //bottom halfs for SWEX
+       swex_start_task.routine = amazon_atm_swex;
+       swex_start_task.data = NULL;
+       swex_complete_task.routine = amazon_atm_swex_push;
+       swex_complete_task.data = NULL;
+#ifdef AMAZON_TPE_SCR
+       a5r_task.routine = amazon_atm_a5r;
+       a5r_task.data = NULL;
+#endif //AMAZON_TPE_SCR
+       //SWIN semaphore
+       sema_init(&(g_atm_dev.swie.in_sem), 1);
+       //SWIE lock
+       clear_bit(SWIE_LOCK, &(g_atm_dev.swie.lock));
+       //SWIE wait queue
+       init_waitqueue_head(&(g_atm_dev.swie.sleep));
+       atm_create_proc();
+               
+       //register DMA
+       memset(&g_dma_dev,0,sizeof(struct dma_device_info));
+       strcpy(g_dma_dev.device_name,"TPE");
+       g_dma_dev.weight=1; 
+       g_dma_dev.num_tx_chan=2;
+       g_dma_dev.num_rx_chan=2; 
+       g_dma_dev.ack=1;
+       g_dma_dev.tx_burst_len=4;
+       g_dma_dev.rx_burst_len=4;
+       //DMA TX
+
+       for(i=0;i<1;i++){
+               g_dma_dev.tx_chan[i].weight=QOS_DEFAULT_WGT;
+                       g_dma_dev.tx_chan[i].desc_num=10;
+                       g_dma_dev.tx_chan[i].packet_size=g_atm_dev.aal5.tx_max_sdu + AAL5S_INBOUND_HEADER;
+                       g_dma_dev.tx_chan[i].control=1;
+       }
+       //DMA RX
+       for(i=0;i<2;i++){
+                       g_dma_dev.rx_chan[i].weight=QOS_DEFAULT_WGT;
+               /* BingTao's suggestion, change from 5->10 will prevent packet loss in NO_TX_INT mode */
+               g_dma_dev.rx_chan[i].desc_num=10;
+               g_dma_dev.rx_chan[i].packet_size=(g_atm_dev.aal5.rx_max_sdu + AAL5R_TRAILER_LEN+0x10f)&(~0xf);
+               g_dma_dev.rx_chan[i].control=1;
+       }
+       g_dma_dev.intr_handler=amazon_atm_dma_handler;
+       g_dma_dev.buffer_alloc=amazon_atm_alloc_rx;
+       g_dma_dev.buffer_free=amazon_atm_free_tx;
+       dma_device_register(&g_dma_dev);
+/***********intialize the atm hardware ****************/
+       if ( atm_init_hard(&g_atm_dev) != 0){
+               return NULL;
+       }
+       //start CBM
+       AMAZON_WRITE_REGISTER_L(CBM_CFG_START,CBM_CFG_ADDR);
+       wmb();
+
+       //Start HTU
+       AMAZON_WRITE_REGISTER_L(HTU_CFG_START ,HTU_CFG_ADDR);
+       wmb();
+
+
+       // Register interrupts for insertion and extraction
+       request_irq(AMAZON_SWIE_INT, amazon_atm_swie_isr, SA_INTERRUPT, "tpe_swie", NULL);
+       request_irq(AMAZON_CBM_INT, amazon_atm_cbm_isr, SA_INTERRUPT, "tpe_cbm", NULL);
+#ifdef AMAZON_ATM_DEBUG
+       request_irq(AMAZON_HTU_INT , amazon_atm_htu_isr, SA_INTERRUPT, "tpe_htu", NULL);
+#endif
+#ifdef AMAZON_TPE_TEST_AAL5_INT        
+       request_irq(AMAZON_AAL5_INT, amazon_atm_aal5_isr, SA_INTERRUPT, "tpe_aal5", NULL);
+#endif
+       return &g_atm_dev;
+}
+
+/* Brief:      clean up atm
+ * Parameters:         no
+ * Return:     no
+ * Description:
+ *  Disable the device.
+ */
+void   amazon_atm_cleanup(void){
+       int i;
+       clear_bit(SWIE_LOCK, &(g_atm_dev.swie.lock));
+       wake_up(&g_atm_dev.swie.sleep);
+       up(&g_atm_dev.swie.in_sem);
+       // diable SWIE interrupts
+       AMAZON_WRITE_REGISTER_L(0, SWIE_ISRC_ADDR);
+       AMAZON_WRITE_REGISTER_L(0, SWIE_ESRC_ADDR);
+       wmb();
+
+       // Disable schedulers ( including interrupts )-----------------------
+       for (i = 0; i < AMAZON_ATM_PORT_NUM; i++);
+       {
+               AMAZON_WRITE_REGISTER_L(QSB_SET_SPT_SBVALID_MASK, QSB_RTM_ADDR);
+               AMAZON_WRITE_REGISTER_L( 0 ,QSB_RTD_ADDR);
+               AMAZON_WRITE_REGISTER_L( (QSB_TABLESEL_SPT<<QSB_TABLESEL_SHIFT)
+                                               | QSB_RAMAC_REG_LOW
+                                               | QSB_WRITE
+                                               | i,
+                                               QSB_RAMAC_ADDR);
+       }
+       // disable QSB_Interrupts
+       AMAZON_WRITE_REGISTER_L( 0, QSB_IMR_ADDR);
+       AMAZON_WRITE_REGISTER_L( 0, QSB_SRC_ADDR);
+       // disable CBM interrupts
+       AMAZON_WRITE_REGISTER_L( 0      , CBM_IMR0_ADDR);
+       AMAZON_WRITE_REGISTER_L( 0 , CBM_SRC0_ADDR);
+       // set CBM start bit to 0
+       AMAZON_WRITE_REGISTER_L(0,CBM_CFG_ADDR);
+       // request hardware extraction of queue 0, wich should force the CBM
+       // to recognize that the start bit is not set
+       AMAZON_WRITE_REGISTER_L(CBM_HWEXPAR_PN_A5, CBM_HWEXPAR0_ADDR);
+       // write frame extraction command into the hw extract command register
+       AMAZON_WRITE_REGISTER_L(CBM_HWEXCMD_FE0, CBM_HWEXCMD_ADDR);
+       // disable htu
+       // disable all HTU interrupts
+       AMAZON_WRITE_REGISTER_L(0  ,HTU_IMR0_ADDR);
+       AMAZON_WRITE_REGISTER_L(0  ,HTU_SRC0_ADDR);
+       
+       if (g_atm_dev.cbm.allocated){
+               free_pages((unsigned long)g_atm_dev.cbm.mem_addr, get_log_2(((CBM_CELL_SIZE * g_atm_dev.cbm.free_cell_cnt) >>PAGE_SHIFT)+1));
+#ifdef CONFIG_USE_VENUS
+               //to work around a bug, bit15 of QDOFF address should be 1
+               free_pages((unsigned long)g_atm_dev.cbm.qd_addr_free,4);
+#else //CONFIG_USE_VENUS
+               kfree(g_atm_dev.cbm.qd_addr);
+#endif //CONFIG_USE_VENUS                                              
+       }
+       atm_delete_proc();
+       // free interrupts for insertion and extraction
+       dma_device_unregister(&g_dma_dev);
+       free_irq(AMAZON_SWIE_INT, NULL);
+       free_irq(AMAZON_CBM_INT, NULL);
+#ifdef AMAZON_ATM_DEBUG
+       free_irq(AMAZON_HTU_INT, NULL);
+#endif
+#ifdef AMAZON_TPE_TEST_AAL5_INT
+       free_irq(AMAZON_AAL5_INT, NULL);
+#endif
+
+}
+
+/************************ ATM network interface ***********************************************/
+/*     Brief:          getsockopt
+ */
+int amazon_atm_getsockopt(struct atm_vcc *vcc, int level, int optname, char *optval, int optlen)
+{
+       int err=0;
+       atm_aal5_vcc_t mib_vcc;
+       AMAZON_TPE_DMSG("1\n");
+       switch (optname){
+               case    SO_AMAZON_ATM_MIB_VCC:
+                       AMAZON_TPE_DMSG("2\n");
+                       err = amazon_atm_vcc_mib(vcc, &mib_vcc);
+                       AMAZON_TPE_DMSG("%u\n",mib_vcc.aal5VccCrcErrors);
+                        err = copy_to_user((void *)optval,&mib_vcc, sizeof(mib_vcc));
+                        AMAZON_TPE_DMSG("err %u\n",err);
+                        break;
+                default:
+                       return -EFAULT;
+       }
+       return err;
+}
+
+/*     Brief:          IOCTL
+ */
+
+int amazon_atm_ioctl(struct atm_dev *dev,unsigned int cmd,void *arg)
+{
+       int     err=0;
+       //MIB
+       atm_cell_ifEntry_t mib_cell;
+       atm_aal5_ifEntry_t mib_aal5;
+       atm_aal5_vcc_x_t mib_vcc;
+       if (_IOC_TYPE(cmd) != AMAZON_ATM_IOC_MAGIC) return -ENOTTY;
+       if (_IOC_NR(cmd) > AMAZON_ATM_IOC_MAXNR) return -ENOTTY;
+
+       if (_IOC_DIR(cmd) & _IOC_READ)
+               err = !access_ok(VERIFY_WRITE, (void *)arg, _IOC_SIZE(cmd));
+       else if (_IOC_DIR(cmd) & _IOC_WRITE)
+               err =  !access_ok(VERIFY_READ, (void *)arg, _IOC_SIZE(cmd));
+       if (err) {
+               AMAZON_TPE_EMSG("acess verification fails \n");
+               return -EFAULT;
+       }
+       switch(cmd) {
+               case AMAZON_ATM_MIB_CELL:
+                       err = amazon_atm_cell_mib(&mib_cell,(u32)arg);
+                       if (err==0){
+                               err = __copy_to_user((void *)arg,&mib_cell,sizeof(mib_cell));
+                       }else{
+                               AMAZON_TPE_EMSG("cannot get MIB ATM_CELL\n");
+                       }
+                       break;
+               case AMAZON_ATM_MIB_AAL5:
+                       err = amazon_atm_aal5_mib(&mib_aal5);
+                       if (err==0){
+                               err=__copy_to_user(arg, &mib_aal5, sizeof(mib_aal5));
+                       }else{
+                               AMAZON_TPE_EMSG("cannot get MIB ATM_AAL5\n");
+                       }
+                       break;
+               case AMAZON_ATM_MIB_VCC:
+                       err=__copy_from_user(&mib_vcc,arg, sizeof(mib_vcc));
+                       AMAZON_TPE_DMSG("return of copy_from_user %x\n",err);
+                       err = amazon_atm_vcc_mib_x(mib_vcc.vpi, mib_vcc.vci, &(mib_vcc.mib_vcc));
+                       if (err==0){
+                               err=__copy_to_user(arg, &mib_vcc, sizeof(mib_vcc));     
+                       }else{
+                               AMAZON_TPE_EMSG("cannot get MIB ATM_VCC\n");
+                       }
+                               
+               default:
+                       return -ENOTTY;
+       }
+       return err;
+}
+/*     Brief:  return a link list of OAM related time stamp info
+ *     Parameter:      none
+ *     Return: 
+               a link list of "struct oam_last_activity" data
+ *     Description:
+               Each time, a F4/F5 cell or AAL5 packet is received, the time stamp is updated.
+               Through this call, u get a list of this time stamp for all active connection.
+               Please note that u have read-only access.
+ */
+const struct oam_last_activity* get_oam_time_stamp()
+{
+       int i,j;
+       for(i=CBM_DEFAULT_Q_OFFSET+CBM_RX_OFFSET,j=0;i<CBM_RX_OFFSET+CBM_DEFAULT_Q_OFFSET+AMAZON_ATM_MAX_VCC_NUM;i++){
+               if (g_atm_dev.queues[i].free != 1 && g_atm_dev.queues[i].vcc != NULL){
+                       //active connection
+                       if (j !=0 ){
+                               g_oam_time_stamp[j-1].next = &g_oam_time_stamp[j];
+                       }
+                       g_oam_time_stamp[j].vpi = g_atm_dev.queues[i].vcc->vpi;
+                       g_oam_time_stamp[j].vci = g_atm_dev.queues[i].vcc->vci;
+                       g_oam_time_stamp[j].stamp = g_atm_dev.queues[i].access_time;
+                       g_oam_time_stamp[j].next = NULL;
+                       j++;
+               }
+       }
+       if (j==0) {
+               return NULL;
+       }else{
+               return g_oam_time_stamp;
+       }
+}
+
+
+/*     Brief:  call back routine for rx
+ *     Parameter:
+ *             vcc atm_vcc pointer
+ *             skb     data if no error
+               err     error flag, 0: no error, 1:error
+ *     Return: 
+ *             0       
+ *             <>0     cannot push up
+ *     Description:
+ *             release the packet if cannot push up
+ */
+static int amazon_atm_net_push(struct atm_vcc *vcc,struct sk_buff *skb, int err)
+{
+       if (err){
+               if (vcc && vcc->stats) {
+                       atomic_inc(&vcc->stats->rx_err);
+               }
+       }else{  
+               ATM_SKB(skb)->vcc = vcc;
+       
+               if (!atm_charge(vcc, skb->truesize)){
+                       //no space this vcc
+                       AMAZON_TPE_EMSG("no space for this vcc\n");
+                       dev_kfree_skb_any(skb);
+                       return -ENOMEM;
+               }
+               atomic_inc(&vcc->stats->rx);
+               AMAZON_TPE_DMSG("push to vcc\n");
+               vcc->push(vcc,skb);
+       }
+       return 0;
+}
+int    amazon_atm_net_send_oam(struct atm_vcc*vcc, void *cell, int flags)
+{
+       return amazon_atm_send_oam(vcc,cell,flags);
+}
+
+int    amazon_atm_net_send(struct atm_vcc *vcc,struct sk_buff *skb)
+{
+       int err=0;
+       if (vcc->qos.aal == ATM_AAL0 || vcc->qos.aal == ATM_AAL5) {
+               err=amazon_atm_send(vcc,skb);
+       }else{
+               //not supported
+               err =  -EPROTONOSUPPORT;
+       }
+       if (err){
+               atomic_inc(&vcc->stats->tx_err);
+       }else{
+               atomic_inc(&vcc->stats->tx);
+       }
+       AMAZON_TPE_DMSG("sent, tx_inuse:%u\n", atomic_read(&vcc->tx_inuse));
+       return err;
+}
+
+int    amazon_atm_net_open(struct atm_vcc *vcc,short vpi, int vci)
+{
+       vcc->itf = (int)  vcc->dev->dev_data;
+       vcc->vpi = vpi;
+       vcc->vci = vci;
+       return(amazon_atm_open(vcc,amazon_atm_net_push));
+}
+
+static int amazon_atm_change_qos(struct atm_vcc *vcc, struct atm_qos *qos, int flgs)
+{
+       int qid;
+       
+       if (vcc == NULL || qos == NULL){
+               AMAZON_TPE_EMSG("invalid parameters\n");
+               return -EINVAL;
+       }
+       qid = amazon_atm_get_queue(vcc);
+       if (valid_qid(qid) != 1) {
+               AMAZON_TPE_EMSG("no vcc connection opened\n");
+               return -EINVAL;
+       }
+       set_qsb(vcc,qos,qid);
+       return 0;
+}
+
+static struct atmdev_ops amazon_atm_ops = {
+   open:       amazon_atm_net_open,
+   close:      amazon_atm_close,
+   ioctl:      amazon_atm_ioctl,
+   send:       amazon_atm_net_send,
+   send_oam:   amazon_atm_net_send_oam,
+//   getsockopt:       amazon_atm_getsockopt,
+   change_qos: amazon_atm_change_qos,
+//   proc_read:        amazon_atm_proc_read,
+   owner:      THIS_MODULE,
+};                             // ATM device callback functions
+
+/*
+ * brief "/proc" function
+ */
+int amazon_atm_read_procmem(char *buf, char **start, off_t offset,int count, int *eof, void *data)
+{
+       int buf_off=0;  /* for buf */
+       int i=0,j=0;
+       int type= (u32)data;//which module
+       atm_aal5_ifEntry_t mib_aal5;
+       atm_cell_ifEntry_t mib_cell;
+       atm_aal5_vcc_t mib_vcc;
+       switch(type){
+               case PROC_MIB:
+                       //MIB counter
+                       amazon_atm_aal5_mib(&mib_aal5);
+                       //TX:
+                       buf_off+=sprintf(buf+buf_off,"\n============= AAL5 Upstream =========\n");
+                       buf_off+=sprintf(buf+buf_off,"received %u (pkts) from upper layer\n", mib_aal5.ifOutUcastPkts);
+                       buf_off+=sprintf(buf+buf_off,"errors: %u (pkts)\n",mib_aal5.ifOutErros);
+                       buf_off+=sprintf(buf+buf_off,"discards: %u (ptks)\n", mib_aal5.ifOutDiscards);
+                       buf_off+=sprintf(buf+buf_off,"transmitted: %x-%x (bytes) \n",
+                                       mib_aal5.ifHCOutOctets_h, mib_aal5.ifHCOutOctets_l);
+                       //RX:
+                       buf_off+=sprintf(buf+buf_off,"\n============= AAL5 Downstream =========\n");
+                       buf_off+=sprintf(buf+buf_off,"received %x-%x (bytes)\n",
+                                       mib_aal5.ifHCInOctets_h,mib_aal5.ifHCInOctets_l);
+                       buf_off+=sprintf(buf+buf_off,"discards: %u (ptks)\n",mib_aal5.ifInDiscards);
+                       buf_off+=sprintf(buf+buf_off,"errors: %u (ptks)\n",mib_aal5.ifInErrors);
+                       buf_off+=sprintf(buf+buf_off,"passed %u (ptks) to upper layer\n",mib_aal5.ifInUcastPkts);
+                       
+                       //Cell level
+                       buf_off+=sprintf(buf+buf_off,"\n============= ATM Cell =========\n");
+                       amazon_atm_cell_mib(&mib_cell,0);
+#ifdef AMAZON_TPE_READ_ARC                     
+                       buf_off+=sprintf(buf+buf_off,"Port 0: downstream received: %x-%x (bytes)\n",mib_cell.ifHCInOctets_h,mib_cell.ifHCInOctets_l);
+                       buf_off+=sprintf(buf+buf_off,"Port 0: upstream transmitted: %x-%x (bytes)\n",mib_cell.ifHCOutOctets_h,mib_cell.ifHCOutOctets_l);
+                       buf_off+=sprintf(buf+buf_off,"Port 0: downstream errors: %u (cells)\n",mib_cell.ifInErrors);
+                       amazon_atm_cell_mib(&mib_cell,1);
+                       buf_off+=sprintf(buf+buf_off,"Port 1: downstream received: %x-%x (bytes)\n",mib_cell.ifHCInOctets_h,mib_cell.ifHCInOctets_l);
+                       buf_off+=sprintf(buf+buf_off,"Port 1: upstream transmitted: %x-%x (bytes)\n",mib_cell.ifHCOutOctets_h,mib_cell.ifHCOutOctets_l);
+                       buf_off+=sprintf(buf+buf_off,"Port 1: downstream errors: %u (cells)\n",mib_cell.ifInErrors);
+#endif
+                       buf_off+=sprintf(buf+buf_off,"HTU discards: %u (cells)\n",mib_cell.ifInUnknownProtos);
+                       
+                       buf_off+=sprintf(buf+buf_off,"\n====== Specials =====\n");
+                       buf_off+=sprintf(buf+buf_off,"AAL5S PPD: %u (cells)\n",g_atm_dev.mib_counter.tx_ppd);
+#ifdef AMAZON_TPE_SCR
+                       buf_off+=sprintf(buf+buf_off,"Reassembly wait: %u \n",g_a5r_wait);
+#endif
+                       break;
+               case PROC_ATM:
+                       //Interface (Port)
+                       buf_off+=sprintf(buf+buf_off,"[Interfaces]\n");
+                       for(i=0;i<AMAZON_ATM_PORT_NUM;i++){
+                               if (g_atm_dev.ports[i].enable==0){
+                                       buf_off+=sprintf(buf+buf_off,"\tport[%u] not in use\n",i);
+                               }else{
+                                       buf_off+=sprintf(buf+buf_off,"\tport[%u]\n\t\tmax_conn=%u\n"
+                                                                       ,i
+                                                                       ,g_atm_dev.ports[i].max_conn
+                                                                       );
+                                       buf_off+=sprintf(buf+buf_off,"\t\ttx_max=%u\n\t\trem=%u\n\t\tcur=%u\n"
+                                                                       ,g_atm_dev.ports[i].tx_max_cr
+                                                                       ,g_atm_dev.ports[i].tx_rem_cr
+                                                                       ,g_atm_dev.ports[i].tx_cur_cr
+                                                                       );
+                               }
+
+                       }
+                       //Units Info
+                       //AAL5
+                       buf_off+=sprintf(buf+buf_off,"[AAL5]\n\tpad=%c(%x)\n\trx_mtu=%u\n\ttx_mtu=%u\n"
+                                       ,g_atm_dev.aal5.padding_byte
+                                       ,g_atm_dev.aal5.padding_byte
+                                       ,g_atm_dev.aal5.rx_max_sdu
+                                       ,g_atm_dev.aal5.tx_max_sdu
+                                       );
+                       //CBM
+                       buf_off+=sprintf(buf+buf_off,
+                               "[CBM]\n\tnrt_thr=%u\n\tclp0_thr=%u\n\tclp1_thr=%u\n\ttx_q_threshold=%u\n\trx_q_threshold=%u\n\toam_q_threshold=%u\n\tfree_cell_cnt=%u\n"
+                                       ,g_atm_dev.cbm.nrt_thr
+                                       ,g_atm_dev.cbm.clp0_thr
+                                       ,g_atm_dev.cbm.clp1_thr
+                                       ,tx_q_threshold
+                                       ,rx_q_threshold
+                                       ,oam_q_threshold
+                                       ,g_atm_dev.cbm.free_cell_cnt
+                                       );
+                       //QSB
+                       buf_off+=sprintf(buf+buf_off,"[QSB]\n\ttau=%u\n\ttstepc=%u\n\tsbl=%u\n"
+                                       ,g_atm_dev.qsb.tau
+                                       ,g_atm_dev.qsb.tstepc
+                                       ,g_atm_dev.qsb.sbl
+                                       );
+                       buf_off+=sprintf(buf+buf_off,"[Debugging]\n\taal5_need_copy=%u\n",g_atm_dev.aal5.cnt_cpy);
+                       break;
+               case PROC_VCC:
+                       for(i=CBM_DEFAULT_Q_OFFSET,j=0;i<g_atm_dev.cbm.max_q_off+CBM_DEFAULT_Q_OFFSET;i++){
+                               if (g_atm_dev.queues[i].free!=1){
+                                       buf_off+=sprintf(buf+buf_off,"vcc[%u]\n\tvpi=%u vci=%u itf=%u qid=%u access_time=%u.%u\n"
+                                                                       ,j++
+                                                                       ,g_atm_dev.queues[i].vcc->vpi
+                                                                       ,g_atm_dev.queues[i].vcc->vci
+                                                                       ,g_atm_dev.queues[i].vcc->itf
+                                                                       ,i
+                                                                       ,(u32)g_atm_dev.queues[i+CBM_RX_OFFSET].access_time.tv_sec
+                                                                       ,(u32)g_atm_dev.queues[i+CBM_RX_OFFSET].access_time.tv_usec
+                                                                       );
+                                       buf_off+=sprintf(buf+buf_off,"\tqos_tx class=%u max_pcr=%u pcr=%u min_pcr=%u scr=%u mbs=%u cdv=%u\n"
+                                                                       ,g_atm_dev.queues[i].vcc->qos.txtp.traffic_class
+                                                                       ,g_atm_dev.queues[i].vcc->qos.txtp.max_pcr
+                                                                       ,g_atm_dev.queues[i].vcc->qos.txtp.pcr
+                                                                       ,g_atm_dev.queues[i].vcc->qos.txtp.min_pcr
+                                                                       ,g_atm_dev.queues[i].vcc->qos.txtp.scr
+                                                                       ,g_atm_dev.queues[i].vcc->qos.txtp.mbs
+                                                                       ,g_atm_dev.queues[i].vcc->qos.txtp.cdv
+                                                                       );
+                                       buf_off+=sprintf(buf+buf_off,"\tqos_rx class=%u max_pcr=%u pcr=%u min_pcr=%u scr=%u mbs=%u cdv=%u\n"
+                                                                       ,g_atm_dev.queues[i].vcc->qos.rxtp.traffic_class
+                                                                       ,g_atm_dev.queues[i].vcc->qos.rxtp.max_pcr
+                                                                       ,g_atm_dev.queues[i].vcc->qos.rxtp.pcr
+                                                                       ,g_atm_dev.queues[i].vcc->qos.rxtp.min_pcr
+                                                                       ,g_atm_dev.queues[i].vcc->qos.rxtp.scr
+                                                                       ,g_atm_dev.queues[i].vcc->qos.rxtp.mbs
+                                                                       ,g_atm_dev.queues[i].vcc->qos.rxtp.cdv
+                                                                       );
+                                       __amazon_atm_vcc_mib((i+CBM_RX_OFFSET),&mib_vcc);
+                                       buf_off+=sprintf(buf+buf_off,"\tCRC error=%u\n", mib_vcc.aal5VccCrcErrors);
+                                       buf_off+=sprintf(buf+buf_off,"\toversized packet=%u\n", mib_vcc.aal5VccOverSizedSDUs);
+#ifdef         AMAZON_ATM_DEBUG
+                                       if ( valid_qid(i+CBM_RX_OFFSET)){
+                                       buf_off+=sprintf(buf+buf_off,"\tdownstream statics\n" );
+                                       buf_off+=sprintf(buf+buf_off,"\t\tpackets=%u\n",g_atm_dev.queues[i+CBM_RX_OFFSET].qs[QS_PKT]);
+                                       buf_off+=sprintf(buf+buf_off,"\t\terr_packets=%u\n",g_atm_dev.queues[i+CBM_RX_OFFSET].qs[QS_ERR] );
+                                       buf_off+=sprintf(buf+buf_off,"\t\tsw_dropped=%u\n",g_atm_dev.queues[i+CBM_RX_OFFSET].qs[QS_SW_DROP] );
+                                       }
+
+                                       buf_off+=sprintf(buf+buf_off,"\tupstream statics\n" );
+                                       buf_off+=sprintf(buf+buf_off,"\t\tpackets=%u\n",g_atm_dev.queues[i].qs[QS_PKT]);
+                                       buf_off+=sprintf(buf+buf_off,"\t\terr_packets=%u\n",g_atm_dev.queues[i].qs[QS_ERR] );
+                                       buf_off+=sprintf(buf+buf_off,"\t\thw_dropped=%u\n",g_atm_dev.queues[i].qs[QS_HW_DROP] );
+                                       buf_off+=sprintf(buf+buf_off,"\t\tsw_dropped=%u\n",g_atm_dev.queues[i].qs[QS_SW_DROP] );
+
+#endif                                 
+       
+                               }
+
+                       }
+                       break;
+               default:
+                       break;
+       }
+       if(buf_off>0)   *eof = 1;
+       return buf_off;
+}
+
+#ifdef AMAZON_TPE_AAL5_RECOVERY
+extern int (*tpe_reset)(void);
+extern int (*tpe_start)(void);
+extern int (*tpe_inject)(void);
+/*     Brief:          Reset TPE hardware
+ *     Description
+ *             This is a wordaround for AAL5 bug. It tries to reset TPE.
+ *      take care of software
+ *      setup all previous connection
+ */
+int amazon_tpe_reset(void)
+{
+       struct atm_vcc * vcc;   
+       int err=0;
+       int i;
+       u8 * qd_addr;
+       u32 reg_l, reg_h;
+       unsigned int a_cfg_value=0;
+       unsigned int a_cfg_old_value=0;
+       atm_aal5_ifEntry_t mib_aal5;
+       atm_cell_ifEntry_t mib_cell;
+       
+       //make sure all cells transmitting out first
+       //Segmentation done
+       amazon_atm_aal5_mib(&mib_aal5);
+       reg_l = g_atm_dev.mib_counter.tx_cnt_l;
+       reg_h = g_atm_dev.mib_counter.tx_cnt_h;
+       while(1){
+               mdelay(10);
+               amazon_atm_aal5_mib(&mib_aal5);
+               if( (reg_l == g_atm_dev.mib_counter.tx_cnt_l) && (reg_h == g_atm_dev.mib_counter.tx_cnt_h) ){
+                       break;
+               }
+               AMAZON_TPE_DMSG("AAL5 Segmentation still in progress!\n");
+               reg_l = g_atm_dev.mib_counter.tx_cnt_l;
+               reg_h = g_atm_dev.mib_counter.tx_cnt_h;
+       }
+       //QSB done
+       qd_addr = (u8 *) KSEG1ADDR((unsigned long)g_atm_dev.cbm.qd_addr);
+       for (i=1;i<15;i++){
+               while ( (err=readl(qd_addr+i*CBM_QD_SIZE+0x8)&0xffff) !=0  ){
+                       mdelay(20);
+                       AMAZON_TPE_DMSG("queue %u not empty (%u)\n",i,err);
+               }
+       }
+       //insurance for interfaces between Aware and CARB
+       mdelay(100);
+       amazon_atm_cell_mib(&mib_cell,0);
+       amazon_atm_cell_mib(&mib_cell,1);
+       amazon_atm_aal5_mib(&mib_aal5);
+       
+       mb();
+       while ( (AMAZON_READ_REGISTER_L(AR_CELLRDY_BC0) != 0 ) || (AMAZON_READ_REGISTER_L(AR_CELLRDY_BC0) != 0 )  ){
+               AMAZON_TPE_EMSG("\nwaiting for AWARE");
+               AMAZON_TPE_EMSG(" BC0 %u ", AMAZON_READ_REGISTER_L(AR_CELLRDY_BC0));
+               AMAZON_TPE_EMSG(" BC1 %u ", AMAZON_READ_REGISTER_L(AR_CELLRDY_BC1));
+               AMAZON_TPE_EMSG("\n");
+               mdelay(1);
+       }
+       // disable AAI module
+       meiDebugRead(A_CFG_ADDR,&a_cfg_value,1);        
+       a_cfg_old_value=a_cfg_value;
+       a_cfg_value &= (~(0x2800));
+       meiDebugWrite(A_CFG_ADDR,&a_cfg_value,1);       
+       //clear buffer
+       a_cfg_value = 0x1;
+       meiDebugWrite(AR_CB0_STATUS_ADDR,&a_cfg_value,1);       
+       meiDebugWrite(AR_CB1_STATUS_ADDR,&a_cfg_value,1);       
+
+       if ( atm_init_hard(&g_atm_dev) != 0){
+               return -EIO;
+       }
+       sema_init(&(g_atm_dev.swie.in_sem), 1);
+       //SWIE lock
+       clear_bit(SWIE_LOCK, &(g_atm_dev.swie.lock));
+       //SWIE wait queue
+       init_waitqueue_head(&(g_atm_dev.swie.sleep));
+       
+       for (i=CBM_DEFAULT_Q_OFFSET;i<AMAZON_ATM_MAX_QUEUE_NUM/2;i++) {
+               vcc = g_atm_dev.queues[i].vcc;
+               if (vcc != NULL){
+                       set_qsb(vcc, &vcc->qos, i);
+                       set_qd(vcc, i);
+                       mb();
+                       err=set_htu(vcc,i);
+                       if (err){
+                               AMAZON_TPE_EMSG("set htu entry fails %u\n",err);
+                       }
+               }
+       }
+       meiDebugWrite(A_CFG_ADDR,&a_cfg_old_value,1);   
+#if 0
+       //reset DFE
+       *(AMAZON_RST_REQ) = (* AMAZON_RST_REQ) | (AMAZON_RST_REQ_DFE);
+       mb();
+       *(AMAZON_RST_REQ) = (* AMAZON_RST_REQ) &  (~AMAZON_RST_REQ_DFE);
+       mb();
+#endif
+       
+       return 0;
+}
+
+/* Brief:      Send a ATM EoP packet to save DMA channel
+ */
+int amazon_tpe_inject_debug_cell(void)
+{
+       //Send a ATM cell to save DMA channel
+       u8 qid;
+       unsigned char atm_cell[48];
+       qid = 0x11;
+       AMAZON_TPE_DMSG("qid = %d\n",qid);
+       memset(atm_cell,0,48);
+       atm_cell[3] = 0x2;
+       if ( amazon_atm_swin(qid,atm_cell)) {
+               AMAZON_TPE_EMSG("cannot insert EoP cell\n");
+               return -1;
+       }
+       return 0;
+}
+
+/* Brief:      start HTU (TPE)
+ */
+
+int amazon_tpe_start(void)
+{
+       AMAZON_WRITE_REGISTER_L(HTU_CFG_START ,HTU_CFG_ADDR);
+       wmb();
+       return 0;
+}
+#endif //AMAZON_TPE_AAL5_RECOVERY
+
+#ifdef AMAZON_CHECK_LINK
+extern int (*adsl_link_notify)(int);
+/*     Brief:  notify link status of ADSL link
+ *     Parameters:     0       link down
+ *                     1       link up
+ *     Returns:        0       OK
+ *     Details:        called by MEI driver 
+ *     should update status and inform upper layer
+ */
+int amazon_tpe_link_notify(int status)
+{
+       adsl_link_status = status;
+       AMAZON_TPE_DMSG("link status %s\n",(status==1)?"Up":"Down");
+       if (status == 0){
+               //wait until no cells in upstream queues
+               set_current_state(TASK_INTERRUPTIBLE);
+               schedule_timeout(2*HZ);
+       }
+       return 0;
+}
+#endif //ifdef AMAZON_CHECK_LINK
+
+/*
+ *     Brief:          Initialize ATM module
+ *
+ *     Return Value:   ENOMEM          - No memory available
+ *                     EBUSY           - Cannot register atm device
+ *                     ERESTARTSYS     - Process interrupted by other signal
+ *                     0               - OK, module initialized
+ *
+ *     Description:
+ *     This function registers an atm device for all UTOPIA devices.
+ *     It also allocates memory for the private device data structures
+ */
+int __init amazon_atm_net_init(void)
+{
+       int i;
+       int err=0;
+       amazon_atm_dev_t *dev = NULL;
+       
+       if ((dev=amazon_atm_create()) != NULL){
+               for(i=0;i<AMAZON_ATM_PORT_NUM;i++){
+                       if (!dev->ports[i].enable){
+                               amazon_atm_devs[i] = NULL;
+                               continue;
+                       }
+                       amazon_atm_devs[i] =atm_dev_register("amazon_atm",&amazon_atm_ops,-1,0UL);
+                       if (amazon_atm_devs[i] == NULL){
+                               AMAZON_TPE_EMSG("atm_dev_register fails\n");
+                               err = -EIO;
+                               goto amazon_atm_net_init_exit;
+                       }else{
+                               AMAZON_TPE_DMSG("registering device %u\n",i);
+                               amazon_atm_devs[i]->ci_range.vpi_bits = 8;
+                               amazon_atm_devs[i]->ci_range.vci_bits = 16;
+                               amazon_atm_devs[i]->link_rate = dev->ports[i].tx_max_cr;
+                               amazon_atm_devs[i]->dev_data = (void *) i;
+                       }
+               }
+                       
+       }else{
+               err = -ENOMEM;
+               AMAZON_TPE_EMSG("cannot init atm device\n");
+               goto amazon_atm_net_init_exit;
+       }
+#ifdef AMAZON_TPE_AAL5_RECOVERY        
+       tpe_reset = & amazon_tpe_reset;
+       tpe_start = & amazon_tpe_start;
+       tpe_inject = & amazon_tpe_inject_debug_cell;
+#endif //AMAZON_TPE_AAL5_RECOVERY
+#ifdef AMAZON_CHECK_LINK
+       adsl_link_notify=amazon_tpe_link_notify;
+#endif //AMAZON_CHECK_LINK
+amazon_atm_net_init_exit:
+       return err;
+}
+
+void __exit amazon_atm_net_cleanup(void)
+{
+       int i;
+       amazon_atm_cleanup();
+       for(i=0;i<AMAZON_ATM_PORT_NUM;i++){
+               if (amazon_atm_devs[i] != NULL){
+                       AMAZON_TPE_DMSG("unregister dev %u\n",i);
+                       atm_dev_deregister(amazon_atm_devs[i]);
+               }
+       }
+       return;
+}
+EXPORT_SYMBOL(get_oam_time_stamp);
+
+MODULE_LICENSE ("GPL"); 
+MODULE_AUTHOR("Infineon IFAP DC COM peng.liu@infineon.com");
+MODULE_DESCRIPTION("AMAZON ATM driver");
+
+module_init(amazon_atm_net_init);
+module_exit(amazon_atm_net_cleanup);
+
+
+
+
diff --git a/target/linux/amazon-2.6/files/drivers/char/admmod.c b/target/linux/amazon-2.6/files/drivers/char/admmod.c
new file mode 100644 (file)
index 0000000..0229f53
--- /dev/null
@@ -0,0 +1,1486 @@
+/******************************************************************************
+     Copyright (c) 2004, Infineon Technologies.  All rights reserved.
+
+                               No Warranty
+   Because the program is licensed free of charge, there is no warranty for
+   the program, to the extent permitted by applicable law.  Except when
+   otherwise stated in writing the copyright holders and/or other parties
+   provide the program "as is" without warranty of any kind, either
+   expressed or implied, including, but not limited to, the implied
+   warranties of merchantability and fitness for a particular purpose. The
+   entire risk as to the quality and performance of the program is with
+   you.  should the program prove defective, you assume the cost of all
+   necessary servicing, repair or correction.
+
+   In no event unless required by applicable law or agreed to in writing
+   will any copyright holder, or any other party who may modify and/or
+   redistribute the program as permitted above, be liable to you for
+   damages, including any general, special, incidental or consequential
+   damages arising out of the use or inability to use the program
+   (including but not limited to loss of data or data being rendered
+   inaccurate or losses sustained by you or third parties or a failure of
+   the program to operate with any other programs), even if such holder or
+   other party has been advised of the possibility of such damages.
+ ******************************************************************************
+   Module      : admmod.c
+   Date        : 2004-09-01
+   Description : JoeLin
+   Remarks:
+
+   Revision:
+       MarsLin, add to support VLAN
+
+ *****************************************************************************/
+//000001.joelin 2005/06/02 add"ADM6996_MDC_MDIO_MODE" define, 
+//             if define ADM6996_MDC_MDIO_MODE==> ADM6996LC and ADM6996I will be in MDIO/MDC(SMI)(16 bit) mode,
+//             amazon should contrl ADM6996 by MDC/MDIO pin
+//             if undef ADM6996_MDC_MDIO_MODE==> ADM6996  will be in EEProm(32 bit) mode,
+//             amazon should contrl ADM6996 by GPIO15,16,17,18  pin
+/* 507281:linmars 2005/07/28 support MDIO/EEPROM config mode */
+/* 509201:linmars remove driver testing codes */
+
+#include <linux/module.h>
+#include <linux/string.h>
+#include <linux/proc_fs.h>
+#include <linux/delay.h>
+#include <asm/uaccess.h>
+#include <linux/init.h>
+#include <linux/ioctl.h>
+#include <asm/atomic.h>
+#include <asm-mips/amazon/amazon.h>
+#include <asm-mips/amazon/adm6996.h>
+//#include <linux/amazon/adm6996.h>
+
+
+unsigned int ifx_sw_conf[ADM_SW_MAX_PORT_NUM+1] = \
+       {ADM_SW_PORT0_CONF, ADM_SW_PORT1_CONF, ADM_SW_PORT2_CONF, \
+       ADM_SW_PORT3_CONF, ADM_SW_PORT4_CONF, ADM_SW_PORT5_CONF};
+unsigned int ifx_sw_bits[8] = \
+       {0x1, 0x3, 0x7, 0xf, 0x1f, 0x3f, 0x7f, 0xff};
+unsigned int ifx_sw_vlan_port[6] = {0, 2, 4, 6, 7, 8};
+//050613:fchang 
+/* 507281:linmars start */
+#ifdef CONFIG_SWITCH_ADM6996_MDIO
+#define ADM6996_MDC_MDIO_MODE 1 //000001.joelin
+#else
+#undef ADM6996_MDC_MDIO_MODE
+#endif
+/* 507281:linmars end */
+#define adm6996i 0
+#define adm6996lc 1
+#define adm6996l  2
+unsigned int adm6996_mode=adm6996i;
+/*
+  initialize GPIO pins.
+  output mode, low
+*/
+void ifx_gpio_init(void)
+{
+ //GPIO16,17,18 direction:output
+ //GPIO16,17,18 output 0
+    AMAZON_SW_REG(AMAZON_GPIO_P1_DIR) |= (GPIO_MDIO|GPIO_MDCS|GPIO_MDC);
+    AMAZON_SW_REG(AMAZON_GPIO_P1_OUT) =AMAZON_SW_REG(AMAZON_GPIO_P1_IN)& ~(GPIO_MDIO|GPIO_MDCS|GPIO_MDC);
+
+}
+
+/* read one bit from mdio port */
+int ifx_sw_mdio_readbit(void)
+{
+    //int val;
+
+    //val = (AMAZON_SW_REG(GPIO_conf0_REG) & GPIO0_INPUT_MASK) >> 8;
+    //return val;
+    //GPIO16
+    return AMAZON_SW_REG(AMAZON_GPIO_P1_IN)&1;
+}
+
+/*
+  MDIO mode selection
+  1 -> output
+  0 -> input
+
+  switch input/output mode of GPIO 0
+*/
+void ifx_mdio_mode(int mode)
+{
+//    AMAZON_SW_REG(GPIO_conf0_REG) = mode ? GPIO_ENABLEBITS :
+//                             ((GPIO_ENABLEBITS | MDIO_INPUT) & ~MDIO_OUTPUT_EN);
+    mode?(AMAZON_SW_REG(AMAZON_GPIO_P1_DIR)|=GPIO_MDIO):
+         (AMAZON_SW_REG(AMAZON_GPIO_P1_DIR)&=~GPIO_MDIO);
+    /*int r=AMAZON_SW_REG(AMAZON_GPIO_P1_DIR);
+    mode?(r|=GPIO_MDIO):(r&=~GPIO_MDIO);
+    AMAZON_SW_REG(AMAZON_GPIO_P1_DIR)=r;*/
+}
+
+void ifx_mdc_hi(void)
+{
+    //GPIO_SET_HI(GPIO_MDC);
+    //AMAZON_SW_REG(AMAZON_GPIO_P1_OUT)|=GPIO_MDC;
+    /*int r=AMAZON_SW_REG(AMAZON_GPIO_P1_OUT);
+    r|=GPIO_MDC;
+    AMAZON_SW_REG(AMAZON_GPIO_P1_OUT)=r;*/
+
+    AMAZON_SW_REG(AMAZON_GPIO_P1_OUT)=AMAZON_SW_REG(AMAZON_GPIO_P1_IN)|GPIO_MDC;
+}
+
+void ifx_mdio_hi(void)
+{
+    //GPIO_SET_HI(GPIO_MDIO);
+    //AMAZON_SW_REG(AMAZON_GPIO_P1_OUT)|=GPIO_MDIO;
+    /*int r=AMAZON_SW_REG(AMAZON_GPIO_P1_OUT);
+    r|=GPIO_MDIO;
+    AMAZON_SW_REG(AMAZON_GPIO_P1_OUT)=r;*/
+
+    AMAZON_SW_REG(AMAZON_GPIO_P1_OUT)=AMAZON_SW_REG(AMAZON_GPIO_P1_IN)|GPIO_MDIO;
+}
+
+void ifx_mdcs_hi(void)
+{
+    //GPIO_SET_HI(GPIO_MDCS);
+    //AMAZON_SW_REG(AMAZON_GPIO_P1_OUT)|=GPIO_MDCS;
+    /*int r=AMAZON_SW_REG(AMAZON_GPIO_P1_OUT);
+    r|=GPIO_MDCS;
+    AMAZON_SW_REG(AMAZON_GPIO_P1_OUT)=r;*/
+
+    AMAZON_SW_REG(AMAZON_GPIO_P1_OUT)=AMAZON_SW_REG(AMAZON_GPIO_P1_IN)|GPIO_MDCS;
+}
+
+void ifx_mdc_lo(void)
+{
+    //GPIO_SET_LOW(GPIO_MDC);
+    //AMAZON_SW_REG(AMAZON_GPIO_P1_OUT)&=~GPIO_MDC;
+    /*int r=AMAZON_SW_REG(AMAZON_GPIO_P1_OUT);
+    r&=~GPIO_MDC;
+    AMAZON_SW_REG(AMAZON_GPIO_P1_OUT)=r;*/
+
+    AMAZON_SW_REG(AMAZON_GPIO_P1_OUT)=AMAZON_SW_REG(AMAZON_GPIO_P1_IN)&(~GPIO_MDC);
+}
+
+void ifx_mdio_lo(void)
+{
+    //GPIO_SET_LOW(GPIO_MDIO);
+    //AMAZON_SW_REG(AMAZON_GPIO_P1_OUT)&=~GPIO_MDIO;
+    /*int r=AMAZON_SW_REG(AMAZON_GPIO_P1_OUT);
+    r&=~GPIO_MDIO;
+    AMAZON_SW_REG(AMAZON_GPIO_P1_OUT)=r;*/
+
+    AMAZON_SW_REG(AMAZON_GPIO_P1_OUT)=AMAZON_SW_REG(AMAZON_GPIO_P1_IN)&(~GPIO_MDIO);
+}
+
+void ifx_mdcs_lo(void)
+{
+    //GPIO_SET_LOW(GPIO_MDCS);
+    //AMAZON_SW_REG(AMAZON_GPIO_P1_OUT)&=~GPIO_MDCS;
+    /*int r=AMAZON_SW_REG(AMAZON_GPIO_P1_OUT);
+    r&=~GPIO_MDCS;
+    AMAZON_SW_REG(AMAZON_GPIO_P1_OUT)=r;*/
+    
+    AMAZON_SW_REG(AMAZON_GPIO_P1_OUT)=AMAZON_SW_REG(AMAZON_GPIO_P1_IN)&(~GPIO_MDCS);
+}
+
+/*
+  mdc pulse
+  0 -> 1 -> 0
+*/
+static void ifx_sw_mdc_pulse(void)
+{
+    ifx_mdc_lo();
+    udelay(ADM_SW_MDC_DOWN_DELAY);
+    ifx_mdc_hi();
+    udelay(ADM_SW_MDC_UP_DELAY);
+    ifx_mdc_lo();
+}
+
+/*
+  mdc toggle
+  1 -> 0
+*/
+static void ifx_sw_mdc_toggle(void)
+{
+    ifx_mdc_hi();
+    udelay(ADM_SW_MDC_UP_DELAY);
+    ifx_mdc_lo();
+    udelay(ADM_SW_MDC_DOWN_DELAY);
+}
+
+/*
+  enable eeprom write
+  For ATC 93C66 type EEPROM; accessing ADM6996 internal EEPROM type registers
+*/
+static void ifx_sw_eeprom_write_enable(void)
+{
+    unsigned int op;
+
+    ifx_mdcs_lo();
+    ifx_mdc_lo();
+    ifx_mdio_hi();
+    udelay(ADM_SW_CS_DELAY);
+    /* enable chip select */
+    ifx_mdcs_hi();
+    udelay(ADM_SW_CS_DELAY);
+    /* start bit */
+    ifx_mdio_hi();
+    ifx_sw_mdc_pulse();
+
+    /* eeprom write enable */
+    op = ADM_SW_BIT_MASK_4;
+    while (op)
+    {
+        if (op & ADM_SW_EEPROM_WRITE_ENABLE)
+            ifx_mdio_hi();
+        else
+            ifx_mdio_lo();
+
+        ifx_sw_mdc_pulse();
+        op >>= 1;
+    }
+
+    op = ADM_SW_BIT_MASK_1 << (EEPROM_TYPE - 3);
+    while (op)
+    {
+        ifx_mdio_lo();
+        ifx_sw_mdc_pulse();
+        op >>= 1;
+    }
+    /* disable chip select */
+    ifx_mdcs_lo();
+    udelay(ADM_SW_CS_DELAY);
+    ifx_sw_mdc_pulse();
+}
+
+/*
+  disable eeprom write
+*/
+static void ifx_sw_eeprom_write_disable(void)
+{
+    unsigned int op;
+
+    ifx_mdcs_lo();
+    ifx_mdc_lo();
+    ifx_mdio_hi();
+    udelay(ADM_SW_CS_DELAY);
+    /* enable chip select */
+    ifx_mdcs_hi();
+    udelay(ADM_SW_CS_DELAY);
+
+    /* start bit */
+    ifx_mdio_hi();
+    ifx_sw_mdc_pulse();
+    /* eeprom write disable */
+    op = ADM_SW_BIT_MASK_4;
+    while (op)
+    {
+        if (op & ADM_SW_EEPROM_WRITE_DISABLE)
+            ifx_mdio_hi();
+        else
+            ifx_mdio_lo();
+
+        ifx_sw_mdc_pulse();
+        op >>= 1;
+    }
+
+    op = ADM_SW_BIT_MASK_1 << (EEPROM_TYPE - 3);
+    while (op)
+    {
+        ifx_mdio_lo();
+
+        ifx_sw_mdc_pulse();
+        op >>= 1;
+    }
+    /* disable chip select */
+    ifx_mdcs_lo();
+    udelay(ADM_SW_CS_DELAY);
+    ifx_sw_mdc_pulse();
+}
+
+/*
+  read registers from ADM6996
+  serial registers start at 0x200 (addr bit 9 = 1b)
+  EEPROM registers -> 16bits; Serial registers -> 32bits
+*/
+#ifdef ADM6996_MDC_MDIO_MODE //smi mode//000001.joelin
+static int ifx_sw_read_adm6996i_smi(unsigned int addr, unsigned int *dat)
+{
+   addr=(addr<<16)&0x3ff0000;
+   AMAZON_SW_REG(AMAZON_SW_MDIO_ACC) =(0xC0000000|addr);
+   while ((AMAZON_SW_REG(AMAZON_SW_MDIO_ACC))&0x80000000){};
+   *dat=((AMAZON_SW_REG(AMAZON_SW_MDIO_ACC))&0x0FFFF);
+    return 0;
+}
+#endif
+
+static int ifx_sw_read_adm6996i(unsigned int addr, unsigned int *dat)
+{
+    unsigned int op;
+
+    ifx_gpio_init();
+
+    ifx_mdcs_hi();
+    udelay(ADM_SW_CS_DELAY);
+
+    ifx_mdcs_lo();
+    ifx_mdc_lo();
+    ifx_mdio_lo();
+
+    udelay(ADM_SW_CS_DELAY);
+
+    /* preamble, 32 bit 1 */
+    ifx_mdio_hi();
+    op = ADM_SW_BIT_MASK_32;
+    while (op)
+    {
+        ifx_sw_mdc_pulse();
+        op >>= 1;
+    }
+
+    /* command start (01b) */
+    op = ADM_SW_BIT_MASK_2;
+    while (op)
+    {
+        if (op & ADM_SW_SMI_START)
+            ifx_mdio_hi();
+        else
+            ifx_mdio_lo();
+
+        ifx_sw_mdc_pulse();
+        op >>= 1;
+    }
+
+    /* read command (10b) */
+    op = ADM_SW_BIT_MASK_2;
+    while (op)
+    {
+        if (op & ADM_SW_SMI_READ)
+            ifx_mdio_hi();
+        else
+            ifx_mdio_lo();
+
+        ifx_sw_mdc_pulse();
+        op >>= 1;
+    }
+
+    /* send address A9 ~ A0 */
+    op = ADM_SW_BIT_MASK_10;
+    while (op)
+    {
+        if (op & addr)
+            ifx_mdio_hi();
+        else
+            ifx_mdio_lo();
+
+        ifx_sw_mdc_pulse();
+        op >>= 1;
+    }
+
+    /* turnaround bits */
+    op = ADM_SW_BIT_MASK_2;
+    ifx_mdio_hi();
+    while (op)
+    {
+        ifx_sw_mdc_pulse();
+        op >>= 1;
+    }
+
+    udelay(ADM_SW_MDC_DOWN_DELAY);
+
+    /* set MDIO pin to input mode */
+    ifx_mdio_mode(ADM_SW_MDIO_INPUT);
+
+    /* start read data */
+    *dat = 0;
+//adm6996i    op = ADM_SW_BIT_MASK_32;
+    op = ADM_SW_BIT_MASK_16;//adm6996i
+    while (op)
+    {
+        *dat <<= 1;
+        if (ifx_sw_mdio_readbit()) *dat |= 1;
+        ifx_sw_mdc_toggle();
+
+        op >>= 1;
+    }
+
+    /* set MDIO to output mode */
+    ifx_mdio_mode(ADM_SW_MDIO_OUTPUT);
+
+    /* dummy clock */
+    op = ADM_SW_BIT_MASK_4;
+    ifx_mdio_lo();
+    while(op)
+    {
+        ifx_sw_mdc_pulse();
+        op >>= 1;
+    }
+
+    ifx_mdc_lo();
+    ifx_mdio_lo();
+    ifx_mdcs_hi();
+
+    /* EEPROM registers */
+//adm6996i    if (!(addr & 0x200))
+//adm6996i    {
+//adm6996i        if (addr % 2)
+//adm6996i            *dat >>= 16;
+//adm6996i        else
+//adm6996i        *dat &= 0xffff;
+//adm6996i    }
+
+    return 0;
+}
+//adm6996
+static int ifx_sw_read_adm6996l(unsigned int addr, unsigned int *dat)
+{
+    unsigned int op;
+
+    ifx_gpio_init();
+
+    ifx_mdcs_hi();
+    udelay(ADM_SW_CS_DELAY);
+
+    ifx_mdcs_lo();
+    ifx_mdc_lo();
+    ifx_mdio_lo();
+
+    udelay(ADM_SW_CS_DELAY);
+
+    /* preamble, 32 bit 1 */
+    ifx_mdio_hi();
+    op = ADM_SW_BIT_MASK_32;
+    while (op)
+    {
+        ifx_sw_mdc_pulse();
+        op >>= 1;
+    }
+
+    /* command start (01b) */
+    op = ADM_SW_BIT_MASK_2;
+    while (op)
+    {
+        if (op & ADM_SW_SMI_START)
+            ifx_mdio_hi();
+        else
+            ifx_mdio_lo();
+
+        ifx_sw_mdc_pulse();
+        op >>= 1;
+    }
+
+    /* read command (10b) */
+    op = ADM_SW_BIT_MASK_2;
+    while (op)
+    {
+        if (op & ADM_SW_SMI_READ)
+            ifx_mdio_hi();
+        else
+            ifx_mdio_lo();
+
+        ifx_sw_mdc_pulse();
+        op >>= 1;
+    }
+
+    /* send address A9 ~ A0 */
+    op = ADM_SW_BIT_MASK_10;
+    while (op)
+    {
+        if (op & addr)
+            ifx_mdio_hi();
+        else
+            ifx_mdio_lo();
+
+        ifx_sw_mdc_pulse();
+        op >>= 1;
+    }
+
+    /* turnaround bits */
+    op = ADM_SW_BIT_MASK_2;
+    ifx_mdio_hi();
+    while (op)
+    {
+        ifx_sw_mdc_pulse();
+        op >>= 1;
+    }
+
+    udelay(ADM_SW_MDC_DOWN_DELAY);
+
+    /* set MDIO pin to input mode */
+    ifx_mdio_mode(ADM_SW_MDIO_INPUT);
+
+    /* start read data */
+    *dat = 0;
+    op = ADM_SW_BIT_MASK_32;
+    while (op)
+    {
+        *dat <<= 1;
+        if (ifx_sw_mdio_readbit()) *dat |= 1;
+        ifx_sw_mdc_toggle();
+
+        op >>= 1;
+    }
+
+    /* set MDIO to output mode */
+    ifx_mdio_mode(ADM_SW_MDIO_OUTPUT);
+
+    /* dummy clock */
+    op = ADM_SW_BIT_MASK_4;
+    ifx_mdio_lo();
+    while(op)
+    {
+        ifx_sw_mdc_pulse();
+        op >>= 1;
+    }
+
+    ifx_mdc_lo();
+    ifx_mdio_lo();
+    ifx_mdcs_hi();
+
+    /* EEPROM registers */
+    if (!(addr & 0x200))
+    {
+        if (addr % 2)
+            *dat >>= 16;
+        else
+        *dat &= 0xffff;
+    }
+
+    return 0;
+}
+
+static int ifx_sw_read(unsigned int addr, unsigned int *dat)
+{
+#ifdef ADM6996_MDC_MDIO_MODE //smi mode ////000001.joelin
+       ifx_sw_read_adm6996i_smi(addr,dat);
+#else  
+       if (adm6996_mode==adm6996i) ifx_sw_read_adm6996i(addr,dat);
+               else ifx_sw_read_adm6996l(addr,dat);
+#endif         
+       return 0;
+       
+}
+
+/*
+  write register to ADM6996 eeprom registers
+*/
+//for adm6996i -start
+#ifdef ADM6996_MDC_MDIO_MODE //smi mode //000001.joelin
+static int ifx_sw_write_adm6996i_smi(unsigned int addr, unsigned int dat)
+{
+   AMAZON_SW_REG(AMAZON_SW_MDIO_ACC) = ((addr<<16)&0x3ff0000)|dat|0x80000000;
+   while ((AMAZON_SW_REG(AMAZON_SW_MDIO_ACC))&0x80000000){};
+  
+    return 0;
+}
+#endif //ADM6996_MDC_MDIO_MODE //000001.joelin
+
+static int ifx_sw_write_adm6996i(unsigned int addr, unsigned int dat)
+{
+    unsigned int op;
+
+    ifx_gpio_init();
+
+    ifx_mdcs_hi();
+    udelay(ADM_SW_CS_DELAY);
+
+    ifx_mdcs_lo();
+    ifx_mdc_lo();
+    ifx_mdio_lo();
+
+    udelay(ADM_SW_CS_DELAY);
+
+    /* preamble, 32 bit 1 */
+    ifx_mdio_hi();
+    op = ADM_SW_BIT_MASK_32;
+    while (op)
+    {
+        ifx_sw_mdc_pulse();
+        op >>= 1;
+    }
+
+    /* command start (01b) */
+    op = ADM_SW_BIT_MASK_2;
+    while (op)
+    {
+        if (op & ADM_SW_SMI_START)
+            ifx_mdio_hi();
+        else
+            ifx_mdio_lo();
+
+        ifx_sw_mdc_pulse();
+        op >>= 1;
+    }
+
+    /* write command (01b) */
+    op = ADM_SW_BIT_MASK_2;
+    while (op)
+    {
+        if (op & ADM_SW_SMI_WRITE)
+            ifx_mdio_hi();
+        else
+            ifx_mdio_lo();
+
+        ifx_sw_mdc_pulse();
+        op >>= 1;
+    }
+
+    /* send address A9 ~ A0 */
+    op = ADM_SW_BIT_MASK_10;
+    while (op)
+    {
+        if (op & addr)
+            ifx_mdio_hi();
+        else
+            ifx_mdio_lo();
+
+        ifx_sw_mdc_pulse();
+        op >>= 1;
+    }
+
+    /* turnaround bits */
+    op = ADM_SW_BIT_MASK_2;
+    ifx_mdio_hi();
+    while (op)
+    {
+        ifx_sw_mdc_pulse();
+        op >>= 1;
+    }
+
+    udelay(ADM_SW_MDC_DOWN_DELAY);
+
+    /* set MDIO pin to output mode */
+    ifx_mdio_mode(ADM_SW_MDIO_OUTPUT);
+
+  
+    /* start write data */
+    op = ADM_SW_BIT_MASK_16;
+    while (op)
+    {
+        if (op & dat)
+            ifx_mdio_hi();
+        else
+            ifx_mdio_lo();
+
+        ifx_sw_mdc_toggle();
+        op >>= 1;
+    }
+
+ //   /* set MDIO to output mode */
+ //   ifx_mdio_mode(ADM_SW_MDIO_OUTPUT);
+
+    /* dummy clock */
+    op = ADM_SW_BIT_MASK_4;
+    ifx_mdio_lo();
+    while(op)
+    {
+        ifx_sw_mdc_pulse();
+        op >>= 1;
+    }
+
+    ifx_mdc_lo();
+    ifx_mdio_lo();
+    ifx_mdcs_hi();
+
+    /* EEPROM registers */
+//adm6996i    if (!(addr & 0x200))
+//adm6996i    {
+//adm6996i        if (addr % 2)
+//adm6996i            *dat >>= 16;
+//adm6996i        else
+//adm6996i        *dat &= 0xffff;
+//adm6996i    }
+
+    return 0;
+}
+//for adm6996i-end
+static int ifx_sw_write_adm6996l(unsigned int addr, unsigned int dat)
+{
+    unsigned int op;
+
+    ifx_gpio_init();
+
+    /* enable write */
+    ifx_sw_eeprom_write_enable();
+
+    /* chip select */
+    ifx_mdcs_hi();
+    udelay(ADM_SW_CS_DELAY);
+
+    /* issue write command */
+    /* start bit */
+    ifx_mdio_hi();
+    ifx_sw_mdc_pulse();
+
+    /* EEPROM write command */
+    op = ADM_SW_BIT_MASK_2;
+    while (op)
+    {
+        if (op & ADM_SW_EEPROM_WRITE)
+            ifx_mdio_hi();
+        else
+            ifx_mdio_lo();
+
+        ifx_sw_mdc_pulse();
+        op >>= 1;
+    }
+
+    /* send address A7 ~ A0 */
+    op = ADM_SW_BIT_MASK_1 << (EEPROM_TYPE - 1);
+
+    while (op)
+    {
+        if (op & addr)
+            ifx_mdio_hi();
+        else
+            ifx_mdio_lo();
+
+        ifx_sw_mdc_toggle();
+        op >>= 1;
+    }
+
+    /* start write data */
+    op = ADM_SW_BIT_MASK_16;
+    while (op)
+    {
+        if (op & dat)
+            ifx_mdio_hi();
+        else
+            ifx_mdio_lo();
+
+        ifx_sw_mdc_toggle();
+        op >>= 1;
+    }
+
+    /* disable cs & wait 1 clock */
+    ifx_mdcs_lo();
+    udelay(ADM_SW_CS_DELAY);
+    ifx_sw_mdc_toggle();
+
+    ifx_sw_eeprom_write_disable();
+
+    return 0;
+}
+
+static int ifx_sw_write(unsigned int addr, unsigned int dat)
+{
+#ifdef ADM6996_MDC_MDIO_MODE //smi mode ////000001.joelin
+       ifx_sw_write_adm6996i_smi(addr,dat);
+#else  //000001.joelin
+       if (adm6996_mode==adm6996i) ifx_sw_write_adm6996i(addr,dat);
+               else ifx_sw_write_adm6996l(addr,dat);
+#endif //000001.joelin
+       return 0;
+}
+
+/*
+  do switch PHY reset
+*/
+int ifx_sw_reset(void)
+{
+    /* reset PHY */
+    ifx_sw_write(ADM_SW_PHY_RESET, 0);
+
+    return 0;
+}
+
+/* 509201:linmars start */
+#if 0
+/*
+  check port status
+*/
+int ifx_check_port_status(int port)
+{
+    unsigned int val;
+
+    if ((port < 0) || (port > ADM_SW_MAX_PORT_NUM))
+    {
+        ifx_printf(("error on port number (%d)!!\n", port));
+        return -1;
+    }
+
+    ifx_sw_read(ifx_sw_conf[port], &val);
+    if (ifx_sw_conf[port]%2) val >>= 16;
+    /* only 16bits are effective */
+    val &= 0xFFFF;
+
+    ifx_printf(("Port %d status (%.8x): \n", port, val));
+
+    if (val & ADM_SW_PORT_FLOWCTL)
+        ifx_printf(("\t802.3x flow control supported!\n"));
+    else
+        ifx_printf(("\t802.3x flow control not supported!\n"));
+
+    if (val & ADM_SW_PORT_AN)
+        ifx_printf(("\tAuto negotiation ON!\n"));
+    else
+        ifx_printf(("\tAuto negotiation OFF!\n"));
+
+    if (val & ADM_SW_PORT_100M)
+        ifx_printf(("\tLink at 100M!\n"));
+    else
+        ifx_printf(("\tLink at 10M!\n"));
+
+    if (val & ADM_SW_PORT_FULL)
+        ifx_printf(("\tFull duplex!\n"));
+    else
+        ifx_printf(("\tHalf duplex!\n"));
+
+    if (val & ADM_SW_PORT_DISABLE)
+        ifx_printf(("\tPort disabled!\n"));
+    else
+        ifx_printf(("\tPort enabled!\n"));
+
+    if (val & ADM_SW_PORT_TOS)
+        ifx_printf(("\tTOS enabled!\n"));
+    else
+        ifx_printf(("\tTOS disabled!\n"));
+
+    if (val & ADM_SW_PORT_PPRI)
+        ifx_printf(("\tPort priority first!\n"));
+    else
+        ifx_printf(("\tVLAN or TOS priority first!\n"));
+
+    if (val & ADM_SW_PORT_MDIX)
+        ifx_printf(("\tAuto MDIX!\n"));
+    else
+        ifx_printf(("\tNo auto MDIX\n"));
+
+    ifx_printf(("\tPVID: %d\n", \
+           ((val >> ADM_SW_PORT_PVID_SHIFT)&ifx_sw_bits[ADM_SW_PORT_PVID_BITS])));
+
+    return 0;
+}
+/*
+  initialize a VLAN
+  clear all VLAN bits
+*/
+int ifx_sw_vlan_init(int vlanid)
+{
+    ifx_sw_write(ADM_SW_VLAN0_CONF + vlanid, 0);
+
+    return 0;
+}
+
+/*
+  add a port to certain vlan
+*/
+int ifx_sw_vlan_add(int port, int vlanid)
+{
+    int reg = 0;
+
+    if ((port < 0) || (port > ADM_SW_MAX_PORT_NUM) || (vlanid < 0) ||
+        (vlanid > ADM_SW_MAX_VLAN_NUM))
+    {
+        ifx_printf(("Port number or VLAN number ERROR!!\n"));
+        return -1;
+    }
+    ifx_sw_read(ADM_SW_VLAN0_CONF + vlanid, &reg);
+    reg |= (1 << ifx_sw_vlan_port[port]);
+    ifx_sw_write(ADM_SW_VLAN0_CONF + vlanid, reg);
+
+    return 0;
+}
+
+/*
+  delete a given port from certain vlan
+*/
+int ifx_sw_vlan_del(int port, int vlanid)
+{
+    unsigned int reg = 0;
+
+    if ((port < 0) || (port > ADM_SW_MAX_PORT_NUM) || (vlanid < 0) || (vlanid > ADM_SW_MAX_VLAN_NUM))
+    {
+        ifx_printf(("Port number or VLAN number ERROR!!\n"));
+        return -1;
+    }
+    ifx_sw_read(ADM_SW_VLAN0_CONF + vlanid, &reg);
+    reg &= ~(1 << ifx_sw_vlan_port[port]);
+    ifx_sw_write(ADM_SW_VLAN0_CONF + vlanid, reg);
+
+    return 0;
+}
+
+/*
+  default VLAN setting
+
+  port 0~3 as untag port and PVID = 1
+  VLAN1: port 0~3 and port 5 (MII)
+*/
+static int ifx_sw_init(void)
+{
+    ifx_printf(("Setting default ADM6996 registers... \n"));
+
+    /* MAC clone, 802.1q based VLAN */
+    ifx_sw_write(ADM_SW_VLAN_MODE, 0xff30);
+    /* auto MDIX, PVID=1, untag */
+    ifx_sw_write(ADM_SW_PORT0_CONF, 0x840f);
+    ifx_sw_write(ADM_SW_PORT1_CONF, 0x840f);
+    ifx_sw_write(ADM_SW_PORT2_CONF, 0x840f);
+    ifx_sw_write(ADM_SW_PORT3_CONF, 0x840f);
+    /* auto MDIX, PVID=2, untag */
+    ifx_sw_write(ADM_SW_PORT5_CONF, 0x880f);
+    /* port 0~3 & 5 as VLAN1 */
+    ifx_sw_write(ADM_SW_VLAN0_CONF+1, 0x0155);
+
+    return 0;
+}
+#endif
+/* 509201:linmars end */
+
+int adm_open(struct inode *node, struct file *filp)
+{
+    MOD_INC_USE_COUNT;
+    return 0;
+}
+
+ssize_t adm_read(struct file *filep, char *buf, size_t count, loff_t *ppos)
+{
+    return count;
+}
+
+ssize_t adm_write(struct file *filep, const char *buf, size_t count, loff_t *ppos)
+{
+    return count;
+}
+
+/* close */
+int adm_release(struct inode *inode, struct file *filp)
+{
+    MOD_DEC_USE_COUNT;
+    return 0;
+}
+
+/* IOCTL function */
+int adm_ioctl(struct inode *inode, struct file *filp, unsigned int cmd, unsigned long args)
+{
+    PREGRW uREGRW;
+    unsigned int rtval;
+    unsigned int val;          //6996i
+    unsigned int control[6] ;  //6996i
+    unsigned int status[6] ;   //6996i
+    
+    PMACENTRY mMACENTRY;//adm6996i
+    PPROTOCOLFILTER uPROTOCOLFILTER ;///adm6996i
+
+    if (_IOC_TYPE(cmd) != ADM_MAGIC)
+    {
+        printk("adm_ioctl: IOC_TYPE(%x) != ADM_MAGIC(%x)! \n", _IOC_TYPE(cmd), ADM_MAGIC);
+        return (-EINVAL);
+    }
+
+    if(_IOC_NR(cmd) >= KEY_IOCTL_MAX_KEY)
+    {
+        printk(KERN_WARNING "adm_ioctl: IOC_NR(%x) invalid! \n", _IOC_NR(cmd));
+        return (-EINVAL);
+    }
+
+    switch (cmd)
+    {
+        case ADM_IOCTL_REGRW:
+        {
+            uREGRW = (PREGRW)kmalloc(sizeof(REGRW), GFP_KERNEL);
+            rtval = copy_from_user(uREGRW, (PREGRW)args, sizeof(REGRW));
+            if (rtval != 0)
+            {
+                printk("ADM_IOCTL_REGRW: copy from user FAILED!! \n");
+                return (-EFAULT);
+            }
+
+            switch(uREGRW->mode)
+            {
+                case REG_READ:
+                    uREGRW->value = 0x12345678;//inl(uREGRW->addr);
+                    copy_to_user((PREGRW)args, uREGRW, sizeof(REGRW));
+                    break;
+                case REG_WRITE:
+                    //outl(uREGRW->value, uREGRW->addr);
+                    break;
+
+                default:
+                    printk("No such Register Read/Write function!! \n");
+                    return (-EFAULT);
+            }
+            kfree(uREGRW);
+            break;
+        }
+
+        case ADM_SW_IOCTL_REGRW:
+        {
+            unsigned int val = 0xff;
+
+            uREGRW = (PREGRW)kmalloc(sizeof(REGRW), GFP_KERNEL);
+            rtval = copy_from_user(uREGRW, (PREGRW)args, sizeof(REGRW));
+            if (rtval != 0)
+            {
+                printk("ADM_IOCTL_REGRW: copy from user FAILED!! \n");
+                return (-EFAULT);
+            }
+
+            switch(uREGRW->mode)
+            {
+                case REG_READ:
+                    ifx_sw_read(uREGRW->addr, &val);
+                    uREGRW->value = val;
+                    copy_to_user((PREGRW)args, uREGRW, sizeof(REGRW));
+                    break;
+
+                case REG_WRITE:
+                    ifx_sw_write(uREGRW->addr, uREGRW->value);
+                    break;
+                default:
+                    printk("No such Register Read/Write function!! \n");
+                    return (-EFAULT);
+            }
+            kfree(uREGRW);
+            break;
+        }
+/* 509201:linmars start */
+#if 0
+        case ADM_SW_IOCTL_PORTSTS:
+            for (rtval = 0; rtval < ADM_SW_MAX_PORT_NUM+1; rtval++)
+                ifx_check_port_status(rtval);
+            break;
+        case ADM_SW_IOCTL_INIT:
+            ifx_sw_init();
+            break;
+#endif
+/* 509201:linmars end */
+//adm6996i
+        case ADM_SW_IOCTL_MACENTRY_ADD:
+        case ADM_SW_IOCTL_MACENTRY_DEL:
+        case ADM_SW_IOCTL_MACENTRY_GET_INIT:
+        case ADM_SW_IOCTL_MACENTRY_GET_MORE:
+                
+
+           mMACENTRY = (PMACENTRY)kmalloc(sizeof(MACENTRY), GFP_KERNEL);
+            rtval = copy_from_user(mMACENTRY, (PMACENTRY)args, sizeof(MACENTRY));
+            if (rtval != 0)
+            {
+                printk("ADM_SW_IOCTL_MACENTRY: copy from user FAILED!! \n");
+                return (-EFAULT);
+            }
+           control[0]=(mMACENTRY->mac_addr[1]<<8)+mMACENTRY->mac_addr[0]     ; 
+           control[1]=(mMACENTRY->mac_addr[3]<<8)+mMACENTRY->mac_addr[2]      ;         
+           control[2]=(mMACENTRY->mac_addr[5]<<8)+mMACENTRY->mac_addr[4]     ;
+           control[3]=(mMACENTRY->fid&0xf)+((mMACENTRY->portmap&0x3f)<<4);
+           if (((mMACENTRY->info_type)&0x01)) control[4]=(mMACENTRY->ctrl.info_ctrl)+0x1000; //static ,info control
+               else    control[4]=((mMACENTRY->ctrl.age_timer)&0xff);//not static ,agetimer
+               if (cmd==ADM_SW_IOCTL_MACENTRY_GET_INIT) {      
+                  //initial  the pointer to the first address  
+                                  val=0x8000;//busy ,status5[15]
+                                  while(val&0x8000){           //check busy ?
+                                         ifx_sw_read(0x125, &val);
+                                       }    
+                                  control[5]=0x030;//initial the first address 
+                                  ifx_sw_write(0x11f,control[5]);
+                                               
+                                       
+                                  val=0x8000;//busy ,status5[15]
+                                  while(val&0x8000){           //check busy ?
+                                         ifx_sw_read(0x125, &val);
+                                       }               
+                       
+                  }    //if (cmd==ADM_SW_IOCTL_MACENTRY_GET_INIT)                                                              
+           if (cmd==ADM_SW_IOCTL_MACENTRY_ADD) control[5]=0x07;//create a new address
+               else if (cmd==ADM_SW_IOCTL_MACENTRY_DEL) control[5]=0x01f;//erased an existed address
+               else if ((cmd==ADM_SW_IOCTL_MACENTRY_GET_INIT)||(cmd==ADM_SW_IOCTL_MACENTRY_GET_MORE)) 
+                       control[5]=0x02c;//search by the mac address field
+           
+           val=0x8000;//busy ,status5[15]
+           while(val&0x8000){          //check busy ?
+                 ifx_sw_read(0x125, &val);
+               }
+               ifx_sw_write(0x11a,control[0]); 
+               ifx_sw_write(0x11b,control[1]); 
+               ifx_sw_write(0x11c,control[2]); 
+               ifx_sw_write(0x11d,control[3]); 
+               ifx_sw_write(0x11e,control[4]); 
+               ifx_sw_write(0x11f,control[5]); 
+           val=0x8000;//busy ,status5[15]
+           while(val&0x8000){          //check busy ?
+                 ifx_sw_read(0x125, &val);
+               }       
+           val=((val&0x7000)>>12);//result ,status5[14:12]
+           mMACENTRY->result=val;
+   
+           if (!val) {
+                       printk(" Command OK!! \n");
+                       if ((cmd==ADM_SW_IOCTL_MACENTRY_GET_INIT)||(cmd==ADM_SW_IOCTL_MACENTRY_GET_MORE)) {
+                                       ifx_sw_read(0x120,&(status[0]));        
+                                       ifx_sw_read(0x121,&(status[1]));        
+                                       ifx_sw_read(0x122,&(status[2]));        
+                                       ifx_sw_read(0x123,&(status[3]));        
+                                       ifx_sw_read(0x124,&(status[4]));        
+                                       ifx_sw_read(0x125,&(status[5]));        
+               
+                                       
+                                       mMACENTRY->mac_addr[0]=(status[0]&0x00ff)       ;
+                                       mMACENTRY->mac_addr[1]=(status[0]&0xff00)>>8    ;
+                                       mMACENTRY->mac_addr[2]=(status[1]&0x00ff)    ;
+                                       mMACENTRY->mac_addr[3]=(status[1]&0xff00)>>8 ;
+                                       mMACENTRY->mac_addr[4]=(status[2]&0x00ff)    ;
+                                       mMACENTRY->mac_addr[5]=(status[2]&0xff00)>>8 ;
+                                       mMACENTRY->fid=(status[3]&0xf);
+                                       mMACENTRY->portmap=((status[3]>>4)&0x3f);
+                                       if (status[5]&0x2) {//static info_ctrl //status5[1]????
+                                               mMACENTRY->ctrl.info_ctrl=(status[4]&0x00ff);
+                                               mMACENTRY->info_type=1;
+                                                       }
+                                       else {//not static age_timer
+                                               mMACENTRY->ctrl.age_timer=(status[4]&0x00ff);
+                                               mMACENTRY->info_type=0;
+                                                       }
+//status5[13]????                                      mMACENTRY->occupy=(status[5]&0x02)>>1;//status5[1]
+                                       mMACENTRY->occupy=(status[5]&0x02000)>>13;//status5[13] ???
+                                       mMACENTRY->bad=(status[5]&0x04)>>2;//status5[2]
+                               }//if ((cmd==ADM_SW_IOCTL_MACENTRY_GET_INIT)||(cmd==ADM_SW_IOCTL_MACENTRY_GET_MORE)) 
+                       
+               }
+           else if (val==0x001)  
+                printk(" All Entry Used!! \n");
+            else if (val==0x002) 
+                printk("  Entry Not Found!! \n");
+            else if (val==0x003) 
+                printk(" Try Next Entry!! \n");
+            else if (val==0x005)  
+                printk(" Command Error!! \n");   
+            else   
+                printk(" UnKnown Error!! \n");
+                
+            copy_to_user((PMACENTRY)args, mMACENTRY,sizeof(MACENTRY));    
+                
+           break;  
+        case ADM_SW_IOCTL_FILTER_ADD:
+        case ADM_SW_IOCTL_FILTER_DEL:
+        case ADM_SW_IOCTL_FILTER_GET:
+
+            uPROTOCOLFILTER = (PPROTOCOLFILTER)kmalloc(sizeof(PROTOCOLFILTER), GFP_KERNEL);
+            rtval = copy_from_user(uPROTOCOLFILTER, (PPROTOCOLFILTER)args, sizeof(PROTOCOLFILTER));
+            if (rtval != 0)
+            {
+                printk("ADM_SW_IOCTL_FILTER_ADD: copy from user FAILED!! \n");
+                return (-EFAULT);
+            }
+            
+               if(cmd==ADM_SW_IOCTL_FILTER_DEL) {      //delete filter
+                       uPROTOCOLFILTER->ip_p=00;       //delet filter
+                       uPROTOCOLFILTER->action=00;     //delete filter
+               }                                       //delete filter
+
+            ifx_sw_read(((uPROTOCOLFILTER->protocol_filter_num/2)+0x68), &val);//rx68~rx6b,protocol filter0~7  
+
+               if (((uPROTOCOLFILTER->protocol_filter_num)%2)==00){    
+                       if(cmd==ADM_SW_IOCTL_FILTER_GET) uPROTOCOLFILTER->ip_p= val&0x00ff;//get filter ip_p
+                               else val=(val&0xff00)|(uPROTOCOLFILTER->ip_p);//set filter ip_p
+               }
+               else {
+                       if(cmd==ADM_SW_IOCTL_FILTER_GET) uPROTOCOLFILTER->ip_p= (val>>8);//get filter ip_p
+                               else val=(val&0x00ff)|((uPROTOCOLFILTER->ip_p)<<8);//set filter ip_p
+               }       
+            if(cmd!=ADM_SW_IOCTL_FILTER_GET) ifx_sw_write(((uPROTOCOLFILTER->protocol_filter_num/2)+0x68), val);//write rx68~rx6b,protocol filter0~7   
+                       
+            ifx_sw_read(0x95, &val);   //protocol filter action
+            if(cmd==ADM_SW_IOCTL_FILTER_GET) {
+                       uPROTOCOLFILTER->action= ((val>>(uPROTOCOLFILTER->protocol_filter_num*2))&0x3);//get filter action
+                       copy_to_user((PPROTOCOLFILTER)args, uPROTOCOLFILTER, sizeof(PROTOCOLFILTER));
+               
+               }
+               else {
+                       val=(val&(~(0x03<<(uPROTOCOLFILTER->protocol_filter_num*2))))|(((uPROTOCOLFILTER->action)&0x03)<<(uPROTOCOLFILTER->protocol_filter_num*2));
+  //                   printk("%d----\n",val);
+                       ifx_sw_write(0x95, val);        //write protocol filter action          
+               }
+               
+            break;
+//adm6996i  
+
+        /* others */
+        default:
+            return -EFAULT;
+    }
+    /* end of switch */
+    return 0;
+}
+
+/* Santosh: handle IGMP protocol filter ADD/DEL/GET */
+int adm_process_protocol_filter_request (unsigned int cmd, PPROTOCOLFILTER uPROTOCOLFILTER)
+{
+    unsigned int val;          //6996i
+
+       if(cmd==ADM_SW_IOCTL_FILTER_DEL) {      //delete filter
+       uPROTOCOLFILTER->ip_p=00;       //delet filter
+       uPROTOCOLFILTER->action=00;     //delete filter
+       }                                       //delete filter
+
+    ifx_sw_read(((uPROTOCOLFILTER->protocol_filter_num/2)+0x68), &val);//rx68~rx6b,protocol filter0~7  
+
+    if (((uPROTOCOLFILTER->protocol_filter_num)%2)==00){       
+       if(cmd==ADM_SW_IOCTL_FILTER_GET) uPROTOCOLFILTER->ip_p= val&0x00ff;//get filter ip_p
+        else val=(val&0xff00)|(uPROTOCOLFILTER->ip_p);//set filter ip_p
+    }
+    else {
+       if(cmd==ADM_SW_IOCTL_FILTER_GET) uPROTOCOLFILTER->ip_p= (val>>8);//get filter ip_p
+       else val=(val&0x00ff)|((uPROTOCOLFILTER->ip_p)<<8);//set filter ip_p
+    }  
+    if(cmd!=ADM_SW_IOCTL_FILTER_GET) ifx_sw_write(((uPROTOCOLFILTER->protocol_filter_num/2)+0x68), val);//write rx68~rx6b,protocol filter0~7   
+                       
+       ifx_sw_read(0x95, &val);        //protocol filter action
+    if(cmd==ADM_SW_IOCTL_FILTER_GET) {
+               uPROTOCOLFILTER->action= ((val>>(uPROTOCOLFILTER->protocol_filter_num*2))&0x3);//get filter action
+    }
+    else {
+       val=(val&(~(0x03<<(uPROTOCOLFILTER->protocol_filter_num*2))))|(((uPROTOCOLFILTER->action)&0x03)<<(uPROTOCOLFILTER->protocol_filter_num*2));
+        ifx_sw_write(0x95, val);       //write protocol filter action          
+    }
+               
+       return 0;
+}
+
+
+/* Santosh: function for MAC ENTRY ADD/DEL/GET */
+
+int adm_process_mac_table_request (unsigned int cmd, PMACENTRY mMACENTRY)
+{
+    unsigned int rtval;
+    unsigned int val;          //6996i
+    unsigned int control[6] ;  //6996i
+    unsigned int status[6] ;   //6996i
+
+       // printk ("adm_process_mac_table_request: enter\n");   
+
+    control[0]=(mMACENTRY->mac_addr[1]<<8)+mMACENTRY->mac_addr[0]     ; 
+    control[1]=(mMACENTRY->mac_addr[3]<<8)+mMACENTRY->mac_addr[2]      ;         
+    control[2]=(mMACENTRY->mac_addr[5]<<8)+mMACENTRY->mac_addr[4]     ;
+    control[3]=(mMACENTRY->fid&0xf)+((mMACENTRY->portmap&0x3f)<<4);
+
+    if (((mMACENTRY->info_type)&0x01)) control[4]=(mMACENTRY->ctrl.info_ctrl)+0x1000; //static ,info control
+               else    control[4]=((mMACENTRY->ctrl.age_timer)&0xff);//not static ,agetimer
+               if (cmd==ADM_SW_IOCTL_MACENTRY_GET_INIT) {      
+                 //initial  the pointer to the first address   
+                  val=0x8000;//busy ,status5[15]
+                  while(val&0x8000){           //check busy ?
+                  ifx_sw_read(0x125, &val);
+               }    
+               control[5]=0x030;//initial the first address    
+               ifx_sw_write(0x11f,control[5]);
+                                               
+                                       
+                                  val=0x8000;//busy ,status5[15]
+                                  while(val&0x8000){           //check busy ?
+                                         ifx_sw_read(0x125, &val);
+                                       }               
+                       
+                  }    //if (cmd==ADM_SW_IOCTL_MACENTRY_GET_INIT)                                                              
+           if (cmd==ADM_SW_IOCTL_MACENTRY_ADD) control[5]=0x07;//create a new address
+               else if (cmd==ADM_SW_IOCTL_MACENTRY_DEL) control[5]=0x01f;//erased an existed address
+               else if ((cmd==ADM_SW_IOCTL_MACENTRY_GET_INIT)||(cmd==ADM_SW_IOCTL_MACENTRY_GET_MORE)) 
+                       control[5]=0x02c;//search by the mac address field
+           
+           val=0x8000;//busy ,status5[15]
+           while(val&0x8000){          //check busy ?
+                 ifx_sw_read(0x125, &val);
+               }
+               ifx_sw_write(0x11a,control[0]); 
+               ifx_sw_write(0x11b,control[1]); 
+               ifx_sw_write(0x11c,control[2]); 
+               ifx_sw_write(0x11d,control[3]); 
+               ifx_sw_write(0x11e,control[4]); 
+               ifx_sw_write(0x11f,control[5]); 
+           val=0x8000;//busy ,status5[15]
+           while(val&0x8000){          //check busy ?
+                 ifx_sw_read(0x125, &val);
+               }       
+           val=((val&0x7000)>>12);//result ,status5[14:12]
+           mMACENTRY->result=val;
+   
+           if (!val) {
+                       printk(" Command OK!! \n");
+                       if ((cmd==ADM_SW_IOCTL_MACENTRY_GET_INIT)||(cmd==ADM_SW_IOCTL_MACENTRY_GET_MORE)) {
+                                       ifx_sw_read(0x120,&(status[0]));        
+                                       ifx_sw_read(0x121,&(status[1]));        
+                                       ifx_sw_read(0x122,&(status[2]));        
+                                       ifx_sw_read(0x123,&(status[3]));        
+                                       ifx_sw_read(0x124,&(status[4]));        
+                                       ifx_sw_read(0x125,&(status[5]));        
+               
+                                       
+                                       mMACENTRY->mac_addr[0]=(status[0]&0x00ff)       ;
+                                       mMACENTRY->mac_addr[1]=(status[0]&0xff00)>>8    ;
+                                       mMACENTRY->mac_addr[2]=(status[1]&0x00ff)    ;
+                                       mMACENTRY->mac_addr[3]=(status[1]&0xff00)>>8 ;
+                                       mMACENTRY->mac_addr[4]=(status[2]&0x00ff)    ;
+                                       mMACENTRY->mac_addr[5]=(status[2]&0xff00)>>8 ;
+                                       mMACENTRY->fid=(status[3]&0xf);
+                                       mMACENTRY->portmap=((status[3]>>4)&0x3f);
+                                       if (status[5]&0x2) {//static info_ctrl //status5[1]????
+                                               mMACENTRY->ctrl.info_ctrl=(status[4]&0x00ff);
+                                               mMACENTRY->info_type=1;
+                                                       }
+                                       else {//not static age_timer
+                                               mMACENTRY->ctrl.age_timer=(status[4]&0x00ff);
+                                               mMACENTRY->info_type=0;
+                                                       }
+//status5[13]????                                      mMACENTRY->occupy=(status[5]&0x02)>>1;//status5[1]
+                                       mMACENTRY->occupy=(status[5]&0x02000)>>13;//status5[13] ???
+                                       mMACENTRY->bad=(status[5]&0x04)>>2;//status5[2]
+                               }//if ((cmd==ADM_SW_IOCTL_MACENTRY_GET_INIT)||(cmd==ADM_SW_IOCTL_MACENTRY_GET_MORE)) 
+                       
+               }
+           else if (val==0x001)  
+                printk(" All Entry Used!! \n");
+            else if (val==0x002) 
+                printk("  Entry Not Found!! \n");
+            else if (val==0x003) 
+                printk(" Try Next Entry!! \n");
+            else if (val==0x005)  
+                printk(" Command Error!! \n");   
+            else   
+                printk(" UnKnown Error!! \n");
+
+       // printk ("adm_process_mac_table_request: Exit\n");    
+       return 0;
+}
+
+/* Santosh: End of function for MAC ENTRY ADD/DEL*/
+struct file_operations adm_ops =
+{
+    read: adm_read,
+    write: adm_write,
+    open: adm_open,
+    release: adm_release,
+    ioctl: adm_ioctl
+};
+
+int adm_proc(char *buf, char **start, off_t offset, int count, int *eof, void *data)
+{
+    int len = 0;
+
+    len += sprintf(buf+len, " ************ Registers ************ \n");
+    *eof = 1;
+    return len;
+}
+
+int __init init_adm6996_module(void)
+{
+    unsigned int val = 000;
+    unsigned int val1 = 000;
+
+    printk("Loading ADM6996 driver... \n");
+
+    /* if running on adm5120 */
+    /* set GPIO 0~2 as adm6996 control pins */
+    //outl(0x003f3f00, 0x12000028);
+    /* enable switch port 5 (MII) as RMII mode (5120MAC <-> 6996MAC) */
+    //outl(0x18a, 0x12000030);
+    /* group adm5120 port 1 ~ 5 as VLAN0, port 5 & 6(CPU) as VLAN1 */
+    //outl(0x417e, 0x12000040);
+    /* end adm5120 fixup */
+#ifdef ADM6996_MDC_MDIO_MODE //smi mode //000001.joelin
+    register_chrdev(69, "adm6996", &adm_ops);
+    AMAZON_SW_REG(AMAZON_SW_MDIO_CFG) = 0x27be;
+    AMAZON_SW_REG(AMAZON_SW_EPHY) = 0xfc;
+    adm6996_mode=adm6996i;
+    ifx_sw_read(0xa0, &val);
+    ifx_sw_read(0xa1, &val1);
+    val=((val1&0x0f)<<16)|val;
+    printk ("\nADM6996 SMI Mode-");
+    printk ("Chip ID:%5x \n ", val);
+#else    //000001.joelin
+    AMAZON_SW_REG(AMAZON_SW_MDIO_CFG) = 0x2c50;
+    AMAZON_SW_REG(AMAZON_SW_EPHY) = 0xff;
+
+    AMAZON_SW_REG(AMAZON_GPIO_P1_ALTSEL0) &= ~(GPIO_MDIO|GPIO_MDCS|GPIO_MDC);
+    AMAZON_SW_REG(AMAZON_GPIO_P1_ALTSEL1) &= ~(GPIO_MDIO|GPIO_MDCS|GPIO_MDC);
+    AMAZON_SW_REG(AMAZON_GPIO_P1_OD) |= (GPIO_MDIO|GPIO_MDCS|GPIO_MDC);
+  
+    ifx_gpio_init();
+    register_chrdev(69, "adm6996", &adm_ops);
+    mdelay(100);
+
+    /* create proc entries */
+    //  create_proc_read_entry("admide", 0, NULL, admide_proc, NULL);
+
+//joelin adm6996i support start
+    adm6996_mode=adm6996i;
+    ifx_sw_read(0xa0, &val);
+    adm6996_mode=adm6996l;
+    ifx_sw_read(0x200, &val1);
+//  printk ("\n %0x \n",val1);
+    if ((val&0xfff0)==0x1020) {
+        printk ("\n ADM6996I .. \n");
+        adm6996_mode=adm6996i; 
+    }
+    else if ((val1&0xffffff00)==0x71000) {//71010 or 71020
+        printk ("\n ADM6996LC .. \n");
+        adm6996_mode=adm6996lc;        
+    }
+    else  {
+        printk ("\n ADM6996L .. \n");
+        adm6996_mode=adm6996l; 
+    }
+#endif //ADM6996_MDC_MDIO_MODE //smi mode //000001.joelin      
+
+    if ((adm6996_mode==adm6996lc)||(adm6996_mode==adm6996i)){
+#if 0  /* removed by MarsLin */
+        ifx_sw_write(0x29,0xc000);
+        ifx_sw_write(0x30,0x0985);
+#else
+        ifx_sw_read(0xa0, &val);
+        if (val == 0x1021) // for both 6996LC and 6996I, only AB version need the patch
+            ifx_sw_write(0x29, 0x9000);
+        ifx_sw_write(0x30,0x0985);
+#endif
+    }
+//joelin adm6996i support end
+    return 0;
+}
+
+void __exit cleanup_adm6996_module(void)
+{
+    printk("Free ADM device driver... \n");
+
+    unregister_chrdev(69, "adm6996");
+
+    /* remove proc entries */
+    //  remove_proc_entry("admide", NULL);
+}
+
+/* MarsLin, add start */
+#if defined(CONFIG_IFX_NFEXT_AMAZON_SWITCH_PHYPORT) || defined(CONFIG_IFX_NFEXT_AMAZON_SWITCH_PHYPORT_MODULE)
+    #define SET_BIT(reg, mask)         reg |= (mask)
+    #define CLEAR_BIT(reg, mask)       reg &= (~mask)
+    static int ifx_hw_reset(void)
+    {
+        CLEAR_BIT((*AMAZON_GPIO_P0_ALTSEL0),0x2000);
+        CLEAR_BIT((*AMAZON_GPIO_P0_ALTSEL1),0x2000);
+        SET_BIT((*AMAZON_GPIO_P0_OD),0x2000);
+        SET_BIT((*AMAZON_GPIO_P0_DIR), 0x2000);
+       CLEAR_BIT((*AMAZON_GPIO_P0_OUT), 0x2000);
+       mdelay(500);
+       SET_BIT((*AMAZON_GPIO_P0_OUT), 0x2000);
+        cleanup_adm6996_module();
+        return init_adm6996_module();
+    }
+    int (*adm6996_hw_reset)(void) = ifx_hw_reset;
+    EXPORT_SYMBOL(adm6996_hw_reset);
+    EXPORT_SYMBOL(adm6996_mode);
+    int (*adm6996_sw_read)(unsigned int addr, unsigned int *data) = ifx_sw_read;
+    EXPORT_SYMBOL(adm6996_sw_read);
+    int (*adm6996_sw_write)(unsigned int addr, unsigned int data) = ifx_sw_write;
+    EXPORT_SYMBOL(adm6996_sw_write);
+#endif
+/* MarsLin, add end */
+
+/* Santosh: for IGMP proxy/snooping, Begin */
+EXPORT_SYMBOL (adm_process_mac_table_request);
+EXPORT_SYMBOL (adm_process_protocol_filter_request);
+/* Santosh: for IGMP proxy/snooping, End */
+       
+MODULE_DESCRIPTION("ADMtek 6996 Driver");
+MODULE_AUTHOR("Joe Lin <joe.lin@infineon.com>");
+MODULE_LICENSE("GPL");
+
+module_init(init_adm6996_module);
+module_exit(cleanup_adm6996_module);
+
diff --git a/target/linux/amazon-2.6/files/drivers/char/amazon_mei.c b/target/linux/amazon-2.6/files/drivers/char/amazon_mei.c
new file mode 100644 (file)
index 0000000..7efe52e
--- /dev/null
@@ -0,0 +1,7918 @@
+/* ============================================================================
+ * Copyright (C) 2004 -Infineon Technologies AG.
+ *
+ * All rights reserved.
+ * ============================================================================
+ *
+ *============================================================================
+ * Licensed under GNU GPL v2
+ * ============================================================================
+ */
+
+/* ===========================================================================
+ *
+ * File Name:   amazon_mei.c
+ * Author :     Ou Ke
+ *
+ * ===========================================================================
+ *
+ * Project: Amazon
+ *
+ * ===========================================================================
+ * Contents:This file implements the MEI driver for Amazon ADSL/ADSL2+
+ *  controller.
+ *  
+ * ===========================================================================
+ * References: 
+ *
+ */
+
+
+/* ===========================================================================
+ * Revision History:
+ *             12/1/2005 : Ritesh Banerjee
+ *                     - Create a kernel thread kmibpoll to poll for periodic RFC 2662
+ *                     and RFC 3440 counters. Removes the need for user space 
+ *                     adsl_mibpoll_daemon and saves atleast 30KB of RAM.
+ *
+ * $Log$
+ * ===========================================================================
+ */
+
+/*
+ * ===========================================================================
+ *                           INCLUDE FILES
+ * ===========================================================================
+ */
+//000002:fchang 2005/6/2 joelin 04/27/2005 for pcm clock
+//000003:fchang 2005/6/2 Henry added for Amazon-E support
+//165001:henryhsu 2005/9/6 Modify for adsl firmware version 1.2.1.2.0.1 DATA_LED can't flash.
+// 509221:tc.chen 2005/09/22 Reset DFE added when MEI_TO_ARC_CS_DONE not cleared by ARC
+// 603221:tc.chen 2006/03/21 added APIs to support the WEB related parameters for ADSL Statistics
+
+#ifndef EXPORT_SYMTAB
+#define EXPORT_SYMTAB
+#endif
+#define AMAZON_MEI_MIB_RFC3440
+
+#include <linux/config.h>
+#include <linux/kernel.h>
+#include <linux/module.h>               
+#include <linux/version.h>
+#include <linux/types.h>
+#include <linux/fs.h>
+#include <linux/mm.h>
+#include <linux/errno.h>
+#include <linux/interrupt.h>
+#include <linux/netdevice.h>
+#include <linux/etherdevice.h>
+#include <asm/irq.h>
+#include <asm/segment.h>
+#include <asm/semaphore.h>
+#include <linux/init.h>                                  
+#include <linux/ioport.h>
+#include <asm/uaccess.h>                       
+#include <linux/proc_fs.h>
+#include <asm/io.h>
+#include <linux/vmalloc.h>
+#include <linux/delay.h>
+#include <linux/poll.h>
+#include <linux/list.h>
+#include <linux/time.h>
+
+#include <asm/amazon/amazon.h>
+#include <asm/irq.h>
+#include <asm/amazon/irq.h>
+#include <asm/amazon/amazon_mei.h>
+#include <asm/amazon/amazon_mei_app.h>
+#include <asm/amazon/amazon_mei_ioctl.h>
+#include <asm/amazon/amazon_mei_app_ioctl.h>
+
+#define SET_BIT(reg, mask)                  reg |= (mask)
+#define CLEAR_BIT(reg, mask)                reg &= (~mask)
+#define CLEAR_BITS(reg, mask)               CLEAR_BIT(reg, mask)
+#define SET_BITS(reg, mask)                 SET_BIT(reg, mask)
+#define SET_BITFIELD(reg, mask, off, val)   {reg &= (~mask); reg |= (val << off);}
+
+extern void mask_and_ack_amazon_irq(unsigned int irq_nr);
+
+#ifdef AMAZON_CHECK_LINK
+//amazon_tpe.c
+extern int (*adsl_link_notify)(int);
+#endif //AMAZON_CHECK_LINK
+
+// for ARC memory access
+#define WHILE_DELAY 20000
+#define AMAZON_DMA_DEBUG_MUTEX
+
+
+//TODO
+#undef DFE_LOOPBACK
+#define ARC_READY_ACK
+
+static amazon_mei_mib * current_intvl;
+static struct list_head interval_list;
+static amazon_mei_mib * mei_mib;
+
+static int reboot_firsttime=1;//000002:fchang
+
+       //PCM
+#define PCM_CHANNEL_NUM                2       //1 rx, 1 tx
+static pcm_data_struct pcm_data[PCM_CHANNEL_NUM]__attribute__ ((aligned(4)));  //0=tx0, 1=rx0, 2=tx1, 3=rx1
+static u32 pcm_start_addr;
+//#define PCM_HRT_TIME_HZ              4000    //?us
+#define PCM_ACCESS_DEBUG
+static int irqtimes=0;
+#undef DATA_LED_ON_MODE
+#define ADSL_LED_SUPPORT       //joelin for adsl led
+#ifdef ADSL_LED_SUPPORT
+static int firmware_support_led=0; //joelin version check      for adsl led    
+static int stop_led_module=0;  //wakeup and clean led module
+static int led_support_check=0;        //1.1.2.7.1.1
+#endif //ADSL_LED_SUPPORT
+#define IFX_DYING_GASP
+#ifdef IFX_DYING_GASP
+static wait_queue_head_t wait_queue_dying_gasp;        //dying gasp
+//struct tq_struct dying_gasp_task;            //dying gasp
+static wait_queue_head_t wait_queue_uas_poll;  //joelin 04/16/2005
+static u16 unavailable_seconds=0;              //joelin 04/16/2005
+static meidebug lop_debugwr;                           //dying gasp
+#endif //IFX_DYING_GASP
+static int dbg_int=0;
+//#define DEBUG_ACCESS_DELAY   for(dbg_int=0;dbg_int<100;dbg_int++){;}
+#define DEBUG_ACCESS_DELAY
+static u8 sampledata[512];
+static int firsttime[PCM_CHANNEL_NUM]={0,1};
+static int num_cmp[PCM_CHANNEL_NUM]={0,0};
+static int pcm_start_loc[PCM_CHANNEL_NUM]={0,0}; 
+
+       // for clearEoC 
+//#define MEI_CLREOC_BUFF_SIZE 512     //double the receive fifo size, bytes
+//static u8 clreoc[MEI_CLREOC_BUFF_SIZE]__attribute__ ((aligned(4)));  //buffer to hold clearEoC data in bytes
+#undef AMAZON_CLEAR_EOC
+#ifdef AMAZON_CLEAR_EOC
+extern void ifx_push_eoc(struct sk_buff * pkt);
+#endif
+static int meiResetArc(void); 
+#define IFX_POP_EOC_DONE       0
+#define IFX_POP_EOC_FAIL       -1
+static struct list_head clreoc_list;
+static amazon_clreoc_pkt * clreoc_pkt;
+#define CLREOC_BUFF_SIZE       12      //number of clreoc commands being buffered
+//static int clreoc_wr=0;
+//static int clreoc_rd=0;              //used to control clreoc circular buffer 
+static wait_queue_head_t wait_queue_clreoc;
+#ifdef ADSL_LED_SUPPORT
+static wait_queue_head_t wait_queue_led;       //adsl led
+static wait_queue_head_t wait_queue_led_polling;// adsl led
+struct tq_struct led_task;                     // adsl led
+static DECLARE_TASK_QUEUE(tq_ifx_led);         // task
+int adsl_led_flash_task(void *ptr);            // adsl led
+#endif //ADSL_LED_SUPPORT
+static void * clreoc_command_pkt=NULL;
+static int clreoc_max_tx_len=0;
+
+// 603221:tc.chen start
+#define ME_HDLC_IDLE 0
+#define ME_HDLC_INVALID_MSG 1
+#define ME_HDLC_MSG_QUEUED 2
+#define ME_HDLC_MSG_SENT 3
+#define ME_HDLC_RESP_RCVD 4
+#define ME_HDLC_RESP_TIMEOUT 5
+#define ME_HDLC_RX_BUF_OVERFLOW 6
+#define ME_HDLC_UNRESOLVED 1
+#define ME_HDLC_RESOLVED 2
+// 603221:tc.chen end
+
+#ifdef LOCK_RETRY
+static int reboot_lock=0;
+#endif
+
+static mib_previous_read mib_pread={0,0,0,0,0,0,0,0,0,0,0,0};
+static mib_flags_pretime mib_pflagtime;// initialized when module loaded
+
+       static u32 ATUC_PERF_LOFS=0;
+       static u32 ATUC_PERF_LOSS=0;
+       static u32 ATUC_PERF_ESS=0;
+       static u32 ATUC_PERF_INITS=0;
+       static u32 ATUR_PERF_LOFS=0;
+       static u32 ATUR_PERF_LOSS=0;
+       static u32 ATUR_PERF_LPR=0;
+       static u32 ATUR_PERF_ESS=0;
+       static u32 ATUR_CHAN_RECV_BLK=0;
+       static u32 ATUR_CHAN_TX_BLK=0;
+       static u32 ATUR_CHAN_CORR_BLK=0;
+       static u32 ATUR_CHAN_UNCORR_BLK=0;
+       //RFC-3440
+       static u32 ATUC_PERF_STAT_FASTR=0;
+       static u32 ATUC_PERF_STAT_FAILED_FASTR=0;
+       static u32 ATUC_PERF_STAT_SESL=0;
+       static u32 ATUC_PERF_STAT_UASL=0;
+       static u32 ATUR_PERF_STAT_SESL=0;
+       static u32 ATUR_PERF_STAT_UASL=0;
+
+       static adslChanPrevTxRate PrevTxRate={0,0};
+       static adslPhysCurrStatus CurrStatus={0,0};
+       static ChanType chantype={0,0};
+       static adslLineAlarmConfProfileEntry AlarmConfProfile={"No Name\0",0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1};
+// 603221:tc.chen start
+       static adslFarEndPerfStats FarendStatsData;
+       struct timeval FarendData_acquire_time={0};
+       static u32 adsl_mode,adsl_mode_extend; // adsl mode : adsl/ 2/ 2+
+       static adslInitStats AdslInitStatsData;
+//603221:tc.chen end
+static u32 loop_diagnostics_mode=0;
+static wait_queue_head_t wait_queue_loop_diagnostic;
+#ifdef AMAZON_MEI_MIB_RFC3440
+       static adslLineAlarmConfProfileExtEntry AlarmConfProfileExt={"No Name\0",0,0,0,0,0,0};
+#endif
+
+static int showtime=0;
+static int loop_diagnostics_completed=0;
+//////////////////////////////////////////////////////////////////////////////////
+static int phy_mei_net_init(struct net_device * dev);
+static int interleave_mei_net_init(struct net_device * dev);
+static int fast_mei_net_init(struct net_device * dev);
+static struct net_device_stats * phy_mei_net_get_stats(struct net_device * dev);
+static struct net_device_stats * interleave_mei_net_get_stats(struct net_device * dev);
+static struct net_device_stats * fast_mei_net_get_stats(struct net_device * dev);
+
+typedef struct mei_priv{
+        struct net_device_stats stats;
+}mei_priv;
+
+static struct net_device phy_mei_net = { init: phy_mei_net_init, name: "MEI_PHY"};
+static struct net_device interleave_mei_net = { init: interleave_mei_net_init, name: "MEI_INTL"};
+static struct net_device fast_mei_net = { init: fast_mei_net_init, name: "MEI_FAST"};
+///////////////////////////////////////////////////////////////////////////////////
+
+static int major=AMAZON_MEI_MAJOR;
+
+static struct semaphore mei_sema;
+
+// Mei to ARC CMV count, reply count, ARC Indicator count
+static int indicator_count=0;
+static int cmv_count=0;
+static int reply_count=0;
+static u16 Recent_indicator[MSG_LENGTH];
+
+// Used in interrupt handler as flags
+static int arcmsgav=0;
+static int cmv_reply=0;
+static int cmv_waiting=0;
+
+#define PROC_ITEMS 8
+
+long mei_debug_mode = 0; //509221:tc.chen for adsl firmware debug
+
+//  to wait for arc cmv reply, sleep on wait_queue_arcmsgav;
+static wait_queue_head_t wait_queue_arcmsgav;
+static wait_queue_head_t wait_queue_codeswap;
+static wait_queue_head_t wait_queue_mibdaemon;
+static wait_queue_head_t wait_queue_reboot;
+static u32 * image_buffer=NULL;                // holding adsl firmware image
+static u16 RxMessage[MSG_LENGTH]__attribute__ ((aligned(4)));
+static u16 TxMessage[MSG_LENGTH]__attribute__ ((aligned(4)));                                                                                                               
+static u32 * mei_arc_swap_buff=NULL;           //  holding swap pages
+static ARC_IMG_HDR * img_hdr;
+static int reboot_flag;
+
+#ifdef DFE_LOOPBACK
+#include "arc_pm.h"
+#endif
+
+
+/////////////////               net device                              ///////////////////////////////////////////////////
+static int phy_mei_net_init(struct net_device * dev)
+{
+        //ether_setup(dev);
+        dev->get_stats = phy_mei_net_get_stats;
+        dev->ip_ptr = NULL;
+       dev->type = 94;
+       
+//     dev->mtu=12345;
+       dev->flags=IFF_UP;
+       
+        dev->priv = kmalloc(sizeof(struct mei_priv), GFP_KERNEL);
+        if(dev->priv == NULL)
+                return -ENOMEM;
+        memset(dev->priv, 0, sizeof(struct mei_priv));
+        return 0;
+}
+
+static int interleave_mei_net_init(struct net_device * dev)
+{
+        //ether_setup(dev);
+        dev->get_stats = interleave_mei_net_get_stats;
+        dev->ip_ptr = NULL;
+       dev->type = 124;
+       dev->flags=IFF_UP;
+        dev->priv = kmalloc(sizeof(struct mei_priv), GFP_KERNEL);
+        if(dev->priv == NULL)
+                return -ENOMEM;
+        memset(dev->priv, 0, sizeof(struct mei_priv));
+        return 0;
+}
+
+static int fast_mei_net_init(struct net_device * dev)
+{
+        //ether_setup(dev);
+        dev->get_stats = fast_mei_net_get_stats;
+        dev->ip_ptr = NULL;
+       dev->type = 125;
+       dev->flags=IFF_UP;
+        dev->priv = kmalloc(sizeof(struct mei_priv), GFP_KERNEL);
+        if(dev->priv == NULL)
+                return -ENOMEM;
+        memset(dev->priv, 0, sizeof(struct mei_priv));
+        return 0;
+}
+
+static struct net_device_stats * phy_mei_net_get_stats(struct net_device * dev)
+{
+        struct mei_priv * priv;
+        priv = (struct mei_priv *)dev->priv;
+       // update statistics
+       (priv->stats).rx_packets = ATUR_CHAN_RECV_BLK;
+       (priv->stats).tx_packets = ATUR_CHAN_TX_BLK;
+       (priv->stats).rx_errors = ATUR_CHAN_CORR_BLK + ATUR_CHAN_UNCORR_BLK;
+       (priv->stats).rx_dropped = ATUR_CHAN_UNCORR_BLK;
+       
+        return &(priv->stats);
+}
+
+static struct net_device_stats * interleave_mei_net_get_stats(struct net_device * dev)
+{
+        struct mei_priv * priv;
+        priv = (struct mei_priv *)dev->priv;
+       // update statistics
+       (priv->stats).rx_packets = ATUR_CHAN_RECV_BLK;
+       (priv->stats).tx_packets = ATUR_CHAN_TX_BLK;
+       (priv->stats).rx_errors = ATUR_CHAN_CORR_BLK + ATUR_CHAN_UNCORR_BLK;
+       (priv->stats).rx_dropped = ATUR_CHAN_UNCORR_BLK;
+       
+        return &(priv->stats);
+}
+
+static struct net_device_stats * fast_mei_net_get_stats(struct net_device * dev)
+{
+        struct mei_priv * priv;
+        priv = (struct mei_priv *)dev->priv;
+       // update statistics
+       (priv->stats).rx_packets = ATUR_CHAN_RECV_BLK;
+       (priv->stats).tx_packets = ATUR_CHAN_TX_BLK;
+       (priv->stats).rx_errors = ATUR_CHAN_CORR_BLK + ATUR_CHAN_UNCORR_BLK;
+       (priv->stats).rx_dropped = ATUR_CHAN_UNCORR_BLK;
+       
+        return &(priv->stats);
+}
+/////////////////               mei access Rd/Wr methods       ///////////////////////////////////////////////////
+void meiLongwordWrite(u32 ul_address, u32 ul_data)
+{
+       *((volatile u32 *)ul_address) = ul_data;
+       asm("SYNC");
+       return;
+} //   end of "meiLongwordWrite(..."
+
+void meiLongwordRead(u32 ul_address, u32 *pul_data)
+{
+       *pul_data = *((volatile u32 *)ul_address);
+       asm("SYNC");
+       return;
+} //   end of "meiLongwordRead(..."
+
+MEI_ERROR meiDMAWrite(u32 destaddr, u32 *databuff, u32 databuffsize)
+{
+       u32 *p = databuff;
+       u32 temp;
+       u32 flags;
+
+       if( destaddr & 3)
+               return MEI_FAILURE;
+
+#ifdef AMAZON_DMA_DEBUG_MUTEX
+       save_flags(flags);
+       cli();
+#endif
+               
+
+       //      Set the write transfer address
+       meiLongwordWrite(MEI_XFR_ADDR, destaddr);
+
+       //      Write the data pushed across DMA
+       while (databuffsize--)
+       {
+               temp = *p;
+               if(databuff==(u32 *)TxMessage)  // swap half word
+                       temp = ((temp & 0xffff)<<16) + ((temp & 0xffff0000)>>16);
+               meiLongwordWrite(MEI_DATA_XFR, temp);
+               p++;
+       } //    end of "while(..."
+
+#ifdef AMAZON_DMA_DEBUG_MUTEX
+       restore_flags(flags);   
+#endif
+       
+       return MEI_SUCCESS;
+
+} //   end of "meiDMAWrite(..."
+
+MEI_ERROR meiDMAWrite_16(u32 destaddr, u32 *databuff, u32 databuffsize)
+{
+       u32 *p = databuff;
+       u32 temp;
+       u32 flags;
+
+       if( destaddr & 3)
+               return MEI_FAILURE;
+               
+#ifdef AMAZON_DMA_DEBUG_MUTEX
+       save_flags(flags);
+       cli();
+#endif
+               
+
+       //      Set the write transfer address
+       meiLongwordWrite(MEI_XFR_ADDR, destaddr);
+
+       //      Write the data pushed across DMA
+       while (databuffsize--)
+       {
+               temp = *p;
+               temp = ((temp & 0xffff)<<16) + ((temp & 0xffff0000)>>16);//swap half word
+               meiLongwordWrite(MEI_DATA_XFR, temp);
+               p++;
+       } //    end of "while(..."
+       
+#ifdef AMAZON_DMA_DEBUG_MUTEX
+       restore_flags(flags);
+#endif
+
+       return MEI_SUCCESS;
+
+} //   end of "meiDMAWrite_16(..."
+
+MEI_ERROR meiDMAWrite_8(u32 destaddr, u32 *databuff, u32 databuffsize)
+{
+       u32 *p = databuff;
+       u32 temp;
+       u32 flags;
+
+       if( destaddr & 3)
+               return MEI_FAILURE;
+               
+#ifdef AMAZON_DMA_DEBUG_MUTEX
+       save_flags(flags);
+       cli();
+#endif
+               
+
+       //      Set the write transfer address
+       meiLongwordWrite(MEI_XFR_ADDR, destaddr);
+
+       //      Write the data pushed across DMA
+       while (databuffsize--)
+       {
+               temp = *p;
+               temp = ((temp & 0xff)<<24) + ((temp & 0xff00)<<8)+ ((temp & 0xff0000)>>8)+ ((temp & 0xff000000)>>24);//swap byte
+               meiLongwordWrite(MEI_DATA_XFR, temp);
+               p++;
+       } //    end of "while(..."
+       
+#ifdef AMAZON_DMA_DEBUG_MUTEX
+       restore_flags(flags);
+#endif
+
+       return MEI_SUCCESS;
+
+} //   end of "meiDMAWrite_8(..."
+
+MEI_ERROR meiDMARead(u32 srcaddr, u32 *databuff, u32 databuffsize)
+{
+       u32 *p = databuff;
+       u32 temp;
+       u32 flags;
+       
+       if( srcaddr & 3)
+               return MEI_FAILURE;
+
+#ifdef AMAZON_DMA_DEBUG_MUTEX
+       save_flags(flags);
+       cli();
+#endif
+       
+
+       //      Set the read transfer address
+       meiLongwordWrite(MEI_XFR_ADDR, srcaddr);
+
+       //      Read the data popped across DMA
+       while (databuffsize--)
+       {
+               meiLongwordRead(MEI_DATA_XFR, &temp);
+               if(databuff==(u32 *)RxMessage)  // swap half word
+                       temp = ((temp & 0xffff)<<16) + ((temp & 0xffff0000)>>16);
+               *p=temp;
+               p++;
+       } //    end of "while(..."
+
+#ifdef AMAZON_DMA_DEBUG_MUTEX
+       restore_flags(flags);
+#endif
+
+       return MEI_SUCCESS;
+
+} //   end of "meiDMARead(..."
+
+MEI_ERROR meiDMARead_16(u32 srcaddr, u32 *databuff, u32 databuffsize)
+{
+       u32 *p = databuff;
+       u32 temp;
+       u32 flags;
+       
+       if( srcaddr & 3)
+               return MEI_FAILURE;
+               
+#ifdef AMAZON_DMA_DEBUG_MUTEX
+       save_flags(flags);
+       cli();
+#endif
+               
+
+       //      Set the read transfer address
+       meiLongwordWrite(MEI_XFR_ADDR, srcaddr);
+
+       //      Read the data popped across DMA
+       while (databuffsize--)
+       {
+               meiLongwordRead(MEI_DATA_XFR, &temp);
+               temp = ((temp & 0xffff)<<16) + ((temp & 0xffff0000)>>16);
+               *p=temp;
+               p++;
+       } //    end of "while(..."
+       
+#ifdef AMAZON_DMA_DEBUG_MUTEX
+       restore_flags(flags);
+#endif
+
+       return MEI_SUCCESS;
+
+} //   end of "meiDMARead_16(..."
+
+MEI_ERROR meiDMARead_8(u32 srcaddr, u32 *databuff, u32 databuffsize)
+{
+       u32 *p = databuff;
+       u32 temp;
+       u32 flags;
+       
+       if( srcaddr & 3)
+               return MEI_FAILURE;
+               
+#ifdef AMAZON_DMA_DEBUG_MUTEX
+       save_flags(flags);
+       cli();
+#endif
+               
+
+       //      Set the read transfer address
+       meiLongwordWrite(MEI_XFR_ADDR, srcaddr);
+
+       //      Read the data popped across DMA
+       while (databuffsize--)
+       {
+               meiLongwordRead(MEI_DATA_XFR, &temp);
+               temp = ((temp & 0xff)<<24) + ((temp & 0xff00)<<8)+ ((temp & 0xff0000)>>8)+ ((temp & 0xff000000)>>24);//swap byte
+               *p=temp;
+               p++;
+       } //    end of "while(..."
+       
+#ifdef AMAZON_DMA_DEBUG_MUTEX
+       restore_flags(flags);
+#endif
+
+       return MEI_SUCCESS;
+
+} //   end of "meiDMARead_8(..."
+
+void meiPollForDbgDone(void)
+{
+       u32     query = 0;
+       int     i=0;
+       while (i<WHILE_DELAY)
+       {
+               meiLongwordRead(ARC_TO_MEI_INT, &query);
+               query &= (ARC_TO_MEI_DBG_DONE);
+               if(query)
+                       break;
+               i++;
+               if(i==WHILE_DELAY){
+#ifdef AMAZON_MEI_DEBUG_ON
+                       printk("\n\n PollforDbg fail");
+#endif
+               }
+                       DEBUG_ACCESS_DELAY;
+       } 
+       meiLongwordWrite(ARC_TO_MEI_INT,  ARC_TO_MEI_DBG_DONE);  // to clear this interrupt
+} //   end of "meiPollForDbgDone(..."
+
+MEI_ERROR meiDebugWrite_8(u32 destaddr, u32 *databuff, u32 databuffsize)
+{
+       u32 i;
+       u32 temp = 0x0;
+       u32 address = 0x0;
+       u32 *buffer = 0x0;
+       u32 flags;
+       
+#ifdef AMAZON_DMA_DEBUG_MUTEX
+       save_flags(flags);
+       cli();
+#endif
+       
+
+       //      Open the debug port before DMP memory write
+       meiLongwordRead(MEI_CONTROL, &temp);
+               DEBUG_ACCESS_DELAY;     
+       temp |= (HOST_MSTR);
+       meiLongwordWrite(MEI_CONTROL, temp);
+               DEBUG_ACCESS_DELAY;
+       meiLongwordWrite(MEI_DEBUG_DEC, MEI_DEBUG_DEC_DMP1_MASK);
+               DEBUG_ACCESS_DELAY;
+
+       //      For the requested length, write the address and write the data
+       address = destaddr;
+       buffer = databuff;
+       for (i=0; i < databuffsize; i++)
+       {
+               meiLongwordWrite(MEI_DEBUG_WAD, address);
+                       DEBUG_ACCESS_DELAY;
+               temp=*buffer;
+               temp = ((temp & 0xff)<<24) + ((temp & 0xff00)<<8)+ ((temp & 0xff0000)>>8)+ ((temp & 0xff000000)>>24);//swap byte
+               meiLongwordWrite(MEI_DEBUG_DATA, temp);
+                       DEBUG_ACCESS_DELAY;
+               meiPollForDbgDone();
+               address += 4;
+               buffer++;
+       } //    end of "for(..."
+
+       //      Close the debug port after DMP memory write
+       meiLongwordRead(MEI_CONTROL, &temp);
+               DEBUG_ACCESS_DELAY;
+       temp &= ~(HOST_MSTR);
+       meiLongwordWrite(MEI_CONTROL, temp);
+               DEBUG_ACCESS_DELAY;
+               
+#ifdef AMAZON_DMA_DEBUG_MUTEX
+       restore_flags(flags);
+#endif
+
+       //      Return
+       return MEI_SUCCESS;
+
+} //   end of "meiDebugWrite_8(..."
+
+MEI_ERROR meiDebugRead_8(u32 srcaddr, u32 *databuff, u32 databuffsize)
+{
+       u32 i;
+       u32 temp = 0x0;
+       u32 address = 0x0;
+       u32 *buffer = 0x0;
+       u32 flags;
+       
+#ifdef AMAZON_DMA_DEBUG_MUTEX
+       save_flags(flags);
+       cli();
+#endif
+       
+
+       //      Open the debug port before DMP memory read
+       meiLongwordRead(MEI_CONTROL, &temp);
+               DEBUG_ACCESS_DELAY;
+       temp |= (HOST_MSTR);
+       meiLongwordWrite(MEI_CONTROL, temp);
+               DEBUG_ACCESS_DELAY;
+       meiLongwordWrite(MEI_DEBUG_DEC, MEI_DEBUG_DEC_DMP2_MASK);
+               DEBUG_ACCESS_DELAY;
+
+       //      For the requested length, write the address and read the data
+       address = srcaddr;
+       buffer = databuff;
+       for (i=0; i<databuffsize; i++)
+       {
+               meiLongwordWrite(MEI_DEBUG_RAD, address);
+                       DEBUG_ACCESS_DELAY;
+               meiPollForDbgDone();
+               meiLongwordRead(MEI_DEBUG_DATA, &temp);
+                       DEBUG_ACCESS_DELAY;
+               temp = ((temp & 0xff)<<24) + ((temp & 0xff00)<<8)+ ((temp & 0xff0000)>>8)+ ((temp & 0xff000000)>>24);//swap byte
+               *buffer=temp;
+               address += 4;
+               buffer++;
+       } //    end of "for(..."
+
+       //      Close the debug port after DMP memory read
+       meiLongwordRead(MEI_CONTROL, &temp);
+               DEBUG_ACCESS_DELAY;
+       temp &= ~(HOST_MSTR);
+       meiLongwordWrite(MEI_CONTROL, temp);
+               DEBUG_ACCESS_DELAY;
+               
+#ifdef AMAZON_DMA_DEBUG_MUTEX
+       restore_flags(flags);
+#endif
+
+       //      Return
+       return MEI_SUCCESS;
+
+} //   end of "meiDebugRead_8(..."
+
+MEI_ERROR meiDebugWrite_16(u32 destaddr, u32 *databuff, u32 databuffsize)
+{
+       u32 i;
+       u32 temp = 0x0;
+       u32 address = 0x0;
+       u32 *buffer = 0x0;
+       u32 flags;
+       
+#ifdef AMAZON_DMA_DEBUG_MUTEX
+       save_flags(flags);
+       cli();
+#endif
+       
+
+       //      Open the debug port before DMP memory write
+       meiLongwordRead(MEI_CONTROL, &temp);
+               DEBUG_ACCESS_DELAY;
+       temp |= (HOST_MSTR);
+       meiLongwordWrite(MEI_CONTROL, temp);
+               DEBUG_ACCESS_DELAY;
+       meiLongwordWrite(MEI_DEBUG_DEC, MEI_DEBUG_DEC_DMP1_MASK);
+               DEBUG_ACCESS_DELAY;
+
+       //      For the requested length, write the address and write the data
+       address = destaddr;
+       buffer = databuff;
+       for (i=0; i < databuffsize; i++)
+       {
+               meiLongwordWrite(MEI_DEBUG_WAD, address);
+                       DEBUG_ACCESS_DELAY;
+               temp=*buffer;
+               temp = ((temp & 0xffff)<<16) + ((temp & 0xffff0000)>>16);//swap half word
+               meiLongwordWrite(MEI_DEBUG_DATA, temp);
+                       DEBUG_ACCESS_DELAY;
+               meiPollForDbgDone();
+               address += 4;
+               buffer++;
+       } //    end of "for(..."
+
+       //      Close the debug port after DMP memory write
+       meiLongwordRead(MEI_CONTROL, &temp);
+               DEBUG_ACCESS_DELAY;
+       temp &= ~(HOST_MSTR);
+       meiLongwordWrite(MEI_CONTROL, temp);
+               DEBUG_ACCESS_DELAY;
+               
+#ifdef AMAZON_DMA_DEBUG_MUTEX
+       restore_flags(flags);
+#endif
+
+       //      Return
+       return MEI_SUCCESS;
+
+} //   end of "meiDebugWrite_16(..."
+
+MEI_ERROR meiDebugRead_16(u32 srcaddr, u32 *databuff, u32 databuffsize)
+{
+       u32 i;
+       u32 temp = 0x0;
+       u32 address = 0x0;
+       u32 *buffer = 0x0;
+       u32 flags;
+       
+#ifdef AMAZON_DMA_DEBUG_MUTEX
+       save_flags(flags);
+       cli();
+#endif
+       
+
+       //      Open the debug port before DMP memory read
+       meiLongwordRead(MEI_CONTROL, &temp);
+               DEBUG_ACCESS_DELAY;
+       temp |= (HOST_MSTR);
+       meiLongwordWrite(MEI_CONTROL, temp);
+               DEBUG_ACCESS_DELAY;
+       meiLongwordWrite(MEI_DEBUG_DEC, MEI_DEBUG_DEC_DMP2_MASK);
+               DEBUG_ACCESS_DELAY;
+
+       //      For the requested length, write the address and read the data
+       address = srcaddr;
+       buffer = databuff;
+       for (i=0; i<databuffsize; i++)
+       {
+               meiLongwordWrite(MEI_DEBUG_RAD, address);
+                       DEBUG_ACCESS_DELAY;
+               meiPollForDbgDone();
+               meiLongwordRead(MEI_DEBUG_DATA, &temp);
+                       DEBUG_ACCESS_DELAY;
+               temp = ((temp & 0xffff)<<16) + ((temp & 0xffff0000)>>16);//swap half word
+               *buffer=temp;
+               address += 4;
+               buffer++;
+       } //    end of "for(..."
+
+       //      Close the debug port after DMP memory read
+       meiLongwordRead(MEI_CONTROL, &temp);
+               DEBUG_ACCESS_DELAY;
+       temp &= ~(HOST_MSTR);
+       meiLongwordWrite(MEI_CONTROL, temp);
+               DEBUG_ACCESS_DELAY;
+               
+#ifdef AMAZON_DMA_DEBUG_MUTEX
+       restore_flags(flags);
+#endif
+
+       //      Return
+       return MEI_SUCCESS;
+
+} //   end of "meiDebugRead_16(..."
+
+MEI_ERROR meiDebugWrite(u32 destaddr, u32 *databuff, u32 databuffsize)
+{
+       u32 i;
+       u32 temp = 0x0;
+       u32 address = 0x0;
+       u32 *buffer = 0x0;
+       u32 flags;
+       
+#ifdef AMAZON_DMA_DEBUG_MUTEX
+       save_flags(flags);
+       cli();
+#endif
+       
+
+       //      Open the debug port before DMP memory write
+       meiLongwordRead(MEI_CONTROL, &temp);
+               DEBUG_ACCESS_DELAY;
+       temp |= (HOST_MSTR);
+       meiLongwordWrite(MEI_CONTROL, temp);
+               DEBUG_ACCESS_DELAY;
+       meiLongwordWrite(MEI_DEBUG_DEC, MEI_DEBUG_DEC_DMP1_MASK);
+               DEBUG_ACCESS_DELAY;
+
+       //      For the requested length, write the address and write the data
+       address = destaddr;
+       buffer = databuff;
+       for (i=0; i < databuffsize; i++)
+       {
+               meiLongwordWrite(MEI_DEBUG_WAD, address);
+                       DEBUG_ACCESS_DELAY;
+               temp=*buffer;
+               meiLongwordWrite(MEI_DEBUG_DATA, temp);
+                       DEBUG_ACCESS_DELAY;
+               meiPollForDbgDone();
+               address += 4;
+               buffer++;
+       } //    end of "for(..."
+
+       //      Close the debug port after DMP memory write
+       meiLongwordRead(MEI_CONTROL, &temp);
+               DEBUG_ACCESS_DELAY;
+       temp &= ~(HOST_MSTR);
+       meiLongwordWrite(MEI_CONTROL, temp);
+               DEBUG_ACCESS_DELAY;
+
+#ifdef AMAZON_DMA_DEBUG_MUTEX
+       restore_flags(flags);
+#endif
+
+       //      Return
+       return MEI_SUCCESS;
+
+} //   end of "meiDebugWrite(..."
+
+MEI_ERROR meiDebugRead(u32 srcaddr, u32 *databuff, u32 databuffsize)
+{
+       u32 i;
+       u32 temp = 0x0;
+       u32 address = 0x0;
+       u32 *buffer = 0x0;
+       u32 flags;
+       
+#ifdef AMAZON_DMA_DEBUG_MUTEX
+       save_flags(flags);
+       cli();
+#endif
+       
+
+       //      Open the debug port before DMP memory read
+       meiLongwordRead(MEI_CONTROL, &temp);
+               DEBUG_ACCESS_DELAY;
+       temp |= (HOST_MSTR);
+       meiLongwordWrite(MEI_CONTROL, temp);
+               DEBUG_ACCESS_DELAY;
+       meiLongwordWrite(MEI_DEBUG_DEC, MEI_DEBUG_DEC_DMP2_MASK);
+               DEBUG_ACCESS_DELAY;
+
+       //      For the requested length, write the address and read the data
+       address = srcaddr;
+       buffer = databuff;
+       for (i=0; i<databuffsize; i++)
+       {
+               meiLongwordWrite(MEI_DEBUG_RAD, address);
+                       DEBUG_ACCESS_DELAY;
+               meiPollForDbgDone();
+               meiLongwordRead(MEI_DEBUG_DATA, &temp);
+                       DEBUG_ACCESS_DELAY;
+               *buffer=temp;
+               address += 4;
+               buffer++;
+       } //    end of "for(..."
+
+       //      Close the debug port after DMP memory read
+       meiLongwordRead(MEI_CONTROL, &temp);
+               DEBUG_ACCESS_DELAY;
+       temp &= ~(HOST_MSTR);
+       meiLongwordWrite(MEI_CONTROL, temp);
+               DEBUG_ACCESS_DELAY;
+               
+#ifdef AMAZON_DMA_DEBUG_MUTEX
+       restore_flags(flags);
+#endif
+
+       //      Return
+       return MEI_SUCCESS;
+
+} //   end of "meiDebugRead(..."
+EXPORT_SYMBOL(meiDebugRead);
+
+void meiMailboxInterruptsDisable(void)
+{
+       meiLongwordWrite(ARC_TO_MEI_INT_MASK, 0x0);
+} //   end of "meiMailboxInterruptsDisable(..."
+
+void meiMailboxInterruptsEnable(void)
+{
+       meiLongwordWrite(ARC_TO_MEI_INT_MASK, MSGAV_EN); 
+} //   end of "meiMailboxInterruptsEnable(..."
+
+MEI_ERROR meiMailboxWrite(u16 *msgsrcbuffer, u16 msgsize)
+{
+       int i;
+       u32 arc_mailbox_status = 0x0;
+       u32 temp=0;
+       MEI_ERROR meiMailboxError = MEI_SUCCESS;
+
+       //      Check arc if mailbox write can be initiated
+/*     meiLongwordRead(MEI_TO_ARC_INT, &arc_mailbox_status);
+       if ((arc_mailbox_status & MEI_TO_ARC_MSGAV))
+       {
+               return MEI_MAILBOX_FULL;
+       }
+*/
+       //      Write to mailbox
+       meiMailboxError = meiDMAWrite(MEI_TO_ARC_MAILBOX, (u32*)msgsrcbuffer, msgsize/2);
+       meiMailboxError = meiDMAWrite(MEI_TO_ARC_MAILBOXR, (u32 *)(&temp), 1); 
+
+       //      Notify arc that mailbox write completed
+       cmv_waiting=1;
+       meiLongwordWrite(MEI_TO_ARC_INT, MEI_TO_ARC_MSGAV);
+       
+       i=0;
+        while(i<WHILE_DELAY){ // wait for ARC to clear the bit
+               meiLongwordRead(MEI_TO_ARC_INT, &arc_mailbox_status);
+               if((arc_mailbox_status & MEI_TO_ARC_MSGAV) != MEI_TO_ARC_MSGAV)
+                       break;
+               i++;
+               if(i==WHILE_DELAY){
+#ifdef AMAZON_MEI_DEBUG_ON
+                       printk("\n\n MEI_TO_ARC_MSGAV not cleared by ARC");
+#endif
+                       meiMailboxError = MEI_FAILURE;
+#if 0                  
+                       for(i=0;i<msgsize;i++)
+                               printk("\n %8x", (*(msgsrcbuffer+i)));
+#endif
+               }       
+       }      
+               
+       //      Return
+       return meiMailboxError;
+
+} //   end of "meiMailboxWrite(..."
+
+MEI_ERROR meiMailboxRead(u16 *msgdestbuffer, u16 msgsize)
+{
+       //u32 arc_mailbox_status = 0x0;
+       //u32 *mei_arc_msgbuff = 0x0;
+       MEI_ERROR meiMailboxError = MEI_SUCCESS;
+
+            /*
+            // Check arc if mailbox read can be initiated
+       meiLongwordRead(ARC_TO_MEI_INT, &arc_mailbox_status);
+       if ((arc_mailbox_status & ARC_TO_MEI_MSGAV) == 0)
+       {
+               return MEI_MAILBOX_EMPTY;
+       } //    end of "if(..."
+            */
+            
+       //      Read from mailbox
+       meiMailboxError = meiDMARead(ARC_TO_MEI_MAILBOX, (u32*)msgdestbuffer, msgsize/2);
+
+       //      Notify arc that mailbox read completed
+       meiLongwordWrite(ARC_TO_MEI_INT, ARC_TO_MEI_MSGAV);
+
+       //      Return
+       return meiMailboxError;
+
+} //   end of "meiMailboxRead(..."
+
+MEI_ERROR meiHaltArc(void)
+{
+       u32 arc_control_mode = 0x0;
+       u32 arc_debug_addr = 0x5;
+       u32 arc_debug_data = 0x0;
+
+       //      Switch arc control from JTAG mode to MEI mode- write '1' to bit0
+       meiLongwordRead(MEI_CONTROL, &arc_control_mode);
+       arc_control_mode |= (HOST_MSTR);
+       meiLongwordWrite(MEI_CONTROL, arc_control_mode);
+
+       //      Write arc aux reg access mask (0x0) into debug addr decode reg
+       meiLongwordWrite(MEI_DEBUG_DEC, MEI_DEBUG_DEC_AUX_MASK);
+
+       //      Write arc debug reg addr (0x5) into debug read addr reg
+       meiLongwordWrite(MEI_DEBUG_RAD, arc_debug_addr);
+       meiPollForDbgDone();
+
+       //      Read debug data reg and save content
+       meiLongwordRead(MEI_DEBUG_DATA, &arc_debug_data);
+
+       //      Write arc debug reg addr (0x5) into debug write addr reg
+       meiLongwordWrite(MEI_DEBUG_WAD, arc_debug_addr);
+
+       //      Write debug data reg with content ORd with 0x2 (halt bit set)
+       arc_debug_data |= (BIT1);
+       meiLongwordWrite(MEI_DEBUG_DATA, arc_debug_data);
+               meiPollForDbgDone();
+
+       //      Switch arc control from MEI mode to JTAG mode- write '0' to bit0
+       meiLongwordRead(MEI_CONTROL, &arc_control_mode);
+       arc_control_mode &= ~(HOST_MSTR);
+       meiLongwordWrite(MEI_CONTROL, arc_control_mode);
+
+       //      Return
+       return MEI_SUCCESS;
+
+} //   end of "meiHalt(..."
+
+MEI_ERROR meiDownloadBootCode(void)
+{
+       u32 arc_control_mode;
+       u32 boot_loop;
+       u32 page_size;
+       u32 dest_addr;
+
+       u32 arc_debug_addr = 0x31F00;
+       u32 arc_debug_data = 0x10;
+       u32 temp;
+//     int i;
+
+       //MEI_ERROR meiDMAError = MEI_SUCCESS;
+
+       //      Disable mask for arc codeswap interrupts
+       meiMailboxInterruptsDisable();
+
+       //      Switch arc control from JTAG mode to MEI mode- write '1' to bit0
+       meiLongwordRead(MEI_CONTROL, &arc_control_mode);
+       arc_control_mode |= (HOST_MSTR);
+       meiLongwordWrite(MEI_CONTROL, arc_control_mode);
+
+       //      Write (0x10) to CRI_CCR0(0x31F00) to enable ac_clk signal       
+       meiLongwordWrite(MEI_DEBUG_DEC, MEI_DEBUG_DEC_DMP1_MASK);
+       meiLongwordWrite(MEI_DEBUG_RAD, arc_debug_addr);
+       meiPollForDbgDone();
+       meiLongwordRead(MEI_DEBUG_DATA, &temp);
+       temp |=arc_debug_data;
+       
+       meiLongwordWrite(MEI_DEBUG_WAD, arc_debug_addr);
+       meiLongwordWrite(MEI_DEBUG_DATA, temp);
+        meiPollForDbgDone();
+            //meiLongwordWrite(MEI_DEBUG_DEC, MEI_DEBUG_DEC_AUX_MASK);
+
+       //      Switch arc control from MEI mode to JTAG mode- write '0' to bit0
+       meiLongwordRead(MEI_CONTROL, &arc_control_mode);
+       arc_control_mode &= ~(HOST_MSTR);
+       meiLongwordWrite(MEI_CONTROL, arc_control_mode);
+       
+#ifdef         AMAZON_MEI_DEBUG_ON   //to test ac_clk setting correctness
+       meiLongwordRead(MEI_CONTROL, &arc_control_mode);
+       arc_control_mode |= (HOST_MSTR);
+       meiLongwordWrite(MEI_CONTROL, arc_control_mode);
+       
+       meiLongwordWrite(MEI_DEBUG_DEC, MEI_DEBUG_DEC_DMP1_MASK);
+       meiLongwordWrite(MEI_DEBUG_RAD, arc_debug_addr);
+       meiPollForDbgDone();
+       meiLongwordRead(MEI_DEBUG_DATA, &arc_debug_data);
+
+       meiLongwordRead(MEI_CONTROL, &arc_control_mode);
+       arc_control_mode &= ~(HOST_MSTR);
+       meiLongwordWrite(MEI_CONTROL, arc_control_mode);
+       
+//     printk("\n\n ac_clk is %8x\n", arc_debug_data);
+#endif
+
+       /*
+       **      DMA the boot code page(s)
+       */
+#ifdef AMAZON_MEI_DEBUG_ON
+//     printk("\n\n start download pages");
+#endif
+       for( boot_loop = 0; boot_loop < img_hdr->count; boot_loop++)
+       {
+               if( img_hdr->page[boot_loop].p_size & BOOT_FLAG)
+               {
+                       page_size = meiGetPage( boot_loop, GET_PROG, MAXSWAPSIZE, mei_arc_swap_buff, &dest_addr);
+                       if( page_size > 0)
+                       {
+                               meiDMAWrite(dest_addr, mei_arc_swap_buff, page_size);
+                       }
+               }
+               if( img_hdr->page[boot_loop].d_size & BOOT_FLAG)
+               {
+                       page_size = meiGetPage( boot_loop, GET_DATA, MAXSWAPSIZE, mei_arc_swap_buff, &dest_addr);
+                       if( page_size > 0)
+                       {
+                               meiDMAWrite( dest_addr, mei_arc_swap_buff, page_size);
+                       }
+               }
+       }
+#ifdef AMAZON_MEI_DEBUG_ON
+//     printk("\n\n pages downloaded");
+#endif
+       return MEI_SUCCESS;
+
+} //   end of "meiDownloadBootCode(..."
+
+MEI_ERROR meiRunArc(void)
+{
+       u32 arc_control_mode = 0x0;
+       u32 arc_debug_addr = 0x0;
+       u32 arc_debug_data = 0x0;
+
+       //      Switch arc control from JTAG mode to MEI mode- write '1' to bit0
+       meiLongwordRead(MEI_CONTROL, &arc_control_mode);
+       arc_control_mode |= (HOST_MSTR);
+       meiLongwordWrite(MEI_CONTROL, arc_control_mode);
+
+       //      Write arc aux reg access mask (0x0) into debug addr decode reg
+       meiLongwordWrite(MEI_DEBUG_DEC, MEI_DEBUG_DEC_AUX_MASK);
+
+       //      Write arc status aux reg addr (0x0) into debug read addr reg
+       meiLongwordWrite(MEI_DEBUG_RAD, arc_debug_addr);
+       meiPollForDbgDone();
+
+       //      Read debug data reg and save content
+       meiLongwordRead(MEI_DEBUG_DATA, &arc_debug_data);
+
+       //      Write arc status aux reg addr (0x0) into debug write addr reg
+       meiLongwordWrite(MEI_DEBUG_WAD, arc_debug_addr);
+
+       //      Write debug data reg with content ANDd with 0xFDFFFFFF (halt bit cleared)
+       arc_debug_data &= ~(BIT25);
+       meiLongwordWrite(MEI_DEBUG_DATA, arc_debug_data);
+        meiPollForDbgDone();
+
+       //      Switch arc control from MEI mode to JTAG mode- write '0' to bit0
+       meiLongwordRead(MEI_CONTROL, &arc_control_mode);
+       arc_control_mode &= ~(HOST_MSTR);
+       meiLongwordWrite(MEI_CONTROL, arc_control_mode);
+
+       //      Enable mask for arc codeswap interrupts
+       meiMailboxInterruptsEnable();
+
+       //      Return
+       return MEI_SUCCESS;
+
+} //   end of "meiActivate(..."
+
+int meiGetPage( u32 Page, u32 data, u32 MaxSize, u32 *Buffer, u32 *Dest)
+{
+       u32     size;
+       u32     i;
+       u32     *p;
+
+       if( Page > img_hdr->count)
+               return -2;
+
+       /*
+       **      Get program or data size, depending on "data" flag
+       */
+       size = (data == GET_DATA) ? img_hdr->page[ Page].d_size : img_hdr->page[ Page].p_size;
+
+       size &= BOOT_FLAG_MASK;         //      Clear boot bit!
+       if( size > MaxSize)
+               return -1;
+
+       if( size == 0)
+               return 0;
+       /*
+       **      Get program or data offset, depending on "data" flag
+       */
+       i = data ? img_hdr->page[ Page].d_offset : img_hdr->page[ Page].p_offset;
+
+       /*
+       **      Copy data/program to buffer
+       */
+
+       i /= 4; //      Adjust offset for byte-to-UINT for array operation
+
+       p = (u32 *)img_hdr + i;
+       for(i = 0; i < size; i++)
+               Buffer[i] = *p++;
+       /*
+       **      Pass back data/program destination address
+       */
+       *Dest = data ? img_hdr->page[Page].d_dest : img_hdr->page[Page].p_dest;
+
+       return size;
+}
+
+MEI_ERROR meiCMV(u16 * request, int reply)            // write cmv to arc, if reply needed, wait for reply
+{
+        MEI_ERROR meierror;
+        wait_queue_t wait;
+        
+        cmv_reply=reply;
+        
+        meierror = meiMailboxWrite(request, MSG_LENGTH);
+       
+        if(meierror != MEI_SUCCESS){
+#ifdef AMAZON_MEI_DEBUG_ON
+                printk("\n\n MailboxWrite Fail.");
+#endif
+                return meierror;
+        }
+        else{
+                cmv_count++;
+       }
+
+        if(cmv_reply == NO_REPLY)
+                return MEI_SUCCESS;
+
+        init_waitqueue_entry(&wait, current);
+        add_wait_queue(&wait_queue_arcmsgav, &wait);
+        set_current_state(TASK_INTERRUPTIBLE);
+//     cmv_waiting=1;
+       
+        if(arcmsgav==1){
+                set_current_state(TASK_RUNNING);
+                remove_wait_queue(&wait_queue_arcmsgav, &wait);
+        }
+        else{
+                schedule_timeout(CMV_TIMEOUT);
+                remove_wait_queue(&wait_queue_arcmsgav, &wait);
+        }
+       if(arcmsgav==0){//CMV_timeout
+               cmv_waiting=0;
+               arcmsgav=0;
+#ifdef AMAZON_MEI_DEBUG_ON
+               printk("\nmeiCMV: MEI_MAILBOX_TIMEOUT\n");
+#endif
+               return MEI_MAILBOX_TIMEOUT;     
+       }
+       else{
+               arcmsgav=0;
+                       reply_count++;
+               return MEI_SUCCESS;
+       }
+}
+
+//TODO, for loopback test
+#ifdef DFE_LOOPBACK
+#define mte_reg_base                    (0x4800*4+0x20000)
+/* Iridia Registers Address Constants */
+#define MTE_Reg(r)                              (int)(mte_reg_base + (r*4))
+#define IT_AMODE                                MTE_Reg(0x0004)
+
+
+#define OMBOX_BASE 0x15F80
+#define IMBOX_BASE 0x15FC0
+
+#define TIMER_DELAY   (1024)
+#define BC0_BYTES     (32)
+#define BC1_BYTES     (30)
+#define NUM_MB        (12)
+#define TIMEOUT_VALUE 2000
+
+void BFMWait (u32 cycle) {
+  u32 i;
+  for (i = 0 ; i< cycle ; i++); 
+}
+
+void WriteRegLong(u32 addr, u32 data){
+  //printk("[%8x] <= %8x \n\n", addr, data);
+  *((volatile u32 *)(addr)) =  data; 
+}
+
+u32 ReadRegLong (u32 addr) {
+  u32  rd_val;
+  
+  rd_val = *((volatile u32 *)(addr));
+  //printk("[%8x] => %8x \n\n", addr, rd_val);
+  return rd_val;
+
+}
+
+/* This routine writes the mailbox with the data in an input array */
+void WriteMbox(u32 *mboxarray,u32 size) {
+  u32 i;
+  
+  WriteRegLong(MEI_XFR_ADDR,IMBOX_BASE);
+  for (i=0;i<size;i++) {
+    WriteRegLong(MEI_DATA_XFR,*(mboxarray+i));
+  }
+}
+
+/* This routine reads the output mailbox and places the results into an array */
+void ReadMbox(u32 *mboxarray,u32 size) {
+  u32 i;
+  
+  WriteRegLong(MEI_XFR_ADDR,OMBOX_BASE);
+  for (i=0;i<size;i++) {
+    mboxarray[i] = ReadRegLong(MEI_DATA_XFR);
+  }
+}
+
+void MEIWriteARCValue(u32 address, u32 value)
+{
+  u32 i,check = 0;
+  /* Write address register */
+  *((volatile u32 *)MEI_DEBUG_WAD) =  address;
+
+  /* Write data register */
+  *((volatile u32 *)MEI_DEBUG_DATA) =  value;
+
+  /* wait until complete - timeout at 40*/
+  for (i=0;i<40;i++) {
+    check = *((volatile u32 *)ARC_TO_MEI_INT);
+    if ((check & 0x20)) break;
+    //printk("MEIWriteARCValue: check:%8x\n\n", check);
+    }
+
+  /* clear the flag */
+  *((volatile u32 *)ARC_TO_MEI_INT)  = 0x20;
+
+}
+
+
+void post_mei_init(void)
+{
+u32 mailbox[NUM_MB];
+
+  mailbox[0] = TIMER_DELAY;
+  /* set bytes per bearer channel */
+  mailbox[1] = BC0_BYTES;
+  mailbox[2] = BC1_BYTES;
+  WriteMbox(mailbox, 3);
+
+  WriteRegLong(AAI_ACCESS, 0x00000001);
+
+  /* enable ADSL block clock, ac_clk */
+  WriteRegLong(MEI_CONTROL, 0x01);
+  WriteRegLong(MEI_DEBUG_DEC, 0x00000001); // select ld/st space
+  MEIWriteARCValue(0x31F00,   0x00000010); // write CRI_CCR0 to enable ac_clk
+
+  /* set the MTE to register start */
+  MEIWriteARCValue(IT_AMODE, 0xF);
+  BFMWait(10); 
+}
+
+
+int wait_sync(void)
+{
+u32 mailbox[NUM_MB];
+  /* wait for ATM sync to be achieved on both BC0 and BC1 */
+  u32 timeout=0;
+  ReadMbox(mailbox, 1);
+  u32 readval = mailbox[0];
+  while( ((readval & 0xFFFFFFFF) == 0) && (timeout < TIMEOUT_VALUE) ) {
+    BFMWait(1);
+    //printk("wait_sync\n\n");
+    ReadMbox(mailbox, 1);
+    readval = mailbox[0];
+    timeout++;
+  }
+  if(timeout == TIMEOUT_VALUE)return 0;
+  else return 1;
+}
+#endif //DFE_LOOPBACK
+//end of TODO, for loopback test
+
+MEI_ERROR meiForceRebootAdslModem(void)
+{
+#if 0
+//#ifdef       ARC_READY_ACK
+               if(down_interruptible(&mei_sema))       //disable CMV access until ARC ready
+               {
+                       return -ERESTARTSYS;
+               }
+#endif
+       if(reboot_firsttime==1){//000002:fchang Start
+               // reset ARC
+               *((volatile u32 *)0xB0100910) = 0x80;   //reset DFE
+               asm("SYNC");
+               *((volatile u32 *)0xB0100910) = 0x0;
+               asm("SYNC");
+               if((*((volatile u32 *)0xB0100910))!=0x0)
+#ifdef AMAZON_MEI_DEBUG_ON
+                       printk("\n reset DFE fail");
+#endif
+               
+               // reset ARC
+               meiLongwordWrite(MEI_CONTROL, SOFT_RESET);
+               asm("SYNC");
+               meiLongwordWrite(MEI_CONTROL, 0);
+               asm("SYNC");    
+
+       }       //000002:fchang End             
+#ifdef DFE_LOOPBACK
+                img_hdr=(ARC_IMG_HDR *)lp_image;
+#else
+               img_hdr=(ARC_IMG_HDR *)image_buffer;
+#endif         
+//             printk("\n\n enter haltarc");
+                meiHaltArc();
+//             printk("\n\n haltarc done");
+//000002:fchang Start
+       if(reboot_firsttime==0){
+               printk("\n\n new reboot");
+               meiResetArc();
+               meiResetCore();
+       }
+       if(reboot_firsttime==1)
+                meiDownloadBootCode();
+       else
+               mei_ioctl((struct inode *)NULL, (struct file *)NULL, AMAZON_MEI_DOWNLOAD, (unsigned long)NULL);
+
+//000002:fchang End
+#ifdef AMAZON_MEI_DEBUG_ON
+//             printk("\n\n Download Done");
+#endif
+
+#ifdef DFE_LOOPBACK
+               post_mei_init();
+#endif         
+
+//             sema_init(&mei_sema, 1);
+               //up(&mei_sema);
+
+//             enable_irq(AMAZON_MEI_INT);
+                                       
+               meiRunArc();
+//000002:fchang Start          
+       if(reboot_firsttime==0){
+               meiEnalbeMailboxInt();
+       }               
+//000002:fchang End
+               
+#ifdef AMAZON_MEI_DEBUG_ON
+//             printk("\n\n ARC Running");
+#endif
+               
+#ifdef         AMAZON_MEI_DEBUG_ON   //to test ac_clk setting correctness
+       {
+       u32 arc_control_mode;
+       u32 arc_debug_addr = 0x31F00;
+       u32 arc_debug_data = 0x10;
+       meiLongwordRead(MEI_CONTROL, &arc_control_mode);
+       arc_control_mode |= (HOST_MSTR);
+       meiLongwordWrite(MEI_CONTROL, arc_control_mode);
+       
+       meiLongwordWrite(MEI_DEBUG_DEC, MEI_DEBUG_DEC_DMP1_MASK);
+       meiLongwordWrite(MEI_DEBUG_RAD, arc_debug_addr);
+       meiPollForDbgDone();
+       meiLongwordRead(MEI_DEBUG_DATA, &arc_debug_data);
+
+       meiLongwordRead(MEI_CONTROL, &arc_control_mode);
+       arc_control_mode &= ~(HOST_MSTR);
+       meiLongwordWrite(MEI_CONTROL, arc_control_mode);
+       
+//     printk("\n\n ac_clk is %8x\n", arc_debug_data);
+       }
+#endif         
+                       
+               
+#ifdef DFE_LOOPBACK
+               if (wait_sync() == 0){
+                       printk("ARC fails to run: time out\n\n");
+               }else{
+//                     printk("ARC is ready\n\n");
+               }
+#endif         
+               if(reboot_firsttime==1) //000002:fchang
+                       reboot_firsttime=0;     //000002:fchang
+               
+                return MEI_SUCCESS;
+}
+
+////////////////////            procfs debug            ////////////////////////////////////////////////////////
+#define MEI_DIRNAME     "mei"
+static struct proc_dir_entry *meidir;
+
+static ssize_t proc_write(struct file *, const char *, size_t, loff_t *);
+static ssize_t proc_read(struct file *, char *, size_t, loff_t *);
+
+static struct file_operations proc_operations = {
+       read:   proc_read,
+       write:  proc_write,
+};
+
+typedef struct reg_entry {
+       int * flag;
+       char name[30];          // big enough to hold names
+       char description[100];      // big enough to hold description
+       unsigned short low_ino;
+} reg_entry_t;
+
+static reg_entry_t regs[PROC_ITEMS];       // total items to be monitored by /proc/mei
+
+#define NUM_OF_REG_ENTRY       (sizeof(regs)/sizeof(reg_entry_t))
+
+static int proc_read(struct file * file, char * buf, size_t nbytes, loff_t *ppos)
+{
+        int i_ino = (file->f_dentry->d_inode)->i_ino;
+       char outputbuf[64];
+       int count=0;
+       int i;
+       u32 version=0;
+       reg_entry_t* current_reg=NULL;
+       
+       for (i=0;i<NUM_OF_REG_ENTRY;i++) {
+               if (regs[i].low_ino==i_ino) {
+                       current_reg = &regs[i];
+                       break;
+               }
+       }
+       if (current_reg==NULL)
+               return -EINVAL;
+       
+       if (current_reg->flag == (int *) 8){
+       ///proc/mei/version
+       //format:
+       //Firmware version: major.minor.sub_version.int_version.rel_state.spl_appl
+       //Firmware Date Time Code: date/month min:hour
+               if (*ppos>0) /* Assume reading completed in previous read*/
+                       return 0;               // indicates end of file
+               if(down_interruptible(&mei_sema))
+                       return -ERESTARTSYS;
+               
+               //if (indicator_count != 1){
+               if (indicator_count < 1){
+                       up(&mei_sema);
+                       return -EAGAIN;
+               }
+               //major:bits 0-7 
+               //minor:bits 8-15
+               makeCMV(H2D_CMV_READ, INFO, 54, 0, 1, NULL);
+               if(meiCMV(TxMessage, YES_REPLY)!=MEI_SUCCESS){
+#if 0
+#ifdef AMAZON_MEI_DEBUG_ON
+                       printk("\n\n WINHOST CMV fail");
+#endif 
+#endif
+                       up(&mei_sema);
+                       return -EIO;
+               }
+               version = RxMessage[4];
+               count = sprintf(outputbuf, "%d.%d.",(version)&0xff,(version>>8)&0xff);
+               
+               //sub_version:bits 4-7
+               //int_version:bits 0-3
+               //spl_appl:bits 8-13
+               //rel_state:bits 14-15
+               makeCMV(H2D_CMV_READ, INFO, 54, 1, 1, NULL);
+               if(meiCMV(TxMessage, YES_REPLY)!=MEI_SUCCESS){
+#if 0
+#ifdef AMAZON_MEI_DEBUG_ON
+                       printk("\n\n WINHOST CMV fail");        
+#endif
+#endif
+                       up(&mei_sema);
+                       return -EFAULT;
+               }
+               version =RxMessage[4];
+               count += sprintf(outputbuf+count, "%d.%d.%d.%d",
+                               (version>>4)&0xf, 
+                               version&0xf,
+                               (version>>14)&0x3, 
+                               (version>>8)&0x3f);     
+#ifdef ADSL_LED_SUPPORT                                
+// version check -start        for adsl led                    
+               if ((((version>>4)&0xf)==2)&&((version&0xf)>=3)&&((version&0xf)<7)) firmware_support_led=1;
+               else if ((((version>>4)&0xf)==2)&&((version&0xf)>=7)) firmware_support_led=2;
+               else if (((version>>4)&0xf)>2) firmware_support_led=2;
+
+//165001:henryhsu:20050906:Modify for adsl firmware version 1.2.1.2.0.1 DATA_LED can't flash.
+       //else firmware_support_led=0;
+       else firmware_support_led=2;
+//165001               
+
+
+// version check -end  
+#endif 
+               //Date:bits 0-7
+               //Month:bits 8-15
+               makeCMV(H2D_CMV_READ, INFO, 55, 0, 1, NULL);
+               if(meiCMV(TxMessage, YES_REPLY)!=MEI_SUCCESS){
+#if 0
+#ifdef AMAZON_MEI_DEBUG_ON
+                       printk("\n\n WINHOST CMV fail");
+#endif 
+#endif
+                       up(&mei_sema);
+                       return -EIO;
+               }
+               version = RxMessage[4];
+               
+               //Hour:bits 0-7
+               //Minute:bits 8-15
+               makeCMV(H2D_CMV_READ, INFO, 55, 1, 1, NULL);
+               if(meiCMV(TxMessage, YES_REPLY)!=MEI_SUCCESS){
+#if 0
+#ifdef AMAZON_MEI_DEBUG_ON
+                       printk("\n\n WINHOST CMV fail");
+#endif 
+#endif
+                       up(&mei_sema);
+                       return -EFAULT;
+               }
+               version += (RxMessage[4]<<16);
+               count += sprintf(outputbuf+count, " %d/%d %d:%d\n"
+                               ,version&0xff
+                               ,(version>>8)&0xff
+                               ,(version>>25)&0xff
+                               ,(version>>16)&0xff);
+                               
+               up(&mei_sema);  
+               
+               *ppos+=count;
+       }else if(current_reg->flag != (int *)Recent_indicator){
+               if (*ppos>0) /* Assume reading completed in previous read*/
+                       return 0;               // indicates end of file
+               count = sprintf(outputbuf, "0x%08X\n\n", *(current_reg->flag));
+               *ppos+=count;
+               if (count>nbytes)  /* Assume output can be read at one time */
+                       return -EINVAL;
+        }else{
+               if((int)(*ppos)/((int)7)==16)
+                       return 0;  // indicate end of the message
+               count = sprintf(outputbuf, "0x%04X\n\n", *(((u16 *)(current_reg->flag))+ (int)(*ppos)/((int)7)));
+                *ppos+=count;
+       }
+       if (copy_to_user(buf, outputbuf, count))
+               return -EFAULT;
+       return count;
+}
+
+static ssize_t proc_write(struct file * file, const char * buffer, size_t count, loff_t *ppos)
+{
+       int i_ino = (file->f_dentry->d_inode)->i_ino;
+       reg_entry_t* current_reg=NULL;
+       int i;
+       unsigned long newRegValue;
+       char *endp;
+
+       for (i=0;i<NUM_OF_REG_ENTRY;i++) {
+               if (regs[i].low_ino==i_ino) {
+                       current_reg = &regs[i];
+                       break;
+               }
+       }
+       if ((current_reg==NULL) || (current_reg->flag == (int *)Recent_indicator))
+               return -EINVAL;
+
+       newRegValue = simple_strtoul(buffer,&endp,0);
+       *(current_reg->flag)=(int)newRegValue;
+       return (count+endp-buffer);
+}
+////////////////makeCMV(Opcode, Group, Address, Index, Size, Data), CMV in u16 TxMessage[MSG_LENGTH]///////////////////////////
+void makeCMV(u8 opcode, u8 group, u16 address, u16 index, int size, u16 * data)
+{
+       memset(TxMessage, 0, MSG_LENGTH*2);
+       TxMessage[0]= (opcode<<4) + (size&0xf);
+       TxMessage[1]= (((index==0)?0:1)<<7) + (group&0x7f);
+       TxMessage[2]= address;
+       TxMessage[3]= index;
+       if(opcode == H2D_CMV_WRITE)
+               memcpy(TxMessage+4, data, size*2);
+       return;
+}
+
+////////////////makeCMV(Opcode, Group, Address, Index, Size, Data), CMV in u16 TxMessage[MSG_LENGTH]///////////////////////////
+void makeCMV_local(u8 opcode, u8 group, u16 address, u16 index, int size, u16 * data,u16 *CMVMSG)
+{
+       memset(CMVMSG, 0, MSG_LENGTH*2);
+       CMVMSG[0]= (opcode<<4) + (size&0xf);
+       CMVMSG[1]= (((index==0)?0:1)<<7) + (group&0x7f);
+       CMVMSG[2]= address;
+       CMVMSG[3]= index;
+       if(opcode == H2D_CMV_WRITE)
+               memcpy(CMVMSG+4, data, size*2);
+       return;
+}
+
+////////////////                Driver Structure                /////////////////////////////////////////////////////////////////////////////
+static ssize_t mei_write(struct file *, const char *, size_t, loff_t *);
+static int mei_ioctl(struct inode *, struct file *, unsigned int, unsigned long);
+
+static struct file_operations mei_operations = {
+        write:                 mei_write,
+        ioctl:                 mei_ioctl,
+};
+
+
+static ssize_t mei_write(struct file * filp, const char * buf, size_t size, loff_t * loff)
+{
+//     printk("\n\n mei_write entered");
+//      image_buffer = (u32 *)kmalloc(size, GFP_KERNEL);
+       image_buffer = (u32 *)vmalloc(size);
+//     printk("\n\n image_buffer kmalloc done");
+       if(image_buffer == NULL){
+#ifdef AMAZON_MEI_DEBUG_ON
+//             printk("\n\n kmalloc for firmware image fail");
+               printk("\n\n vmalloc for firmware image fail");
+#endif
+               return -1;
+       }
+       copy_from_user((char *)image_buffer, buf, size);
+//     printk("\n\n copy_from_user done");
+        return size;
+}
+
+       ////////// ISR GPTU Timer 6 for high resolution timer /////////////
+void amazon_timer6_interrupt_MEI(int irq, void *dev_id, struct pt_regs *regs)
+{
+       int i,j;
+       u32 temp;
+       u16 temp16;
+       u16 rdindex, wrindex;
+       u16 num_rd=0;   //num of byte can be read
+       u16 bytes_to_wr=0;
+       
+//     printk("\n\nenter timer\n\n");
+       irqtimes++;
+//     printk("\n%d\n",irqtimes);
+
+
+/*
+#ifdef PCM_ACCESS_DEBUG
+               meiDebugRead_8(0x30f20, &temp, 1);
+#else
+               meiDMARead_8(0x30f20, &temp, 1);
+#endif         
+       if((temp&0x4000)!=0){
+               printk("\nER_ERR");
+#ifdef PCM_ACCESS_DEBUG
+               meiDebugWrite_8(0x30f20, &temp, 1);
+#else
+               meiDMAWrite_8(0x30f20, &temp, 1);
+#endif
+#ifdef PCM_ACCESS_DEBUG
+               meiDebugRead_8(0x30f20, &temp, 1);
+#else
+               meiDMARead_8(0x30f20, &temp, 1);
+#endif
+               if((temp&0x4000)!=0)
+                       printk("\nER_ERR not cleared");
+       }
+*/     
+       
+       for(i=PCM_CHANNEL_NUM-1;i>=0;i--){// start from last channel, which is rx  
+#ifdef PCM_ACCESS_DEBUG
+               meiDebugRead_16(pcm_start_addr+i*16+12, &temp, 1);
+#else
+               meiDMARead_16(pcm_start_addr+i*16+12, &temp, 1);
+#endif
+               wrindex = (u16)((temp & 0xffff0000)>>16);
+//             printk(" %d",wrindex);
+#ifdef PCM_ACCESS_DEBUG
+               meiDebugRead_16(pcm_start_addr+i*16+8, &temp, 1);
+#else
+               meiDMARead_16(pcm_start_addr+i*16+8, &temp, 1);
+#endif
+               rdindex = (u16)(temp & 0xffff);
+//             printk(" %d",rdindex);
+               if(rdindex<=wrindex)
+                       num_rd=((wrindex-rdindex)/4)*4; //read multiply of 4 bytes
+               else
+                       num_rd=((pcm_data[i].len-(rdindex-wrindex))/4)*4;       //read multiply of 4 bytes
+               
+               if(i%2!=0){//rx channel
+                       pcm_data[i].point=0;
+                       for(j=0;j<num_rd/4;j++){
+                               if(pcm_data[i].finish!=1){
+                                       if((rdindex+j*4)>=pcm_data[i].len)
+                                               temp16=(rdindex+j*4) - pcm_data[i].len;
+                                       else
+                                               temp16=rdindex+j*4;
+#ifdef PCM_ACCESS_DEBUG
+                                       meiDebugRead_8((((u32)(pcm_data[i].LSW))+(((u32)(pcm_data[i].MSW))<<16))+temp16, (u32*)(pcm_data[i].buff+pcm_data[i].point), 1);
+#else
+                                       meiDMARead_8((((u32)(pcm_data[i].LSW))+(((u32)(pcm_data[i].MSW))<<16))+temp16, (u32*)(pcm_data[i].buff+pcm_data[i].point), 1);
+#endif
+                               //      printk(" %8x", *((u32*)(pcm_data[i].buff+pcm_data[i].point)));  
+                               /*      if(pcm_data[i].point==0){
+                                               if(pcm_data[i].buff[0]==0xA5){// start of loopback data
+                                                       pcm_data[i].point+=4;   
+                                                       printk("\nstart receive data");
+                                               }       
+                                       } 
+                                       else*/
+                                               pcm_data[i].point+=4;
+                               /*      if(pcm_data[i].point==PCM_BUFF_SIZE){   //finish rx
+                                               pcm_data[i].finish=1;
+                                               printk("\nchannel[%d] finished", i);
+                                       }       */
+                               }
+                       }
+                       if(firsttime[i]==1){
+                               for(j=0;j<num_rd;j++){
+                                       if(pcm_data[i].buff[j]==0x1){
+                                               num_cmp[i]=num_rd-j;
+                                               firsttime[i]=0;
+                                               break;
+                                       }
+                               }
+                               if(memcmp(sampledata+1, pcm_data[i].buff+j, num_cmp[i])!=0)
+                                       printk("\n\ndata wrong,1st\n\n");
+                               else
+                                       pcm_start_loc[i] = num_cmp[i]+1;
+                       }
+                       else{
+                               if(memcmp(sampledata+pcm_start_loc[i], pcm_data[i].buff, num_rd)!=0)
+                                       printk("\n\ndata wrong\n\n");
+                               else{
+                                       pcm_start_loc[i]+=num_rd;
+                                       if(pcm_start_loc[i]>=256)
+                                               pcm_start_loc[i]=pcm_start_loc[i]-256;
+                               }
+                       }
+                       
+                       rdindex +=num_rd;
+                       if(rdindex>=pcm_data[i].len)
+                               rdindex=rdindex-pcm_data[i].len;
+#ifdef PCM_ACCESS_DEBUG
+                       meiDebugRead_16(pcm_start_addr+i*16+8, &temp, 1);
+#else
+                       meiDMARead_16(pcm_start_addr+i*16+8, &temp, 1);
+#endif
+                       temp= (temp & 0xffff0000) + rdindex;
+#ifdef PCM_ACCESS_DEBUG
+                       meiDebugWrite_16(pcm_start_addr+i*16+8, &temp, 1); // update rdindex 
+#else
+                       meiDMAWrite_16(pcm_start_addr+i*16+8, &temp, 1); // update rdindex
+#endif
+                       
+                       bytes_to_wr = num_rd;
+                       
+       //              if(bytes_to_wr>0){
+               //              printk(" %d", num_rd);
+               //              printk(" %d", rdindex);
+//                             printk("\n\nrdindex = %d", rdindex);    
+                       //}
+               }
+               else{   //tx channel
+       //              if((bytes_to_wr + num_rd) < pcm_data[i].len){
+                               for(j=0;j<bytes_to_wr/4;j++){
+                                       if(pcm_data[i].finish!=1){
+                                               if((wrindex+j*4)>=pcm_data[i].len)
+                                                       temp16=(wrindex+j*4) - pcm_data[i].len;
+                                               else
+                                                       temp16=wrindex + j*4;
+/*                                                     
+#ifdef PCM_ACCESS_DEBUG
+                                               meiDebugWrite_8((((u32)(pcm_data[i].LSW))+(((u32)(pcm_data[i].MSW))<<16))+temp16,(u32*)(pcm_data[i+1].buff+j*4), 1);
+#else
+                                               meiDMAWrite_8((((u32)(pcm_data[i].LSW))+(((u32)(pcm_data[i].MSW))<<16))+temp16,(u32*)(pcm_data[i+1].buff+j*4), 1);
+#endif*/
+                                                       
+#ifdef PCM_ACCESS_DEBUG
+                                               meiDebugWrite_8((((u32)(pcm_data[i].LSW))+(((u32)(pcm_data[i].MSW))<<16))+temp16,(u32*)(pcm_data[i].buff+pcm_data[i].point), 1);
+                               //              meiDebugWrite_8((((u32)(pcm_data[i].LSW))+(((u32)(pcm_data[i].MSW))<<16))+temp16,(u32*)(pcm_data[i].buff), 1);
+#else
+                                               meiDMAWrite_8((((u32)(pcm_data[i].LSW))+(((u32)(pcm_data[i].MSW))<<16))+temp16,(u32*)(pcm_data[i].buff+pcm_data[i].point), 1);
+#endif         
+                                               pcm_data[i].point+=4;
+                                               if(pcm_data[i].point==PCM_BUFF_SIZE){
+                                       //              pcm_data[i].finish=1; 
+                                       //              printk("\nchannel[%d] finished", i);
+                                                       pcm_data[i].point=0;
+                                               }       
+                                       }
+                               }
+                               wrindex+=bytes_to_wr;
+                               if(wrindex>=pcm_data[i].len)
+                                       wrindex=wrindex-pcm_data[i].len;
+#ifdef PCM_ACCESS_DEBUG
+                               meiDebugRead_16(pcm_start_addr+i*16+12, &temp, 1);
+#else
+                               meiDMARead_16(pcm_start_addr+i*16+12, &temp, 1);
+#endif
+                               temp=(temp&0xffff) + (wrindex<<16);
+#ifdef PCM_ACCESS_DEBUG
+                               meiDebugWrite_16(pcm_start_addr+i*16+12, &temp, 1); // update wrindex
+#else
+                               meiDMAWrite_16(pcm_start_addr+i*16+12, &temp, 1); // update wrindex
+#endif
+                       
+                               //if(bytes_to_wr>0){
+                       //              printk(" %d", bytes_to_wr);
+                       //              printk(" %d", wrindex);
+//                                     printk("\n\nwrindex = %d", wrindex);    
+                               //}
+               //      }
+               }
+       }
+       return;
+}
+//000002:fchang Start
+static int meiResetArc(void)
+{
+       u32 auxreg0;
+       u32 auxreg5;
+       int flshcnt=0;
+       int flshcnt1=0;
+       int flshcnt2=0;
+       
+       meiLongwordWrite(MEI_CONTROL, 1);
+       meiLongwordWrite(MEI_DEBUG_DEC, 3);     
+       meiLongwordWrite(MEI_DEBUG_WAD, 0x3c);
+       meiLongwordWrite(MEI_DEBUG_DATA, 0x10);
+       meiPollForDbgDone();
+       meiLongwordWrite(MEI_DEBUG_DEC, 0x0);
+       meiLongwordWrite(MEI_DEBUG_WAD, 0x2);
+       meiLongwordWrite(MEI_DEBUG_DATA, 0x0);
+       meiPollForDbgDone();
+       meiLongwordWrite(MEI_DEBUG_WAD, 0x3);
+       meiLongwordWrite(MEI_DEBUG_DATA, 0x0);
+       meiPollForDbgDone();
+       meiLongwordWrite(MEI_DEBUG_DEC, 0x0);
+       meiLongwordWrite(MEI_DEBUG_RAD, 0x0);
+       meiPollForDbgDone();
+       meiLongwordRead(MEI_DEBUG_DATA, &auxreg0);
+       auxreg0 = auxreg0 & 0x03ffffff;
+       meiLongwordWrite(MEI_DEBUG_WAD, 0x0);
+       meiLongwordWrite(MEI_DEBUG_DATA, auxreg0);
+       meiPollForDbgDone();
+       meiLongwordWrite(MEI_DEBUG_WAD, 0x10a);
+       meiLongwordWrite(MEI_DEBUG_DATA, 0x0);
+       meiPollForDbgDone();
+       meiLongwordWrite(MEI_DEBUG_DEC, 0x2);
+       meiLongwordWrite(MEI_DEBUG_WAD, 0xfffc);
+       meiLongwordWrite(MEI_DEBUG_DATA, 0x1fffffff);
+       meiPollForDbgDone();
+       while(flshcnt<3){
+               meiLongwordWrite(MEI_DEBUG_DEC, 0x0);
+               meiLongwordWrite(MEI_DEBUG_RAD, 0x0);
+               meiPollForDbgDone();
+               meiLongwordRead(MEI_DEBUG_DATA, &auxreg0);
+               auxreg0 = auxreg0 & 0xff000000;
+               auxreg0 = auxreg0 | 0x3fff;
+               meiLongwordWrite(MEI_DEBUG_WAD, 0x0);
+               meiLongwordWrite(MEI_DEBUG_DATA, auxreg0);
+               meiPollForDbgDone();
+               
+               meiLongwordWrite(MEI_DEBUG_DEC, 0x0);
+               meiLongwordWrite(MEI_DEBUG_RAD, 0x5);
+               meiPollForDbgDone();
+               meiLongwordRead(MEI_DEBUG_DATA, &auxreg5);
+               auxreg5 = auxreg5 | 0x801;
+               meiLongwordWrite(MEI_DEBUG_WAD, 0x5);
+               meiLongwordWrite(MEI_DEBUG_DATA, auxreg5);
+               meiPollForDbgDone();
+               meiLongwordWrite(MEI_DEBUG_RAD, 0x0);
+               meiPollForDbgDone();
+               meiLongwordRead(MEI_DEBUG_DATA, &auxreg0);
+               auxreg0 = auxreg0 & 0x00ffffff;
+               if(auxreg0 == 0x4000)
+                       flshcnt = flshcnt+1;
+               else{
+                       if(flshcnt == 0)
+                               flshcnt1 = flshcnt1 +1;
+                       else
+                               flshcnt2 = flshcnt2 +1;
+               }       
+       }
+       
+       return 1;
+}
+
+static int meiResetCore(void)
+{
+       meiLongwordWrite(MEI_CONTROL, 0x1);
+       meiLongwordWrite(MEI_DEBUG_DEC, 0x2);
+       meiLongwordWrite(MEI_DEBUG_WAD, 0x31f10);
+       meiLongwordWrite(MEI_DEBUG_DATA, 0xf);
+       meiPollForDbgDone();
+       meiLongwordWrite(MEI_DEBUG_WAD, 0x31f10);
+       meiLongwordWrite(MEI_DEBUG_DATA, 0x0);
+       meiPollForDbgDone();
+       meiLongwordWrite(MEI_DEBUG_WAD, 0x31f00);
+       meiLongwordWrite(MEI_DEBUG_DATA, 0x55);
+       meiPollForDbgDone();
+       return 1;
+}
+
+static int meiEnalbeMailboxInt(void)
+{
+       u32 arc2meiintmsk;
+       meiLongwordRead(ARC_TO_MEI_INT_MASK, &arc2meiintmsk);
+       arc2meiintmsk = arc2meiintmsk | 0x1;
+       meiLongwordWrite(ARC_TO_MEI_INT_MASK, arc2meiintmsk);
+       meiLongwordWrite(MEI_CONTROL, 0x0);
+       return 1;
+}
+
+
+
+//000002:fchang End
+
+static int mei_ioctl(struct inode * ino, struct file * fil, unsigned int command, unsigned long lon)
+{
+        int i,k;
+       u32 boot_loop;
+       u32 page_size;
+       u32 dest_addr;
+       u32 j;
+       u32 temp;
+       u32 temp2;
+       u16 trapsflag=0;
+       amazon_clreoc_pkt * current_clreoc;
+       struct timeval time_now;
+       struct timeval time_fini;
+       struct list_head * ptr;
+       amazon_mei_mib * mib_ptr;
+//     u16 buff[MSG_LENGTH]__attribute__ ((aligned(4)));
+       structpts pts;
+        int meierr=MEI_SUCCESS;
+       u16 data[12];  //used in makeCMV, to pass in payload when CMV set, ignored when CMV read.
+       meireg regrdwr;
+       meidebug debugrdwr;
+       amazon_mei_mib * temp_intvl;
+       struct sk_buff * eoc_skb;
+// 603221:tc.chen start
+       u16 hdlc_cmd[2];
+       u16 hdlc_rx_buffer[32];
+       int hdlc_rx_len=0;
+// 603221:tc.chen end
+       
+       int from_kernel = 0;//joelin
+       if (ino == (struct inode *)0) from_kernel = 1;//joelin
+       
+//     printk("\n switch.command = %i\n", command);
+        switch(command){
+               case GET_ADSL_LINE_CODE:
+                       pts.adslLineTableEntry_pt = (adslLineTableEntry *)kmalloc(sizeof(adslLineTableEntry), GFP_KERNEL);
+                       copy_from_user((char *)pts.adslLineTableEntry_pt, (char *)lon, sizeof(adslLineTableEntry));
+                       if(IS_FLAG_SET((&(pts.adslLineTableEntry_pt->flags)), LINE_CODE_FLAG)){
+                               pts.adslLineTableEntry_pt->adslLineCode = 2;
+                       }
+                       copy_to_user((char *)lon, (char *)pts.adslLineTableEntry_pt, sizeof(adslLineTableEntry));
+                       kfree(pts.adslLineTableEntry_pt);
+                       break;
+#ifdef AMAZON_MEI_MIB_RFC3440
+               case GET_ADSL_ATUC_LINE_EXT:
+                       if(down_interruptible(&mei_sema))
+                               return -ERESTARTSYS;
+                       pts.adslLineExtTableEntry_pt = (adslLineExtTableEntry *)kmalloc(sizeof(adslLineExtTableEntry), GFP_KERNEL);
+                       copy_from_user((char *)pts.adslLineExtTableEntry_pt, (char *)lon, sizeof(adslLineExtTableEntry));
+                       if(IS_FLAG_SET((&(pts.adslLineExtTableEntry_pt->flags)), ATUC_LINE_TRANS_CAP_FLAG)){
+                               ATUC_LINE_TRANS_CAP_FLAG_MAKECMV;
+                               if(meiCMV(TxMessage, YES_REPLY)!=MEI_SUCCESS){
+#ifdef AMAZON_MEI_DEBUG_ON
+                                       printk("\n\nCMV fail, Group 3 Address 67 Index 0");
+#endif
+                                       CLR_FLAG((&(pts.adslLineExtTableEntry_pt->flags)), ATUC_LINE_TRANS_CAP_FLAG);   
+                               }       
+                               else{
+                                       memcpy((&(pts.adslLineExtTableEntry_pt->adslLineTransAtucCap)), RxMessage+4, ((RxMessage[0]&0xf)*2));
+                               }
+                       }
+                       if(IS_FLAG_SET((&(pts.adslLineExtTableEntry_pt->flags)), ATUC_LINE_TRANS_CONFIG_FLAG)){
+                               ATUC_LINE_TRANS_CONFIG_FLAG_MAKECMV;
+                               if(meiCMV(TxMessage, YES_REPLY)!=MEI_SUCCESS){
+#ifdef AMAZON_MEI_DEBUG_ON
+                                       printk("\n\nCMV fail, Group 3 Address 67 Index 0");
+#endif
+                                       CLR_FLAG((&(pts.adslLineExtTableEntry_pt->flags)), ATUC_LINE_TRANS_CONFIG_FLAG);        
+                               }       
+                               else{
+                                       memcpy((&(pts.adslLineExtTableEntry_pt->adslLineTransAtucConfig)), RxMessage+4, ((RxMessage[0]&0xf)*2));
+                               }
+                       }
+                       if(IS_FLAG_SET((&(pts.adslLineExtTableEntry_pt->flags)), ATUC_LINE_TRANS_ACTUAL_FLAG)){
+                               ATUC_LINE_TRANS_ACTUAL_FLAG_MAKECMV;
+                               if(meiCMV(TxMessage, YES_REPLY)!=MEI_SUCCESS){
+#ifdef AMAZON_MEI_DEBUG_ON
+                                       printk("\n\nCMV fail, Group 2 Address 1 Index 0");
+#endif
+                                       CLR_FLAG((&(pts.adslLineExtTableEntry_pt->flags)), ATUC_LINE_TRANS_ACTUAL_FLAG);        
+                               }       
+                               else{
+                                       memcpy((&(pts.adslLineExtTableEntry_pt->adslLineTransAtucActual)), RxMessage+4, ((RxMessage[0]&0xf)*2));
+                               }
+                       }
+                       if(IS_FLAG_SET((&(pts.adslLineExtTableEntry_pt->flags)), LINE_GLITE_POWER_STATE_FLAG)){    // not supported currently
+/*
+                               LINE_GLITE_POWER_STATE_FLAG_MAKECMV;
+                               if(meiCMV(TxMessage, YES_REPLY)!=MEI_SUCCESS){
+#ifdef AMAZON_MEI_DEBUG_ON
+                                       printk("\n\nCMV fail, Group 2 Address 0 Index 0");
+#endif
+                                       CLR_FLAG((&(pts.adslLineExtTableEntry_pt->flags)), LINE_GLITE_POWER_STATE_FLAG);        
+                               }       
+                               else{
+                                       memcpy((&(pts.adslLineExtTableEntry_pt->adslLineGlitePowerState)), RxMessage+4, ((RxMessage[0]&0xf)*2));
+                               }
+*/
+                               CLR_FLAG((&(pts.adslLineExtTableEntry_pt->flags)), LINE_GLITE_POWER_STATE_FLAG);
+                       }
+                       copy_to_user((char *)lon, (char *)pts.adslLineExtTableEntry_pt, sizeof(adslLineExtTableEntry));
+                       kfree(pts.adslLineTableEntry_pt);
+                       up(&mei_sema);
+                       break;
+#endif
+
+#ifdef AMAZON_MEI_MIB_RFC3440
+               case SET_ADSL_ATUC_LINE_EXT:
+                       if(down_interruptible(&mei_sema))
+                               return -ERESTARTSYS;
+                       pts.adslLineExtTableEntry_pt = (adslLineExtTableEntry *)kmalloc(sizeof(adslLineExtTableEntry), GFP_KERNEL);
+                       copy_from_user((char *)pts.adslLineExtTableEntry_pt, (char *)lon, sizeof(adslLineExtTableEntry));
+                       
+                       //only adslLineTransAtucConfig can be set.
+                       CLR_FLAG((&(pts.adslLineExtTableEntry_pt->flags)), ATUC_LINE_TRANS_CAP_FLAG);
+                       if(IS_FLAG_SET((&(pts.adslLineExtTableEntry_pt->flags)), ATUC_LINE_TRANS_CONFIG_FLAG)){
+                               memcpy(data,(&(pts.adslLineExtTableEntry_pt->adslLineTransAtucConfig)), 2); 
+                               ATUC_LINE_TRANS_CONFIG_FLAG_MAKECMV_WR;
+                               if(meiCMV(TxMessage, YES_REPLY)!=MEI_SUCCESS){
+#ifdef AMAZON_MEI_DEBUG_ON
+                                       printk("\n\nCMV fail, Group 3 Address 67 Index 0");
+#endif
+                                       CLR_FLAG((&(pts.adslLineExtTableEntry_pt->flags)), ATUC_LINE_TRANS_CONFIG_FLAG);        
+                               }       
+                       }
+                       CLR_FLAG((&(pts.adslLineExtTableEntry_pt->flags)), ATUC_LINE_TRANS_ACTUAL_FLAG);
+                       CLR_FLAG((&(pts.adslLineExtTableEntry_pt->flags)), LINE_GLITE_POWER_STATE_FLAG);
+       
+                       copy_to_user((char *)lon, (char *)pts.adslLineExtTableEntry_pt, sizeof(adslLineExtTableEntry));
+                       kfree(pts.adslLineTableEntry_pt);
+                       up(&mei_sema);
+                       break;
+#endif
+
+               case GET_ADSL_ATUC_PHY:
+                       if(down_interruptible(&mei_sema))
+                               return -ERESTARTSYS;
+                       
+                       pts.adslAtucPhysEntry_pt = (adslAtucPhysEntry *)kmalloc(sizeof(adslAtucPhysEntry), GFP_KERNEL);
+                       copy_from_user((char *)pts.adslAtucPhysEntry_pt, (char *)lon, sizeof(adslAtucPhysEntry));
+                       if(IS_FLAG_SET((&(pts.adslAtucPhysEntry_pt->flags)), ATUC_PHY_SER_NUM_FLAG)){
+                               ATUC_PHY_SER_NUM_FLAG_MAKECMV1;
+                               if(meiCMV(TxMessage, YES_REPLY)!=MEI_SUCCESS){
+#ifdef AMAZON_MEI_DEBUG_ON
+                                       printk("\n\nCMV fail, Group 3 Address 57 Index 0");
+#endif
+                                       CLR_FLAG((&(pts.adslAtucPhysEntry_pt->flags)), ATUC_PHY_SER_NUM_FLAG);  
+                               }
+                               else{
+                                       memcpy(pts.adslAtucPhysEntry_pt->serial_no, RxMessage+4, ((RxMessage[0]&0xf)*2));
+                               }
+                               ATUC_PHY_SER_NUM_FLAG_MAKECMV2;
+                               if(meiCMV(TxMessage, YES_REPLY)!=MEI_SUCCESS){
+#ifdef AMAZON_MEI_DEBUG_ON
+                                       printk("\n\nCMV fail, Group 3 Address 57 Index 12");
+#endif
+                                       CLR_FLAG((&(pts.adslAtucPhysEntry_pt->flags)), ATUC_PHY_SER_NUM_FLAG);  
+                               }
+                               else{
+                                       memcpy((pts.adslAtucPhysEntry_pt->serial_no+24), RxMessage+4, ((RxMessage[0]&0xf)*2));
+                               } 
+                       }
+                       if(IS_FLAG_SET((&(pts.adslAtucPhysEntry_pt->flags)), ATUC_PHY_VENDOR_ID_FLAG)){
+                               ATUC_PHY_VENDOR_ID_FLAG_MAKECMV;
+                               if(meiCMV(TxMessage, YES_REPLY)!=MEI_SUCCESS){
+#ifdef AMAZON_MEI_DEBUG_ON
+                                       printk("\n\nCMV fail, Group 3 Address 64 Index 0");
+#endif
+                                       CLR_FLAG((&(pts.adslAtucPhysEntry_pt->flags)), ATUC_PHY_VENDOR_ID_FLAG);        
+                               }       
+                               else{
+                                       memcpy(pts.adslAtucPhysEntry_pt->vendor_id.vendor_id, RxMessage+4, ((RxMessage[0]&0xf)*2));
+                               }
+                       }
+                       if(IS_FLAG_SET((&(pts.adslAtucPhysEntry_pt->flags)), ATUC_PHY_VER_NUM_FLAG)){
+                               ATUC_PHY_VER_NUM_FLAG_MAKECMV;
+                               if(meiCMV(TxMessage, YES_REPLY)!=MEI_SUCCESS){
+#ifdef AMAZON_MEI_DEBUG_ON
+                                       printk("\n\nCMV fail, Group 3 Address 58 Index 0");
+#endif
+                                       CLR_FLAG((&(pts.adslAtucPhysEntry_pt->flags)), ATUC_PHY_VER_NUM_FLAG);  
+                               }       
+                               else{
+                                       memcpy(pts.adslAtucPhysEntry_pt->version_no, RxMessage+4, ((RxMessage[0]&0xf)*2));
+                               }
+                       }
+                       if(IS_FLAG_SET((&(pts.adslAtucPhysEntry_pt->flags)), ATUC_CURR_STAT_FLAG)){
+                               pts.adslAtucPhysEntry_pt->status = CurrStatus.adslAtucCurrStatus;
+                       }               
+                       if(IS_FLAG_SET((&(pts.adslAtucPhysEntry_pt->flags)), ATUC_CURR_OUT_PWR_FLAG)){
+                               ATUC_CURR_OUT_PWR_FLAG_MAKECMV;
+                               if(meiCMV(TxMessage, YES_REPLY)!=MEI_SUCCESS){
+#ifdef AMAZON_MEI_DEBUG_ON
+                                       printk("\n\nCMV fail, Group 3 Address 68 Index 5");
+#endif
+                                       CLR_FLAG((&(pts.adslAtucPhysEntry_pt->flags)), ATUC_CURR_OUT_PWR_FLAG); 
+                               }       
+                               else{
+                                       memcpy((&(pts.adslAtucPhysEntry_pt->outputPwr)), RxMessage+4, ((RxMessage[0]&0xf)*2));
+                               }
+                       }
+                       if(IS_FLAG_SET((&(pts.adslAtucPhysEntry_pt->flags)), ATUC_CURR_ATTR_FLAG)){
+                               ATUC_CURR_ATTR_FLAG_MAKECMV;
+                               if(meiCMV(TxMessage, YES_REPLY)!=MEI_SUCCESS){
+#ifdef AMAZON_MEI_DEBUG_ON
+                                       printk("\n\nCMV fail, Group 3 Address 69 Index 0");
+#endif
+                                       CLR_FLAG((&(pts.adslAtucPhysEntry_pt->flags)), ATUC_CURR_ATTR_FLAG);    
+                               }       
+                               else{
+                                       memcpy((&(pts.adslAtucPhysEntry_pt->attainableRate)), RxMessage+4, ((RxMessage[0]&0xf)*2));
+                               }
+                       }
+                       copy_to_user((char *)lon, (char *)pts.adslAtucPhysEntry_pt, sizeof(adslAtucPhysEntry));
+                       kfree(pts.adslAtucPhysEntry_pt);
+                       
+                       up(&mei_sema);
+                       break;
+               case GET_ADSL_ATUR_PHY:
+                       if(down_interruptible(&mei_sema))
+                               return -ERESTARTSYS;
+                       
+                       pts.adslAturPhysEntry_pt = (adslAturPhysEntry *)kmalloc(sizeof(adslAturPhysEntry), GFP_KERNEL);
+                       copy_from_user((char *)pts.adslAturPhysEntry_pt, (char *)lon, sizeof(adslAturPhysEntry));
+                       if(IS_FLAG_SET((&(pts.adslAturPhysEntry_pt->flags)), ATUR_PHY_SER_NUM_FLAG)){
+                               ATUR_PHY_SER_NUM_FLAG_MAKECMV1;
+                               if(meiCMV(TxMessage, YES_REPLY)!=MEI_SUCCESS){
+#ifdef AMAZON_MEI_DEBUG_ON
+                                       printk("\n\nCMV fail, Group 3 Address 62 Index 0");
+#endif
+                                       CLR_FLAG((&(pts.adslAturPhysEntry_pt->flags)), ATUR_PHY_SER_NUM_FLAG);  
+                               }
+                               else{
+                                       memcpy(pts.adslAturPhysEntry_pt->serial_no, RxMessage+4, ((RxMessage[0]&0xf)*2));
+                               }
+                               ATUR_PHY_SER_NUM_FLAG_MAKECMV2;
+                               if(meiCMV(TxMessage, YES_REPLY)!=MEI_SUCCESS){
+#ifdef AMAZON_MEI_DEBUG_ON
+                                       printk("\n\nCMV fail, Group 3 Address 62 Index 12");
+#endif
+                                       CLR_FLAG((&(pts.adslAturPhysEntry_pt->flags)), ATUR_PHY_SER_NUM_FLAG);  
+                               }
+                               else{
+                                       memcpy((pts.adslAturPhysEntry_pt->serial_no+24), RxMessage+4, ((RxMessage[0]&0xf)*2));
+                               } 
+                       }
+                       if(IS_FLAG_SET((&(pts.adslAturPhysEntry_pt->flags)), ATUR_PHY_VENDOR_ID_FLAG)){
+                               ATUR_PHY_VENDOR_ID_FLAG_MAKECMV;
+                               if(meiCMV(TxMessage, YES_REPLY)!=MEI_SUCCESS){
+#ifdef AMAZON_MEI_DEBUG_ON
+                                       printk("\n\nCMV fail, Group 3 Address 65 Index 0");
+#endif
+                                       CLR_FLAG((&(pts.adslAturPhysEntry_pt->flags)), ATUR_PHY_VENDOR_ID_FLAG);        
+                               }       
+                               else{
+                                       memcpy(pts.adslAturPhysEntry_pt->vendor_id.vendor_id, RxMessage+4, ((RxMessage[0]&0xf)*2));
+                               }
+                       }
+                       if(IS_FLAG_SET((&(pts.adslAturPhysEntry_pt->flags)), ATUR_PHY_VER_NUM_FLAG)){
+                               ATUR_PHY_VER_NUM_FLAG_MAKECMV;
+                               if(meiCMV(TxMessage, YES_REPLY)!=MEI_SUCCESS){
+#ifdef AMAZON_MEI_DEBUG_ON
+                                       printk("\n\nCMV fail, Group 3 Address 61 Index 0");
+#endif
+                                       CLR_FLAG((&(pts.adslAturPhysEntry_pt->flags)), ATUR_PHY_VER_NUM_FLAG);  
+                               }       
+                               else{
+                                       memcpy(pts.adslAturPhysEntry_pt->version_no, RxMessage+4, ((RxMessage[0]&0xf)*2));
+                               }
+                       }
+                       if(IS_FLAG_SET((&(pts.adslAturPhysEntry_pt->flags)), ATUR_SNRMGN_FLAG)){
+                               ATUR_SNRMGN_FLAG_MAKECMV;
+                               if(meiCMV(TxMessage, YES_REPLY)!=MEI_SUCCESS){
+#ifdef AMAZON_MEI_DEBUG_ON
+                                       printk("\n\nCMV fail, Group 3 Address 68 Index 4");
+#endif
+                                       CLR_FLAG((&(pts.adslAturPhysEntry_pt->flags)), ATUR_SNRMGN_FLAG);       
+                               }       
+                               else{
+                                       memcpy((&(pts.adslAturPhysEntry_pt->SnrMgn)), RxMessage+4, ((RxMessage[0]&0xf)*2));
+                               }
+                       }
+                       if(IS_FLAG_SET((&(pts.adslAturPhysEntry_pt->flags)), ATUR_ATTN_FLAG)){
+                               ATUR_ATTN_FLAG_MAKECMV;
+                               if(meiCMV(TxMessage, YES_REPLY)!=MEI_SUCCESS){
+#ifdef AMAZON_MEI_DEBUG_ON
+                                       printk("\n\nCMV fail, Group 3 Address 68 Index 2");
+#endif
+                                       CLR_FLAG((&(pts.adslAturPhysEntry_pt->flags)), ATUR_ATTN_FLAG); 
+                               }       
+                               else{
+                                       memcpy((&(pts.adslAturPhysEntry_pt->Attn)), RxMessage+4, ((RxMessage[0]&0xf)*2));
+                               }
+                       }
+                       if(IS_FLAG_SET((&(pts.adslAturPhysEntry_pt->flags)), ATUR_CURR_STAT_FLAG)){
+                               pts.adslAturPhysEntry_pt->status = CurrStatus.adslAturCurrStatus;
+                       }
+                       if(IS_FLAG_SET((&(pts.adslAturPhysEntry_pt->flags)), ATUR_CURR_OUT_PWR_FLAG)){
+                               ATUR_CURR_OUT_PWR_FLAG_MAKECMV;
+                               if(meiCMV(TxMessage, YES_REPLY)!=MEI_SUCCESS){
+#ifdef AMAZON_MEI_DEBUG_ON
+                                       printk("\n\nCMV fail, Group 3 Address 69 Index 5");
+#endif
+                                       CLR_FLAG((&(pts.adslAturPhysEntry_pt->flags)), ATUR_CURR_OUT_PWR_FLAG); 
+                               }       
+                               else{
+                                       memcpy((&(pts.adslAturPhysEntry_pt->outputPwr)), RxMessage+4, ((RxMessage[0]&0xf)*2));
+                               }
+                       }
+                       if(IS_FLAG_SET((&(pts.adslAturPhysEntry_pt->flags)), ATUR_CURR_ATTR_FLAG)){
+                               ATUR_CURR_ATTR_FLAG_MAKECMV;
+                               if(meiCMV(TxMessage, YES_REPLY)!=MEI_SUCCESS){
+#ifdef AMAZON_MEI_DEBUG_ON
+                                       printk("\n\nCMV fail, Group 3 Address 68 Index 0");
+#endif
+                                       CLR_FLAG((&(pts.adslAturPhysEntry_pt->flags)), ATUR_CURR_ATTR_FLAG);    
+                               }       
+                               else{
+                                       memcpy((&(pts.adslAturPhysEntry_pt->attainableRate)), RxMessage+4, ((RxMessage[0]&0xf)*2));
+                               }
+                       }
+                       copy_to_user((char *)lon, (char *)pts.adslAturPhysEntry_pt, sizeof(adslAturPhysEntry));
+                       kfree(pts.adslAturPhysEntry_pt);
+                       
+                       up(&mei_sema);
+                       break;
+               case GET_ADSL_ATUC_CHAN_INFO:
+                       if(down_interruptible(&mei_sema))
+                               return -ERESTARTSYS;
+                       
+                       pts.adslAtucChanInfo_pt = (adslAtucChanInfo *)kmalloc(sizeof(adslAtucChanInfo), GFP_KERNEL);
+                       copy_from_user((char *)pts.adslAtucChanInfo_pt, (char *)lon, sizeof(adslAtucChanInfo));
+                       if(IS_FLAG_SET((&(pts.adslAtucChanInfo_pt->flags)), ATUC_CHAN_INTLV_DELAY_FLAG)){
+                               if((chantype.interleave!=1) || (chantype.fast==1)){
+                                       CLR_FLAG((&(pts.adslAtucChanInfo_pt->flags)), ATUC_CHAN_INTLV_DELAY_FLAG);
+                               }
+                               else{
+                                       ATUC_CHAN_INTLV_DELAY_FLAG_MAKECMV;
+                                       if(meiCMV(TxMessage, YES_REPLY)!=MEI_SUCCESS){
+#ifdef AMAZON_MEI_DEBUG_ON
+                                               printk("\n\nCMV fail, Group 6 Address 3 Index 1");
+#endif
+                                               CLR_FLAG((&(pts.adslAtucChanInfo_pt->flags)), ATUC_CHAN_INTLV_DELAY_FLAG);      
+                                       }       
+                                       else{
+                                               memcpy((&(pts.adslAtucChanInfo_pt->interleaveDelay)), RxMessage+4, ((RxMessage[0]&0xf)*2));
+                                       }
+                               }
+                       }
+                       if(IS_FLAG_SET((&(pts.adslAtucChanInfo_pt->flags)), ATUC_CHAN_CURR_TX_RATE_FLAG)){
+                               ATUC_CHAN_CURR_TX_RATE_FLAG_MAKECMV;
+                               if(meiCMV(TxMessage, YES_REPLY)!=MEI_SUCCESS){
+#ifdef AMAZON_MEI_DEBUG_ON
+                                       printk("\n\nCMV fail, Group 6 Address 1 Index 0");
+#endif
+                                       CLR_FLAG((&(pts.adslAtucChanInfo_pt->flags)), ATUC_CHAN_CURR_TX_RATE_FLAG);     
+                               }       
+                               else{
+                                       pts.adslAtucChanInfo_pt->currTxRate = (u32)(RxMessage[4]) + (((u32)(RxMessage[5]))<<16);
+                               }
+                       }
+                       if(IS_FLAG_SET((&(pts.adslAtucChanInfo_pt->flags)), ATUC_CHAN_PREV_TX_RATE_FLAG)){
+                               pts.adslAtucChanInfo_pt->prevTxRate = PrevTxRate.adslAtucChanPrevTxRate;
+                       }
+                       copy_to_user((char *)lon, (char *)pts.adslAtucChanInfo_pt, sizeof(adslAtucChanInfo));
+                       kfree(pts.adslAtucChanInfo_pt);
+                       
+                       up(&mei_sema);
+                       break;
+               case GET_ADSL_ATUR_CHAN_INFO:
+                       if(down_interruptible(&mei_sema))
+                               return -ERESTARTSYS;
+                       
+                       pts.adslAturChanInfo_pt = (adslAturChanInfo *)kmalloc(sizeof(adslAturChanInfo), GFP_KERNEL);
+                       copy_from_user((char *)pts.adslAturChanInfo_pt, (char *)lon, sizeof(adslAturChanInfo));
+                       if(IS_FLAG_SET((&(pts.adslAturChanInfo_pt->flags)), ATUR_CHAN_INTLV_DELAY_FLAG)){
+                               if((chantype.interleave!=1) || (chantype.fast==1)){
+                                       CLR_FLAG((&(pts.adslAturChanInfo_pt->flags)), ATUR_CHAN_INTLV_DELAY_FLAG);
+                               }
+                               else{
+                                       ATUR_CHAN_INTLV_DELAY_FLAG_MAKECMV;
+                                       if(meiCMV(TxMessage, YES_REPLY)!=MEI_SUCCESS){
+#ifdef AMAZON_MEI_DEBUG_ON
+                                               printk("\n\nCMV fail, Group 6 Address 2 Index 1");
+#endif
+                                               CLR_FLAG((&(pts.adslAturChanInfo_pt->flags)), ATUR_CHAN_INTLV_DELAY_FLAG);      
+                                       }       
+                                       else{
+                                               memcpy((&(pts.adslAturChanInfo_pt->interleaveDelay)), RxMessage+4, ((RxMessage[0]&0xf)*2));
+                                       }
+                               }
+                       }
+                       if(IS_FLAG_SET((&(pts.adslAturChanInfo_pt->flags)), ATUR_CHAN_CURR_TX_RATE_FLAG)){
+                               ATUR_CHAN_CURR_TX_RATE_FLAG_MAKECMV;
+                               if(meiCMV(TxMessage, YES_REPLY)!=MEI_SUCCESS){
+#ifdef AMAZON_MEI_DEBUG_ON
+                                       printk("\n\nCMV fail, Group 6 Address 0 Index 0");
+#endif
+                                       CLR_FLAG((&(pts.adslAturChanInfo_pt->flags)), ATUR_CHAN_CURR_TX_RATE_FLAG);     
+                               }       
+                               else{
+                                       pts.adslAturChanInfo_pt->currTxRate = (u32)(RxMessage[4]) + (((u32)(RxMessage[5]))<<16);
+                               }
+                       }
+                       if(IS_FLAG_SET((&(pts.adslAturChanInfo_pt->flags)), ATUR_CHAN_PREV_TX_RATE_FLAG)){
+                               pts.adslAturChanInfo_pt->prevTxRate = PrevTxRate.adslAturChanPrevTxRate;
+                       }
+                       if(IS_FLAG_SET((&(pts.adslAturChanInfo_pt->flags)), ATUR_CHAN_CRC_BLK_LEN_FLAG)){
+                               // ? no CMV to update this 
+                               CLR_FLAG((&(pts.adslAturChanInfo_pt->flags)), ATUR_CHAN_CRC_BLK_LEN_FLAG);
+                       }
+                       copy_to_user((char *)lon, (char *)pts.adslAturChanInfo_pt, sizeof(adslAturChanInfo));
+                       kfree(pts.adslAturChanInfo_pt);
+                       
+                       up(&mei_sema);
+                       break;
+               case GET_ADSL_ATUC_PERF_DATA:
+                       pts.atucPerfDataEntry_pt = (atucPerfDataEntry *)kmalloc(sizeof(atucPerfDataEntry), GFP_KERNEL);
+                       copy_from_user((char *)pts.atucPerfDataEntry_pt, (char *)lon, sizeof(atucPerfDataEntry));
+                       if(IS_FLAG_SET((&(pts.atucPerfDataEntry_pt->flags)), ATUC_PERF_LOFS_FLAG)){
+                               pts.atucPerfDataEntry_pt->adslAtucPerfLofs=ATUC_PERF_LOFS;
+                       }
+                       if(IS_FLAG_SET((&(pts.atucPerfDataEntry_pt->flags)), ATUC_PERF_LOSS_FLAG)){
+                               pts.atucPerfDataEntry_pt->adslAtucPerfLoss=ATUC_PERF_LOSS;
+                       }
+                       if(IS_FLAG_SET((&(pts.atucPerfDataEntry_pt->flags)), ATUC_PERF_ESS_FLAG)){
+                               pts.atucPerfDataEntry_pt->adslAtucPerfESs=ATUC_PERF_ESS;
+                       }
+                       if(IS_FLAG_SET((&(pts.atucPerfDataEntry_pt->flags)), ATUC_PERF_INITS_FLAG)){
+                               pts.atucPerfDataEntry_pt->adslAtucPerfInits=ATUC_PERF_INITS;
+                       }
+                       if(IS_FLAG_SET((&(pts.atucPerfDataEntry_pt->flags)), ATUC_PERF_VALID_INTVLS_FLAG)){
+                               i=0;
+                               for(ptr=(current_intvl->list).prev; ptr!=&interval_list; ptr=ptr->prev){
+                                       i++;
+                                       if(i==96)
+                                               break;
+                               }
+                               pts.atucPerfDataEntry_pt->adslAtucPerfValidIntervals=i;
+                       }
+                       if(IS_FLAG_SET((&(pts.atucPerfDataEntry_pt->flags)), ATUC_PERF_INVALID_INTVLS_FLAG)){
+                               pts.atucPerfDataEntry_pt->adslAtucPerfInvalidIntervals=0;
+                       }
+                       if(IS_FLAG_SET((&(pts.atucPerfDataEntry_pt->flags)), ATUC_PERF_CURR_15MIN_TIME_ELAPSED_FLAG)){
+                               do_gettimeofday(&time_now);
+                               pts.atucPerfDataEntry_pt->adslAtucPerfCurr15MinTimeElapsed=time_now.tv_sec - (current_intvl->start_time).tv_sec;
+                       }
+                       if(IS_FLAG_SET((&(pts.atucPerfDataEntry_pt->flags)), ATUC_PERF_CURR_15MIN_LOFS_FLAG)){
+                               pts.atucPerfDataEntry_pt->adslAtucPerfCurr15MinLofs=current_intvl->AtucPerfLof;
+                       }
+                       if(IS_FLAG_SET((&(pts.atucPerfDataEntry_pt->flags)), ATUC_PERF_CURR_15MIN_LOSS_FLAG)){
+                               pts.atucPerfDataEntry_pt->adslAtucPerfCurr15MinLoss=current_intvl->AtucPerfLos;
+                       }
+                       if(IS_FLAG_SET((&(pts.atucPerfDataEntry_pt->flags)), ATUC_PERF_CURR_15MIN_ESS_FLAG)){
+                               pts.atucPerfDataEntry_pt->adslAtucPerfCurr15MinESs=current_intvl->AtucPerfEs;
+                       }
+                       if(IS_FLAG_SET((&(pts.atucPerfDataEntry_pt->flags)), ATUC_PERF_CURR_15MIN_INIT_FLAG)){
+                               pts.atucPerfDataEntry_pt->adslAtucPerfCurr15MinInits=current_intvl->AtucPerfInit;
+                       }
+                       if(IS_FLAG_SET((&(pts.atucPerfDataEntry_pt->flags)), ATUC_PERF_CURR_1DAY_TIME_ELAPSED_FLAG)){
+                               i=0;            
+                               for(ptr=(current_intvl->list).prev; ptr!=&interval_list; ptr=ptr->prev){
+                                       i+=900; 
+                               }
+                               do_gettimeofday(&time_now);
+                               i+=time_now.tv_sec - (current_intvl->start_time).tv_sec;
+                               if(i>=86400)
+                                       pts.atucPerfDataEntry_pt->adslAtucPerfCurr1DayTimeElapsed=i-86400;
+                               else
+                                       pts.atucPerfDataEntry_pt->adslAtucPerfCurr1DayTimeElapsed=i;            
+                       }
+                       if(IS_FLAG_SET((&(pts.atucPerfDataEntry_pt->flags)), ATUC_PERF_CURR_1DAY_LOFS_FLAG)){           
+                               i=0;
+                               j=0;
+                               for(ptr=interval_list.next; ptr!=&(current_intvl->list); ptr=ptr->next){
+                                       mib_ptr = list_entry(ptr, amazon_mei_mib, list);
+                                       j+=mib_ptr->AtucPerfLof;
+                                       i++;    
+                                       if(i==96)
+                                               j=0;
+                               }
+                               j+=current_intvl->AtucPerfLof;
+                               pts.atucPerfDataEntry_pt->adslAtucPerfCurr1DayLofs=j;
+                       }
+                       if(IS_FLAG_SET((&(pts.atucPerfDataEntry_pt->flags)), ATUC_PERF_CURR_1DAY_LOSS_FLAG)){           
+                               i=0;
+                               j=0;
+                               for(ptr=interval_list.next; ptr!=&(current_intvl->list); ptr=ptr->next){
+                                       mib_ptr = list_entry(ptr, amazon_mei_mib, list);
+                                       j+=mib_ptr->AtucPerfLos;
+                                       i++;    
+                                       if(i==96)
+                                               j=0;
+                               }
+                               j+=current_intvl->AtucPerfLos;
+                               pts.atucPerfDataEntry_pt->adslAtucPerfCurr1DayLoss=j;
+                       }
+                       if(IS_FLAG_SET((&(pts.atucPerfDataEntry_pt->flags)), ATUC_PERF_CURR_1DAY_ESS_FLAG)){            
+                               i=0;
+                               j=0;
+                               for(ptr=interval_list.next; ptr!=&(current_intvl->list); ptr=ptr->next){
+                                       mib_ptr = list_entry(ptr, amazon_mei_mib, list);
+                                       j+=mib_ptr->AtucPerfEs;
+                                       i++;    
+                                       if(i==96)
+                                               j=0;
+                               }
+                               j+=current_intvl->AtucPerfEs;
+                               pts.atucPerfDataEntry_pt->adslAtucPerfCurr1DayESs=j;
+                       }
+                       if(IS_FLAG_SET((&(pts.atucPerfDataEntry_pt->flags)), ATUC_PERF_CURR_1DAY_INIT_FLAG)){           
+                               i=0;
+                               j=0;
+                               for(ptr=interval_list.next; ptr!=&(current_intvl->list); ptr=ptr->next){
+                                       mib_ptr = list_entry(ptr, amazon_mei_mib, list);
+                                       j+=mib_ptr->AtucPerfInit;
+                                       i++;    
+                                       if(i==96)
+                                               j=0;
+                               }
+                               j+=current_intvl->AtucPerfInit;
+                               pts.atucPerfDataEntry_pt->adslAtucPerfCurr1DayInits=j;
+                       }
+                       if(IS_FLAG_SET((&(pts.atucPerfDataEntry_pt->flags)), ATUC_PERF_PREV_1DAY_MON_SEC_FLAG)){                
+                               i=0;
+                               for(ptr=interval_list.next; ptr!=&(current_intvl->list); ptr=ptr->next){
+                                       i++;            
+                               }
+                               if(i>=96)
+                                       pts.atucPerfDataEntry_pt->adslAtucPerfPrev1DayMoniSecs=86400;
+                               else
+                                       pts.atucPerfDataEntry_pt->adslAtucPerfPrev1DayMoniSecs=0;
+                       }
+                       if(IS_FLAG_SET((&(pts.atucPerfDataEntry_pt->flags)), ATUC_PERF_PREV_1DAY_LOFS_FLAG)){
+                               i=0;
+                               j=0;
+                               for(ptr=interval_list.next; ptr!=&(current_intvl->list); ptr=ptr->next){
+                                       mib_ptr = list_entry(ptr, amazon_mei_mib, list);
+                                       j+=mib_ptr->AtucPerfLof;
+                                       i++;
+                                       if(i==96)
+                                               break;
+                               }       
+                               if(i==96)
+                                       pts.atucPerfDataEntry_pt->adslAtucPerfPrev1DayLofs=j;
+                               else
+                                       pts.atucPerfDataEntry_pt->adslAtucPerfPrev1DayLofs=0;
+                       }
+                       if(IS_FLAG_SET((&(pts.atucPerfDataEntry_pt->flags)), ATUC_PERF_PREV_1DAY_LOSS_FLAG)){
+                               i=0;
+                               j=0;
+                               for(ptr=interval_list.next; ptr!=&(current_intvl->list); ptr=ptr->next){
+                                       mib_ptr = list_entry(ptr, amazon_mei_mib, list);
+                                       j+=mib_ptr->AtucPerfLos;
+                                       i++;
+                                       if(i==96)
+                                               break;
+                               }       
+                               if(i==96)
+                                       pts.atucPerfDataEntry_pt->adslAtucPerfPrev1DayLoss=j;
+                               else
+                                       pts.atucPerfDataEntry_pt->adslAtucPerfPrev1DayLoss=0;
+                       }
+                       if(IS_FLAG_SET((&(pts.atucPerfDataEntry_pt->flags)), ATUC_PERF_PREV_1DAY_ESS_FLAG)){
+                               i=0;
+                               j=0;
+                               for(ptr=interval_list.next; ptr!=&(current_intvl->list); ptr=ptr->next){
+                                       mib_ptr = list_entry(ptr, amazon_mei_mib, list);
+                                       j+=mib_ptr->AtucPerfEs;
+                                       i++;
+                                       if(i==96)
+                                               break;
+                               }       
+                               if(i==96)
+                                       pts.atucPerfDataEntry_pt->adslAtucPerfPrev1DayESs=j;
+                               else
+                                       pts.atucPerfDataEntry_pt->adslAtucPerfPrev1DayESs=0;
+                       }
+                       if(IS_FLAG_SET((&(pts.atucPerfDataEntry_pt->flags)), ATUC_PERF_PREV_1DAY_INITS_FLAG)){
+                               i=0;
+                               j=0;
+                               for(ptr=interval_list.next; ptr!=&(current_intvl->list); ptr=ptr->next){
+                                       mib_ptr = list_entry(ptr, amazon_mei_mib, list);
+                                       j+=mib_ptr->AtucPerfInit;
+                                       i++;
+                                       if(i==96)
+                                               break;
+                               }       
+                               if(i==96)
+                                       pts.atucPerfDataEntry_pt->adslAtucPerfPrev1DayInits=j;
+                               else
+                                       pts.atucPerfDataEntry_pt->adslAtucPerfPrev1DayInits=0;
+                       }
+                       
+                       copy_to_user((char *)lon, (char *)pts.atucPerfDataEntry_pt, sizeof(atucPerfDataEntry));
+                       kfree(pts.atucPerfDataEntry_pt);
+                       break;
+#ifdef AMAZON_MEI_MIB_RFC3440
+               case GET_ADSL_ATUC_PERF_DATA_EXT:       //??? CMV mapping not available
+                       pts.atucPerfDataExtEntry_pt = (atucPerfDataExtEntry *)kmalloc(sizeof(atucPerfDataExtEntry), GFP_KERNEL);
+                       copy_from_user((char *)pts.atucPerfDataExtEntry_pt, (char *)lon, sizeof(atucPerfDataExtEntry));
+                       if(IS_FLAG_SET((&(pts.atucPerfDataExtEntry_pt->flags)), ATUC_PERF_STAT_FASTR_FLAG)){
+                               pts.atucPerfDataExtEntry_pt->adslAtucPerfStatFastR=ATUC_PERF_STAT_FASTR;
+                       }       
+                       if(IS_FLAG_SET((&(pts.atucPerfDataExtEntry_pt->flags)), ATUC_PERF_STAT_FAILED_FASTR_FLAG)){
+                               pts.atucPerfDataExtEntry_pt->adslAtucPerfStatFailedFastR=ATUC_PERF_STAT_FAILED_FASTR;
+                       }
+                       if(IS_FLAG_SET((&(pts.atucPerfDataExtEntry_pt->flags)), ATUC_PERF_STAT_SESL_FLAG)){
+                               pts.atucPerfDataExtEntry_pt->adslAtucPerfStatSesL=ATUC_PERF_STAT_SESL;
+                       }
+                       if(IS_FLAG_SET((&(pts.atucPerfDataExtEntry_pt->flags)), ATUC_PERF_STAT_UASL_FLAG)){
+                               pts.atucPerfDataExtEntry_pt->adslAtucPerfStatUasL=ATUC_PERF_STAT_UASL;
+                       }       
+                       if(IS_FLAG_SET((&(pts.atucPerfDataExtEntry_pt->flags)), ATUC_PERF_CURR_15MIN_FASTR_FLAG)){
+                               pts.atucPerfDataExtEntry_pt->adslAtucPerfCurr15MinFastR=current_intvl->AtucPerfStatFastR;
+                       }       
+                       if(IS_FLAG_SET((&(pts.atucPerfDataExtEntry_pt->flags)), ATUC_PERF_CURR_15MIN_FAILED_FASTR_FLAG)){
+                               pts.atucPerfDataExtEntry_pt->adslAtucPerfCurr15MinFailedFastR=current_intvl->AtucPerfStatFailedFastR;
+                       }
+                       if(IS_FLAG_SET((&(pts.atucPerfDataExtEntry_pt->flags)), ATUC_PERF_CURR_15MIN_SESL_FLAG)){
+                               pts.atucPerfDataExtEntry_pt->adslAtucPerfCurr15MinSesL=current_intvl->AtucPerfStatSesL;
+                       }
+                       if(IS_FLAG_SET((&(pts.atucPerfDataExtEntry_pt->flags)), ATUC_PERF_CURR_15MIN_UASL_FLAG)){
+                               pts.atucPerfDataExtEntry_pt->adslAtucPerfCurr15MinUasL=current_intvl->AtucPerfStatUasL;
+                       }
+                       if(IS_FLAG_SET((&(pts.atucPerfDataExtEntry_pt->flags)), ATUC_PERF_CURR_1DAY_FASTR_FLAG)){
+                               i=0;
+                               j=0;
+                               for(ptr=interval_list.next; ptr!=&(current_intvl->list); ptr=ptr->next){
+                                       mib_ptr = list_entry(ptr, amazon_mei_mib, list);
+                                       j+=mib_ptr->AtucPerfStatFastR;
+                                       i++;    
+                                       if(i==96)
+                                               j=0;
+                               }
+                               j+=current_intvl->AtucPerfStatFastR;
+                               pts.atucPerfDataExtEntry_pt->adslAtucPerfCurr1DayFastR=j;
+                       }       
+                       if(IS_FLAG_SET((&(pts.atucPerfDataExtEntry_pt->flags)), ATUC_PERF_CURR_1DAY_FAILED_FASTR_FLAG)){
+                               i=0;
+                               j=0;
+                               for(ptr=interval_list.next; ptr!=&(current_intvl->list); ptr=ptr->next){
+                                       mib_ptr = list_entry(ptr, amazon_mei_mib, list);
+                                       j+=mib_ptr->AtucPerfStatFailedFastR;
+                                       i++;    
+                                       if(i==96)
+                                               j=0;
+                               }
+                               j+=current_intvl->AtucPerfStatFailedFastR;
+                               pts.atucPerfDataExtEntry_pt->adslAtucPerfCurr1DayFailedFastR=j;
+                       }
+                       if(IS_FLAG_SET((&(pts.atucPerfDataExtEntry_pt->flags)), ATUC_PERF_CURR_1DAY_SESL_FLAG)){
+                               i=0;
+                               j=0;
+                               for(ptr=interval_list.next; ptr!=&(current_intvl->list); ptr=ptr->next){
+                                       mib_ptr = list_entry(ptr, amazon_mei_mib, list);
+                                       j+=mib_ptr->AtucPerfStatSesL;
+                                       i++;    
+                                       if(i==96)
+                                               j=0;
+                               }
+                               j+=current_intvl->AtucPerfStatSesL;
+                               pts.atucPerfDataExtEntry_pt->adslAtucPerfCurr1DaySesL=j;
+                       }
+                       if(IS_FLAG_SET((&(pts.atucPerfDataExtEntry_pt->flags)), ATUC_PERF_CURR_1DAY_UASL_FLAG)){
+                               i=0;
+                               j=0;
+                               for(ptr=interval_list.next; ptr!=&(current_intvl->list); ptr=ptr->next){
+                                       mib_ptr = list_entry(ptr, amazon_mei_mib, list);
+                                       j+=mib_ptr->AtucPerfStatUasL;
+                                       i++;    
+                                       if(i==96)
+                                               j=0;
+                               }
+                               j+=current_intvl->AtucPerfStatUasL;
+                               pts.atucPerfDataExtEntry_pt->adslAtucPerfCurr1DayUasL=j;
+                       }
+                       if(IS_FLAG_SET((&(pts.atucPerfDataExtEntry_pt->flags)), ATUC_PERF_PREV_1DAY_FASTR_FLAG)){
+                               i=0;
+                               j=0;
+                               for(ptr=interval_list.next; ptr!=&(current_intvl->list); ptr=ptr->next){
+                                       mib_ptr = list_entry(ptr, amazon_mei_mib, list);
+                                       j+=mib_ptr->AtucPerfStatFastR;
+                                       i++;
+                                       if(i==96)
+                                               break;
+                               }       
+                               if(i==96)
+                                       pts.atucPerfDataExtEntry_pt->adslAtucPerfPrev1DayFastR=j;
+                               else
+                                       pts.atucPerfDataExtEntry_pt->adslAtucPerfPrev1DayFastR=0;
+                       }       
+                       if(IS_FLAG_SET((&(pts.atucPerfDataExtEntry_pt->flags)), ATUC_PERF_PREV_1DAY_FAILED_FASTR_FLAG)){
+                               i=0;
+                               j=0;
+                               for(ptr=interval_list.next; ptr!=&(current_intvl->list); ptr=ptr->next){
+                                       mib_ptr = list_entry(ptr, amazon_mei_mib, list);
+                                       j+=mib_ptr->AtucPerfStatFailedFastR;
+                                       i++;
+                                       if(i==96)
+                                               break;
+                               }       
+                               if(i==96)
+                                       pts.atucPerfDataExtEntry_pt->adslAtucPerfPrev1DayFailedFastR=j;
+                               else
+                                       pts.atucPerfDataExtEntry_pt->adslAtucPerfPrev1DayFailedFastR=0;
+                       }
+                       if(IS_FLAG_SET((&(pts.atucPerfDataExtEntry_pt->flags)), ATUC_PERF_PREV_1DAY_SESL_FLAG)){
+                               i=0;
+                               j=0;
+                               for(ptr=interval_list.next; ptr!=&(current_intvl->list); ptr=ptr->next){
+                                       mib_ptr = list_entry(ptr, amazon_mei_mib, list);
+                                       j+=mib_ptr->AtucPerfStatSesL;
+                                       i++;
+                                       if(i==96)
+                                               break;
+                               }       
+                               if(i==96)
+                                       pts.atucPerfDataExtEntry_pt->adslAtucPerfPrev1DaySesL=j;
+                               else
+                                       pts.atucPerfDataExtEntry_pt->adslAtucPerfPrev1DaySesL=0;
+                       }
+                       if(IS_FLAG_SET((&(pts.atucPerfDataExtEntry_pt->flags)), ATUC_PERF_PREV_1DAY_UASL_FLAG)){
+                               i=0;
+                               j=0;
+                               for(ptr=interval_list.next; ptr!=&(current_intvl->list); ptr=ptr->next){
+                                       mib_ptr = list_entry(ptr, amazon_mei_mib, list);
+                                       j+=mib_ptr->AtucPerfStatUasL;
+                                       i++;
+                                       if(i==96)
+                                               break;
+                               }       
+                               if(i==96)
+                                       pts.atucPerfDataExtEntry_pt->adslAtucPerfPrev1DayUasL=j;
+                               else
+                                       pts.atucPerfDataExtEntry_pt->adslAtucPerfPrev1DayUasL=0;
+                       }
+                       copy_to_user((char *)lon, (char *)pts.atucPerfDataExtEntry_pt, sizeof(atucPerfDataExtEntry));
+                       kfree(pts.atucPerfDataExtEntry_pt);
+                       break;
+#endif
+               case GET_ADSL_ATUR_PERF_DATA:
+                       pts.aturPerfDataEntry_pt = (aturPerfDataEntry *)kmalloc(sizeof(aturPerfDataEntry), GFP_KERNEL);
+                       copy_from_user((char *)pts.aturPerfDataEntry_pt, (char *)lon, sizeof(aturPerfDataEntry));
+                       if(IS_FLAG_SET((&(pts.aturPerfDataEntry_pt->flags)), ATUR_PERF_LOFS_FLAG)){
+                               pts.aturPerfDataEntry_pt->adslAturPerfLofs=ATUR_PERF_LOFS;
+                       }
+                       if(IS_FLAG_SET((&(pts.aturPerfDataEntry_pt->flags)), ATUR_PERF_LOSS_FLAG)){
+                               pts.aturPerfDataEntry_pt->adslAturPerfLoss=ATUR_PERF_LOSS;
+                       }
+                       if(IS_FLAG_SET((&(pts.aturPerfDataEntry_pt->flags)), ATUR_PERF_LPR_FLAG)){
+                               pts.aturPerfDataEntry_pt->adslAturPerfLprs=ATUR_PERF_LPR;
+                       }
+                       if(IS_FLAG_SET((&(pts.aturPerfDataEntry_pt->flags)), ATUR_PERF_ESS_FLAG)){
+                               pts.aturPerfDataEntry_pt->adslAturPerfESs=ATUR_PERF_ESS;
+                       }
+                       if(IS_FLAG_SET((&(pts.aturPerfDataEntry_pt->flags)), ATUR_PERF_VALID_INTVLS_FLAG)){
+                               i=0;
+                               for(ptr=(current_intvl->list).prev; ptr!=&interval_list; ptr=ptr->prev){
+                                       i++;
+                                       if(i==96)
+                                               break;
+                               }
+                               pts.aturPerfDataEntry_pt->adslAturPerfValidIntervals=i;
+                       }
+                       if(IS_FLAG_SET((&(pts.aturPerfDataEntry_pt->flags)), ATUR_PERF_INVALID_INTVLS_FLAG)){
+                               pts.aturPerfDataEntry_pt->adslAturPerfInvalidIntervals=0;
+                       }
+                       if(IS_FLAG_SET((&(pts.aturPerfDataEntry_pt->flags)), ATUR_PERF_CURR_15MIN_TIME_ELAPSED_FLAG)){
+                               do_gettimeofday(&time_now);
+                               pts.aturPerfDataEntry_pt->adslAturPerfCurr15MinTimeElapsed=time_now.tv_sec - (current_intvl->start_time).tv_sec;
+                       }
+                       if(IS_FLAG_SET((&(pts.aturPerfDataEntry_pt->flags)), ATUR_PERF_CURR_15MIN_LOFS_FLAG)){
+                               pts.aturPerfDataEntry_pt->adslAturPerfCurr15MinLofs=current_intvl->AturPerfLof;
+                       }
+                       if(IS_FLAG_SET((&(pts.aturPerfDataEntry_pt->flags)), ATUR_PERF_CURR_15MIN_LOSS_FLAG)){
+                               pts.aturPerfDataEntry_pt->adslAturPerfCurr15MinLoss=current_intvl->AturPerfLos;
+                       }
+                       if(IS_FLAG_SET((&(pts.aturPerfDataEntry_pt->flags)), ATUR_PERF_CURR_15MIN_LPR_FLAG)){
+                               pts.aturPerfDataEntry_pt->adslAturPerfCurr15MinLprs=current_intvl->AturPerfLpr;
+                       }
+                       if(IS_FLAG_SET((&(pts.aturPerfDataEntry_pt->flags)), ATUR_PERF_CURR_15MIN_ESS_FLAG)){
+                               pts.aturPerfDataEntry_pt->adslAturPerfCurr15MinESs=current_intvl->AturPerfEs;
+                       }
+                       if(IS_FLAG_SET((&(pts.aturPerfDataEntry_pt->flags)), ATUR_PERF_CURR_1DAY_TIME_ELAPSED_FLAG)){
+                               i=0;            
+                               for(ptr=(current_intvl->list).prev; ptr!=&interval_list; ptr=ptr->prev){
+                                       i+=900; 
+                               }
+                               do_gettimeofday(&time_now);
+                               i+=time_now.tv_sec - (current_intvl->start_time).tv_sec;
+                               if(i>=86400)
+                                       pts.aturPerfDataEntry_pt->adslAturPerfCurr1DayTimeElapsed=i-86400;
+                               else
+                                       pts.aturPerfDataEntry_pt->adslAturPerfCurr1DayTimeElapsed=i;            
+                       }
+                       if(IS_FLAG_SET((&(pts.aturPerfDataEntry_pt->flags)), ATUR_PERF_CURR_1DAY_LOFS_FLAG)){           
+                               i=0;
+                               j=0;
+                               for(ptr=interval_list.next; ptr!=&(current_intvl->list); ptr=ptr->next){
+                                       mib_ptr = list_entry(ptr, amazon_mei_mib, list);
+                                       j+=mib_ptr->AturPerfLof;
+                                       i++;    
+                                       if(i==96)
+                                               j=0;
+                               }
+                               j+=current_intvl->AturPerfLof;
+                               pts.aturPerfDataEntry_pt->adslAturPerfCurr1DayLofs=j;
+                       }
+                       if(IS_FLAG_SET((&(pts.aturPerfDataEntry_pt->flags)), ATUR_PERF_CURR_1DAY_LOSS_FLAG)){           
+                               i=0;
+                               j=0;
+                               for(ptr=interval_list.next; ptr!=&(current_intvl->list); ptr=ptr->next){
+                                       mib_ptr = list_entry(ptr, amazon_mei_mib, list);
+                                       j+=mib_ptr->AturPerfLos;
+                                       i++;    
+                                       if(i==96)
+                                               j=0;
+                               }
+                               j+=current_intvl->AturPerfLos;
+                               pts.aturPerfDataEntry_pt->adslAturPerfCurr1DayLoss=j;
+                       }
+                       if(IS_FLAG_SET((&(pts.aturPerfDataEntry_pt->flags)), ATUR_PERF_CURR_1DAY_LPR_FLAG)){            
+                               i=0;
+                               j=0;
+                               for(ptr=interval_list.next; ptr!=&(current_intvl->list); ptr=ptr->next){
+                                       mib_ptr = list_entry(ptr, amazon_mei_mib, list);
+                                       j+=mib_ptr->AturPerfLpr;
+                                       i++;    
+                                       if(i==96)
+                                               j=0;
+                               }
+                               j+=current_intvl->AturPerfLpr;
+                               pts.aturPerfDataEntry_pt->adslAturPerfCurr1DayLprs=j;
+                       }
+                       if(IS_FLAG_SET((&(pts.aturPerfDataEntry_pt->flags)), ATUR_PERF_CURR_1DAY_ESS_FLAG)){            
+                               i=0;
+                               j=0;
+                               for(ptr=interval_list.next; ptr!=&(current_intvl->list); ptr=ptr->next){
+                                       mib_ptr = list_entry(ptr, amazon_mei_mib, list);
+                                       j+=mib_ptr->AturPerfEs;
+                                       i++;    
+                                       if(i==96)
+                                               j=0;
+                               }
+                               j+=current_intvl->AturPerfEs;
+                               pts.aturPerfDataEntry_pt->adslAturPerfCurr1DayESs=j;
+                       }
+                       if(IS_FLAG_SET((&(pts.aturPerfDataEntry_pt->flags)), ATUR_PERF_PREV_1DAY_MON_SEC_FLAG)){                
+                               i=0;
+                               for(ptr=interval_list.next; ptr!=&(current_intvl->list); ptr=ptr->next){
+                                       i++;            
+                               }
+                               if(i>=96)
+                                       pts.aturPerfDataEntry_pt->adslAturPerfPrev1DayMoniSecs=86400;
+                               else
+                                       pts.aturPerfDataEntry_pt->adslAturPerfPrev1DayMoniSecs=0;
+                       }
+                       if(IS_FLAG_SET((&(pts.aturPerfDataEntry_pt->flags)), ATUR_PERF_PREV_1DAY_LOFS_FLAG)){
+                               i=0;
+                               j=0;
+                               for(ptr=interval_list.next; ptr!=&(current_intvl->list); ptr=ptr->next){
+                                       mib_ptr = list_entry(ptr, amazon_mei_mib, list);
+                                       j+=mib_ptr->AturPerfLof;
+                                       i++;
+                                       if(i==96)
+                                               break;
+                               }       
+                               if(i==96)
+                                       pts.aturPerfDataEntry_pt->adslAturPerfPrev1DayLofs=j;
+                               else
+                                       pts.aturPerfDataEntry_pt->adslAturPerfPrev1DayLofs=0;
+                       }
+                       if(IS_FLAG_SET((&(pts.aturPerfDataEntry_pt->flags)), ATUR_PERF_PREV_1DAY_LOSS_FLAG)){
+                               i=0;
+                               j=0;
+                               for(ptr=interval_list.next; ptr!=&(current_intvl->list); ptr=ptr->next){
+                                       mib_ptr = list_entry(ptr, amazon_mei_mib, list);
+                                       j+=mib_ptr->AturPerfLos;
+                                       i++;
+                                       if(i==96)
+                                               break;
+                               }       
+                               if(i==96)
+                                       pts.aturPerfDataEntry_pt->adslAturPerfPrev1DayLoss=j;
+                               else
+                                       pts.aturPerfDataEntry_pt->adslAturPerfPrev1DayLoss=0;
+                       }
+                       if(IS_FLAG_SET((&(pts.aturPerfDataEntry_pt->flags)), ATUR_PERF_PREV_1DAY_LPR_FLAG)){
+                               i=0;
+                               j=0;
+                               for(ptr=interval_list.next; ptr!=&(current_intvl->list); ptr=ptr->next){
+                                       mib_ptr = list_entry(ptr, amazon_mei_mib, list);
+                                       j+=mib_ptr->AturPerfLpr;
+                                       i++;
+                                       if(i==96)
+                                               break;
+                               }       
+                               if(i==96)
+                                       pts.aturPerfDataEntry_pt->adslAturPerfPrev1DayLprs=j;
+                               else
+                                       pts.aturPerfDataEntry_pt->adslAturPerfPrev1DayLprs=0;
+                       }
+                       if(IS_FLAG_SET((&(pts.aturPerfDataEntry_pt->flags)), ATUR_PERF_PREV_1DAY_ESS_FLAG)){
+                               i=0;
+                               j=0;
+                               for(ptr=interval_list.next; ptr!=&(current_intvl->list); ptr=ptr->next){
+                                       mib_ptr = list_entry(ptr, amazon_mei_mib, list);
+                                       j+=mib_ptr->AturPerfEs;
+                                       i++;
+                                       if(i==96)
+                                               break;
+                               }       
+                               if(i==96)
+                                       pts.aturPerfDataEntry_pt->adslAturPerfPrev1DayESs=j;
+                               else
+                                       pts.aturPerfDataEntry_pt->adslAturPerfPrev1DayESs=0;
+                       }               
+                       
+                       copy_to_user((char *)lon, (char *)pts.aturPerfDataEntry_pt, sizeof(aturPerfDataEntry));
+                       kfree(pts.aturPerfDataEntry_pt);
+                       break;
+#ifdef AMAZON_MEI_MIB_RFC3440
+               case GET_ADSL_ATUR_PERF_DATA_EXT:
+                       pts.aturPerfDataExtEntry_pt = (aturPerfDataExtEntry *)kmalloc(sizeof(aturPerfDataExtEntry), GFP_KERNEL);
+                       copy_from_user((char *)pts.aturPerfDataExtEntry_pt, (char *)lon, sizeof(aturPerfDataExtEntry));
+                       if(IS_FLAG_SET((&(pts.aturPerfDataExtEntry_pt->flags)), ATUR_PERF_STAT_SESL_FLAG)){
+                               pts.aturPerfDataExtEntry_pt->adslAturPerfStatSesL=ATUR_PERF_STAT_SESL;
+                       }       
+                       if(IS_FLAG_SET((&(pts.aturPerfDataExtEntry_pt->flags)), ATUR_PERF_STAT_UASL_FLAG)){
+                               pts.aturPerfDataExtEntry_pt->adslAturPerfStatUasL=ATUR_PERF_STAT_UASL;
+                       }
+                       if(IS_FLAG_SET((&(pts.aturPerfDataExtEntry_pt->flags)), ATUR_PERF_CURR_15MIN_SESL_FLAG)){
+                               pts.aturPerfDataExtEntry_pt->adslAturPerfCurr15MinSesL=current_intvl->AturPerfStatSesL;
+                       }       
+                       if(IS_FLAG_SET((&(pts.aturPerfDataExtEntry_pt->flags)), ATUR_PERF_CURR_15MIN_UASL_FLAG)){
+                               pts.aturPerfDataExtEntry_pt->adslAturPerfCurr15MinUasL=current_intvl->AturPerfStatUasL;
+                       }
+                       if(IS_FLAG_SET((&(pts.aturPerfDataExtEntry_pt->flags)), ATUR_PERF_CURR_1DAY_SESL_FLAG)){
+                               i=0;
+                               j=0;
+                               for(ptr=interval_list.next; ptr!=&(current_intvl->list); ptr=ptr->next){
+                                       mib_ptr = list_entry(ptr, amazon_mei_mib, list);
+                                       j+=mib_ptr->AturPerfStatSesL;
+                                       i++;    
+                                       if(i==96)
+                                               j=0;
+                               }
+                               j+=current_intvl->AturPerfStatSesL;
+                               pts.aturPerfDataExtEntry_pt->adslAturPerfCurr1DaySesL=j;        
+                       }       
+                       if(IS_FLAG_SET((&(pts.aturPerfDataExtEntry_pt->flags)), ATUR_PERF_CURR_1DAY_UASL_FLAG)){
+                               i=0;
+                               j=0;
+                               for(ptr=interval_list.next; ptr!=&(current_intvl->list); ptr=ptr->next){
+                                       mib_ptr = list_entry(ptr, amazon_mei_mib, list);
+                                       j+=mib_ptr->AturPerfStatUasL;
+                                       i++;    
+                                       if(i==96)
+                                               j=0;
+                               }
+                               j+=current_intvl->AturPerfStatUasL;
+                               pts.aturPerfDataExtEntry_pt->adslAturPerfCurr1DayUasL=j;
+                       }
+                       if(IS_FLAG_SET((&(pts.aturPerfDataExtEntry_pt->flags)), ATUR_PERF_PREV_1DAY_SESL_FLAG)){
+                               i=0;
+                               j=0;
+                               for(ptr=interval_list.next; ptr!=&(current_intvl->list); ptr=ptr->next){
+                                       mib_ptr = list_entry(ptr, amazon_mei_mib, list);
+                                       j+=mib_ptr->AturPerfStatSesL;
+                                       i++;
+                                       if(i==96)
+                                               break;
+                               }       
+                               if(i==96)
+                                       pts.aturPerfDataExtEntry_pt->adslAturPerfPrev1DaySesL=j;
+                               else
+                                       pts.aturPerfDataExtEntry_pt->adslAturPerfPrev1DaySesL=0;        
+                       }       
+                       if(IS_FLAG_SET((&(pts.aturPerfDataExtEntry_pt->flags)), ATUR_PERF_PREV_1DAY_UASL_FLAG)){
+                               i=0;
+                               j=0;
+                               for(ptr=interval_list.next; ptr!=&(current_intvl->list); ptr=ptr->next){
+                                       mib_ptr = list_entry(ptr, amazon_mei_mib, list);
+                                       j+=mib_ptr->AturPerfStatUasL;
+                                       i++;
+                                       if(i==96)
+                                               break;
+                               }       
+                               if(i==96)
+                                       pts.aturPerfDataExtEntry_pt->adslAturPerfPrev1DayUasL=j;
+                               else
+                                       pts.aturPerfDataExtEntry_pt->adslAturPerfPrev1DayUasL=0;
+                       }
+                       copy_to_user((char *)lon, (char *)pts.aturPerfDataExtEntry_pt, sizeof(aturPerfDataExtEntry));
+                       kfree(pts.aturPerfDataExtEntry_pt);
+                       break;
+#endif
+               case GET_ADSL_ATUC_INTVL_INFO:
+                       pts.adslAtucIntvlInfo_pt = (adslAtucIntvlInfo *)kmalloc(sizeof(adslAtucIntvlInfo), GFP_KERNEL);
+                       copy_from_user((char *)pts.adslAtucIntvlInfo_pt, (char *)lon, sizeof(adslAtucIntvlInfo));
+                       
+                       if(pts.adslAtucIntvlInfo_pt->IntervalNumber <1){
+                               pts.adslAtucIntvlInfo_pt->intervalLOF = ATUC_PERF_LOFS;
+                               pts.adslAtucIntvlInfo_pt->intervalLOS = ATUC_PERF_LOSS;
+                               pts.adslAtucIntvlInfo_pt->intervalES = ATUC_PERF_ESS;
+                               pts.adslAtucIntvlInfo_pt->intervalInits = ATUC_PERF_INITS;
+                               pts.adslAtucIntvlInfo_pt->intervalValidData = 1;        
+                       }
+                       else{
+                               i=0;
+                               for(ptr=(current_intvl->list).prev; ptr!=&interval_list; ptr=ptr->prev){
+                                       i++;
+                                       if(i==pts.adslAtucIntvlInfo_pt->IntervalNumber){
+                                               temp_intvl = list_entry(ptr, amazon_mei_mib, list);
+                                               pts.adslAtucIntvlInfo_pt->intervalLOF = temp_intvl->AtucPerfLof;
+                                               pts.adslAtucIntvlInfo_pt->intervalLOS = temp_intvl->AtucPerfLos;
+                                               pts.adslAtucIntvlInfo_pt->intervalES = temp_intvl->AtucPerfEs;
+                                               pts.adslAtucIntvlInfo_pt->intervalInits = temp_intvl->AtucPerfInit;
+                                               pts.adslAtucIntvlInfo_pt->intervalValidData = 1;
+                                               break;
+                                       }               
+                               }
+                               if(ptr==&interval_list){
+                                       pts.adslAtucIntvlInfo_pt->intervalValidData = 0;
+                                       pts.adslAtucIntvlInfo_pt->flags = 0;
+                                       pts.adslAtucIntvlInfo_pt->intervalLOF = 0;
+                                       pts.adslAtucIntvlInfo_pt->intervalLOS = 0;
+                                       pts.adslAtucIntvlInfo_pt->intervalES = 0;
+                                       pts.adslAtucIntvlInfo_pt->intervalInits = 0;    
+                               }
+                       }
+                                                                       
+                       copy_to_user((char *)lon, (char *)pts.adslAtucIntvlInfo_pt, sizeof(adslAtucIntvlInfo));
+                       kfree(pts.adslAtucIntvlInfo_pt);
+                       break;
+#ifdef AMAZON_MEI_MIB_RFC3440
+               case GET_ADSL_ATUC_INTVL_EXT_INFO:
+                       pts.adslAtucInvtlExtInfo_pt = (adslAtucInvtlExtInfo *)kmalloc(sizeof(adslAtucInvtlExtInfo), GFP_KERNEL);
+                       copy_from_user((char *)pts.adslAtucInvtlExtInfo_pt, (char *)lon, sizeof(adslAtucInvtlExtInfo));
+                       if(pts.adslAtucInvtlExtInfo_pt->IntervalNumber <1){
+                               pts.adslAtucInvtlExtInfo_pt->adslAtucIntervalFastR = ATUC_PERF_STAT_FASTR;
+                               pts.adslAtucInvtlExtInfo_pt->adslAtucIntervalFailedFastR = ATUC_PERF_STAT_FAILED_FASTR;
+                               pts.adslAtucInvtlExtInfo_pt->adslAtucIntervalSesL = ATUC_PERF_STAT_SESL;
+                               pts.adslAtucInvtlExtInfo_pt->adslAtucIntervalUasL = ATUC_PERF_STAT_UASL;
+//                             pts.adslAtucInvtlExtInfo_pt->intervalValidData = 1;     
+                       }
+                       else{
+                               i=0;
+                               for(ptr=(current_intvl->list).prev; ptr!=&interval_list; ptr=ptr->prev){
+                                       i++;
+                                       if(i==pts.adslAtucInvtlExtInfo_pt->IntervalNumber){
+                                               temp_intvl = list_entry(ptr, amazon_mei_mib, list);
+                                               pts.adslAtucInvtlExtInfo_pt->adslAtucIntervalFastR = temp_intvl->AtucPerfStatFastR;
+                                               pts.adslAtucInvtlExtInfo_pt->adslAtucIntervalFailedFastR = temp_intvl->AtucPerfStatFailedFastR;
+                                               pts.adslAtucInvtlExtInfo_pt->adslAtucIntervalSesL = temp_intvl->AtucPerfStatSesL;
+                                               pts.adslAtucInvtlExtInfo_pt->adslAtucIntervalUasL = temp_intvl->AtucPerfStatUasL;
+//                                             pts.adslAtucInvtlExtInfo_pt->intervalValidData = 1;
+                                               break;
+                                       }               
+                               } 
+                               if(ptr==&interval_list){
+//                                     pts.adslAtucInvtlExtInfo_pt->intervalValidData = 0;
+                                       pts.adslAtucInvtlExtInfo_pt->flags = 0; 
+                                       pts.adslAtucInvtlExtInfo_pt->adslAtucIntervalFastR = 0;
+                                       pts.adslAtucInvtlExtInfo_pt->adslAtucIntervalFailedFastR = 0;
+                                       pts.adslAtucInvtlExtInfo_pt->adslAtucIntervalSesL = 0;
+                                       pts.adslAtucInvtlExtInfo_pt->adslAtucIntervalUasL = 0;
+                               }
+                       }
+                       copy_to_user((char *)lon, (char *)pts.adslAtucInvtlExtInfo_pt, sizeof(adslAtucInvtlExtInfo));
+                       kfree(pts.adslAtucInvtlExtInfo_pt);
+                       break;
+#endif
+               case GET_ADSL_ATUR_INTVL_INFO:
+                       pts.adslAturIntvlInfo_pt = (adslAturIntvlInfo *)kmalloc(sizeof(adslAturIntvlInfo), GFP_KERNEL);
+                       copy_from_user((char *)pts.adslAturIntvlInfo_pt, (char *)lon, sizeof(adslAturIntvlInfo));
+                       
+                       if(pts.adslAturIntvlInfo_pt->IntervalNumber <1){
+                               pts.adslAturIntvlInfo_pt->intervalLOF = ATUR_PERF_LOFS;
+                               pts.adslAturIntvlInfo_pt->intervalLOS = ATUR_PERF_LOSS;
+                               pts.adslAturIntvlInfo_pt->intervalES = ATUR_PERF_ESS;
+                               pts.adslAturIntvlInfo_pt->intervalLPR = ATUR_PERF_LPR;
+                               pts.adslAturIntvlInfo_pt->intervalValidData = 1;        
+                       }
+                       else{
+                               i=0;
+                               for(ptr=(current_intvl->list).prev; ptr!=&interval_list; ptr=ptr->prev){
+                                       i++;
+                                       if(i==pts.adslAturIntvlInfo_pt->IntervalNumber){
+                                               temp_intvl = list_entry(ptr, amazon_mei_mib, list);
+                                               pts.adslAturIntvlInfo_pt->intervalLOF = temp_intvl->AturPerfLof;
+                                               pts.adslAturIntvlInfo_pt->intervalLOS = temp_intvl->AturPerfLos;
+                                               pts.adslAturIntvlInfo_pt->intervalES = temp_intvl->AturPerfEs;
+                                               pts.adslAturIntvlInfo_pt->intervalLPR = temp_intvl->AturPerfLpr;
+                                               pts.adslAturIntvlInfo_pt->intervalValidData = 1;
+                                               break;
+                                       }               
+                               }
+                               if(ptr==&interval_list){
+                                       pts.adslAturIntvlInfo_pt->intervalValidData = 0;
+                                       pts.adslAturIntvlInfo_pt->flags = 0;
+                                       pts.adslAturIntvlInfo_pt->intervalLOF = 0;
+                                       pts.adslAturIntvlInfo_pt->intervalLOS = 0;
+                                       pts.adslAturIntvlInfo_pt->intervalES = 0;
+                                       pts.adslAturIntvlInfo_pt->intervalLPR = 0;      
+                               }
+                       }
+                       
+                       copy_to_user((char *)lon, (char *)pts.adslAturIntvlInfo_pt, sizeof(adslAturIntvlInfo));
+                       kfree(pts.adslAturIntvlInfo_pt);
+                       break;
+#ifdef AMAZON_MEI_MIB_RFC3440
+               case GET_ADSL_ATUR_INTVL_EXT_INFO:
+                       pts.adslAturInvtlExtInfo_pt = (adslAturInvtlExtInfo *)kmalloc(sizeof(adslAturInvtlExtInfo), GFP_KERNEL);
+                       copy_from_user((char *)pts.adslAturInvtlExtInfo_pt, (char *)lon, sizeof(adslAturInvtlExtInfo));
+                       
+                       if(pts.adslAturInvtlExtInfo_pt->IntervalNumber <1){
+                               pts.adslAturInvtlExtInfo_pt->adslAturIntervalSesL = ATUR_PERF_STAT_SESL;
+                               pts.adslAturInvtlExtInfo_pt->adslAturIntervalUasL = ATUR_PERF_STAT_UASL;
+//                             pts.adslAturInvtlExtInfo_pt->intervalValidData = 1;
+                       }
+                       else{
+                               i=0;
+                               for(ptr=(current_intvl->list).prev; ptr!=&interval_list; ptr=ptr->prev){
+                                       i++;
+                                       if(i==pts.adslAturInvtlExtInfo_pt->IntervalNumber){
+                                               temp_intvl = list_entry(ptr, amazon_mei_mib, list);
+                                               pts.adslAturInvtlExtInfo_pt->adslAturIntervalSesL = temp_intvl->AturPerfStatSesL;
+                                               pts.adslAturInvtlExtInfo_pt->adslAturIntervalUasL = temp_intvl->AturPerfStatUasL;
+//                                             pts.adslAturInvtlExtInfo_pt->intervalValidData = 1;
+                                               break; 
+                                       }               
+                               }
+                               if(ptr==&interval_list){
+//                                     pts.adslAturInvtlExtInfo_pt->intervalValidData = 0;
+                                       pts.adslAturInvtlExtInfo_pt->flags = 0; 
+                                       pts.adslAturInvtlExtInfo_pt->adslAturIntervalSesL = 0;
+                                       pts.adslAturInvtlExtInfo_pt->adslAturIntervalUasL = 0; 
+                               }
+                       }
+                       
+                       copy_to_user((char *)lon, (char *)pts.adslAturInvtlExtInfo_pt, sizeof(adslAturInvtlExtInfo));
+                       kfree(pts.adslAturInvtlExtInfo_pt);
+                       break;
+#endif
+               case GET_ADSL_ATUC_CHAN_PERF_DATA:
+                       pts.atucChannelPerfDataEntry_pt = (atucChannelPerfDataEntry *)kmalloc(sizeof(atucChannelPerfDataEntry), GFP_KERNEL);
+                       copy_from_user((char *)pts.atucChannelPerfDataEntry_pt, (char *)lon, sizeof(atucChannelPerfDataEntry));
+       
+                       pts.atucChannelPerfDataEntry_pt->flags = 0;
+                       
+                       copy_to_user((char *)lon, (char *)pts.atucChannelPerfDataEntry_pt, sizeof(atucChannelPerfDataEntry));
+                       kfree(pts.atucChannelPerfDataEntry_pt);
+                       break;
+               case GET_ADSL_ATUR_CHAN_PERF_DATA:
+                       pts.aturChannelPerfDataEntry_pt = (aturChannelPerfDataEntry *)kmalloc(sizeof(aturChannelPerfDataEntry), GFP_KERNEL);
+                       copy_from_user((char *)pts.aturChannelPerfDataEntry_pt, (char *)lon, sizeof(aturChannelPerfDataEntry));
+                       if(IS_FLAG_SET((&(pts.aturChannelPerfDataEntry_pt->flags)), ATUR_CHAN_RECV_BLK_FLAG)){
+                               pts.aturChannelPerfDataEntry_pt->adslAturChanReceivedBlks=ATUR_CHAN_RECV_BLK;
+                       }
+                       if(IS_FLAG_SET((&(pts.aturChannelPerfDataEntry_pt->flags)), ATUR_CHAN_TX_BLK_FLAG)){
+                               pts.aturChannelPerfDataEntry_pt->adslAturChanTransmittedBlks=ATUR_CHAN_TX_BLK;
+                       }
+                       if(IS_FLAG_SET((&(pts.aturChannelPerfDataEntry_pt->flags)), ATUR_CHAN_CORR_BLK_FLAG)){
+                               pts.aturChannelPerfDataEntry_pt->adslAturChanCorrectedBlks=ATUR_CHAN_CORR_BLK;
+                       }
+                       if(IS_FLAG_SET((&(pts.aturChannelPerfDataEntry_pt->flags)), ATUR_CHAN_UNCORR_BLK_FLAG)){
+                               pts.aturChannelPerfDataEntry_pt->adslAturChanUncorrectBlks=ATUR_CHAN_UNCORR_BLK;
+                       }
+                       if(IS_FLAG_SET((&(pts.aturChannelPerfDataEntry_pt->flags)), ATUR_CHAN_PERF_VALID_INTVL_FLAG)){
+                               i=0;
+                               for(ptr=(current_intvl->list).prev; ptr!=&interval_list; ptr=ptr->prev){
+                                       i++;
+                                       if(i==96)
+                                               break;
+                               }
+                               pts.aturChannelPerfDataEntry_pt->adslAturChanPerfValidIntervals=i;
+                       }
+                       if(IS_FLAG_SET((&(pts.aturChannelPerfDataEntry_pt->flags)), ATUR_CHAN_PERF_INVALID_INTVL_FLAG)){
+                               pts.aturChannelPerfDataEntry_pt->adslAturChanPerfInvalidIntervals=0;
+                       }
+                       if(IS_FLAG_SET((&(pts.aturChannelPerfDataEntry_pt->flags)), ATUR_CHAN_PERF_CURR_15MIN_TIME_ELAPSED_FLAG)){
+                               do_gettimeofday(&time_now);
+                               pts.aturChannelPerfDataEntry_pt->adslAturChanPerfCurr15MinTimeElapsed=time_now.tv_sec - (current_intvl->start_time).tv_sec;
+                       }
+                       if(IS_FLAG_SET((&(pts.aturChannelPerfDataEntry_pt->flags)), ATUR_CHAN_PERF_CURR_15MIN_RECV_BLK_FLAG)){
+                               pts.aturChannelPerfDataEntry_pt->adslAturChanPerfCurr15MinReceivedBlks=current_intvl->AturChanPerfRxBlk;
+                       }
+                       if(IS_FLAG_SET((&(pts.aturChannelPerfDataEntry_pt->flags)), ATUR_CHAN_PERF_CURR_15MIN_TX_BLK_FLAG)){
+                               pts.aturChannelPerfDataEntry_pt->adslAturChanPerfCurr15MinTransmittedBlks=current_intvl->AturChanPerfTxBlk;
+                       }
+                       if(IS_FLAG_SET((&(pts.aturChannelPerfDataEntry_pt->flags)), ATUR_CHAN_PERF_CURR_15MIN_CORR_BLK_FLAG)){
+                               pts.aturChannelPerfDataEntry_pt->adslAturChanPerfCurr15MinCorrectedBlks=current_intvl->AturChanPerfCorrBlk;
+                       }
+                       if(IS_FLAG_SET((&(pts.aturChannelPerfDataEntry_pt->flags)), ATUR_CHAN_PERF_CURR_15MIN_UNCORR_BLK_FLAG)){
+                               pts.aturChannelPerfDataEntry_pt->adslAturChanPerfCurr15MinUncorrectBlks=current_intvl->AturChanPerfUncorrBlk;
+                       }
+                       if(IS_FLAG_SET((&(pts.aturChannelPerfDataEntry_pt->flags)), ATUR_CHAN_PERF_CURR_1DAY_TIME_ELAPSED_FLAG)){
+                               i=0;            
+                               for(ptr=(current_intvl->list).prev; ptr!=&interval_list; ptr=ptr->prev){
+                                       i+=900; 
+                               }
+                               do_gettimeofday(&time_now);
+                               i+=time_now.tv_sec - (current_intvl->start_time).tv_sec;
+                               if(i>=86400)
+                                       pts.aturChannelPerfDataEntry_pt->adslAturChanPerfCurr1DayTimeElapsed=i-86400;
+                               else
+                                       pts.aturChannelPerfDataEntry_pt->adslAturChanPerfCurr1DayTimeElapsed=i;         
+                       }
+                       if(IS_FLAG_SET((&(pts.aturChannelPerfDataEntry_pt->flags)), ATUR_CHAN_PERF_CURR_1DAY_RECV_BLK_FLAG)){           
+                               i=0;
+                               j=0;
+                               for(ptr=interval_list.next; ptr!=&(current_intvl->list); ptr=ptr->next){
+                                       mib_ptr = list_entry(ptr, amazon_mei_mib, list);
+                                       j+=mib_ptr->AturChanPerfRxBlk;
+                                       i++;    
+                                       if(i==96)
+                                               j=0;
+                               }
+                               j+=current_intvl->AturChanPerfRxBlk;
+                               pts.aturChannelPerfDataEntry_pt->adslAturChanPerfCurr1DayReceivedBlks=j;
+                       }
+                       if(IS_FLAG_SET((&(pts.aturChannelPerfDataEntry_pt->flags)), ATUR_CHAN_PERF_CURR_1DAY_TX_BLK_FLAG)){             
+                               i=0;
+                               j=0;
+                               for(ptr=interval_list.next; ptr!=&(current_intvl->list); ptr=ptr->next){
+                                       mib_ptr = list_entry(ptr, amazon_mei_mib, list);
+                                       j+=mib_ptr->AturChanPerfTxBlk;
+                                       i++;    
+                                       if(i==96)
+                                               j=0;
+                               }
+                               j+=current_intvl->AturChanPerfTxBlk;
+                               pts.aturChannelPerfDataEntry_pt->adslAturChanPerfCurr1DayTransmittedBlks=j;
+                       }
+                       if(IS_FLAG_SET((&(pts.aturChannelPerfDataEntry_pt->flags)), ATUR_CHAN_PERF_CURR_1DAY_CORR_BLK_FLAG)){           
+                               i=0;
+                               j=0;
+                               for(ptr=interval_list.next; ptr!=&(current_intvl->list); ptr=ptr->next){
+                                       mib_ptr = list_entry(ptr, amazon_mei_mib, list);
+                                       j+=mib_ptr->AturChanPerfCorrBlk;
+                                       i++;    
+                                       if(i==96)
+                                               j=0;
+                               }
+                               j+=current_intvl->AturChanPerfCorrBlk;
+                               pts.aturChannelPerfDataEntry_pt->adslAturChanPerfCurr1DayCorrectedBlks=j;
+                       }
+                       if(IS_FLAG_SET((&(pts.aturChannelPerfDataEntry_pt->flags)), ATUR_CHAN_PERF_CURR_1DAY_UNCORR_BLK_FLAG)){         
+                               i=0;
+                               j=0;
+                               for(ptr=interval_list.next; ptr!=&(current_intvl->list); ptr=ptr->next){
+                                       mib_ptr = list_entry(ptr, amazon_mei_mib, list);
+                                       j+=mib_ptr->AturChanPerfUncorrBlk;
+                                       i++;    
+                                       if(i==96)
+                                               j=0;
+                               }
+                               j+=current_intvl->AturChanPerfUncorrBlk;
+                               pts.aturChannelPerfDataEntry_pt->adslAturChanPerfCurr1DayUncorrectBlks=j;
+                       }
+                       if(IS_FLAG_SET((&(pts.aturChannelPerfDataEntry_pt->flags)), ATUR_CHAN_PERF_PREV_1DAY_MONI_SEC_FLAG)){           
+                               i=0;
+                               for(ptr=interval_list.next; ptr!=&(current_intvl->list); ptr=ptr->next){
+                                       i++;            
+                               }
+                               if(i>=96)
+                                       pts.aturChannelPerfDataEntry_pt->adslAturChanPerfPrev1DayMoniSecs=86400;
+                               else
+                                       pts.aturChannelPerfDataEntry_pt->adslAturChanPerfPrev1DayMoniSecs=0;
+                       }
+                       if(IS_FLAG_SET((&(pts.aturChannelPerfDataEntry_pt->flags)), ATUR_CHAN_PERF_PREV_1DAY_RECV_BLK_FLAG)){
+                               i=0;
+                               j=0;
+                               for(ptr=interval_list.next; ptr!=&(current_intvl->list); ptr=ptr->next){
+                                       mib_ptr = list_entry(ptr, amazon_mei_mib, list);
+                                       j+=mib_ptr->AturChanPerfRxBlk;
+                                       i++;
+                                       if(i==96)
+                                               break;
+                               }       
+                               if(i==96)
+                                       pts.aturChannelPerfDataEntry_pt->adslAturChanPerfPrev1DayReceivedBlks=j;
+                               else
+                                       pts.aturChannelPerfDataEntry_pt->adslAturChanPerfPrev1DayReceivedBlks=0;
+                       }
+                       if(IS_FLAG_SET((&(pts.aturChannelPerfDataEntry_pt->flags)), ATUR_CHAN_PERF_PREV_1DAY_TRANS_BLK_FLAG)){
+                               i=0;
+                               j=0;
+                               for(ptr=interval_list.next; ptr!=&(current_intvl->list); ptr=ptr->next){
+                                       mib_ptr = list_entry(ptr, amazon_mei_mib, list);
+                                       j+=mib_ptr->AturChanPerfTxBlk;
+                                       i++;
+                                       if(i==96)
+                                               break;
+                               }       
+                               if(i==96)
+                                       pts.aturChannelPerfDataEntry_pt->adslAturChanPerfPrev1DayTransmittedBlks=j;
+                               else
+                                       pts.aturChannelPerfDataEntry_pt->adslAturChanPerfPrev1DayTransmittedBlks=0;
+                       }
+                       if(IS_FLAG_SET((&(pts.aturChannelPerfDataEntry_pt->flags)), ATUR_CHAN_PERF_PREV_1DAY_CORR_BLK_FLAG)){
+                               i=0;
+                               j=0;
+                               for(ptr=interval_list.next; ptr!=&(current_intvl->list); ptr=ptr->next){
+                                       mib_ptr = list_entry(ptr, amazon_mei_mib, list);
+                                       j+=mib_ptr->AturChanPerfCorrBlk;
+                                       i++;
+                                       if(i==96)
+                                               break;
+                               }       
+                               if(i==96)
+                                       pts.aturChannelPerfDataEntry_pt->adslAturChanPerfPrev1DayCorrectedBlks=j;
+                               else
+                                       pts.aturChannelPerfDataEntry_pt->adslAturChanPerfPrev1DayCorrectedBlks=0;
+                       }
+                       if(IS_FLAG_SET((&(pts.aturChannelPerfDataEntry_pt->flags)), ATUR_CHAN_PERF_PREV_1DAY_UNCORR_BLK_FLAG)){
+                               i=0;
+                               j=0;
+                               for(ptr=interval_list.next; ptr!=&(current_intvl->list); ptr=ptr->next){
+                                       mib_ptr = list_entry(ptr, amazon_mei_mib, list);
+                                       j+=mib_ptr->AturChanPerfUncorrBlk;
+                                       i++;
+                                       if(i==96)
+                                               break;
+                               }       
+                               if(i==96)
+                                       pts.aturChannelPerfDataEntry_pt->adslAturChanPerfPrev1DayUncorrectBlks=j;
+                               else
+                                       pts.aturChannelPerfDataEntry_pt->adslAturChanPerfPrev1DayUncorrectBlks=0;
+                       }
+                       
+                       copy_to_user((char *)lon, (char *)pts.aturChannelPerfDataEntry_pt, sizeof(aturChannelPerfDataEntry));
+                       kfree(pts.aturChannelPerfDataEntry_pt);
+                       break;
+               case GET_ADSL_ATUC_CHAN_INTVL_INFO:
+                       pts.adslAtucChanIntvlInfo_pt = (adslAtucChanIntvlInfo *)kmalloc(sizeof(adslAtucChanIntvlInfo), GFP_KERNEL);
+                       copy_from_user((char *)pts.adslAtucChanIntvlInfo_pt, (char *)lon, sizeof(adslAtucChanIntvlInfo));
+                               
+                               pts.adslAtucChanIntvlInfo_pt->flags = 0;
+                               
+                       copy_to_user((char *)lon, (char *)pts.adslAtucChanIntvlInfo_pt, sizeof(adslAtucChanIntvlInfo));
+                       kfree(pts.adslAtucChanIntvlInfo_pt);
+                       break;
+               case GET_ADSL_ATUR_CHAN_INTVL_INFO:
+                       pts.adslAturChanIntvlInfo_pt = (adslAturChanIntvlInfo *)kmalloc(sizeof(adslAturChanIntvlInfo), GFP_KERNEL);
+                       copy_from_user((char *)pts.adslAturChanIntvlInfo_pt, (char *)lon, sizeof(adslAturChanIntvlInfo));
+                       
+                       if(pts.adslAturChanIntvlInfo_pt->IntervalNumber <1){
+                               pts.adslAturChanIntvlInfo_pt->chanIntervalRecvdBlks = ATUR_CHAN_RECV_BLK;
+                               pts.adslAturChanIntvlInfo_pt->chanIntervalXmitBlks = ATUR_CHAN_TX_BLK;
+                               pts.adslAturChanIntvlInfo_pt->chanIntervalCorrectedBlks = ATUR_CHAN_CORR_BLK;
+                               pts.adslAturChanIntvlInfo_pt->chanIntervalUncorrectBlks = ATUR_CHAN_UNCORR_BLK;
+                               pts.adslAturChanIntvlInfo_pt->intervalValidData = 1;
+                       }
+                       else{
+                               i=0;
+                               for(ptr=(current_intvl->list).prev; ptr!=&interval_list; ptr=ptr->prev){
+                                       i++;
+                                       if(i==pts.adslAturChanIntvlInfo_pt->IntervalNumber){
+                                               temp_intvl = list_entry(ptr, amazon_mei_mib, list);
+                                               pts.adslAturChanIntvlInfo_pt->chanIntervalRecvdBlks = temp_intvl->AturChanPerfRxBlk;
+                                               pts.adslAturChanIntvlInfo_pt->chanIntervalXmitBlks = temp_intvl->AturChanPerfTxBlk;
+                                               pts.adslAturChanIntvlInfo_pt->chanIntervalCorrectedBlks = temp_intvl->AturChanPerfCorrBlk;
+                                               pts.adslAturChanIntvlInfo_pt->chanIntervalUncorrectBlks = temp_intvl->AturChanPerfUncorrBlk;
+                                               pts.adslAturChanIntvlInfo_pt->intervalValidData = 1;
+                                               break;
+                                       }               
+                               }
+                               if(ptr==&interval_list){
+                                       pts.adslAturChanIntvlInfo_pt->intervalValidData = 0;
+                                       pts.adslAturChanIntvlInfo_pt->flags = 0;        
+                               }
+                       }
+                       
+                       copy_to_user((char *)lon, (char *)pts.adslAturChanIntvlInfo_pt, sizeof(adslAturChanIntvlInfo));
+                       kfree(pts.adslAturChanIntvlInfo_pt);
+                       break;
+               case GET_ADSL_ALRM_CONF_PROF:
+                       pts.adslLineAlarmConfProfileEntry_pt = (adslLineAlarmConfProfileEntry *)kmalloc(sizeof(adslLineAlarmConfProfileEntry), GFP_KERNEL);
+                       copy_from_user((char *)pts.adslLineAlarmConfProfileEntry_pt, (char *)lon, sizeof(adslLineAlarmConfProfileEntry));
+                       
+                       strncpy(pts.adslLineAlarmConfProfileEntry_pt->adslLineAlarmConfProfileName, AlarmConfProfile.adslLineAlarmConfProfileName, 32); 
+                       if(IS_FLAG_SET((&(pts.adslLineAlarmConfProfileEntry_pt->flags)), ATUC_THRESH_15MIN_LOFS_FLAG)){
+                               pts.adslLineAlarmConfProfileEntry_pt->adslAtucThresh15MinLofs=AlarmConfProfile.adslAtucThresh15MinLofs;
+                       }
+                       if(IS_FLAG_SET((&(pts.adslLineAlarmConfProfileEntry_pt->flags)), ATUC_THRESH_15MIN_LOSS_FLAG)){
+                               pts.adslLineAlarmConfProfileEntry_pt->adslAtucThresh15MinLoss=AlarmConfProfile.adslAtucThresh15MinLoss;
+                       }
+                       if(IS_FLAG_SET((&(pts.adslLineAlarmConfProfileEntry_pt->flags)), ATUC_THRESH_15MIN_ESS_FLAG)){
+                               pts.adslLineAlarmConfProfileEntry_pt->adslAtucThresh15MinESs=AlarmConfProfile.adslAtucThresh15MinESs;
+                       }
+                       if(IS_FLAG_SET((&(pts.adslLineAlarmConfProfileEntry_pt->flags)), ATUC_THRESH_FAST_RATEUP_FLAG)){
+                               pts.adslLineAlarmConfProfileEntry_pt->adslAtucThreshFastRateUp=AlarmConfProfile.adslAtucThreshFastRateUp;
+                       }
+                       if(IS_FLAG_SET((&(pts.adslLineAlarmConfProfileEntry_pt->flags)), ATUC_THRESH_INTERLEAVE_RATEUP_FLAG)){
+                               pts.adslLineAlarmConfProfileEntry_pt->adslAtucThreshInterleaveRateUp=AlarmConfProfile.adslAtucThreshInterleaveRateUp;
+                       }
+                       if(IS_FLAG_SET((&(pts.adslLineAlarmConfProfileEntry_pt->flags)), ATUC_THRESH_FAST_RATEDOWN_FLAG)){
+                               pts.adslLineAlarmConfProfileEntry_pt->adslAtucThreshFastRateDown=AlarmConfProfile.adslAtucThreshFastRateDown;
+                       }
+                       if(IS_FLAG_SET((&(pts.adslLineAlarmConfProfileEntry_pt->flags)), ATUC_THRESH_INTERLEAVE_RATEDOWN_FLAG)){
+                               pts.adslLineAlarmConfProfileEntry_pt->adslAtucThreshInterleaveRateDown=AlarmConfProfile.adslAtucThreshInterleaveRateDown;
+                       }
+                       if(IS_FLAG_SET((&(pts.adslLineAlarmConfProfileEntry_pt->flags)), ATUC_INIT_FAILURE_TRAP_ENABLE_FLAG)){
+                               pts.adslLineAlarmConfProfileEntry_pt->adslAtucInitFailureTrapEnable=AlarmConfProfile.adslAtucInitFailureTrapEnable;
+                       }
+                       if(IS_FLAG_SET((&(pts.adslLineAlarmConfProfileEntry_pt->flags)), ATUR_THRESH_15MIN_LOFS_FLAG)){
+                               pts.adslLineAlarmConfProfileEntry_pt->adslAturThresh15MinLofs=AlarmConfProfile.adslAturThresh15MinLofs;
+                       }
+                       if(IS_FLAG_SET((&(pts.adslLineAlarmConfProfileEntry_pt->flags)), ATUR_THRESH_15MIN_LOSS_FLAG)){
+                               pts.adslLineAlarmConfProfileEntry_pt->adslAturThresh15MinLoss=AlarmConfProfile.adslAturThresh15MinLoss;
+                       }
+                       if(IS_FLAG_SET((&(pts.adslLineAlarmConfProfileEntry_pt->flags)), ATUR_THRESH_15MIN_LPRS_FLAG)){
+                               pts.adslLineAlarmConfProfileEntry_pt->adslAturThresh15MinLprs=AlarmConfProfile.adslAturThresh15MinLprs;
+                       }
+                       if(IS_FLAG_SET((&(pts.adslLineAlarmConfProfileEntry_pt->flags)), ATUR_THRESH_15MIN_ESS_FLAG)){
+                               pts.adslLineAlarmConfProfileEntry_pt->adslAturThresh15MinESs=AlarmConfProfile.adslAturThresh15MinESs;
+                       }
+                       if(IS_FLAG_SET((&(pts.adslLineAlarmConfProfileEntry_pt->flags)), ATUR_THRESH_FAST_RATEUP_FLAG)){
+                               pts.adslLineAlarmConfProfileEntry_pt->adslAturThreshFastRateUp=AlarmConfProfile.adslAturThreshFastRateUp;
+                       }
+                       if(IS_FLAG_SET((&(pts.adslLineAlarmConfProfileEntry_pt->flags)), ATUR_THRESH_INTERLEAVE_RATEUP_FLAG)){
+                               pts.adslLineAlarmConfProfileEntry_pt->adslAturThreshInterleaveRateUp=AlarmConfProfile.adslAturThreshInterleaveRateUp;
+                       }
+                       if(IS_FLAG_SET((&(pts.adslLineAlarmConfProfileEntry_pt->flags)), ATUR_THRESH_FAST_RATEDOWN_FLAG)){
+                               pts.adslLineAlarmConfProfileEntry_pt->adslAturThreshFastRateDown=AlarmConfProfile.adslAturThreshFastRateDown;
+                       }
+                       if(IS_FLAG_SET((&(pts.adslLineAlarmConfProfileEntry_pt->flags)), ATUR_THRESH_INTERLEAVE_RATEDOWN_FLAG)){
+                               pts.adslLineAlarmConfProfileEntry_pt->adslAturThreshInterleaveRateDown=AlarmConfProfile.adslAturThreshInterleaveRateDown;
+                       }
+                       if(IS_FLAG_SET((&(pts.adslLineAlarmConfProfileEntry_pt->flags)), LINE_ALARM_CONF_PROFILE_ROWSTATUS_FLAG)){
+                               pts.adslLineAlarmConfProfileEntry_pt->adslLineAlarmConfProfileRowStatus=AlarmConfProfile.adslLineAlarmConfProfileRowStatus;
+                       }
+                       copy_to_user((char *)lon, (char *)pts.adslLineAlarmConfProfileEntry_pt, sizeof(adslLineAlarmConfProfileEntry));
+                       kfree(pts.adslLineAlarmConfProfileEntry_pt);
+                       break;
+#ifdef AMAZON_MEI_MIB_RFC3440
+               case GET_ADSL_ALRM_CONF_PROF_EXT:
+                       pts.adslLineAlarmConfProfileExtEntry_pt = (adslLineAlarmConfProfileExtEntry *)kmalloc(sizeof(adslLineAlarmConfProfileExtEntry), GFP_KERNEL);
+                       copy_from_user((char *)pts.adslLineAlarmConfProfileExtEntry_pt, (char *)lon, sizeof(adslLineAlarmConfProfileExtEntry));
+                       if(IS_FLAG_SET((&(pts.adslLineAlarmConfProfileExtEntry_pt->flags)), ATUC_THRESH_15MIN_FAILED_FASTR_FLAG)){
+                               pts.adslLineAlarmConfProfileExtEntry_pt->adslAtucThreshold15MinFailedFastR=AlarmConfProfileExt.adslAtucThreshold15MinFailedFastR;
+                       }
+                       if(IS_FLAG_SET((&(pts.adslLineAlarmConfProfileExtEntry_pt->flags)), ATUC_THRESH_15MIN_SESL_FLAG)){
+                               pts.adslLineAlarmConfProfileExtEntry_pt->adslAtucThreshold15MinSesL=AlarmConfProfileExt.adslAtucThreshold15MinSesL;
+                       }
+                       if(IS_FLAG_SET((&(pts.adslLineAlarmConfProfileExtEntry_pt->flags)), ATUC_THRESH_15MIN_UASL_FLAG)){
+                               pts.adslLineAlarmConfProfileExtEntry_pt->adslAtucThreshold15MinUasL=AlarmConfProfileExt.adslAtucThreshold15MinUasL;
+                       }
+                       if(IS_FLAG_SET((&(pts.adslLineAlarmConfProfileExtEntry_pt->flags)), ATUR_THRESH_15MIN_SESL_FLAG)){
+                               pts.adslLineAlarmConfProfileExtEntry_pt->adslAturThreshold15MinSesL=AlarmConfProfileExt.adslAturThreshold15MinSesL;
+                       }
+                       if(IS_FLAG_SET((&(pts.adslLineAlarmConfProfileExtEntry_pt->flags)), ATUR_THRESH_15MIN_UASL_FLAG)){
+                               pts.adslLineAlarmConfProfileExtEntry_pt->adslAturThreshold15MinUasL=AlarmConfProfileExt.adslAturThreshold15MinUasL;
+                       }
+                       copy_to_user((char *)lon, (char *)pts.adslLineAlarmConfProfileExtEntry_pt, sizeof(adslLineAlarmConfProfileExtEntry));
+                       kfree(pts.adslLineAlarmConfProfileExtEntry_pt);
+                       break;
+#endif
+               case SET_ADSL_ALRM_CONF_PROF:
+                       pts.adslLineAlarmConfProfileEntry_pt = (adslLineAlarmConfProfileEntry *)kmalloc(sizeof(adslLineAlarmConfProfileEntry), GFP_KERNEL);
+                       copy_from_user((char *)pts.adslLineAlarmConfProfileEntry_pt, (char *)lon, sizeof(adslLineAlarmConfProfileEntry));
+
+                       strncpy(AlarmConfProfile.adslLineAlarmConfProfileName, pts.adslLineAlarmConfProfileEntry_pt->adslLineAlarmConfProfileName, 32);
+                       if(IS_FLAG_SET((&(pts.adslLineAlarmConfProfileEntry_pt->flags)), ATUC_THRESH_15MIN_LOFS_FLAG)){
+                               AlarmConfProfile.adslAtucThresh15MinLofs=pts.adslLineAlarmConfProfileEntry_pt->adslAtucThresh15MinLofs;
+                       }
+                       if(IS_FLAG_SET((&(pts.adslLineAlarmConfProfileEntry_pt->flags)), ATUC_THRESH_15MIN_LOSS_FLAG)){
+                               AlarmConfProfile.adslAtucThresh15MinLoss=pts.adslLineAlarmConfProfileEntry_pt->adslAtucThresh15MinLoss;
+                       }
+                       if(IS_FLAG_SET((&(pts.adslLineAlarmConfProfileEntry_pt->flags)), ATUC_THRESH_15MIN_ESS_FLAG)){
+                               AlarmConfProfile.adslAtucThresh15MinESs=pts.adslLineAlarmConfProfileEntry_pt->adslAtucThresh15MinESs;
+                       }
+                       if(IS_FLAG_SET((&(pts.adslLineAlarmConfProfileEntry_pt->flags)), ATUC_THRESH_FAST_RATEUP_FLAG)){
+                               AlarmConfProfile.adslAtucThreshFastRateUp=pts.adslLineAlarmConfProfileEntry_pt->adslAtucThreshFastRateUp;
+                       }
+                       if(IS_FLAG_SET((&(pts.adslLineAlarmConfProfileEntry_pt->flags)), ATUC_THRESH_INTERLEAVE_RATEUP_FLAG)){
+                               AlarmConfProfile.adslAtucThreshInterleaveRateUp=pts.adslLineAlarmConfProfileEntry_pt->adslAtucThreshInterleaveRateUp;
+                       }
+                       if(IS_FLAG_SET((&(pts.adslLineAlarmConfProfileEntry_pt->flags)), ATUC_THRESH_FAST_RATEDOWN_FLAG)){
+                               AlarmConfProfile.adslAtucThreshFastRateDown=pts.adslLineAlarmConfProfileEntry_pt->adslAtucThreshFastRateDown;
+                       }
+                       if(IS_FLAG_SET((&(pts.adslLineAlarmConfProfileEntry_pt->flags)), ATUC_THRESH_INTERLEAVE_RATEDOWN_FLAG)){
+                               AlarmConfProfile.adslAtucThreshInterleaveRateDown=pts.adslLineAlarmConfProfileEntry_pt->adslAtucThreshInterleaveRateDown;
+                       }
+                       if(IS_FLAG_SET((&(pts.adslLineAlarmConfProfileEntry_pt->flags)), ATUC_INIT_FAILURE_TRAP_ENABLE_FLAG)){
+                               AlarmConfProfile.adslAtucInitFailureTrapEnable=pts.adslLineAlarmConfProfileEntry_pt->adslAtucInitFailureTrapEnable;
+                       }
+                       if(IS_FLAG_SET((&(pts.adslLineAlarmConfProfileEntry_pt->flags)), ATUR_THRESH_15MIN_LOFS_FLAG)){
+                               AlarmConfProfile.adslAturThresh15MinLofs=pts.adslLineAlarmConfProfileEntry_pt->adslAturThresh15MinLofs;
+                       }
+                       if(IS_FLAG_SET((&(pts.adslLineAlarmConfProfileEntry_pt->flags)), ATUR_THRESH_15MIN_LOSS_FLAG)){
+                               AlarmConfProfile.adslAturThresh15MinLoss=pts.adslLineAlarmConfProfileEntry_pt->adslAturThresh15MinLoss;
+                       }
+                       if(IS_FLAG_SET((&(pts.adslLineAlarmConfProfileEntry_pt->flags)), ATUR_THRESH_15MIN_LPRS_FLAG)){
+                               AlarmConfProfile.adslAturThresh15MinLprs=pts.adslLineAlarmConfProfileEntry_pt->adslAturThresh15MinLprs;
+                       }
+                       if(IS_FLAG_SET((&(pts.adslLineAlarmConfProfileEntry_pt->flags)), ATUR_THRESH_15MIN_ESS_FLAG)){
+                               AlarmConfProfile.adslAturThresh15MinESs=pts.adslLineAlarmConfProfileEntry_pt->adslAturThresh15MinESs;
+                       }
+                       if(IS_FLAG_SET((&(pts.adslLineAlarmConfProfileEntry_pt->flags)), ATUR_THRESH_FAST_RATEUP_FLAG)){
+                               AlarmConfProfile.adslAturThreshFastRateUp=pts.adslLineAlarmConfProfileEntry_pt->adslAturThreshFastRateUp;
+                       }
+                       if(IS_FLAG_SET((&(pts.adslLineAlarmConfProfileEntry_pt->flags)), ATUR_THRESH_INTERLEAVE_RATEUP_FLAG)){
+                               AlarmConfProfile.adslAturThreshInterleaveRateUp=pts.adslLineAlarmConfProfileEntry_pt->adslAturThreshInterleaveRateUp;
+                       }
+                       if(IS_FLAG_SET((&(pts.adslLineAlarmConfProfileEntry_pt->flags)), ATUR_THRESH_FAST_RATEDOWN_FLAG)){
+                               AlarmConfProfile.adslAturThreshFastRateDown=pts.adslLineAlarmConfProfileEntry_pt->adslAturThreshFastRateDown;
+                       }
+                       if(IS_FLAG_SET((&(pts.adslLineAlarmConfProfileEntry_pt->flags)), ATUR_THRESH_INTERLEAVE_RATEDOWN_FLAG)){
+                               AlarmConfProfile.adslAturThreshInterleaveRateDown=pts.adslLineAlarmConfProfileEntry_pt->adslAturThreshInterleaveRateDown;
+                       }
+                       if(IS_FLAG_SET((&(pts.adslLineAlarmConfProfileEntry_pt->flags)), LINE_ALARM_CONF_PROFILE_ROWSTATUS_FLAG)){
+                               AlarmConfProfile.adslLineAlarmConfProfileRowStatus=pts.adslLineAlarmConfProfileEntry_pt->adslLineAlarmConfProfileRowStatus;
+                       }
+                       copy_to_user((char *)lon, (char *)pts.adslLineAlarmConfProfileEntry_pt, sizeof(adslLineAlarmConfProfileEntry));
+                       kfree(pts.adslLineAlarmConfProfileEntry_pt);
+                       break;
+                       
+#ifdef AMAZON_MEI_MIB_RFC3440
+               case SET_ADSL_ALRM_CONF_PROF_EXT:
+                       pts.adslLineAlarmConfProfileExtEntry_pt = (adslLineAlarmConfProfileExtEntry *)kmalloc(sizeof(adslLineAlarmConfProfileExtEntry), GFP_KERNEL);
+                       copy_from_user((char *)pts.adslLineAlarmConfProfileExtEntry_pt, (char *)lon, sizeof(adslLineAlarmConfProfileExtEntry));
+                       if(IS_FLAG_SET((&(pts.adslLineAlarmConfProfileExtEntry_pt->flags)), ATUC_THRESH_15MIN_FAILED_FASTR_FLAG)){
+                               AlarmConfProfileExt.adslAtucThreshold15MinFailedFastR=pts.adslLineAlarmConfProfileExtEntry_pt->adslAtucThreshold15MinFailedFastR;
+                       }
+                       if(IS_FLAG_SET((&(pts.adslLineAlarmConfProfileExtEntry_pt->flags)), ATUC_THRESH_15MIN_SESL_FLAG)){
+                               AlarmConfProfileExt.adslAtucThreshold15MinSesL=pts.adslLineAlarmConfProfileExtEntry_pt->adslAtucThreshold15MinSesL;
+                       }
+                       if(IS_FLAG_SET((&(pts.adslLineAlarmConfProfileExtEntry_pt->flags)), ATUC_THRESH_15MIN_UASL_FLAG)){
+                               AlarmConfProfileExt.adslAtucThreshold15MinUasL=pts.adslLineAlarmConfProfileExtEntry_pt->adslAtucThreshold15MinUasL;
+                       }
+                       if(IS_FLAG_SET((&(pts.adslLineAlarmConfProfileExtEntry_pt->flags)), ATUR_THRESH_15MIN_SESL_FLAG)){
+                               AlarmConfProfileExt.adslAturThreshold15MinSesL=pts.adslLineAlarmConfProfileExtEntry_pt->adslAturThreshold15MinSesL;
+                       }
+                       if(IS_FLAG_SET((&(pts.adslLineAlarmConfProfileExtEntry_pt->flags)), ATUR_THRESH_15MIN_UASL_FLAG)){
+                               AlarmConfProfileExt.adslAturThreshold15MinUasL=pts.adslLineAlarmConfProfileExtEntry_pt->adslAturThreshold15MinUasL;
+                       }
+                       copy_to_user((char *)lon, (char *)pts.adslLineAlarmConfProfileExtEntry_pt, sizeof(adslLineAlarmConfProfileExtEntry));
+                       kfree(pts.adslLineAlarmConfProfileExtEntry_pt);
+                       break;
+#endif
+
+               case ADSL_ATUR_TRAPS:
+                       if(down_interruptible(&mei_sema))
+                               return -ERESTARTSYS;
+                       
+                       trapsflag=0;
+                       if(AlarmConfProfile.adslAtucThresh15MinLofs!=0 && current_intvl->AtucPerfLof>=AlarmConfProfile.adslAtucThresh15MinLofs)
+                               trapsflag|=ATUC_PERF_LOFS_THRESH_FLAG;
+                       if(AlarmConfProfile.adslAtucThresh15MinLoss!=0 && current_intvl->AtucPerfLos>=AlarmConfProfile.adslAtucThresh15MinLoss)
+                               trapsflag|=ATUC_PERF_LOSS_THRESH_FLAG;
+                       if(AlarmConfProfile.adslAtucThresh15MinESs!=0 && current_intvl->AtucPerfEs>=AlarmConfProfile.adslAtucThresh15MinESs)
+                               trapsflag|=ATUC_PERF_ESS_THRESH_FLAG;
+                       if(chantype.fast==1){
+                               if(AlarmConfProfile.adslAtucThreshFastRateUp!=0 || AlarmConfProfile.adslAtucThreshFastRateDown!=0){
+                                       ATUC_CHAN_CURR_TX_RATE_FLAG_MAKECMV;
+                                       if(meiCMV(TxMessage, YES_REPLY)!=MEI_SUCCESS){
+#ifdef AMAZON_MEI_DEBUG_ON
+                                               printk("\n\nCMV fail, Group 6 Address 1 Index 0");
+#endif                 
+                                       }
+                                       else{
+                                               temp = (u32)(RxMessage[4]) + (((u32)(RxMessage[5]))<<16); 
+                                               if((AlarmConfProfile.adslAtucThreshFastRateUp!=0) && (temp>=PrevTxRate.adslAtucChanPrevTxRate+AlarmConfProfile.adslAtucThreshFastRateUp)){
+                                                       trapsflag|=ATUC_RATE_CHANGE_FLAG;
+                                                       PrevTxRate.adslAtucChanPrevTxRate = temp;                                               
+                                               }
+                                               if((AlarmConfProfile.adslAtucThreshFastRateDown!=0) && (temp<=PrevTxRate.adslAtucChanPrevTxRate-AlarmConfProfile.adslAtucThreshFastRateDown)){
+                                                       trapsflag|=ATUC_RATE_CHANGE_FLAG;
+                                                       PrevTxRate.adslAtucChanPrevTxRate = temp;                                               
+                                               }
+                                       }
+                               }
+                       }       
+                       if(chantype.interleave==1){
+                               if(AlarmConfProfile.adslAtucThreshInterleaveRateUp!=0 || AlarmConfProfile.adslAtucThreshInterleaveRateDown!=0){
+                                       ATUC_CHAN_CURR_TX_RATE_FLAG_MAKECMV;
+                                       if(meiCMV(TxMessage, YES_REPLY)!=MEI_SUCCESS){
+#ifdef AMAZON_MEI_DEBUG_ON
+                                               printk("\n\nCMV fail, Group 6 Address 1 Index 0");
+#endif                 
+                                       }
+                                       else{
+                                               temp = (u32)(RxMessage[4]) + (((u32)(RxMessage[5]))<<16); 
+                                               if((AlarmConfProfile.adslAtucThreshInterleaveRateUp!=0) && (temp>=PrevTxRate.adslAtucChanPrevTxRate+AlarmConfProfile.adslAtucThreshInterleaveRateUp)){
+                                                       trapsflag|=ATUC_RATE_CHANGE_FLAG;
+                                                       PrevTxRate.adslAtucChanPrevTxRate = temp;                                               
+                                               }
+                                               if((AlarmConfProfile.adslAtucThreshInterleaveRateDown!=0) && (temp<=PrevTxRate.adslAtucChanPrevTxRate-AlarmConfProfile.adslAtucThreshInterleaveRateDown)){
+                                                       trapsflag|=ATUC_RATE_CHANGE_FLAG;
+                                                       PrevTxRate.adslAtucChanPrevTxRate = temp;                                               
+                                               }
+                                       }
+                               }
+                       }       
+                       if(AlarmConfProfile.adslAturThresh15MinLofs!=0 && current_intvl->AturPerfLof>=AlarmConfProfile.adslAturThresh15MinLofs)
+                               trapsflag|=ATUR_PERF_LOFS_THRESH_FLAG;
+                       if(AlarmConfProfile.adslAturThresh15MinLoss!=0 && current_intvl->AturPerfLos>=AlarmConfProfile.adslAturThresh15MinLoss)
+                               trapsflag|=ATUR_PERF_LOSS_THRESH_FLAG;
+                       if(AlarmConfProfile.adslAturThresh15MinLprs!=0 && current_intvl->AturPerfLpr>=AlarmConfProfile.adslAturThresh15MinLprs)
+                               trapsflag|=ATUR_PERF_LPRS_THRESH_FLAG;
+                       if(AlarmConfProfile.adslAturThresh15MinESs!=0 && current_intvl->AturPerfEs>=AlarmConfProfile.adslAturThresh15MinESs)
+                               trapsflag|=ATUR_PERF_ESS_THRESH_FLAG;   
+                       if(chantype.fast==1){
+                               if(AlarmConfProfile.adslAturThreshFastRateUp!=0 || AlarmConfProfile.adslAturThreshFastRateDown!=0){
+                                       ATUR_CHAN_CURR_TX_RATE_FLAG_MAKECMV;
+                                       if(meiCMV(TxMessage, YES_REPLY)!=MEI_SUCCESS){
+#ifdef AMAZON_MEI_DEBUG_ON
+                                               printk("\n\nCMV fail, Group 6 Address 0 Index 0");
+#endif                 
+                                       }
+                                       else{
+                                               temp = (u32)(RxMessage[4]) + (((u32)(RxMessage[5]))<<16); 
+                                               if((AlarmConfProfile.adslAturThreshFastRateUp!=0) && (temp>=PrevTxRate.adslAturChanPrevTxRate+AlarmConfProfile.adslAturThreshFastRateUp)){
+                                                       trapsflag|=ATUR_RATE_CHANGE_FLAG;
+                                                       PrevTxRate.adslAturChanPrevTxRate = temp;                                               
+                                               }
+                                               if((AlarmConfProfile.adslAturThreshFastRateDown!=0) && (temp<=PrevTxRate.adslAturChanPrevTxRate-AlarmConfProfile.adslAturThreshFastRateDown)){
+                                                       trapsflag|=ATUR_RATE_CHANGE_FLAG;
+                                                       PrevTxRate.adslAturChanPrevTxRate = temp;                                               
+                                               }
+                                       }
+                               }
+                       }       
+                       if(chantype.interleave==1){
+                               if(AlarmConfProfile.adslAturThreshInterleaveRateUp!=0 || AlarmConfProfile.adslAturThreshInterleaveRateDown!=0){
+                                       ATUR_CHAN_CURR_TX_RATE_FLAG_MAKECMV;
+                                       if(meiCMV(TxMessage, YES_REPLY)!=MEI_SUCCESS){
+#ifdef AMAZON_MEI_DEBUG_ON
+                                               printk("\n\nCMV fail, Group 6 Address 0 Index 0");
+#endif                 
+                                       }
+                                       else{
+                                               temp = (u32)(RxMessage[4]) + (((u32)(RxMessage[5]))<<16);
+                                               if((AlarmConfProfile.adslAturThreshInterleaveRateUp!=0) && (temp>=PrevTxRate.adslAturChanPrevTxRate+AlarmConfProfile.adslAturThreshInterleaveRateUp)){
+                                                       trapsflag|=ATUR_RATE_CHANGE_FLAG;
+                                                       PrevTxRate.adslAturChanPrevTxRate = temp;                                               
+                                               }
+                                               if((AlarmConfProfile.adslAturThreshInterleaveRateDown!=0) && (temp<=PrevTxRate.adslAturChanPrevTxRate-AlarmConfProfile.adslAturThreshInterleaveRateDown)){
+                                                       trapsflag|=ATUR_RATE_CHANGE_FLAG;
+                                                       PrevTxRate.adslAturChanPrevTxRate = temp;                                               
+                                               }
+                                       }
+                               }
+                       }       
+                       copy_to_user((char *)lon, (char *)(&trapsflag), 2);
+                       
+                       up(&mei_sema);  
+                       break;
+                       
+#ifdef AMAZON_MEI_MIB_RFC3440
+               case ADSL_ATUR_EXT_TRAPS:
+                       trapsflag=0;
+                       if(AlarmConfProfileExt.adslAtucThreshold15MinFailedFastR!=0 && current_intvl->AtucPerfStatFailedFastR>=AlarmConfProfileExt.adslAtucThreshold15MinFailedFastR)
+                               trapsflag|=ATUC_15MIN_FAILED_FASTR_TRAP_FLAG;
+                       if(AlarmConfProfileExt.adslAtucThreshold15MinSesL!=0 && current_intvl->AtucPerfStatSesL>=AlarmConfProfileExt.adslAtucThreshold15MinSesL)
+                               trapsflag|=ATUC_15MIN_SESL_TRAP_FLAG;
+                       if(AlarmConfProfileExt.adslAtucThreshold15MinUasL!=0 && current_intvl->AtucPerfStatUasL>=AlarmConfProfileExt.adslAtucThreshold15MinUasL)
+                               trapsflag|=ATUC_15MIN_UASL_TRAP_FLAG;
+                       if(AlarmConfProfileExt.adslAturThreshold15MinSesL!=0 && current_intvl->AturPerfStatSesL>=AlarmConfProfileExt.adslAturThreshold15MinSesL)
+                               trapsflag|=ATUR_15MIN_SESL_TRAP_FLAG;
+                       if(AlarmConfProfileExt.adslAturThreshold15MinUasL!=0 && current_intvl->AturPerfStatUasL>=AlarmConfProfileExt.adslAturThreshold15MinUasL)
+                               trapsflag|=ATUR_15MIN_UASL_TRAP_FLAG;
+                       copy_to_user((char *)lon, (char *)(&trapsflag), 2);
+                       break;
+#endif
+
+// 603221:tc.chen start
+               case GET_ADSL_LINE_STATUS:
+                       if(down_interruptible(&mei_sema))
+                               return -ERESTARTSYS;
+                       
+                       pts.adslLineStatusInfo_pt = (adslLineStatusInfo *)kmalloc(sizeof(adslLineStatusInfo), GFP_KERNEL);
+                       copy_from_user((char *)pts.adslLineStatusInfo_pt, (char *)lon, sizeof(adslLineStatusInfo));
+                       
+                       if(IS_FLAG_SET((&(pts.adslLineStatusInfo_pt->flags)), LINE_STAT_MODEM_STATUS_FLAG)){
+                               LINE_STAT_MODEM_STATUS_FLAG_MAKECMV;
+                               if(meiCMV(TxMessage, YES_REPLY)!=MEI_SUCCESS){
+#ifdef AMAZON_MEI_DEBUG_ON
+                                       printk("\n\nCMV fail, Group STAT Address 0 Index 0");
+#endif
+                                       pts.adslLineStatusInfo_pt->adslModemStatus = 0; 
+                               }
+                               else{
+                                       pts.adslLineStatusInfo_pt->adslModemStatus = RxMessage[4];
+                               }
+                       }
+                       
+                       if(IS_FLAG_SET((&(pts.adslLineStatusInfo_pt->flags)), LINE_STAT_MODE_SEL_FLAG)){
+                               LINE_STAT_MODE_SEL_FLAG_MAKECMV;
+                               if(meiCMV(TxMessage, YES_REPLY)!=MEI_SUCCESS){
+#ifdef AMAZON_MEI_DEBUG_ON
+                                       printk("\n\nCMV fail, Group STAT Address 1 Index 0");
+#endif
+                                       pts.adslLineStatusInfo_pt->adslModeSelected = 0;        
+                               }
+                               else{
+                                       pts.adslLineStatusInfo_pt->adslModeSelected = RxMessage[4];
+                               }
+                       }
+                       
+                       if(IS_FLAG_SET((&(pts.adslLineStatusInfo_pt->flags)), LINE_STAT_TRELLCOD_ENABLE_FLAG)){
+                               LINE_STAT_TRELLCOD_ENABLE_FLAG_MAKECMV;
+                               if(meiCMV(TxMessage, YES_REPLY)!=MEI_SUCCESS){
+#ifdef AMAZON_MEI_DEBUG_ON
+                                       printk("\n\nCMV fail, Group OPTN Address 2 Index 0");
+#endif
+                                       pts.adslLineStatusInfo_pt->adslTrellisCodeEnable = 0;   
+                               }
+                               else{
+                                       
+                                       pts.adslLineStatusInfo_pt->adslTrellisCodeEnable = (RxMessage[4]>>13)&0x1==0x1?0:1;
+                               }
+                       }
+                       
+                       if(IS_FLAG_SET((&(pts.adslLineStatusInfo_pt->flags)), LINE_STAT_LATENCY_FLAG)){
+                               LINE_STAT_LATENCY_FLAG_MAKECMV;
+                               if(meiCMV(TxMessage, YES_REPLY)!=MEI_SUCCESS){
+#ifdef AMAZON_MEI_DEBUG_ON
+                                       printk("\n\nCMV fail, Group STAT Address 12 Index 0");
+#endif
+                                       pts.adslLineStatusInfo_pt->adslLatency = 0;     
+                               }
+                               else{
+                                       pts.adslLineStatusInfo_pt->adslLatency = RxMessage[4];
+                               }
+                       }
+                       
+                       copy_to_user((char *)lon, (char *)pts.adslLineStatusInfo_pt, sizeof(adslLineStatusInfo));
+                       kfree(pts.adslLineStatusInfo_pt);
+                       
+                       up(&mei_sema);
+                       break;
+
+
+               case GET_ADSL_LINE_RATE:
+                       if (showtime!=1)
+                               return -ERESTARTSYS;
+                       if(down_interruptible(&mei_sema))
+                               return -ERESTARTSYS;
+                       
+                       pts.adslLineRateInfo_pt = (adslLineRateInfo *)kmalloc(sizeof(adslLineRateInfo), GFP_KERNEL);
+                       copy_from_user((char *)pts.adslLineRateInfo_pt, (char *)lon, sizeof(adslLineRateInfo));
+                       
+                       if(IS_FLAG_SET((&(pts.adslLineRateInfo_pt->flags)), LINE_RATE_DATA_RATEDS_FLAG)){
+                               if (adsl_mode <=8 && adsl_mode_extend==0) // adsl mode
+                               {
+                                       if (chantype.interleave)
+                                               LINE_RATE_DATA_RATEDS_FLAG_ADSL1_LP0_MAKECMV;
+                                       else
+                                               LINE_RATE_DATA_RATEDS_FLAG_ADSL1_LP1_MAKECMV;
+                                               
+                                       if(meiCMV(TxMessage, YES_REPLY)!=MEI_SUCCESS){
+#ifdef AMAZON_MEI_DEBUG_ON
+                                               printk("\n\nCMV fail, Group RATE Address 1 Index 0");
+#endif
+                                               pts.adslLineRateInfo_pt->adslDataRateds = 0;    
+                                       }
+                                       else{
+                                               pts.adslLineRateInfo_pt->adslDataRateds = (u32)(RxMessage[4]) + (((u32)(RxMessage[5]))<<16);
+                                       }               
+                               }else  // adsl 2/2+
+                               {
+                                       unsigned long Mp,Lp,Tp,Rp,Kp,Bpn,DataRate,DataRate_remain;
+                                       Mp=Lp=Tp=Rp=Kp=Bpn=DataRate=DataRate_remain=0;
+                                       //// up stream data rate
+                                         
+                                           if (chantype.interleave)
+                                           {
+                                                   LINE_RATE_DATA_RATEUS_FLAG_ADSL2_LP_LP0_MAKECMV;
+                                                   if(meiCMV(TxMessage, YES_REPLY)!=MEI_SUCCESS){
+#ifdef AMAZON_MEI_DEBUG_ON
+                                                       printk("\n\nCMV fail, Group CNFG Address 25 Index 0");
+#endif
+                                                       Lp = 0; 
+                                                   }else
+                                                       Lp=RxMessage[4];
+                                  
+                                                   LINE_RATE_DATA_RATEUS_FLAG_ADSL2_RP_LP0_MAKECMV;
+                                                   if(meiCMV(TxMessage, YES_REPLY)!=MEI_SUCCESS){
+#ifdef AMAZON_MEI_DEBUG_ON
+                                                       printk("\n\nCMV fail, Group CNFG Address 23 Index 0");
+#endif
+                                                       Rp = 0; 
+                                                   }else
+                                                       Rp=RxMessage[4];
+                               
+                                                   LINE_RATE_DATA_RATEUS_FLAG_ADSL2_MP_LP0_MAKECMV;
+                                                   if(meiCMV(TxMessage, YES_REPLY)!=MEI_SUCCESS){
+#ifdef AMAZON_MEI_DEBUG_ON
+                                                       printk("\n\nCMV fail, Group CNFG Address 24 Index 0");
+#endif
+                                                       Mp = 0; 
+                                                   }else
+                                                       Mp=RxMessage[4];
+                               
+                                                   LINE_RATE_DATA_RATEUS_FLAG_ADSL2_TP_LP0_MAKECMV;
+                                                   if(meiCMV(TxMessage, YES_REPLY)!=MEI_SUCCESS){
+#ifdef AMAZON_MEI_DEBUG_ON
+                                                       printk("\n\nCMV fail, Group CNFG Address 26 Index 0");
+#endif
+                                                       Tp = 0; 
+                                                   }else
+                                                       Tp=RxMessage[4];
+                               
+                                                   LINE_RATE_DATA_RATEUS_FLAG_ADSL2_KP_LP0_MAKECMV;
+                                                   if(meiCMV(TxMessage, YES_REPLY)!=MEI_SUCCESS){
+#ifdef AMAZON_MEI_DEBUG_ON
+                                                       printk("\n\nCMV fail, Group CNFG Address 28 Index 0");
+#endif
+                                                       Kp = 0; 
+                                                   }else
+                                                   {
+                                                       Kp=RxMessage[4]+ RxMessage[5]+1;
+                                                       Bpn=RxMessage[4]+ RxMessage[5];
+                                                   }
+                                           }else
+                                           {
+                                                   LINE_RATE_DATA_RATEUS_FLAG_ADSL2_LP_LP1_MAKECMV;
+                                                   if(meiCMV(TxMessage, YES_REPLY)!=MEI_SUCCESS){
+#ifdef AMAZON_MEI_DEBUG_ON
+                                                       printk("\n\nCMV fail, Group CNFG Address 25 Index 1");
+#endif
+                                                       Lp = 0; 
+                                                   }else
+                                                       Lp=RxMessage[4];
+                                  
+                                                   LINE_RATE_DATA_RATEUS_FLAG_ADSL2_RP_LP1_MAKECMV;
+                                                   if(meiCMV(TxMessage, YES_REPLY)!=MEI_SUCCESS){
+#ifdef AMAZON_MEI_DEBUG_ON
+                                                       printk("\n\nCMV fail, Group CNFG Address 23 Index 1");
+#endif
+                                                       Rp = 0; 
+                                                   }else
+                                                       Rp=RxMessage[4];
+                               
+                                                   LINE_RATE_DATA_RATEUS_FLAG_ADSL2_MP_LP1_MAKECMV;
+                                                   if(meiCMV(TxMessage, YES_REPLY)!=MEI_SUCCESS){
+#ifdef AMAZON_MEI_DEBUG_ON
+                                                       printk("\n\nCMV fail, Group CNFG Address 24 Index 1");
+#endif
+                                                       Mp = 0; 
+                                                   }else
+                                                       Mp=RxMessage[4];
+                               
+                                                   LINE_RATE_DATA_RATEUS_FLAG_ADSL2_TP_LP1_MAKECMV;
+                                                   if(meiCMV(TxMessage, YES_REPLY)!=MEI_SUCCESS){
+#ifdef AMAZON_MEI_DEBUG_ON
+                                                       printk("\n\nCMV fail, Group CNFG Address 26 Index 1");
+#endif
+                                                       Tp = 0; 
+                                                   }else
+                                                       Tp=RxMessage[4];
+                               
+                                                   LINE_RATE_DATA_RATEUS_FLAG_ADSL2_KP_LP1_MAKECMV;
+                                                   if(meiCMV(TxMessage, YES_REPLY)!=MEI_SUCCESS){
+#ifdef AMAZON_MEI_DEBUG_ON
+                                                       printk("\n\nCMV fail, Group CNFG Address 28 Index 2");
+#endif
+                                                       Kp = 0; 
+                                                   }else
+                                                   {
+                                                       Kp=RxMessage[4]+ RxMessage[5]+1;
+                                                       Bpn=RxMessage[4]+ RxMessage[5];
+                                                   }
+                                           }
+                                           DataRate=((Tp*(Bpn+1)-1)*Mp*Lp*4)/(Tp*(Kp*Mp+Rp));
+                                           //DataRate_remain=((((Tp*(Bpn+1)-1)*Mp*Lp*4)%(Tp*(Kp*Mp+Rp)))*1000)/(Tp*(Kp*Mp+Rp));
+                                           //pts.adslLineRateInfo_pt->adslDataRateds = DataRate * 1000 + DataRate_remain;
+                                           pts.adslLineRateInfo_pt->adslDataRateds = DataRate;
+                               }               
+                       }
+                       
+                       if(IS_FLAG_SET((&(pts.adslLineRateInfo_pt->flags)), LINE_RATE_DATA_RATEUS_FLAG)){
+                               if (adsl_mode <=8 && adsl_mode_extend==0) // adsl mode
+                               {
+                                       if (chantype.interleave)
+                                               LINE_RATE_DATA_RATEUS_FLAG_ADSL1_LP0_MAKECMV;
+                                       else
+                                               LINE_RATE_DATA_RATEUS_FLAG_ADSL1_LP1_MAKECMV;
+                                               
+                                       if(meiCMV(TxMessage, YES_REPLY)!=MEI_SUCCESS){
+       #ifdef AMAZON_MEI_DEBUG_ON
+                                               printk("\n\nCMV fail, Group RATE Address 0 Index 0");
+       #endif
+                                               pts.adslLineRateInfo_pt->adslDataRateus = 0;    
+                                       }
+                                       else{
+                                               pts.adslLineRateInfo_pt->adslDataRateus = (u32)(RxMessage[4]) + (((u32)(RxMessage[5]))<<16);
+                                       }               
+                               }else  // adsl 2/2+
+                               {
+                                       unsigned long Mp,Lp,Tp,Rp,Kp,Bpn,DataRate,DataRate_remain;
+                                       Mp=Lp=Tp=Rp=Kp=Bpn=DataRate=DataRate_remain=0;
+                                       //// down stream data rate
+                                          
+                                           if (chantype.interleave)
+                                           {
+                                                   LINE_RATE_DATA_RATEDS_FLAG_ADSL2_LP_LP0_MAKECMV;
+                                                   if(meiCMV(TxMessage, YES_REPLY)!=MEI_SUCCESS){
+#ifdef AMAZON_MEI_DEBUG_ON
+                                                       printk("\n\nCMV fail, Group CNFG Address 14 Index 0");
+#endif
+                                                       Lp = 0; 
+                                                   }else
+                                                       Lp=RxMessage[4];
+                                  
+                                                   LINE_RATE_DATA_RATEDS_FLAG_ADSL2_RP_LP0_MAKECMV;
+                                                   if(meiCMV(TxMessage, YES_REPLY)!=MEI_SUCCESS){
+#ifdef AMAZON_MEI_DEBUG_ON
+                                                       printk("\n\nCMV fail, Group CNFG Address 12 Index 0");
+#endif
+                                                       Rp = 0; 
+                                                   }else
+                                                       Rp=RxMessage[4];
+                               
+                                                   LINE_RATE_DATA_RATEDS_FLAG_ADSL2_MP_LP0_MAKECMV;
+                                                   if(meiCMV(TxMessage, YES_REPLY)!=MEI_SUCCESS){
+#ifdef AMAZON_MEI_DEBUG_ON
+                                                       printk("\n\nCMV fail, Group CNFG Address 13 Index 0");
+#endif
+                                                       Mp = 0; 
+                                                   }else
+                                                       Mp=RxMessage[4];
+                               
+                                                   LINE_RATE_DATA_RATEDS_FLAG_ADSL2_TP_LP0_MAKECMV;
+                                                   if(meiCMV(TxMessage, YES_REPLY)!=MEI_SUCCESS){
+#ifdef AMAZON_MEI_DEBUG_ON
+                                                       printk("\n\nCMV fail, Group CNFG Address 15 Index 0");
+#endif
+                                                       Tp = 0; 
+                                                   }else
+                                                       Tp=RxMessage[4];
+                               
+                                                   LINE_RATE_DATA_RATEDS_FLAG_ADSL2_KP_LP0_MAKECMV;
+                                                   if(meiCMV(TxMessage, YES_REPLY)!=MEI_SUCCESS){
+#ifdef AMAZON_MEI_DEBUG_ON
+                                                       printk("\n\nCMV fail, Group CNFG Address 17 Index 0");
+#endif
+                                                       Kp = 0; 
+                                                   }else
+                                                   {
+                                                       Kp=RxMessage[4]+ RxMessage[5]+1;
+                                                       Bpn=RxMessage[4]+ RxMessage[5];
+                                                   }
+                                           }else
+                                           {
+                                                   LINE_RATE_DATA_RATEDS_FLAG_ADSL2_LP_LP1_MAKECMV;
+                                                   if(meiCMV(TxMessage, YES_REPLY)!=MEI_SUCCESS){
+#ifdef AMAZON_MEI_DEBUG_ON
+                                                       printk("\n\nCMV fail, Group CNFG Address 14 Index 1");
+#endif
+                                                       Lp = 0; 
+                                                   }else
+                                                       Lp=RxMessage[4];
+                                  
+                                                   LINE_RATE_DATA_RATEDS_FLAG_ADSL2_RP_LP1_MAKECMV;
+                                                   if(meiCMV(TxMessage, YES_REPLY)!=MEI_SUCCESS){
+#ifdef AMAZON_MEI_DEBUG_ON
+                                                       printk("\n\nCMV fail, Group CNFG Address 12 Index 1");
+#endif
+                                                       Rp = 0; 
+                                                   }else
+                                                       Rp=RxMessage[4];
+                               
+                                                   LINE_RATE_DATA_RATEDS_FLAG_ADSL2_MP_LP1_MAKECMV;
+                                                   if(meiCMV(TxMessage, YES_REPLY)!=MEI_SUCCESS){
+#ifdef AMAZON_MEI_DEBUG_ON
+                                                       printk("\n\nCMV fail, Group CNFG Address 13 Index 1");
+#endif
+                                                       Mp = 0; 
+                                                   }else
+                                                       Mp=RxMessage[4];
+                               
+                                                   LINE_RATE_DATA_RATEDS_FLAG_ADSL2_TP_LP1_MAKECMV;
+                                                   if(meiCMV(TxMessage, YES_REPLY)!=MEI_SUCCESS){
+#ifdef AMAZON_MEI_DEBUG_ON
+                                                       printk("\n\nCMV fail, Group CNFG Address 15 Index 1");
+#endif
+                                                       Tp = 0; 
+                                                   }else
+                                                       Tp=RxMessage[4];
+                               
+                                                   LINE_RATE_DATA_RATEDS_FLAG_ADSL2_KP_LP1_MAKECMV;
+                                                   if(meiCMV(TxMessage, YES_REPLY)!=MEI_SUCCESS){
+#ifdef AMAZON_MEI_DEBUG_ON
+                                                       printk("\n\nCMV fail, Group CNFG Address 17 Index 2");
+#endif
+                                                       Kp = 0; 
+                                                   }else
+                                                   {
+                                                       Kp=RxMessage[4]+ RxMessage[5]+1;
+                                                       Bpn=RxMessage[4]+ RxMessage[5];
+                                                   }
+                                           }
+                                           DataRate=((Tp*(Bpn+1)-1)*Mp*Lp*4)/(Tp*(Kp*Mp+Rp));
+                                           //DataRate_remain=((((Tp*(Bpn+1)-1)*Mp*Lp*4)%(Tp*(Kp*Mp+Rp)))*1000)/(Tp*(Kp*Mp+Rp));
+                                           //pts.adslLineRateInfo_pt->adslDataRateus = DataRate * 1000 + DataRate_remain;
+                                           pts.adslLineRateInfo_pt->adslDataRateus = DataRate;
+                               }               
+                       }
+                       
+                       if(IS_FLAG_SET((&(pts.adslLineRateInfo_pt->flags)), LINE_RATE_ATTNDRDS_FLAG)){
+                               LINE_RATE_ATTNDRDS_FLAG_MAKECMV;
+                               if(meiCMV(TxMessage, YES_REPLY)!=MEI_SUCCESS){
+#ifdef AMAZON_MEI_DEBUG_ON
+                                       printk("\n\nCMV fail, Group INFO Address 68 Index 4");
+#endif
+                                       pts.adslLineRateInfo_pt->adslATTNDRds = 0;      
+                               }
+                               else{
+                                       pts.adslLineRateInfo_pt->adslATTNDRds = (u32)(RxMessage[4]) + (((u32)(RxMessage[5]))<<16);
+                               }
+                       }
+                       
+                       if(IS_FLAG_SET((&(pts.adslLineRateInfo_pt->flags)), LINE_RATE_ATTNDRUS_FLAG)){
+                               if (adsl_mode <=8 && adsl_mode_extend==0) // adsl mode
+                               {
+                                       LINE_RATE_ATTNDRUS_FLAG_MAKECMV;
+                                       if(meiCMV(TxMessage, YES_REPLY)!=MEI_SUCCESS){
+       #ifdef AMAZON_MEI_DEBUG_ON
+                                               printk("\n\nCMV fail, Group INFO Address 69 Index 4");
+       #endif
+                                               pts.adslLineRateInfo_pt->adslATTNDRus = 0;      
+                                       }
+                                       else{
+                                               pts.adslLineRateInfo_pt->adslATTNDRus = (u32)(RxMessage[4]) + (((u32)(RxMessage[5]))<<16);
+                                       }
+                               }else
+                               {
+                                       hdlc_cmd[0]=0x0181;
+                                       hdlc_cmd[1]=0x24;
+                                       up(&mei_sema);
+                                       if (ifx_me_hdlc_send((unsigned char *)&hdlc_cmd[0],4)!= -EBUSY)
+                                       {
+                                               set_current_state(TASK_INTERRUPTIBLE);
+                                               schedule_timeout(1);            
+                                               hdlc_rx_len=0;                  
+                                               hdlc_rx_len = ifx_mei_hdlc_read(&hdlc_rx_buffer,32*2);
+                                               if (hdlc_rx_len <=0)
+                                               {
+                                                       meierr = -ERESTARTSYS;
+                                                       goto GET_ADSL_LINE_RATE_END;
+                                               }
+                                               pts.adslLineRateInfo_pt->adslATTNDRus = (u32)le16_to_cpu(hdlc_rx_buffer[1])<<16 | (u32)le16_to_cpu(hdlc_rx_buffer[2]);
+                                       }
+                                       if(down_interruptible(&mei_sema))
+                                       {
+                                               meierr = -ERESTARTSYS;
+                                               goto GET_ADSL_LINE_RATE_END;
+                                       }
+                               }
+                       }       
+                       copy_to_user((char *)lon, (char *)pts.adslLineRateInfo_pt, sizeof(adslLineRateInfo));
+                       up(&mei_sema);
+                       
+GET_ADSL_LINE_RATE_END:                                                
+                       kfree(pts.adslLineRateInfo_pt);
+                       break;
+
+               case GET_ADSL_LINE_INFO:
+                       if (showtime!=1)
+                               return -ERESTARTSYS;
+                       if(down_interruptible(&mei_sema))
+                               return -ERESTARTSYS;
+                       
+                       pts.adslLineInfo_pt = (adslLineInfo *)kmalloc(sizeof(adslLineInfo), GFP_KERNEL);
+                       copy_from_user((char *)pts.adslLineInfo_pt, (char *)lon, sizeof(adslLineInfo));
+                       
+                       if(IS_FLAG_SET((&(pts.adslLineInfo_pt->flags)), LINE_INFO_INTLV_DEPTHDS_FLAG)){
+                               if (chantype.interleave)
+                                       LINE_INFO_INTLV_DEPTHDS_FLAG_LP0_MAKECMV;
+                               else
+                                       LINE_INFO_INTLV_DEPTHDS_FLAG_LP1_MAKECMV;
+                                       
+                               if(meiCMV(TxMessage, YES_REPLY)!=MEI_SUCCESS){
+#ifdef AMAZON_MEI_DEBUG_ON
+                                       printk("\n\nCMV fail, Group CNFG Address 27 Index 0");
+#endif
+                                       pts.adslLineInfo_pt->adslInterleaveDepthds = 0; 
+                               }
+                               else{
+                                       pts.adslLineInfo_pt->adslInterleaveDepthds = RxMessage[4];
+                               }                               
+                       }
+                       
+                       if(IS_FLAG_SET((&(pts.adslLineInfo_pt->flags)), LINE_INFO_INTLV_DEPTHUS_FLAG)){
+                               if (chantype.interleave)
+                                       LINE_INFO_INTLV_DEPTHUS_FLAG_LP0_MAKECMV;
+                               else
+                                       LINE_INFO_INTLV_DEPTHUS_FLAG_LP1_MAKECMV;
+                                       
+                               if(meiCMV(TxMessage, YES_REPLY)!=MEI_SUCCESS){
+#ifdef AMAZON_MEI_DEBUG_ON
+                                       printk("\n\nCMV fail, Group CNFG Address 16 Index 0");
+#endif
+                                       pts.adslLineInfo_pt->adslInterleaveDepthus = 0; 
+                               }
+                               else{
+                                       pts.adslLineInfo_pt->adslInterleaveDepthus = RxMessage[4];
+                               }                               
+                       }
+                       
+                       if(IS_FLAG_SET((&(pts.adslLineInfo_pt->flags)), LINE_INFO_LATNDS_FLAG)){
+                               LINE_INFO_LATNDS_FLAG_MAKECMV;
+                               if(meiCMV(TxMessage, YES_REPLY)!=MEI_SUCCESS){
+#ifdef AMAZON_MEI_DEBUG_ON
+                                       printk("\n\nCMV fail, Group INFO Address 68 Index 1");
+#endif
+                                       pts.adslLineInfo_pt->adslLATNds = 0;    
+                               }
+                               else{
+                                       pts.adslLineInfo_pt->adslLATNds = RxMessage[4];
+                               }
+                       }
+                       
+                       if(IS_FLAG_SET((&(pts.adslLineInfo_pt->flags)), LINE_INFO_LATNUS_FLAG)){
+                               if (adsl_mode <=8 && adsl_mode_extend==0) // adsl mode
+                               {
+                                       LINE_INFO_LATNUS_FLAG_MAKECMV;
+                                       if(meiCMV(TxMessage, YES_REPLY)!=MEI_SUCCESS){
+#ifdef AMAZON_MEI_DEBUG_ON
+                                               printk("\n\nCMV fail, Group INFO Address 69 Index 1");
+#endif
+                                               pts.adslLineInfo_pt->adslLATNus = 0;    
+                                       }
+                                       else{
+                                               pts.adslLineInfo_pt->adslLATNus = RxMessage[4];
+                                       }
+                               }else
+                               {
+                                       hdlc_cmd[0]=0x0181;
+                                       hdlc_cmd[1]=0x21;
+                                       up(&mei_sema);
+                                       if (ifx_me_hdlc_send((unsigned char *)&hdlc_cmd[0],4)!= -EBUSY)
+                                       {
+                                               set_current_state(TASK_INTERRUPTIBLE);
+                                               schedule_timeout(1);            
+                                               hdlc_rx_len=0;                  
+                                               hdlc_rx_len = ifx_mei_hdlc_read(&hdlc_rx_buffer,32*2);
+                                               if (hdlc_rx_len <=0)
+                                               {
+                                                       meierr = -ERESTARTSYS;
+                                                       goto GET_ADSL_LINE_INFO_END;
+                                               }
+                                               pts.adslLineInfo_pt->adslLATNus = le16_to_cpu(hdlc_rx_buffer[1]);
+                                       }
+                                       if(down_interruptible(&mei_sema))
+                                       {
+                                               meierr = -ERESTARTSYS;
+                                               goto GET_ADSL_LINE_INFO_END;
+                                       }
+                               }
+                       }
+                       
+                       if(IS_FLAG_SET((&(pts.adslLineInfo_pt->flags)), LINE_INFO_SATNDS_FLAG)){
+                               LINE_INFO_SATNDS_FLAG_MAKECMV;
+                               if(meiCMV(TxMessage, YES_REPLY)!=MEI_SUCCESS){
+#ifdef AMAZON_MEI_DEBUG_ON
+                                       printk("\n\nCMV fail, Group INFO Address 68 Index 2");
+#endif
+                                       pts.adslLineInfo_pt->adslSATNds = 0;    
+                               }
+                               else{
+                                       pts.adslLineInfo_pt->adslSATNds = RxMessage[4];
+                               }
+                       }
+                       
+                       if(IS_FLAG_SET((&(pts.adslLineInfo_pt->flags)), LINE_INFO_SATNUS_FLAG)){
+                               if (adsl_mode <=8 && adsl_mode_extend==0) // adsl mode
+                               {
+                                       LINE_INFO_SATNUS_FLAG_MAKECMV;
+                                       if(meiCMV(TxMessage, YES_REPLY)!=MEI_SUCCESS){
+#ifdef AMAZON_MEI_DEBUG_ON
+                                               printk("\n\nCMV fail, Group INFO Address 69 Index 2");
+#endif
+                                               pts.adslLineInfo_pt->adslSATNus = 0;    
+                                       }
+                                       else{
+                                               pts.adslLineInfo_pt->adslSATNus = RxMessage[4];
+                                       }
+                               }else
+                               {
+                                       hdlc_cmd[0]=0x0181;
+                                       hdlc_cmd[1]=0x22;
+                                       up(&mei_sema);
+                                       if (ifx_me_hdlc_send((unsigned char *)&hdlc_cmd[0],4)!= -EBUSY)
+                                       {
+                                               set_current_state(TASK_INTERRUPTIBLE);
+                                               schedule_timeout(1);            
+                                               hdlc_rx_len=0;                  
+                                               hdlc_rx_len = ifx_mei_hdlc_read(&hdlc_rx_buffer,32*2);
+                                               if (hdlc_rx_len <=0)
+                                               {
+                                                       meierr = -ERESTARTSYS;
+                                                       goto GET_ADSL_LINE_INFO_END;
+                                               }
+                                               pts.adslLineInfo_pt->adslSATNus = le16_to_cpu(hdlc_rx_buffer[1]);
+                                       }
+                                       if(down_interruptible(&mei_sema))
+                                       {
+                                               meierr = -ERESTARTSYS;
+                                               goto GET_ADSL_LINE_INFO_END;
+                                       }
+                               }
+                       }
+                       
+                       if(IS_FLAG_SET((&(pts.adslLineInfo_pt->flags)), LINE_INFO_SNRMNDS_FLAG)){
+                               if (adsl_mode <=8 && adsl_mode_extend==0) // adsl mode
+                               {
+                                       LINE_INFO_SNRMNDS_FLAG_ADSL1_MAKECMV;
+                               }
+                               else if ((adsl_mode == 0x4000) || (adsl_mode == 0x8000) || adsl_mode_extend > 0)
+                               {
+                                       LINE_INFO_SNRMNDS_FLAG_ADSL2PLUS_MAKECMV;
+                               }
+                               else
+                               {
+                                       LINE_INFO_SNRMNDS_FLAG_ADSL2_MAKECMV;
+                               }
+                               if(meiCMV(TxMessage, YES_REPLY)!=MEI_SUCCESS){
+#ifdef AMAZON_MEI_DEBUG_ON
+                                       printk("\n\nCMV fail, Group INFO Address 68 Index 3");
+#endif
+                                       pts.adslLineInfo_pt->adslSNRMds = 0;    
+                               }
+                               else{
+                                       if (adsl_mode>8 || adsl_mode_extend>0)
+                                       {
+                                               int SNRMds,SNRMds_remain;
+                                               SNRMds=RxMessage[4];    
+                                               SNRMds_remain=((SNRMds&0xff)*1000)/256;
+                                               SNRMds=(SNRMds>>8)&0xff;
+                                               if ((SNRMds_remain%100)>=50) SNRMds_remain=(SNRMds_remain/100)+1;
+                                               else  SNRMds_remain=(SNRMds_remain/100);
+                                               pts.adslLineInfo_pt->adslSNRMds = SNRMds*10 + SNRMds_remain;
+                                       }else
+                                       {
+                                               pts.adslLineInfo_pt->adslSNRMds = RxMessage[4];
+                                       }
+                               }
+                       }
+                       
+                       if(IS_FLAG_SET((&(pts.adslLineInfo_pt->flags)), LINE_INFO_SNRMNUS_FLAG)){
+                               if (adsl_mode <=8 && adsl_mode_extend == 0)
+                               {
+                                       LINE_INFO_SNRMNUS_FLAG_MAKECMV;
+                                       if(meiCMV(TxMessage, YES_REPLY)!=MEI_SUCCESS){
+#ifdef AMAZON_MEI_DEBUG_ON
+                                               printk("\n\nCMV fail, Group INFO Address 69 Index 3");
+#endif
+                                               pts.adslLineInfo_pt->adslSNRMus = 0;    
+                                       }
+                                       else{
+                                               pts.adslLineInfo_pt->adslSNRMus = RxMessage[4];
+                                       }
+                               }else
+                               {
+                                       hdlc_cmd[0]=0x0181;
+                                       hdlc_cmd[1]=0x23;
+                                       up(&mei_sema);
+                                       if (ifx_me_hdlc_send((unsigned char *)&hdlc_cmd[0],4)!= -EBUSY)
+                                       {
+                                               set_current_state(TASK_INTERRUPTIBLE);
+                                               schedule_timeout(1);            
+                                               hdlc_rx_len=0;                  
+                                               hdlc_rx_len = ifx_mei_hdlc_read(&hdlc_rx_buffer,32*2);
+                                               if (hdlc_rx_len <=0)
+                                               {
+                                                       meierr = -ERESTARTSYS;
+                                                       goto GET_ADSL_LINE_INFO_END;
+                                               }
+                                               pts.adslLineInfo_pt->adslSNRMus = le16_to_cpu(hdlc_rx_buffer[1]);
+                                       }
+                                       if(down_interruptible(&mei_sema))
+                                       {
+                                               meierr = -ERESTARTSYS;
+                                               goto GET_ADSL_LINE_INFO_END;
+                                       }
+                               }
+                       }
+                       
+                       if(IS_FLAG_SET((&(pts.adslLineInfo_pt->flags)), LINE_INFO_ACATPDS_FLAG)){
+                               if (adsl_mode <=8 && adsl_mode_extend == 0)
+                               {
+                                       LINE_INFO_ACATPDS_FLAG_MAKECMV;
+                                       if(meiCMV(TxMessage, YES_REPLY)!=MEI_SUCCESS){
+       #ifdef AMAZON_MEI_DEBUG_ON
+                                               printk("\n\nCMV fail, Group INFO Address 68 Index 6");
+       #endif
+                                               pts.adslLineInfo_pt->adslACATPds = 0;   
+                                       }
+                                       else{
+                                               pts.adslLineInfo_pt->adslACATPds = RxMessage[4];
+                                       }
+                               }else
+                               {
+                                       hdlc_cmd[0]=0x0181;
+                                       hdlc_cmd[1]=0x25;
+                                       up(&mei_sema);
+                                       if (ifx_me_hdlc_send((unsigned char *)&hdlc_cmd[0],4)!= -EBUSY)
+                                       {
+                                               set_current_state(TASK_INTERRUPTIBLE);
+                                               schedule_timeout(1);            
+                                               hdlc_rx_len=0;                  
+                                               hdlc_rx_len = ifx_mei_hdlc_read(&hdlc_rx_buffer,32*2);
+                                               if (hdlc_rx_len <=0)
+                                               {
+                                                       meierr = -ERESTARTSYS;
+                                                       goto GET_ADSL_LINE_INFO_END;
+                                               }
+                                               pts.adslLineInfo_pt->adslACATPds = le16_to_cpu(hdlc_rx_buffer[1]);
+                                       }
+                                       if(down_interruptible(&mei_sema))
+                                       {
+                                               meierr = -ERESTARTSYS;
+                                               goto GET_ADSL_LINE_INFO_END;
+                                       }
+                               }
+                       }
+                       
+                       if(IS_FLAG_SET((&(pts.adslLineInfo_pt->flags)), LINE_INFO_ACATPUS_FLAG)){
+                               if (adsl_mode <=8 && adsl_mode_extend == 0)
+                               {
+                                       LINE_INFO_ACATPUS_FLAG_MAKECMV;
+                                       if(meiCMV(TxMessage, YES_REPLY)!=MEI_SUCCESS){
+#ifdef AMAZON_MEI_DEBUG_ON
+                                               printk("\n\nCMV fail, Group INFO Address 69 Index 6");
+#endif
+                                               pts.adslLineInfo_pt->adslACATPus = 0;   
+                                       }
+                                       else{
+                                               pts.adslLineInfo_pt->adslACATPus = RxMessage[4];
+                                       }
+                               }else
+                               {
+                                       hdlc_cmd[0]=0x0181;
+                                       hdlc_cmd[1]=0x26;
+                                       up(&mei_sema);
+                                       if (ifx_me_hdlc_send((unsigned char *)&hdlc_cmd[0],4)!= -EBUSY)
+                                       {
+                                               set_current_state(TASK_INTERRUPTIBLE);
+                                               schedule_timeout(1);            
+                                               hdlc_rx_len=0;                  
+                                               hdlc_rx_len = ifx_mei_hdlc_read(&hdlc_rx_buffer,32*2);
+                                               if (hdlc_rx_len <=0)
+                                               {
+                                                       meierr = -ERESTARTSYS;
+                                                       goto GET_ADSL_LINE_INFO_END;
+                                               }
+                                               pts.adslLineInfo_pt->adslACATPus = le16_to_cpu(hdlc_rx_buffer[1]);
+                                       }
+                                       if(down_interruptible(&mei_sema))
+                                       {
+                                               meierr = -ERESTARTSYS;
+                                               goto GET_ADSL_LINE_INFO_END;
+                                       }
+                               }
+                       }
+                       
+                       copy_to_user((char *)lon, (char *)pts.adslLineInfo_pt, sizeof(adslLineInfo));
+                       up(&mei_sema);
+
+GET_ADSL_LINE_INFO_END:                        
+                       kfree(pts.adslLineInfo_pt);
+                       break;
+
+               case GET_ADSL_NEAREND_STATS:
+                       if (showtime!=1)
+                               return -ERESTARTSYS;
+                       if(down_interruptible(&mei_sema))
+                               return -ERESTARTSYS;
+                       
+                       pts.adslNearEndPerfStats_pt = (adslNearEndPerfStats *)kmalloc(sizeof(adslNearEndPerfStats), GFP_KERNEL);
+                       copy_from_user((char *)pts.adslNearEndPerfStats_pt, (char *)lon, sizeof(adslNearEndPerfStats));
+                       
+                       if(IS_FLAG_SET((&(pts.adslNearEndPerfStats_pt->flags)), NEAREND_PERF_SUPERFRAME_FLAG)){
+                               NEAREND_PERF_SUPERFRAME_FLAG_LSW_MAKECMV;
+                               if(meiCMV(TxMessage, YES_REPLY)!=MEI_SUCCESS){
+#ifdef AMAZON_MEI_DEBUG_ON
+                                       printk("\n\nCMV fail, Group PLAM Address 20 Index 0");
+#endif
+                                       pts.adslNearEndPerfStats_pt->adslSuperFrames = 0;       
+                               }
+                               else{
+                                       pts.adslNearEndPerfStats_pt->adslSuperFrames = (u32)(RxMessage[4]);
+                               }
+                               NEAREND_PERF_SUPERFRAME_FLAG_MSW_MAKECMV;
+                               if(meiCMV(TxMessage, YES_REPLY)!=MEI_SUCCESS){
+#ifdef AMAZON_MEI_DEBUG_ON
+                                       printk("\n\nCMV fail, Group PLAM Address 21 Index 0");
+#endif
+                                       pts.adslNearEndPerfStats_pt->adslSuperFrames = 0;       
+                               }
+                               else{
+                                       pts.adslNearEndPerfStats_pt->adslSuperFrames += (((u32)(RxMessage[4]))<<16);
+                               }
+                       }
+                       
+                       if(IS_FLAG_SET((&(pts.adslNearEndPerfStats_pt->flags)), NEAREND_PERF_LOS_FLAG) || 
+                          IS_FLAG_SET((&(pts.adslNearEndPerfStats_pt->flags)), NEAREND_PERF_LOF_FLAG) ||
+                          IS_FLAG_SET((&(pts.adslNearEndPerfStats_pt->flags)), NEAREND_PERF_LPR_FLAG) ||
+                          IS_FLAG_SET((&(pts.adslNearEndPerfStats_pt->flags)), NEAREND_PERF_NCD_FLAG) ||
+                          IS_FLAG_SET((&(pts.adslNearEndPerfStats_pt->flags)), NEAREND_PERF_LCD_FLAG) ){
+                               NEAREND_PERF_LOS_FLAG_MAKECMV;
+                               if(meiCMV(TxMessage, YES_REPLY)!=MEI_SUCCESS){
+#ifdef AMAZON_MEI_DEBUG_ON
+                                       printk("\n\nCMV fail, Group PLAM Address 0 Index 0");
+#endif                                 
+                                       RxMessage[4] = 0;
+                               }
+                               if(IS_FLAG_SET((&(pts.adslNearEndPerfStats_pt->flags)), NEAREND_PERF_LOS_FLAG)){
+                                       if( (RxMessage[4]&0x1) == 0x1)
+                                               pts.adslNearEndPerfStats_pt->adslneLOS = 1;
+                                       else
+                                               pts.adslNearEndPerfStats_pt->adslneLOS = 0;
+                               }
+                               
+                               if(IS_FLAG_SET((&(pts.adslNearEndPerfStats_pt->flags)), NEAREND_PERF_LOF_FLAG)){
+                                       if( (RxMessage[4]&0x2) == 0x2)
+                                               pts.adslNearEndPerfStats_pt->adslneLOF = 1;
+                                       else
+                                               pts.adslNearEndPerfStats_pt->adslneLOF = 0;
+                               }
+                               
+                               if(IS_FLAG_SET((&(pts.adslNearEndPerfStats_pt->flags)), NEAREND_PERF_LPR_FLAG)){
+                                       if( (RxMessage[4]&0x4) == 0x4)
+                                               pts.adslNearEndPerfStats_pt->adslneLPR = 1;
+                                       else
+                                               pts.adslNearEndPerfStats_pt->adslneLPR = 0;
+                               }
+                               
+                               if(IS_FLAG_SET((&(pts.adslNearEndPerfStats_pt->flags)), NEAREND_PERF_NCD_FLAG)){
+                                       pts.adslNearEndPerfStats_pt->adslneNCD = (RxMessage[4]>>4)&0x3;
+                               }
+                               
+                               if(IS_FLAG_SET((&(pts.adslNearEndPerfStats_pt->flags)), NEAREND_PERF_LCD_FLAG)){
+                                       pts.adslNearEndPerfStats_pt->adslneLCD = (RxMessage[4]>>6)&0x3;
+                               }
+                       }
+                                               
+                       if(IS_FLAG_SET((&(pts.adslNearEndPerfStats_pt->flags)), NEAREND_PERF_CRC_FLAG)){
+                               if (chantype.interleave)
+                                       NEAREND_PERF_CRC_FLAG_LP0_MAKECMV;
+                               else
+                                       NEAREND_PERF_CRC_FLAG_LP1_MAKECMV;
+                               if(meiCMV(TxMessage, YES_REPLY)!=MEI_SUCCESS){
+#ifdef AMAZON_MEI_DEBUG_ON
+                                       printk("\n\nCMV fail, Group PLAM Address 2 Index 0");
+#endif
+                                       pts.adslNearEndPerfStats_pt->adslneCRC = 0;     
+                               }
+                               else{
+                                       pts.adslNearEndPerfStats_pt->adslneCRC = (u32)(RxMessage[4]) + (((u32)(RxMessage[5]))<<16);
+                               }
+                       }
+                       
+                       if(IS_FLAG_SET((&(pts.adslNearEndPerfStats_pt->flags)), NEAREND_PERF_RSCORR_FLAG)){
+                               if (chantype.interleave)
+                                       NEAREND_PERF_RSCORR_FLAG_LP0_MAKECMV;
+                               else
+                                       NEAREND_PERF_RSCORR_FLAG_LP1_MAKECMV;
+                                       
+                               if(meiCMV(TxMessage, YES_REPLY)!=MEI_SUCCESS){
+#ifdef AMAZON_MEI_DEBUG_ON
+                                       printk("\n\nCMV fail, Group PLAM Address 3 Index 0");
+#endif
+                                       pts.adslNearEndPerfStats_pt->adslneRSCorr = 0;  
+                               }
+                               else{
+                                       pts.adslNearEndPerfStats_pt->adslneRSCorr = RxMessage[4];
+                               }
+                       }
+                       
+                       if(IS_FLAG_SET((&(pts.adslNearEndPerfStats_pt->flags)), NEAREND_PERF_FECS_FLAG)){
+                               NEAREND_PERF_FECS_FLAG_MAKECMV;
+                               if(meiCMV(TxMessage, YES_REPLY)!=MEI_SUCCESS){
+#ifdef AMAZON_MEI_DEBUG_ON
+                                       printk("\n\nCMV fail, Group PLAM Address 6 Index 0");
+#endif
+                                       pts.adslNearEndPerfStats_pt->adslneFECS = 0;    
+                               }
+                               else{
+                                       pts.adslNearEndPerfStats_pt->adslneFECS = RxMessage[4];
+                               }
+                       }
+                       
+                       if(IS_FLAG_SET((&(pts.adslNearEndPerfStats_pt->flags)), NEAREND_PERF_ES_FLAG)){
+                               NEAREND_PERF_ES_FLAG_MAKECMV;
+                               if(meiCMV(TxMessage, YES_REPLY)!=MEI_SUCCESS){
+#ifdef AMAZON_MEI_DEBUG_ON
+                                       printk("\n\nCMV fail, Group PLAM Address 7 Index 0");
+#endif
+                                       pts.adslNearEndPerfStats_pt->adslneES = 0;      
+                               }
+                               else{
+                                       pts.adslNearEndPerfStats_pt->adslneES = RxMessage[4];
+                               }
+                       }
+                       
+                       if(IS_FLAG_SET((&(pts.adslNearEndPerfStats_pt->flags)), NEAREND_PERF_SES_FLAG)){
+                               NEAREND_PERF_SES_FLAG_MAKECMV;
+                               if(meiCMV(TxMessage, YES_REPLY)!=MEI_SUCCESS){
+#ifdef AMAZON_MEI_DEBUG_ON
+                                       printk("\n\nCMV fail, Group PLAM Address 8 Index 0");
+#endif
+                                       pts.adslNearEndPerfStats_pt->adslneSES = 0;     
+                               }
+                               else{
+                                       pts.adslNearEndPerfStats_pt->adslneSES = RxMessage[4];
+                               }
+                       }
+                       
+                       if(IS_FLAG_SET((&(pts.adslNearEndPerfStats_pt->flags)), NEAREND_PERF_LOSS_FLAG)){
+                               NEAREND_PERF_LOSS_FLAG_MAKECMV;
+                               if(meiCMV(TxMessage, YES_REPLY)!=MEI_SUCCESS){
+#ifdef AMAZON_MEI_DEBUG_ON
+                                       printk("\n\nCMV fail, Group PLAM Address 9 Index 0");
+#endif
+                                       pts.adslNearEndPerfStats_pt->adslneLOSS = 0;    
+                               }
+                               else{
+                                       pts.adslNearEndPerfStats_pt->adslneLOSS = RxMessage[4];
+                               }
+                       }
+                       
+                       if(IS_FLAG_SET((&(pts.adslNearEndPerfStats_pt->flags)), NEAREND_PERF_UAS_FLAG)){
+                               NEAREND_PERF_UAS_FLAG_MAKECMV;
+                               if(meiCMV(TxMessage, YES_REPLY)!=MEI_SUCCESS){
+#ifdef AMAZON_MEI_DEBUG_ON
+                                       printk("\n\nCMV fail, Group PLAM Address 10 Index 0");
+#endif
+                                       pts.adslNearEndPerfStats_pt->adslneUAS = 0;     
+                               }
+                               else{
+                                       pts.adslNearEndPerfStats_pt->adslneUAS = RxMessage[4];
+                               }
+                       }
+                       
+                       if(IS_FLAG_SET((&(pts.adslNearEndPerfStats_pt->flags)), NEAREND_PERF_HECERR_FLAG)){
+                               if (chantype.bearchannel0)
+                               {
+                                       NEAREND_PERF_HECERR_FLAG_BC0_MAKECMV;
+                               }else if (chantype.bearchannel1)
+                               {
+                                       NEAREND_PERF_HECERR_FLAG_BC1_MAKECMV;
+                               }
+                               if(meiCMV(TxMessage, YES_REPLY)!=MEI_SUCCESS){
+#ifdef AMAZON_MEI_DEBUG_ON
+                                       printk("\n\nCMV fail, Group PLAM Address 11 Index 0");
+#endif
+                                       pts.adslNearEndPerfStats_pt->adslneHECErrors = 0;       
+                               }
+                               else{
+                                       pts.adslNearEndPerfStats_pt->adslneHECErrors = (u32)(RxMessage[4]) + (((u32)(RxMessage[5]))<<16);
+                               }
+                       }
+                       
+                       copy_to_user((char *)lon, (char *)pts.adslNearEndPerfStats_pt, sizeof(adslNearEndPerfStats));
+                       kfree(pts.adslNearEndPerfStats_pt);
+                       
+                       up(&mei_sema);
+                       break;
+
+               case GET_ADSL_FAREND_STATS:
+
+                       if (showtime!=1)
+                               return -ERESTARTSYS;
+                       
+                       if (adsl_mode>8 || adsl_mode_extend > 0)
+                       {
+                               do_gettimeofday(&time_now);
+                               if( FarendData_acquire_time.tv_sec==0 || time_now.tv_sec - FarendData_acquire_time.tv_sec>=1)
+                               {                                                               
+                                       hdlc_cmd[0]=0x105;
+                                       
+                                       if (ifx_me_hdlc_send((unsigned char *)&hdlc_cmd[0],2)!= -EBUSY)
+                                       {
+                                               set_current_state(TASK_INTERRUPTIBLE);
+                                               schedule_timeout(1);            
+                                               hdlc_rx_len=0;                  
+                                               hdlc_rx_len = ifx_mei_hdlc_read(&hdlc_rx_buffer,32*2);
+                                               if (hdlc_rx_len <=0)
+                                               {
+                                                       return -ERESTARTSYS;
+                                               }
+                                               FarendStatsData.adslfeRSCorr = ((u32)le16_to_cpu(hdlc_rx_buffer[1]) << 16) + (u32)le16_to_cpu(hdlc_rx_buffer[2]);
+                                               FarendStatsData.adslfeCRC = ((u32)le16_to_cpu(hdlc_rx_buffer[3]) << 16) + (u32)le16_to_cpu(hdlc_rx_buffer[4]);
+                                               FarendStatsData.adslfeFECS = ((u32)le16_to_cpu(hdlc_rx_buffer[5]) << 16) + (u32)le16_to_cpu(hdlc_rx_buffer[6]);
+                                               FarendStatsData.adslfeES = ((u32)le16_to_cpu(hdlc_rx_buffer[7]) << 16) + (u32)le16_to_cpu(hdlc_rx_buffer[8]);
+                                               FarendStatsData.adslfeSES = ((u32)le16_to_cpu(hdlc_rx_buffer[9]) << 16) + (u32)le16_to_cpu(hdlc_rx_buffer[10]);
+                                               FarendStatsData.adslfeLOSS = ((u32)le16_to_cpu(hdlc_rx_buffer[11]) << 16) + (u32)le16_to_cpu(hdlc_rx_buffer[12]);
+                                               FarendStatsData.adslfeUAS = ((u32)le16_to_cpu(hdlc_rx_buffer[13]) << 16) + (u32)le16_to_cpu(hdlc_rx_buffer[14]);
+                                               do_gettimeofday(&FarendData_acquire_time);
+                                       }
+                                       
+                               }
+                       }
+                       
+                       if(down_interruptible(&mei_sema))
+                               return -ERESTARTSYS;
+                       pts.adslFarEndPerfStats_pt = (adslFarEndPerfStats *)kmalloc(sizeof(adslFarEndPerfStats), GFP_KERNEL);
+                       copy_from_user((char *)pts.adslFarEndPerfStats_pt, (char *)lon, sizeof(adslFarEndPerfStats));
+                       if(IS_FLAG_SET((&(pts.adslFarEndPerfStats_pt->flags)), FAREND_PERF_LOS_FLAG) || 
+                          IS_FLAG_SET((&(pts.adslFarEndPerfStats_pt->flags)), FAREND_PERF_LOF_FLAG) ||
+                          IS_FLAG_SET((&(pts.adslFarEndPerfStats_pt->flags)), FAREND_PERF_LPR_FLAG) ||
+                          IS_FLAG_SET((&(pts.adslFarEndPerfStats_pt->flags)), FAREND_PERF_NCD_FLAG) ||
+                          IS_FLAG_SET((&(pts.adslFarEndPerfStats_pt->flags)), FAREND_PERF_LCD_FLAG) ){
+                               FAREND_PERF_LOS_FLAG_MAKECMV;
+                               if(meiCMV(TxMessage, YES_REPLY)!=MEI_SUCCESS){
+#ifdef AMAZON_MEI_DEBUG_ON
+                                       printk("\n\nCMV fail, Group PLAM Address 1 Index 0");
+#endif                                 
+                                       RxMessage[4] = 0;
+                               }
+                               if(IS_FLAG_SET((&(pts.adslFarEndPerfStats_pt->flags)), FAREND_PERF_LOS_FLAG)){
+                                       if((RxMessage[4]&0x1) == 0x1)
+                                               pts.adslFarEndPerfStats_pt->adslfeLOS = 1;
+                                       else
+                                               pts.adslFarEndPerfStats_pt->adslfeLOS = 0;
+                               }
+                               
+                               if(IS_FLAG_SET((&(pts.adslFarEndPerfStats_pt->flags)), FAREND_PERF_LOF_FLAG)){
+                                       if((RxMessage[4]&0x2) == 0x2)
+                                               pts.adslFarEndPerfStats_pt->adslfeLOF = 1;
+                                       else
+                                               pts.adslFarEndPerfStats_pt->adslfeLOF = 0;
+                               }
+                               
+                               if(IS_FLAG_SET((&(pts.adslFarEndPerfStats_pt->flags)), FAREND_PERF_LPR_FLAG)){
+                                       if((RxMessage[4]&0x4) == 0x4)
+                                               pts.adslFarEndPerfStats_pt->adslfeLPR = 1;
+                                       else
+                                               pts.adslFarEndPerfStats_pt->adslfeLPR = 0;
+                               }
+                               
+                               if(IS_FLAG_SET((&(pts.adslFarEndPerfStats_pt->flags)), FAREND_PERF_NCD_FLAG)){
+                                       pts.adslFarEndPerfStats_pt->adslfeNCD = (RxMessage[4]>>4)&0x3;
+                               }
+                               
+                               if(IS_FLAG_SET((&(pts.adslFarEndPerfStats_pt->flags)), FAREND_PERF_LCD_FLAG)){
+                                       pts.adslFarEndPerfStats_pt->adslfeLCD = (RxMessage[4]>>6)&0x3;
+                               }
+                       }
+                                               
+                       if(IS_FLAG_SET((&(pts.adslFarEndPerfStats_pt->flags)), FAREND_PERF_CRC_FLAG)){
+                               if (adsl_mode<=8 && adsl_mode_extend == 0)
+                               {
+                                       if (chantype.interleave)
+                                       {
+                                               FAREND_PERF_CRC_FLAG_LP0_MAKECMV;
+                                       }
+                                       else
+                                       {
+                                               FAREND_PERF_CRC_FLAG_LP1_MAKECMV;
+                                       }
+                                       if(meiCMV(TxMessage, YES_REPLY)!=MEI_SUCCESS){
+#ifdef AMAZON_MEI_DEBUG_ON
+                                               printk("\n\nCMV fail, Group PLAM Address 24 Index 0");
+#endif
+                                               pts.adslFarEndPerfStats_pt->adslfeCRC = 0;      
+                                       }
+                                       else{
+                                               pts.adslFarEndPerfStats_pt->adslfeCRC = RxMessage[4];                                   
+                                       }
+                               }else
+                               {
+                                       pts.adslFarEndPerfStats_pt->adslfeCRC = FarendStatsData.adslfeCRC;
+                               }
+                       }
+                       
+                       if(IS_FLAG_SET((&(pts.adslFarEndPerfStats_pt->flags)), FAREND_PERF_RSCORR_FLAG)){
+                               if (adsl_mode<=8 && adsl_mode_extend == 0)
+                               {
+                                       if (chantype.interleave)
+                                               FAREND_PERF_RSCORR_FLAG_LP0_MAKECMV;
+                                       else
+                                               FAREND_PERF_RSCORR_FLAG_LP1_MAKECMV;
+                                       if(meiCMV(TxMessage, YES_REPLY)!=MEI_SUCCESS){
+#ifdef AMAZON_MEI_DEBUG_ON
+                                               printk("\n\nCMV fail, Group PLAM Address 28 Index 0");
+#endif
+                                               pts.adslFarEndPerfStats_pt->adslfeRSCorr = 0;   
+                                       }
+                                       else{
+                                               pts.adslFarEndPerfStats_pt->adslfeRSCorr = RxMessage[4];
+                                               
+                                       }
+                               }
+                               else
+                               {
+                                       pts.adslFarEndPerfStats_pt->adslfeRSCorr = FarendStatsData.adslfeRSCorr;
+                               }
+                       }
+                       
+                       if(IS_FLAG_SET((&(pts.adslFarEndPerfStats_pt->flags)), FAREND_PERF_FECS_FLAG)){
+                               if (adsl_mode<=8 && adsl_mode_extend == 0)
+                               {
+                                       FAREND_PERF_FECS_FLAG_MAKECMV;
+                                       if(meiCMV(TxMessage, YES_REPLY)!=MEI_SUCCESS){
+#ifdef AMAZON_MEI_DEBUG_ON
+                                               printk("\n\nCMV fail, Group PLAM Address 32 Index 0");
+#endif
+                                               pts.adslFarEndPerfStats_pt->adslfeFECS = 0;     
+                                       }
+                                       else{
+                                               pts.adslFarEndPerfStats_pt->adslfeFECS = RxMessage[4];                                          
+                                       }
+                               }else {
+                                       pts.adslFarEndPerfStats_pt->adslfeFECS = FarendStatsData.adslfeFECS;
+                               }
+                       }
+                       
+                       if(IS_FLAG_SET((&(pts.adslFarEndPerfStats_pt->flags)), FAREND_PERF_ES_FLAG)){
+                               if (adsl_mode<=8 && adsl_mode_extend == 0)
+                               {
+                                       FAREND_PERF_ES_FLAG_MAKECMV;
+                                       if(meiCMV(TxMessage, YES_REPLY)!=MEI_SUCCESS){
+#ifdef AMAZON_MEI_DEBUG_ON
+                                               printk("\n\nCMV fail, Group PLAM Address 33 Index 0");
+#endif
+                                               pts.adslFarEndPerfStats_pt->adslfeES = 0;       
+                                       }
+                                       else{
+                                               pts.adslFarEndPerfStats_pt->adslfeES = RxMessage[4];                                            
+                                       }
+                               }else
+                               {
+                                       pts.adslFarEndPerfStats_pt->adslfeES = FarendStatsData.adslfeES;
+                               }
+                       }
+                       
+                       if(IS_FLAG_SET((&(pts.adslFarEndPerfStats_pt->flags)), FAREND_PERF_SES_FLAG)){
+                               if (adsl_mode<=8 && adsl_mode_extend == 0)
+                               {
+                                       FAREND_PERF_SES_FLAG_MAKECMV;
+                                       if(meiCMV(TxMessage, YES_REPLY)!=MEI_SUCCESS){
+#ifdef AMAZON_MEI_DEBUG_ON
+                                               printk("\n\nCMV fail, Group PLAM Address 34 Index 0");
+#endif
+                                               pts.adslFarEndPerfStats_pt->adslfeSES = 0;      
+                                       }
+                                       else{
+                                               pts.adslFarEndPerfStats_pt->adslfeSES = RxMessage[4];
+                                               
+                                       }
+                               }else
+                               {
+                                       pts.adslFarEndPerfStats_pt->adslfeSES = FarendStatsData.adslfeSES;
+                               }
+                       }
+                       
+                       if(IS_FLAG_SET((&(pts.adslFarEndPerfStats_pt->flags)), FAREND_PERF_LOSS_FLAG)){
+                               if (adsl_mode<=8 && adsl_mode_extend == 0)
+                               {
+                                       FAREND_PERF_LOSS_FLAG_MAKECMV;
+                                       if(meiCMV(TxMessage, YES_REPLY)!=MEI_SUCCESS){
+#ifdef AMAZON_MEI_DEBUG_ON
+                                               printk("\n\nCMV fail, Group PLAM Address 35 Index 0");
+#endif
+                                               pts.adslFarEndPerfStats_pt->adslfeLOSS = 0;     
+                                       }
+                                       else{
+                                               pts.adslFarEndPerfStats_pt->adslfeLOSS = RxMessage[4];
+                                               
+                                       }
+                               }else
+                               {
+                                       pts.adslFarEndPerfStats_pt->adslfeLOSS = FarendStatsData.adslfeLOSS;
+                               }
+                       }
+                       
+                       if(IS_FLAG_SET((&(pts.adslFarEndPerfStats_pt->flags)), FAREND_PERF_UAS_FLAG)){
+                               if (adsl_mode<=8 && adsl_mode_extend == 0)
+                               {
+                                       FAREND_PERF_UAS_FLAG_MAKECMV;
+                                       if(meiCMV(TxMessage, YES_REPLY)!=MEI_SUCCESS){
+#ifdef AMAZON_MEI_DEBUG_ON
+                                               printk("\n\nCMV fail, Group PLAM Address 36 Index 0");
+#endif
+                                               pts.adslFarEndPerfStats_pt->adslfeUAS = 0;      
+                                       }
+                                       else{
+                                               pts.adslFarEndPerfStats_pt->adslfeUAS = RxMessage[4];
+                                               
+                                       }
+                               }else
+                               {
+                                       pts.adslFarEndPerfStats_pt->adslfeUAS = FarendStatsData.adslfeUAS;
+                               }
+                       }
+                       
+                       if(IS_FLAG_SET((&(pts.adslFarEndPerfStats_pt->flags)), FAREND_PERF_HECERR_FLAG)){
+                               if (chantype.bearchannel0)
+                               {
+                                       FAREND_PERF_HECERR_FLAG_BC0_MAKECMV;
+                               }else if (chantype.bearchannel1)
+                               {
+                                       FAREND_PERF_HECERR_FLAG_BC1_MAKECMV;
+                               }
+                               if(meiCMV(TxMessage, YES_REPLY)!=MEI_SUCCESS){
+#ifdef AMAZON_MEI_DEBUG_ON
+                                       printk("\n\nCMV fail, Group PLAM Address 37 Index 0");
+#endif
+                                       pts.adslFarEndPerfStats_pt->adslfeHECErrors = 0;        
+                               }
+                               else{
+                                       pts.adslFarEndPerfStats_pt->adslfeHECErrors = (u32)(RxMessage[4]) + (((u32)(RxMessage[5]))<<16);
+                               }
+                       }
+                       
+                       copy_to_user((char *)lon, (char *)pts.adslFarEndPerfStats_pt, sizeof(adslFarEndPerfStats));             
+                       kfree(pts.adslFarEndPerfStats_pt);
+                       
+                       up(&mei_sema);
+                       
+                       break;
+// 603221:tc.chen end
+               case GET_ADSL_LOOP_DIAGNOSTICS_MODE:
+                       //lon = loop_diagnostics_mode;
+                       copy_to_user((char *)lon, (char *)&loop_diagnostics_mode, sizeof(int)); 
+                       break;
+//>> SHC
+               case IS_ADSL_LOOP_DIAGNOSTICS_MODE_COMPLETE:
+                       copy_to_user((char *)lon, (char *)&loop_diagnostics_completed, sizeof(int));    
+                       break;
+                       
+//<< end SHC
+               case LOOP_DIAGNOSTIC_MODE_COMPLETE:
+                       loop_diagnostics_completed = 1;
+                       // read adsl mode
+                       makeCMV(H2D_CMV_READ, STAT, 1, 0, 1, data); 
+                       if(meiCMV(TxMessage, YES_REPLY)!=MEI_SUCCESS){
+#ifdef AMAZON_MEI_DEBUG_ON
+                               printk("\n\nCMV fail, Group STAT Address 1 Index 0");
+#endif
+                       }
+                       adsl_mode = RxMessage[4];
+
+                       makeCMV(H2D_CMV_READ, STAT, 17, 0, 1, data); 
+                       if(meiCMV(TxMessage, YES_REPLY)!=MEI_SUCCESS){
+#ifdef AMAZON_MEI_DEBUG_ON
+                               printk("\n\nCMV fail, Group STAT Address 1 Index 0");
+#endif
+                       }
+                       adsl_mode_extend = RxMessage[4];
+                       wake_up_interruptible(&wait_queue_loop_diagnostic);     
+                       break;
+               case SET_ADSL_LOOP_DIAGNOSTICS_MODE:
+                       if (lon != loop_diagnostics_mode)
+                       {
+                               loop_diagnostics_completed = 0;
+                               loop_diagnostics_mode = lon;
+
+                               mei_ioctl((struct inode *)0,NULL, AMAZON_MEI_REBOOT, NULL);
+                               
+                       }
+                       break;
+               case GET_ADSL_ATUR_SUBCARRIER_STATS:
+                       if (loop_diagnostics_completed == 0)
+                       {
+                               interruptible_sleep_on_timeout(&wait_queue_loop_diagnostic,300*HZ);
+                               if (loop_diagnostics_completed==0)
+                               {
+                                       return -ERESTARTSYS;
+                               }
+                       }
+                       if(down_interruptible(&mei_sema))
+                               return -ERESTARTSYS;
+                               
+                       pts.adslATURSubcarrierInfo_pt = (adslATURSubcarrierInfo *)kmalloc(sizeof(adslATURSubcarrierInfo), GFP_KERNEL);
+                       copy_from_user((char *)pts.adslATURSubcarrierInfo_pt, (char *)lon, sizeof(adslATURSubcarrierInfo));
+                       
+                       if(IS_FLAG_SET((&(pts.adslATURSubcarrierInfo_pt->flags)),  FAREND_HLINSC)){
+                               FAREND_HLINSC_MAKECMV(H2D_CMV_READ);
+                               if(meiCMV(TxMessage, YES_REPLY)!=MEI_SUCCESS){
+#ifdef AMAZON_MEI_DEBUG_ON
+                                       printk("\n\nCMV fail, Group PLAM Address 35 Index 0");
+#endif
+                                       pts.adslATURSubcarrierInfo_pt->HLINSCds = 0;    
+                               }
+                               else{
+                                       pts.adslATURSubcarrierInfo_pt->HLINSCds = RxMessage[4];
+                                       
+                               }
+                       }
+                       if(IS_FLAG_SET((&(pts.adslATURSubcarrierInfo_pt->flags)),  FAREND_HLINPS)){
+                               int index=0,size=12;
+                               //printk("FAREND_HLINPS\n");
+                               for (index=0;index<1024;index+=size)
+                               {
+                                       if (index+size>=1024)
+                                               size = 1024-index;
+                                       FAREND_HLINPS_MAKECMV(H2D_CMV_READ,index,size);
+                                       if(meiCMV(TxMessage, YES_REPLY)!=MEI_SUCCESS){
+#ifdef AMAZON_MEI_DEBUG_ON
+                                               printk("\n\nCMV fail, Group PLAM Address 35 Index 0");
+#endif
+                                       }
+                                       else{
+                                               memcpy(&pts.adslATURSubcarrierInfo_pt->HLINpsds[index],&RxMessage[4],size*2);
+#if 0
+                                               int msg_idx;
+                                               for(msg_idx=0;msg_idx<size;msg_idx++)
+                                                       printk("index:%d ,cmv_result: %04X\n",index+msg_idx,RxMessage[4+msg_idx]);
+#endif
+                                       }
+                               }
+                       }
+                       
+                       if(IS_FLAG_SET((&(pts.adslATURSubcarrierInfo_pt->flags)),  FAREND_HLOGMT)){
+                               FAREND_HLOGMT_MAKECMV(H2D_CMV_READ);
+                               if(meiCMV(TxMessage, YES_REPLY)!=MEI_SUCCESS){
+#ifdef AMAZON_MEI_DEBUG_ON
+                                       printk("\n\nCMV fail, Group PLAM Address 35 Index 0");
+#endif
+                                       pts.adslATURSubcarrierInfo_pt->HLOGMTds = 0;    
+                               }
+                               else{
+                                       pts.adslATURSubcarrierInfo_pt->HLOGMTds = RxMessage[4];
+                                       
+                               }
+                       }
+                       
+                       /////////////////////////////////////////////////////////////////////////
+                       if(IS_FLAG_SET((&(pts.adslATURSubcarrierInfo_pt->flags)),  FAREND_HLOGPS)){
+                               //printk("FAREND_HLOGPS\n");
+                               int index=0,size=12;
+                               for (index=0;index<256;index+=size)
+                               {
+                                       if (index+size>=256)
+                                               size = 256-index;
+
+                                       FAREND_HLOGPS_MAKECMV(H2D_CMV_READ,index,size);
+                                       if(meiCMV(TxMessage, YES_REPLY)!=MEI_SUCCESS){
+#ifdef AMAZON_MEI_DEBUG_ON
+                                               printk("\n\nCMV fail, Group PLAM Address 35 Index 0");
+#endif
+                                       }
+                                       else{
+                                               if (adsl_mode < 0x4000 && adsl_mode_extend==0)//adsl2 mode
+                                               {
+                                                       memcpy(&pts.adslATURSubcarrierInfo_pt->HLOGpsds[index],&RxMessage[4],size*2);
+                                               }else
+                                               {
+                                                       int msg_idx=0;
+                                                       for (msg_idx=0;msg_idx<size;msg_idx++)
+                                                       {
+                                                               pts.adslATURSubcarrierInfo_pt->HLOGpsds[(index+msg_idx)*2+1] = RxMessage[4+msg_idx];
+                                                               //printk("index:%d ,cmv_result: %04X\n",index+msg_idx,RxMessage[4+msg_idx]);
+                                                       }
+                                               }       
+                                       }
+                               }
+                               if (adsl_mode >= 0x4000 || adsl_mode_extend >0)//adsl2+ mode
+                               {
+                                       pts.adslATURSubcarrierInfo_pt->HLOGpsds[0] = pts.adslATURSubcarrierInfo_pt->HLOGpsds[1];
+                                       for (index=1;index<256;index++)
+                                       {
+                                               pts.adslATURSubcarrierInfo_pt->HLOGpsds[index*2]   = (pts.adslATURSubcarrierInfo_pt->HLOGpsds[(index)*2-1] +  pts.adslATURSubcarrierInfo_pt->HLOGpsds[(index)*2+1] +1) >>1;
+                                       }
+                               }
+                       }
+                       if(IS_FLAG_SET((&(pts.adslATURSubcarrierInfo_pt->flags)),  FAREND_QLNMT)){
+                               FAREND_QLNMT_MAKECMV(H2D_CMV_READ);
+                               if(meiCMV(TxMessage, YES_REPLY)!=MEI_SUCCESS){
+#ifdef AMAZON_MEI_DEBUG_ON
+                                       printk("\n\nCMV fail, Group PLAM Address 35 Index 0");
+#endif
+                                       pts.adslATURSubcarrierInfo_pt->QLNMTds = 0;     
+                               }
+                               else{
+                                       pts.adslATURSubcarrierInfo_pt->QLNMTds = RxMessage[4];                                  
+                               }
+                       }
+                       
+                       /////////////////////////////////////////////////////////////////////////
+                       if(IS_FLAG_SET((&(pts.adslATURSubcarrierInfo_pt->flags)),  FAREND_QLNPS)){
+                               int index=0,size=12;
+                               //printk("FAREND_QLNPS\n");
+                               for (index=0;index<128;index+=size)
+                               {
+                                       if (index+size>=128)
+                                               size = 128-index;
+                                       FAREND_QLNPS_MAKECMV(H2D_CMV_READ,index,size);
+                                       if(meiCMV(TxMessage, YES_REPLY)!=MEI_SUCCESS){
+#ifdef AMAZON_MEI_DEBUG_ON
+                                               printk("\n\nCMV fail, Group PLAM Address 35 Index 0");
+#endif
+                                       }
+                                       else{
+                                               int msg_idx=0;
+                                               for (msg_idx=0;msg_idx<size;msg_idx++)
+                                               {
+                                                       //memcpy(&pts.adslATURSubcarrierInfo_pt->QLNpsds[index],&RxMessage[4],size*2);
+                                                       if (adsl_mode < 0x4000 && adsl_mode_extend==0)//adsl2 mode
+                                                       {
+                                                               pts.adslATURSubcarrierInfo_pt->QLNpsds[(index+msg_idx)*2] = (u16)(RxMessage[4+msg_idx]&0xFF);
+                                                               pts.adslATURSubcarrierInfo_pt->QLNpsds[(index+msg_idx)*2+1] = (u16)((RxMessage[4+msg_idx]>>8)&0xFF);
+                                                       }else
+                                                       {
+                                                               pts.adslATURSubcarrierInfo_pt->QLNpsds[(index+msg_idx)*4+1] = (u16)(RxMessage[4+msg_idx]&0xFF);
+                                                               pts.adslATURSubcarrierInfo_pt->QLNpsds[(index+msg_idx)*4+3] = (u16)((RxMessage[4+msg_idx]>>8)&0xFF);
+                                                               //printk("index:%d ,cmv_result: %04X\n",index+msg_idx,RxMessage[4+msg_idx]);
+                                                       }
+                                               }
+
+                                               
+                                       }
+                               }
+                               if (adsl_mode >= 0x4000 || adsl_mode_extend >0)//adsl2+ mode
+                               {
+                                       pts.adslATURSubcarrierInfo_pt->QLNpsds[0] = pts.adslATURSubcarrierInfo_pt->QLNpsds[1];
+                                       for (index=1;index<256;index++)
+                                       {
+                                               pts.adslATURSubcarrierInfo_pt->QLNpsds[index*2]   = (pts.adslATURSubcarrierInfo_pt->QLNpsds[(index)*2-1] +  pts.adslATURSubcarrierInfo_pt->QLNpsds[(index)*2+1]) >>1;
+                                       }
+                               }
+                       }
+                       if(IS_FLAG_SET((&(pts.adslATURSubcarrierInfo_pt->flags)),  FAREND_SNRMT)){
+                               FAREND_SNRMT_MAKECMV(H2D_CMV_READ);
+                               if(meiCMV(TxMessage, YES_REPLY)!=MEI_SUCCESS){
+#ifdef AMAZON_MEI_DEBUG_ON
+                                       printk("\n\nCMV fail, Group PLAM Address 35 Index 0");
+#endif
+                                       pts.adslATURSubcarrierInfo_pt->SNRMTds = 0;     
+                               }
+                               else{
+                                       pts.adslATURSubcarrierInfo_pt->SNRMTds = RxMessage[4];                                  
+                               }
+                       }
+                       if(IS_FLAG_SET((&(pts.adslATURSubcarrierInfo_pt->flags)),  FAREND_SNRPS)){
+                               int index=0,size=12;
+                               //printk("FAREND_SNRPS\n");
+                               for (index=0;index<512;index+=size)
+                               {
+                                       if (index+size>=512)
+                                               size = 512-index;
+                                       FAREND_SNRPS_MAKECMV(H2D_CMV_READ,index,size);
+                                       if(meiCMV(TxMessage, YES_REPLY)!=MEI_SUCCESS){
+#ifdef AMAZON_MEI_DEBUG_ON
+                                               printk("\n\nCMV fail, Group PLAM Address 35 Index 0");
+#endif
+                                       }
+                                       else{
+                                               //memcpy(&pts.adslATURSubcarrierInfo_pt->SNRpsds[index],&RxMessage[4],size*2);
+                                               int msg_idx=0;
+                                               for (msg_idx=0;msg_idx<size;msg_idx++)
+                                               {
+                                                       pts.adslATURSubcarrierInfo_pt->SNRpsds[index+msg_idx] = (u16)(RxMessage[4+msg_idx]&0xFF);
+                                                       //printk("index:%d ,cmv_result: %04X\n",index+msg_idx,RxMessage[4+msg_idx]);
+                                               }
+                                               
+                                       }
+                               }
+                       }
+                       if(IS_FLAG_SET((&(pts.adslATURSubcarrierInfo_pt->flags)),  FAREND_BITPS)){
+                               int index=0,size=12;
+                               //printk("FAREND_BITPS\n");
+                               for (index=0;index<256;index+=size)
+                               {
+                                       if (index+size>=256)
+                                               size = 256-index;
+                                       FAREND_BITPS_MAKECMV(H2D_CMV_READ,index,size);
+                                       if(meiCMV(TxMessage, YES_REPLY)!=MEI_SUCCESS){
+#ifdef AMAZON_MEI_DEBUG_ON
+                                               printk("\n\nCMV fail, Group PLAM Address 35 Index 0");
+#endif
+                                       }
+                                       else{
+                                               int msg_idx=0;
+                                               for (msg_idx=0;msg_idx<size;msg_idx++)
+                                               {
+                                                       pts.adslATURSubcarrierInfo_pt->BITpsds[(index+msg_idx)*2] = (u16)(RxMessage[4+msg_idx]&0xFF);
+                                                       pts.adslATURSubcarrierInfo_pt->BITpsds[(index+msg_idx)*2+1] = (u16)((RxMessage[4+msg_idx]>>8)&0xFF);
+                                                       //printk("index:%d ,cmv_result: %04X, %d\n",index+msg_idx,RxMessage[4+msg_idx],RxMessage[4+msg_idx]);
+                                                       
+                                               }
+                                               
+                                       }
+                               }
+                       }
+                       if(IS_FLAG_SET((&(pts.adslATURSubcarrierInfo_pt->flags)),  FAREND_GAINPS)){
+                               int index=0,size=12;
+                               //printk("FAREND_GAINPS\n");
+                               for (index=0;index<512;index+=size)
+                               {
+                                       FAREND_GAINPS_MAKECMV(H2D_CMV_READ,index,size);
+                                       if(meiCMV(TxMessage, YES_REPLY)!=MEI_SUCCESS){
+#ifdef AMAZON_MEI_DEBUG_ON
+                                               printk("\n\nCMV fail, Group PLAM Address 35 Index 0");
+#endif
+                                       }
+                                       else{
+                                       /*
+                                               int msg_idx=0;
+                                               for (msg_idx=0;msg_idx<size;msg_idx++)
+                                               {
+                                                       pts.adslATURSubcarrierInfo_pt->GAINpsds[(index+msg_idx)*2] = RxMessage[4+msg_idx]&0xFF;
+                                                       pts.adslATURSubcarrierInfo_pt->GAINpsds[(index+msg_idx)*2+1] = (RxMessage[4+msg_idx]>>8)&0xFF;
+                                                       
+                                               }
+                                               */
+                                               memcpy(&pts.adslATURSubcarrierInfo_pt->GAINpsds[index],&RxMessage[4],size*2);   
+#if 0
+                                               int msg_idx=0;
+                                               for (msg_idx=0;msg_idx<size;msg_idx++)
+                                               {
+                                                       printk("index:%d ,cmv_result: %04X\n",index+msg_idx,RxMessage[4+msg_idx]);
+                                                       
+                                               }
+#endif
+                                       }
+                               }
+                       }                               
+                       copy_to_user((char *)lon, (char *)pts.adslATURSubcarrierInfo_pt, sizeof(adslATURSubcarrierInfo));               
+                       kfree(pts.adslATURSubcarrierInfo_pt);
+                       
+                       up(&mei_sema);
+                       break;
+               case GET_ADSL_ATUC_SUBCARRIER_STATS:
+                       if (loop_diagnostics_completed == 0)
+                       {
+                               interruptible_sleep_on_timeout(&wait_queue_loop_diagnostic,300*HZ);
+                               if (loop_diagnostics_completed==0)
+                               {
+                                       return -ERESTARTSYS;
+                               }
+                       }
+                       if(down_interruptible(&mei_sema))
+                               return -ERESTARTSYS;
+                       pts.adslATUCSubcarrierInfo_pt = (adslATUCSubcarrierInfo *)kmalloc(sizeof(adslATUCSubcarrierInfo), GFP_KERNEL);
+                       copy_from_user((char *)pts.adslATUCSubcarrierInfo_pt, (char *)lon, sizeof(adslATUCSubcarrierInfo));
+                       
+                       
+                       if(IS_FLAG_SET((&(pts.adslATUCSubcarrierInfo_pt->flags)),  NEAREND_HLINSC)){
+                               NEAREND_HLINSC_MAKECMV(H2D_CMV_READ);
+                               if(meiCMV(TxMessage, YES_REPLY)!=MEI_SUCCESS){
+#ifdef AMAZON_MEI_DEBUG_ON
+                                       printk("\n\nCMV fail, Group INFO Address 71 Index 2");
+#endif
+                                       pts.adslATUCSubcarrierInfo_pt->HLINSCus = 0;    
+                               }
+                               else{
+                                       pts.adslATUCSubcarrierInfo_pt->HLINSCus = RxMessage[4];
+                                       
+                               }
+                       }
+                       if(IS_FLAG_SET((&(pts.adslATUCSubcarrierInfo_pt->flags)),  NEAREND_HLINPS)){
+                               int index=0,size=12;
+                               //printk("NEAREND_HLINPS\n");
+                               for (index=0;index<128;index+=size)
+                               {
+                                       if (index+size>=128)
+                                               size = 128-index;
+                                       NEAREND_HLINPS_MAKECMV(H2D_CMV_READ,index,size);
+                                       if(meiCMV(TxMessage, YES_REPLY)!=MEI_SUCCESS){
+#ifdef AMAZON_MEI_DEBUG_ON
+                                               printk("\n\nCMV fail, Group INFO Address 73 Index 0");
+#endif
+                                       }
+                                       else{
+                                               memcpy(&pts.adslATUCSubcarrierInfo_pt->HLINpsus[index],&RxMessage[4],size*2);
+#if 0
+                                               int msg_idx;
+                                               for (msg_idx=0;msg_idx<size;msg_idx++)
+                                               {
+                                                       printk("index:%d ,cmv_result: %04X\n",index+msg_idx,RxMessage[4+msg_idx]);
+                                               }
+#endif
+                                       }
+                               }
+                       }
+                       
+                       if(IS_FLAG_SET((&(pts.adslATUCSubcarrierInfo_pt->flags)),  NEAREND_HLOGMT)){
+                               NEAREND_HLOGMT_MAKECMV(H2D_CMV_READ);
+                               if(meiCMV(TxMessage, YES_REPLY)!=MEI_SUCCESS){
+#ifdef AMAZON_MEI_DEBUG_ON
+                                       printk("\n\nCMV fail, Group INFO Address 80 Index 0");
+#endif
+                                       pts.adslATUCSubcarrierInfo_pt->HLOGMTus = 0;    
+                               }
+                               else{
+                                       pts.adslATUCSubcarrierInfo_pt->HLOGMTus = RxMessage[4];
+                                       
+                               }
+                       }
+                       
+                       /////////////////////////////////////////////////////////////////////////
+                       if(IS_FLAG_SET((&(pts.adslATUCSubcarrierInfo_pt->flags)),  NEAREND_HLOGPS)){
+                               int index=0,size=12;
+                               //printk("NEAREND_HLOGPS\n");
+                               for (index=0;index<64;index+=size)
+                               {
+                                       if (index+size>=64)
+                                               size = 64-index;
+                                       NEAREND_HLOGPS_MAKECMV(H2D_CMV_READ,index,size);
+                                       if(meiCMV(TxMessage, YES_REPLY)!=MEI_SUCCESS){
+#ifdef AMAZON_MEI_DEBUG_ON
+                                               printk("\n\nCMV fail, Group INFO Address 75 Index 0");
+#endif
+                                       }
+                                       else{                                           
+#if 0
+                                               if (adsl_mode <0x4000)//adsl /adsl2 mode
+                                               {
+#endif
+                                               memcpy(&pts.adslATUCSubcarrierInfo_pt->HLOGpsus[index],&RxMessage[4],size*2);
+#if 0
+                                               }else
+                                               {
+                                                       int msg_idx=0;
+                                                       for (msg_idx=0;msg_idx<size;msg_idx++)
+                                                       {
+                                                               //pts.adslATUCSubcarrierInfo_pt->HLOGpsus[(index+msg_idx)*2+1] = RxMessage[4+msg_idx];
+                                                               pts.adslATUCSubcarrierInfo_pt->HLOGpsus[(index+msg_idx)] = RxMessage[4+msg_idx];
+                                                       }
+                                               }                                               
+#endif
+                                       }
+                               }
+#if 0
+                               if (adsl_mode >= 0x4000)//adsl2 mode
+                               {
+                                       pts.adslATUCSubcarrierInfo_pt->HLOGpsus[0] = pts.adslATUCSubcarrierInfo_pt->HLOGpsus[1];
+                                       for (index=1;index<64;index++)
+                                       {
+                                               pts.adslATUCSubcarrierInfo_pt->HLOGpsus[index*2]   = (pts.adslATUCSubcarrierInfo_pt->HLOGpsus[(index)*2-1] +  pts.adslATUCSubcarrierInfo_pt->HLOGpsus[(index)*2+1]) >>1;
+                                       }
+                               }
+#endif
+                       }
+                       if(IS_FLAG_SET((&(pts.adslATUCSubcarrierInfo_pt->flags)),  NEAREND_QLNMT)){
+                               NEAREND_QLNMT_MAKECMV(H2D_CMV_READ);
+                               if(meiCMV(TxMessage, YES_REPLY)!=MEI_SUCCESS){
+#ifdef AMAZON_MEI_DEBUG_ON
+                                       printk("\n\nCMV fail, Group INFO Address 80 Index 1");
+#endif
+                                       pts.adslATUCSubcarrierInfo_pt->QLNMTus = 0;     
+                               }
+                               else{
+                                       pts.adslATUCSubcarrierInfo_pt->QLNMTus = RxMessage[4];                                  
+                               }
+                       }
+                       
+                       /////////////////////////////////////////////////////////////////////////
+                       if(IS_FLAG_SET((&(pts.adslATUCSubcarrierInfo_pt->flags)),  NEAREND_QLNPS)){
+                               int index=0,size=12;
+                               //printk("NEAREND_QLNPS\n");
+                               for (index=0;index<32;index+=size)
+                               {
+                                       if (index+size>=32)
+                                               size = 32-index;
+                                       NEAREND_QLNPS_MAKECMV(H2D_CMV_READ,index,size);
+                                       if(meiCMV(TxMessage, YES_REPLY)!=MEI_SUCCESS){
+#ifdef AMAZON_MEI_DEBUG_ON
+                                               printk("\n\nCMV fail, Group INFO Address 77 Index 0");
+#endif
+                                       }
+                                       else{
+                                               int msg_idx=0;
+                                               for (msg_idx=0;msg_idx<size;msg_idx++)
+                                               {
+
+#if 0
+                                                       //memcpy(&pts.adslATUCSubcarrierInfo_pt->QLNpsds[index],&RxMessage[4],size*2);
+                                                       if (adsl_mode == 0x200 || adsl_mode == 0x800 || adsl_mode ==0x2000  || adsl_mode ==0x4000 || (adsl_mode == 0 && (adsl_mode_extend == 0x4 || adsl_mode_extend == 0x2))//ADSL 2 Annex B(0x200)/J(0x800)/M(0x2000) //ADSL 2+ B,J,M
+                                                       if (adsl_mode < 0x4000 && adsl_mode_extend==0)//adsl2 mode
+                                                       {
+                                                               pts.adslATUCSubcarrierInfo_pt->QLNpsus[(index+msg_idx)*4+1] = (u16)(RxMessage[4+msg_idx]&0xFF);
+                                                               pts.adslATUCSubcarrierInfo_pt->QLNpsus[(index+msg_idx)*4+3] = (u16)((RxMessage[4+msg_idx]>>8)&0xFF);
+                                                       }else
+#endif
+                                                       {
+                                                               pts.adslATUCSubcarrierInfo_pt->QLNpsus[(index+msg_idx)*2] = (u16)(RxMessage[4+msg_idx]&0xFF);
+                                                               pts.adslATUCSubcarrierInfo_pt->QLNpsus[(index+msg_idx)*2+1] = (u16)((RxMessage[4+msg_idx]>>8)&0xFF);
+                                                       //printk("index:%d ,cmv_result: %04X\n",index+msg_idx,RxMessage[4+msg_idx]);
+                                                       }
+                                               }
+
+                                               
+                                       }
+                               }
+#if 0
+                               //if (adsl_mode <0x4000)//Annex I/J/L/M
+                               if (adsl_mode == 0x200 || adsl_mode == 0x800 || adsl_mode ==0x2000  || adsl_mode ==0x4000 || (adsl_mode == 0 && (adsl_mode_extend == 0x4 || adsl_mode_extend == 0x2))//ADSL 2 Annex B(0x200)/J(0x800)/M(0x2000) //ADSL 2+ B,J,M
+                               {
+                                       pts.adslATUCSubcarrierInfo_pt->QLNpsus[0] = pts.adslATUCSubcarrierInfo_pt->QLNpsus[1];
+                                       for (index=1;index<64;index++)
+                                       {
+                                               pts.adslATUCSubcarrierInfo_pt->QLNpsus[index*2]   = (pts.adslATUCSubcarrierInfo_pt->QLNpsus[(index)*2-1] +  pts.adslATUCSubcarrierInfo_pt->QLNpsus[(index)*2+1]) >>1;
+                                       }
+                               }
+#endif
+                       }
+                       if(IS_FLAG_SET((&(pts.adslATUCSubcarrierInfo_pt->flags)),  NEAREND_SNRMT)){
+                               NEAREND_SNRMT_MAKECMV(H2D_CMV_READ);
+                               if(meiCMV(TxMessage, YES_REPLY)!=MEI_SUCCESS){
+#ifdef AMAZON_MEI_DEBUG_ON
+                                       printk("\n\nCMV fail, Group INFO Address 80 Index 2");
+#endif
+                                       pts.adslATUCSubcarrierInfo_pt->SNRMTus = 0;     
+                               }
+                               else{
+                                       pts.adslATUCSubcarrierInfo_pt->SNRMTus = RxMessage[4];                                  
+                               }
+                       }
+                       if(IS_FLAG_SET((&(pts.adslATUCSubcarrierInfo_pt->flags)),  NEAREND_SNRPS)){
+                               int index=0,size=12;
+                               //printk("NEAREND_SNRPS\n");
+                               for (index=0;index<64;index+=size)
+                               {
+                                       if (index+size>=64)
+                                               size = 64-index;
+                                       NEAREND_SNRPS_MAKECMV(H2D_CMV_READ,index,size);
+                                       if(meiCMV(TxMessage, YES_REPLY)!=MEI_SUCCESS){
+#ifdef AMAZON_MEI_DEBUG_ON
+                                               printk("\n\nCMV fail, Group INFO Address 78 Index 0");
+#endif
+                                       }
+                                       else{
+                                               //memcpy(&pts.adslATUCSubcarrierInfo_pt->SNRpsus[index],&RxMessage[4],size*2);
+                                               int msg_idx=0;
+                                               for (msg_idx=0;msg_idx<size;msg_idx++)
+                                               {
+                                                       pts.adslATUCSubcarrierInfo_pt->SNRpsus[index+msg_idx] = (u16)(RxMessage[4+msg_idx]&0xFF);
+                                                       //printk("index:%d ,cmv_result: %04X\n",index+msg_idx,RxMessage[4+msg_idx]);
+                                               }
+                                               
+                                       }
+                               }
+                       }
+                       if(IS_FLAG_SET((&(pts.adslATUCSubcarrierInfo_pt->flags)),  NEAREND_BITPS)){
+                               int index=0,size=12;
+                               //printk("NEAREND_BITPS\n");
+                               for (index=0;index<32;index+=size)
+                               {
+                                       if (index+size>=32)
+                                               size = 32-index;
+                                       NEAREND_BITPS_MAKECMV(H2D_CMV_READ,index,size);
+                                       if(meiCMV(TxMessage, YES_REPLY)!=MEI_SUCCESS){
+#ifdef AMAZON_MEI_DEBUG_ON
+                                               printk("\n\nCMV fail, Group INFO Address 22 Index 0");
+#endif
+                                       }
+                                       else{
+                                               int msg_idx=0;
+                                               for (msg_idx=0;msg_idx<size;msg_idx++)
+                                               {
+                                                       pts.adslATUCSubcarrierInfo_pt->BITpsus[(index+msg_idx)*2] = (u16)(RxMessage[4+msg_idx]&0xFF);
+                                                       pts.adslATUCSubcarrierInfo_pt->BITpsus[(index+msg_idx)*2+1] = (u16)((RxMessage[4+msg_idx]>>8)&0xFF);
+                                                       //printk("index:%d ,cmv_result: %04X\n",index+msg_idx,RxMessage[4+msg_idx]);
+                                               }
+                                               
+                                       }
+                               }
+                       }
+                       if(IS_FLAG_SET((&(pts.adslATUCSubcarrierInfo_pt->flags)),  NEAREND_GAINPS)){
+                               int index=0,size=12;
+                               //printk("NEAREND_GAINPS\n");
+                               for (index=0;index<64;index+=size)
+                               {
+                                       if (index+size>=64)
+                                               size = 64-index;
+                                       NEAREND_GAINPS_MAKECMV(H2D_CMV_READ,index,size);
+                                       if(meiCMV(TxMessage, YES_REPLY)!=MEI_SUCCESS){
+#ifdef AMAZON_MEI_DEBUG_ON
+                                               printk("\n\nCMV fail, Group INFO Address 24 Index 0");
+#endif
+                                       }
+                                       else{
+                                       /*
+                                               int msg_idx=0;
+                                               for (msg_idx=0;msg_idx<size;msg_idx++)
+                                               {
+                                                       pts.adslATUCSubcarrierInfo_pt->GAINpsds[(index+msg_idx)*2] = RxMessage[4+msg_idx]&0xFF;
+                                                       pts.adslATUCSubcarrierInfo_pt->GAINpsds[(index+msg_idx)*2+1] = (RxMessage[4+msg_idx]>>8)&0xFF;
+                                                       
+                                               }
+                                               */
+                                               memcpy(&pts.adslATUCSubcarrierInfo_pt->GAINpsus[index],&RxMessage[4],size*2);   
+#if 0
+                                               int msg_idx;
+                                               for (msg_idx=0;msg_idx<size;msg_idx++)
+                                               {
+                                                       printk("index:%d ,cmv_result: %04X\n",index+msg_idx,RxMessage[4+msg_idx]);
+                                               }
+#endif
+                                       }
+                               }
+                       }                               
+                       copy_to_user((char *)lon, (char *)pts.adslATUCSubcarrierInfo_pt, sizeof(adslATUCSubcarrierInfo));               
+                       kfree(pts.adslATUCSubcarrierInfo_pt);                   
+                       up(&mei_sema);
+                       break;
+               case GET_ADSL_LINE_INIT_STATS:                  
+                       copy_to_user((char *)lon, (char *)&AdslInitStatsData, sizeof(AdslInitStatsData));               
+                       break;
+               
+               case GET_ADSL_POWER_SPECTRAL_DENSITY:           
+                       if(down_interruptible(&mei_sema))
+                               return -ERESTARTSYS;
+                       i=0;
+                       pts.adslPowerSpectralDensity_pt = (adslPowerSpectralDensity *)kmalloc(sizeof(adslPowerSpectralDensity), GFP_KERNEL);
+                       memset((char *)pts.adslPowerSpectralDensity_pt, 0, sizeof(adslPowerSpectralDensity));   
+
+                       //US
+                       NOMPSD_US_MAKECMV;
+                       if(meiCMV(TxMessage, YES_REPLY)!=MEI_SUCCESS){
+#ifdef AMAZON_MEI_DEBUG_ON
+                               printk("\n\nCMV fail, Group PLAM Address 35 Index 0");
+#endif
+                               i=-1;
+                       }
+                       else{
+                               j=RxMessage[4];
+                       }
+                       PCB_US_MAKECMV;
+                       if(meiCMV(TxMessage, YES_REPLY)!=MEI_SUCCESS){
+#ifdef AMAZON_MEI_DEBUG_ON
+                               printk("\n\nCMV fail, Group PLAM Address 35 Index 0");
+#endif
+                               i=-1;
+                       }
+                       else{
+                               temp=RxMessage[4];
+                       }
+                       RMSGI_US_MAKECMV;
+                       if(meiCMV(TxMessage, YES_REPLY)!=MEI_SUCCESS){
+#ifdef AMAZON_MEI_DEBUG_ON
+                               printk("\n\nCMV fail, Group PLAM Address 35 Index 0");
+#endif
+                               i=-1;
+                       }
+                       else{
+                               k=(int16_t)RxMessage[4];
+                       }
+                       if (i==0)
+                       {
+                               pts.adslPowerSpectralDensity_pt->ACTPSDus = ((int )(j*256 - temp*10*256 + k*10)) /256;
+                       }
+                       // DS
+                       i=0;
+                       j=temp=temp2=0;
+                       NOMPSD_DS_MAKECMV;
+                       if(meiCMV(TxMessage, YES_REPLY)!=MEI_SUCCESS){
+#ifdef AMAZON_MEI_DEBUG_ON
+                               printk("\n\nCMV fail, Group PLAM Address 35 Index 0");
+#endif
+                               i=-1;
+                       }
+                       else{
+                               j=RxMessage[4];
+                       }
+                       PCB_DS_MAKECMV;
+                       if(meiCMV(TxMessage, YES_REPLY)!=MEI_SUCCESS){
+#ifdef AMAZON_MEI_DEBUG_ON
+                               printk("\n\nCMV fail, Group PLAM Address 35 Index 0");
+#endif
+                               i=-1;
+                       }
+                       else{
+                               temp=RxMessage[4];
+                       }
+                       RMSGI_DS_MAKECMV;
+                       if(meiCMV(TxMessage, YES_REPLY)!=MEI_SUCCESS){
+#ifdef AMAZON_MEI_DEBUG_ON
+                               printk("\n\nCMV fail, Group PLAM Address 35 Index 0");
+#endif
+                               i=-1;
+                       }
+                       else{
+                               //temp2=RxMessage[4];
+                               k=(int16_t)RxMessage[4];
+                       }
+                       if (i==0)
+                       {
+                               pts.adslPowerSpectralDensity_pt->ACTPSDds = ((int )(j*256 - temp*10*256 + k*10)) /256;
+                       }
+                       copy_to_user((char *)lon, (char *)pts.adslPowerSpectralDensity_pt, sizeof(adslPowerSpectralDensity));   
+                       kfree(pts.adslPowerSpectralDensity_pt);         
+                       up(&mei_sema);
+                       break;
+                case AMAZON_MEI_START:
+                       showtime=0;
+                       loop_diagnostics_completed = 0;
+#ifdef ARC_READY_ACK
+#ifdef LOCK_RETRY
+                       i=0;
+lock_retry:
+                       if(down_trylock(&mei_sema)!=0)
+                       {
+                               reboot_lock = 1;
+                               printk("lock fail\n");
+                               i++;
+                               if (i <=5)
+                               {
+                                       set_current_state(TASK_INTERRUPTIBLE);
+                                       schedule_timeout(10);
+                                       goto lock_retry;
+                               }else
+                               {
+                                       printk("Force to Reboot ADSL!\n");
+                                       up(&mei_sema);
+                                       set_current_state(TASK_INTERRUPTIBLE);
+                                       schedule_timeout(1000);
+                                       sema_init(&mei_sema, 1);  // semaphore initialization, mutex
+                               }
+                       }else
+                       {
+                               reboot_lock = 1;
+                       }
+#else
+                       if(down_interruptible(&mei_sema))       //disable CMV access until ARC ready
+                       {
+                               return -ERESTARTSYS;
+                       }
+#endif
+#endif
+                       //CLEAR_BIT((*((volatile u32 *)0xB0100B40)), 0x40); //Warning LED GPIO ON
+                       if(chantype.interleave==1){
+                               kfree(interleave_mei_net.priv);
+                               unregister_netdev(&interleave_mei_net);
+                       }
+                       else if(chantype.fast==1){
+                               kfree(fast_mei_net.priv);
+                               unregister_netdev(&fast_mei_net);
+                       }               
+                       chantype.interleave=0;
+                       chantype.fast=0;
+                       meiMailboxInterruptsDisable(); //disable all MEI interrupts
+                       if(mei_arc_swap_buff == NULL){
+                       mei_arc_swap_buff = (u32 *)kmalloc(MAXSWAPSIZE*4, GFP_KERNEL);
+                       if(mei_arc_swap_buff==NULL){
+#ifdef AMAZON_MEI_DEBUG_ON
+                               printk("\n\n malloc fail for codeswap buff");
+#endif
+                               meierr=MEI_FAILURE;
+                       }
+                       }
+                        if(meiForceRebootAdslModem() != MEI_SUCCESS){
+#ifdef AMAZON_MEI_DEBUG_ON
+                                printk("\n\n meiForceRebootAdslModem()  error...");
+#endif
+                                meierr=MEI_FAILURE;
+                        }     
+                       interruptible_sleep_on(&wait_queue_codeswap);
+                       // reset is called
+                        break;
+               case AMAZON_MEI_MIB_DAEMON:
+#ifdef IFX_SMALL_FOOTPRINT /* [ */
+                       return -1;
+#else /* ][ !IFX_SMALL_FOOTPRINT */
+                       i=0;
+                       while(1){
+                               if(i<MIB_INTERVAL)
+                                       interruptible_sleep_on_timeout(&wait_queue_mibdaemon, ((MIB_INTERVAL-i)/(1000/HZ)));
+                               i=0;
+                               if(showtime==1){
+//                                     printk("\n\n update mib");
+                                       
+                                       do_gettimeofday(&time_now);
+                                       if(time_now.tv_sec - current_intvl->start_time.tv_sec>=900){
+                                               if(current_intvl->list.next!=&interval_list){
+                                                       current_intvl = list_entry(current_intvl->list.next, amazon_mei_mib, list);
+                                                       do_gettimeofday(&(current_intvl->start_time));
+                                               }
+                                               else{
+                                                       mib_ptr = list_entry(interval_list.next, amazon_mei_mib, list);
+                                                       list_del(interval_list.next);
+                                                       memset(mib_ptr, 0, sizeof(amazon_mei_mib));
+                                                       list_add_tail(&(mib_ptr->list), &interval_list);
+                                                       if(current_intvl->list.next==&interval_list)
+#ifdef AMAZON_MEI_DEBUG_ON
+                                                               printk("\n\nlink list error");
+#endif
+                                                       current_intvl = list_entry(current_intvl->list.next, amazon_mei_mib, list);
+                                                       do_gettimeofday(&(current_intvl->start_time));
+                                               }       
+                                       }
+                                       
+                                       if(down_interruptible(&mei_sema))
+                                               return -ERESTARTSYS;
+/*                                             
+                                       ATUC_PERF_LO_FLAG_MAKECMV;
+                                       if(meiCMV(TxMessage, YES_REPLY)!=MEI_SUCCESS){
+#ifdef AMAZON_MEI_DEBUG_ON
+                                               printk("\n\nCMV fail, Group 7 Address 0 Index 0");
+#endif
+                                       }
+                                       else{
+                                               if(RxMessage[4]&PLAM_LOS_FailureBit){
+                                                       current_intvl->AtucPerfLos++;
+                                                       ATUC_PERF_LOSS++;
+                                                       CurrStatus.adslAtucCurrStatus = 2;
+                                               }
+                                               if(RxMessage[4]&PLAM_LOF_FailureBit){
+                                                       current_intvl->AtucPerfLof++;
+                                                       ATUC_PERF_LOFS++;
+                                                       CurrStatus.adslAtucCurrStatus = 1;
+                                               }
+                                               if(!(RxMessage[4]&(PLAM_LOS_FailureBit|PLAM_LOF_FailureBit)))
+                                                       CurrStatus.adslAtucCurrStatus = 0;
+                                       }
+*/
+                                       ATUC_PERF_ESS_FLAG_MAKECMV;
+                                       if(meiCMV(TxMessage, YES_REPLY)!=MEI_SUCCESS){
+#ifdef AMAZON_MEI_DEBUG_ON
+                                               printk("\n\nCMV fail, Group 7 Address 7 Index 0");
+#endif
+                                       }
+                                       else{
+                                               temp = RxMessage[4]-mib_pread.ATUC_PERF_ESS;
+                                               if(temp>=0){
+                                                       current_intvl->AtucPerfEs+=temp;
+                                                       ATUC_PERF_ESS+=temp;
+                                                       mib_pread.ATUC_PERF_ESS = RxMessage[4];
+                                               }
+                                               else{
+                                                       current_intvl->AtucPerfEs+=0xffff-mib_pread.ATUC_PERF_ESS+RxMessage[4];
+                                                       ATUC_PERF_ESS+=0xffff-mib_pread.ATUC_PERF_ESS+RxMessage[4];
+                                                       mib_pread.ATUC_PERF_ESS = RxMessage[4];         
+                                               }
+                                       }
+/*             
+                                       ATUR_PERF_LO_FLAG_MAKECMV;
+                                       if(meiCMV(TxMessage, YES_REPLY)!=MEI_SUCCESS){
+#ifdef AMAZON_MEI_DEBUG_ON
+                                               printk("\n\nCMV fail, Group 7 Address 1 Index 0");
+#endif
+                                       }
+                                       else{
+                                               if(RxMessage[4]&PLAM_LOS_FailureBit){
+                                                       current_intvl->AturPerfLos++;
+                                                       ATUR_PERF_LOSS++;
+                                                       CurrStatus.adslAturCurrStatus = 2;
+                                               }
+                                               if(RxMessage[4]&PLAM_LOF_FailureBit){
+                                                       current_intvl->AturPerfLof++;
+                                                       ATUR_PERF_LOFS++;
+                                                       CurrStatus.adslAturCurrStatus = 1;
+                                               }
+                                               if(RxMessage[4]&PLAM_LPR_FailureBit){
+                                                       current_intvl->AturPerfLpr++;
+                                                       ATUR_PERF_LPR++;
+                                                       CurrStatus.adslAturCurrStatus = 3;
+                                               }
+                                               if(!(RxMessage[4]&(PLAM_LOS_FailureBit|PLAM_LOF_FailureBit|PLAM_LPR_FailureBit)))
+                                                       CurrStatus.adslAturCurrStatus = 0;      
+                                       }
+*/
+                                       ATUR_PERF_ESS_FLAG_MAKECMV;
+                                       if(meiCMV(TxMessage, YES_REPLY)!=MEI_SUCCESS){
+#ifdef AMAZON_MEI_DEBUG_ON
+                                               printk("\n\nCMV fail, Group 7 Address 33 Index 0");
+#endif
+                                       }
+                                       else{
+                                               temp = RxMessage[4]-mib_pread.ATUR_PERF_ESS;
+                                               if(temp>=0){
+                                                       current_intvl->AturPerfEs+=temp;
+                                                       ATUR_PERF_ESS+=temp;
+                                                       mib_pread.ATUR_PERF_ESS = RxMessage[4];
+                                               }
+                                               else{
+                                                       current_intvl->AturPerfEs+=0xffff-mib_pread.ATUR_PERF_ESS+RxMessage[4];
+                                                       ATUR_PERF_ESS+= 0xffff-mib_pread.ATUR_PERF_ESS+RxMessage[4];
+                                                       mib_pread.ATUR_PERF_ESS=RxMessage[4];
+                                               }
+                                       }
+                                       // to update rx/tx blocks
+                                       ATUR_CHAN_RECV_BLK_FLAG_MAKECMV_LSW;
+                                       if(meiCMV(TxMessage, YES_REPLY)!=MEI_SUCCESS){
+#ifdef AMAZON_MEI_DEBUG_ON
+                                               printk("\n\nCMV fail, Group 7 Address 20 Index 0");
+#endif
+                                       }
+                                       else{
+                                               temp = RxMessage[4];    
+                                       }
+                                       ATUR_CHAN_RECV_BLK_FLAG_MAKECMV_MSW;
+                                       if(meiCMV(TxMessage, YES_REPLY)!=MEI_SUCCESS){
+#ifdef AMAZON_MEI_DEBUG_ON
+                                               printk("\n\nCMV fail, Group 7 Address 21 Index 0");
+#endif
+                                       }
+                                       else{
+                                               temp2 = RxMessage[4];   
+                                       }
+                                       if((temp + (temp2<<16) - mib_pread.ATUR_CHAN_RECV_BLK)>=0){
+                                               current_intvl->AturChanPerfRxBlk+=temp + (temp2<<16) - mib_pread.ATUR_CHAN_RECV_BLK;
+                                               ATUR_CHAN_RECV_BLK+=temp + (temp2<<16) - mib_pread.ATUR_CHAN_RECV_BLK;
+                                               mib_pread.ATUR_CHAN_RECV_BLK = temp + (temp2<<16);
+                                               }       
+                                       else{
+                                               current_intvl->AturChanPerfRxBlk+=0xffffffff - mib_pread.ATUR_CHAN_RECV_BLK +(temp + (temp2<<16));
+                                               ATUR_CHAN_RECV_BLK+=0xffffffff - mib_pread.ATUR_CHAN_RECV_BLK +(temp + (temp2<<16));
+                                               mib_pread.ATUR_CHAN_RECV_BLK = temp + (temp2<<16);
+                                       }
+                                       current_intvl->AturChanPerfTxBlk = current_intvl->AturChanPerfRxBlk;
+                                       ATUR_CHAN_TX_BLK = ATUR_CHAN_RECV_BLK;
+/*                                     
+                                       ATUR_CHAN_TX_BLK_FLAG_MAKECMV_LSW;
+                                       if(meiCMV(TxMessage, YES_REPLY)!=MEI_SUCCESS)
+                                               printk("\n\nCMV fail, Group 7 Address 20 Index 0");
+                                       else{
+                                               if(RxMessage[4]){
+                                                       current_intvl->AturChanPerfTxBlk+=RxMessage[4];
+                                                       ATUR_CHAN_TX_BLK+=RxMessage[4];
+                                               }       
+                                       }
+                                       ATUR_CHAN_TX_BLK_FLAG_MAKECMV_MSW;
+                                       if(meiCMV(TxMessage, YES_REPLY)!=MEI_SUCCESS)
+                                               printk("\n\nCMV fail, Group 7 Address 21 Index 0");
+                                       else{
+                                               if(RxMessage[4]){
+                                                       current_intvl->AturChanPerfTxBlk+=(int)((RxMessage[4])<<16);
+                                                       ATUR_CHAN_TX_BLK+=(int)((RxMessage[4])<<16);
+                                               }       
+                                       }
+*/                                     
+                                       if(chantype.interleave == 1){
+                                               ATUR_CHAN_CORR_BLK_FLAG_MAKECMV_INTL;
+                                               if(meiCMV(TxMessage, YES_REPLY)!=MEI_SUCCESS){
+#ifdef AMAZON_MEI_DEBUG_ON
+                                                       printk("\n\nCMV fail, Group 7 Address 3 Index 0");
+#endif
+                                               }
+                                               else{
+                                                       temp = RxMessage[4] - mib_pread.ATUR_CHAN_CORR_BLK_INTL;
+                                                       if(temp>=0){
+                                                               current_intvl->AturChanPerfCorrBlk+=temp;
+                                                               ATUR_CHAN_CORR_BLK+=temp;
+                                                               mib_pread.ATUR_CHAN_CORR_BLK_INTL = RxMessage[4];
+                                                       }       
+                                                       else{
+                                                               current_intvl->AturChanPerfCorrBlk+=0xffff - mib_pread.ATUR_CHAN_CORR_BLK_INTL +RxMessage[4];
+                                                               ATUR_CHAN_CORR_BLK+=0xffff - mib_pread.ATUR_CHAN_CORR_BLK_INTL +RxMessage[4];
+                                                               mib_pread.ATUR_CHAN_CORR_BLK_INTL = RxMessage[4];       
+                                                       }       
+                                               }       
+                                       }
+                                       else if(chantype.fast == 1){
+                                               ATUR_CHAN_CORR_BLK_FLAG_MAKECMV_FAST;
+                                               if(meiCMV(TxMessage, YES_REPLY)!=MEI_SUCCESS){
+#ifdef AMAZON_MEI_DEBUG_ON
+                                                       printk("\n\nCMV fail, Group 7 Address 3 Index 1");
+#endif
+                                               }
+                                               else{
+                                                       temp = RxMessage[4] - mib_pread.ATUR_CHAN_CORR_BLK_FAST;
+                                                       if(temp>=0){
+                                                               current_intvl->AturChanPerfCorrBlk+=temp;
+                                                               ATUR_CHAN_CORR_BLK+=temp;
+                                                               mib_pread.ATUR_CHAN_CORR_BLK_FAST = RxMessage[4];
+                                                       }       
+                                                       else{
+                                                               current_intvl->AturChanPerfCorrBlk+=0xffff - mib_pread.ATUR_CHAN_CORR_BLK_FAST + RxMessage[4];
+                                                               ATUR_CHAN_CORR_BLK+=0xffff - mib_pread.ATUR_CHAN_CORR_BLK_FAST + RxMessage[4];
+                                                               mib_pread.ATUR_CHAN_CORR_BLK_FAST = RxMessage[4];
+                                                       }       
+                                               }               
+                                       }
+                                       
+                                       if(chantype.interleave == 1){
+                                               ATUR_CHAN_UNCORR_BLK_FLAG_MAKECMV_INTL;
+                                               if(meiCMV(TxMessage, YES_REPLY)!=MEI_SUCCESS){
+#ifdef AMAZON_MEI_DEBUG_ON
+                                                       printk("\n\nCMV fail, Group 7 Address 2 Index 0");
+#endif
+                                               }
+                                               else{
+                                                       temp = RxMessage[4] - mib_pread.ATUR_CHAN_UNCORR_BLK_INTL;
+                                                       if(temp>=0){
+                                                               current_intvl->AturChanPerfUncorrBlk+=temp;
+                                                               ATUR_CHAN_UNCORR_BLK+=temp;
+                                                               mib_pread.ATUR_CHAN_UNCORR_BLK_INTL = RxMessage[4];
+                                                       }
+                                                       else{
+                                                               current_intvl->AturChanPerfUncorrBlk+=0xffff - mib_pread.ATUR_CHAN_UNCORR_BLK_INTL + RxMessage[4];
+                                                               ATUR_CHAN_UNCORR_BLK+=0xffff - mib_pread.ATUR_CHAN_UNCORR_BLK_INTL + RxMessage[4];
+                                                               mib_pread.ATUR_CHAN_UNCORR_BLK_INTL = RxMessage[4];
+                                                       }
+                                               }               
+                                       }
+                                       else if(chantype.fast == 1){
+                                               ATUR_CHAN_UNCORR_BLK_FLAG_MAKECMV_FAST;
+                                               if(meiCMV(TxMessage, YES_REPLY)!=MEI_SUCCESS){
+#ifdef AMAZON_MEI_DEBUG_ON
+                                                       printk("\n\nCMV fail, Group 7 Address 2 Index 1");
+#endif
+                                               }
+                                               else{
+                                                       temp = RxMessage[4] - mib_pread.ATUR_CHAN_UNCORR_BLK_FAST;
+                                                       if(temp>=0){
+                                                               current_intvl->AturChanPerfUncorrBlk+=temp;
+                                                               ATUR_CHAN_UNCORR_BLK+=temp;
+                                                               mib_pread.ATUR_CHAN_UNCORR_BLK_FAST = RxMessage[4];
+                                                       }
+                                                       else{
+                                                               current_intvl->AturChanPerfUncorrBlk+=0xffff - mib_pread.ATUR_CHAN_UNCORR_BLK_FAST + RxMessage[4];
+                                                               ATUR_CHAN_UNCORR_BLK+=0xffff - mib_pread.ATUR_CHAN_UNCORR_BLK_FAST + RxMessage[4];
+                                                               mib_pread.ATUR_CHAN_UNCORR_BLK_FAST = RxMessage[4];
+                                                       }
+                                               }               
+                                       }
+                                       
+                                       //RFC-3440
+
+#ifdef AMAZON_MEI_MIB_RFC3440
+                                       ATUC_PERF_STAT_FASTR_FLAG_MAKECMV; //???
+                                       if(meiCMV(TxMessage, YES_REPLY)!=MEI_SUCCESS){
+#ifdef AMAZON_MEI_DEBUG_ON
+                                               printk("\n\nCMV fail, Group 0 Address 0 Index 0");
+#endif
+                                       }
+                                       else{
+                                               temp = RxMessage[4] - mib_pread.ATUC_PERF_STAT_FASTR;
+                                               if(temp>=0){
+                                                       current_intvl->AtucPerfStatFastR+=temp;
+                                                       ATUC_PERF_STAT_FASTR+=temp;
+                                                       mib_pread.ATUC_PERF_STAT_FASTR = RxMessage[4];
+                                               }
+                                               else{
+                                                       current_intvl->AtucPerfStatFastR+=0xffff - mib_pread.ATUC_PERF_STAT_FASTR + RxMessage[4];
+                                                       ATUC_PERF_STAT_FASTR+=0xffff - mib_pread.ATUC_PERF_STAT_FASTR + RxMessage[4];
+                                                       mib_pread.ATUC_PERF_STAT_FASTR = RxMessage[4];
+                                               }
+                                       }
+                                       ATUC_PERF_STAT_FAILED_FASTR_FLAG_MAKECMV; //???
+                                       if(meiCMV(TxMessage, YES_REPLY)!=MEI_SUCCESS){
+#ifdef AMAZON_MEI_DEBUG_ON
+                                               printk("\n\nCMV fail, Group 0 Address 0 Index 0");
+#endif
+                                       }
+                                       else{
+                                               temp = RxMessage[4] - mib_pread.ATUC_PERF_STAT_FAILED_FASTR;
+                                               if(temp>=0){
+                                                       current_intvl->AtucPerfStatFailedFastR+=temp;
+                                                       ATUC_PERF_STAT_FAILED_FASTR+=temp;
+                                                       mib_pread.ATUC_PERF_STAT_FAILED_FASTR = RxMessage[4];
+                                               }
+                                               else{
+                                                       current_intvl->AtucPerfStatFailedFastR+=0xffff - mib_pread.ATUC_PERF_STAT_FAILED_FASTR + RxMessage[4];
+                                                       ATUC_PERF_STAT_FAILED_FASTR+=0xffff - mib_pread.ATUC_PERF_STAT_FAILED_FASTR + RxMessage[4];
+                                                       mib_pread.ATUC_PERF_STAT_FAILED_FASTR = RxMessage[4];
+                                               }
+                                       }
+                                       ATUC_PERF_STAT_SESL_FLAG_MAKECMV;
+                                       if(meiCMV(TxMessage, YES_REPLY)!=MEI_SUCCESS){
+#ifdef AMAZON_MEI_DEBUG_ON
+                                               printk("\n\nCMV fail, Group 7 Address 8 Index 0");
+#endif
+                                       }
+                                       else{
+                                               temp = RxMessage[4] - mib_pread.ATUC_PERF_STAT_SESL;
+                                               if(temp>=0){
+                                                       current_intvl->AtucPerfStatSesL+=temp;
+                                                       ATUC_PERF_STAT_SESL+=temp;
+                                                       mib_pread.ATUC_PERF_STAT_SESL = RxMessage[4];
+                                               }
+                                               else{
+                                                       current_intvl->AtucPerfStatSesL+=0xffff - mib_pread.ATUC_PERF_STAT_SESL + RxMessage[4];
+                                                       ATUC_PERF_STAT_SESL+=0xffff - mib_pread.ATUC_PERF_STAT_SESL + RxMessage[4];
+                                                       mib_pread.ATUC_PERF_STAT_SESL = RxMessage[4];
+                                               }
+                                       }
+                                       ATUC_PERF_STAT_UASL_FLAG_MAKECMV;
+                                       if(meiCMV(TxMessage, YES_REPLY)!=MEI_SUCCESS){
+#ifdef AMAZON_MEI_DEBUG_ON
+                                               printk("\n\nCMV fail, Group 7 Address 10 Index 0");
+#endif
+                                       }
+                                       else{
+                                               temp = RxMessage[4] - mib_pread.ATUC_PERF_STAT_UASL;
+                                               if(temp>=0){
+                                                       current_intvl->AtucPerfStatUasL+=temp;
+                                                       ATUC_PERF_STAT_UASL+=temp;
+                                                       mib_pread.ATUC_PERF_STAT_UASL = RxMessage[4];
+                                               }
+                                               else{
+                                                       current_intvl->AtucPerfStatUasL+=0xffff - mib_pread.ATUC_PERF_STAT_UASL + RxMessage[4];
+                                                       ATUC_PERF_STAT_UASL+=0xffff - mib_pread.ATUC_PERF_STAT_UASL + RxMessage[4];
+                                                       mib_pread.ATUC_PERF_STAT_UASL = RxMessage[4];
+                                               }
+                                       }
+                                       ATUR_PERF_STAT_SESL_FLAG_MAKECMV;
+                                       if(meiCMV(TxMessage, YES_REPLY)!=MEI_SUCCESS){
+#ifdef AMAZON_MEI_DEBUG_ON
+                                               printk("\n\nCMV fail, Group 7 Address 34 Index 0");
+#endif
+                                       }
+                                       else{
+                                               temp = RxMessage[4] - mib_pread.ATUR_PERF_STAT_SESL;
+                                               if(temp>=0){
+                                                       current_intvl->AtucPerfStatUasL+=temp;
+                                                       ATUC_PERF_STAT_UASL+=temp;
+                                                       mib_pread.ATUR_PERF_STAT_SESL = RxMessage[4];
+                                               }
+                                               else{
+                                                       current_intvl->AtucPerfStatUasL+=0xffff - mib_pread.ATUR_PERF_STAT_SESL + RxMessage[4];
+                                                       ATUC_PERF_STAT_UASL+=0xffff - mib_pread.ATUR_PERF_STAT_SESL + RxMessage[4];
+                                                       mib_pread.ATUR_PERF_STAT_SESL = RxMessage[4];
+                                               }
+                                       }
+                                       
+#endif
+                                       up(&mei_sema);
+                                       
+                                       do_gettimeofday(&time_fini);
+                                       i = ((int)((time_fini.tv_sec-time_now.tv_sec)*1000)) + ((int)((time_fini.tv_usec-time_now.tv_usec)/1000))  ; //msec 
+                               }//showtime==1
+                       }        
+                       break;
+#endif /* ] !IFX_SMALL_FOOTPRINT */
+               case AMAZON_MEI_RESET:                  
+               case AMAZON_MEI_REBOOT:
+               case AMAZON_MEI_SHOWTIME:
+/*                     if(mei_arc_swap_buff !=NULL){
+                               kfree(mei_arc_swap_buff);
+                               mei_arc_swap_buff=NULL;
+                       }       
+                       if(image_buffer !=NULL){
+//                             kfree(image_buffer);
+                               vfree(image_buffer);
+                               image_buffer =NULL;
+                       }
+*/
+                       if(clreoc_command_pkt !=NULL){
+                               kfree(clreoc_command_pkt);
+                               clreoc_command_pkt =NULL;
+                       }
+                       for(i=0;i<CLREOC_BUFF_SIZE;i++)
+                               clreoc_pkt[i].len=0;    //flush all remaining clreoc commands in buffer
+/*
+                       memset(mei_mib, 0, (sizeof(amazon_mei_mib)*INTERVAL_NUM));
+                       INIT_LIST_HEAD(&interval_list);
+                       for(i=0;i<INTERVAL_NUM;i++)
+                               list_add_tail(&(mei_mib[i].list), &interval_list); 
+                       current_intvl = list_entry(interval_list.next, amazon_mei_mib, list);
+                       do_gettimeofday(&(current_intvl->start_time));
+                       ATUC_PERF_LOFS=0;
+                       ATUC_PERF_LOSS=0;
+                       ATUC_PERF_ESS=0;
+                       ATUC_PERF_INITS=0;
+                       ATUR_PERF_LOFS=0;
+                       ATUR_PERF_LOSS=0;
+                       ATUR_PERF_LPR=0;
+                       ATUR_PERF_ESS=0;
+                       ATUR_CHAN_RECV_BLK=0;
+                       ATUR_CHAN_TX_BLK=0;
+                       ATUR_CHAN_CORR_BLK=0;
+                       ATUR_CHAN_UNCORR_BLK=0;
+                       memset((((u8 *)&AlarmConfProfile)+32), 0, 16*4);
+                       AlarmConfProfile.adslLineAlarmConfProfileRowStatus=1;
+*/
+                       PrevTxRate.adslAtucChanPrevTxRate=0;
+                       PrevTxRate.adslAturChanPrevTxRate=0;
+                       CurrStatus.adslAtucCurrStatus=0;
+                       CurrStatus.adslAturCurrStatus=0;
+                       
+                       if((command==AMAZON_MEI_RESET) || (command==AMAZON_MEI_REBOOT)){
+#ifdef AMAZON_CHECK_LINK
+                               if (adsl_link_notify){
+                                       (*adsl_link_notify)(0);
+                               }
+#endif
+                               showtime=0;
+                               //CLEAR_BIT((*((volatile u32 *)0xB0100B40)), 0x40); //Warning LED GPIO ON
+                               // disconnect net_dev
+                               if(chantype.interleave==1){
+                                       kfree(interleave_mei_net.priv);
+                                       unregister_netdev(&interleave_mei_net);
+//                                     if(unregister_netdev(&interleave_mei_net)!=0)
+//                                             printk("\n unregister interleave fail");
+                               }
+                               else if(chantype.fast==1){
+                                       kfree(fast_mei_net.priv);
+                                       unregister_netdev(&fast_mei_net);
+//                                     if(unregister_netdev(&fast_mei_net)!=0)
+//                                             printk("\n unregister fast fail");
+                               }
+                               chantype.interleave=0;
+                               chantype.fast=0;
+// 603221:tc.chen start
+                               chantype.bearchannel0 = 0;
+                               chantype.bearchannel1 = 0;
+                               adsl_mode = 0;
+// 603221:tc.chen end
+                               
+                               while(1){
+                                       
+                                       makeCMV(H2D_CMV_READ, STAT, 0, 0, 1, NULL); //maximum allowed tx message length, in bytes
+                                       if(meiCMV(TxMessage, YES_REPLY)!=MEI_SUCCESS){
+                                               //printk("AdslInitStatsData.FullInitializationCount++\n");
+                                               AdslInitStatsData.FullInitializationCount++;
+                                               //printk("AdslInitStatsData.FailedFullInitializationCount++\n");
+                                               AdslInitStatsData.FailedFullInitializationCount++;
+                                               //printk("AdslInitStatsData.LINIT_Errors++\n");
+                                               AdslInitStatsData.LINIT_Errors++;
+                                       }else
+                                       {
+                                               //printk("RxMessage=%X\n",RxMessage[4]);
+                                               if ( RxMessage[4]!=0x1)
+                                               {
+                                                       //printk("AdslInitStatsData.FullInitializationCount++\n");
+                                                       AdslInitStatsData.FullInitializationCount++;    
+                                                       if ( RxMessage[4] != 0x7)
+                                                       {
+                                                               //printk("AdslInitStatsData.LINIT_Errors++\n");
+                                                               AdslInitStatsData.LINIT_Errors++;
+                                                               //printk("AdslInitStatsData.FailedFullInitializationCount++\n");
+                                                               AdslInitStatsData.FailedFullInitializationCount++;
+                                                               
+                                                       }                       
+                                               }
+                                       }
+
+                                       reboot_flag=0;
+                                       wake_up_interruptible(&wait_queue_codeswap); //wake up codeswap daemon                          
+
+                                       interruptible_sleep_on_timeout(&wait_queue_reboot, 1*HZ);  // sleep until arc ready
+#ifdef ARC_READY_ACK
+                                       if(reboot_flag!=0)
+                                               break;
+                                       else
+                                       {
+                                               up(&mei_sema);
+                                               printk("\n reboot retry");
+                                       }
+#else
+                                       break;
+#endif
+                               }
+                       }
+                       else{ //AMAZON_MEI_SHOWTIME 
+                               if(down_interruptible(&mei_sema))
+                                       return -ERESTARTSYS;
+                               
+                               // clreoc stuff
+                               makeCMV(H2D_CMV_READ, INFO, 83, 0, 1, data); //maximum allowed tx message length, in bytes
+                               if(meiCMV(TxMessage, YES_REPLY)!=MEI_SUCCESS){
+#ifdef AMAZON_MEI_DEBUG_ON
+                                       printk("\n\nCMV fail, Group 3 Address 83 Index 0");
+#endif
+                               }
+                               else{
+                                       clreoc_max_tx_len = (int)RxMessage[4];
+                                       clreoc_command_pkt = kmalloc((clreoc_max_tx_len*CLREOC_BUFF_SIZE), GFP_KERNEL);
+                                       if(clreoc_command_pkt == NULL){
+#ifdef AMAZON_MEI_DEBUG_ON
+                                               printk("kmalloc error for clreoc_command_pkt\n\n");
+#endif
+                                               up(&mei_sema);
+                                               return -1;
+                                       }
+                                       for(i=0;i<CLREOC_BUFF_SIZE;i++){
+                                               clreoc_pkt[i].command = (u8 *)(((u8 *)clreoc_command_pkt) + (clreoc_max_tx_len*i));
+                                               clreoc_pkt[i].len=0;
+                                       }       
+                               }
+                               
+                               // decide what channel, then register   
+                               makeCMV(H2D_CMV_READ, STAT, 12, 0, 1, data); 
+                               if(meiCMV(TxMessage, YES_REPLY)!=MEI_SUCCESS){
+#ifdef AMAZON_MEI_DEBUG_ON
+                                       printk("\n\nCMV fail, Group 2 Address 12 Index 0");
+#endif
+                               }
+                               else{
+                                       if((RxMessage[4]&0x1)==1){      
+                                               if(register_netdev(&interleave_mei_net)!=0){
+#ifdef AMAZON_MEI_DEBUG_ON
+                                                       printk("\n\n Register interleave Device Failed.");
+#endif
+                                               }
+                                               else{
+                                                       chantype.interleave = 1;
+                                                       chantype.fast= 0;
+#ifdef AMAZON_MEI_DEBUG_ON
+                                                       printk("\n channel is interleave");
+#endif
+                                               }       
+                                       }
+                                       else if((RxMessage[4]&0x2)==2){ 
+                                               if(register_netdev(&fast_mei_net)!=0){
+#ifdef AMAZON_MEI_DEBUG_ON
+                                                       printk("\n\n Register fast Device Failed.");
+#endif
+                                               }
+                                               else{
+                                                       chantype.fast = 1;
+                                                       chantype.interleave = 0;
+#ifdef AMAZON_MEI_DEBUG_ON
+                                                       printk("\n channel is fast");
+#endif
+                                               }
+                                       }
+                                       else{
+#ifdef AMAZON_MEI_DEBUG_ON
+                                               printk("\nunknown channel type, 0x%8x", RxMessage[4]);
+#endif
+                                       }       
+// 603221:tc.chen start        
+                                       if ( (RxMessage[4]&0x100) == 0x100)
+                                       {
+                                               chantype.bearchannel0 = 1;
+                                       }else   if ( (RxMessage[4]&0x100) == 0x200)
+                                       {
+                                               chantype.bearchannel1 = 1;
+                                       }
+// 603221:tc.chen end
+                               }
+// 603221:tc.chen start                        
+                               // read adsl mode
+                               makeCMV(H2D_CMV_READ, STAT, 1, 0, 1, data); 
+                               if(meiCMV(TxMessage, YES_REPLY)!=MEI_SUCCESS){
+#ifdef AMAZON_MEI_DEBUG_ON
+                                       printk("\n\nCMV fail, Group STAT Address 1 Index 0");
+#endif
+                               }
+                               adsl_mode = RxMessage[4];
+// 603221:tc.chen end
+                               makeCMV(H2D_CMV_READ, STAT, 17, 0, 1, data); 
+                               if(meiCMV(TxMessage, YES_REPLY)!=MEI_SUCCESS){
+#ifdef AMAZON_MEI_DEBUG_ON
+                                       printk("\n\nCMV fail, Group STAT Address 1 Index 0");
+#endif
+                               }
+                               adsl_mode_extend = RxMessage[4];
+                               
+                               // update previous channel tx rate
+                               ATUC_CHAN_CURR_TX_RATE_FLAG_MAKECMV;
+                               if(meiCMV(TxMessage, YES_REPLY)!=MEI_SUCCESS){
+#ifdef AMAZON_MEI_DEBUG_ON
+                                       printk("\n\nCMV fail, Group 6 Address 1 Index 0");
+#endif
+                                       PrevTxRate.adslAtucChanPrevTxRate = 0;  
+                               }
+                               else{
+                                       PrevTxRate.adslAtucChanPrevTxRate = (u32)(RxMessage[4]) + (((u32)(RxMessage[5]))<<16);
+                               }
+                               ATUR_CHAN_CURR_TX_RATE_FLAG_MAKECMV;
+                               if(meiCMV(TxMessage, YES_REPLY)!=MEI_SUCCESS){
+#ifdef AMAZON_MEI_DEBUG_ON
+                                       printk("\n\nCMV fail, Group 6 Address 0 Index 0");
+#endif
+                                       PrevTxRate.adslAturChanPrevTxRate = 0;  
+                               }
+                               else{
+                                       PrevTxRate.adslAturChanPrevTxRate = (u32)(RxMessage[4]) + (((u32)(RxMessage[5]))<<16);
+                               }
+                               
+//                             up(&mei_sema);
+                               
+//                             showtime=1;
+                               //SET_BIT((*((volatile u32 *)0xB0100B40)), 0x40); //Warning LED GPIO OFF
+//dying gasp -start    
+#ifdef IFX_DYING_GASP                  
+                               lop_debugwr.buffer[0]=0xffffffff;               //dying gasp
+                               lop_debugwr.iCount=1;                           //dying gasp
+                               makeCMV(H2D_CMV_READ, INFO, 66, 4, 1, NULL);
+                               //mei_ioctl((struct inode *)0,NULL, AMAZON_MEI_CMV_WINHOST, &RxMessage);        
+                               if(meiCMV(TxMessage, YES_REPLY)!=MEI_SUCCESS){
+#ifdef AMAZON_MEI_DEBUG_ON
+                                       printk("\n\nCMV fail, Group 3 Address 66 Index 4");
+                               }
+#endif
+                               lop_debugwr.iAddress=(u32)RxMessage[4];
+                               makeCMV(H2D_CMV_READ, INFO, 66, 5, 1, NULL);
+                               //mei_ioctl((struct inode *)0,NULL, AMAZON_MEI_CMV_WINHOST, &RxMessage);                        
+                               if(meiCMV(TxMessage, YES_REPLY)!=MEI_SUCCESS){
+#ifdef AMAZON_MEI_DEBUG_ON
+                                       printk("\n\nCMV fail, Group 3 Address 66 Index 5");
+                               }
+#endif
+                               lop_debugwr.iAddress+=((u32)RxMessage[4])<<16;
+                               
+//dying gasp -end                              
+#endif // IFX_DYING_GASP                       
+
+//joelin 04/16/2005-start
+                               makeCMV(H2D_CMV_WRITE, PLAM, 10, 0, 1, &unavailable_seconds);
+                               //mei_ioctl((struct inode *)0,NULL, AMAZON_MEI_CMV_WINHOST, &RxMessage);                        
+                               if(meiCMV(TxMessage, YES_REPLY)!=MEI_SUCCESS){
+#ifdef AMAZON_MEI_DEBUG_ON
+                                       printk("\n\nCMV fail, Group 7 Address 10 Index 0");
+                               
+#endif
+                               }
+                               
+
+//joelin 04/16/2005-end                
+                               showtime=1;
+                               up(&mei_sema);
+#ifdef AMAZON_CHECK_LINK
+                               if (adsl_link_notify){
+                                       (*adsl_link_notify)(1);
+                               }
+#endif
+                               
+                               
+                       }
+                       break;
+/*
+                case AMAZON_MEI_REPLY:
+                        copy_from_user((char *)buff, (char *)lon, MSG_LENGTH * 2);
+                        if(meiCMV(buff, YES_REPLY) != MEI_SUCCESS){
+                                printk("\n\n meiCMV no reply back");
+                                meierr=MEI_FAILURE;
+                        }
+                        else
+                                copy_to_user((char *)lon, (char *)RxMessage, MSG_LENGTH * 2);
+                        break;
+                case AMAZON_MEI_NOREPLY:
+                        copy_from_user((char *)buff, (char *)lon, MSG_LENGTH * 2);
+                        if(meiCMV(buff, NO_REPLY) != MEI_SUCCESS){
+                                printk("\n\n meiCMV Host to DSP failed");
+                                meierr=MEI_FAILURE;
+                        }  
+                        break;
+*/
+               
+               case AMAZON_MEI_HALT:
+                       meiHaltArc();
+                       break;
+               case AMAZON_MEI_CMV_WINHOST:
+                       if(down_interruptible(&mei_sema))
+                               return -ERESTARTSYS;
+
+                       if (!from_kernel )      
+                               copy_from_user((char *)TxMessage, (char *)lon, MSG_LENGTH*2);//joelin
+                       else
+                               memcpy(TxMessage,(char *)lon,MSG_LENGTH*2);
+                               
+#if 0                  
+//                     if((TxMessage[0]&0xff0)==0x0a0){
+                               for(i=0;i<16;i++){
+                                       printk("\nTxMessage[%i]=%8x", i, TxMessage[i]);
+                               }
+//                     }                       
+#endif                 
+                       
+                       if(meiCMV(TxMessage, YES_REPLY)!=MEI_SUCCESS){
+#ifdef AMAZON_MEI_DEBUG_ON
+//                             printk("\n\n WINHOST CMV fail ");
+                                printk("\n\nWINHOST CMV fail :TxMessage:%X %X %X %X, RxMessage:%X %X %X %X %X\n",TxMessage[0],TxMessage[1],TxMessage[2],TxMessage[3],RxMessage[0],RxMessage[1],RxMessage[2],RxMessage[3],RxMessage[4]);
+#endif
+                               meierr = MEI_FAILURE;   
+                       }
+                       else 
+                       {
+                               if (!from_kernel )      //joelin
+                               copy_to_user((char *)lon, (char *)RxMessage, MSG_LENGTH*2);
+                               else
+                                       memcpy((char *)lon,(char *)RxMessage,MSG_LENGTH*2);
+                       }
+                               
+                       up(&mei_sema);  
+                       break;
+#ifdef AMAZON_MEI_CMV_EXTRA
+               case AMAZON_MEI_CMV_READ:
+                       copy_from_user((char *)(&regrdwr), (char *)lon, sizeof(meireg));
+                       meiLongwordRead(regrdwr.iAddress, &(regrdwr.iData));
+                       {
+//                             printk("\n\n iAddress = %8x",regrdwr.iAddress);
+                       }
+                       copy_to_user((char *)lon, (char *)(&regrdwr), sizeof(meireg));
+                       {
+//                             printk("\n\n iData readback = %8x", regrdwr.iData);
+                       }
+                       break;
+#endif
+
+#ifdef AMAZON_MEI_CMV_EXTRA
+               case AMAZON_MEI_CMV_WRITE:
+                       copy_from_user((char *)(&regrdwr), (char *)lon, sizeof(meireg));
+                       {
+//                             printk("\n\n iAddress = %8x",regrdwr.iAddress);
+//                             printk("\n\n iData = %8x",regrdwr.iData);
+                       }
+                       meiLongwordWrite(regrdwr.iAddress, regrdwr.iData);
+                       break;
+#endif
+
+#ifdef AMAZON_MEI_CMV_EXTRA
+               case AMAZON_MEI_REMOTE:
+                       copy_from_user((char *)(&i), (char *)lon, sizeof(int));
+                       if(i==0){
+                               meiMailboxInterruptsEnable();
+                                       
+                               up(&mei_sema);
+                       }
+                       else if(i==1){
+                               meiMailboxInterruptsDisable();
+                               if(down_interruptible(&mei_sema))
+                                       return -ERESTARTSYS;
+                       }
+                       else{
+#ifdef AMAZON_MEI_DEBUG_ON
+                               printk("\n\n AMAZON_MEI_REMOTE argument error");
+#endif
+                               meierr=MEI_FAILURE;
+                       }               
+                       break;
+#endif
+
+#ifdef AMAZON_MEI_CMV_EXTRA
+               case AMAZON_MEI_READDEBUG:
+               case AMAZON_MEI_WRITEDEBUG:
+                       if(down_interruptible(&mei_sema))
+                               return -ERESTARTSYS;
+#ifdef IFX_DYING_GASP                  
+       if (!from_kernel) copy_from_user((char *)(&debugrdwr), (char *)lon, sizeof(debugrdwr));//dying gasp
+                               else memcpy((char *)(&debugrdwr), (char *)lon,  sizeof(debugrdwr));
+#else //IFX_DYING_GASP 
+                       copy_from_user((char *)(&debugrdwr), (char *)lon, sizeof(debugrdwr));
+
+#endif //IFX_DYING_GASP                                                        
+#if 0
+                       printk("\nIN iAddress: %8x, iCount:%8x\n", debugrdwr.iAddress, debugrdwr.iCount);
+#endif
+                       
+                       if(command==AMAZON_MEI_READDEBUG)
+                               meiDebugRead(debugrdwr.iAddress, debugrdwr.buffer, debugrdwr.iCount);
+                       else
+                               meiDebugWrite(debugrdwr.iAddress, debugrdwr.buffer, debugrdwr.iCount);  
+                               
+#ifdef IFX_DYING_GASP                          
+                       if (!from_kernel) copy_to_user((char *)lon, (char*)(&debugrdwr), sizeof(debugrdwr));//dying gasp
+#else //IFX_DYING_GASP 
+                       copy_to_user((char *)lon, (char*)(&debugrdwr), sizeof(debugrdwr));
+#endif //IFX_DYING_GASP        
+                       up(&mei_sema);
+                       
+#if 0
+                       printk("\nOUT iAddress: %8x, iCount:%8x\n", debugrdwr.iAddress, debugrdwr.iCount);
+                       for(i=0;i<debugrdwr.iCount;i++)
+                               printk("\n %8x",debugrdwr.buffer[i]);
+#endif
+                       break;
+#endif
+
+               case AMAZON_MEI_LOP:    
+               //GPIO31 :dying gasp event indication
+               //      (1) logic high: dying gasp event is false (default)
+               //      (2) logic low: dying gasp event is true
+#ifdef IFX_DYING_GASP
+                       break;
+#else                                  
+                       CLEAR_BIT((*((volatile u32 *)0xB0100B48)), 0x8000);
+                       CLEAR_BIT((*((volatile u32 *)0xB0100B4C)), 0x8000);
+                       CLEAR_BIT((*((volatile u32 *)0xB0100B50)), 0x8000);
+                       SET_BIT((*((volatile u32 *)0xB0100B54)), 0x8000);
+                       asm("SYNC");
+                       if(((*((volatile u32 *)0xB0100B44))&0x8000)==0x0)
+                               meierr=MEI_FAILURE; //return - to indicate loss of power
+                       break;
+#endif //#ifdef IFX_DYING_GASP                 
+                       
+                                       //for PCM
+               case AMAZON_MEI_PCM_SETUP:
+                       //gpio
+                       
+                       *AMAZON_GPIO_P0_DIR |=1<<15;
+                       *AMAZON_GPIO_P0_ALTSEL0 |=1<<15;
+                       *AMAZON_GPIO_P0_ALTSEL1 &=~(1<<15);
+                       *AMAZON_GPIO_P0_OD |=1<<15;
+                                                                                
+                       /*GPIO 16 TDM_DI*/
+                       *AMAZON_GPIO_P1_DIR &=~1;
+                       *AMAZON_GPIO_P1_ALTSEL0 |=1;
+                       *AMAZON_GPIO_P1_ALTSEL1 &=~1;
+                                                                                
+                       /*GPIO 17 TDM_DCL */
+                       *AMAZON_GPIO_P1_DIR|=0x02;
+                       *AMAZON_GPIO_P1_ALTSEL0|=0x02;
+                       *AMAZON_GPIO_P1_ALTSEL1 &=(u32)~0x02;
+                       *AMAZON_GPIO_P1_OD|=0x02;
+                                                                                
+                       /*GPIO 18 TDM FSC*/
+                       *AMAZON_GPIO_P1_DIR|=0x04;
+                       *AMAZON_GPIO_P1_ALTSEL0|=0x04;
+                       *AMAZON_GPIO_P1_ALTSEL1 &=(u32)~0x04;
+                       *AMAZON_GPIO_P1_OD|=0x04;
+                       
+                       for(i=0;i<2;i++){
+                               for(j=0;j<256;j++)
+                                       sampledata[i*256+j]=j;
+                       }
+                       
+                       pcm_start_addr = lon;
+                       
+                       printk("\n\n pcm_start_addr is %8x", lon);
+                       
+                       for(i=0;i<PCM_CHANNEL_NUM;i++){
+#ifdef PCM_ACCESS_DEBUG
+                               meiDebugRead_16((pcm_start_addr+i*16), (u32*)(pcm_data+i), 4);
+#else
+                               meiDMARead_16((pcm_start_addr+i*16), (u32*)(pcm_data+i), 4);
+#endif
+                               if((pcm_data[i].S!=8)||(pcm_data[i].len<1)||(pcm_data[i].rdindex!=0)||(pcm_data[i].wrindex!=0)||(pcm_data[i].flow!=0))
+                                       printk("\n\n pcm_data fill in wrongly\n\n");
+                               printk("\npcm_data %d",i);
+                               printk("\n S = %d", pcm_data[i].S);
+                               printk("\n LSW = %4x", pcm_data[i].LSW);
+                               printk("\n MSW = %4x", pcm_data[i].MSW);
+                               printk("\n len = %d", pcm_data[i].len);
+                               printk("\n rdindex = %d", pcm_data[i].rdindex);
+                               printk("\n wrindex = %d", pcm_data[i].wrindex); 
+                               printk("\n flow = %d", pcm_data[i].flow);                               
+                               pcm_data[i].finish=0;   
+                               if(i%2==0){//tx channel
+                                       for(j=0;j<PCM_BUFF_SIZE/256;j++){
+                                               for(k=0;k<256;k++){
+                                                       pcm_data[i].buff[j*256+k]=k;
+                                               /*      if(k%2==0)
+                                                               pcm_data[i].buff[j*256+k]=0xaa;
+                                                       else
+                                                               pcm_data[i].buff[j*256+k]=0x55;*/
+                                               }
+                                       }
+#ifdef PCM_ACCESS_DEBUG
+                                       meiDebugWrite_8((((u32)(pcm_data[i].LSW))+(((u32)(pcm_data[i].MSW))<<16)), (u32*)(pcm_data[i].buff),((pcm_data[i].len/4)/2));//fill half first
+//                                     meiDebugWrite_8((((u32)(pcm_data[i].LSW))+(((u32)(pcm_data[i].MSW))<<16)), (u32*)(pcm_data[i].buff),2);//fill half first
+#else
+                                       meiDMAWrite_8((((u32)(pcm_data[i].LSW))+(((u32)(pcm_data[i].MSW))<<16)), (u32*)(pcm_data[i].buff),((pcm_data[i].len/4)/2));//fill half first
+//                                     meiDMAWrite_8((((u32)(pcm_data[i].LSW))+(((u32)(pcm_data[i].MSW))<<16)), (u32*)(pcm_data[i].buff),2);//fill half first
+#endif
+                                       pcm_data[i].point=(pcm_data[i].len)/2;
+//                                     pcm_data[i].point=8;
+#ifdef PCM_ACCESS_DEBUG
+                                       meiDebugRead_16(pcm_start_addr+i*16+12, &temp, 1);
+#else
+                                       meiDMARead_16(pcm_start_addr+i*16+12, &temp, 1);
+#endif
+                                       temp = (temp &0xffff) + (((u32)(pcm_data[i].point))<<16);
+#ifdef PCM_ACCESS_DEBUG
+                                       meiDebugWrite_16(pcm_start_addr+i*16+12,&temp, 1);//update wrindex
+#else
+                                       meiDMAWrite_16(pcm_start_addr+i*16+12,&temp, 1);//update wrindex
+#endif
+                               }
+                               else{// rx channel
+                                       pcm_data[i].point=0;
+                               }
+                       }
+                       break;
+               case AMAZON_MEI_PCM_START_TIMER:
+                               /* GPTU timer 6 */
+                       /* enable the timer in the PMU */
+                       *(AMAZON_PMU_PWDCR) = (*(AMAZON_PMU_PWDCR))| AMAZON_PMU_PWDCR_GPT|AMAZON_PMU_PWDCR_FPI;
+                       /* setup the GPTU for timer tick  f_fpi == f_gptu*/
+                       *(AMAZON_GPTU_CLC) = 0x100;
+                       //reload value = fpi/(HZ * P), timer mode, Prescaler = 4 ( T6I = 000, T6BPS2 = 0)
+                       *(AMAZON_GPTU_CAPREL) = (int)(117500000/(lon*4));       
+                       *(AMAZON_GPTU_T6CON) = 0x80C0;
+                       
+                       if (request_irq(AMAZON_TIMER6_INT, amazon_timer6_interrupt_MEI,0, "hrt", NULL)!=0){
+#ifdef AMAZON_MEI_DEBUG_ON
+                               printk("\n\n unable to register irq for hrt!!!");
+#endif
+                               return -1;
+                       }
+                       enable_irq(AMAZON_TIMER6_INT);
+                       break;
+               case AMAZON_MEI_PCM_STOP_TIMER:
+                       disable_irq(AMAZON_TIMER6_INT);
+                       free_irq(AMAZON_TIMER6_INT, NULL);
+                       break;
+               case AMAZON_MEI_PCM_CHECK:
+                       for(i=0;i<PCM_CHANNEL_NUM;i++){
+                               if(pcm_data[i].finish!=1)
+                                       return 0;       
+                       }
+                       for(i=0;i<PCM_CHANNEL_NUM/2;i++){
+                               j=0;
+                               while(1){
+                                       if((pcm_data[i*2+1].buff[j]==0x0) && (pcm_data[i*2+1].buff[j+1]==0x1)&& (pcm_data[i*2+1].buff[j+2]==0x2))
+                                               break;
+                                       else
+                                               j++;
+                               }
+                               printk("\n j=%d", j);
+                               temp=0;
+                               for(k=0;k<((PCM_BUFF_SIZE-j)/4);k++){
+                                       if(memcmp(pcm_data[i*2].buff+k*4, pcm_data[i*2+1].buff+j+k*4, 4)!=0){
+                                               temp++;
+                                               printk("\n\n%2x %2x %2x %2x %2x %2x %2x %2x\n\n", *((u8*)(pcm_data[i*2].buff+k*4)), *((u8*)(pcm_data[i*2].buff+k*4+1)),*((u8*)(pcm_data[i*2].buff+k*4+2)),*((u8*)(pcm_data[i*2].buff+k*4+3)),*((u8*)(pcm_data[i*2+1].buff+j+k*4)),*((u8*)(pcm_data[i*2+1].buff+j+k*4+1)),*((u8*)(pcm_data[i*2+1].buff+j+k*4+2)),*((u8*)(pcm_data[i*2+1].buff+j+k*4+3)));
+                                               break;
+                                       }
+                               }
+                               if(temp!=0)
+                                       printk("\n\n Channel pair %d not match: err32 %d\n\n", i, temp);
+                               else
+                                       printk("\n\n Channel pair %d match\n\n", i);
+                       }
+                       for(i=0;i<PCM_CHANNEL_NUM;i++){
+                               if(i%2==1){//rx channel
+#ifdef PCM_ACCESS_DEBUG
+                                       meiDebugRead_16(pcm_start_addr+i*16+12, &temp, 1);
+#else
+                                       meiDMARead_16(pcm_start_addr+i*16+12, &temp, 1);
+#endif
+                                       printk("\n\nRx channel %d: Overflow Bytes %d", i, (temp&0xffff));       
+                               }
+                               else{//tx channel
+#ifdef PCM_ACCESS_DEBUG
+                                       meiDebugRead_16(pcm_start_addr+i*16, &temp, 1);
+#else
+                                       meiDMARead_16(pcm_start_addr+i*16, &temp, 1);
+#endif
+                                       printk("\n\nElectra Err: %d",(temp&0xffff));            
+                               }
+                       }
+                       //check electra overflow
+                       
+                       meierr=1;
+                       break;
+               case AMAZON_MEI_PCM_GETDATA:
+                       copy_to_user(lon, pcm_data[1].buff, PCM_BUFF_SIZE);
+                       break;
+               case AMAZON_MEI_PCM_GPIO:
+                       //gpio
+                       
+                       *AMAZON_GPIO_P0_DIR |=1<<15;
+                       *AMAZON_GPIO_P0_ALTSEL0 |=1<<15;
+                       *AMAZON_GPIO_P0_ALTSEL1 &=~(1<<15);
+                       *AMAZON_GPIO_P0_OD |=1<<15;
+                                                                                
+                       /*GPIO 16 TDM_DI*/
+                       *AMAZON_GPIO_P1_DIR &=~1;
+                       *AMAZON_GPIO_P1_ALTSEL0 |=1;
+                       *AMAZON_GPIO_P1_ALTSEL1 &=~1;
+                                                                                
+                       /*GPIO 17 TDM_DCL */
+                       *AMAZON_GPIO_P1_DIR|=0x02;
+                       *AMAZON_GPIO_P1_ALTSEL0|=0x02;
+                       *AMAZON_GPIO_P1_ALTSEL1 &=(u32)~0x02;
+                       *AMAZON_GPIO_P1_OD|=0x02;
+                                                                                
+                       /*GPIO 18 TDM FSC*/
+                       *AMAZON_GPIO_P1_DIR|=0x04;
+                       *AMAZON_GPIO_P1_ALTSEL0|=0x04;
+                       *AMAZON_GPIO_P1_ALTSEL1 &=(u32)~0x04;
+                       *AMAZON_GPIO_P1_OD|=0x04;       
+                       break;
+                       
+                       
+                       
+                               //for clearEoC
+#ifdef AMAZON_CLEAR_EOC
+               case AMAZON_MEI_GET_EOC_LEN:
+                       while(1){
+                               current_clreoc = list_entry(clreoc_list.next, amazon_clreoc_pkt, list);
+                               if((current_clreoc->len)>0){
+                                       copy_to_user((char *)lon, (char*)(&(current_clreoc->len)), 4);
+                                       break;  
+                               }
+                               else//wait for eoc data from higher layer
+                                       interruptible_sleep_on(&wait_queue_clreoc);     
+                       }
+                       break;
+               case AMAZON_MEI_GET_EOC_DATA:
+                       current_clreoc = list_entry(clreoc_list.next, amazon_clreoc_pkt, list);
+                       if((current_clreoc->len)>0){
+                               copy_to_user((char*)lon, (char*)(current_clreoc->command), current_clreoc->len);
+                               meierr=1;
+                               list_del(clreoc_list.next);     //remove and add to end of list
+                               current_clreoc->len = 0;
+                               list_add_tail(&(current_clreoc->list), &clreoc_list);
+                       }
+                       else
+                               meierr=-1;
+                       break;
+               case AMAZON_MEI_EOC_SEND:
+                       copy_from_user((char *)(&debugrdwr), (char *)lon, sizeof(debugrdwr));
+                       eoc_skb = dev_alloc_skb(debugrdwr.iCount*4);
+                       if(eoc_skb==NULL){
+                               printk("\n\nskb alloc fail");
+                               break;
+                       }
+                       
+                       eoc_skb->len=debugrdwr.iCount*4;
+                       memcpy(skb_put(eoc_skb, debugrdwr.iCount*4), (char *)debugrdwr.buffer, debugrdwr.iCount*4);
+                       
+                       ifx_push_eoc(eoc_skb);  //pass data to higher layer
+                       break;
+#endif //#ifdef AMAZON_CLEAR_EOC
+               case AMAZON_MIB_LO_ATUC:
+                       do_gettimeofday(&time_now);
+                       if(lon&0x1){
+                               if((time_now.tv_sec-(mib_pflagtime.ATUC_PERF_LOSS_PTIME).tv_sec)>2){
+                                       current_intvl->AtucPerfLos++;
+                                       ATUC_PERF_LOSS++;
+                                       CurrStatus.adslAtucCurrStatus = 2;
+                               }
+                               (mib_pflagtime.ATUC_PERF_LOSS_PTIME).tv_sec = time_now.tv_sec;
+                       }
+                       if(lon&0x2){
+                               if((time_now.tv_sec-(mib_pflagtime.ATUC_PERF_LOFS_PTIME).tv_sec)>2){
+                                       current_intvl->AtucPerfLof++;
+                                       ATUC_PERF_LOFS++;
+                                       CurrStatus.adslAtucCurrStatus = 1;
+                               }
+                               (mib_pflagtime.ATUC_PERF_LOFS_PTIME).tv_sec = time_now.tv_sec;
+                       }
+                       if(!(lon&0x3))
+                               CurrStatus.adslAtucCurrStatus = 0;
+                       break;
+               case AMAZON_MIB_LO_ATUR:
+                       do_gettimeofday(&time_now);
+                       if(lon&0x1){
+                               if((time_now.tv_sec-(mib_pflagtime.ATUR_PERF_LOSS_PTIME).tv_sec)>2){
+                                       current_intvl->AturPerfLos++;
+                                       ATUR_PERF_LOSS++;
+                                       CurrStatus.adslAturCurrStatus = 2;
+                       }
+                               (mib_pflagtime.ATUR_PERF_LOSS_PTIME).tv_sec = time_now.tv_sec;
+                       }
+                       if(lon&0x2){
+                               if((time_now.tv_sec-(mib_pflagtime.ATUR_PERF_LOFS_PTIME).tv_sec)>2){
+                                       current_intvl->AturPerfLof++;
+                                       ATUR_PERF_LOFS++;
+                                       CurrStatus.adslAturCurrStatus = 1;
+                               }
+                               (mib_pflagtime.ATUR_PERF_LOFS_PTIME).tv_sec = time_now.tv_sec;
+                       }
+                       if(lon&0x4){
+                               if((time_now.tv_sec-(mib_pflagtime.ATUR_PERF_LPR_PTIME).tv_sec)>2){
+                                       current_intvl->AturPerfLpr++;
+                                       ATUR_PERF_LPR++;
+                                       CurrStatus.adslAturCurrStatus = 3;
+                               }
+                               (mib_pflagtime.ATUR_PERF_LPR_PTIME).tv_sec = time_now.tv_sec;
+                       }
+                       if(!(lon&0x7))
+                               CurrStatus.adslAturCurrStatus = 0;
+                       break;
+               case AMAZON_MEI_DOWNLOAD:
+                       // DMA the boot code page(s)
+#ifdef AMAZON_MEI_DEBUG_ON
+                       printk("\n\n start download pages");
+#endif
+                       for( boot_loop = 0; boot_loop < img_hdr->count; boot_loop++){
+                               if( img_hdr->page[boot_loop].p_size & BOOT_FLAG){
+                                       page_size = meiGetPage( boot_loop, GET_PROG, MAXSWAPSIZE, mei_arc_swap_buff, &dest_addr);
+                                       if( page_size > 0){
+                                               meiDMAWrite(dest_addr, mei_arc_swap_buff, page_size);
+                                       }
+                               }
+                               if( img_hdr->page[boot_loop].d_size & BOOT_FLAG){
+                                       page_size = meiGetPage( boot_loop, GET_DATA, MAXSWAPSIZE, mei_arc_swap_buff, &dest_addr);
+                                       if( page_size > 0){
+                                               meiDMAWrite( dest_addr, mei_arc_swap_buff, page_size);
+                                       }
+                               }
+                       }
+#ifdef AMAZON_MEI_DEBUG_ON
+                       printk("\n\n pages downloaded");
+#endif
+                       break;
+               //509221:tc.chen start
+                case AMAZON_MEI_DEBUG_MODE:
+                        mei_debug_mode = lon;
+                       break;
+               //509221:tc.chen end
+        }
+        return meierr;
+}
+
+
+//////////////////////          Interrupt handler               /////////////////////////////////////////////////////
+static void mei_interrupt_arcmsgav(int,void *,struct pt_regs *);
+static void mei_interrupt_arcmsgav(int int1, void * void0, struct pt_regs * regs)
+{
+        u32 scratch;
+        u32 fetchpage;
+        u32 size;
+        u32 dest_addr;
+       u32 temp;
+       int i;
+        
+        meiDebugRead(ARC_MEI_MAILBOXR, &scratch, 1);
+        if(scratch & OMB_CODESWAP_MESSAGE_MSG_TYPE_MASK)
+        {
+               if(showtime==1){
+#ifdef AMAZON_MEI_DEBUG_ON
+                       printk("\n\n Code Swap Request After ShowTime !!!");
+#endif
+               }
+               else{
+#ifdef AMAZON_MEI_DEBUG_ON
+//                     printk("\n\n Code Swap Request");
+#endif
+                       fetchpage = scratch & ~OMB_CODESWAP_MESSAGE_MSG_TYPE_MASK;
+                       size = meiGetPage( fetchpage, GET_PROG, MAXSWAPSIZE, mei_arc_swap_buff, &dest_addr);
+                       if( size > 0)
+                       {
+#ifdef AMAZON_MEI_DEBUG_ON
+//                             printk("  : prom page num %d",fetchpage);
+#endif
+                               meiDMAWrite( dest_addr, mei_arc_swap_buff, size);
+                       }
+
+                       size = meiGetPage( fetchpage, GET_DATA, MAXSWAPSIZE, mei_arc_swap_buff, &dest_addr);
+                       if( size > 0)
+                       {
+#ifdef AMAZON_MEI_DEBUG_ON
+//                             printk("  : data page num %d",fetchpage);
+#endif
+                               meiDMAWrite( dest_addr, mei_arc_swap_buff, size);
+                       }
+               }
+                        //     Notify arc that mailbox read complete
+               meiLongwordWrite(ARC_TO_MEI_INT, ARC_TO_MEI_MSGAV);
+
+               //      Tell ARC Codeswap is done
+               meiLongwordWrite(MEI_TO_ARC_INT, MEI_TO_ARC_CS_DONE);
+               asm("SYNC");
+               i=0;
+               while(i<WHILE_DELAY){
+                       meiLongwordRead(MEI_TO_ARC_INT, &temp);
+                       if((temp & MEI_TO_ARC_CS_DONE) ==0){
+#ifdef AMAZON_MEI_DEBUG_ON
+//                             printk("\n\n Code Swap Done");
+#endif
+                               break;
+                       }
+                       i++;
+                       if(i==WHILE_DELAY){
+#ifdef AMAZON_MEI_DEBUG_ON
+                               printk("\n\n MEI_TO_ARC_CS_DONE not cleared by ARC");
+                               //509221:tc.chen start
+                               if (!mei_debug_mode)
+                               {
+                                       //printk("Reset Arc!\n");
+                                       //printk("AdslInitStatsData.FullInitializationCount++\n");
+                                       AdslInitStatsData.FullInitializationCount++;    
+                                       if (!showtime)
+                                       {
+                                               //printk("AdslInitStatsData.FailedFullInitializationCount++\n");
+                                               AdslInitStatsData.FailedFullInitializationCount++;
+                                               //printk("AdslInitStatsData.LINIT_Errors++\n");
+                                               AdslInitStatsData.LINIT_Errors++;
+                                       }
+
+                                       wake_up_interruptible(&wait_queue_codeswap);    // wait up ioctl reboot
+                               }
+                               //509221:tc.chen end
+#endif
+                       }
+               }
+        }
+        else{    // normal message
+//                     printk("\n\n interrupt");       
+                        meiMailboxRead(RxMessage, MSG_LENGTH);
+                        if(cmv_waiting==1){            
+                                arcmsgav=1;
+                                cmv_waiting=0;
+                                wake_up_interruptible(&wait_queue_arcmsgav);                  
+                        }
+                        else{
+                                indicator_count++;
+                                memcpy((char *)Recent_indicator, (char *)RxMessage,  MSG_LENGTH *2);
+#ifdef ARC_READY_ACK
+                               if(((RxMessage[0]&0xff0)>>4)==D2H_AUTONOMOUS_MODEM_READY_MSG){  //check ARC ready message
+                                       
+#ifdef LOCK_RETRY
+                                       if (reboot_lock)
+                                       {
+                                           reboot_lock = 0;
+                                           up(&mei_sema);      // allow cmv access
+                                       }
+#else
+                                       up(&mei_sema);  // allow cmv access
+#endif
+                                       reboot_flag=1;
+//#ifdef ADSL_LED_SUPPORT                                      
+#if 0
+                                       led_support_check=1;//adsl led for 1.1.2.7.1.1
+                                       adsl_led_flash();//adsl led for 1.1.2.7.1.1
+#endif
+                                       wake_up_interruptible(&wait_queue_reboot);      // wait up ioctl reboot
+                               }
+#endif
+                       }                  
+        }
+//     meiLongwordWrite(ARC_TO_MEI_INT, ARC_TO_MEI_MSGAV);
+       mask_and_ack_amazon_irq(AMAZON_MEI_INT);
+        return;
+}
+
+// 603221:tc.chen start
+////////////////////////hdlc ////////////////
+
+// get hdlc status
+static unsigned int ifx_me_hdlc_status(void)
+{
+       u16 CMVMSG[MSG_LENGTH]; 
+       int ret;
+
+       if (showtime!=1)
+               return -ENETRESET;
+       
+       makeCMV_local(H2D_CMV_READ, STAT, 14, 0, 1, NULL,CMVMSG);       //Get HDLC status 
+       ret = mei_ioctl((struct inode *)0,NULL, AMAZON_MEI_CMV_WINHOST, CMVMSG);
+       if (ret != 0)
+       {
+               return -EIO;
+       }
+       return CMVMSG[4]&0x0F;
+}
+
+int ifx_me_is_resloved(int status)
+{
+       u16 CMVMSG[MSG_LENGTH];
+       int ret;
+       
+       if (status == ME_HDLC_MSG_QUEUED || status == ME_HDLC_MSG_SENT)
+               return ME_HDLC_UNRESOLVED;
+       if (status == ME_HDLC_IDLE)
+       {
+               makeCMV_local(H2D_CMV_READ, CNTL, 2, 0, 1, NULL,CMVMSG);        //Get ME-HDLC Control
+               ret = mei_ioctl((struct inode *)0,NULL, AMAZON_MEI_CMV_WINHOST, CMVMSG);
+               if (ret != 0)
+               {
+                       return IFX_POP_EOC_FAIL;
+               }
+               if (CMVMSG[4]&(1<<0))
+               {
+                       return ME_HDLC_UNRESOLVED;
+               }
+               
+       }
+       return ME_HDLC_RESOLVED;
+}
+
+int _ifx_me_hdlc_send(unsigned char *hdlc_pkt,int len,int max_length)
+{
+       int ret;
+       u16 CMVMSG[MSG_LENGTH];
+       u16 data=0;
+       u16 pkt_len=len;
+       if (pkt_len > max_length)
+       {
+               printk("Exceed maximum eoc message length\n");
+               return -ENOBUFS;
+       }
+       //while(pkt_len > 0)
+       {               
+               makeCMV_local(H2D_CMV_WRITE, INFO, 81, 0, (pkt_len+1)/2,(u16 *)hdlc_pkt,CMVMSG);        //Write clear eoc message to ARC
+               ret = mei_ioctl((struct inode *)0,NULL, AMAZON_MEI_CMV_WINHOST, CMVMSG);
+               if (ret != 0)
+               {
+                       return -EIO;
+               }
+               
+               makeCMV_local(H2D_CMV_WRITE, INFO, 83, 2, 1,&pkt_len,CMVMSG);   //Update tx message length
+               ret = mei_ioctl((struct inode *)0,NULL, AMAZON_MEI_CMV_WINHOST, CMVMSG);
+               if (ret != 0)
+               {
+                       return -EIO;
+               }
+               
+               data = (1<<0);
+               makeCMV_local(H2D_CMV_WRITE, CNTL, 2, 0, 1,&data,CMVMSG);       //Start to send
+               ret = mei_ioctl((struct inode *)0,NULL, AMAZON_MEI_CMV_WINHOST, CMVMSG);
+               if (ret != 0)
+               {
+                       return -EIO;
+               }
+               return 0;
+       }
+}
+
+static int ifx_me_hdlc_send(unsigned char *hdlc_pkt,int hdlc_pkt_len)
+{
+       int hdlc_status=0;
+       u16 CMVMSG[MSG_LENGTH];
+       int max_hdlc_tx_length=0,ret=0,retry=0;
+       
+       while(retry<10)
+       {
+               hdlc_status = ifx_me_hdlc_status();
+               if (ifx_me_is_resloved(hdlc_status)==ME_HDLC_RESOLVED) // arc ready to send HDLC message
+               {
+                       makeCMV_local(H2D_CMV_READ, INFO, 83, 0, 1, NULL,CMVMSG);       //Get Maximum Allowed HDLC Tx Message Length
+                       ret = mei_ioctl((struct inode *)0,NULL, AMAZON_MEI_CMV_WINHOST, CMVMSG);
+                       if (ret != 0)
+                       {
+                               return -EIO;
+                       }
+                       max_hdlc_tx_length = CMVMSG[4];
+                       ret = _ifx_me_hdlc_send(hdlc_pkt,hdlc_pkt_len,max_hdlc_tx_length);
+                       return ret;
+               }
+               set_current_state(TASK_INTERRUPTIBLE);
+               schedule_timeout(10);
+       }
+       return -EBUSY;
+}
+
+int ifx_mei_hdlc_read(char *hdlc_pkt,int max_hdlc_pkt_len)
+{
+       u16 CMVMSG[MSG_LENGTH]; 
+       int msg_read_len,ret=0,pkt_len=0,retry = 0;
+               
+       while(retry<10)
+       {
+               ret = ifx_me_hdlc_status();
+               if (ret == ME_HDLC_RESP_RCVD)
+               {
+                       int current_size=0;
+                       makeCMV_local(H2D_CMV_READ, INFO, 83, 3, 1, NULL,CMVMSG);       //Get EoC packet length
+                       ret = mei_ioctl((struct inode *)0,NULL, AMAZON_MEI_CMV_WINHOST, CMVMSG);
+                       if (ret != 0)
+                       {
+                               return -EIO;
+                       }
+       
+                       pkt_len = CMVMSG[4];
+                       if (pkt_len > max_hdlc_pkt_len)
+                       {
+                               ret = -ENOMEM;
+                               goto error;
+                       }
+                       while( current_size < pkt_len)
+                       {
+                               if (pkt_len - current_size >(MSG_LENGTH*2-8))
+                                       msg_read_len = (MSG_LENGTH*2-8);
+                               else
+                                       msg_read_len = pkt_len - (current_size);
+                               makeCMV_local(H2D_CMV_READ, INFO, 82, 0 + (current_size/2), (msg_read_len+1)/2, NULL,CMVMSG);   //Get hdlc packet
+                               ret = mei_ioctl((struct inode *)0,NULL, AMAZON_MEI_CMV_WINHOST, CMVMSG);
+                               if (ret != 0)
+                               {
+                                       goto error;
+                               }
+                               memcpy(hdlc_pkt+current_size,&CMVMSG[4],msg_read_len);
+                               current_size +=msg_read_len;
+                       }
+                       ret = current_size;
+                       break;
+               }else
+               {
+                       ret = -ENODATA;
+               }
+               
+               retry++;
+               set_current_state(TASK_INTERRUPTIBLE);
+               schedule_timeout(10);
+               
+       }
+       return ret;
+error:
+       
+       return ret;
+}
+
+////////////////////////hdlc ////////////////
+// 603221:tc.chen end
+
+/////////////////////// clearEoC, int ifx_pop_eoc(sk_buff * pkt)  //////////
+int ifx_pop_eoc(struct sk_buff * pkt);
+int ifx_pop_eoc(struct sk_buff * pkt)
+{
+       amazon_clreoc_pkt * current;
+       if(showtime!=1){
+               dev_kfree_skb(pkt);
+               return IFX_POP_EOC_FAIL;
+       }
+       if((pkt->len)>clreoc_max_tx_len){
+               dev_kfree_skb(pkt);
+               return IFX_POP_EOC_FAIL;
+       }
+       current = list_entry(clreoc_list.next, amazon_clreoc_pkt, list);
+       while(1){
+               if(current->len==0){
+                       memcpy(current->command, pkt->data, pkt->len);
+                       current->len=pkt->len;
+                       break;
+               }
+               else{
+                       if((current->list).next==&clreoc_list){
+                               dev_kfree_skb(pkt);
+                               return IFX_POP_EOC_FAIL;        //buffer full
+                       }
+                       current = list_entry((current->list).next,amazon_clreoc_pkt, list);
+               }
+       }       
+       wake_up_interruptible(&wait_queue_clreoc);
+       
+       dev_kfree_skb(pkt);
+       return IFX_POP_EOC_DONE;
+}      
+/*  this is used in circular fifo mode */
+/*
+int ifx_pop_eoc(sk_buff * pkt);
+int ifx_pop_eoc(sk_buff * pkt)
+{
+       int buff_space,i;
+       if(showtime!=1)
+               return IFX_POP_EOC_FAIL;
+       
+       if(clreoc_wr>=clreoc_rd)
+               buff_space = (MEI_CLREOC_BUFF_SIZE-1)-(clreoc_wr - clreoc_rd);
+       else
+               buff_space = clreoc_rd - clreoc_wr - 1;
+       if((pkt->len)>buff_space)
+               return IFX_POP_EOC_FAIL;
+                                       
+       if((clreoc_wr+pkt->len)>MEI_CLREOC_BUFF_SIZE){
+               memcpy((clreoc+clreoc_wr), pkt->data, ((clreoc_wr+pkt->len)-MEI_CLREOC_BUFF_SIZE+1));
+               memcpy(clreoc, (pkt->data)+((clreoc_wr+pkt->len)-MEI_CLREOC_BUFF_SIZE+1), (pkt->len)-((clreoc_wr+pkt->len)-MEI_CLREOC_BUFF_SIZE+1)); 
+               clreoc_wr=(clreoc_wr+pkt->len)-MEI_CLREOC_BUFF_SIZE;
+       }       
+       else{
+               memcpy((clreoc+clreoc_wr), pkt->data, pkt->len);
+               if((clreoc_wr+pkt->len)=MEI_CLREOC_BUFF_SIZE)
+                       clreoc_wr=0;
+               else
+                       clreoc_wr+=pkt->len;
+       }
+       wake_up_interruptible(&wait_queue_clreoc);
+       return IFX_POP_EOC_DONE;                        
+}
+*/
+
+
+////////////////////////////////////////////////////////////////////////////
+//int amazon_mei_init_module (void);
+//void amazon_mei_cleanup_module (void);
+//int __init init_module (void);
+//void __exit cleanup_module (void);
+
+int __init amazon_mei_init_module(void)
+//int __init init_module(void)
+{
+        struct proc_dir_entry *entry;
+        int i;
+       
+//dying gasp-start     
+#ifdef IFX_DYING_GASP
+
+//000003:fchang Start
+#ifdef CONFIG_CPU_AMAZON_E
+               //GPIO31 :dying gasp event indication
+               //      (1) logic high: dying gasp event is false (default)
+               //      (2) logic low: dying gasp event is true
+                       CLEAR_BIT((*((volatile u32 *)0xB0100B18)), 0x4);
+                       CLEAR_BIT((*((volatile u32 *)0xB0100B1c)), 0x4);
+                       CLEAR_BIT((*((volatile u32 *)0xB0100B20)), 0x4);
+                       SET_BIT((*((volatile u32 *)0xB0100B24)), 0x4);
+                       asm("SYNC");                    
+#else //000003:fchang End
+
+               //GPIO31 :dying gasp event indication
+               //      (1) logic high: dying gasp event is false (default)
+               //      (2) logic low: dying gasp event is true
+                       CLEAR_BIT((*((volatile u32 *)0xB0100B48)), 0x8000);
+                       CLEAR_BIT((*((volatile u32 *)0xB0100B4C)), 0x8000);
+                       CLEAR_BIT((*((volatile u32 *)0xB0100B50)), 0x8000);
+                       SET_BIT((*((volatile u32 *)0xB0100B54)), 0x8000);
+#if 0                  
+//warning-led-start    
+//GPIO 22              
+                       SET_BIT ((*((volatile u32 *)0xB0100B48)), 0x40);
+                       CLEAR_BIT((*((volatile u32 *)0xB0100B4C)), 0x40);
+                       CLEAR_BIT((*((volatile u32 *)0xB0100B50)), 0x40);
+                       SET_BIT((*((volatile u32 *)0xB0100B54)), 0x40);                 
+                       CLEAR_BIT((*((volatile u32 *)0xB0100B40)), 0x40); //GPIO ON
+                       printk("LED ON ON ON ON ON ON.....");
+//warning-led-end                      
+#endif
+                       asm("SYNC");    
+#endif //000003:fchang
+
+#endif //IFX_DYING_GASP        
+//dying gasp -end        
+        
+       
+        reg_entry_t regs_temp[PROC_ITEMS] =                                     // Items being debugged
+        {
+        /*     {       flag,          name,          description } */
+       { &arcmsgav, "arcmsgav", "arc to mei message ", 0 },
+            { &cmv_reply, "cmv_reply", "cmv needs reply", 0},
+            { &cmv_waiting, "cmv_waiting", "waiting for cmv reply from arc", 0},
+            { &indicator_count, "indicator_count", "ARC to MEI indicator count", 0},
+            { &cmv_count, "cmv_count", "MEI to ARC CMVs", 0},
+            { &reply_count, "reply_count", "ARC to MEI Reply", 0},
+            { (int *)Recent_indicator, "Recent_indicator", "most recent indicator", 0},
+           { (int *)8, "version", "version of firmware", 0},
+        };
+        memcpy((char *)regs, (char *)regs_temp, sizeof(regs_temp));
+
+
+        //sema_init(&mei_sema, 0);  // semaphore initialization, mutex
+        sema_init(&mei_sema, 1);  // semaphore initialization, mutex
+       
+        init_waitqueue_head(&wait_queue_arcmsgav);             // for ARCMSGAV
+       init_waitqueue_head(&wait_queue_codeswap);              // for codeswap daemon
+       init_waitqueue_head(&wait_queue_mibdaemon);             // for mib daemon
+       init_waitqueue_head(&wait_queue_reboot);                // for ioctl reboot 
+       init_waitqueue_head(&wait_queue_clreoc);                // for clreoc_wr function
+       init_waitqueue_head(&wait_queue_loop_diagnostic);               // for loop diagnostic function
+#ifdef ADSL_LED_SUPPORT        
+       init_waitqueue_head(&wait_queue_led);                   // adsl led for led function
+       init_waitqueue_head(&wait_queue_led_polling);           // adsl led for led function
+       led_task.routine = adsl_led_flash_task;                 // adsl led for led function
+       led_poll_init();                                        // adsl led for led function
+#endif //ADSL_LED_SUPPORT
+#ifdef IFX_DYING_GASP  
+       init_waitqueue_head(&wait_queue_dying_gasp);            // IFX_DYING_GASP
+       lop_poll_init();                                        // IFX_DYING_GASP 
+#endif //IFX_DYING_GASP
+       init_waitqueue_head(&wait_queue_uas_poll);//joelin 04/16/2005
+       unavailable_seconds_poll_init();//joelin 04/16/2005
+       memset(&mib_pflagtime, 0, (sizeof(mib_flags_pretime)));
+       
+       // initialize link list for intervals
+       mei_mib = (amazon_mei_mib *)kmalloc((sizeof(amazon_mei_mib)*INTERVAL_NUM), GFP_KERNEL);
+       if(mei_mib == NULL){
+#ifdef AMAZON_MEI_DEBUG_ON
+               printk("kmalloc error for amazon_mei_mib\n\n");
+#endif
+               return -1;
+       }
+       memset(mei_mib, 0, (sizeof(amazon_mei_mib)*INTERVAL_NUM));
+       INIT_LIST_HEAD(&interval_list);
+       for(i=0;i<INTERVAL_NUM;i++)
+               list_add_tail(&(mei_mib[i].list), &interval_list); 
+       current_intvl = list_entry(interval_list.next, amazon_mei_mib, list);
+       do_gettimeofday(&(current_intvl->start_time)); 
+       // initialize clreoc list
+       clreoc_pkt = (amazon_clreoc_pkt *)kmalloc((sizeof(amazon_clreoc_pkt)*CLREOC_BUFF_SIZE), GFP_KERNEL);
+       if(clreoc_pkt == NULL){
+#ifdef AMAZON_MEI_DEBUG_ON
+               printk("kmalloc error for clreoc_pkt\n\n");
+#endif
+               return -1;
+       }
+       memset(clreoc_pkt, 0, (sizeof(amazon_clreoc_pkt)*CLREOC_BUFF_SIZE));
+       INIT_LIST_HEAD(&clreoc_list);
+       for(i=0;i<CLREOC_BUFF_SIZE;i++)
+               list_add_tail(&(clreoc_pkt[i].list), &clreoc_list);
+               
+        memset(&AdslInitStatsData, 0, sizeof(AdslInitStatsData));
+        if (register_chrdev(major, "amazon_mei", &mei_operations)!=0) {
+#ifdef AMAZON_MEI_DEBUG_ON
+                printk("\n\n unable to register major for amazon_mei!!!");
+#endif
+                return -1;
+        }
+        if (request_irq(AMAZON_MEI_INT, mei_interrupt_arcmsgav,0, "amazon_mei_arcmsgav", NULL)!=0){
+#ifdef AMAZON_MEI_DEBUG_ON
+                printk("\n\n unable to register irq for amazon_mei!!!");
+#endif
+                return -1;
+        }
+//        disable_irq(AMAZON_MEI_INT);
+       enable_irq(AMAZON_MEI_INT);
+        // procfs
+        meidir=proc_mkdir(MEI_DIRNAME, &proc_root);
+        if ( meidir == NULL) {
+#ifdef AMAZON_MEI_DEBUG_ON
+               printk(KERN_ERR ": can't create /proc/" MEI_DIRNAME "\n\n");
+#endif
+               return(-ENOMEM);
+        }
+
+        for(i=0;i<NUM_OF_REG_ENTRY;i++) {
+               entry = create_proc_entry(regs[i].name,
+                               S_IWUSR |S_IRUSR | S_IRGRP | S_IROTH,
+                               meidir);
+               if(entry) {
+                       regs[i].low_ino = entry->low_ino;
+                       entry->proc_fops = &proc_operations;
+               } else {
+#ifdef AMAZON_MEI_DEBUG_ON
+                       printk( KERN_ERR 
+                               ": can't create /proc/" MEI_DIRNAME
+                               "/%s\n\n", regs[i].name);
+#endif
+                       return(-ENOMEM);
+               }
+        }
+        ///////////////////////////////// register net device ////////////////////////////
+        if(register_netdev(&phy_mei_net)!=0){
+#ifdef AMAZON_MEI_DEBUG_ON
+                printk("\n\n Register phy Device Failed.");
+#endif
+                return -1;
+        }
+/*
+       if(register_netdev(&interleave_mei_net)!=0){
+                printk("\n\n Register interleave Device Failed.");
+                return -1;
+        }
+       if(register_netdev(&fast_mei_net)!=0){
+                printk("\n\n Register fast Device Failed.");
+                return -1;
+        }
+*/
+#ifdef DFE_LOOPBACK
+       mei_arc_swap_buff = (u32 *)kmalloc(MAXSWAPSIZE*4, GFP_KERNEL);
+       if (mei_arc_swap_buff){
+#ifdef ARC_READY_ACK
+               if(down_interruptible(&mei_sema))       //disable CMV access until ARC ready
+               {
+                       return -ERESTARTSYS;
+               }
+#ifdef LOCK_RETRY
+               reboot_lock = 1;
+#endif
+#endif
+               meiForceRebootAdslModem();
+               kfree(mei_arc_swap_buff);
+       }else{
+#ifdef AMAZON_MEI_DEBUG_ON
+               printk("cannot load image: no memory\n\n");
+#endif
+       }
+#endif
+#ifdef IFX_SMALL_FOOTPRINT
+       mib_poll_init();
+#endif
+        return 0;
+}
+
+void __exit amazon_mei_cleanup_module(void)
+//void __exit cleanup_module(void)
+{
+        int i;
+#ifdef ADSL_LED_SUPPORT        
+        stop_led_module=1;                     //wake up and clean led module 
+        led_support_check=0;//joelin , clear task
+        showtime=0;//joelin,clear task
+        //CLEAR_BIT((*((volatile u32 *)0xB0100B40)), 0x40); //Warning LED GPIO ON
+        firmware_support_led=0;//joelin ,clear task
+        wake_up_interruptible(&wait_queue_led); //wake up and clean led module 
+        wake_up_interruptible(&wait_queue_led_polling); //wake up and clean led module         
+#endif        
+        for(i=0;i<NUM_OF_REG_ENTRY;i++)
+               remove_proc_entry(regs[i].name, meidir);
+        remove_proc_entry(MEI_DIRNAME, &proc_root);
+       
+        disable_irq(AMAZON_MEI_INT);
+        free_irq(AMAZON_MEI_INT, NULL);
+        unregister_chrdev(major, "amazon_mei");
+
+        kfree(mei_mib);
+       kfree(clreoc_pkt);
+       
+       kfree(phy_mei_net.priv);
+        unregister_netdev(&phy_mei_net);
+       
+        return;
+}
+#ifdef IFX_SMALL_FOOTPRINT
+
+
+int adsl_mib_poll(void *unused)
+{
+       struct task_struct *tsk = current;
+       int i=0;
+       struct timeval time_now;
+       struct timeval time_fini;
+       u32 temp,temp2;
+
+       amazon_mei_mib * mib_ptr;
+//     u16 buff[MSG_LENGTH]__attribute__ ((aligned(4)));
+       u16 * data=NULL;  //used in makeCMV, to pass in payload when CMV set, ignored when CMV read.
+
+       daemonize();
+       strcpy(tsk->comm, "kmibpoll");
+       sigfillset(&tsk->blocked);
+
+       printk("Inside mib poll loop ...\n");
+       i=0;
+       while(1){
+               if(i<MIB_INTERVAL)
+                       interruptible_sleep_on_timeout(&wait_queue_mibdaemon, ((MIB_INTERVAL-i)/(1000/HZ)));
+               i=0;
+               if(showtime==1){
+//                     printk("\n\n update mib");
+                                       
+                       do_gettimeofday(&time_now);
+                       if(time_now.tv_sec - current_intvl->start_time.tv_sec>=900){
+                               if(current_intvl->list.next!=&interval_list){
+                                       current_intvl = list_entry(current_intvl->list.next, amazon_mei_mib, list);
+                                       do_gettimeofday(&(current_intvl->start_time));
+                               }
+                               else{
+                                       mib_ptr = list_entry(interval_list.next, amazon_mei_mib, list);
+                                       list_del(interval_list.next);
+                                       memset(mib_ptr, 0, sizeof(amazon_mei_mib));
+                                       list_add_tail(&(mib_ptr->list), &interval_list);
+                                       if(current_intvl->list.next==&interval_list)
+#ifdef AMAZON_MEI_DEBUG_ON
+                                       printk("\n\nlink list error");
+#endif
+                                       current_intvl = list_entry(current_intvl->list.next, amazon_mei_mib, list);
+                                       do_gettimeofday(&(current_intvl->start_time));
+                               }       
+                       }
+                                       
+                       if(down_interruptible(&mei_sema))
+                               return -ERESTARTSYS;
+/*                                             
+                       ATUC_PERF_LO_FLAG_MAKECMV;
+                       if(meiCMV(TxMessage, YES_REPLY)!=MEI_SUCCESS){
+#ifdef AMAZON_MEI_DEBUG_ON
+                               printk("\n\nCMV fail, Group 7 Address 0 Index 0");
+#endif
+                       }
+                       else{
+                               if(RxMessage[4]&PLAM_LOS_FailureBit){
+                                       current_intvl->AtucPerfLos++;
+                                       ATUC_PERF_LOSS++;
+                                       CurrStatus.adslAtucCurrStatus = 2;
+                               }
+                               if(RxMessage[4]&PLAM_LOF_FailureBit){
+                                       current_intvl->AtucPerfLof++;
+                                       ATUC_PERF_LOFS++;
+                                       CurrStatus.adslAtucCurrStatus = 1;
+                               }
+                               if(!(RxMessage[4]&(PLAM_LOS_FailureBit|PLAM_LOF_FailureBit)))
+                                       CurrStatus.adslAtucCurrStatus = 0;
+                               }
+*/
+                               
+                               if(showtime!=1)
+                                       goto mib_poll_end;
+                               ATUC_PERF_ESS_FLAG_MAKECMV;
+                               if(meiCMV(TxMessage, YES_REPLY)!=MEI_SUCCESS){
+#ifdef AMAZON_MEI_DEBUG_ON
+                                       printk("\n\nCMV fail, Group 7 Address 7 Index 0");
+#endif
+                               }
+                               else{
+                                               temp = RxMessage[4]-mib_pread.ATUC_PERF_ESS;
+                                               if(temp>=0){
+                                                       current_intvl->AtucPerfEs+=temp;
+                                                       ATUC_PERF_ESS+=temp;
+                                                       mib_pread.ATUC_PERF_ESS = RxMessage[4];
+                                               }
+                                               else{
+                                                       current_intvl->AtucPerfEs+=0xffff-mib_pread.ATUC_PERF_ESS+RxMessage[4];
+                                                       ATUC_PERF_ESS+=0xffff-mib_pread.ATUC_PERF_ESS+RxMessage[4];
+                                                       mib_pread.ATUC_PERF_ESS = RxMessage[4];         
+                                       }
+                               }
+/*             
+                               ATUR_PERF_LO_FLAG_MAKECMV;
+                               if(meiCMV(TxMessage, YES_REPLY)!=MEI_SUCCESS){
+#ifdef AMAZON_MEI_DEBUG_ON
+                                       printk("\n\nCMV fail, Group 7 Address 1 Index 0");
+#endif
+                               }
+                               else{
+                                       if(RxMessage[4]&PLAM_LOS_FailureBit){
+                                               current_intvl->AturPerfLos++;
+                                               ATUR_PERF_LOSS++;
+                                               CurrStatus.adslAturCurrStatus = 2;
+                                       }
+                                       if(RxMessage[4]&PLAM_LOF_FailureBit){
+                                               current_intvl->AturPerfLof++;
+                                               ATUR_PERF_LOFS++;
+                                               CurrStatus.adslAturCurrStatus = 1;
+                                       }
+                                       if(RxMessage[4]&PLAM_LPR_FailureBit){
+                                               current_intvl->AturPerfLpr++;
+                                               ATUR_PERF_LPR++;
+                                               CurrStatus.adslAturCurrStatus = 3;
+                                       }
+                                       if(!(RxMessage[4]&(PLAM_LOS_FailureBit|PLAM_LOF_FailureBit|PLAM_LPR_FailureBit)))
+                                               CurrStatus.adslAturCurrStatus = 0;      
+                               }
+*/
+                               if(showtime!=1)
+                                       goto mib_poll_end;
+                               ATUR_PERF_ESS_FLAG_MAKECMV;
+                               if(meiCMV(TxMessage, YES_REPLY)!=MEI_SUCCESS){
+#ifdef AMAZON_MEI_DEBUG_ON
+                                       printk("\n\nCMV fail, Group 7 Address 33 Index 0");
+#endif
+                               }
+                               else{
+                                               temp = RxMessage[4]-mib_pread.ATUR_PERF_ESS;
+                                               if(temp>=0){
+                                                       current_intvl->AturPerfEs+=temp;
+                                                       ATUR_PERF_ESS+=temp;
+                                                       mib_pread.ATUR_PERF_ESS = RxMessage[4];
+                                               }
+                                               else{
+                                                       current_intvl->AturPerfEs+=0xffff-mib_pread.ATUR_PERF_ESS+RxMessage[4];
+                                                       ATUR_PERF_ESS+= 0xffff-mib_pread.ATUR_PERF_ESS+RxMessage[4];
+                                                       mib_pread.ATUR_PERF_ESS=RxMessage[4];
+                                       }
+                               }
+                               if(showtime!=1)
+                                       goto mib_poll_end;
+                               // to update rx/tx blocks
+                               ATUR_CHAN_RECV_BLK_FLAG_MAKECMV_LSW;
+                               if(meiCMV(TxMessage, YES_REPLY)!=MEI_SUCCESS){
+#ifdef AMAZON_MEI_DEBUG_ON
+                                       printk("\n\nCMV fail, Group 7 Address 20 Index 0");
+#endif
+                               }
+                               else{
+                                               temp = RxMessage[4];    
+                               }
+                               if(showtime!=1)
+                                       goto mib_poll_end;
+                               ATUR_CHAN_RECV_BLK_FLAG_MAKECMV_MSW;
+                               if(meiCMV(TxMessage, YES_REPLY)!=MEI_SUCCESS){
+#ifdef AMAZON_MEI_DEBUG_ON
+                                       printk("\n\nCMV fail, Group 7 Address 21 Index 0");
+#endif
+                               }
+                               else{
+                                               temp2 = RxMessage[4];   
+                                       }       
+                                       if((temp + (temp2<<16) - mib_pread.ATUR_CHAN_RECV_BLK)>=0){
+                                               current_intvl->AturChanPerfRxBlk+=temp + (temp2<<16) - mib_pread.ATUR_CHAN_RECV_BLK;
+                                               ATUR_CHAN_RECV_BLK+=temp + (temp2<<16) - mib_pread.ATUR_CHAN_RECV_BLK;
+                                               mib_pread.ATUR_CHAN_RECV_BLK = temp + (temp2<<16);
+                                       }
+                                       else{
+                                               current_intvl->AturChanPerfRxBlk+=0xffffffff - mib_pread.ATUR_CHAN_RECV_BLK +(temp + (temp2<<16));
+                                               ATUR_CHAN_RECV_BLK+=0xffffffff - mib_pread.ATUR_CHAN_RECV_BLK +(temp + (temp2<<16));
+                                               mib_pread.ATUR_CHAN_RECV_BLK = temp + (temp2<<16);
+                               }
+                               current_intvl->AturChanPerfTxBlk = current_intvl->AturChanPerfRxBlk;
+                               ATUR_CHAN_TX_BLK = ATUR_CHAN_RECV_BLK;
+/*                                     
+                               ATUR_CHAN_TX_BLK_FLAG_MAKECMV_LSW;
+                               if(meiCMV(TxMessage, YES_REPLY)!=MEI_SUCCESS)
+                                       printk("\n\nCMV fail, Group 7 Address 20 Index 0");
+                               else{
+                                       if(RxMessage[4]){
+                                               current_intvl->AturChanPerfTxBlk+=RxMessage[4];
+                                               ATUR_CHAN_TX_BLK+=RxMessage[4];
+                                       }       
+                               }
+                               ATUR_CHAN_TX_BLK_FLAG_MAKECMV_MSW;
+                               if(meiCMV(TxMessage, YES_REPLY)!=MEI_SUCCESS)
+                                       printk("\n\nCMV fail, Group 7 Address 21 Index 0");
+                               else{
+                                       if(RxMessage[4]){
+                                               current_intvl->AturChanPerfTxBlk+=(int)((RxMessage[4])<<16);
+                                               ATUR_CHAN_TX_BLK+=(int)((RxMessage[4])<<16);
+                                       }       
+                               }
+*/                                     
+                               if(chantype.interleave == 1){
+                               if(showtime!=1)
+                                       goto mib_poll_end;
+                                       ATUR_CHAN_CORR_BLK_FLAG_MAKECMV_INTL;
+                                       if(meiCMV(TxMessage, YES_REPLY)!=MEI_SUCCESS){
+#ifdef AMAZON_MEI_DEBUG_ON
+                                               printk("\n\nCMV fail, Group 7 Address 3 Index 0");
+#endif
+                                       }
+                                       else{
+                                                       temp = RxMessage[4] - mib_pread.ATUR_CHAN_CORR_BLK_INTL;
+                                                       if(temp>=0){
+                                                               current_intvl->AturChanPerfCorrBlk+=temp;
+                                                               ATUR_CHAN_CORR_BLK+=temp;
+                                                               mib_pread.ATUR_CHAN_CORR_BLK_INTL = RxMessage[4];
+                                                       }       
+                                                       else{
+                                                               current_intvl->AturChanPerfCorrBlk+=0xffff - mib_pread.ATUR_CHAN_CORR_BLK_INTL +RxMessage[4];
+                                                               ATUR_CHAN_CORR_BLK+=0xffff - mib_pread.ATUR_CHAN_CORR_BLK_INTL +RxMessage[4];
+                                                               mib_pread.ATUR_CHAN_CORR_BLK_INTL = RxMessage[4];       
+                                               }       
+                                       }       
+                               }
+                               else if(chantype.fast == 1){
+                               if(showtime!=1)
+                                       goto mib_poll_end;
+                                       ATUR_CHAN_CORR_BLK_FLAG_MAKECMV_FAST;
+                                       if(meiCMV(TxMessage, YES_REPLY)!=MEI_SUCCESS){
+#ifdef AMAZON_MEI_DEBUG_ON
+                                               printk("\n\nCMV fail, Group 7 Address 3 Index 1");
+#endif
+                                       }
+                                       else{
+                                                       temp = RxMessage[4] - mib_pread.ATUR_CHAN_CORR_BLK_FAST;
+                                                       if(temp>=0){
+                                                               current_intvl->AturChanPerfCorrBlk+=temp;
+                                                               ATUR_CHAN_CORR_BLK+=temp;
+                                                               mib_pread.ATUR_CHAN_CORR_BLK_FAST = RxMessage[4];
+                                                       }       
+                                                       else{
+                                                               current_intvl->AturChanPerfCorrBlk+=0xffff - mib_pread.ATUR_CHAN_CORR_BLK_FAST + RxMessage[4];
+                                                               ATUR_CHAN_CORR_BLK+=0xffff - mib_pread.ATUR_CHAN_CORR_BLK_FAST + RxMessage[4];
+                                                               mib_pread.ATUR_CHAN_CORR_BLK_FAST = RxMessage[4];
+                                               }       
+                                       }               
+                               }
+                               
+                               if(chantype.interleave == 1){
+                               if(showtime!=1)
+                                       goto mib_poll_end;
+                                       ATUR_CHAN_UNCORR_BLK_FLAG_MAKECMV_INTL;
+                                       if(meiCMV(TxMessage, YES_REPLY)!=MEI_SUCCESS){
+#ifdef AMAZON_MEI_DEBUG_ON
+                                               printk("\n\nCMV fail, Group 7 Address 2 Index 0");
+#endif
+                                       }
+                                       else{
+                                                       temp = RxMessage[4] - mib_pread.ATUR_CHAN_UNCORR_BLK_INTL;
+                                                       if(temp>=0){
+                                                               current_intvl->AturChanPerfUncorrBlk+=temp;
+                                                               ATUR_CHAN_UNCORR_BLK+=temp;
+                                                               mib_pread.ATUR_CHAN_UNCORR_BLK_INTL = RxMessage[4];
+                                                       }
+                                                       else{
+                                                               current_intvl->AturChanPerfUncorrBlk+=0xffff - mib_pread.ATUR_CHAN_UNCORR_BLK_INTL + RxMessage[4];
+                                                               ATUR_CHAN_UNCORR_BLK+=0xffff - mib_pread.ATUR_CHAN_UNCORR_BLK_INTL + RxMessage[4];
+                                                               mib_pread.ATUR_CHAN_UNCORR_BLK_INTL = RxMessage[4];
+                                               }
+                                       }               
+                               }
+                               else if(chantype.fast == 1){
+                               if(showtime!=1)
+                                       goto mib_poll_end;
+                                       ATUR_CHAN_UNCORR_BLK_FLAG_MAKECMV_FAST;
+                                       if(meiCMV(TxMessage, YES_REPLY)!=MEI_SUCCESS){
+#ifdef AMAZON_MEI_DEBUG_ON
+                                               printk("\n\nCMV fail, Group 7 Address 2 Index 1");
+#endif
+                                       }
+                                       else{
+                                                       temp = RxMessage[4] - mib_pread.ATUR_CHAN_UNCORR_BLK_FAST;
+                                                       if(temp>=0){
+                                                               current_intvl->AturChanPerfUncorrBlk+=temp;
+                                                               ATUR_CHAN_UNCORR_BLK+=temp;
+                                                               mib_pread.ATUR_CHAN_UNCORR_BLK_FAST = RxMessage[4];
+                                                       }
+                                                       else{
+                                                               current_intvl->AturChanPerfUncorrBlk+=0xffff - mib_pread.ATUR_CHAN_UNCORR_BLK_FAST + RxMessage[4];
+                                                               ATUR_CHAN_UNCORR_BLK+=0xffff - mib_pread.ATUR_CHAN_UNCORR_BLK_FAST + RxMessage[4];
+                                                               mib_pread.ATUR_CHAN_UNCORR_BLK_FAST = RxMessage[4];
+                                               }
+                                       }               
+                               }
+                                       
+                               //RFC-3440
+
+#ifdef AMAZON_MEI_MIB_RFC3440
+                               if(showtime!=1)
+                                       goto mib_poll_end;
+                               ATUC_PERF_STAT_FASTR_FLAG_MAKECMV; //???
+                               if(meiCMV(TxMessage, YES_REPLY)!=MEI_SUCCESS){
+#ifdef AMAZON_MEI_DEBUG_ON
+                                       printk("\n\nCMV fail, Group 0 Address 0 Index 0");
+#endif
+                               }
+                               else{
+                                               temp = RxMessage[4] - mib_pread.ATUC_PERF_STAT_FASTR;
+                                               if(temp>=0){
+                                                       current_intvl->AtucPerfStatFastR+=temp;
+                                                       ATUC_PERF_STAT_FASTR+=temp;
+                                                       mib_pread.ATUC_PERF_STAT_FASTR = RxMessage[4];
+                                               }
+                                               else{
+                                                       current_intvl->AtucPerfStatFastR+=0xffff - mib_pread.ATUC_PERF_STAT_FASTR + RxMessage[4];
+                                                       ATUC_PERF_STAT_FASTR+=0xffff - mib_pread.ATUC_PERF_STAT_FASTR + RxMessage[4];
+                                                       mib_pread.ATUC_PERF_STAT_FASTR = RxMessage[4];
+                                       }
+                               }
+                               if(showtime!=1)
+                                       goto mib_poll_end;
+                               ATUC_PERF_STAT_FAILED_FASTR_FLAG_MAKECMV; //???
+                               if(meiCMV(TxMessage, YES_REPLY)!=MEI_SUCCESS){
+#ifdef AMAZON_MEI_DEBUG_ON
+                                       printk("\n\nCMV fail, Group 0 Address 0 Index 0");
+#endif
+                               }
+                               else{
+                                               temp = RxMessage[4] - mib_pread.ATUC_PERF_STAT_FAILED_FASTR;
+                                               if(temp>=0){
+                                                       current_intvl->AtucPerfStatFailedFastR+=temp;
+                                                       ATUC_PERF_STAT_FAILED_FASTR+=temp;
+                                                       mib_pread.ATUC_PERF_STAT_FAILED_FASTR = RxMessage[4];
+                                               }
+                                               else{
+                                                       current_intvl->AtucPerfStatFailedFastR+=0xffff - mib_pread.ATUC_PERF_STAT_FAILED_FASTR + RxMessage[4];
+                                                       ATUC_PERF_STAT_FAILED_FASTR+=0xffff - mib_pread.ATUC_PERF_STAT_FAILED_FASTR + RxMessage[4];
+                                                       mib_pread.ATUC_PERF_STAT_FAILED_FASTR = RxMessage[4];
+                                       }
+                               }
+                               if(showtime!=1)
+                                       goto mib_poll_end;
+                               ATUC_PERF_STAT_SESL_FLAG_MAKECMV;
+                               if(meiCMV(TxMessage, YES_REPLY)!=MEI_SUCCESS){
+#ifdef AMAZON_MEI_DEBUG_ON
+                                       printk("\n\nCMV fail, Group 7 Address 8 Index 0");
+#endif
+                               }
+                               else{
+                                               temp = RxMessage[4] - mib_pread.ATUC_PERF_STAT_SESL;
+                                               if(temp>=0){
+                                                       current_intvl->AtucPerfStatSesL+=temp;
+                                                       ATUC_PERF_STAT_SESL+=temp;
+                                                       mib_pread.ATUC_PERF_STAT_SESL = RxMessage[4];
+                                               }
+                                               else{
+                                                       current_intvl->AtucPerfStatSesL+=0xffff - mib_pread.ATUC_PERF_STAT_SESL + RxMessage[4];
+                                                       ATUC_PERF_STAT_SESL+=0xffff - mib_pread.ATUC_PERF_STAT_SESL + RxMessage[4];
+                                                       mib_pread.ATUC_PERF_STAT_SESL = RxMessage[4];
+                                       }
+                               }
+                               if(showtime!=1)
+                                       goto mib_poll_end;
+                               ATUC_PERF_STAT_UASL_FLAG_MAKECMV;
+                               if(meiCMV(TxMessage, YES_REPLY)!=MEI_SUCCESS){
+#ifdef AMAZON_MEI_DEBUG_ON
+                                       printk("\n\nCMV fail, Group 7 Address 10 Index 0");
+#endif
+                               }
+                               else{
+                                               temp = RxMessage[4] - mib_pread.ATUC_PERF_STAT_UASL;
+                                               if(temp>=0){
+                                                       current_intvl->AtucPerfStatUasL+=temp;
+                                                       ATUC_PERF_STAT_UASL+=temp;
+                                                       mib_pread.ATUC_PERF_STAT_UASL = RxMessage[4];
+                                               }
+                                               else{
+                                                       current_intvl->AtucPerfStatUasL+=0xffff - mib_pread.ATUC_PERF_STAT_UASL + RxMessage[4];
+                                                       ATUC_PERF_STAT_UASL+=0xffff - mib_pread.ATUC_PERF_STAT_UASL + RxMessage[4];
+                                                       mib_pread.ATUC_PERF_STAT_UASL = RxMessage[4];
+                                       }
+                               }
+                               if(showtime!=1)
+                                       goto mib_poll_end;
+                               ATUR_PERF_STAT_SESL_FLAG_MAKECMV;
+                               if(meiCMV(TxMessage, YES_REPLY)!=MEI_SUCCESS){
+#ifdef AMAZON_MEI_DEBUG_ON
+                                       printk("\n\nCMV fail, Group 7 Address 34 Index 0");
+#endif
+                               }
+                               else{
+                                               temp = RxMessage[4] - mib_pread.ATUR_PERF_STAT_SESL;
+                                               if(temp>=0){
+                                                       current_intvl->AtucPerfStatUasL+=temp;
+                                                       ATUC_PERF_STAT_UASL+=temp;
+                                                       mib_pread.ATUR_PERF_STAT_SESL = RxMessage[4];
+                                               }
+                                               else{
+                                                       current_intvl->AtucPerfStatUasL+=0xffff - mib_pread.ATUR_PERF_STAT_SESL + RxMessage[4];
+                                                       ATUC_PERF_STAT_UASL+=0xffff - mib_pread.ATUR_PERF_STAT_SESL + RxMessage[4];
+                                                       mib_pread.ATUR_PERF_STAT_SESL = RxMessage[4];
+                                       }
+                               }
+                                       
+#endif
+mib_poll_end:
+                               up(&mei_sema);
+                               
+                               do_gettimeofday(&time_fini);
+                               i = ((int)((time_fini.tv_sec-time_now.tv_sec)*1000)) + ((int)((time_fini.tv_usec-time_now.tv_usec)/1000))  ; //msec 
+                       }//showtime==1
+               }        
+       
+}
+int mib_poll_init(void)
+{
+       printk("Starting mib_poll...\n");
+
+       kernel_thread(adsl_mib_poll, NULL, CLONE_FS | CLONE_FILES | CLONE_SIGNAL);
+       return 0;
+}
+#endif //IFX_SMALL_FOOTPRINT
+//EXPORT_NO_SYMBOLS;
+
+#ifdef ADSL_LED_SUPPORT
+// adsl led -start
+int led_status_on=0,led_need_to_flash=0;
+int led_current_flashing=0;
+unsigned long led_delay=0;
+static int led_poll(void *unused)
+{
+       stop_led_module=0;      //begin polling ...
+       while(!stop_led_module){
+               if ((!led_status_on)&&(!led_need_to_flash)) interruptible_sleep_on_timeout (&wait_queue_led_polling,1000); //10 seconds timeout for waiting wakeup
+//                     else printk("direct running task, no waiting");
+               run_task_queue(&tq_ifx_led);//joelin task
+//     printk("led and LOP polling...\n");
+               }
+       return 0;       
+}      
+static int led_poll_init(void)
+{
+//     printk("Starting adsl led polling...\n");
+
+//warning-led-start
+//     CLEAR_BIT((*((volatile u32 *)0xB0100B40)), 0x40); //Warning LED GPIO ON
+//warning-led-end
+
+       kernel_thread(led_poll, NULL, CLONE_FS | CLONE_FILES | CLONE_SIGNAL);
+       return 0;
+}
+
+int adsl_led_flash(void)
+{      
+       int i;
+       if (!firmware_support_led)      return 0;       //joelin version check 
+
+       if (led_status_on == 0 && led_need_to_flash == 0)
+       {
+               queue_task(&led_task, &tq_ifx_led);//joelin task
+               wake_up_interruptible(&wait_queue_led_polling); //wake up and clean led module 
+//             printk("queue Task 1...\n");    //joelin  test  
+       }
+       led_need_to_flash=1;//asking to flash led
+
+       return 0;
+}
+
+int adsl_led_flash_task(void *ptr)
+{
+
+       u16     one=1;
+       u16     zero=0;
+       u16     data=0x0600;
+       int kernel_use=1;
+       u16 CMVMSG[MSG_LENGTH];                                                                           
+//adsl-led-start for >v1.1.2.7.1.1
+//     printk("Task Running...\n");    //joelin  test
+       if ((firmware_support_led==2)&&(led_support_check))
+       {
+       led_support_check=0;
+       data=0x0600;
+       makeCMV_local(H2D_CMV_WRITE, INFO, 91, 0, 1, &data,CMVMSG);     //configure GPIO9 GPIO10 as outputs
+       mei_ioctl((struct inode *)0,NULL, AMAZON_MEI_CMV_WINHOST, CMVMSG);
+
+       makeCMV_local(H2D_CMV_WRITE, INFO, 91, 2, 1, &data,CMVMSG);     //enable writing to bit 9 and bit10
+       mei_ioctl((struct inode *)0,NULL, AMAZON_MEI_CMV_WINHOST, CMVMSG);
+       
+       data=0x0a01;
+       makeCMV_local(H2D_CMV_WRITE, INFO, 91, 4, 1, &data,CMVMSG);     //use GPIO10 for TR68 .Enable and don't invert.
+       mei_ioctl((struct inode *)0,NULL, AMAZON_MEI_CMV_WINHOST, CMVMSG);      
+       
+#ifdef DATA_LED_ON_MODE        
+       data=0x0903;//tecom //use GPIO9 for TR68 data led .turn on.
+#else
+       data=0x0900;
+#endif 
+       makeCMV_local(H2D_CMV_WRITE, INFO, 91, 5, 1, &data,CMVMSG);     //use GPIO9 for TR68 data led .turn off.
+       mei_ioctl((struct inode *)0,NULL, AMAZON_MEI_CMV_WINHOST, CMVMSG);              
+       
+       }
+       if (!showtime) {led_need_to_flash=0; return 0;} 
+//adsl-led-end for >v1.1.2.7.1.1
+
+       if (led_status_on == 0 || led_need_to_flash == 1)
+       {
+
+               if (led_current_flashing==0)
+               {
+                       if (firmware_support_led==1){//>1.1.2.3.1.1
+                       makeCMV_local(H2D_CMV_WRITE, INFO, 91, 0, 1, &one,CMVMSG);      //flash
+                       mei_ioctl((struct inode *)0,NULL, AMAZON_MEI_CMV_WINHOST, &CMVMSG);     
+               }
+                       else if (firmware_support_led==2){//>1.1.2.7.1.1
+                               data=0x0901;//flash
+                               makeCMV_local(H2D_CMV_WRITE, INFO, 91, 5, 1, &data,CMVMSG);     //use GPIO9 for TR68 data led .flash.
+                               mei_ioctl((struct inode *)0,NULL, AMAZON_MEI_CMV_WINHOST, &CMVMSG);                     
+                               
+                       }//(firmware_support_led==2)
+                       led_current_flashing = 1;//turn on led
+               }
+               led_status_on=1;
+
+               do{//do nothing , waiting untill no data traffic 
+                       led_need_to_flash=0;
+                       interruptible_sleep_on_timeout(&wait_queue_led, 25); //the time for LED Off , if no data traffic                         
+               }while(led_need_to_flash==1);
+               
+       }else if (led_status_on == 1 && led_need_to_flash==0)
+       {
+               if (led_current_flashing==1)
+               {//turn off led
+                       if (firmware_support_led==1){//>1.1.2.3.1.1
+                       makeCMV_local(H2D_CMV_WRITE, INFO, 91, 0, 1, &zero,CMVMSG);//off        
+                       mei_ioctl((struct inode *)0,NULL, AMAZON_MEI_CMV_WINHOST, &CMVMSG);
+                       }       //>1.1.2.3.1.1          
+                       else if (firmware_support_led==2){//>1.1.2.7.1.1
+#ifdef DATA_LED_ON_MODE                                        
+                               data=0x0903;//tecom //use GPIO9 for TR68 data led .turn on.
+#else
+                               data=0x0900;//off
+#endif                         
+                               makeCMV_local(H2D_CMV_WRITE, INFO, 91, 5, 1, &data,CMVMSG);     //use GPIO9 for TR68 data led .off.
+                       mei_ioctl((struct inode *)0,NULL, AMAZON_MEI_CMV_WINHOST, &CMVMSG);
+                               
+                       }//(firmware_support_led==2)
+                       led_status_on=0;
+                       led_current_flashing = 0;
+               }
+               }
+       
+       if (led_status_on == 1 || led_need_to_flash)
+       {//led flash job on going or led need to flash 
+               queue_task(&led_task, &tq_ifx_led);     //joelin task   
+//             printk("queue Task 2...\n");    //joelin  test  
+       }
+       return 0;
+}
+//joelin adsl led-end
+#else 
+int adsl_led_flash(void)
+{
+       return 0;
+}
+#endif //ADSL_LED_SUPPORT
+#ifdef IFX_DYING_GASP
+static int lop_poll(void *unused)
+{
+       
+       while(1)
+       {
+       interruptible_sleep_on_timeout(&wait_queue_dying_gasp, 1); 
+#ifdef CONFIG_CPU_AMAZON_E //000003:fchang
+        if(showtime&&((*((volatile u32 *)0xB0100B14))&0x4)==0x0)       {//000003:fchang
+#else //000003:fchang
+       if(showtime&&((*((volatile u32 *)0xB0100B44))&0x8000)==0x0)     {
+#endif //CONFIG_CPU_AMAZON_E
+               mei_ioctl((struct inode *)0,NULL, AMAZON_MEI_WRITEDEBUG, &lop_debugwr);
+               printk("send dying gasp..\n");}
+               
+       }
+       return 0;       
+       }
+static int lop_poll_init(void)
+{
+//     printk("Starting LOP polling...\n");
+       kernel_thread(lop_poll, NULL, CLONE_FS | CLONE_FILES | CLONE_SIGNAL);
+       return 0;
+}
+
+#endif //IFX_DYING_GASP
+
+//joelin 04/16/2005-satrt
+static int unavailable_seconds_poll(void *unused)
+{
+       while(1){
+               interruptible_sleep_on_timeout (&wait_queue_uas_poll,100); //1 second timeout for waiting wakeup
+               if (!showtime) unavailable_seconds++;
+       }
+       return 0;       
+}      
+static int unavailable_seconds_poll_init(void)
+{
+  
+       kernel_thread(unavailable_seconds_poll, NULL, CLONE_FS | CLONE_FILES | CLONE_SIGNAL);
+       return 0;
+}
+
+
+//joelin 04/16/2005-end
+EXPORT_SYMBOL(meiDebugWrite);
+EXPORT_SYMBOL(ifx_pop_eoc);
+
+MODULE_LICENSE("GPL");
+
+module_init(amazon_mei_init_module);
+module_exit(amazon_mei_cleanup_module);
+
diff --git a/target/linux/amazon-2.6/files/drivers/char/amazon_wdt.c b/target/linux/amazon-2.6/files/drivers/char/amazon_wdt.c
new file mode 100644 (file)
index 0000000..c6a90f0
--- /dev/null
@@ -0,0 +1,261 @@
+/*
+ * Infineon AP DC COM  Amazon WDT driver
+ * Copyright 2004 Wu Qi Ming <gokimi@msn.com>
+ * All rights reserved
+ */
+#if defined(MODVERSIONS)
+#include <linux/modversions.h>
+#endif
+
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/sched.h>
+#include <linux/kernel.h>
+#include <linux/slab.h>
+#include <linux/string.h>
+#include <linux/timer.h>
+#include <linux/fs.h>
+#include <linux/errno.h>
+#include <linux/proc_fs.h>
+#include <linux/stat.h>
+#include <linux/tty.h>
+#include <linux/selection.h>
+#include <linux/kmod.h>
+#include <linux/vmalloc.h>
+#include <linux/kdev_t.h>
+#include <linux/ioctl.h>
+#include <asm/uaccess.h>
+#include <asm/system.h>
+#include <asm/amazon/amazon.h>
+#include <asm/amazon/amazon_wdt.h>
+
+#define AMAZON_WDT_EMSG(fmt, args...) printk( "%s: " fmt, __FUNCTION__ , ##args)
+
+extern unsigned int amazon_get_fpi_hz(void);
+
+/* forward declarations for _fops */
+static ssize_t wdt_read(struct file *file, char *buf, size_t count, loff_t *offset);
+static ssize_t wdt_write(struct file *file, const char *buf, size_t count, loff_t *offset);
+static int wdt_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg);
+static int wdt_open(struct inode *inode, struct file *file);
+static int wdt_release(struct inode *inode, struct file *file);
+static int wdt_proc_read(char *buf, char **start, off_t offset,int count, int *eof, void *data);
+
+
+static struct file_operations wdt_fops = {
+       read:wdt_read,
+       write:wdt_write,
+       ioctl:wdt_ioctl,
+       open:wdt_open,
+       release:wdt_release,    
+};
+
+/* data */
+static struct wdt_dev *amazon_wdt_dev;
+static struct proc_dir_entry* amazon_wdt_dir;
+static int occupied=0;
+
+
+/* Brief: enable WDT
+ * Parameter:
+       timeout: time interval for WDT
+ * Return:
+       0       OK
+               EINVAL
+ * Describes:
+       1. Password Access
+       2. Modify Access (change ENDINIT => 0)
+       3. Change WDT_CON1 (enable WDT)
+       4. Password Access again
+       5. Modify Access (change ENDINIT => 1)
+ */
+int wdt_enable(int timeout)
+{
+       u32 hard_psw,ffpi;
+       int reload_value, divider=0;
+  
+       ffpi = amazon_get_fpi_hz();
+       
+       divider = 1;
+       if((reload_value=65536-timeout*ffpi/256)<0){
+               divider = 0;
+               reload_value=65536-timeout*ffpi/16384;
+       }
+       if (reload_value < 0){
+               AMAZON_WDT_EMSG("timeout too large %d\n", timeout);
+               return -EINVAL;
+       }
+       
+       AMAZON_WDT_EMSG("timeout:%d reload_value: %8x\n", timeout, reload_value);
+       
+       hard_psw=(AMAZON_WDT_REG32(AMAZON_WDT_CON0)&0xffffff01)+(AMAZON_WDT_REG32(AMAZON_WDT_CON1)&0xc)+ 0xf0;  
+       AMAZON_WDT_REG32(AMAZON_WDT_CON0)=hard_psw;
+       wmb();
+       
+       AMAZON_WDT_REG32(AMAZON_WDT_CON0)=(hard_psw&0xff00)+(reload_value<<16)+0xf2;
+       wmb();
+
+       AMAZON_WDT_REG32(AMAZON_WDT_CON1)=divider<<2;  
+       wmb();
+       
+       hard_psw=(AMAZON_WDT_REG32(AMAZON_WDT_CON0)&0xffffff01)+(AMAZON_WDT_REG32(AMAZON_WDT_CON1)&0xc)+ 0xf0;
+       AMAZON_WDT_REG32(AMAZON_WDT_CON0)=hard_psw;
+       
+       wmb();
+       AMAZON_WDT_REG32(AMAZON_WDT_CON0)=(AMAZON_WDT_REG32(AMAZON_WDT_CON0)&0xffffff00)+0xf3;
+       wmb();
+       return 0;
+}
+
+/*     Brief:  Disable/stop WDT
+ */
+void wdt_disable(void)
+{
+       u32 hard_psw=0;
+       
+       hard_psw=(AMAZON_WDT_REG32(AMAZON_WDT_CON0)&0xffffff01)+(AMAZON_WDT_REG32(AMAZON_WDT_CON1)&0xc)+ 0xf0;  
+       AMAZON_WDT_REG32(AMAZON_WDT_CON0)=hard_psw;
+       wmb();
+
+       AMAZON_WDT_REG32(AMAZON_WDT_CON0)=(AMAZON_WDT_REG32(AMAZON_WDT_CON0)&0xffffff00)+0xf2;
+       wmb();
+       
+       AMAZON_WDT_REG32(AMAZON_WDT_CON1)|=8;  
+       wmb();
+       
+       hard_psw=(AMAZON_WDT_REG32(AMAZON_WDT_CON0)&0xffffff01)+(AMAZON_WDT_REG32(AMAZON_WDT_CON1)&0xc)+ 0xf0;  
+       AMAZON_WDT_REG32(AMAZON_WDT_CON0)=hard_psw;
+       wmb();
+
+       AMAZON_WDT_REG32(AMAZON_WDT_CON0)=(AMAZON_WDT_REG32(AMAZON_WDT_CON0)&0xffffff00)+0xf3;
+       wmb();
+       
+       return;
+}
+
+static int wdt_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg)
+{
+        int result=0;
+       static int timeout=-1;
+        
+        switch(cmd){
+         case AMAZON_WDT_IOC_START:
+               AMAZON_WDT_DMSG("enable watch dog timer!\n");
+               if ( copy_from_user((void*)&timeout, (void*)arg, sizeof (int)) ){
+                       AMAZON_WDT_EMSG("invalid argument\n");
+                       result=-EINVAL;
+               }else{
+                       if ((result = wdt_enable(timeout)) < 0){
+                               timeout = -1;
+                       }
+               }
+               break;
+        case AMAZON_WDT_IOC_STOP:
+               AMAZON_WDT_DMSG("disable watch dog timer\n");
+               timeout = -1;
+               wdt_disable();
+               
+               break;
+       case AMAZON_WDT_IOC_PING:
+               if (timeout <0 ){
+                       result = -EIO;
+               }else{
+                       result = wdt_enable(timeout); 
+               }               
+       }
+       return result;
+}
+
+static ssize_t wdt_read(struct file *file, char *buf, size_t count, loff_t *offset)
+{
+       return 0;
+}
+
+static ssize_t wdt_write(struct file *file, const char *buf, size_t count, loff_t *offset)
+{      
+       return count;
+}
+
+static int wdt_open(struct inode *inode, struct file *file)
+{
+        AMAZON_WDT_DMSG("wdt_open\n");
+       
+       if (occupied == 1) return -EBUSY;
+       occupied = 1;
+       
+       return 0;
+}
+
+static int wdt_release(struct inode *inode, struct file *file)
+{
+        AMAZON_WDT_DMSG("wdt_release\n"); 
+       
+       occupied = 0;
+       return 0;
+}
+
+
+int wdt_register_proc_read(char *buf, char **start, off_t offset,
+                         int count, int *eof, void *data)
+{
+       int len=0;
+       printk("wdt_registers:\n");
+       len+=sprintf(buf+len,"NMISR:    0x%08x\n",AMAZON_WDT_REG32(AMAZON_WDT_NMISR));
+       len+=sprintf(buf+len,"RST_REQ:  0x%08x\n",AMAZON_WDT_REG32(AMAZON_RST_REQ));
+       len+=sprintf(buf+len,"RST_SR:   0x%08x\n",AMAZON_WDT_REG32(AMAZON_RST_SR));
+       len+=sprintf(buf+len,"WDT_CON0: 0x%08x\n",AMAZON_WDT_REG32(AMAZON_WDT_CON0));
+       len+=sprintf(buf+len,"WDT_CON1: 0x%08x\n",AMAZON_WDT_REG32(AMAZON_WDT_CON1));
+       len+=sprintf(buf+len,"WDT_SR:   0x%08x\n",AMAZON_WDT_REG32(AMAZON_WDT_SR));
+       *eof = 1;
+       return len;
+}
+
+
+int __init amazon_wdt_init_module(void)
+{
+       int result=0;
+
+       amazon_wdt_dev = (wdt_dev*)kmalloc(sizeof(wdt_dev),GFP_KERNEL);
+       if (amazon_wdt_dev == NULL){
+               return -ENOMEM;
+       }
+       memset(amazon_wdt_dev,0,sizeof(wdt_dev));
+       
+       amazon_wdt_dev->major=result;
+       strcpy(amazon_wdt_dev->name,"wdt");
+       
+       result = register_chrdev(0,amazon_wdt_dev->name,&wdt_fops);
+       if (result < 0) {
+               AMAZON_WDT_EMSG("cannot register device\n");
+               kfree(amazon_wdt_dev);
+                       return result;
+       }
+
+       amazon_wdt_dir=proc_mkdir("amazon_wdt",NULL);
+       create_proc_read_entry("wdt_register",
+                               0,
+                               amazon_wdt_dir,
+                               wdt_register_proc_read,
+                               NULL);  
+   
+       occupied=0;
+       return 0;
+}
+
+void amazon_wdt_cleanup_module(void)
+{
+       unregister_chrdev(amazon_wdt_dev->major,amazon_wdt_dev->name);
+        kfree(amazon_wdt_dev); 
+       remove_proc_entry("wdt_register",amazon_wdt_dir);
+       remove_proc_entry("amazon_wdt",NULL);
+        AMAZON_WDT_DMSG("unloaded\n");
+       return;
+}
+
+MODULE_LICENSE ("GPL");
+MODULE_AUTHOR("Infineon IFAP DC COM");
+MODULE_DESCRIPTION("AMAZON WDT driver");
+
+module_init(amazon_wdt_init_module);
+module_exit(amazon_wdt_cleanup_module);
+
diff --git a/target/linux/amazon-2.6/files/drivers/char/ifx_ssc.c b/target/linux/amazon-2.6/files/drivers/char/ifx_ssc.c
new file mode 100644 (file)
index 0000000..ea01659
--- /dev/null
@@ -0,0 +1,2121 @@
+/**************************************************
+ *
+ * drivers/ifx/serial/ifx_ssc.c
+ *
+ * Driver for IFX_SSC serial ports
+ *
+ * Copyright (C) 2004 Infineon Technologies AG
+ * Author Michael Schoenenborn (IFX COM TI BT)
+ *
+ */
+#define IFX_SSC_DRV_VERSION "0.2.1"
+/*
+ **************************************************
+ *
+ * This driver was originally based on the INCA-IP driver, but due to 
+ * fundamental conceptual drawbacks there has been changed a lot.
+ *
+ * Based on INCA-IP driver Copyright (c) 2003 Gary Jennejohn <gj@denx.de>
+ * Based on the VxWorks drivers Copyright (c) 2002, Infineon Technologies.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ */
+
+// ### TO DO: general issues:
+//           - power management
+//           - interrupt handling (direct/indirect)
+//           - pin/mux-handling (just overall concept due to project dependency)
+//           - multiple instances capability
+//           - slave functionality
+
+/*
+ * Include section 
+ */
+#ifndef EXPORT_SYMTAB
+#define EXPORT_SYMTAB
+#endif
+
+#include <linux/config.h>
+#include <linux/module.h>
+#include <linux/errno.h>
+#include <linux/signal.h>
+#include <linux/sched.h>
+#include <linux/timer.h>
+#include <linux/interrupt.h>
+#include <linux/major.h>
+#include <linux/string.h>
+#include <linux/fs.h>
+#include <linux/proc_fs.h>
+#include <linux/fcntl.h>
+#include <linux/ptrace.h>
+#include <linux/mm.h>
+#include <linux/ioport.h>
+#include <linux/init.h>
+#include <linux/delay.h>
+#include <linux/spinlock.h>
+#include <linux/slab.h>
+//#include <linux/poll.h>
+
+#include <asm/system.h>
+#include <asm/io.h>
+#include <asm/irq.h>
+#include <asm/uaccess.h>
+#include <asm/bitops.h>
+
+#include <linux/types.h>
+#include <linux/kernel.h>
+#include <linux/version.h>
+
+#include <asm/amazon/amazon.h>
+#include <asm/amazon/irq.h>
+#include <asm/amazon/ifx_ssc_defines.h>
+#include <asm/amazon/ifx_ssc.h>
+
+#ifdef SSC_FRAME_INT_ENABLE
+#undef SSC_FRAME_INT_ENABLE
+#endif
+
+#define not_yet
+
+#define SPI_VINETIC
+
+/*
+ * Deal with CONFIG_MODVERSIONS
+ */
+#if CONFIG_MODVERSIONS==1
+# include <linux/modversions.h>
+#endif
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Michael Schoenenborn");
+MODULE_DESCRIPTION("IFX SSC driver");
+MODULE_SUPPORTED_DEVICE("ifx_ssc");
+MODULE_PARM(maj, "i");
+MODULE_PARM_DESC(maj, "Major device number");
+
+/* allow the user to set the major device number */
+static int maj = 0;
+
+
+/*
+ * This is the per-channel data structure containing pointers, flags
+ * and variables for the port. This driver supports a maximum of PORT_CNT.
+ * isp is allocated in ifx_ssc_init() based on the chip version.
+ */
+static struct ifx_ssc_port *isp;
+
+/* prototypes for fops */
+static ssize_t ifx_ssc_read(struct file *, char *, size_t, loff_t *);
+static ssize_t ifx_ssc_write(struct file *, const char *, size_t, loff_t *);
+//static unsigned int ifx_ssc_poll(struct file *, struct poll_table_struct *);
+int ifx_ssc_ioctl(struct inode *, struct file *, unsigned int, unsigned long);
+int ifx_ssc_open(struct inode *, struct file *);
+int ifx_ssc_close(struct inode *, struct file *);
+
+/* other forward declarations */
+static unsigned int ifx_ssc_get_kernel_clk(struct ifx_ssc_port *info);
+static void ifx_ssc_rx_int(int, void *, struct pt_regs *);
+static void ifx_ssc_tx_int(int, void *, struct pt_regs *);
+static void ifx_ssc_err_int(int, void *, struct pt_regs *);
+#ifdef SSC_FRAME_INT_ENABLE
+static void ifx_ssc_frm_int(int, void *, struct pt_regs *);
+#endif
+static void tx_int(struct ifx_ssc_port *);
+static int ifx_ssc1_read_proc(char *, char **, off_t, int, int *, void *);
+static void ifx_gpio_init(void);
+/************************************************************************
+ *  Function declaration
+ ************************************************************************/
+//interrupt.c
+extern unsigned int amazon_get_fpi_hz(void);
+extern void disable_amazon_irq(unsigned int irq_nr);
+extern void enable_amazon_irq(unsigned int irq_nr);
+extern void mask_and_ack_amazon_irq(unsigned int irq_nr);
+
+
+/*****************************************************************/
+typedef struct {
+       int (*request)(unsigned int irq, 
+                      void (*handler)(int, void *, struct pt_regs *), 
+                      unsigned long irqflags,
+                      const char * devname, 
+                      void *dev_id);
+       void (*free)(unsigned int irq, void *dev_id);
+       void (*enable)(unsigned int irq);
+       void (*disable)(unsigned int irq);
+        void (*clear)(unsigned int irq);
+} ifx_int_wrapper_t;
+
+static ifx_int_wrapper_t ifx_int_wrapper = {
+       request:        request_irq,    // IM action: enable int
+       free:           free_irq,       // IM action: disable int
+       enable:         enable_amazon_irq,
+       disable:        disable_amazon_irq,
+        clear:          mask_and_ack_amazon_irq,
+       //end:          
+};
+
+/* Fops-struct */
+static struct file_operations ifx_ssc_fops = {
+        owner:         THIS_MODULE,
+       read:           ifx_ssc_read,    /* read */
+       write:          ifx_ssc_write,   /* write */
+//        poll:                ifx_ssc_poll,    /* poll */
+        ioctl:         ifx_ssc_ioctl,   /* ioctl */
+        open:          ifx_ssc_open,    /* open */
+        release:       ifx_ssc_close,   /* release */
+};
+
+
+static inline unsigned int ifx_ssc_get_kernel_clk(struct ifx_ssc_port *info)
+{ // ATTENTION: This function assumes that the CLC register is set with the 
+  // appropriate value for RMC.
+       unsigned int rmc;
+
+       rmc = (READ_PERIPHERAL_REGISTER(info->mapbase + IFX_SSC_CLC) & 
+              IFX_CLC_RUN_DIVIDER_MASK) >> IFX_CLC_RUN_DIVIDER_OFFSET;
+       if (rmc == 0){
+               printk("ifx_ssc_get_kernel_clk rmc==0 \n");
+               return (0);
+       }
+       return (amazon_get_fpi_hz() / rmc);
+}
+
+#ifndef not_yet
+#ifdef IFX_SSC_INT_USE_BH
+/*
+ * This routine is used by the interrupt handler to schedule
+ * processing in the software interrupt portion of the driver
+ * (also known as the "bottom half").  This can be called any
+ * number of times for any channel without harm.
+ */
+static inline void
+ifx_ssc_sched_event(struct ifx_ssc_port *info, int event)
+{
+    info->event |= 1 << event; /* remember what kind of event and who */
+    queue_task(&info->tqueue, &tq_cyclades); /* it belongs to */
+    mark_bh(CYCLADES_BH);                       /* then trigger event */
+} /* ifx_ssc_sched_event */
+
+
+/*
+ * This routine is used to handle the "bottom half" processing for the
+ * serial driver, known also the "software interrupt" processing.
+ * This processing is done at the kernel interrupt level, after the
+ * cy#/_interrupt() has returned, BUT WITH INTERRUPTS TURNED ON.  This
+ * is where time-consuming activities which can not be done in the
+ * interrupt driver proper are done; the interrupt driver schedules
+ * them using ifx_ssc_sched_event(), and they get done here.
+ *
+ * This is done through one level of indirection--the task queue.
+ * When a hardware interrupt service routine wants service by the
+ * driver's bottom half, it enqueues the appropriate tq_struct (one
+ * per port) to the tq_cyclades work queue and sets a request flag
+ * via mark_bh for processing that queue.  When the time is right,
+ * do_ifx_ssc_bh is called (because of the mark_bh) and it requests
+ * that the work queue be processed.
+ *
+ * Although this may seem unwieldy, it gives the system a way to
+ * pass an argument (in this case the pointer to the ifx_ssc_port
+ * structure) to the bottom half of the driver.  Previous kernels
+ * had to poll every port to see if that port needed servicing.
+ */
+static void
+do_ifx_ssc_bh(void)
+{
+    run_task_queue(&tq_cyclades);
+} /* do_ifx_ssc_bh */
+
+static void
+do_softint(void *private_)
+{
+  struct ifx_ssc_port *info = (struct ifx_ssc_port *) private_;
+
+    if (test_and_clear_bit(Cy_EVENT_HANGUP, &info->event)) {
+        wake_up_interruptible(&info->open_wait);
+        info->flags &= ~(ASYNC_NORMAL_ACTIVE|
+                             ASYNC_CALLOUT_ACTIVE);
+    }
+    if (test_and_clear_bit(Cy_EVENT_OPEN_WAKEUP, &info->event)) {
+        wake_up_interruptible(&info->open_wait);
+    }
+    if (test_and_clear_bit(Cy_EVENT_DELTA_WAKEUP, &info->event)) {
+       wake_up_interruptible(&info->delta_msr_wait);
+    }
+    if (test_and_clear_bit(Cy_EVENT_WRITE_WAKEUP, &info->event)) {
+        wake_up_interruptible(&tty->write_wait);
+    }
+#ifdef Z_WAKE
+    if (test_and_clear_bit(Cy_EVENT_SHUTDOWN_WAKEUP, &info->event)) {
+        wake_up_interruptible(&info->shutdown_wait);
+    }
+#endif
+} /* do_softint */
+#endif /* IFX_SSC_INT_USE_BH */
+#endif // not_yet
+
+inline static void
+rx_int(struct ifx_ssc_port *info)
+{
+       int             fifo_fill_lev, bytes_in_buf, i;
+       unsigned long   tmp_val;
+       unsigned long   *tmp_ptr;
+       unsigned int    rx_valid_cnt;
+       /* number of words waiting in the RX FIFO */
+       fifo_fill_lev = (READ_PERIPHERAL_REGISTER(info->mapbase + 
+                                                  IFX_SSC_FSTAT) & 
+                         IFX_SSC_FSTAT_RECEIVED_WORDS_MASK) >>
+                         IFX_SSC_FSTAT_RECEIVED_WORDS_OFFSET;
+        // Note: There are always 32 bits in a fifo-entry except for the last 
+        // word of a contigous transfer block and except for not in rx-only 
+        // mode and CON.ENBV set. But for this case it should be a convention 
+        // in software which helps:
+        // In tx or rx/tx mode all transfers from the buffer to the FIFO are 
+        // 32-bit wide, except for the last three bytes, which could be a 
+        // combination of 16- and 8-bit access.
+        // => The whole block is received as 32-bit words as a contigous stream, 
+        // even if there was a gap in tx which has the fifo run out of data! 
+        // Just the last fifo entry *may* be partially filled (0, 1, 2 or 3 bytes)!
+
+       /* free space in the RX buffer */
+       bytes_in_buf = info->rxbuf_end - info->rxbuf_ptr;
+        // transfer with 32 bits per entry
+       while ((bytes_in_buf >= 4) && (fifo_fill_lev > 0)) {
+               tmp_ptr = (unsigned long *)info->rxbuf_ptr;
+                *tmp_ptr = READ_PERIPHERAL_REGISTER(info->mapbase + IFX_SSC_RB);
+                info->rxbuf_ptr += 4;
+                info->stats.rxBytes += 4;
+                fifo_fill_lev --;
+                bytes_in_buf -= 4;
+       } // while ((bytes_in_buf >= 4) && (fifo_fill_lev > 0))
+        // now do the rest as mentioned in STATE.RXBV
+        while ((bytes_in_buf > 0) && (fifo_fill_lev > 0)) {
+                rx_valid_cnt = (READ_PERIPHERAL_REGISTER(info->mapbase + IFX_SSC_STATE) & 
+                                IFX_SSC_STATE_RX_BYTE_VALID_MASK) >> 
+                        IFX_SSC_STATE_RX_BYTE_VALID_OFFSET;
+               if (rx_valid_cnt == 0) break;
+                if (rx_valid_cnt > bytes_in_buf) {
+                        // ### TO DO: warning message: not block aligned data, other data 
+                        //                             in this entry will be lost
+                        rx_valid_cnt = bytes_in_buf;
+                }
+                tmp_val = READ_PERIPHERAL_REGISTER(info->mapbase + IFX_SSC_RB);
+               
+                for (i=0; i<rx_valid_cnt; i++) {               
+                       *info->rxbuf_ptr = (tmp_val >> ( 8 * (rx_valid_cnt - i-1))) & 0xff;
+/*                     
+                        *info->rxbuf_ptr = tmp_val & 0xff;
+                        tmp_val >>= 8;
+*/                     
+                       bytes_in_buf--;
+
+                       
+                       info->rxbuf_ptr++;
+                }
+                info->stats.rxBytes += rx_valid_cnt;
+        }  // while ((bytes_in_buf > 0) && (fifo_fill_lev > 0))
+
+        // check if transfer is complete
+        if (info->rxbuf_ptr >= info->rxbuf_end) {
+                ifx_int_wrapper.disable(info->rxirq);
+                /* wakeup any processes waiting in read() */
+                wake_up_interruptible(&info->rwait);
+                /* and in poll() */
+                //wake_up_interruptible(&info->pwait);
+        } else if ((info->opts.modeRxTx == IFX_SSC_MODE_RX) && 
+                  (READ_PERIPHERAL_REGISTER(info->mapbase + IFX_SSC_RXCNT) == 0)) {
+               // if buffer not filled completely and rx request done initiate new transfer
+/*
+               if  (info->rxbuf_end - info->rxbuf_ptr < 65536)
+*/
+               if  (info->rxbuf_end - info->rxbuf_ptr < IFX_SSC_RXREQ_BLOCK_SIZE)
+                        WRITE_PERIPHERAL_REGISTER((info->rxbuf_end - info->rxbuf_ptr) << 
+                                                 IFX_SSC_RXREQ_RXCOUNT_OFFSET, 
+                                                  info->mapbase + IFX_SSC_RXREQ);
+                else 
+                       WRITE_PERIPHERAL_REGISTER(IFX_SSC_RXREQ_BLOCK_SIZE << IFX_SSC_RXREQ_RXCOUNT_OFFSET, 
+                                                  info->mapbase + IFX_SSC_RXREQ);
+       }
+} // rx_int
+
+inline static void
+tx_int(struct ifx_ssc_port *info)
+{
+       
+       int fifo_space, fill, i;
+       fifo_space = ((READ_PERIPHERAL_REGISTER(info->mapbase + IFX_SSC_ID) & 
+                       IFX_SSC_PERID_TXFS_MASK) >> IFX_SSC_PERID_TXFS_OFFSET) - 
+                ((READ_PERIPHERAL_REGISTER(info->mapbase + IFX_SSC_FSTAT) & 
+                  IFX_SSC_FSTAT_TRANSMIT_WORDS_MASK) >> 
+                 IFX_SSC_FSTAT_TRANSMIT_WORDS_OFFSET);
+
+       if (fifo_space == 0)
+               return;
+
+       fill = info->txbuf_end - info->txbuf_ptr;
+
+       if (fill > fifo_space * 4)
+               fill = fifo_space * 4;
+
+       for (i = 0; i < fill / 4; i++) {
+                // at first 32 bit access
+               WRITE_PERIPHERAL_REGISTER(*(UINT32 *)info->txbuf_ptr, info->mapbase + IFX_SSC_TB);
+                info->txbuf_ptr += 4;
+       }
+
+        fifo_space -= fill / 4;
+       info->stats.txBytes += fill & ~0x3;
+        fill &= 0x3;
+        if ((fifo_space > 0) & (fill > 1)) {
+                // trailing 16 bit access
+                WRITE_PERIPHERAL_REGISTER_16(*(UINT16 *)info->txbuf_ptr, info->mapbase + IFX_SSC_TB);
+                info->txbuf_ptr += 2;
+                info->stats.txBytes += 2;
+                fifo_space --;
+/* added by bingtao */
+               fill -=2;
+       }
+        if ((fifo_space > 0) & (fill > 0)) {
+                // trailing 8 bit access
+                WRITE_PERIPHERAL_REGISTER_8(*(UINT8 *)info->txbuf_ptr, info->mapbase + IFX_SSC_TB);
+                info->txbuf_ptr ++;
+                info->stats.txBytes ++;
+/*
+                fifo_space --;
+*/
+       }
+
+        // check if transmission complete
+        if (info->txbuf_ptr >= info->txbuf_end) {
+                ifx_int_wrapper.disable(info->txirq);
+                kfree(info->txbuf);
+                info->txbuf = NULL;
+                /* wake up any process waiting in poll() */
+                //wake_up_interruptible(&info->pwait);
+        }      
+
+} // tx_int
+
+static void
+ifx_ssc_rx_int(int irq, void *dev_id, struct pt_regs *regs)
+{
+       struct ifx_ssc_port *info = (struct ifx_ssc_port *)dev_id;
+       //WRITE_PERIPHERAL_REGISTER(IFX_SSC_R_BIT, info->mapbase + IFX_SSC_IRN_CR);
+        rx_int(info);
+}
+
+static void
+ifx_ssc_tx_int(int irq, void *dev_id, struct pt_regs *regs)
+{
+       struct ifx_ssc_port *info = (struct ifx_ssc_port *)dev_id;
+       //WRITE_PERIPHERAL_REGISTER(IFX_SSC_T_BIT, info->mapbase + IFX_SSC_IRN_CR);
+        tx_int(info);
+}
+
+static void
+ifx_ssc_err_int(int irq, void *dev_id, struct pt_regs *regs)
+{
+       struct ifx_ssc_port *info = (struct ifx_ssc_port *)dev_id;
+       unsigned int state;
+       unsigned int write_back = 0;
+       unsigned long flags;
+
+
+       local_irq_save(flags);
+       state = READ_PERIPHERAL_REGISTER(info->mapbase + IFX_SSC_STATE); 
+
+       if ((state & IFX_SSC_STATE_RX_UFL) != 0) {
+               info->stats.rxUnErr++;
+               write_back |= IFX_SSC_WHBSTATE_CLR_RX_UFL_ERROR;
+       }
+       if ((state & IFX_SSC_STATE_RX_OFL) != 0) {
+               info->stats.rxOvErr++;
+               write_back |= IFX_SSC_WHBSTATE_CLR_RX_OFL_ERROR;
+       }
+       if ((state & IFX_SSC_STATE_TX_OFL) != 0) {
+               info->stats.txOvErr++;
+               write_back |= IFX_SSC_WHBSTATE_CLR_TX_OFL_ERROR;
+       }
+       if ((state & IFX_SSC_STATE_TX_UFL) != 0) {
+               info->stats.txUnErr++;
+               write_back |= IFX_SSC_WHBSTATE_CLR_TX_UFL_ERROR;
+       }
+//     if ((state & IFX_SSC_STATE_ABORT_ERR) != 0) {
+//             info->stats.abortErr++;
+//             write_back |= IFX_SSC_WHBSTATE_CLR_ABORT_ERROR;
+//     }
+       if ((state & IFX_SSC_STATE_MODE_ERR) != 0) {
+               info->stats.modeErr++;
+               write_back |= IFX_SSC_WHBSTATE_CLR_MODE_ERROR;
+       }
+
+       if (write_back)
+               WRITE_PERIPHERAL_REGISTER(write_back, 
+                                         info->mapbase + IFX_SSC_WHBSTATE);
+
+       local_irq_restore(flags);
+}
+
+#ifdef SSC_FRAME_INT_ENABLE
+static void
+ifx_ssc_frm_int(int irq, void *dev_id, struct pt_regs *regs)
+{
+       // ### TO DO: wake up framing wait-queue in conjunction with batch execution
+}
+#endif
+
+static void
+ifx_ssc_abort(struct ifx_ssc_port *info)
+{
+       unsigned long flags;
+       bool enabled;
+
+        local_irq_save(flags);
+
+       // disable all int's
+       ifx_int_wrapper.disable(info->rxirq);
+       ifx_int_wrapper.disable(info->txirq);
+       ifx_int_wrapper.disable(info->errirq);
+/*
+       ifx_int_wrapper.disable(info->frmirq);
+*/
+        local_irq_restore(flags);
+
+       // disable SSC (also aborts a receive request!)
+       // ### TO DO: Perhaps it's better to abort after the receiption of a 
+       // complete word. The disable cuts the transmission immediatly and 
+       // releases the chip selects. This could result in unpredictable 
+       // behavior of connected external devices!
+       enabled = (READ_PERIPHERAL_REGISTER(info->mapbase + IFX_SSC_STATE) 
+                  & IFX_SSC_STATE_IS_ENABLED) != 0;
+       WRITE_PERIPHERAL_REGISTER(IFX_SSC_WHBSTATE_CLR_ENABLE, 
+                                 info->mapbase + IFX_SSC_WHBSTATE);
+
+
+       // flush fifos
+        WRITE_PERIPHERAL_REGISTER(IFX_SSC_XFCON_FIFO_FLUSH, 
+                                  info->mapbase + IFX_SSC_TXFCON);
+        WRITE_PERIPHERAL_REGISTER(IFX_SSC_XFCON_FIFO_FLUSH, 
+                                  info->mapbase + IFX_SSC_RXFCON);
+
+       // free txbuf
+       if (info->txbuf != NULL) {
+               kfree(info->txbuf);
+               info->txbuf = NULL;
+       }
+
+       // wakeup read process
+       if (info->rxbuf != NULL)
+               wake_up_interruptible(&info->rwait);
+
+       // clear pending int's 
+       ifx_int_wrapper.clear(info->rxirq);
+       ifx_int_wrapper.clear(info->txirq);
+       ifx_int_wrapper.clear(info->errirq);
+/*
+       ifx_int_wrapper.clear(info->frmirq);
+*/
+
+       // clear error flags
+       WRITE_PERIPHERAL_REGISTER(IFX_SSC_WHBSTATE_CLR_ALL_ERROR,
+                                 info->mapbase + IFX_SSC_WHBSTATE);
+
+       //printk("IFX SSC%d: Transmission aborted\n", info->port_nr);
+       // enable SSC
+       if (enabled)
+               WRITE_PERIPHERAL_REGISTER(IFX_SSC_WHBSTATE_SET_ENABLE, 
+                                         info->mapbase + IFX_SSC_WHBSTATE);
+
+} // ifx_ssc_abort
+
+
+/*
+ * This routine is called whenever a port is opened.  It enforces
+ * exclusive opening of a port and enables interrupts, etc.
+ */
+int
+ifx_ssc_open(struct inode *inode, struct file * filp)
+{
+       struct ifx_ssc_port  *info;
+       int line;
+       int from_kernel = 0;
+
+       if ((inode == (struct inode *)0) || (inode == (struct inode *)1)) {
+               from_kernel = 1;
+               line = (int)inode;
+       }
+       else {
+               line = MINOR(filp->f_dentry->d_inode->i_rdev);
+               filp->f_op = &ifx_ssc_fops;
+       }
+
+       /* don't open more minor devices than we can support */
+       if (line < 0 || line >= PORT_CNT)
+               return -ENXIO;
+
+       info = &isp[line];
+
+       /* exclusive open */
+       if (info->port_is_open != 0)
+               return -EBUSY;
+       info->port_is_open++;
+
+       ifx_int_wrapper.disable(info->rxirq);
+       ifx_int_wrapper.disable(info->txirq);
+       ifx_int_wrapper.disable(info->errirq);
+/*
+       ifx_int_wrapper.disable(info->frmirq);
+*/
+
+       /* Flush and enable TX/RX FIFO */
+       WRITE_PERIPHERAL_REGISTER((IFX_SSC_DEF_TXFIFO_FL << 
+                                   IFX_SSC_XFCON_ITL_OFFSET) | 
+                                 IFX_SSC_XFCON_FIFO_FLUSH   |
+                                  IFX_SSC_XFCON_FIFO_ENABLE, 
+                                  info->mapbase + IFX_SSC_TXFCON);
+        WRITE_PERIPHERAL_REGISTER((IFX_SSC_DEF_RXFIFO_FL << 
+                                   IFX_SSC_XFCON_ITL_OFFSET) |
+                                 IFX_SSC_XFCON_FIFO_FLUSH   | 
+                                  IFX_SSC_XFCON_FIFO_ENABLE, 
+                                  info->mapbase + IFX_SSC_RXFCON);
+
+
+       /* logically flush the software FIFOs */
+       info->rxbuf_ptr = 0;
+       info->txbuf_ptr = 0;
+
+       /* clear all error bits */
+       WRITE_PERIPHERAL_REGISTER(IFX_SSC_WHBSTATE_CLR_ALL_ERROR,
+                                 info->mapbase + IFX_SSC_WHBSTATE);
+
+       // clear pending interrupts
+       ifx_int_wrapper.clear(info->rxirq);
+       ifx_int_wrapper.clear(info->txirq);
+       ifx_int_wrapper.clear(info->errirq);
+/*
+       ifx_int_wrapper.clear(info->frmirq);
+*/
+
+       // enable SSC
+       WRITE_PERIPHERAL_REGISTER(IFX_SSC_WHBSTATE_SET_ENABLE, 
+                                 info->mapbase + IFX_SSC_WHBSTATE);
+
+       MOD_INC_USE_COUNT;
+
+       return 0;
+} /* ifx_ssc_open */
+EXPORT_SYMBOL(ifx_ssc_open);
+
+/*
+ * This routine is called when a particular device is closed.
+ */
+int
+ifx_ssc_close(struct inode *inode, struct file *filp)
+{
+       struct ifx_ssc_port *info;
+        int idx;
+
+       if ((inode == (struct inode *)0) || (inode == (struct inode *)1))
+               idx = (int)inode;
+       else
+               idx = MINOR(filp->f_dentry->d_inode->i_rdev);
+
+       if (idx < 0 || idx >= PORT_CNT)
+               return -ENXIO;
+
+       info = &isp[idx];
+        if (!info)
+                return -ENXIO;
+
+       // disable SSC
+       WRITE_PERIPHERAL_REGISTER(IFX_SSC_WHBSTATE_CLR_ENABLE, 
+                                 info->mapbase + IFX_SSC_WHBSTATE);
+
+       // call abort function to disable int's, flush fifos...
+       ifx_ssc_abort(info);
+
+       info->port_is_open --;
+       MOD_DEC_USE_COUNT;
+
+       return 0;
+} /* ifx_ssc_close */
+EXPORT_SYMBOL(ifx_ssc_close);
+
+/* added by bingtao */
+/* helper routine to handle reads from the kernel or user-space */
+/* info->rxbuf : never kfree and contains valid data */
+/* should be points to NULL after copying data !!! */
+static ssize_t
+ifx_ssc_read_helper_poll(struct ifx_ssc_port *info, char *buf, size_t len,
+                    int from_kernel)
+{
+        ssize_t         ret_val;
+       unsigned long   flags;
+
+        if (info->opts.modeRxTx == IFX_SSC_MODE_TX) 
+                return -EFAULT;
+        local_irq_save(flags);
+        info->rxbuf_ptr = info->rxbuf;
+        info->rxbuf_end = info->rxbuf + len;
+        local_irq_restore(flags);
+/* Vinetic driver always works in IFX_SSC_MODE_RXTX */ 
+/* TXRX in poll mode */
+       while (info->rxbuf_ptr < info->rxbuf_end){
+/* This is the key point, if you don't check this condition 
+   kfree (NULL) will happen 
+   because tx only need write into FIFO, it's much fast than rx
+   So when rx still waiting , tx already finish and release buf        
+*/     
+               if (info->txbuf_ptr < info->txbuf_end) {
+                       tx_int(info);
+               }
+               
+               rx_int(info);
+        };
+
+        ret_val = info->rxbuf_ptr - info->rxbuf; 
+       return (ret_val);
+} // ifx_ssc_read_helper_poll
+
+/* helper routine to handle reads from the kernel or user-space */
+/* info->rx_buf : never kfree and contains valid data */
+/* should be points to NULL after copying data !!! */
+static ssize_t
+ifx_ssc_read_helper(struct ifx_ssc_port *info, char *buf, size_t len,
+                    int from_kernel)
+{
+        ssize_t         ret_val;
+       unsigned long   flags;
+        DECLARE_WAITQUEUE(wait, current);
+
+        if (info->opts.modeRxTx == IFX_SSC_MODE_TX) 
+                return -EFAULT;
+        local_irq_save(flags);
+        info->rxbuf_ptr = info->rxbuf;
+        info->rxbuf_end = info->rxbuf + len;
+        if (info->opts.modeRxTx == IFX_SSC_MODE_RXTX) {
+                if ((info->txbuf == NULL) ||
+                    (info->txbuf != info->txbuf_ptr) ||
+                    (info->txbuf_end != len + info->txbuf)) {
+                        local_irq_restore(flags);
+                        printk("IFX SSC - %s: write must be called before calling "
+                               "read in combined RX/TX!\n", __FUNCTION__);
+                        return -EFAULT;
+                }
+               local_irq_restore(flags);
+               /* should enable tx, right?*/
+               tx_int(info);
+               if (info->txbuf_ptr < info->txbuf_end){
+                       ifx_int_wrapper.enable(info->txirq);
+               }
+                
+               ifx_int_wrapper.enable(info->rxirq);
+        } else { // rx mode
+               local_irq_restore(flags);
+                if (READ_PERIPHERAL_REGISTER(info->mapbase + IFX_SSC_RXCNT) &
+                    IFX_SSC_RXCNT_TODO_MASK)
+                        return -EBUSY;
+               ifx_int_wrapper.enable(info->rxirq);
+               // rx request limited to ' bytes
+/*
+                if (len < 65536)
+*/
+                if (len < IFX_SSC_RXREQ_BLOCK_SIZE)
+                        WRITE_PERIPHERAL_REGISTER(len << IFX_SSC_RXREQ_RXCOUNT_OFFSET, 
+                                                  info->mapbase + IFX_SSC_RXREQ);
+                else 
+                       WRITE_PERIPHERAL_REGISTER(IFX_SSC_RXREQ_BLOCK_SIZE << IFX_SSC_RXREQ_RXCOUNT_OFFSET, 
+                                                  info->mapbase + IFX_SSC_RXREQ);
+        }
+
+        __add_wait_queue(&info->rwait, &wait);
+        set_current_state(TASK_INTERRUPTIBLE);
+        // wakeup done in rx_int
+        do {
+               local_irq_save(flags);
+                if (info->rxbuf_ptr >= info->rxbuf_end)
+                        break;
+               local_irq_restore(flags);
+
+//                if (filp->f_flags & O_NONBLOCK)
+//                {
+//                        N = -EAGAIN;
+//                        goto out;
+//                }
+                if (signal_pending(current)) {
+                        ret_val = -ERESTARTSYS;
+                        goto out;
+                }
+                schedule();
+        } while (1);
+
+        ret_val = info->rxbuf_ptr - info->rxbuf; // should be equal to len
+       local_irq_restore(flags);
+
+  out:
+        current->state = TASK_RUNNING;
+        __remove_wait_queue(&info->rwait, &wait);
+       return (ret_val);
+} // ifx_ssc_read_helper
+
+
+#if 0
+/* helper routine to handle reads from the kernel or user-space */
+/* appropriate in interrupt context */
+static ssize_t
+ifx_ssc_read_helper(struct ifx_ssc_port *info, char *buf, size_t len,
+                    int from_kernel)
+{
+        ssize_t         ret_val;
+       unsigned long   flags;
+               DECLARE_WAITQUEUE(wait, current);
+       
+        if (info->opts.modeRxTx == IFX_SSC_MODE_TX) 
+                return -EFAULT;
+        local_irq_save(flags);
+        info->rxbuf_ptr = info->rxbuf;
+        info->rxbuf_end = info->rxbuf + len;
+        if (info->opts.modeRxTx == IFX_SSC_MODE_RXTX) {
+                if ((info->txbuf == NULL) ||
+                    (info->txbuf != info->txbuf_ptr) ||
+                    (info->txbuf_end != len + info->txbuf)) {
+                        local_irq_restore(flags);
+                        printk("IFX SSC - %s: write must be called before calling "
+                               "read in combined RX/TX!\n", __FUNCTION__);
+                        return -EFAULT;
+                }
+               local_irq_restore(flags);
+               /* should enable tx, right?*/
+               tx_int(info);
+               if (!in_irq()){
+                       if (info->txbuf_ptr < info->txbuf_end){
+                               ifx_int_wrapper.enable(info->txirq);
+                       }
+                       ifx_int_wrapper.enable(info->rxirq);
+               }
+        } else { // rx mode
+               local_irq_restore(flags);
+                if (READ_PERIPHERAL_REGISTER(info->mapbase + IFX_SSC_RXCNT) &
+                    IFX_SSC_RXCNT_TODO_MASK)
+                        return -EBUSY;
+               if (!in_irq()){
+                       ifx_int_wrapper.enable(info->rxirq);
+               }
+
+                if (len < IFX_SSC_RXREQ_BLOCK_SIZE)
+                        WRITE_PERIPHERAL_REGISTER(len << IFX_SSC_RXREQ_RXCOUNT_OFFSET, 
+                                                  info->mapbase + IFX_SSC_RXREQ);
+                else 
+                       WRITE_PERIPHERAL_REGISTER(IFX_SSC_RXREQ_BLOCK_SIZE << IFX_SSC_RXREQ_RXCOUNT_OFFSET, 
+                                                  info->mapbase + IFX_SSC_RXREQ);
+        }
+       if (in_irq()){
+               do {
+                       rx_int(info);
+                       if (info->opts.modeRxTx == IFX_SSC_MODE_RXTX) {
+                               tx_int(info);
+                       }
+                       
+                       if (info->rxbuf_ptr >= info->rxbuf_end)
+                               break;
+               } while (1);
+               ret_val = info->rxbuf_ptr - info->rxbuf;
+       }else{
+               __add_wait_queue(&info->rwait, &wait);
+               set_current_state(TASK_INTERRUPTIBLE);
+               // wakeup done in rx_int
+       
+               do {
+                       local_irq_save(flags);
+                       if (info->rxbuf_ptr >= info->rxbuf_end)
+                               break;
+                       local_irq_restore(flags);
+
+                       if (signal_pending(current)) {
+                               ret_val = -ERESTARTSYS;
+                               goto out;
+                       }
+                       schedule();
+               } while (1);
+
+               ret_val = info->rxbuf_ptr - info->rxbuf; // should be equal to len
+               local_irq_restore(flags);
+
+  out:
+               current->state = TASK_RUNNING;
+               __remove_wait_queue(&info->rwait, &wait);
+       }
+       return (ret_val);
+} // ifx_ssc_read_helper
+#endif
+
+/* helper routine to handle writes to the kernel or user-space */
+/* info->txbuf has two cases:
+ *     1) return value < 0 (-EFAULT), not touched at all
+ *     2) kfree and points to NULL in interrupt routine (but maybe later )
+ */
+static ssize_t
+ifx_ssc_write_helper(struct ifx_ssc_port *info, const char *buf,
+               size_t len, int from_kernel)
+{
+        // check if in tx or tx/rx mode
+        if (info->opts.modeRxTx == IFX_SSC_MODE_RX)
+                return -EFAULT;
+
+        info->txbuf_ptr = info->txbuf;
+        info->txbuf_end = len + info->txbuf;
+       /* start the transmission (not in rx/tx, see read helper) */
+        if (info->opts.modeRxTx == IFX_SSC_MODE_TX) {
+               tx_int(info);
+               if (info->txbuf_ptr < info->txbuf_end){
+                       ifx_int_wrapper.enable(info->txirq);
+               }
+        }
+       //local_irq_restore(flags);
+        return len;
+}
+
+/*
+ * kernel interfaces for read and write.
+ * The caller must set port to: n for SSC<m> with n=m-1 (e.g. n=0 for SSC1)
+ */
+ssize_t
+ifx_ssc_kread(int port, char *kbuf, size_t len)
+{
+       struct ifx_ssc_port *info;
+        ssize_t ret_val;
+
+       if (port < 0 || port >= PORT_CNT)
+               return -ENXIO;
+
+        if (len == 0)
+                return 0;
+
+       info = &isp[port];
+
+        // check if reception in progress
+        if (info->rxbuf != NULL){
+               printk("SSC device busy\n");
+                return -EBUSY;
+       }
+
+       info->rxbuf = kbuf;
+        if (info->rxbuf == NULL){
+               printk("SSC device error\n");
+                return -EINVAL;
+       }
+
+/* changed by bingtao */
+       /* change by TaiCheng */
+       //if (!in_irq()){
+       if (0){
+               ret_val = ifx_ssc_read_helper(info, kbuf, len, 1);
+       }else{
+               ret_val = ifx_ssc_read_helper_poll(info, kbuf, len, 1);
+       };              
+       info->rxbuf = NULL;
+
+        // ### TO DO: perhaps warn if ret_val != len
+       ifx_int_wrapper.disable(info->rxirq);
+
+        return (ret_val);
+} // ifx_ssc_kread
+EXPORT_SYMBOL(ifx_ssc_kread);
+
+ssize_t
+ifx_ssc_kwrite(int port, const char *kbuf, size_t len)
+{
+       struct ifx_ssc_port *info;
+       ssize_t ret_val;
+
+       if (port < 0 || port >= PORT_CNT)
+               return -ENXIO;
+
+        if (len == 0)
+                return 0;
+
+       info = &isp[port];
+
+        // check if transmission in progress
+        if (info->txbuf != NULL)
+                return -EBUSY;
+        info->txbuf = (char *)kbuf;
+
+       ret_val = ifx_ssc_write_helper(info, info->txbuf, len, 1);
+       if (ret_val < 0){
+               info->txbuf = NULL;
+       }
+       return ret_val;
+}
+EXPORT_SYMBOL(ifx_ssc_kwrite);
+
+
+/* 
+ * user interfaces to read and write
+ */
+static ssize_t
+ifx_ssc_read(struct file *filp, char *ubuf, size_t len, loff_t *off)
+{
+        ssize_t ret_val;
+        int idx;
+       struct ifx_ssc_port *info;
+
+/*
+        if (len == 0)
+                return (0);
+*/
+        idx = MINOR(filp->f_dentry->d_inode->i_rdev);
+       info = &isp[idx];
+
+        // check if reception in progress
+        if (info->rxbuf != NULL)
+                return -EBUSY;
+
+       info->rxbuf = kmalloc(len+ 3, GFP_KERNEL);
+        if (info->rxbuf == NULL)
+                return -ENOMEM;
+
+       ret_val = ifx_ssc_read_helper(info, info->rxbuf, len, 0);
+       // ### TO DO: perhaps warn if ret_val != len
+        if (copy_to_user((void*)ubuf, info->rxbuf, ret_val) != 0)
+                ret_val = -EFAULT;
+
+       ifx_int_wrapper.disable(info->rxirq);
+
+        kfree(info->rxbuf);
+       info->rxbuf = NULL;
+        return (ret_val);
+} // ifx_ssc_read
+
+/*
+ * As many bytes as we have free space for are copied from the user
+ * into txbuf and the actual byte count is returned. The transmission is
+ * always kicked off by calling the appropriate TX routine.
+ */
+static ssize_t
+ifx_ssc_write(struct file *filp, const char *ubuf, size_t len, loff_t *off)
+{
+        int idx;
+       struct ifx_ssc_port *info;
+       int ret_val;
+
+        if (len == 0)
+                return (0);
+
+        idx = MINOR(filp->f_dentry->d_inode->i_rdev);
+       info = &isp[idx];
+
+        // check if transmission in progress
+        if (info->txbuf != NULL)
+                return -EBUSY;
+
+       info->txbuf = kmalloc(len+ 3, GFP_KERNEL);
+        if (info->txbuf == NULL)
+                return -ENOMEM;
+
+       ret_val = copy_from_user(info->txbuf, ubuf, len);
+       if (ret_val == 0)
+               ret_val = ifx_ssc_write_helper(info, info->txbuf, len, 0);
+       else
+               ret_val = -EFAULT;
+       if (ret_val < 0) {
+                kfree(info->txbuf); // otherwise will be done in ISR
+               info->txbuf = NULL;
+       }
+       return (ret_val);
+} /* ifx_ssc_write */
+
+
+/*
+ * ------------------------------------------------------------
+ * ifx_ssc_ioctl() and friends
+ * ------------------------------------------------------------
+ */
+
+/*-----------------------------------------------------------------------------
+ FUNC-NAME  : ifx_ssc_frm_status_get
+ LONG-NAME  : framing status get
+ PURPOSE    : Get the actual status of the framing.
+
+ PARAMETER  : *info    pointer to the port-specific structure ifx_ssc_port.
+
+ RESULT     : pointer to a structure ifx_ssc_frm_status which holds busy and 
+             count values.
+
+ REMARKS    : Returns a register value independent of framing is enabled or 
+             not! Changes structure inside of info, so the return value isn't 
+             needed at all, but could be used for simple access.
+-----------------------------------------------------------------------------*/
+static struct ifx_ssc_frm_status *
+ifx_ssc_frm_status_get(struct ifx_ssc_port *info)
+{
+       unsigned long tmp;
+       
+       tmp = READ_PERIPHERAL_REGISTER(info->mapbase + IFX_SSC_SFSTAT);
+       info->frm_status.DataBusy = (tmp & IFX_SSC_SFSTAT_IN_DATA) > 0;
+       info->frm_status.PauseBusy = (tmp & IFX_SSC_SFSTAT_IN_PAUSE) > 0;
+       info->frm_status.DataCount = (tmp & IFX_SSC_SFSTAT_DATA_COUNT_MASK) 
+               >> IFX_SSC_SFSTAT_DATA_COUNT_OFFSET;
+       info->frm_status.PauseCount = (tmp & IFX_SSC_SFSTAT_PAUSE_COUNT_MASK) 
+               >> IFX_SSC_SFSTAT_PAUSE_COUNT_OFFSET;
+       tmp = READ_PERIPHERAL_REGISTER(info->mapbase + IFX_SSC_SFCON);
+       info->frm_status.EnIntAfterData = 
+               (tmp & IFX_SSC_SFCON_FIR_ENABLE_BEFORE_PAUSE) > 0;
+       info->frm_status.EnIntAfterPause = 
+               (tmp & IFX_SSC_SFCON_FIR_ENABLE_AFTER_PAUSE) > 0;
+       return (&info->frm_status);
+} // ifx_ssc_frm_status_get
+
+
+/*-----------------------------------------------------------------------------
+ FUNC-NAME  : ifx_ssc_frm_control_get
+ LONG-NAME  : framing control get
+ PURPOSE    : Get the actual control values of the framing.
+
+ PARAMETER  : *info    pointer to the port-specific structure ifx_ssc_port.
+
+ RESULT     : pointer to a structure ifx_ssc_frm_opts which holds control bits  
+             and count reload values.
+
+ REMARKS    : Changes structure inside of info, so the return value isn't 
+             needed at all, but could be used for simple access.
+-----------------------------------------------------------------------------*/
+static struct ifx_ssc_frm_opts *
+ifx_ssc_frm_control_get(struct ifx_ssc_port *info)
+{
+       unsigned long tmp;
+       
+       tmp = READ_PERIPHERAL_REGISTER(info->mapbase + IFX_SSC_SFCON);
+       info->frm_opts.FrameEnable = (tmp & IFX_SSC_SFCON_SF_ENABLE) > 0;
+       info->frm_opts.DataLength = (tmp & IFX_SSC_SFCON_DATA_LENGTH_MASK) 
+               >> IFX_SSC_SFCON_DATA_LENGTH_OFFSET;
+       info->frm_opts.PauseLength = (tmp & IFX_SSC_SFCON_PAUSE_LENGTH_MASK) 
+               >> IFX_SSC_SFCON_PAUSE_LENGTH_OFFSET;
+       info->frm_opts.IdleData = (tmp & IFX_SSC_SFCON_PAUSE_DATA_MASK) 
+               >> IFX_SSC_SFCON_PAUSE_DATA_OFFSET;
+       info->frm_opts.IdleClock = (tmp & IFX_SSC_SFCON_PAUSE_CLOCK_MASK) 
+               >> IFX_SSC_SFCON_PAUSE_CLOCK_OFFSET;
+       info->frm_opts.StopAfterPause = 
+               (tmp & IFX_SSC_SFCON_STOP_AFTER_PAUSE) > 0;
+       return (&info->frm_opts);
+} // ifx_ssc_frm_control_get
+
+
+/*-----------------------------------------------------------------------------
+ FUNC-NAME  : ifx_ssc_frm_control_set
+ LONG-NAME  : framing control set
+ PURPOSE    : Set the actual control values of the framing.
+
+ PARAMETER  : *info    pointer to the port-specific structure ifx_ssc_port.
+
+ RESULT     : pointer to a structure ifx_ssc_frm_opts which holds control bits  
+             and count reload values.
+
+ REMARKS    : 
+-----------------------------------------------------------------------------*/
+static int
+ifx_ssc_frm_control_set(struct ifx_ssc_port *info)
+{
+       unsigned long tmp;
+
+       // check parameters
+       if ((info->frm_opts.DataLength > IFX_SSC_SFCON_DATA_LENGTH_MAX) || 
+           (info->frm_opts.DataLength < 1) ||
+           (info->frm_opts.PauseLength > IFX_SSC_SFCON_PAUSE_LENGTH_MAX) || 
+           (info->frm_opts.PauseLength < 1) ||
+           ((info->frm_opts.IdleData & ~(IFX_SSC_SFCON_PAUSE_DATA_MASK >> 
+                                         IFX_SSC_SFCON_PAUSE_DATA_OFFSET)) != 0 ) || 
+           ((info->frm_opts.IdleClock & ~(IFX_SSC_SFCON_PAUSE_CLOCK_MASK >> 
+                                          IFX_SSC_SFCON_PAUSE_CLOCK_OFFSET)) != 0 ))
+               return -EINVAL;
+
+       // read interrupt bits (they're not changed here)
+       tmp = READ_PERIPHERAL_REGISTER(info->mapbase + IFX_SSC_SFCON) &
+               (IFX_SSC_SFCON_FIR_ENABLE_BEFORE_PAUSE | 
+                IFX_SSC_SFCON_FIR_ENABLE_AFTER_PAUSE);
+
+       // set all values with respect to it's bit position (for data and pause 
+       // length set N-1)
+       tmp = (info->frm_opts.DataLength - 1) << IFX_SSC_SFCON_DATA_LENGTH_OFFSET;
+       tmp |= (info->frm_opts.PauseLength - 1) << IFX_SSC_SFCON_PAUSE_LENGTH_OFFSET;
+       tmp |= info->frm_opts.IdleData << IFX_SSC_SFCON_PAUSE_DATA_OFFSET;
+       tmp |= info->frm_opts.IdleClock << IFX_SSC_SFCON_PAUSE_CLOCK_OFFSET;
+       tmp |= info->frm_opts.FrameEnable * IFX_SSC_SFCON_SF_ENABLE;
+       tmp |= info->frm_opts.StopAfterPause * IFX_SSC_SFCON_STOP_AFTER_PAUSE;
+
+       WRITE_PERIPHERAL_REGISTER(tmp, info->mapbase + IFX_SSC_SFCON);
+
+       return 0;
+} // ifx_ssc_frm_control_set
+
+
+/*-----------------------------------------------------------------------------
+ FUNC-NAME  : ifx_ssc_rxtx_mode_set
+ LONG-NAME  : rxtx mode set
+ PURPOSE    : Set the transmission mode.
+
+ PARAMETER  : *info    pointer to the port-specific structure ifx_ssc_port.
+
+ RESULT     : Returns error code
+
+ REMARKS    : Assumes that SSC not used (SSC disabled, device not opened yet 
+             or just closed) 
+-----------------------------------------------------------------------------*/
+static int
+ifx_ssc_rxtx_mode_set(struct ifx_ssc_port *info, unsigned int val)
+{
+       unsigned long tmp;
+
+       // check parameters
+       if (!(info) || (val & ~(IFX_SSC_MODE_MASK)))
+               return -EINVAL;
+       /*check BUSY and RXCNT*/        
+       if (  READ_PERIPHERAL_REGISTER(info->mapbase + IFX_SSC_STATE) & IFX_SSC_STATE_BUSY
+           ||READ_PERIPHERAL_REGISTER(info->mapbase + IFX_SSC_RXCNT) & IFX_SSC_RXCNT_TODO_MASK)
+               return -EBUSY;
+       // modify 
+       tmp = (READ_PERIPHERAL_REGISTER(info->mapbase + IFX_SSC_CON) &
+               ~(IFX_SSC_CON_RX_OFF | IFX_SSC_CON_TX_OFF)) | (val);
+       WRITE_PERIPHERAL_REGISTER(tmp, info->mapbase + IFX_SSC_CON);
+       info->opts.modeRxTx = val;
+/*     
+       printk(KERN_DEBUG "IFX SSC%d: Setting mode to %s%s\n", 
+              info->port_nr,
+              ((val & IFX_SSC_CON_RX_OFF) == 0) ? "rx ":"", 
+              ((val & IFX_SSC_CON_TX_OFF) == 0) ? "tx":"");
+*/
+       return 0;
+} // ifx_ssc_rxtx_mode_set
+
+void ifx_gpio_init(void) 
+{
+       u32     temp;
+/* set gpio pin p0.10(SPI_DIN) p0.11(SPI_DOUT) p0.12(SPI_CLK) p0.13(SPI_CS2) direction */
+       temp = *(AMAZON_GPIO_P0_DIR) ;
+       temp &= 0xFFFFFBFF;
+       temp |= 0x3800;
+       *(AMAZON_GPIO_P0_DIR) = temp;
+/* set port 0 alternate select register 0 */
+       temp = *(AMAZON_GPIO_P0_ALTSEL0) ;
+       temp &= 0xFFFFC3FF;
+       temp |= 0x00001c00;
+       *(AMAZON_GPIO_P0_ALTSEL0) = temp;
+
+/* set port 0 alternate select register 1 */
+       temp = *(AMAZON_GPIO_P0_ALTSEL1) ;
+       temp &= 0xFFFFC3FF;
+       temp |= 0x00002000;
+       *(AMAZON_GPIO_P0_ALTSEL1) = temp;
+
+/* set port 0 open drain mode register */
+       temp = *(AMAZON_GPIO_P0_OD);
+       temp |= 0x00003800;     /* set output pin normal mode */
+       *(AMAZON_GPIO_P0_OD)= temp;
+}
+
+/*
+ * This routine intializes the SSC appropriately depending
+ * on slave/master and full-/half-duplex mode.
+ * It assumes that the SSC is disabled and the fifo's and buffers 
+ * are flushes later on.
+ */
+static int
+ifx_ssc_sethwopts(struct ifx_ssc_port *info)
+{
+       unsigned long flags, bits;
+       struct ifx_ssc_hwopts *opts = &info->opts;
+
+       /* sanity checks */
+       if ((opts->dataWidth < IFX_SSC_MIN_DATA_WIDTH) ||
+           (opts->dataWidth > IFX_SSC_MAX_DATA_WIDTH)) {
+               printk("%s: sanity check failed\n", __FUNCTION__);
+               return -EINVAL;
+       }
+        bits = (opts->dataWidth - 1) << IFX_SSC_CON_DATA_WIDTH_OFFSET;
+       bits |= IFX_SSC_CON_ENABLE_BYTE_VALID;
+//     if (opts->abortErrDetect)
+//             bits |= IFX_SSC_CON_ABORT_ERR_CHECK;
+       if (opts->rxOvErrDetect)
+               bits |= IFX_SSC_CON_RX_OFL_CHECK;
+       if (opts->rxUndErrDetect)
+               bits |= IFX_SSC_CON_RX_UFL_CHECK;
+       if (opts->txOvErrDetect)
+               bits |= IFX_SSC_CON_TX_OFL_CHECK;
+       if (opts->txUndErrDetect)
+               bits |= IFX_SSC_CON_TX_UFL_CHECK;
+       if (opts->loopBack)
+               bits |= IFX_SSC_CON_LOOPBACK_MODE;
+       if (opts->echoMode)
+               bits |= IFX_SSC_CON_ECHO_MODE_ON;
+       if (opts->headingControl)
+               bits |= IFX_SSC_CON_MSB_FIRST;
+       if (opts->clockPhase)
+               bits |= IFX_SSC_CON_LATCH_THEN_SHIFT;
+       if (opts->clockPolarity)
+               bits |= IFX_SSC_CON_CLOCK_FALL;
+       switch (opts->modeRxTx) {
+       case IFX_SSC_MODE_TX:
+               bits |= IFX_SSC_CON_RX_OFF;
+               break;
+       case IFX_SSC_MODE_RX:
+               bits |= IFX_SSC_CON_TX_OFF;
+               break;
+       } // switch (opts->modeRxT)
+       local_irq_save(flags);
+        WRITE_PERIPHERAL_REGISTER(bits, info->mapbase + IFX_SSC_CON);
+        WRITE_PERIPHERAL_REGISTER((info->opts.gpoCs << IFX_SSC_GPOCON_ISCSB0_POS) | 
+                                 (info->opts.gpoInv << IFX_SSC_GPOCON_INVOUT0_POS), 
+                                 info->mapbase + IFX_SSC_GPOCON);
+       //master mode
+       if (opts->masterSelect){
+               WRITE_PERIPHERAL_REGISTER(IFX_SSC_WHBSTATE_SET_MASTER_SELECT,info->mapbase + IFX_SSC_WHBSTATE);
+       }else{
+               WRITE_PERIPHERAL_REGISTER(IFX_SSC_WHBSTATE_CLR_MASTER_SELECT,info->mapbase + IFX_SSC_WHBSTATE);
+       }
+       // init serial framing
+        WRITE_PERIPHERAL_REGISTER(0, info->mapbase + IFX_SSC_SFCON);
+       /* set up the port pins */
+        //check for general requirements to switch (external) pad/pin characteristics
+       ifx_gpio_init();
+       local_irq_restore(flags);
+
+       return 0;
+} // ifx_ssc_sethwopts
+
+static int
+ifx_ssc_set_baud(struct ifx_ssc_port *info, unsigned int baud)
+{
+       unsigned int ifx_ssc_clock;
+       unsigned int br;
+       unsigned long flags;
+       bool enabled;
+
+       ifx_ssc_clock = ifx_ssc_get_kernel_clk(info);
+       if (ifx_ssc_clock ==0)
+               return -EINVAL;
+
+       local_irq_save(flags);
+       /* have to disable the SSC to set the baudrate */
+       enabled = (READ_PERIPHERAL_REGISTER(info->mapbase + IFX_SSC_STATE) 
+                  & IFX_SSC_STATE_IS_ENABLED) != 0;
+       WRITE_PERIPHERAL_REGISTER(IFX_SSC_WHBSTATE_CLR_ENABLE, 
+                                 info->mapbase + IFX_SSC_WHBSTATE);
+
+       // compute divider
+       br = ((ifx_ssc_clock >> 1)/baud) - 1;
+       asm("SYNC"); 
+       if (br > 0xffff || 
+           ((br == 0) && 
+            ((READ_PERIPHERAL_REGISTER(info->mapbase + IFX_SSC_STATE) & 
+              IFX_SSC_STATE_IS_MASTER) == 0))){
+               local_irq_restore(flags);
+               printk("%s: illegal baudrate %u\n", __FUNCTION__, baud);
+               return -EINVAL;
+       }
+       WRITE_PERIPHERAL_REGISTER(br, info->mapbase + IFX_SSC_BR);
+       if (enabled)
+               WRITE_PERIPHERAL_REGISTER(IFX_SSC_WHBSTATE_SET_ENABLE, 
+                                         info->mapbase + IFX_SSC_WHBSTATE);
+
+       local_irq_restore(flags);
+       return 0;
+} // ifx_ssc_set_baud
+
+static int
+ifx_ssc_hwinit(struct ifx_ssc_port *info)
+{
+       unsigned long flags;
+       bool enabled;
+
+       /* have to disable the SSC */
+       enabled = (READ_PERIPHERAL_REGISTER(info->mapbase + IFX_SSC_STATE) 
+                  & IFX_SSC_STATE_IS_ENABLED) != 0;
+       WRITE_PERIPHERAL_REGISTER(IFX_SSC_WHBSTATE_CLR_ENABLE, 
+                                 info->mapbase + IFX_SSC_WHBSTATE);
+
+       if (ifx_ssc_sethwopts(info) < 0)
+       {
+               printk("%s: setting the hardware options failed\n",
+                       __FUNCTION__);
+               return -EINVAL;
+       }
+
+       if (ifx_ssc_set_baud(info, info->baud) < 0) {
+               printk("%s: setting the baud rate failed\n", __FUNCTION__);
+               return -EINVAL;
+       }
+        local_irq_save(flags);
+        /* TX FIFO */
+        WRITE_PERIPHERAL_REGISTER((IFX_SSC_DEF_TXFIFO_FL << 
+                                   IFX_SSC_XFCON_ITL_OFFSET) | 
+                                  IFX_SSC_XFCON_FIFO_ENABLE, 
+                                  info->mapbase + IFX_SSC_TXFCON);
+        /* RX FIFO */
+        WRITE_PERIPHERAL_REGISTER((IFX_SSC_DEF_RXFIFO_FL << 
+                                   IFX_SSC_XFCON_ITL_OFFSET) | 
+                                  IFX_SSC_XFCON_FIFO_ENABLE, 
+                                  info->mapbase + IFX_SSC_RXFCON);
+        local_irq_restore(flags);
+       if (enabled)
+               WRITE_PERIPHERAL_REGISTER(IFX_SSC_WHBSTATE_SET_ENABLE, 
+                                         info->mapbase + IFX_SSC_WHBSTATE);
+       return 0;
+} // ifx_ssc_hwinit
+
+/*-----------------------------------------------------------------------------
+ FUNC-NAME  : ifx_ssc_batch_exec
+ LONG-NAME  : 
+ PURPOSE    : 
+
+ PARAMETER  : *info    pointer to the port-specific structure ifx_ssc_port.
+
+ RESULT     : Returns error code
+
+ REMARKS    : 
+-----------------------------------------------------------------------------*/
+static int
+ifx_ssc_batch_exec(struct ifx_ssc_port *info, struct ifx_ssc_batch_list *batch_anchor)
+{
+       // ### TO DO: implement user space batch execution
+       // first, copy the whole linked list from user to kernel space
+       // save some hardware options
+       // execute list
+       // restore hardware options if selected
+       return -EFAULT;
+} // ifx_ssc_batch_exec
+
+
+/*
+ * This routine allows the driver to implement device-
+ * specific ioctl's.  If the ioctl number passed in cmd is
+ * not recognized by the driver, it should return ENOIOCTLCMD.
+ */
+int
+ifx_ssc_ioctl(struct inode *inode, struct file *filp, unsigned int cmd,
+              unsigned long data)
+{
+       struct ifx_ssc_port *info;
+       int line, ret_val = 0;
+       unsigned long flags;
+       unsigned long tmp;
+       int from_kernel = 0;
+
+       if ((inode == (struct inode *)0) || (inode == (struct inode *)1))
+       {
+               from_kernel = 1;
+               line = (int)inode;
+       }
+       else
+               line = MINOR(filp->f_dentry->d_inode->i_rdev);
+
+       /* don't use more minor devices than we can support */
+       if (line < 0 || line >= PORT_CNT)
+               return -ENXIO;
+
+       info = &isp[line];
+
+       switch (cmd) {
+       case IFX_SSC_STATS_READ:
+               /* data must be a pointer to a struct ifx_ssc_statistics */
+               if (from_kernel)
+                       memcpy((void *)data, (void *)&info->stats,
+                              sizeof(struct ifx_ssc_statistics));
+               else
+                       if (copy_to_user((void *)data,
+                                        (void *)&info->stats,
+                                        sizeof(struct ifx_ssc_statistics)))
+                               ret_val = -EFAULT;
+               break;
+       case IFX_SSC_STATS_RESET:
+               /* just resets the statistics counters */
+               memset((void *)&info->stats, 0, sizeof(struct ifx_ssc_statistics));
+               break;
+        case IFX_SSC_BAUD_SET:
+                /* if the buffers are not empty then the port is */
+                /* busy and we shouldn't change things on-the-fly! */
+                if (!info->txbuf || !info->rxbuf || 
+                   (READ_PERIPHERAL_REGISTER(info->mapbase + IFX_SSC_STATE) 
+                    & IFX_SSC_STATE_BUSY)) {
+                        ret_val = -EBUSY;
+                        break;
+                }
+                /* misuse flags */
+                if (from_kernel)
+                        flags = *((unsigned long *)data);
+                else
+                        if (copy_from_user((void *)&flags,
+                                           (void *)data, sizeof(flags)))
+                        {
+                                ret_val = -EFAULT;
+                                break;
+                        }
+                if (flags == 0)
+                {
+                        ret_val = -EINVAL;
+                        break;
+                }
+                if (ifx_ssc_set_baud(info, flags) < 0)
+                {
+                        ret_val = -EINVAL;
+                        break;
+                }
+                info->baud = flags;
+                break;
+        case IFX_SSC_BAUD_GET:
+                if (from_kernel)
+                        *((unsigned int *)data) = info->baud;
+                else
+                        if (copy_to_user((void *)data,
+                                         (void *)&info->baud,
+                                         sizeof(unsigned long)))
+                                ret_val = -EFAULT;
+                break;
+       case IFX_SSC_RXTX_MODE_SET:
+                if (from_kernel)
+                        tmp = *((unsigned long *)data);
+                else
+                        if (copy_from_user((void *)&tmp,
+                                           (void *)data, sizeof(tmp))) {
+                                ret_val = -EFAULT;
+                                break;
+                        }
+               ret_val = ifx_ssc_rxtx_mode_set(info, tmp);
+               break;
+       case IFX_SSC_RXTX_MODE_GET:
+               tmp = READ_PERIPHERAL_REGISTER(info->mapbase + IFX_SSC_CON) &
+                       (~(IFX_SSC_CON_RX_OFF | IFX_SSC_CON_TX_OFF));
+                if (from_kernel)
+                        *((unsigned int *)data) = tmp;
+                else
+                        if (copy_to_user((void *)data,
+                                         (void *)&tmp,
+                                         sizeof(tmp)))
+                                ret_val = -EFAULT;
+               break;
+
+       case IFX_SSC_ABORT:
+               ifx_ssc_abort(info);
+               break;
+
+       case IFX_SSC_GPO_OUT_SET:
+                if (from_kernel)
+                        tmp = *((unsigned long *)data);
+                else
+                        if (copy_from_user((void *)&tmp,
+                                           (void *)data, sizeof(tmp))) {
+                                ret_val = -EFAULT;
+                                break;
+                        }
+               if (tmp > IFX_SSC_MAX_GPO_OUT)
+                       ret_val = -EINVAL;
+               else
+                       WRITE_PERIPHERAL_REGISTER
+                               (1<<(tmp + IFX_SSC_WHBGPOSTAT_SETOUT0_POS), 
+                                info->mapbase + IFX_SSC_WHBGPOSTAT);
+               break;
+       case IFX_SSC_GPO_OUT_CLR:
+                if (from_kernel)
+                        tmp = *((unsigned long *)data);
+                else
+                        if (copy_from_user((void *)&tmp,
+                                           (void *)data, sizeof(tmp))) {
+                                ret_val = -EFAULT;
+                                break;
+                        }
+               if (tmp > IFX_SSC_MAX_GPO_OUT)
+                       ret_val = -EINVAL;
+               else {
+                       WRITE_PERIPHERAL_REGISTER
+                               (1<<(tmp + IFX_SSC_WHBGPOSTAT_CLROUT0_POS), 
+                                info->mapbase + IFX_SSC_WHBGPOSTAT);
+               }
+               break;
+       case IFX_SSC_GPO_OUT_GET:
+               tmp = READ_PERIPHERAL_REGISTER
+                       (info->mapbase + IFX_SSC_GPOSTAT);
+                if (from_kernel)
+                        *((unsigned int *)data) = tmp;
+                else
+                        if (copy_to_user((void *)data,
+                                         (void *)&tmp,
+                                         sizeof(tmp)))
+                                ret_val = -EFAULT;
+               break;
+       case IFX_SSC_FRM_STATUS_GET:
+               ifx_ssc_frm_status_get(info);
+               if (from_kernel)
+                       memcpy((void *)data, (void *)&info->frm_status,
+                              sizeof(struct ifx_ssc_frm_status));
+               else
+                       if (copy_to_user((void *)data,
+                                        (void *)&info->frm_status,
+                                        sizeof(struct ifx_ssc_frm_status)))
+                               ret_val = -EFAULT;
+               break;
+       case IFX_SSC_FRM_CONTROL_GET:
+               ifx_ssc_frm_control_get(info);
+               if (from_kernel)
+                       memcpy((void *)data, (void *)&info->frm_opts,
+                              sizeof(struct ifx_ssc_frm_opts));
+               else
+                       if (copy_to_user((void *)data,
+                                        (void *)&info->frm_opts,
+                                        sizeof(struct ifx_ssc_frm_opts)))
+                               ret_val = -EFAULT;
+               break;
+       case IFX_SSC_FRM_CONTROL_SET:
+               if (from_kernel)
+                       memcpy((void *)&info->frm_opts, (void *)data, 
+                              sizeof(struct ifx_ssc_frm_opts));
+               else
+                       if (copy_to_user((void *)&info->frm_opts,
+                                        (void *)data,
+                                        sizeof(struct ifx_ssc_frm_opts))){
+                               ret_val = -EFAULT;
+                               break;
+                       }
+               ret_val = ifx_ssc_frm_control_set(info);
+               break;
+        case IFX_SSC_HWOPTS_SET:
+               /* data must be a pointer to a struct ifx_ssc_hwopts */
+                /* if the buffers are not empty then the port is */
+                /* busy and we shouldn't change things on-the-fly! */
+                if (!info->txbuf || !info->rxbuf || 
+                   (READ_PERIPHERAL_REGISTER(info->mapbase + IFX_SSC_STATE) 
+                    & IFX_SSC_STATE_BUSY)) {
+                        ret_val = -EBUSY;
+                        break;
+                }
+                if (from_kernel)
+                        memcpy((void *)&info->opts, (void *)data,
+                               sizeof(struct ifx_ssc_hwopts));
+                else
+                        if (copy_from_user((void *)&info->opts,
+                                           (void *)data,
+                                           sizeof(struct ifx_ssc_hwopts)))
+                        {
+                                ret_val = -EFAULT;
+                                break;
+                        }
+                if (ifx_ssc_hwinit(info) < 0)
+                {
+                        ret_val = -EIO;
+                }
+                break;
+        case IFX_SSC_HWOPTS_GET:
+               /* data must be a pointer to a struct ifx_ssc_hwopts */
+                if (from_kernel)
+                        memcpy((void *)data, (void *)&info->opts,
+                               sizeof(struct ifx_ssc_hwopts));
+                else
+                        if (copy_to_user((void *)data,
+                                         (void *)&info->opts,
+                                         sizeof(struct ifx_ssc_hwopts)))
+                                ret_val = -EFAULT;
+                break;
+        default:
+                ret_val = -ENOIOCTLCMD;
+       }
+
+       return ret_val;
+} /* ifx_ssc_ioctl */
+EXPORT_SYMBOL(ifx_ssc_ioctl);
+
+///* the poll routine */
+//static unsigned int
+//ifx_ssc_poll(struct file *filp, struct poll_table_struct *pts)
+//{
+//        int unit = MINOR(filp->f_dentry->d_inode->i_rdev);
+//     struct ifx_ssc_port *info;
+//        unsigned int mask = 0; 
+//     int spc;
+//
+//     info = &isp[unit];
+//
+//        /* add event to the wait queues */
+//        /* DO NOT FORGET TO DO A WAKEUP ON THESE !!!! */
+//        poll_wait(filp, &info->pwait, pts);
+//
+//     /* are there bytes in the RX SW-FIFO? */
+//        if (info->rxrp != info->rxwp)
+//                mask |= POLLIN | POLLRDNORM;
+//
+//     /* free space in the TX SW-FIFO */
+//     spc = info->txrp - info->txwp - 1;
+//     if (spc < 0)
+//             spc += TX_BUFSIZE;
+//#ifdef IFX_SSC_USEDMA
+//     /* writing always works, except in the DMA case when all descriptors */
+//     /* are used up */
+//     if (unit == 1 && info->dma_freecnt == 0)
+//             spc = 0;
+//#endif
+//     if (spc > 0)
+//             mask |= POLLOUT | POLLWRNORM;
+//
+//        return (mask);
+//}
+
+static int
+ifx_ssc1_read_proc(char *page, char **start, off_t offset, int count, int *eof, void *data)
+{
+       int off = 0;
+       unsigned long flags;
+
+       /* don't want any interrupts here */
+       save_flags(flags);
+       cli();
+
+
+       /* print statistics */
+       off += sprintf(page+off, "Statistics for Infineon Synchronous Serial Controller SSC1\n");
+       off += sprintf(page+off, "RX overflow errors %d\n", isp[0].stats.rxOvErr);
+       off += sprintf(page+off, "RX underflow errors %d\n", isp[0].stats.rxUnErr);
+       off += sprintf(page+off, "TX overflow errors %d\n", isp[0].stats.txOvErr);
+       off += sprintf(page+off, "TX underflow errors %d\n", isp[0].stats.txUnErr);
+       off += sprintf(page+off, "Abort errors %d\n", isp[0].stats.abortErr);
+       off += sprintf(page+off, "Mode errors %d\n", isp[0].stats.modeErr);
+       off += sprintf(page+off, "RX Bytes %d\n", isp[0].stats.rxBytes);
+       off += sprintf(page+off, "TX Bytes %d\n", isp[0].stats.txBytes);
+
+       restore_flags (flags); /* XXXXX */
+       *eof = 1;
+       return (off);
+}
+
+
+/*
+ * This routine prints out the appropriate serial driver version number
+ */
+static inline void
+show_version(void)
+{
+#if 0
+    printk("Infineon Technologies Synchronous Serial Controller (SSC) driver\n"
+           "  version %s - built %s %s\n", IFX_SSC_DRV_VERSION, __DATE__, __TIME__);
+#endif  
+} /* show_version */
+
+
+/*
+ * Due to the fact that a port can be dynamically switched between slave
+ * and master mode using an IOCTL the hardware is not initialized here,
+ * but in ifx_ssc_hwinit() as a result of an IOCTL.
+ */
+int __init
+ifx_ssc_init(void)
+{
+       struct ifx_ssc_port  *info;
+       int i, nbytes;
+       unsigned long flags;
+       int ret_val;
+
+       // ### TO DO: dynamic port count evaluation due to pin multiplexing
+
+       ret_val = -ENOMEM;
+       nbytes = PORT_CNT * sizeof(struct ifx_ssc_port);
+       isp = (struct ifx_ssc_port *)kmalloc(nbytes, GFP_KERNEL);
+       if (isp == NULL)
+       {
+               printk("%s: no memory for isp\n", __FUNCTION__);
+               return (ret_val);
+       }
+       memset(isp, 0, nbytes);
+
+       show_version();
+
+       /* register the device */
+       ret_val = -ENXIO;
+/*
+       i = maj;
+*/
+       if ((i = register_chrdev(maj, "ssc", &ifx_ssc_fops)) < 0)
+       {
+               printk("Unable to register major %d for the Infineon SSC\n", maj);
+               if (maj == 0){
+                       goto errout;
+               }
+               else{
+                       maj = 0;
+                       if ((i = register_chrdev(maj, "ssc", &ifx_ssc_fops)) < 0)
+                       {
+                               printk("Unable to register major %d for the Infineon SSC\n", maj);
+                               goto errout;
+                       }
+               }
+       }
+       if (maj == 0) maj = i;
+       //printk("registered major %d for Infineon SSC\n", maj);
+
+       /* set default values in ifx_ssc_port */
+       for (i = 0; i < PORT_CNT; i++) {
+               info = &isp[i];
+                info->port_nr = i;
+               /* default values for the HwOpts */
+               info->opts.AbortErrDetect = IFX_SSC_DEF_ABRT_ERR_DETECT;
+               info->opts.rxOvErrDetect = IFX_SSC_DEF_RO_ERR_DETECT;
+               info->opts.rxUndErrDetect = IFX_SSC_DEF_RU_ERR_DETECT;
+               info->opts.txOvErrDetect = IFX_SSC_DEF_TO_ERR_DETECT;
+               info->opts.txUndErrDetect = IFX_SSC_DEF_TU_ERR_DETECT;
+               info->opts.loopBack = IFX_SSC_DEF_LOOP_BACK;
+               info->opts.echoMode = IFX_SSC_DEF_ECHO_MODE;
+               info->opts.idleValue = IFX_SSC_DEF_IDLE_DATA;
+               info->opts.clockPolarity = IFX_SSC_DEF_CLOCK_POLARITY;
+               info->opts.clockPhase = IFX_SSC_DEF_CLOCK_PHASE;
+               info->opts.headingControl = IFX_SSC_DEF_HEADING_CONTROL;
+               info->opts.dataWidth = IFX_SSC_DEF_DATA_WIDTH;
+               info->opts.modeRxTx = IFX_SSC_DEF_MODE_RXTX;
+               info->opts.gpoCs = IFX_SSC_DEF_GPO_CS;
+               info->opts.gpoInv = IFX_SSC_DEF_GPO_INV;
+               info->opts.masterSelect = IFX_SSC_DEF_MASTERSLAVE;
+               info->baud = IFX_SSC_DEF_BAUDRATE;
+               info->rxbuf = NULL;
+               info->txbuf = NULL;
+               /* values specific to SSC1 */
+               if (i == 0) {
+                       info->mapbase = AMAZON_SSC_BASE_ADD_0;
+                       // ### TO DO: power management
+
+                       // setting interrupt vectors
+                       info->txirq = IFX_SSC_TIR;
+                       info->rxirq = IFX_SSC_RIR;
+                       info->errirq = IFX_SSC_EIR;
+/*
+                       info->frmirq = IFX_SSC_FIR;
+*/
+               }
+               /* activate SSC */
+               /* CLC.DISS = 0 */
+               WRITE_PERIPHERAL_REGISTER(IFX_SSC_DEF_RMC << IFX_CLC_RUN_DIVIDER_OFFSET, info->mapbase + IFX_SSC_CLC);
+
+// ### TO DO: multiple instances
+
+               init_waitqueue_head(&info->rwait);
+               //init_waitqueue_head(&info->pwait);
+
+               local_irq_save(flags);
+
+               // init serial framing register
+               WRITE_PERIPHERAL_REGISTER(IFX_SSC_DEF_SFCON, info->mapbase + IFX_SSC_SFCON);
+
+               /* try to get the interrupts */
+               // ### TO DO: interrupt handling with multiple instances
+               ret_val = ifx_int_wrapper.request(info->txirq, ifx_ssc_tx_int, 
+                                                 0, "ifx_ssc_tx", info);
+               if (ret_val){
+                       printk("%s: unable to get irq %d\n", __FUNCTION__,
+                                       info->txirq);
+                       local_irq_restore(flags);
+                       goto errout;
+               }
+               ret_val = ifx_int_wrapper.request(info->rxirq, ifx_ssc_rx_int, 
+                                                 0, "ifx_ssc_rx", info);
+               if (ret_val){
+                       printk("%s: unable to get irq %d\n", __FUNCTION__,
+                                       info->rxirq);
+                       local_irq_restore(flags);
+                       goto irqerr;
+               }
+               ret_val = ifx_int_wrapper.request(info->errirq, ifx_ssc_err_int, 
+                                                 0, "ifx_ssc_err", info);
+               if (ret_val){
+                       printk("%s: unable to get irq %d\n", __FUNCTION__,
+                                       info->errirq);
+                       local_irq_restore(flags);
+                       goto irqerr;
+               }
+/*
+               ret_val = ifx_int_wrapper.request(info->frmirq, ifx_ssc_frm_int, 
+                                                 0, "ifx_ssc_frm", info);
+               if (ret_val){
+                       printk("%s: unable to get irq %d\n", __FUNCTION__,
+                                       info->frmirq);
+                       local_irq_restore(flags);
+                       goto irqerr;
+               }
+
+*/
+               WRITE_PERIPHERAL_REGISTER(IFX_SSC_DEF_IRNEN, info->mapbase + IFX_SSC_IRN_EN);
+
+               local_irq_restore(flags);
+       } // for (i = 0; i < PORT_CNT; i++)
+
+       /* init the SSCs with default values */
+       for (i = 0; i < PORT_CNT; i++)
+       {
+               info = &isp[i];
+               if (ifx_ssc_hwinit(info) < 0)
+               {
+                       printk("%s: hardware init failed for port %d\n",
+                               __FUNCTION__, i);
+                       goto irqerr;
+               }
+       }
+
+       /* register /proc read handler */
+       // ### TO DO: multiple instances
+       /* for SSC1, which is always present */
+       create_proc_read_entry("driver/ssc1", 0, NULL, ifx_ssc1_read_proc, NULL);
+       return 0;
+
+irqerr:
+       // ### TO DO: multiple instances
+       ifx_int_wrapper.free(isp[0].txirq,&isp[0]);
+       ifx_int_wrapper.free(isp[0].rxirq,&isp[0]);
+       ifx_int_wrapper.free(isp[0].errirq,&isp[0]);
+/*
+       ifx_int_wrapper.free(isp[0].frmirq, &isp[0]);
+*/
+errout:
+       /* free up any allocated memory in the error case */
+       kfree(isp);
+       return (ret_val);
+} /* ifx_ssc_init */
+
+
+void
+ifx_ssc_cleanup_module(void)
+{
+       int i;
+
+       /* free up any allocated memory */
+       for (i = 0; i < PORT_CNT; i++)
+       {
+               /* disable the SSC */
+               WRITE_PERIPHERAL_REGISTER(IFX_SSC_WHBSTATE_CLR_ENABLE,isp[i].mapbase + IFX_SSC_WHBSTATE);
+               /* free the interrupts */
+               ifx_int_wrapper.free(isp[i].txirq, &isp[i]);
+               ifx_int_wrapper.free(isp[i].rxirq, &isp[i]);
+               ifx_int_wrapper.free(isp[i].errirq, &isp[i]);
+/*
+               ifx_int_wrapper.free(isp[i].frmirq, &isp[i]);
+
+               if (isp[i].rxbuf != NULL)
+                       kfree(isp[i].rxbuf);
+               if (isp[i].txbuf != NULL)
+                       kfree(isp[i].txbuf);
+*/
+       }
+       kfree(isp);
+       /* unregister the device */
+       if (unregister_chrdev(maj, "ssc"))
+       {
+               printk("Unable to unregister major %d for the SSC\n", maj);
+       }
+       /* delete /proc read handler */
+       remove_proc_entry("driver/ssc1", NULL);
+       remove_proc_entry("driver/ssc2", NULL);
+} /* ifx_ssc_cleanup_module */
+
+module_exit(ifx_ssc_cleanup_module);
+
+/* Module entry-points */
+module_init(ifx_ssc_init);
+
+#ifndef MODULE
+static int __init
+ifx_ssc_set_maj(char *str)
+{
+       maj = simple_strtol(str, NULL, 0);
+       return 1;
+}
+__setup("ssc_maj=", ifx_ssc_set_maj);
+#endif /* !MODULE */
+
+#define AMAZON_SSC_EMSG(fmt,arg...) printk("%s: "fmt,__FUNCTION__, ##arg)
+/* Brief:      chip select enable
+ */
+inline int amazon_ssc_cs_low(u32 pin)
+{
+       int ret=0;
+       if ((ret=ifx_ssc_ioctl((struct inode *)0, NULL,IFX_SSC_GPO_OUT_CLR, (unsigned long)&pin))){
+               AMAZON_SSC_EMSG("clear CS %d fails\n",pin);
+       }
+       wmb();
+       return ret;
+}
+EXPORT_SYMBOL(amazon_ssc_cs_low);
+/* Brief:      chip select disable
+ */
+inline int amazon_ssc_cs_high(u32 pin)
+{
+       int ret=0;
+       if ((ret=ifx_ssc_ioctl((struct inode *)0, NULL,IFX_SSC_GPO_OUT_SET, (unsigned long)&pin))){
+               AMAZON_SSC_EMSG("set CS %d fails\n", pin);
+       }
+       wmb();
+       return ret;
+}
+EXPORT_SYMBOL(amazon_ssc_cs_high);
+/* Brief:      one SSC session
+ * Parameter:  
+ *     tx_buf
+ *     tx_len
+ *     rx_buf
+ *     rx_len
+ *     session_mode: IFX_SSC_MODE_RXTX or IFX_SSC_MODE_TX
+ * Return:     >=0 number of bytes received (if rx_buf != 0) or transmitted
+ *             <0 error code
+ * Description:
+ *     0. copy data to internal buffer 
+ *     1. Write command
+ *     2a. If SSC_SESSION_MODE_TXONLY, read tx_len data
+ *     2b. If not Read back (tx_len + rx_len) data
+ *     3. copy internal buffer to rx buf if necessary
+ */
+static int ssc_session(char * tx_buf, u32 tx_len, char * rx_buf, u32 rx_len)
+{
+       int ret=0;
+
+       char * ssc_tx_buf=NULL;
+       char * ssc_rx_buf=NULL;
+
+//     volatile char ssc_tx_buf[128]={0};
+//     volatile char ssc_rx_buf[128]={0};
+
+       int eff_size=0;
+       u8 mode=0;
+       
+       if (tx_buf == NULL && tx_len ==0 && rx_buf == NULL && rx_len == 0){
+               AMAZON_SSC_EMSG("invalid parameters\n");
+               ret=-EINVAL;
+               goto ssc_session_exit;
+       }else if (tx_buf == NULL || tx_len == 0){
+               if (rx_buf != NULL && rx_len != 0){
+                       mode = IFX_SSC_MODE_RX;
+               }else{
+                       AMAZON_SSC_EMSG("invalid parameters\n");
+                       ret=-EINVAL;
+                       goto ssc_session_exit;
+               }
+       }else if (rx_buf == NULL || rx_len ==0){
+               if (tx_buf != NULL && tx_len != 0){
+                       mode = IFX_SSC_MODE_TX;
+               }else{
+                       AMAZON_SSC_EMSG("invalid parameters\n");
+                       ret=-EINVAL;
+                       goto ssc_session_exit;
+               }
+       }else{
+               mode = IFX_SSC_MODE_RXTX;
+       }
+       
+       if (mode == IFX_SSC_MODE_RXTX){
+               eff_size = tx_len + rx_len;
+       }else if (mode == IFX_SSC_MODE_RX){
+               eff_size = rx_len;
+       }else{
+               eff_size = tx_len;
+       }
+
+       //4 bytes alignment,  required by driver
+       /* change by TaiCheng */
+       //if (in_irq()){
+       if (1){
+               ssc_tx_buf = (char*) kmalloc(sizeof(char) *  ((eff_size + 3) & (~3)), GFP_ATOMIC);
+               ssc_rx_buf = (char*) kmalloc(sizeof(char) *  ((eff_size + 3) & (~3)), GFP_ATOMIC);
+       }else{
+               ssc_tx_buf = (char*) kmalloc(sizeof(char) *  ((eff_size + 3) & (~3)), GFP_KERNEL);
+               ssc_rx_buf = (char*) kmalloc(sizeof(char) *  ((eff_size + 3) & (~3)), GFP_KERNEL);
+       }
+       if (ssc_tx_buf == NULL || ssc_rx_buf == NULL){
+               AMAZON_SSC_EMSG("no memory for size of %d\n", eff_size);
+               ret = -ENOMEM;
+               goto ssc_session_exit;
+       }
+       memset((void*)ssc_tx_buf, 0, eff_size);
+       memset((void*)ssc_rx_buf, 0, eff_size);
+
+       if (tx_len>0){
+               memcpy(ssc_tx_buf, tx_buf, tx_len);
+       }
+       
+       ret=ifx_ssc_kwrite(0, ssc_tx_buf, eff_size);
+
+       if (ret > 0) {
+               ssc_tx_buf = NULL; //should be freed by ifx_ssc_kwrite
+       }
+               
+       if (  ret != eff_size ){
+               AMAZON_SSC_EMSG("ifx_ssc_write return %d\n",ret); 
+               goto ssc_session_exit;
+       }
+       ret=ifx_ssc_kread(0, ssc_rx_buf,eff_size);
+       if (  ret != eff_size ){
+               AMAZON_SSC_EMSG("ifx_ssc_read return %d\n",ret); 
+               goto ssc_session_exit;
+       }
+       
+       memcpy(rx_buf, ssc_rx_buf+tx_len, rx_len);
+       
+       if (mode == IFX_SSC_MODE_TX) {
+               ret = tx_len;
+       }else{
+               ret = rx_len;
+       }
+ssc_session_exit:
+
+       if (ssc_tx_buf != NULL) kfree(ssc_tx_buf);
+       if (ssc_rx_buf != NULL) kfree(ssc_rx_buf);
+
+       if (ret<0) {
+               printk("ssc session fails\n");
+       }
+       return ret;
+}
+/* Brief:      TX-RX session
+ * Parameter:  
+ *     tx_buf
+ *     tx_len
+ *     rx_buf
+ *     rx_len
+ * Return:     >=0 number of bytes received
+ *             <0 error code
+ * Description: 
+ *     1. TX session
+ *     2. RX session
+ */
+int amazon_ssc_txrx(char * tx_buf, u32 tx_len, char * rx_buf, u32 rx_len)
+{
+       return ssc_session(tx_buf,tx_len,rx_buf,rx_len);
+}
+EXPORT_SYMBOL(amazon_ssc_txrx);
+/* Brief:      TX only session
+ * Parameter:
+ *     tx_buf
+ *     tx_len
+ * Return:     >=0 number of bytes transmitted
+ *             <0 error code
+ */
+int amazon_ssc_tx(char * tx_buf, u32 tx_len)
+{
+       return ssc_session(tx_buf,tx_len,NULL,0);
+}
+EXPORT_SYMBOL(amazon_ssc_tx);
+/* Brief:      RX only session
+ * Parameter:
+ *     rx_buf
+ *     rx_len
+ * Return:     >=0 number of bytes received
+ *             <0 error code
+ */
+int amazon_ssc_rx(char * rx_buf, u32 rx_len)
+{
+       return ssc_session(NULL,0,rx_buf,rx_len);
+}
+EXPORT_SYMBOL(amazon_ssc_rx);
+
diff --git a/target/linux/amazon-2.6/files/drivers/mtd/maps/amazon.c b/target/linux/amazon-2.6/files/drivers/mtd/maps/amazon.c
new file mode 100644 (file)
index 0000000..3e7dc4f
--- /dev/null
@@ -0,0 +1,166 @@
+/*
+ * Handle mapping of the flash memory access routines
+ * on Amazon  based devices.
+ *
+ * Copyright(C) 2004 peng.liu@infineon.com
+ *
+ * This code is GPLed
+ *
+ */
+// 000005:fchang 2005/6/2 Modified by Bingtao to double check if the EBU is enabled/disabled
+// 506231:tc.chen 2005/06/23 increase firmware partition size form 192KB to 256KB
+// 050701:linmars 2005/07/01 fix flash size wrong alignment after increase firmware partition
+// 165001:henryhsu 2005/8/18 Remove the support for Intel flash because of 2.1 not enough rootfs partition size
+// 165001:henryhsu 2005/9/7 Rolback to support INtel flash
+// 509071:tc.chen 2005/09/07 Reduced flash writing time
+// 511046:linmars 2005/11/04 change bootloader size from 128 into 64
+// 511241:linmars 2005/11/24 merge TaiChen's IRM patch 
+
+// copyright 2005 infineon
+
+// copyright 2007 john crispin <blogic@openwrt.org>
+// copyright 2007 felix fietkau <nbd@openwrt.org>
+
+#include <linux/module.h>
+#include <linux/types.h>
+#include <linux/kernel.h>
+#include <asm/io.h>
+
+#include <linux/init.h>
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/map.h>
+#include <linux/mtd/partitions.h>
+#include <linux/mtd/cfi.h>
+#include <linux/mutex.h>
+#include <asm/amazon/amazon.h>
+
+#define AMAZON_PCI_ARB_CTL_ALT 0xb100205c
+#define AMAZON_MTD_REG32( addr )          (*(volatile u32 *)(addr))
+
+
+static struct map_info amazon_map = {
+       .name = "AMAZON_FLASH",
+       .bankwidth = 2,
+       .size = 0x400000,
+};
+
+static map_word amazon_read16(struct map_info * map, unsigned long ofs)
+{
+       map_word temp;
+       ofs ^= 2;
+       temp.x[0] = *((__u16 *) (map->virt + ofs));
+       return temp;
+}
+
+static void amazon_write16(struct map_info *map, map_word d, unsigned long adr)
+{
+       adr ^= 2;
+       *((__u16 *) (map->virt + adr)) = d.x[0];
+}
+
+void amazon_copy_from(struct map_info *map, void *to, unsigned long from, ssize_t len)
+{
+       u8 *p;
+       u8 *to_8;
+       ssize_t l = len;
+       from = (unsigned long) (from + map->virt);
+       p = (u8 *) from;
+       to_8 = (u8 *) to;
+       while(len--){
+               *to_8++ = *p++;
+       }
+}
+
+void amazon_copy_to(struct map_info *map, unsigned long to, const void *from, ssize_t len)
+{
+       u8 *p =  (u8*) from;
+       u8 *to_8;
+       to += (unsigned long) map->virt;
+       to_8 = (u8*)to;
+       while(len--){
+               *p++ = *to_8++;
+       }
+}
+
+#define UBOOT_SIZE             0x40000
+
+static struct mtd_partition    amazon_partitions[3] = {
+        {
+                 name:"U-Boot",                /* U-Boot firmware */
+                 offset:0x00000000,
+                 size:UBOOT_SIZE ,             /* 128k */
+         },
+        {
+                 name:"kernel",                /* firmware */
+                 offset:UBOOT_SIZE,
+                 size:0x00100000,              /* 192K */
+         },
+        {
+                 name:"rootfs",                /* default partition */
+                 offset:0x00200000,
+                 size:0x00200000,
+         },
+};
+
+
+unsigned long flash_start = 0x13000000;
+unsigned long flash_size = 0x800000;
+unsigned long uImage_size = 0x10000d;
+
+int find_uImage_size(unsigned long start_offset){
+       unsigned long temp;
+
+       printk("trying to find uImage and its size\n");
+       amazon_copy_from(&amazon_map, &temp, start_offset + 12, 4);
+       printk("kernel size is %d \n", temp + 0x40);
+       return temp + 0x40;
+}
+
+int __init init_amazon_mtd(void)
+{
+       int ret = 0;
+       struct mtd_info *mymtd = NULL;
+       struct mtd_partition *parts = NULL;
+
+       *AMAZON_EBU_BUSCON0 = 0x1d7ff;
+       
+       amazon_map.read = amazon_read16;
+       amazon_map.write = amazon_write16;
+       amazon_map.copy_from = amazon_copy_from;
+       amazon_map.copy_to = amazon_copy_to;
+
+       amazon_map.phys = flash_start;
+       amazon_map.virt = ioremap_nocache(flash_start, flash_size);
+       
+       if (!amazon_map.virt) {
+               printk(KERN_WARNING "Failed to ioremap!\n");
+               return -EIO;
+       }
+       
+       mymtd = (struct mtd_info *) do_map_probe("cfi_probe", &amazon_map);
+       if (!mymtd) {
+               iounmap(amazon_map.virt);
+               printk("probing failed\n");
+               return -ENXIO;
+       }
+
+       mymtd->owner = THIS_MODULE;
+       parts = &amazon_partitions[0];
+       amazon_partitions[2].offset = UBOOT_SIZE + find_uImage_size(amazon_partitions[1].offset);
+       amazon_partitions[1].size = mymtd->size - amazon_partitions[1].offset - (2 * mymtd->erasesize);
+       amazon_partitions[2].size = mymtd->size - amazon_partitions[2].offset - (2 * mymtd->erasesize);
+       add_mtd_partitions(mymtd, parts, 3);
+       return 0;
+}
+
+static void __exit cleanup_amazon_mtd(void)
+{
+       /* FIXME! */
+}
+
+module_init(init_amazon_mtd);
+module_exit(cleanup_amazon_mtd);
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("john crispin blogic@openwrt.org");
+MODULE_DESCRIPTION("MTD map driver for AMAZON boards");
diff --git a/target/linux/amazon-2.6/files/drivers/net/amazon_sw.c b/target/linux/amazon-2.6/files/drivers/net/amazon_sw.c
new file mode 100644 (file)
index 0000000..d19db6e
--- /dev/null
@@ -0,0 +1,876 @@
+/*
+ *   This program is free software; you can redistribute it and/or modify
+ *   it under the terms of the GNU General Public License as published by
+ *   the Free Software Foundation; either version 2 of the License, or
+ *   (at your option) any later version.
+ *
+ *   This program is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with this program; if not, write to the Free Software
+ *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
+ */
+//-----------------------------------------------------------------------
+/*
+ * Description:
+ *     Driver for Infineon Amazon 3 port switch
+ */
+//-----------------------------------------------------------------------
+/* Author:     Wu Qi Ming[Qi-Ming.Wu@infineon.com]
+ * Created:    7-April-2004
+ */
+//-----------------------------------------------------------------------
+/* History
+ * Changed on: Jun 28, 2004
+ * Changed by: peng.liu@infineon.com
+ * Reason:     add hardware flow control (HFC) (CONFIG_NET_HW_FLOWCONTROL)
+ *
+ * Changed on: Apr 6, 2005
+ * Changed by: mars.lin@infineon.com
+ * Reason    : supoort port identification
+ */
+
+
+// copyright 2004-2005 infineon.com
+
+// copyright 2007 john crispin <blogic@openwrt.org>
+// copyright 2007 felix fietkau <nbd@openwrt.org>
+
+
+// TODO
+//             port vlan code from bcrm target... the tawainese code was scrapped due to crappyness
+//             check all the mmi reg settings and possibly document them better
+//             verify the ethtool code
+//             remove the while(1) stuff
+//             further clean up and rework ... but it works for now
+//             check the mode[]=bridge stuff
+//             verify that the ethaddr can be set from u-boot
+
+
+#ifndef __KERNEL__
+#define __KERNEL__
+#endif
+
+
+#if defined(CONFIG_MODVERSIONS) && !defined(MODVERSIONS)
+#define MODVERSIONS
+#endif
+
+#if defined(MODVERSIONS) && !defined(__GENKSYMS__)
+#include <linux/modversions.h>
+#endif
+
+#include <linux/module.h>
+#include <linux/string.h>
+#include <linux/sched.h>
+#include <linux/kernel.h>
+#include <linux/slab.h>
+#include <linux/errno.h>
+#include <linux/types.h>
+#include <linux/interrupt.h>
+#include <linux/mii.h>
+#include <asm/uaccess.h>
+#include <linux/in.h>
+#include <linux/netdevice.h>
+#include <linux/etherdevice.h>
+#include <linux/ip.h>
+#include <linux/tcp.h>
+#include <linux/skbuff.h>
+#include <linux/in6.h>
+#include <linux/proc_fs.h>
+#include <linux/mm.h>
+#include <linux/ethtool.h>
+#include <asm/checksum.h>
+#include <linux/init.h>
+
+#include <asm/amazon/amazon.h>
+#include <asm/amazon/amazon_dma.h>
+#include <asm/amazon/amazon_sw.h>
+
+// how many mii ports are there ?
+#define AMAZON_SW_INT_NO 2
+
+#define ETHERNET_PACKET_DMA_BUFFER_SIZE 1536
+
+/***************************************** Module Parameters *************************************/
+char mode[] = "bridge";
+module_param_array(mode, charp, NULL, 0);
+
+static int timeout = 1 * HZ;
+module_param(timeout, int, 0);
+
+int switch_init(struct net_device *dev);
+void switch_tx_timeout(struct net_device *dev);
+
+struct net_device switch_devs[2] = {
+       {init:switch_init,},
+       {init:switch_init,}
+};
+
+int add_mac_table_entry(u64 entry_value)
+{
+       int i;
+       u32 data1, data2;
+
+       AMAZON_SW_REG32(AMAZON_SW_ARL_CTL) = ~7;
+
+       for (i = 0; i < 32; i++) {
+               AMAZON_SW_REG32(AMAZON_SW_CPU_ACTL) = 0x80000000 | 0x20 | i;
+               while (AMAZON_SW_REG32(AMAZON_SW_CPU_ACTL) & (0x80000000)) {};
+               data1 = AMAZON_SW_REG32(AMAZON_SW_DATA1);
+               data2 = AMAZON_SW_REG32(AMAZON_SW_DATA2);
+               if ((data1 & (0x00700000)) != 0x00700000)
+                       continue;
+               AMAZON_SW_REG32(AMAZON_SW_DATA1) = (u32) (entry_value >> 32);
+               AMAZON_SW_REG32(AMAZON_SW_DATA2) = (u32) entry_value & 0xffffffff;
+               AMAZON_SW_REG32(AMAZON_SW_CPU_ACTL) = 0xc0000020 | i;
+               while (AMAZON_SW_REG32(AMAZON_SW_CPU_ACTL) & (0x80000000)) {};
+               break;
+       }
+       AMAZON_SW_REG32(AMAZON_SW_ARL_CTL) |= 7;
+       if (i >= 32)
+               return -1;
+       return OK;
+}
+
+u64 read_mac_table_entry(int index)
+{
+       u32 data1, data2;
+       u64 value;
+       AMAZON_SW_REG32(AMAZON_SW_CPU_ACTL) = 0x80000000 | 0x20 | index;
+       while (AMAZON_SW_REG32(AMAZON_SW_CPU_ACTL) & (0x80000000)) {};
+       data1 = AMAZON_SW_REG32(AMAZON_SW_DATA1) & 0xffffff;
+       data2 = AMAZON_SW_REG32(AMAZON_SW_DATA2);
+       value = (u64) data1 << 32 | (u64) data2;
+       return value;
+}
+
+int write_mac_table_entry(int index, u64 value)
+{
+       u32 data1, data2;
+       data1 = (u32) (value >> 32);
+       data2 = (u32) value & 0xffffffff;
+       AMAZON_SW_REG32(AMAZON_SW_DATA1) = data1;
+       AMAZON_SW_REG32(AMAZON_SW_DATA2) = data2;
+       AMAZON_SW_REG32(AMAZON_SW_CPU_ACTL) = 0xc0000020 | index;
+       while (AMAZON_SW_REG32(AMAZON_SW_CPU_ACTL) & (0x80000000)) {};
+       return OK;
+}
+
+u32 get_mdio_reg(int phy_addr, int reg_num)
+{
+       u32 value;
+       AMAZON_SW_REG32(AMAZON_SW_MDIO_ACC) = (3 << 30) | ((phy_addr & 0x1f) << 21) | ((reg_num & 0x1f) << 16);
+       while (AMAZON_SW_REG32(AMAZON_SW_MDIO_ACC) & (1 << 31)) {};
+       value = AMAZON_SW_REG32(AMAZON_SW_MDIO_ACC) & 0xffff;
+       return value;
+}
+
+int set_mdio_reg(int phy_addr, int reg_num, u32 value)
+{
+       AMAZON_SW_REG32(AMAZON_SW_MDIO_ACC) = (2 << 30) | ((phy_addr & 0x1f) << 21) | ((reg_num & 0x1f) << 16) | (value & 0xffff);
+       while (AMAZON_SW_REG32(AMAZON_SW_MDIO_ACC) & (1 << 31)) {};
+       return OK;
+}
+
+int auto_negotiate(int phy_addr)
+{
+       u32 value = 0;
+       value = get_mdio_reg(phy_addr, MDIO_BASE_CONTROL_REG);
+       set_mdio_reg(phy_addr, MDIO_BASE_CONTROL_REG, (value | RESTART_AUTO_NEGOTIATION | AUTO_NEGOTIATION_ENABLE | PHY_RESET));
+       return OK;
+}
+
+/*
+     In this version of switch driver, we split the dma channels for the switch.
+     2 for port0 and 2 for port1. So that we can do internal bridging if necessary.
+     In switch mode, packets coming in from port0 or port1 is able to do Destination 
+     address lookup. Packets coming from port0 with destination address of port1 should 
+     not go to pmac again. The switch hardware should be able to do the switch in the hard 
+     ware level. Packets coming from the pmac should not do the DA look up in that the
+     desination is already known for the kernel. It only needs to go to the correct NIC to 
+     find its way out.
+  */
+int amazon_sw_chip_init(void)
+{
+       u32 tmp1;
+       int i = 0;
+
+       /* Aging tick select: 5mins */
+       tmp1 = 0xa0;
+       if (strcmp(mode, "bridge") == 0) {
+               // bridge mode, set militarised mode to 1, no learning!
+               tmp1 |= 0xC00;
+       } else {
+               // enable learning for P0 and P1,
+               tmp1 |= 3;
+       }
+
+       /* unknown broadcast/multicast/unicast to all ports */
+       AMAZON_SW_REG32(AMAZON_SW_UN_DEST) = 0x1ff;
+
+       AMAZON_SW_REG32(AMAZON_SW_ARL_CTL) = tmp1;
+
+       /* OCS:1 set OCS bit, split the two NIC in rx direction EDL:1 (enable DA lookup) */
+#if defined(CONFIG_IFX_NFEXT_AMAZON_SWITCH_PHYPORT) || defined(CONFIG_IFX_NFEXT_AMAZON_SWITCH_PHYPORT_MODULE)
+       AMAZON_SW_REG32(AMAZON_SW_P2_PCTL) = 0x700;
+#else
+       AMAZON_SW_REG32(AMAZON_SW_P2_PCTL) = 0x401;
+#endif
+
+       /* EPC: 1 split the two NIC in tx direction CRC is generated */
+       AMAZON_SW_REG32(AMAZON_SW_P2_CTL) = 0x6;
+
+       // for bi-directional 
+       AMAZON_SW_REG32(AMAZON_SW_P0_WM) = 0x14141412;
+       AMAZON_SW_REG32(AMAZON_SW_P1_WM) = 0x14141412;
+       AMAZON_SW_REG32(AMAZON_SW_P2_WM) = 0x28282826;
+       AMAZON_SW_REG32(AMAZON_SW_GBL_WM) = 0x0;
+
+       AMAZON_SW_REG32(AMAZON_CGU_PLL0SR) = (AMAZON_SW_REG32(AMAZON_CGU_PLL0SR)) | 0x58000000;
+       // clock for PHY
+       AMAZON_SW_REG32(AMAZON_CGU_IFCCR) =     (AMAZON_SW_REG32(AMAZON_CGU_IFCCR)) | 0x80000004;
+       // enable power for PHY
+       AMAZON_SW_REG32(AMAZON_PMU_PWDCR) = (AMAZON_SW_REG32(AMAZON_PMU_PWDCR)) | AMAZON_PMU_PWDCR_EPHY;
+       // set reverse MII, enable MDIO statemachine
+       AMAZON_SW_REG32(AMAZON_SW_MDIO_CFG) = 0x800027bf;
+       while (1)
+               if (((AMAZON_SW_REG32(AMAZON_SW_MDIO_CFG)) & 0x80000000) == 0)
+                       break;
+       AMAZON_SW_REG32(AMAZON_SW_EPHY) = 0xff;
+
+       // auto negotiation
+       AMAZON_SW_REG32(AMAZON_SW_MDIO_ACC) = 0x83e08000;
+       auto_negotiate(0x1f);
+
+       /* enable all ports */
+       AMAZON_SW_REG32(AMAZON_SW_PS_CTL) = 0x7;
+       for (i = 0; i < 32; i++)
+               write_mac_table_entry(i, 1 << 50);
+       return 0;
+}
+
+static unsigned char my_ethaddr[MAX_ADDR_LEN];
+/* need to get the ether addr from u-boot */
+static int __init ethaddr_setup(char *line)
+{
+       char *ep;
+       int i;
+
+       memset(my_ethaddr, 0, MAX_ADDR_LEN);
+       for (i = 0; i < 6; i++) {
+               my_ethaddr[i] = line ? simple_strtoul(line, &ep, 16) : 0;
+               if (line)
+                       line = (*ep) ? ep + 1 : ep;
+       }
+       printk("mac address %2x-%2x-%2x-%2x-%2x-%2x \n", my_ethaddr[0], my_ethaddr[1], my_ethaddr[2], my_ethaddr[3], my_ethaddr[4], my_ethaddr[5]);
+       return 0;
+}
+
+__setup("ethaddr=", ethaddr_setup);
+
+static void open_rx_dma(struct net_device *dev)
+{
+       struct switch_priv *priv = (struct switch_priv *) dev->priv;
+       struct dma_device_info *dma_dev = priv->dma_device;
+       int i;
+
+       for (i = 0; i < dma_dev->num_rx_chan; i++)
+               dma_dev->rx_chan[i].control = 1;
+       dma_device_update_rx(dma_dev);
+}
+
+#ifdef CONFIG_NET_HW_FLOWCONTROL
+static void close_rx_dma(struct net_device *dev)
+{
+       struct switch_priv *priv = (struct switch_priv *) dev->priv;
+       struct dma_device_info *dma_dev = priv->dma_device;
+       int i;
+
+       for (i = 0; i < dma_dev->num_rx_chan; i++)
+               dma_dev->rx_chan[i].control = 0;
+       dma_device_update_rx(dma_dev);
+}
+
+void amazon_xon(struct net_device *dev)
+{
+       unsigned long flag;
+       local_irq_save(flag);
+       open_rx_dma(dev);
+       local_irq_restore(flag);
+}
+#endif
+
+int switch_open(struct net_device *dev)
+{
+       struct switch_priv *priv = (struct switch_priv *) dev->priv;
+       if (!strcmp(dev->name, "eth1")) {
+               priv->mdio_phy_addr = PHY0_ADDR;
+       }
+       open_rx_dma(dev);                       
+
+#ifdef CONFIG_NET_HW_FLOWCONTROL
+       if ((priv->fc_bit = netdev_register_fc(dev, amazon_xon)) == 0) {
+               printk("Hardware Flow Control register fails\n");
+       }
+#endif
+
+       netif_start_queue(dev);
+       return OK;
+}
+
+int switch_release(struct net_device *dev)
+{
+       int i;
+       struct switch_priv *priv = (struct switch_priv *) dev->priv;
+       struct dma_device_info *dma_dev = priv->dma_device;
+
+       for (i = 0; i < dma_dev->num_tx_chan; i++)
+               dma_dev->tx_chan[i].control = 0;
+       for (i = 0; i < dma_dev->num_rx_chan; i++)
+               dma_dev->rx_chan[i].control = 0;
+
+       dma_device_update(dma_dev);
+
+#ifdef CONFIG_NET_HW_FLOWCONTROL
+       if (priv->fc_bit) {
+               netdev_unregister_fc(priv->fc_bit);
+       }
+#endif
+       netif_stop_queue(dev);
+
+       return OK;
+}
+
+
+void switch_rx(struct net_device *dev, int len, struct sk_buff *skb)
+{
+       struct switch_priv *priv = (struct switch_priv *) dev->priv;
+#ifdef CONFIG_NET_HW_FLOWCONTROL
+       int mit_sel = 0;
+#endif
+       skb->dev = dev;
+       skb->protocol = eth_type_trans(skb, dev);
+
+#ifdef CONFIG_NET_HW_FLOWCONTROL
+       mit_sel = netif_rx(skb);
+       switch (mit_sel) {
+       case NET_RX_SUCCESS:
+       case NET_RX_CN_LOW:
+       case NET_RX_CN_MOD:
+               break;
+       case NET_RX_CN_HIGH:
+               break;
+       case NET_RX_DROP:
+               if ((priv->fc_bit)
+                       && (!test_and_set_bit(priv->fc_bit, &netdev_fc_xoff))) {
+                       close_rx_dma(dev);
+               }
+               break;
+       }
+#else
+       netif_rx(skb);
+#endif
+       priv->stats.rx_packets++;
+       priv->stats.rx_bytes += len;
+       return;
+}
+
+int asmlinkage switch_hw_tx(char *buf, int len, struct net_device *dev)
+{
+       struct switch_priv *priv = dev->priv;
+       struct dma_device_info *dma_dev = priv->dma_device;
+
+       dma_dev->current_tx_chan = 0;
+       return dma_device_write(dma_dev, buf, len, priv->skb);
+}
+
+int asmlinkage switch_tx(struct sk_buff *skb, struct net_device *dev)
+{
+       int len;
+       char *data;
+       struct switch_priv *priv = (struct switch_priv *) dev->priv;
+
+       len = skb->len < ETH_ZLEN ? ETH_ZLEN : skb->len;
+       data = skb->data;
+       priv->skb = skb;
+       dev->trans_start = jiffies;
+
+       if (switch_hw_tx(data, len, dev) != len) {
+               dev_kfree_skb_any(skb);
+               return OK;
+       }
+
+       priv->stats.tx_packets++;
+       priv->stats.tx_bytes += len;
+       return OK;
+}
+
+void switch_tx_timeout(struct net_device *dev)
+{
+       struct switch_priv *priv = (struct switch_priv *) dev->priv;
+       priv->stats.tx_errors++;
+       netif_wake_queue(dev);
+       return;
+}
+
+void negotiate(struct net_device *dev)
+{
+       struct switch_priv *priv = (struct switch_priv *) dev->priv;
+       unsigned short data = get_mdio_reg(priv->mdio_phy_addr, MDIO_ADVERTISMENT_REG);
+
+       data &= ~(MDIO_ADVERT_100_HD | MDIO_ADVERT_100_FD | MDIO_ADVERT_10_FD | MDIO_ADVERT_10_HD);
+
+       switch (priv->current_speed_selection) {
+       case 10:
+               if (priv->current_duplex == full)
+                       data |= MDIO_ADVERT_10_FD;
+               else if (priv->current_duplex == half)
+                       data |= MDIO_ADVERT_10_HD;
+               else
+                       data |= MDIO_ADVERT_10_HD | MDIO_ADVERT_10_FD;
+               break;
+
+       case 100:
+               if (priv->current_duplex == full)
+                       data |= MDIO_ADVERT_100_FD;
+               else if (priv->current_duplex == half)
+                       data |= MDIO_ADVERT_100_HD;
+               else
+                       data |= MDIO_ADVERT_100_HD | MDIO_ADVERT_100_FD;
+               break;
+
+       case 0:                                 /* Auto */
+               if (priv->current_duplex == full)
+                       data |= MDIO_ADVERT_100_FD | MDIO_ADVERT_10_FD;
+               else if (priv->current_duplex == half)
+                       data |= MDIO_ADVERT_100_HD | MDIO_ADVERT_10_HD;
+               else
+                       data |= MDIO_ADVERT_100_HD | MDIO_ADVERT_100_FD | MDIO_ADVERT_10_FD     | MDIO_ADVERT_10_HD;
+               break;
+
+       default:                                        /* assume autoneg speed and duplex */
+               data |= MDIO_ADVERT_100_HD | MDIO_ADVERT_100_FD | MDIO_ADVERT_10_FD | MDIO_ADVERT_10_HD;
+       }
+
+       set_mdio_reg(priv->mdio_phy_addr, MDIO_ADVERTISMENT_REG, data);
+
+       /* Renegotiate with link partner */
+
+       data = get_mdio_reg(priv->mdio_phy_addr, MDIO_BASE_CONTROL_REG);
+       data |= MDIO_BC_NEGOTIATE;
+
+       set_mdio_reg(priv->mdio_phy_addr, MDIO_BASE_CONTROL_REG, data);
+
+}
+
+
+void set_duplex(struct net_device *dev, enum duplex new_duplex)
+{
+       struct switch_priv *priv = (struct switch_priv *) dev->priv;
+       if (new_duplex != priv->current_duplex) {
+               priv->current_duplex = new_duplex;
+               negotiate(dev);
+       }
+}
+
+void set_speed(struct net_device *dev, unsigned long speed)
+{
+       struct switch_priv *priv = (struct switch_priv *) dev->priv;
+       priv->current_speed_selection = speed;
+       negotiate(dev);
+}
+
+static int switch_ethtool_ioctl(struct net_device *dev, struct ifreq *ifr)
+{
+       struct switch_priv *priv = (struct switch_priv *) dev->priv;
+       struct ethtool_cmd ecmd;
+
+       if (copy_from_user(&ecmd, ifr->ifr_data, sizeof(ecmd)))
+               return -EFAULT;
+
+       switch (ecmd.cmd) {
+       case ETHTOOL_GSET:
+               memset((void *) &ecmd, 0, sizeof(ecmd));
+               ecmd.supported = SUPPORTED_Autoneg | SUPPORTED_TP | SUPPORTED_MII |     SUPPORTED_10baseT_Half | SUPPORTED_10baseT_Full |
+                                               SUPPORTED_100baseT_Half | SUPPORTED_100baseT_Full;
+               ecmd.port = PORT_TP;
+               ecmd.transceiver = XCVR_EXTERNAL;
+               ecmd.phy_address = priv->mdio_phy_addr;
+
+               ecmd.speed = priv->current_speed;
+
+               ecmd.duplex = priv->full_duplex ? DUPLEX_FULL : DUPLEX_HALF;
+
+               ecmd.advertising = ADVERTISED_TP;
+               if (priv->current_duplex == autoneg && priv->current_speed_selection == 0)
+                       ecmd.advertising |= ADVERTISED_Autoneg;
+               else {
+                       ecmd.advertising |=     ADVERTISED_10baseT_Half | ADVERTISED_10baseT_Full |
+                               ADVERTISED_100baseT_Half | ADVERTISED_100baseT_Full;
+                       if (priv->current_speed_selection == 10)
+                               ecmd.advertising &=     ~(ADVERTISED_100baseT_Half | ADVERTISED_100baseT_Full);
+                       else if (priv->current_speed_selection == 100)
+                               ecmd.advertising &=     ~(ADVERTISED_10baseT_Half | ADVERTISED_10baseT_Full);
+                       if (priv->current_duplex == half)
+                               ecmd.advertising &=     ~(ADVERTISED_10baseT_Full | ADVERTISED_100baseT_Full);
+                       else if (priv->current_duplex == full)
+                               ecmd.advertising &=     ~(ADVERTISED_10baseT_Half | ADVERTISED_100baseT_Half);
+               }
+               ecmd.autoneg = AUTONEG_ENABLE;
+               if (copy_to_user(ifr->ifr_data, &ecmd, sizeof(ecmd)))
+                       return -EFAULT;
+               break;
+
+       case ETHTOOL_SSET:
+               if (!capable(CAP_NET_ADMIN)) {
+                       return -EPERM;
+               }
+               if (ecmd.autoneg == AUTONEG_ENABLE) {
+                       set_duplex(dev, autoneg);
+                       set_speed(dev, 0);
+               } else {
+                       set_duplex(dev, ecmd.duplex == DUPLEX_HALF ? half : full);
+                       set_speed(dev, ecmd.speed == SPEED_10 ? 10 : 100);
+               }
+               break;
+
+       case ETHTOOL_GDRVINFO:
+               {
+                       struct ethtool_drvinfo info;
+                       memset((void *) &info, 0, sizeof(info));
+                       strncpy(info.driver, "AMAZONE", sizeof(info.driver) - 1);
+                       strncpy(info.fw_version, "N/A", sizeof(info.fw_version) - 1);
+                       strncpy(info.bus_info, "N/A", sizeof(info.bus_info) - 1);
+                       info.regdump_len = 0;
+                       info.eedump_len = 0;
+                       info.testinfo_len = 0;
+                       if (copy_to_user(ifr->ifr_data, &info, sizeof(info)))
+                               return -EFAULT;
+               }
+               break;
+       case ETHTOOL_NWAY_RST:
+               if (priv->current_duplex == autoneg     && priv->current_speed_selection == 0)
+                       negotiate(dev);
+               break;
+       default:
+               return -EOPNOTSUPP;
+               break;
+       }
+       return 0;
+}
+
+
+
+int mac_table_tools_ioctl(struct net_device *dev, struct mac_table_req *req)
+{
+       int cmd;
+       int i;
+       cmd = req->cmd;
+       switch (cmd) {
+       case RESET_MAC_TABLE:
+               for (i = 0; i < 32; i++) {
+                       write_mac_table_entry(i, 0);
+               }
+               break;
+       case READ_MAC_ENTRY:
+               req->entry_value = read_mac_table_entry(req->index);
+               break;
+       case WRITE_MAC_ENTRY:
+               write_mac_table_entry(req->index, req->entry_value);
+               break;
+       case ADD_MAC_ENTRY:
+               add_mac_table_entry(req->entry_value);
+               break;
+       default:
+               return -EINVAL;
+       }
+
+       return 0;
+}
+
+
+/*
+    the ioctl for the switch driver is developed in the conventional way
+    the control type falls into some basic categories, among them, the 
+    SIOCETHTOOL is the traditional eth interface. VLAN_TOOLS and  
+    MAC_TABLE_TOOLS are designed specifically for amazon chip. User 
+    should be aware of the data structures used in these interfaces. 
+*/
+int switch_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
+{
+       struct data_req *switch_data_req = (struct data_req *) ifr->ifr_data;
+       struct mac_table_req *switch_mac_table_req;
+       switch (cmd) {
+       case SIOCETHTOOL:
+               switch_ethtool_ioctl(dev, ifr);
+               break;
+       case SIOCGMIIPHY:                       /* Get PHY address */
+               break;
+       case SIOCGMIIREG:                       /* Read MII register */
+               break;
+       case SIOCSMIIREG:                       /* Write MII register */
+               break;
+       case SET_ETH_SPEED_10:          /* 10 Mbps */
+               break;
+       case SET_ETH_SPEED_100: /* 100 Mbps */
+               break;
+       case SET_ETH_SPEED_AUTO:        /* Auto negotiate speed */
+               break;
+       case SET_ETH_DUPLEX_HALF:       /* Half duplex. */
+               break;
+       case SET_ETH_DUPLEX_FULL:       /* Full duplex. */
+               break;
+       case SET_ETH_DUPLEX_AUTO:       /* Autonegotiate duplex */
+               break;
+       case SET_ETH_REG:
+               AMAZON_SW_REG32(switch_data_req->index) = switch_data_req->value;
+               break;
+       case MAC_TABLE_TOOLS:
+               switch_mac_table_req = (struct mac_table_req *) ifr->ifr_data;
+               mac_table_tools_ioctl(dev, switch_mac_table_req);
+               break;
+       default:
+               return -EINVAL;
+       }
+
+       return 0;
+}
+
+struct net_device_stats *switch_stats(struct net_device *dev)
+{
+       struct switch_priv *priv = (struct switch_priv *) dev->priv;
+       return &priv->stats;
+}
+
+int switch_change_mtu(struct net_device *dev, int new_mtu)
+{
+       if (new_mtu >= 1516)
+               new_mtu = 1516;
+       dev->mtu = new_mtu;
+       return 0;
+}
+
+int switch_hw_receive(struct net_device *dev, struct dma_device_info *dma_dev)
+{
+       u8 *buf = NULL;
+       int len = 0;
+       struct sk_buff *skb = NULL;
+
+       len = dma_device_read(dma_dev, &buf, (void **) &skb);
+
+       if (len >= 0x600) {
+               printk("packet too large %d\n", len);
+               goto switch_hw_receive_err_exit;
+       }
+
+       /* remove CRC */
+       len -= 4;
+       if (skb == NULL) {
+               printk("cannot restore pointer\n");
+               goto switch_hw_receive_err_exit;
+       }
+       if (len > (skb->end - skb->tail)) {
+               printk("BUG, len:%d end:%p tail:%p\n", (len + 4), skb->end, skb->tail);
+               goto switch_hw_receive_err_exit;
+       }
+       skb_put(skb, len);
+       skb->dev = dev;
+       switch_rx(dev, len, skb);
+       return OK;
+  
+  switch_hw_receive_err_exit:
+       if (skb)
+               dev_kfree_skb_any(skb);
+       return -EIO;
+}
+
+int dma_intr_handler(struct dma_device_info *dma_dev, int status)
+{
+       struct net_device *dev;
+
+       dev = switch_devs + (u32) dma_dev->priv;
+       switch (status) {
+       case RCV_INT:
+               switch_hw_receive(dev, dma_dev);
+               break;
+       case TX_BUF_FULL_INT:
+               netif_stop_queue(dev);
+               break;
+       case TRANSMIT_CPT_INT:
+               netif_wake_queue(dev);
+               break;
+       }
+       return OK;
+}
+
+/* reserve 2 bytes in front of data pointer*/
+u8 *dma_buffer_alloc(int len, int *byte_offset, void **opt)
+{
+       u8 *buffer = NULL;
+       struct sk_buff *skb = NULL;
+       skb = dev_alloc_skb(ETHERNET_PACKET_DMA_BUFFER_SIZE);
+       if (skb == NULL) {
+               return NULL;
+       }
+       buffer = (u8 *) (skb->data);
+       skb_reserve(skb, 2);
+       *(int *) opt = (int) skb;
+       *byte_offset = 2;
+       return buffer;
+}
+
+int dma_buffer_free(u8 * dataptr, void *opt)
+{
+       struct sk_buff *skb = NULL;
+       if (opt == NULL) {
+               kfree(dataptr);
+       } else {
+               skb = (struct sk_buff *) opt;
+               dev_kfree_skb_any(skb);
+       }
+       return OK;
+}
+
+int init_dma_device(_dma_device_info * dma_dev)
+{
+       int i;
+       int num_tx_chan, num_rx_chan;
+       if (strcmp(dma_dev->device_name, "switch1") == 0) {
+               num_tx_chan = 1;
+               num_rx_chan = 2;
+               dma_dev->priv = (void *) 0;
+       } else {
+               num_tx_chan = 1;
+               num_rx_chan = 2;
+               dma_dev->priv = (void *) 1;
+       }
+
+       dma_dev->weight = 1;
+       dma_dev->num_tx_chan = num_tx_chan;
+       dma_dev->num_rx_chan = num_rx_chan;
+       dma_dev->ack = 1;
+       dma_dev->tx_burst_len = 4;
+       dma_dev->rx_burst_len = 4;
+       for (i = 0; i < dma_dev->num_tx_chan; i++) {
+               dma_dev->tx_chan[i].weight = QOS_DEFAULT_WGT;
+               dma_dev->tx_chan[i].desc_num = 10;
+               dma_dev->tx_chan[i].packet_size = 0;
+               dma_dev->tx_chan[i].control = 0;
+       }
+       for (i = 0; i < num_rx_chan; i++) {
+               dma_dev->rx_chan[i].weight = QOS_DEFAULT_WGT;
+               dma_dev->rx_chan[i].desc_num = 10;
+               dma_dev->rx_chan[i].packet_size = ETHERNET_PACKET_DMA_BUFFER_SIZE;
+               dma_dev->rx_chan[i].control = 0;
+       }
+       dma_dev->intr_handler = dma_intr_handler;
+       dma_dev->buffer_alloc = dma_buffer_alloc;
+       dma_dev->buffer_free = dma_buffer_free;
+       return 0;
+}
+
+int switch_set_mac_address(struct net_device *dev, void *p)
+{
+       struct sockaddr *addr = p;
+       memcpy(dev->dev_addr, addr->sa_data, dev->addr_len);
+       return OK;
+}
+
+
+int switch_init(struct net_device *dev)
+{
+       u64 retval = 0;
+       int i;
+       int result;
+       struct switch_priv *priv;
+       ether_setup(dev);                       /* assign some of the fields */
+       printk("%s up using ", dev->name);
+       dev->open = switch_open;
+       dev->stop = switch_release;
+       dev->hard_start_xmit = switch_tx;
+       dev->do_ioctl = switch_ioctl;
+       dev->get_stats = switch_stats;
+       dev->change_mtu = switch_change_mtu;
+       dev->set_mac_address = switch_set_mac_address;
+       dev->tx_timeout = switch_tx_timeout;
+       dev->watchdog_timeo = timeout;
+
+       SET_MODULE_OWNER(dev);
+
+       dev->priv = kmalloc(sizeof(struct switch_priv), GFP_KERNEL);
+       if (dev->priv == NULL)
+               return -ENOMEM;
+       memset(dev->priv, 0, sizeof(struct switch_priv));
+       priv = dev->priv;
+       priv->dma_device = (struct dma_device_info *) kmalloc(sizeof(struct dma_device_info), GFP_KERNEL);
+       if ((dev - switch_devs) == 0) {
+               sprintf(priv->dma_device->device_name, "switch1");
+       } else if ((dev - switch_devs) == 1) {
+               sprintf(priv->dma_device->device_name, "switch2");
+       }
+       printk("\"%s\"\n", priv->dma_device->device_name);
+       init_dma_device(priv->dma_device);
+       result = dma_device_register(priv->dma_device);
+
+       /* read the mac address from the mac table and put them into the mac table. */
+       for (i = 0; i < 6; i++) {
+               retval += my_ethaddr[i];
+       }
+       /* ethaddr not set in u-boot ? */
+       if (retval == 0) {
+               dev->dev_addr[0] = 0x00;
+               dev->dev_addr[1] = 0x20;
+               dev->dev_addr[2] = 0xda;
+               dev->dev_addr[3] = 0x86;
+               dev->dev_addr[4] = 0x23;
+               dev->dev_addr[5] = 0x74 + (unsigned char) (dev - switch_devs);
+       } else {
+               for (i = 0; i < 6; i++) {
+                       dev->dev_addr[i] = my_ethaddr[i];
+               }
+               dev->dev_addr[5] += +(unsigned char) (dev - switch_devs);
+       }
+       return OK;
+}
+
+int switch_init_module(void)
+{
+       int i = 0, result, device_present = 0;
+
+       for (i = 0; i < AMAZON_SW_INT_NO; i++) {
+               sprintf(switch_devs[i].name, "eth%d", i);
+
+               if ((result = register_netdev(switch_devs + i)))
+                       printk("error %i registering device \"%s\"\n", result, switch_devs[i].name);
+               else
+                       device_present++;
+       }
+       amazon_sw_chip_init();
+       return device_present ? 0 : -ENODEV;
+}
+
+void switch_cleanup(void)
+{
+       int i;
+       struct switch_priv *priv;
+       for (i = 0; i < AMAZON_SW_INT_NO; i++) {
+               priv = switch_devs[i].priv;
+               if (priv->dma_device) {
+                       dma_device_unregister(priv->dma_device);
+                       kfree(priv->dma_device);
+               }
+               kfree(switch_devs[i].priv);
+               unregister_netdev(switch_devs + i);
+       }
+       return;
+}
+
+module_init(switch_init_module);
+module_exit(switch_cleanup);
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Wu Qi Ming");
diff --git a/target/linux/amazon-2.6/files/drivers/serial/amazon_asc.c b/target/linux/amazon-2.6/files/drivers/serial/amazon_asc.c
new file mode 100644 (file)
index 0000000..a9be480
--- /dev/null
@@ -0,0 +1,755 @@
+/*
+ *  linux/drivers/char/amazon_asc.c
+ *
+ *  Driver for AMAZONASC serial ports
+ *
+ *  Copyright (C) 2004 Infineon IFAP DC COM CPE
+ *  Copyright (C) 2007 Felix Fietkau <nbd@openwrt.org>
+ *  Copyright (C) 2007 John Crispin <blogic@openwrt.org>
+ *
+ *  Based on drivers/char/serial.c, by Linus Torvalds, Theodore Ts'o.
+ *  Based on drivers/serial/serial_s3c2400.c
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ *  $Id: amazon_asc.c,v 1.2 2005/04/01 02:40:48 pliu Exp $
+ *
+ * This is a generic driver for AMAZONASC-type serial ports.
+ */
+
+#include <linux/module.h>
+#include <linux/errno.h>
+#include <linux/signal.h>
+#include <linux/sched.h>
+#include <linux/interrupt.h>
+#include <linux/tty.h>
+#include <linux/tty_flip.h>
+#include <linux/major.h>
+#include <linux/string.h>
+#include <linux/fcntl.h>
+#include <linux/ptrace.h>
+#include <linux/ioport.h>
+#include <linux/mm.h>
+#include <linux/slab.h>
+#include <linux/init.h>
+#include <linux/circ_buf.h>
+#include <linux/serial.h>
+#include <linux/serial_core.h>
+#include <linux/console.h>
+#include <linux/sysrq.h>
+#include <linux/irq.h>
+
+#include <asm/system.h>
+#include <asm/io.h>
+#include <asm/uaccess.h>
+#include <asm/bitops.h>
+#include <asm/amazon/amazon.h>
+#include <asm/amazon/irq.h>
+#include <asm/amazon/serial.h>
+
+#define PORT_AMAZONASC  111
+
+#if defined(CONFIG_SERIAL_AMAZONASC_CONSOLE) && defined(CONFIG_MAGIC_SYSRQ)
+#define SUPPORT_SYSRQ
+#endif
+
+#include <linux/serial_core.h>
+
+#define UART_NR                1
+
+#define SERIAL_AMAZONASC_MAJOR TTY_MAJOR
+#define CALLOUT_AMAZONASC_MAJOR        TTYAUX_MAJOR
+#define SERIAL_AMAZONASC_MINOR 64
+#define SERIAL_AMAZONASC_NR    UART_NR
+
+extern void prom_printf(const char * fmt, ...);
+static struct uart_port amazonasc_ports[UART_NR];
+static struct uart_driver amazonasc_reg;
+#ifdef CONFIG_SERIAL_AMAZONASC_CONSOLE /*SUPPORT_SYSRQ*/
+static struct console amazonasc_console;
+#endif
+static unsigned int uartclk = 0;
+
+#define SET_BIT(reg, mask)    *reg |= (mask)
+#define CLEAR_BIT(reg, mask)  *reg &= (~mask) 
+#define CLEAR_BITS(reg, mask) CLEAR_BIT(reg, mask)
+#define SET_BITS(reg, mask)   SET_BIT(reg, mask)
+#define SET_BITFIELD(reg, mask, off, val) \
+                               {*reg &= (~mask); *reg |= (val << off);}
+
+static void amazonasc_tx_chars(struct uart_port *port);
+
+/* fake flag to indicate CREAD was not set -> throw away all bytes */
+#define UART_DUMMY_UER_RX 1
+
+/* macro to set the bit corresponding to an interrupt number */
+#define BIT_NO(irq) (1 << (irq - 64))
+
+#define  SERIAL_DEBUG
+
+extern unsigned int amazon_get_fpi_hz(void);
+static int tx_enabled = 0;
+
+static void amazonasc_stop_tx(struct uart_port *port)
+{
+       /* fifo underrun shuts up after firing once */
+       return;
+}
+
+static void amazonasc_start_tx(struct uart_port *port)
+{
+       unsigned long flags;
+
+       local_irq_save(flags);
+       amazonasc_tx_chars(port);
+       local_irq_restore(flags);
+
+       return;
+}
+
+static void amazonasc_stop_rx(struct uart_port *port)
+{
+       /* clear the RX enable bit */
+       *AMAZON_ASC_WHBCON = ASCWHBCON_CLRREN;
+}
+
+static void amazonasc_enable_ms(struct uart_port *port)
+{
+       /* no modem signals */
+       return;
+}
+
+static void
+amazonasc_rx_chars(struct uart_port *port)
+{
+       struct tty_struct *tty = port->info->tty;
+       unsigned int ch = 0, rsr = 0, fifocnt;
+       unsigned long flags;
+
+       fifocnt = *AMAZON_ASC_FSTAT & ASCFSTAT_RXFFLMASK;
+       while (fifocnt--)
+       {
+               u8 flag = TTY_NORMAL;
+               ch = *AMAZON_ASC_RBUF;
+               rsr = (*AMAZON_ASC_CON & ASCCON_ANY) | UART_DUMMY_UER_RX;
+               tty_flip_buffer_push(tty);
+               port->icount.rx++;
+
+               /*
+                * Note that the error handling code is
+                * out of the main execution path
+                */
+               if (rsr & ASCCON_ANY) {
+                       if (rsr & ASCCON_PE) {
+                               port->icount.parity++;
+                               SET_BIT(AMAZON_ASC_WHBCON, ASCWHBCON_CLRPE);
+                       } else if (rsr & ASCCON_FE) {
+                               port->icount.frame++;
+                               SET_BIT(AMAZON_ASC_WHBCON, ASCWHBCON_CLRFE);
+                       }
+                       if (rsr & ASCCON_OE) {
+                               port->icount.overrun++;
+                               SET_BIT(AMAZON_ASC_WHBCON, ASCWHBCON_CLROE);
+                       }
+
+                       rsr &= port->read_status_mask;
+
+                       if (rsr & ASCCON_PE)
+                               flag = TTY_PARITY;
+                       else if (rsr & ASCCON_FE)
+                               flag = TTY_FRAME;
+               }
+
+               if ((rsr & port->ignore_status_mask) == 0)
+                       tty_insert_flip_char(tty, ch, flag);
+
+               if (rsr & ASCCON_OE)
+                       /*
+                        * Overrun is special, since it's reported
+                        * immediately, and doesn't affect the current
+                        * character
+                        */
+                       tty_insert_flip_char(tty, 0, TTY_OVERRUN);
+       }
+       if (ch != 0)
+               tty_flip_buffer_push(tty);
+
+       return;
+}
+
+
+static void amazonasc_tx_chars(struct uart_port *port)
+{
+       struct circ_buf *xmit = &port->info->xmit;
+
+       if (uart_tx_stopped(port)) {
+               amazonasc_stop_tx(port);
+               return;
+       }
+       
+       while (((*AMAZON_ASC_FSTAT & ASCFSTAT_TXFFLMASK)
+                       >> ASCFSTAT_TXFFLOFF) != AMAZONASC_TXFIFO_FULL)
+       {
+               if (port->x_char) {
+                       *AMAZON_ASC_TBUF = port->x_char;
+                       port->icount.tx++;
+                       port->x_char = 0;
+                       continue;
+               }
+
+               if (uart_circ_empty(xmit))
+                       break;
+
+               *AMAZON_ASC_TBUF = xmit->buf[xmit->tail];
+               xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1);
+               port->icount.tx++;
+       }
+
+       if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS)
+               uart_write_wakeup(port);
+}
+
+static irqreturn_t amazonasc_tx_int(int irq, void *port)
+{
+       *(AMAZON_ASC_IRNCR1) = ASC_IRNCR_TIR;
+       amazonasc_start_tx(port);
+
+       /* clear any pending interrupts */
+       SET_BIT(AMAZON_ASC_WHBCON, ASCWHBCON_CLRPE);
+       SET_BIT(AMAZON_ASC_WHBCON, ASCWHBCON_CLRFE);
+       SET_BIT(AMAZON_ASC_WHBCON, ASCWHBCON_CLROE);
+
+       return IRQ_HANDLED;
+}
+
+static irqreturn_t amazonasc_er_int(int irq, void *port)
+{
+       /* clear any pending interrupts */
+       SET_BIT(AMAZON_ASC_WHBCON, ASCWHBCON_CLRPE);
+       SET_BIT(AMAZON_ASC_WHBCON, ASCWHBCON_CLRFE);
+       SET_BIT(AMAZON_ASC_WHBCON, ASCWHBCON_CLROE);
+       return IRQ_HANDLED;
+}
+
+static irqreturn_t amazonasc_rx_int(int irq, void *port)
+{
+       *(AMAZON_ASC_IRNCR1) = ASC_IRNCR_RIR;
+       amazonasc_rx_chars((struct uart_port *) port);
+       return IRQ_HANDLED;
+}
+
+static u_int amazonasc_tx_empty(struct uart_port *port)
+{
+       int status;
+
+       /*
+        * FSTAT tells exactly how many bytes are in the FIFO.
+        * The question is whether we really need to wait for all
+        * 16 bytes to be transmitted before reporting that the
+        * transmitter is empty.
+        */
+       status = *AMAZON_ASC_FSTAT & ASCFSTAT_TXFFLMASK;
+       return status ? 0 : TIOCSER_TEMT;
+}
+
+static u_int amazonasc_get_mctrl(struct uart_port *port)
+{
+       /* no modem control signals - the readme says to pretend all are set */
+       return TIOCM_CTS|TIOCM_CAR|TIOCM_DSR;
+}
+
+static void amazonasc_set_mctrl(struct uart_port *port, u_int mctrl)
+{
+       /* no modem control - just return */
+       return;
+}
+
+static void amazonasc_break_ctl(struct uart_port *port, int break_state)
+{
+       /* no way to send a break */
+       return;
+}
+
+static int amazonasc_startup(struct uart_port *port)
+{
+       unsigned int con = 0;
+       unsigned long flags;
+       int retval;
+
+       /* this assumes: CON.BRS = CON.FDE = 0 */
+       if (uartclk == 0)
+               uartclk = amazon_get_fpi_hz();
+
+       amazonasc_ports[0].uartclk = uartclk;
+
+       /* block the IRQs */
+       local_irq_save(flags);
+
+       /* this setup was probably already done in u-boot */
+       /* ASC and GPIO Port 1 bits 3 and 4 share the same pins
+        * P1.3 (RX) in, Alternate 10
+        * P1.4 (TX) in, Alternate 10
+        */
+        SET_BITFIELD((AMAZON_GPIO_P1_DIR), 0x8, 4, 1);         //P1.4 output, P1.3 input
+        SET_BIT((AMAZON_GPIO_P1_ALTSEL0), 0x18);               //ALTSETL0 11
+        CLEAR_BIT((AMAZON_GPIO_P1_ALTSEL1), 0x18);             //ALTSETL1 00
+        SET_BITFIELD((AMAZON_GPIO_P1_OD), 0x8, 4, 1);
+       
+       /* set up the CLC */
+       CLEAR_BIT(AMAZON_ASC_CLC, AMAZON_ASC_CLC_DISS);
+       SET_BITFIELD(AMAZON_ASC_CLC, ASCCLC_RMCMASK, ASCCLC_RMCOFFSET, 1);
+       /* asynchronous mode */
+       con = ASCCON_M_8ASYNC;
+       /* set error signals  - framing and overrun */
+       con |= ASCCON_FEN;
+       con |= ASCCON_OEN;
+       con |= ASCCON_PEN;
+       /* choose the line - there's only one */
+       *AMAZON_ASC_PISEL = 0;
+#if 1
+       *AMAZON_ASC_TXFCON = (((AMAZONASC_TXFIFO_FL<<ASCTXFCON_TXFITLOFF)&ASCTXFCON_TXFITLMASK) | ASCTXFCON_TXFEN |ASCTXFCON_TXFFLU);
+       *AMAZON_ASC_RXFCON = (((AMAZONASC_RXFIFO_FL<<ASCRXFCON_RXFITLOFF)&ASCRXFCON_RXFITLMASK) | ASCRXFCON_RXFEN |ASCRXFCON_RXFFLU);
+       wmb();
+#else
+       /* TXFIFO's fill level */
+       SET_BITFIELD(AMAZON_ASC_TXFCON, ASCTXFCON_TXFITLMASK,
+               ASCTXFCON_TXFITLOFF, AMAZONASC_TXFIFO_FL);
+       /* enable TXFIFO */
+       SET_BIT(AMAZON_ASC_TXFCON, ASCTXFCON_TXFEN);
+       /* RXFIFO's fill level */
+       SET_BITFIELD(AMAZON_ASC_RXFCON, ASCRXFCON_RXFITLMASK,
+               ASCRXFCON_RXFITLOFF, AMAZONASC_RXFIFO_FL);
+       /* enable RXFIFO */
+       SET_BIT(AMAZON_ASC_RXFCON, ASCRXFCON_RXFEN);
+       /* now really set CON */
+#endif
+       SET_BIT(AMAZON_ASC_CON,con);
+
+       /*
+        * Allocate the IRQs
+        */
+       retval = request_irq(AMAZONASC_RIR, amazonasc_rx_int, 0, "asc_rx", port);
+       if (retval){
+               printk("-------req1 failed\n");
+               return retval;
+       }
+       retval = request_irq(AMAZONASC_TIR, amazonasc_tx_int, 0, "asc_tx", port);
+       if (retval){
+               printk("----------req2 failed\n");
+               goto err1;
+       }
+
+       retval = request_irq(AMAZONASC_EIR, amazonasc_er_int, 0, "asc_er", port);
+       if (retval){
+               printk("---------req3 failed\n");
+               goto err2;
+       }
+       /* unblock the IRQs */
+       local_irq_restore(flags);
+       return 0;
+
+err2:
+       free_irq(AMAZONASC_TIR, port);
+       
+err1:
+       free_irq(AMAZONASC_RIR, port);
+       local_irq_restore(flags);
+       return retval;
+}
+
+static void amazonasc_shutdown(struct uart_port *port)
+{
+       /*
+        * Free the interrupts
+        */
+       free_irq(AMAZONASC_RIR, port);
+       free_irq(AMAZONASC_TIR, port);
+       free_irq(AMAZONASC_EIR, port);
+       /*
+        * disable the baudrate generator to disable the ASC
+        */
+       *AMAZON_ASC_CON = 0;
+
+       /* flush and then disable the fifos */
+       SET_BIT(AMAZON_ASC_RXFCON, ASCRXFCON_RXFFLU);
+       CLEAR_BIT(AMAZON_ASC_RXFCON, ASCRXFCON_RXFEN);
+       SET_BIT(AMAZON_ASC_TXFCON, ASCTXFCON_TXFFLU);
+       CLEAR_BIT(AMAZON_ASC_TXFCON, ASCTXFCON_TXFEN);
+}
+
+static void amazonasc_set_termios(struct uart_port *port, struct ktermios *new, struct ktermios *old)
+{
+       unsigned int cflag;
+       unsigned int iflag;
+       unsigned int baud, quot;
+       unsigned int con = 0;
+       unsigned long flags;
+
+       cflag = new->c_cflag;
+       iflag = new->c_iflag;
+
+       /* byte size and parity */
+       switch (cflag & CSIZE) {
+       /* 7 bits are always with parity */
+       case CS7: con = ASCCON_M_7ASYNCPAR; break;
+       /* the ASC only suports 7 and 8 bits */
+       case CS5:
+       case CS6:
+       default:
+               if (cflag & PARENB)
+                       con = ASCCON_M_8ASYNCPAR;
+               else
+                       con = ASCCON_M_8ASYNC;
+               break;
+       }
+       if (cflag & CSTOPB)
+               con |= ASCCON_STP;
+       if (cflag & PARENB) {
+               if (!(cflag & PARODD))
+                       con &= ~ASCCON_ODD;
+               else
+                       con |= ASCCON_ODD;
+       }
+
+       port->read_status_mask = ASCCON_OE;
+       if (iflag & INPCK)
+               port->read_status_mask |= ASCCON_FE | ASCCON_PE;
+       /* the ASC can't really detect or generate a BREAK */
+#if 0
+       if (iflag & (BRKINT | PARMRK))
+               port->read_status_mask |= UERSTAT_BREAK;
+#endif
+       /*
+        * Characters to ignore
+        */
+       port->ignore_status_mask = 0;
+       if (iflag & IGNPAR)
+               port->ignore_status_mask |= ASCCON_FE | ASCCON_PE;
+#if 0
+       /* always ignore breaks - the ASC can't handle them XXXX */
+       port->ignore_status_mask |= UERSTAT_BREAK;
+#endif
+       if (iflag & IGNBRK) {
+               /*port->ignore_status_mask |= UERSTAT_BREAK;*/
+               /*
+                * If we're ignoring parity and break indicators,
+                * ignore overruns too (for real raw support).
+                */
+               if (iflag & IGNPAR)
+                       port->ignore_status_mask |= ASCCON_OE;
+       }
+
+       /*
+        * Ignore all characters if CREAD is not set.
+        */
+       if ((cflag & CREAD) == 0)
+               port->ignore_status_mask |= UART_DUMMY_UER_RX;
+
+       /* set error signals  - framing, parity  and overrun */
+       con |= ASCCON_FEN;
+       con |= ASCCON_OEN;
+       con |= ASCCON_PEN;
+       /* enable the receiver */
+       con |= ASCCON_REN;
+
+       /* block the IRQs */
+       local_irq_save(flags);
+
+       /* set up CON */
+       *AMAZON_ASC_CON = con;
+
+       /* Set baud rate - take a divider of 2 into account */
+    baud = uart_get_baud_rate(port, new, old, 0, port->uartclk/16);
+       quot = uart_get_divisor(port, baud);
+       quot = quot/2 - 1;
+
+       /* the next 3 probably already happened when we set CON above */
+       /* disable the baudrate generator */
+       CLEAR_BIT(AMAZON_ASC_CON, ASCCON_R);
+       /* make sure the fractional divider is off */
+       CLEAR_BIT(AMAZON_ASC_CON, ASCCON_FDE);
+       /* set up to use divisor of 2 */
+       CLEAR_BIT(AMAZON_ASC_CON, ASCCON_BRS);
+       /* now we can write the new baudrate into the register */
+       *AMAZON_ASC_BTR = quot;
+       /* turn the baudrate generator back on */
+       SET_BIT(AMAZON_ASC_CON, ASCCON_R);
+
+       /* unblock the IRQs */
+       local_irq_restore(flags);
+}
+
+static const char *amazonasc_type(struct uart_port *port)
+{
+       return port->type == PORT_AMAZONASC ? "AMAZONASC" : NULL;
+}
+
+/*
+ * Release the memory region(s) being used by 'port'
+ */
+static void amazonasc_release_port(struct uart_port *port)
+{
+       return;
+}
+
+/*
+ * Request the memory region(s) being used by 'port'
+ */
+static int amazonasc_request_port(struct uart_port *port)
+{
+       return 0;
+}
+
+/*
+ * Configure/autoconfigure the port.
+ */
+static void amazonasc_config_port(struct uart_port *port, int flags)
+{
+       if (flags & UART_CONFIG_TYPE) {
+               port->type = PORT_AMAZONASC;
+               amazonasc_request_port(port);
+       }
+}
+
+/*
+ * verify the new serial_struct (for TIOCSSERIAL).
+ */
+static int amazonasc_verify_port(struct uart_port *port, struct serial_struct *ser)
+{
+       int ret = 0;
+       if (ser->type != PORT_UNKNOWN && ser->type != PORT_AMAZONASC)
+               ret = -EINVAL;
+       if (ser->irq < 0 || ser->irq >= NR_IRQS)
+               ret = -EINVAL;
+       if (ser->baud_base < 9600)
+               ret = -EINVAL;
+       return ret;
+}
+
+static struct uart_ops amazonasc_pops = {
+       .tx_empty =     amazonasc_tx_empty,
+       .set_mctrl =    amazonasc_set_mctrl,
+       .get_mctrl =    amazonasc_get_mctrl,
+       .stop_tx =      amazonasc_stop_tx,
+       .start_tx =     amazonasc_start_tx,
+       .stop_rx =      amazonasc_stop_rx,
+       .enable_ms =    amazonasc_enable_ms,
+       .break_ctl =    amazonasc_break_ctl,
+       .startup =      amazonasc_startup,
+       .shutdown =     amazonasc_shutdown,
+       .set_termios =  amazonasc_set_termios,
+       .type =         amazonasc_type,
+       .release_port = amazonasc_release_port,
+       .request_port = amazonasc_request_port,
+       .config_port =  amazonasc_config_port,
+       .verify_port =  amazonasc_verify_port,
+};
+
+static struct uart_port amazonasc_ports[UART_NR] = {
+       {
+               membase:        (void *)AMAZON_ASC,
+               mapbase:        AMAZON_ASC,
+               iotype:         SERIAL_IO_MEM,
+               irq:            AMAZONASC_RIR, /* RIR */
+               uartclk:        0, /* filled in dynamically */
+               fifosize:       16,
+               unused:         { AMAZONASC_TIR, AMAZONASC_EIR}, /* xmit/error/xmit-buffer-empty IRQ */
+               type:           PORT_AMAZONASC,
+               ops:            &amazonasc_pops,
+               flags:          ASYNC_BOOT_AUTOCONF,
+       },
+};
+
+
+
+static void amazonasc_console_write(struct console *co, const char *s, u_int count)
+{
+       int i, fifocnt;
+       unsigned long flags;
+       /* block the IRQ */
+       local_irq_save(flags);
+       /*
+        *      Now, do each character
+        */
+       for (i = 0; i < count;)
+       {
+               /* wait until the FIFO is not full */
+               do
+               {
+                       fifocnt = (*AMAZON_ASC_FSTAT & ASCFSTAT_TXFFLMASK)
+                                       >> ASCFSTAT_TXFFLOFF;
+               } while (fifocnt == AMAZONASC_TXFIFO_FULL);
+#if 1
+               if (s[i] == '\0')
+               {
+                       break;
+               }
+#endif
+               if (s[i] == '\n')
+               {
+                       *AMAZON_ASC_TBUF = '\r';
+                       do
+                       {
+                               fifocnt = (*AMAZON_ASC_FSTAT &
+                               ASCFSTAT_TXFFLMASK) >> ASCFSTAT_TXFFLOFF;
+                       } while (fifocnt == AMAZONASC_TXFIFO_FULL);
+               }
+               *AMAZON_ASC_TBUF = s[i];
+               i++;
+       } /* for */
+
+       /* restore the IRQ */
+       local_irq_restore(flags);
+}
+
+static void __init
+amazonasc_console_get_options(struct uart_port *port, int *baud, int *parity, int *bits)
+{
+       u_int lcr_h;
+
+       lcr_h = *AMAZON_ASC_CON;
+       /* do this only if the ASC is turned on */
+       if (lcr_h & ASCCON_R) {
+               u_int quot, div, fdiv, frac;
+
+               *parity = 'n';
+               if ((lcr_h & ASCCON_MODEMASK) == ASCCON_M_7ASYNCPAR ||
+                           (lcr_h & ASCCON_MODEMASK) == ASCCON_M_8ASYNCPAR) {
+                       if (lcr_h & ASCCON_ODD)
+                               *parity = 'o';
+                       else
+                               *parity = 'e';
+               }
+
+               if ((lcr_h & ASCCON_MODEMASK) == ASCCON_M_7ASYNCPAR)
+                       *bits = 7;
+               else
+                       *bits = 8;
+
+               quot = *AMAZON_ASC_BTR + 1;
+               
+               /* this gets hairy if the fractional divider is used */
+               if (lcr_h & ASCCON_FDE)
+               {
+                       div = 1;
+                       fdiv = *AMAZON_ASC_FDV;
+                       if (fdiv == 0)
+                               fdiv = 512;
+                       frac = 512;
+               }
+               else
+               {
+                       div = lcr_h & ASCCON_BRS ? 3 : 2;
+                       fdiv = frac = 1;
+               }
+               /*
+                * This doesn't work exactly because we use integer
+                * math to calculate baud which results in rounding
+                * errors when we try to go from quot -> baud !!
+                * Try to make this work for both the fractional divider
+                * and the simple divider. Also try to avoid rounding
+                * errors using integer math.
+                */
+               
+               *baud = frac * (port->uartclk / (div * 512 * 16 * quot));
+               if (*baud > 1100 && *baud < 2400)
+                       *baud = 1200;
+               if (*baud > 2300 && *baud < 4800)
+                       *baud = 2400;
+               if (*baud > 4700 && *baud < 9600)
+                       *baud = 4800;
+               if (*baud > 9500 && *baud < 19200)
+                       *baud = 9600;
+               if (*baud > 19000 && *baud < 38400)
+                       *baud = 19200;
+               if (*baud > 38400 && *baud < 57600)
+                       *baud = 38400;
+               if (*baud > 57600 && *baud < 115200)
+                       *baud = 57600;
+               if (*baud > 115200 && *baud < 230400)
+                       *baud = 115200;
+       }
+}
+
+static int __init amazonasc_console_setup(struct console *co, char *options)
+{
+       struct uart_port *port;
+       int baud = 115200;
+       int bits = 8;
+       int parity = 'n';
+       int flow = 'n';
+
+       /* this assumes: CON.BRS = CON.FDE = 0 */
+       if (uartclk == 0)
+               uartclk = amazon_get_fpi_hz();
+       co->index = 0;  
+       port = &amazonasc_ports[0];
+       amazonasc_ports[0].uartclk = uartclk;
+       amazonasc_ports[0].type = PORT_AMAZONASC;
+
+       if (options){
+               uart_parse_options(options, &baud, &parity, &bits, &flow);
+       }
+
+       return uart_set_options(port, co, baud, parity, bits, flow);
+}
+
+static struct uart_driver amazonasc_reg;
+static struct console amazonasc_console = {
+       name:           "ttyS",
+       write:          amazonasc_console_write,
+       device:         uart_console_device,
+       setup:          amazonasc_console_setup,
+       flags:          CON_PRINTBUFFER,
+       index:          -1,
+       data:           &amazonasc_reg,
+};
+
+static int __init amazonasc_console_init(void)
+{
+       register_console(&amazonasc_console);
+       return 0;
+}
+console_initcall(amazonasc_console_init);
+
+static struct uart_driver amazonasc_reg = {
+       .owner =                        THIS_MODULE,
+       .driver_name =          "serial",
+       .dev_name =                     "ttyS",
+       .major =                        TTY_MAJOR,
+       .minor =                        64,
+       .nr =                           UART_NR,
+       .cons =                         &amazonasc_console,
+};
+
+static int __init amazonasc_init(void)
+{
+       unsigned char res;
+       uart_register_driver(&amazonasc_reg);
+       res = uart_add_one_port(&amazonasc_reg, &amazonasc_ports[0]);
+       return res;
+}
+
+static void __exit amazonasc_exit(void)
+{
+       uart_unregister_driver(&amazonasc_reg);
+}
+
+module_init(amazonasc_init);
+module_exit(amazonasc_exit);
+
+MODULE_AUTHOR("Gary Jennejohn, Felix Fietkau, John Crispin");
+MODULE_DESCRIPTION("MIPS AMAZONASC serial port driver");
+MODULE_LICENSE("GPL");
diff --git a/target/linux/amazon-2.6/files/include/asm-mips/amazon/adm6996.h b/target/linux/amazon-2.6/files/include/asm-mips/amazon/adm6996.h
new file mode 100644 (file)
index 0000000..77cf4b1
--- /dev/null
@@ -0,0 +1,232 @@
+/******************************************************************************
+     Copyright (c) 2004, Infineon Technologies.  All rights reserved.
+
+                               No Warranty
+   Because the program is licensed free of charge, there is no warranty for
+   the program, to the extent permitted by applicable law.  Except when
+   otherwise stated in writing the copyright holders and/or other parties
+   provide the program "as is" without warranty of any kind, either
+   expressed or implied, including, but not limited to, the implied
+   warranties of merchantability and fitness for a particular purpose. The
+   entire risk as to the quality and performance of the program is with
+   you.  should the program prove defective, you assume the cost of all
+   necessary servicing, repair or correction.
+
+   In no event unless required by applicable law or agreed to in writing
+   will any copyright holder, or any other party who may modify and/or
+   redistribute the program as permitted above, be liable to you for
+   damages, including any general, special, incidental or consequential
+   damages arising out of the use or inability to use the program
+   (including but not limited to loss of data or data being rendered
+   inaccurate or losses sustained by you or third parties or a failure of
+   the program to operate with any other programs), even if such holder or
+   other party has been advised of the possibility of such damages.
+ ******************************************************************************
+   Module      : ifx_swdrv.h
+   Date        : 2004-09-01
+   Description : JoeLin
+   Remarks:
+
+ *****************************************************************************/
+
+#ifndef _ADM_6996_MODULE_H_
+#define _ADM_6996_MODULE_H_
+
+#include <asm/amazon/amazon.h>
+
+#define ifx_printf(x)       printk x
+
+/* command codes */
+#define ADM_SW_SMI_READ     0x02
+#define ADM_SW_SMI_WRITE    0x01
+#define ADM_SW_SMI_START    0x01
+
+#define ADM_SW_EEPROM_WRITE     0x01
+#define ADM_SW_EEPROM_WRITE_ENABLE  0x03
+#define ADM_SW_EEPROM_WRITE_DISABLE 0x00
+#define EEPROM_TYPE     8   /* for 93C66 */
+
+/* bit masks */
+#define ADM_SW_BIT_MASK_1   0x00000001
+#define ADM_SW_BIT_MASK_2   0x00000002
+#define ADM_SW_BIT_MASK_4   0x00000008
+#define ADM_SW_BIT_MASK_10  0x00000200
+#define ADM_SW_BIT_MASK_16  0x00008000
+#define ADM_SW_BIT_MASK_32  0x80000000
+
+/* delay timers */
+#define ADM_SW_MDC_DOWN_DELAY   5
+#define ADM_SW_MDC_UP_DELAY 5
+#define ADM_SW_CS_DELAY     5
+
+/* MDIO modes */
+#define ADM_SW_MDIO_OUTPUT  1
+#define ADM_SW_MDIO_INPUT   0
+
+#define ADM_SW_MAX_PORT_NUM 5
+#define ADM_SW_MAX_VLAN_NUM 15
+
+/* registers */
+#define ADM_SW_PORT0_CONF   0x1
+#define ADM_SW_PORT1_CONF   0x3
+#define ADM_SW_PORT2_CONF   0x5
+#define ADM_SW_PORT3_CONF   0x7
+#define ADM_SW_PORT4_CONF   0x8
+#define ADM_SW_PORT5_CONF   0x9
+#define ADM_SW_VLAN_MODE    0x11
+#define ADM_SW_MAC_LOCK     0x12
+#define ADM_SW_VLAN0_CONF   0x13
+#define ADM_SW_PORT0_PVID   0x28
+#define ADM_SW_PORT1_PVID   0x29
+#define ADM_SW_PORT2_PVID   0x2a
+#define ADM_SW_PORT34_PVID  0x2b
+#define ADM_SW_PORT5_PVID   0x2c
+#define ADM_SW_PHY_RESET    0x2f
+#define ADM_SW_MISC_CONF    0x30
+#define ADM_SW_BNDWDH_CTL0  0x31
+#define ADM_SW_BNDWDH_CTL1  0x32
+#define ADM_SW_BNDWDH_CTL_ENA   0x33
+
+/* port modes */
+#define ADM_SW_PORT_FLOWCTL 0x1 /* 802.3x flow control */
+#define ADM_SW_PORT_AN      0x2 /* auto negotiation */
+#define ADM_SW_PORT_100M    0x4 /* 100M */
+#define ADM_SW_PORT_FULL    0x8 /* full duplex */
+#define ADM_SW_PORT_TAG     0x10    /* output tag on */
+#define ADM_SW_PORT_DISABLE 0x20    /* disable port */
+#define ADM_SW_PORT_TOS     0x40    /* TOS first */
+#define ADM_SW_PORT_PPRI    0x80    /* port based priority first */
+#define ADM_SW_PORT_MDIX    0x8000  /* auto MDIX on */
+#define ADM_SW_PORT_PVID_SHIFT  10
+#define ADM_SW_PORT_PVID_BITS   4
+
+/* VLAN */
+#define ADM_SW_VLAN_PORT0   0x1
+#define ADM_SW_VLAN_PORT1   0x2
+#define ADM_SW_VLAN_PORT2   0x10
+#define ADM_SW_VLAN_PORT3   0x40
+#define ADM_SW_VLAN_PORT4   0x80
+#define ADM_SW_VLAN_PORT5   0x100
+
+
+/* GPIO 012 enabled, output mode */
+#define GPIO_ENABLEBITS 0x000700f8
+
+/*
+  define AMAZON GPIO port to ADM6996 EEPROM interface
+  MDIO ->   EEDI        GPIO 16, AMAZON GPIO P1.0, bi-direction
+  MDC ->    EESK        GPIO 17, AMAZON GPIO P1.1, output only
+  MDCS ->   EECS        GPIO 18, AMAZON GPIO P1.2, output only
+            EEDO        GPIO 15, AMAZON GPIO P0.15, do not need this one! */
+
+#define GPIO_MDIO   1          //P1.0
+#define GPIO_MDC    2          //P1.1
+#define GPIO_MDCS   4          //P1.2
+
+//joelin #define GPIO_MDIO   0
+//joelin #define GPIO_MDC    5   /* PORT 0 GPIO5 */
+//joelin #define GPIO_MDCS   6   /* PORT 0 GPIO6 */
+
+
+#define MDIO_INPUT  0x00000001
+#define MDIO_OUTPUT_EN  0x00010000
+
+
+/* type definitions */
+typedef unsigned char U8;
+typedef unsigned short U16;
+typedef unsigned int U32;
+
+typedef struct _REGRW_
+{
+  unsigned int addr;
+  unsigned int value;
+  unsigned int mode;
+}REGRW, *PREGRW;
+
+//joelin adm6996i
+typedef struct _MACENTRY_
+{
+       unsigned char mac_addr[6];
+       unsigned long fid:4;
+            unsigned long portmap:6;
+       union  {
+               unsigned long age_timer:9;
+               unsigned long info_ctrl:9;
+       } ctrl;
+       unsigned long occupy:1;
+       unsigned long info_type:1;
+       unsigned long bad:1;
+       unsigned long result:3;//000:command ok ,001:all entry used,010:Entry Not found  ,011:try next entry ,101:command error
+       
+ }MACENTRY, *PMACENTRY;
+typedef struct _PROTOCOLFILTER_
+{
+       int protocol_filter_num;//[0~7]
+       int ip_p; //Value Compared with Protocol in IP Heade[7:0]
+       char action:2;//Action for protocol Filter .
+//00 = Protocol Portmap is Default Output Ports.
+//01 = Protocol Portmap is 6'b0.
+//10 = Protocol Portmap is the CPU port if the incoming port 
+//is not the CPU port. But if the incoming port is the CPU port, then Type Portmap contains Default Output Ports, excluding the CPU port.
+ }PROTOCOLFILTER, *PPROTOCOLFILTER;
+
+//joelin adm6996i
+
+/* Santosh: for IGMP proxy/snooping */
+
+//050614:fchang int adm_process_mac_table_request (unsigned int cmd, struct _MACENTRY_ *mac);
+//050614:fchang int adm_process_protocol_filter_request (unsigned int cmd, struct _PROTOCOLFILTER_ *filter);
+
+
+/* IOCTL keys */
+#define KEY_IOCTL_ADM_REGRW            0x01
+#define KEY_IOCTL_ADM_SW_REGRW         0x02
+#define KEY_IOCTL_ADM_SW_PORTSTS       0x03
+#define KEY_IOCTL_ADM_SW_INIT          0x04
+//for adm6996i-start
+#define        KEY_IOCTL_ADM_SW_IOCTL_MACENTRY_ADD             0x05
+#define        KEY_IOCTL_ADM_SW_IOCTL_MACENTRY_DEL             0x06
+#define        KEY_IOCTL_ADM_SW_IOCTL_MACENTRY_GET_INIT        0x07
+#define        KEY_IOCTL_ADM_SW_IOCTL_MACENTRY_GET_MORE        0x08
+#define        KEY_IOCTL_ADM_SW_IOCTL_FILTER_ADD               0x09
+#define        KEY_IOCTL_ADM_SW_IOCTL_FILTER_DEL               0x0a
+#define        KEY_IOCTL_ADM_SW_IOCTL_FILTER_GET               0x0b
+//adm6996i #define KEY_IOCTL_MAX_KEY       0x05
+#define KEY_IOCTL_MAX_KEY       0x0c
+//for adm6996i-end
+/* IOCTL MAGIC */
+#define ADM_MAGIC  ('a'|'d'|'m'|'t'|'e'|'k')
+
+/* IOCTL parameters */
+#define ADM_IOCTL_REGRW         _IOWR(ADM_MAGIC, KEY_IOCTL_ADM_REGRW, REGRW)
+#define ADM_SW_IOCTL_REGRW      _IOWR(ADM_MAGIC, KEY_IOCTL_ADM_SW_REGRW, REGRW)
+#define ADM_SW_IOCTL_PORTSTS    _IOWR(ADM_MAGIC, KEY_IOCTL_ADM_SW_PORTSTS, NULL)
+#define ADM_SW_IOCTL_INIT       _IOWR(ADM_MAGIC, KEY_IOCTL_ADM_SW_INIT, NULL)
+
+
+//6996i-stat
+#define ADM_SW_IOCTL_MACENTRY_ADD          _IOWR(ADM_MAGIC, KEY_IOCTL_ADM_SW_IOCTL_MACENTRY_ADD,MACENTRY)
+#define ADM_SW_IOCTL_MACENTRY_DEL          _IOWR(ADM_MAGIC, KEY_IOCTL_ADM_SW_IOCTL_MACENTRY_DEL,MACENTRY)
+#define ADM_SW_IOCTL_MACENTRY_GET_INIT      _IOWR(ADM_MAGIC, KEY_IOCTL_ADM_SW_IOCTL_MACENTRY_GET_INIT,MACENTRY)
+#define ADM_SW_IOCTL_MACENTRY_GET_MORE      _IOWR(ADM_MAGIC, KEY_IOCTL_ADM_SW_IOCTL_MACENTRY_GET_MORE,MACENTRY)
+#define ADM_SW_IOCTL_FILTER_ADD                    _IOWR(ADM_MAGIC, KEY_IOCTL_ADM_SW_IOCTL_FILTER_ADD,PROTOCOLFILTER)  
+#define ADM_SW_IOCTL_FILTER_DEL                    _IOWR(ADM_MAGIC, KEY_IOCTL_ADM_SW_IOCTL_FILTER_DEL,PROTOCOLFILTER)
+#define ADM_SW_IOCTL_FILTER_GET                    _IOWR(ADM_MAGIC, KEY_IOCTL_ADM_SW_IOCTL_FILTER_GET,PROTOCOLFILTER)  
+//6996i-end
+
+
+#define REG_READ    0x0
+#define REG_WRITE   0x1
+
+/* undefine symbol */
+#define AMAZON_SW_REG(reg)  *((volatile U32*)(reg))
+//#define GPIO0_INPUT_MASK    0
+//#define GPIO_conf0_REG      0x12345678
+//#define GPIO_SET_HI
+//#define GPIO_SET_LOW
+
+#endif
+/* _ADM_6996_MODULE_H_ */
diff --git a/target/linux/amazon-2.6/files/include/asm-mips/amazon/amazon.h b/target/linux/amazon-2.6/files/include/asm-mips/amazon/amazon.h
new file mode 100644 (file)
index 0000000..fa90a5e
--- /dev/null
@@ -0,0 +1,1512 @@
+#ifndef AMAZON_H
+#define AMAZON_H
+/******************************************************************************
+       Copyright (c) 2002, Infineon Technologies.  All rights reserved.
+
+                               No Warranty
+   Because the program is licensed free of charge, there is no warranty for 
+   the program, to the extent permitted by applicable law.  Except when     
+   otherwise stated in writing the copyright holders and/or other parties   
+   provide the program "as is" without warranty of any kind, either         
+   expressed or implied, including, but not limited to, the implied         
+   warranties of merchantability and fitness for a particular purpose. The  
+   entire risk as to the quality and performance of the program is with     
+   you.  should the program prove defective, you assume the cost of all     
+   necessary servicing, repair or correction.                               
+                                                                            
+   In no event unless required by applicable law or agreed to in writing    
+   will any copyright holder, or any other party who may modify and/or      
+   redistribute the program as permitted above, be liable to you for        
+   damages, including any general, special, incidental or consequential     
+   damages arising out of the use or inability to use the program           
+   (including but not limited to loss of data or data being rendered        
+   inaccurate or losses sustained by you or third parties or a failure of   
+   the program to operate with any other programs), even if such holder or  
+   other party has been advised of the possibility of such damages. 
+******************************************************************************/
+               
+/* check ADSL link status */
+#define AMAZON_CHECK_LINK
+         
+/***********************************************************************/
+/*  Module      :  WDT register address and bits                       */
+/***********************************************************************/
+         
+#define AMAZON_WDT                          (KSEG1+0x10100900)
+/***********************************************************************/   
+    
+/***Reset Request Register***/ 
+#define AMAZON_RST_REQ                      ((volatile u32*)(AMAZON_WDT+ 0x0010))
+#define AMAZON_RST_REQ_PLL                             (1 << 31)
+#define AMAZON_RST_REQ_PCI_CORE                        (1 << 13) 
+#define AMAZON_RST_REQ_TPE                             (1 << 12)
+#define AMAZON_RST_REQ_AFE                             (1 << 11)
+#define AMAZON_RST_REQ_DMA                             (1 << 9)
+#define AMAZON_RST_REQ_SWITCH                          (1 << 8)
+#define AMAZON_RST_REQ_DFE                             (1 << 7)
+#define AMAZON_RST_REQ_PHY                             (1 << 5)
+#define AMAZON_RST_REQ_PCI                             (1 << 4)
+#define AMAZON_RST_REQ_FPI                             (1 << 2)
+#define AMAZON_RST_REQ_CPU                             (1 << 1)
+#define AMAZON_RST_REQ_HRST                            (1 << 0)
+#define AMAZON_RST_ALL                         (AMAZON_RST_REQ_PLL     \
+                                               |AMAZON_RST_REQ_PCI_CORE \
+                                               |AMAZON_RST_REQ_TPE     \
+                                               |AMAZON_RST_REQ_AFE     \
+                                               |AMAZON_RST_REQ_DMA     \
+                                               |AMAZON_RST_REQ_SWITCH  \
+                                               |AMAZON_RST_REQ_DFE     \
+                                               |AMAZON_RST_REQ_PHY     \
+                                               |AMAZON_RST_REQ_PCI     \
+                                               |AMAZON_RST_REQ_FPI     \
+                                               |AMAZON_RST_REQ_CPU     \
+                                               |AMAZON_RST_REQ_HRST)
+      
+/***Reset Status Register Power On***/ 
+#define AMAZON_RST_SR                       ((volatile u32*)(AMAZON_WDT+ 0x0014))
+
+/***Watchdog Timer Control Register 0***/ 
+#define AMAZON_WDT_CON0                    ((volatile u32*)(AMAZON_WDT+ 0x0020))
+      
+/***Watchdog Timer Control Register 1***/ 
+#define AMAZON_WDT_CON1                    ((volatile u32*)(AMAZON_WDT+ 0x0024))
+#define AMAZON_WDT_CON1_WDTDR                          (1 << 3)
+#define AMAZON_WDT_CON1_WDTIR                          (1 << 2)
+      
+/***Watchdog Timer Status Register***/ 
+#define AMAZON_WDT_SR                       ((volatile u32*)(AMAZON_WDT+ 0x0028))
+#define AMAZON_WDT_SR_WDTTIM(value)             (((( 1 << 16) - 1) & (value)) << 16)
+#define AMAZON_WDT_SR_WDTPR                          (1 << 5)
+#define AMAZON_WDT_SR_WDTTO                          (1 << 4)
+#define AMAZON_WDT_SR_WDTDS                          (1 << 3)
+#define AMAZON_WDT_SR_WDTIS                          (1 << 2)
+#define AMAZON_WDT_SR_WDTOE                          (1 << 1)
+#define AMAZON_WDT_SR_WDTAE                          (1 << 0)          
+
+/***NMI Status Register***/ 
+#define AMAZON_WDT_NMISR                               ((volatile u32*)(AMAZON_WDT+ 0x002C))
+#define AMAZON_WDT_NMISR_NMIWDT                        (1 << 2)
+#define AMAZON_WDT_NMISR_NMIPLL                        (1 << 1)
+#define AMAZON_WDT_NMISR_NMIEXT                        (1 << 0)
+      
+#define AMAZON_WDT_RST_MON                             ((volatile u32*)(AMAZON_WDT+ 0x0030))
+
+/***********************************************************************/
+/*  Module      :  MCD register address and bits                       */
+/***********************************************************************/
+#define AMAZON_MCD                                     (KSEG1+0x1F106000)
+
+/***Manufacturer Identification Register***/ 
+#define AMAZON_MCD_MANID                               ((volatile u32*)(AMAZON_MCD+ 0x0024))
+#define AMAZON_MCD_MANID_MANUF(value)                  (((( 1 << 11) - 1) & (value)) << 5)
+
+/***Chip Identification Register***/ 
+#define AMAZON_MCD_CHIPID                              ((volatile u32*)(AMAZON_MCD+ 0x0028))
+#define AMAZON_MCD_CHIPID_VERSION_GET(value)             (((value) >> 28) & ((1 << 4) - 1))
+#define AMAZON_MCD_CHIPID_VERSION_SET(value)             (((( 1 << 4) - 1) & (value)) << 28)
+#define AMAZON_MCD_CHIPID_PART_NUMBER_GET(value)         (((value) >> 12) & ((1 << 16) - 1))
+#define AMAZON_MCD_CHIPID_PART_NUMBER_SET(value)         (((( 1 << 16) - 1) & (value)) << 12)
+#define AMAZON_MCD_CHIPID_MANID_GET(value)               (((value) >> 1) & ((1 << 11) - 1))
+#define AMAZON_MCD_CHIPID_MANID_SET(value)               (((( 1 << 11) - 1) & (value)) << 1)
+
+#define AMAZON_CHIPID_STANDARD                         0x00EB
+#define AMAZON_CHIPID_YANGTSE                          0x00ED
+
+/***Redesign Tracing Identification Register***/ 
+#define AMAZON_MCD_RTID                                ((volatile u32*)(AMAZON_MCD+ 0x002C))
+#define AMAZON_MCD_RTID_LC                              (1 << 15)
+#define AMAZON_MCD_RTID_RIX(value)                     (((( 1 << 3) - 1) & (value)) << 0)
+
+                 
+/***********************************************************************/
+/*  Module      :  CGU register address and bits                       */
+/***********************************************************************/
+         
+#define AMAZON_CGU                          (KSEG1+0x1F103000)
+/***********************************************************************/   
+
+/***CGU Clock Divider Select Register***/
+#define AMAZON_CGU_DIV                         ((volatile u32*)(AMAZON_CGU+ 0x0000))                   
+
+/***CGU PLL0 Status Register***/ 
+#define AMAZON_CGU_PLL0SR                      ((volatile u32*)(AMAZON_CGU+ 0x0004))
+      
+/***CGU PLL1 Status Register***/ 
+#define AMAZON_CGU_PLL1SR                      ((volatile u32*)(AMAZON_CGU+ 0x0008))
+      
+/***CGU Interface Clock Control Register***/ 
+#define AMAZON_CGU_IFCCR                       ((volatile u32*)(AMAZON_CGU+ 0x000c))
+      
+/***CGU Oscillator Control Register***/ 
+#define AMAZON_CGU_OSCCR                       ((volatile u32*)(AMAZON_CGU+ 0x0010))
+      
+/***CGU Memory Clock Delay Register***/ 
+#define AMAZON_CGU_MCDEL                       ((volatile u32*)(AMAZON_CGU+ 0x0014))
+      
+/***CGU CPU Clock Reduction Register***/ 
+#define AMAZON_CGU_CPUCRD                      ((volatile u32*)(AMAZON_CGU+ 0x0018))
+
+/* 165001:henryhsu:20050603:Source Add by Bing Tao */
+
+/***CGU Test Register**/
+#define AMAZON_CGU_TST                          ((volatile u32*)(AMAZON_CGU+ 0x003c))
+
+/* 165001 */
+
+
+/***********************************************************************/
+/*  Module      :  PMU register address and bits                       */
+/***********************************************************************/
+         
+#define AMAZON_PMU                          AMAZON_CGU
+/***********************************************************************/   
+
+      
+/***PMU Power Down Control Register***/ 
+#define AMAZON_PMU_PWDCR                       ((volatile u32*)(AMAZON_PMU+ 0x001c))
+#define AMAZON_PMU_PWDCR_TPE                            (1 << 13)
+#define AMAZON_PMU_PWDCR_PLL                            (1 << 12)
+#define AMAZON_PMU_PWDCR_XTAL                           (1 << 11)
+#define AMAZON_PMU_PWDCR_EBU                            (1 << 10)
+#define AMAZON_PMU_PWDCR_DFE                            (1 << 9)
+#define AMAZON_PMU_PWDCR_SPI                            (1 << 8)
+#define AMAZON_PMU_PWDCR_UART                           (1 << 7)
+#define AMAZON_PMU_PWDCR_GPT                            (1 << 6)
+#define AMAZON_PMU_PWDCR_DMA                            (1 << 5)
+#define AMAZON_PMU_PWDCR_PCI                            (1 << 4)
+#define AMAZON_PMU_PWDCR_SW                             (1 << 3)
+#define AMAZON_PMU_PWDCR_IOR                           (1 << 2)
+#define AMAZON_PMU_PWDCR_FPI                           (1 << 1)
+#define AMAZON_PMU_PWDCR_EPHY                          (1 << 0)
+      
+/***PMU Status Register***/ 
+#define AMAZON_PMU_SR                        ((volatile u32*)(AMAZON_PMU+ 0x0020))
+#define AMAZON_PMU_SR_TPE                              (1 << 13)
+#define AMAZON_PMU_SR_PLL                              (1 << 12)
+#define AMAZON_PMU_SR_XTAL                             (1 << 11)
+#define AMAZON_PMU_SR_EBU                              (1 << 10)
+#define AMAZON_PMU_SR_DFE                              (1 << 9)
+#define AMAZON_PMU_SR_SPI                              (1 << 8)
+#define AMAZON_PMU_SR_UART                             (1 << 7)
+#define AMAZON_PMU_SR_GPT                              (1 << 6)
+#define AMAZON_PMU_SR_DMA                              (1 << 5)
+#define AMAZON_PMU_SR_PCI                              (1 << 4)
+#define AMAZON_PMU_SR_SW                               (1 << 3)
+#define AMAZON_PMU_SR_IOR                                      (1 << 2)
+#define AMAZON_PMU_SR_FPI                              (1 << 1)
+#define AMAZON_PMU_SR_EPHY                             (1 << 0)
+         
+/***********************************************************************/
+/*  Module      :  BCU register address and bits                       */
+/***********************************************************************/
+         
+#define AMAZON_BCU                          (KSEG1+0x10100000)
+/***********************************************************************/   
+
+      
+/***BCU Control Register (0010H)***/ 
+#define AMAZON_BCU_CON                      ((volatile u32*)(AMAZON_BCU+ 0x0010))
+#define AMAZON_BCU_CON_SPC(value)                (((( 1 << 8) - 1) & (value)) << 24)
+#define AMAZON_BCU_CON_SPE                              (1 << 19)
+#define AMAZON_BCU_CON_PSE                              (1 << 18)
+#define AMAZON_BCU_CON_DBG                              (1 << 16)
+#define AMAZON_BCU_CON_TOUT(value)               (((( 1 << 16) - 1) & (value)) << 0)
+      
+/***BCU Error Control Capture Register (0020H)***/ 
+#define AMAZON_BCU_ECON                    ((volatile u32*)(AMAZON_BCU+ 0x0020))
+#define AMAZON_BCU_ECON_TAG(value)                (((( 1 << 4) - 1) & (value)) << 24)
+#define AMAZON_BCU_ECON_RDN                              (1 << 23)
+#define AMAZON_BCU_ECON_WRN                              (1 << 22)
+#define AMAZON_BCU_ECON_SVM                              (1 << 21)
+#define AMAZON_BCU_ECON_ACK(value)                (((( 1 << 2) - 1) & (value)) << 19)
+#define AMAZON_BCU_ECON_ABT                              (1 << 18)
+#define AMAZON_BCU_ECON_RDY                              (1 << 17)
+#define AMAZON_BCU_ECON_TOUT                            (1 << 16)
+#define AMAZON_BCU_ECON_ERRCNT(value)             (((( 1 << 16) - 1) & (value)) << 0)
+#define AMAZON_BCU_ECON_OPC(value)                (((( 1 << 4) - 1) & (value)) << 28)
+      
+/***BCU Error Address Capture Register (0024 H)***/ 
+#define AMAZON_BCU_EADD                    ((volatile u32*)(AMAZON_BCU+ 0x0024))
+#define AMAZON_BCU_EADD_FPIADR
+      
+/***BCU Error Data Capture Register (0028H)***/ 
+#define AMAZON_BCU_EDAT                    ((volatile u32*)(AMAZON_BCU+ 0x0028))
+#define AMAZON_BCU_EDAT_FPIDAT         
+         
+/***********************************************************************/
+/*  Module      :  Switch register address and bits                    */
+/***********************************************************************/
+         
+#define AMAZON_SWITCH                       (KSEG1+0x10106000)
+/***********************************************************************/   
+#define AMAZON_SW_UN_DEST                      AMAZON_SWITCH+0x00 /*Unknown destination register*/
+#define AMAZON_SW_VLAN_CTRL                    AMAZON_SWITCH+0x04 /*VLAN control register*/
+#define AMAZON_SW_PS_CTL                       AMAZON_SWITCH+0x08 /*port status control register*/
+#define AMAZON_SW_COS_CTL                      AMAZON_SWITCH+0x0c /*Cos control register*/
+#define        AMAZON_SW_VLAN_COS                      AMAZON_SWITCH+0x10 /*VLAN priority cos mapping register*/
+#define AMAZON_SW_DSCP_COS3                    AMAZON_SWITCH+0x14 /*DSCP cos mapping register3*/
+#define AMAZON_SW_DSCP_COS2                    AMAZON_SWITCH+0x18 /*DSCP cos mapping register2*/
+#define AMAZON_SW_DSCP_COS1                    AMAZON_SWITCH+0x1c /*DSCP cos mapping register1*/
+#define AMAZON_SW_DSCP_COS0                    AMAZON_SWITCH+0x20 /*DSCP cos mapping register*/
+#define AMAZON_SW_ARL_CTL                      AMAZON_SWITCH+0x24 /*ARL control register*/
+#define AMAZON_SW_PKT_LEN                      AMAZON_SWITCH+0x28 /*packet length register*/
+#define AMAZON_SW_CPU_ACTL                     AMAZON_SWITCH+0x2c /*CPU control register1*/
+#define AMAZON_SW_DATA1                        AMAZON_SWITCH+0x30 /*CPU access control register1*/
+#define AMAZON_SW_DATA2                        AMAZON_SWITCH+0x34 /*CPU access control register2*/
+#define AMAZON_SW_P2_PCTL                      AMAZON_SWITCH+0x38 /*Port2 control register*/
+#define AMAZON_SW_P0_TX_CTL                    AMAZON_SWITCH+0x3c /*port0 TX control register*/
+#define AMAZON_SW_P1_TX_CTL                    AMAZON_SWITCH+0x40 /*port 1 TX control register*/
+#define AMAZON_SW_P0_WM                        AMAZON_SWITCH+0x44 /*port 0 watermark control register*/
+#define AMAZON_SW_P1_WM                        AMAZON_SWITCH+0x48 /*port 1 watermark control register*/
+#define AMAZON_SW_P2_WM                        AMAZON_SWITCH+0x4c /*port 2 watermark control register*/
+#define AMAZON_SW_GBL_WM                       AMAZON_SWITCH+0x50 /*Global watermark register*/
+#define AMAZON_SW_PM_CTL                       AMAZON_SWITCH+0x54 /*PM control register*/
+#define AMAZON_SW_P2_CTL                       AMAZON_SWITCH+0x58 /*PMAC control register*/
+#define AMAZON_SW_P2_TX_IPG                    AMAZON_SWITCH+0x5c /*port2 TX IPG control register*/
+#define AMAZON_SW_P2_RX_IPG                    AMAZON_SWITCH+0x60 /*prot2 RX IPG control register*/
+#define AMAZON_SW_MDIO_ACC                     AMAZON_SWITCH+0x64 /*MDIO access register*/
+#define AMAZON_SW_EPHY                         AMAZON_SWITCH+0x68 /*Ethernet PHY register*/
+#define AMAZON_SW_MDIO_CFG                     AMAZON_SWITCH+0x6c /*MDIO configuration register*/
+#define AMAZON_SW_P0_RCV_DROP_CNT              AMAZON_SWITCH+0x70 /*port0 receive drop counter */
+#define AMAZON_SW_P0_RCV_FRAME_ERR_CNT         AMAZON_SWITCH+0x74 /*port0 receive frame error conter*/
+#define AMAZON_SW_P0_TX_COLL_CNT               AMAZON_SWITCH+0x78 /*port0 transmit collision counter*/ 
+#define AMAZON_SW_P0_TX_DROP_CNT               AMAZON_SWITCH+0x7c /*port1 transmit drop counter*/
+#define AMAZON_SW_P1_RCV_DROP_CNT              AMAZON_SWITCH+0x80 /*port1 receive drop counter*/
+#define AMAZON_SW_P1_RCV_FRAME_ERR_CNT         AMAZON_SWITCH+0x84 /*port1 receive error counter*/
+#define AMAZON_SW_P1_TX_COLL_CNT               AMAZON_SWITCH+0x88 /*port1 transmit collision counter*/
+#define AMAZON_SW_P1_TX_DROP_CNT               AMAZON_SWITCH+0x8c /*port1 transmit drop counter*/
+
+
+         
+/***********************************************************************/
+/*  Module      :  SSC register address and bits                      */
+/***********************************************************************/
+#define AMAZON_SSC_BASE_ADD_0                  (KSEG1+0x10100800)         
+
+/*165001:henryhsu:20050603:Source add by Bing Tao*/
+
+/*configuration/Status Registers in Bus Clock Domain*/
+#define AMAZON_SSC_CLC                          ((volatile u32*)(AMAZON_SSC_BASE_ADD_0+0x0000))
+#define AMAZON_SSC_ID                           ((volatile u32*)(AMAZON_SSC_BASE_ADD_0+0x0008))
+#define AMAZON_SSC_CON                          ((volatile u32*)(AMAZON_SSC_BASE_ADD_0+0x0010))
+#define AMAZON_SSC_STATE                       ((volatile u32*)(AMAZON_SSC_BASE_ADD_0+0x0014))
+#define AMAZON_SSC_WHBSTATE                    ((volatile u32*)(AMAZON_SSC_BASE_ADD_0+0x0018))
+#define AMAZON_SSC_TB                          ((volatile u32*)(AMAZON_SSC_BASE_ADD_0+0x0020))
+#define AMAZON_SSC_RB                          ((volatile u32*)(AMAZON_SSC_BASE_ADD_0+0x0024))
+#define AMAZON_SSC_FSTAT                       ((volatile u32*)(AMAZON_SSC_BASE_ADD_0+0x0038)) 
+
+/*Configuration/Status Registers in Kernel Clock Domain*/
+#define AMAZON_SSC_PISEL                       ((volatile u32*)(AMAZON_SSC_BASE_ADD_0+0x0004))
+#define AMAZON_SSC_RXFCON                      ((volatile u32*)(AMAZON_SSC_BASE_ADD_0+0x0030))
+#define AMAZON_SSC_TXFCON                      ((volatile u32*)(AMAZON_SSC_BASE_ADD_0+0x0034))
+#define AMAZON_SSC_BR                          ((volatile u32*)(AMAZON_SSC_BASE_ADD_0+0x0040))
+#define AMAZON_SSC_BRSTAT                      ((volatile u32*)(AMAZON_SSC_BASE_ADD_0+0x0044))
+#define AMAZON_SSC_SFCON                       ((volatile u32*)(AMAZON_SSC_BASE_ADD_0+0x0060))
+#define AMAZON_SSC_SFSTAT                      ((volatile u32*)(AMAZON_SSC_BASE_ADD_0+0x0064))
+#define AMAZON_SSC_GPOCON                      ((volatile u32*)(AMAZON_SSC_BASE_ADD_0+0x0070))
+#define AMAZON_SSC_GPOSTAT                     ((volatile u32*)(AMAZON_SSC_BASE_ADD_0+0x0074))
+#define AMAZON_SSC_WHBGPOSTAT                  ((volatile u32*)(AMAZON_SSC_BASE_ADD_0+0x0078))
+#define AMAZON_SSC_RXREQ                       ((volatile u32*)(AMAZON_SSC_BASE_ADD_0+0x0080))
+#define AMAZON_SSC_RXCNT                       ((volatile u32*)(AMAZON_SSC_BASE_ADD_0+0x0084))
+
+/*DMA Registers in Bus Clock Domain*/
+#define AMAZON_SSC_DMA_CON                     ((volatile u32*)(AMAZON_SSC_BASE_ADD_0+0x00ec))
+
+/*interrupt Node Registers in Bus Clock Domain*/
+#define AMAZON_SSC_IRNEN                       ((volatile u32*)(AMAZON_SSC_BASE_ADD_0+0x00F4))
+#define AMAZON_SSC_IRNICR                      ((volatile u32*)(AMAZON_SSC_BASE_ADD_0+0x00FC))
+#define AMAZON_SSC_IRNCR                       ((volatile u32*)(AMAZON_SSC_BASE_ADD_0+0x00F8))
+
+/*165001*/
+
+/***********************************************************************/   
+
+      
+         
+/***********************************************************************/
+/*  Module      :  EBU register address and bits                       */
+/***********************************************************************/
+         
+#define AMAZON_EBU                          (KSEG1+0x10105300)
+/***********************************************************************/   
+
+      
+/***EBU Clock Control Register***/ 
+#define AMAZON_EBU_CLC                      ((volatile u32*)(AMAZON_EBU+ 0x0000))
+#define AMAZON_EBU_CLC_DISS                            (1 << 1)
+#define AMAZON_EBU_CLC_DISR                            (1 << 0)
+      
+/***EBU Global Control Register***/ 
+#define AMAZON_EBU_CON                      ((volatile u32*)(AMAZON_EBU+ 0x0010))
+#define AMAZON_EBU_CON_DTACS(value)              (((( 1 << 3) - 1) & (value)) << 20)
+#define AMAZON_EBU_CON_DTARW(value)              (((( 1 << 3) - 1) & (value)) << 16)
+#define AMAZON_EBU_CON_TOUTC(value)              (((( 1 << 8) - 1) & (value)) << 8)
+#define AMAZON_EBU_CON_ARBMODE(value)            (((( 1 << 2) - 1) & (value)) << 6)
+#define AMAZON_EBU_CON_ARBSYNC                      (1 << 5)
+#define AMAZON_EBU_CON_1                              (1 << 3)
+      
+/***EBU Address Select Register 0***/ 
+#define AMAZON_EBU_ADDSEL0                  ((volatile u32*)(AMAZON_EBU+ 0x0020))
+#define AMAZON_EBU_ADDSEL0_BASE(value)               (((( 1 << 20) - 1) & (value)) << 12)
+#define AMAZON_EBU_ADDSEL0_MASK(value)               (((( 1 << 4) - 1) & (value)) << 4)
+#define AMAZON_EBU_ADDSEL0_MIRRORE                      (1 << 1)
+#define AMAZON_EBU_ADDSEL0_REGEN                          (1 << 0)
+      
+/***EBU Address Select Register 1***/ 
+#define AMAZON_EBU_ADDSEL1                  ((volatile u32*)(AMAZON_EBU+ 0x0024))
+#define AMAZON_EBU_ADDSEL1_BASE(value)               (((( 1 << 20) - 1) & (value)) << 12)
+#define AMAZON_EBU_ADDSEL1_MASK(value)               (((( 1 << 4) - 1) & (value)) << 4)
+#define AMAZON_EBU_ADDSEL1_MIRRORE                      (1 << 1)
+#define AMAZON_EBU_ADDSEL1_REGEN                          (1 << 0)
+      
+/***EBU Address Select Register 2***/ 
+#define AMAZON_EBU_ADDSEL2                  ((volatile u32*)(AMAZON_EBU+ 0x0028))
+#define AMAZON_EBU_ADDSEL2_BASE(value)               (((( 1 << 20) - 1) & (value)) << 12)
+#define AMAZON_EBU_ADDSEL2_MASK(value)               (((( 1 << 4) - 1) & (value)) << 4)
+#define AMAZON_EBU_ADDSEL2_MIRRORE                      (1 << 1)
+#define AMAZON_EBU_ADDSEL2_REGEN                          (1 << 0)
+      
+/***EBU Bus Configuration Register 0***/ 
+#define AMAZON_EBU_BUSCON0                  ((volatile u32*)(AMAZON_EBU+ 0x0060))
+#define AMAZON_EBU_BUSCON0_WRDIS                          (1 << 31)
+#define AMAZON_EBU_BUSCON0_ALEC(value)               (((( 1 << 2) - 1) & (value)) << 29)
+#define AMAZON_EBU_BUSCON0_BCGEN(value)              (((( 1 << 2) - 1) & (value)) << 27)
+#define AMAZON_EBU_BUSCON0_AGEN(value)               (((( 1 << 2) - 1) & (value)) << 24)
+#define AMAZON_EBU_BUSCON0_CMULTR(value)             (((( 1 << 2) - 1) & (value)) << 22)
+#define AMAZON_EBU_BUSCON0_WAIT(value)               (((( 1 << 2) - 1) & (value)) << 20)
+#define AMAZON_EBU_BUSCON0_WAITINV                      (1 << 19)
+#define AMAZON_EBU_BUSCON0_SETUP                          (1 << 18)
+#define AMAZON_EBU_BUSCON0_PORTW(value)              (((( 1 << 2) - 1) & (value)) << 16)
+#define AMAZON_EBU_BUSCON0_WAITRDC(value)            (((( 1 << 7) - 1) & (value)) << 9)
+#define AMAZON_EBU_BUSCON0_WAITWRC(value)            (((( 1 << 3) - 1) & (value)) << 6)
+#define AMAZON_EBU_BUSCON0_HOLDC(value)              (((( 1 << 2) - 1) & (value)) << 4)
+#define AMAZON_EBU_BUSCON0_RECOVC(value)             (((( 1 << 2) - 1) & (value)) << 2)
+#define AMAZON_EBU_BUSCON0_CMULT(value)              (((( 1 << 2) - 1) & (value)) << 0)
+      
+/***EBU Bus Configuration Register 1***/ 
+#define AMAZON_EBU_BUSCON1                  ((volatile u32*)(AMAZON_EBU+ 0x0064))
+#define AMAZON_EBU_BUSCON1_WRDIS                          (1 << 31)
+#define AMAZON_EBU_BUSCON1_ALEC(value)               (((( 1 << 2) - 1) & (value)) << 29)
+#define AMAZON_EBU_BUSCON1_BCGEN(value)              (((( 1 << 2) - 1) & (value)) << 27)
+#define AMAZON_EBU_BUSCON1_AGEN(value)               (((( 1 << 2) - 1) & (value)) << 24)
+#define AMAZON_EBU_BUSCON1_CMULTR(value)             (((( 1 << 2) - 1) & (value)) << 22)
+#define AMAZON_EBU_BUSCON1_WAIT(value)               (((( 1 << 2) - 1) & (value)) << 20)
+#define AMAZON_EBU_BUSCON1_WAITINV                      (1 << 19)
+#define AMAZON_EBU_BUSCON1_SETUP                          (1 << 18)
+#define AMAZON_EBU_BUSCON1_PORTW(value)              (((( 1 << 2) - 1) & (value)) << 16)
+#define AMAZON_EBU_BUSCON1_WAITRDC(value)            (((( 1 << 7) - 1) & (value)) << 9)
+#define AMAZON_EBU_BUSCON1_WAITWRC(value)            (((( 1 << 3) - 1) & (value)) << 6)
+#define AMAZON_EBU_BUSCON1_HOLDC(value)              (((( 1 << 2) - 1) & (value)) << 4)
+#define AMAZON_EBU_BUSCON1_RECOVC(value)             (((( 1 << 2) - 1) & (value)) << 2)
+#define AMAZON_EBU_BUSCON1_CMULT(value)              (((( 1 << 2) - 1) & (value)) << 0)
+      
+/***EBU Bus Configuration Register 2***/ 
+#define AMAZON_EBU_BUSCON2                  ((volatile u32*)(AMAZON_EBU+ 0x0068))
+#define AMAZON_EBU_BUSCON2_WRDIS                          (1 << 31)
+#define AMAZON_EBU_BUSCON2_ALEC(value)               (((( 1 << 2) - 1) & (value)) << 29)
+#define AMAZON_EBU_BUSCON2_BCGEN(value)              (((( 1 << 2) - 1) & (value)) << 27)
+#define AMAZON_EBU_BUSCON2_AGEN(value)               (((( 1 << 2) - 1) & (value)) << 24)
+#define AMAZON_EBU_BUSCON2_CMULTR(value)             (((( 1 << 2) - 1) & (value)) << 22)
+#define AMAZON_EBU_BUSCON2_WAIT(value)               (((( 1 << 2) - 1) & (value)) << 20)
+#define AMAZON_EBU_BUSCON2_WAITINV                      (1 << 19)
+#define AMAZON_EBU_BUSCON2_SETUP                          (1 << 18)
+#define AMAZON_EBU_BUSCON2_PORTW(value)              (((( 1 << 2) - 1) & (value)) << 16)
+#define AMAZON_EBU_BUSCON2_WAITRDC(value)            (((( 1 << 7) - 1) & (value)) << 9)
+#define AMAZON_EBU_BUSCON2_WAITWRC(value)            (((( 1 << 3) - 1) & (value)) << 6)
+#define AMAZON_EBU_BUSCON2_HOLDC(value)              (((( 1 << 2) - 1) & (value)) << 4)
+#define AMAZON_EBU_BUSCON2_RECOVC(value)             (((( 1 << 2) - 1) & (value)) << 2)
+#define AMAZON_EBU_BUSCON2_CMULT(value)              (((( 1 << 2) - 1) & (value)) << 0)                
+         
+/***********************************************************************/
+/*  Module      :  SDRAM register address and bits                     */
+/***********************************************************************/
+         
+#define AMAZON_SDRAM                        (KSEG1+0x1F800000)
+/***********************************************************************/   
+
+      
+/***MC Access Error Cause Register***/ 
+#define AMAZON_SDRAM_MC_ERRCAUSE                  ((volatile u32*)(AMAZON_SDRAM+ 0x0010))
+#define AMAZON_SDRAM_MC_ERRCAUSE_ERR                              (1 << 31)
+#define AMAZON_SDRAM_MC_ERRCAUSE_PORT(value)               (((( 1 << 4) - 1) & (value)) << 16)
+#define AMAZON_SDRAM_MC_ERRCAUSE_CAUSE(value)              (((( 1 << 2) - 1) & (value)) << 0)
+#define AMAZON_SDRAM_MC_ERRCAUSE_Res(value)                (((( 1 << NaN) - 1) & (value)) << NaN)
+      
+/***MC Access Error Address Register***/ 
+#define AMAZON_SDRAM_MC_ERRADDR                   ((volatile u32*)(AMAZON_SDRAM+ 0x0020))
+#define AMAZON_SDRAM_MC_ERRADDR_ADDR
+      
+/***MC I/O General Purpose Register***/ 
+#define AMAZON_SDRAM_MC_IOGP                      ((volatile u32*)(AMAZON_SDRAM+ 0x0100))
+#define AMAZON_SDRAM_MC_IOGP_GPR6(value)               (((( 1 << 4) - 1) & (value)) << 28)
+#define AMAZON_SDRAM_MC_IOGP_GPR5(value)               (((( 1 << 4) - 1) & (value)) << 24)
+#define AMAZON_SDRAM_MC_IOGP_GPR4(value)               (((( 1 << 4) - 1) & (value)) << 20)
+#define AMAZON_SDRAM_MC_IOGP_GPR3(value)               (((( 1 << 4) - 1) & (value)) << 16)
+#define AMAZON_SDRAM_MC_IOGP_GPR2(value)               (((( 1 << 4) - 1) & (value)) << 12)
+#define AMAZON_SDRAM_MC_IOGP_CPS                              (1 << 11)
+#define AMAZON_SDRAM_MC_IOGP_CLKDELAY(value)          (((( 1 << 3) - 1) & (value)) << 8)
+#define AMAZON_SDRAM_MC_IOGP_CLKRAT(value)             (((( 1 << 4) - 1) & (value)) << 4)
+#define AMAZON_SDRAM_MC_IOGP_RDDEL(value)              (((( 1 << 4) - 1) & (value)) << 0)
+      
+/***MC Self Refresh Register***/ 
+#define AMAZON_SDRAM_MC_SELFRFSH                  ((volatile u32*)(AMAZON_SDRAM+ 0x01A0))
+#define AMAZON_SDRAM_MC_SELFRFSH_PWDS                            (1 << 1)
+#define AMAZON_SDRAM_MC_SELFRFSH_PWD                              (1 << 0)
+#define AMAZON_SDRAM_MC_SELFRFSH_Res(value)                (((( 1 << 30) - 1) & (value)) << 2)
+      
+/***MC Enable Register***/ 
+#define AMAZON_SDRAM_MC_CTRLENA                   ((volatile u32*)(AMAZON_SDRAM+ 0x0110))
+#define AMAZON_SDRAM_MC_CTRLENA_ENA                              (1 << 0)
+#define AMAZON_SDRAM_MC_CTRLENA_Res(value)                (((( 1 << 31) - 1) & (value)) << 1)
+      
+/***MC Mode Register Setup Code***/ 
+#define AMAZON_SDRAM_MC_MRSCODE                   ((volatile u32*)(AMAZON_SDRAM+ 0x0120))
+#define AMAZON_SDRAM_MC_MRSCODE_UMC(value)                (((( 1 << 5) - 1) & (value)) << 7)
+#define AMAZON_SDRAM_MC_MRSCODE_CL(value)                (((( 1 << 3) - 1) & (value)) << 4)
+#define AMAZON_SDRAM_MC_MRSCODE_WT                              (1 << 3)
+#define AMAZON_SDRAM_MC_MRSCODE_BL(value)                (((( 1 << 3) - 1) & (value)) << 0)
+      
+/***MC Configuration Data-word Width Register***/ 
+#define AMAZON_SDRAM_MC_CFGDW                    ((volatile u32*)(AMAZON_SDRAM+ 0x0130))
+#define AMAZON_SDRAM_MC_CFGDW_DW(value)                (((( 1 << 4) - 1) & (value)) << 0)
+#define AMAZON_SDRAM_MC_CFGDW_Res(value)                (((( 1 << 28) - 1) & (value)) << 4)
+      
+/***MC Configuration Physical Bank 0 Register***/ 
+#define AMAZON_SDRAM_MC_CFGPB0                    ((volatile u32*)(AMAZON_SDRAM+ 0x140))
+#define AMAZON_SDRAM_MC_CFGPB0_MCSEN0(value)             (((( 1 << 4) - 1) & (value)) << 12)
+#define AMAZON_SDRAM_MC_CFGPB0_BANKN0(value)             (((( 1 << 4) - 1) & (value)) << 8)
+#define AMAZON_SDRAM_MC_CFGPB0_ROWW0(value)              (((( 1 << 4) - 1) & (value)) << 4)
+#define AMAZON_SDRAM_MC_CFGPB0_COLW0(value)              (((( 1 << 4) - 1) & (value)) << 0)
+#define AMAZON_SDRAM_MC_CFGPB0_Res(value)                (((( 1 << 16) - 1) & (value)) << 16)
+      
+/***MC Latency Register***/ 
+#define AMAZON_SDRAM_MC_LATENCY                   ((volatile u32*)(AMAZON_SDRAM+ 0x0180))
+#define AMAZON_SDRAM_MC_LATENCY_TRP(value)                (((( 1 << 4) - 1) & (value)) << 16)
+#define AMAZON_SDRAM_MC_LATENCY_TRAS(value)               (((( 1 << 4) - 1) & (value)) << 12)
+#define AMAZON_SDRAM_MC_LATENCY_TRCD(value)               (((( 1 << 4) - 1) & (value)) << 8)
+#define AMAZON_SDRAM_MC_LATENCY_TDPL(value)               (((( 1 << 4) - 1) & (value)) << 4)
+#define AMAZON_SDRAM_MC_LATENCY_TDAL(value)               (((( 1 << 4) - 1) & (value)) << 0)
+#define AMAZON_SDRAM_MC_LATENCY_Res(value)                (((( 1 << 12) - 1) & (value)) << 20)
+      
+/***MC Refresh Cycle Time Register***/ 
+#define AMAZON_SDRAM_MC_TREFRESH                  ((volatile u32*)(AMAZON_SDRAM+ 0x0190))
+#define AMAZON_SDRAM_MC_TREFRESH_TREF(value)               (((( 1 << 13) - 1) & (value)) << 0)
+#define AMAZON_SDRAM_MC_TREFRESH_Res(value)                (((( 1 << 19) - 1) & (value)) << 13)                
+         
+/***********************************************************************/
+/*  Module      :  GPTU register address and bits                      */
+/***********************************************************************/
+         
+#define AMAZON_GPTU                         (KSEG1+0x10100A00)
+/***********************************************************************/   
+
+      
+/***GPT Clock Control Register***/ 
+#define AMAZON_GPTU_CLC                      ((volatile u32*)(AMAZON_GPTU+ 0x0000))
+#define AMAZON_GPTU_CLC_RMC(value)                (((( 1 << 8) - 1) & (value)) << 8)
+#define AMAZON_GPTU_CLC_DISS                            (1 << 1)
+#define AMAZON_GPTU_CLC_DISR                            (1 << 0)
+      
+/***GPT Timer 3 Control Register***/ 
+#define AMAZON_GPTU_T3CON                    ((volatile u32*)(AMAZON_GPTU+ 0x0014))
+#define AMAZON_GPTU_T3CON_T3RDIR                        (1 << 15)
+#define AMAZON_GPTU_T3CON_T3CHDIR                      (1 << 14)
+#define AMAZON_GPTU_T3CON_T3EDGE                        (1 << 13)
+#define AMAZON_GPTU_T3CON_BPS1(value)               (((( 1 << 2) - 1) & (value)) << 11)
+#define AMAZON_GPTU_T3CON_T3OTL                          (1 << 10)
+#define AMAZON_GPTU_T3CON_T3UD                            (1 << 7)
+#define AMAZON_GPTU_T3CON_T3R                              (1 << 6)
+#define AMAZON_GPTU_T3CON_T3M(value)                (((( 1 << 3) - 1) & (value)) << 3)
+#define AMAZON_GPTU_T3CON_T3I(value)                (((( 1 << 3) - 1) & (value)) << 0)
+      
+/***GPT Write Hardware Modified Timer 3 Control Register 
+If set and clear bit are written concurrently with 1, the associated bit is not changed.***/
+#define AMAZON_GPTU_WHBT3CON                 ((volatile u32*)(AMAZON_GPTU+ 0x004C))
+#define AMAZON_GPTU_WHBT3CON_SETT3CHDIR                (1 << 15)
+#define AMAZON_GPTU_WHBT3CON_CLRT3CHDIR                (1 << 14)
+#define AMAZON_GPTU_WHBT3CON_SETT3EDGE                  (1 << 13)
+#define AMAZON_GPTU_WHBT3CON_CLRT3EDGE                  (1 << 12)
+#define AMAZON_GPTU_WHBT3CON_SETT3OTL                  (1 << 11)
+#define AMAZON_GPTU_WHBT3CON_CLRT3OTL                  (1 << 10)
+      
+/***GPT Timer 2 Control Register***/ 
+#define AMAZON_GPTU_T2CON                    ((volatile u32*)(AMAZON_GPTU+ 0x0010))
+#define AMAZON_GPTU_T2CON_TxRDIR                        (1 << 15)
+#define AMAZON_GPTU_T2CON_TxCHDIR                      (1 << 14)
+#define AMAZON_GPTU_T2CON_TxEDGE                        (1 << 13)
+#define AMAZON_GPTU_T2CON_TxIRDIS                      (1 << 12)
+#define AMAZON_GPTU_T2CON_TxRC                            (1 << 9)
+#define AMAZON_GPTU_T2CON_TxUD                            (1 << 7)
+#define AMAZON_GPTU_T2CON_TxR                              (1 << 6)
+#define AMAZON_GPTU_T2CON_TxM(value)                (((( 1 << 3) - 1) & (value)) << 3)
+#define AMAZON_GPTU_T2CON_TxI(value)                (((( 1 << 3) - 1) & (value)) << 0)
+      
+/***GPT Timer 4 Control Register***/ 
+#define AMAZON_GPTU_T4CON                    ((volatile u32*)(AMAZON_GPTU+ 0x0018))
+#define AMAZON_GPTU_T4CON_TxRDIR                        (1 << 15)
+#define AMAZON_GPTU_T4CON_TxCHDIR                      (1 << 14)
+#define AMAZON_GPTU_T4CON_TxEDGE                        (1 << 13)
+#define AMAZON_GPTU_T4CON_TxIRDIS                      (1 << 12)
+#define AMAZON_GPTU_T4CON_TxRC                            (1 << 9)
+#define AMAZON_GPTU_T4CON_TxUD                            (1 << 7)
+#define AMAZON_GPTU_T4CON_TxR                              (1 << 6)
+#define AMAZON_GPTU_T4CON_TxM(value)                (((( 1 << 3) - 1) & (value)) << 3)
+#define AMAZON_GPTU_T4CON_TxI(value)                (((( 1 << 3) - 1) & (value)) << 0)
+      
+/***GPT Write HW Modified Timer 2 Control Register If set
+ and clear bit are written concurrently with 1, the associated bit is not changed.***/
+#define AMAZON_GPTU_WHBT2CON                 ((volatile u32*)(AMAZON_GPTU+ 0x0048))
+#define AMAZON_GPTU_WHBT2CON_SETTxCHDIR                (1 << 15)
+#define AMAZON_GPTU_WHBT2CON_CLRTxCHDIR                (1 << 14)
+#define AMAZON_GPTU_WHBT2CON_SETTxEDGE                  (1 << 13)
+#define AMAZON_GPTU_WHBT2CON_CLRTxEDGE                  (1 << 12)
+      
+/***GPT Write HW Modified Timer 4 Control Register If set
+ and clear bit are written concurrently with 1, the associated bit is not changed.***/
+#define AMAZON_GPTU_WHBT4CON                 ((volatile u32*)(AMAZON_GPTU+ 0x0050))
+#define AMAZON_GPTU_WHBT4CON_SETTxCHDIR                (1 << 15)
+#define AMAZON_GPTU_WHBT4CON_CLRTxCHDIR                (1 << 14)
+#define AMAZON_GPTU_WHBT4CON_SETTxEDGE                  (1 << 13)
+#define AMAZON_GPTU_WHBT4CON_CLRTxEDGE                  (1 << 12)
+      
+/***GPT Capture Reload Register***/ 
+#define AMAZON_GPTU_CAPREL                   ((volatile u32*)(AMAZON_GPTU+ 0x0030))
+#define AMAZON_GPTU_CAPREL_CAPREL(value)             (((( 1 << 16) - 1) & (value)) << 0)
+      
+/***GPT Timer 2 Register***/ 
+#define AMAZON_GPTU_T2                       ((volatile u32*)(AMAZON_GPTU+ 0x0034))
+#define AMAZON_GPTU_T2_TVAL(value)               (((( 1 << 16) - 1) & (value)) << 0)
+      
+/***GPT Timer 3 Register***/ 
+#define AMAZON_GPTU_T3                       ((volatile u32*)(AMAZON_GPTU+ 0x0038))
+#define AMAZON_GPTU_T3_TVAL(value)               (((( 1 << 16) - 1) & (value)) << 0)
+      
+/***GPT Timer 4 Register***/ 
+#define AMAZON_GPTU_T4                       ((volatile u32*)(AMAZON_GPTU+ 0x003C))
+#define AMAZON_GPTU_T4_TVAL(value)               (((( 1 << 16) - 1) & (value)) << 0)
+      
+/***GPT Timer 5 Register***/ 
+#define AMAZON_GPTU_T5                       ((volatile u32*)(AMAZON_GPTU+ 0x0040))
+#define AMAZON_GPTU_T5_TVAL(value)               (((( 1 << 16) - 1) & (value)) << 0)
+      
+/***GPT Timer 6 Register***/ 
+#define AMAZON_GPTU_T6                       ((volatile u32*)(AMAZON_GPTU+ 0x0044))
+#define AMAZON_GPTU_T6_TVAL(value)               (((( 1 << 16) - 1) & (value)) << 0)
+      
+/***GPT Timer 6 Control Register***/ 
+#define AMAZON_GPTU_T6CON                    ((volatile u32*)(AMAZON_GPTU+ 0x0020))
+#define AMAZON_GPTU_T6CON_T6SR                            (1 << 15)
+#define AMAZON_GPTU_T6CON_T6CLR                          (1 << 14)
+#define AMAZON_GPTU_T6CON_BPS2(value)               (((( 1 << 2) - 1) & (value)) << 11)
+#define AMAZON_GPTU_T6CON_T6OTL                          (1 << 10)
+#define AMAZON_GPTU_T6CON_T6UD                            (1 << 7)
+#define AMAZON_GPTU_T6CON_T6R                              (1 << 6)
+#define AMAZON_GPTU_T6CON_T6M(value)                (((( 1 << 3) - 1) & (value)) << 3)
+#define AMAZON_GPTU_T6CON_T6I(value)                (((( 1 << 3) - 1) & (value)) << 0)
+      
+/***GPT Write HW Modified Timer 6 Control Register If set
+ and clear bit are written concurrently with 1, the associated bit is not changed.***/
+#define AMAZON_GPTU_WHBT6CON                 ((volatile u32*)(AMAZON_GPTU+ 0x0054))
+#define AMAZON_GPTU_WHBT6CON_SETT6OTL                  (1 << 11)
+#define AMAZON_GPTU_WHBT6CON_CLRT6OTL                  (1 << 10)
+      
+/***GPT Timer 5 Control Register***/ 
+#define AMAZON_GPTU_T5CON                    ((volatile u32*)(AMAZON_GPTU+ 0x001C))
+#define AMAZON_GPTU_T5CON_T5SC                            (1 << 15)
+#define AMAZON_GPTU_T5CON_T5CLR                          (1 << 14)
+#define AMAZON_GPTU_T5CON_CI(value)                (((( 1 << 2) - 1) & (value)) << 12)
+#define AMAZON_GPTU_T5CON_T5CC                            (1 << 11)
+#define AMAZON_GPTU_T5CON_CT3                              (1 << 10)
+#define AMAZON_GPTU_T5CON_T5RC                            (1 << 9)
+#define AMAZON_GPTU_T5CON_T5UDE                          (1 << 8)
+#define AMAZON_GPTU_T5CON_T5UD                            (1 << 7)
+#define AMAZON_GPTU_T5CON_T5R                              (1 << 6)
+#define AMAZON_GPTU_T5CON_T5M(value)                (((( 1 << 3) - 1) & (value)) << 3)
+#define AMAZON_GPTU_T5CON_T5I(value)                (((( 1 << 3) - 1) & (value)) << 0)         
+         
+
+/***********************************************************************/
+/*  Module      :  ASC register address and bits                       */
+/***********************************************************************/
+         
+#define AMAZON_ASC                          (KSEG1+0x10100400)
+/***********************************************************************/   
+
+      
+/***ASC Port Input Select Register***/ 
+#define AMAZON_ASC_PISEL                    ((volatile u32*)(AMAZON_ASC+ 0x0004))
+#define AMAZON_ASC_PISEL_RIS                              (1 << 0)
+      
+/***ASC Control Register***/ 
+#define AMAZON_ASC_CON                      ((volatile u32*)(AMAZON_ASC+ 0x0010))
+#define AMAZON_ASC_CON_R                              (1 << 15)
+#define AMAZON_ASC_CON_LB                              (1 << 14)
+#define AMAZON_ASC_CON_BRS                              (1 << 13)
+#define AMAZON_ASC_CON_ODD                              (1 << 12)
+#define AMAZON_ASC_CON_FDE                              (1 << 11)
+#define AMAZON_ASC_CON_OE                              (1 << 10)
+#define AMAZON_ASC_CON_FE                              (1 << 9)
+#define AMAZON_ASC_CON_PE                              (1 << 8)
+#define AMAZON_ASC_CON_OEN                              (1 << 7)
+#define AMAZON_ASC_CON_FEN                              (1 << 6)
+#define AMAZON_ASC_CON_PENRXDI                  (1 << 5)
+#define AMAZON_ASC_CON_REN                              (1 << 4)
+#define AMAZON_ASC_CON_STP                              (1 << 3)
+#define AMAZON_ASC_CON_M(value)                (((( 1 << 3) - 1) & (value)) << 0)
+/***ASC Write Hardware Modified Control Register***/ 
+#define AMAZON_ASC_WHBCON                   ((volatile u32*)(AMAZON_ASC+ 0x0050))
+#define AMAZON_ASC_WHBCON_SETOE                          (1 << 13)
+#define AMAZON_ASC_WHBCON_SETFE                          (1 << 12)
+#define AMAZON_ASC_WHBCON_SETPE                          (1 << 11)
+#define AMAZON_ASC_WHBCON_CLROE                          (1 << 10)
+#define AMAZON_ASC_WHBCON_CLRFE                          (1 << 9)
+#define AMAZON_ASC_WHBCON_CLRPE                          (1 << 8)
+#define AMAZON_ASC_WHBCON_SETREN                        (1 << 5)
+#define AMAZON_ASC_WHBCON_CLRREN                        (1 << 4)
+      
+/***ASC Baudrate Timer/Reload Register***/ 
+#define AMAZON_ASC_BTR                      ((volatile u32*)(AMAZON_ASC+ 0x0014))
+#define AMAZON_ASC_BTR_BR_VALUE(value)          (((( 1 << 13) - 1) & (value)) << 0)
+      
+/***ASC Fractional Divider Register***/ 
+#define AMAZON_ASC_FDV                      ((volatile u32*)(AMAZON_ASC+ 0x0018))
+#define AMAZON_ASC_FDV_FD_VALUE(value)          (((( 1 << 9) - 1) & (value)) << 0)
+      
+/***ASC IrDA Pulse Mode/Width Register***/ 
+#define AMAZON_ASC_PMW                      ((volatile u32*)(AMAZON_ASC+ 0x001C))
+#define AMAZON_ASC_PMW_IRPW                            (1 << 8)
+#define AMAZON_ASC_PMW_PW_VALUE(value)          (((( 1 << 8) - 1) & (value)) << 0)
+      
+/***ASC Transmit Buffer Register***/ 
+#define AMAZON_ASC_TBUF                    ((volatile u32*)(AMAZON_ASC+ 0x0020))
+#define AMAZON_ASC_TBUF_TD_VALUE(value)          (((( 1 << 9) - 1) & (value)) << 0)
+      
+/***ASC Receive Buffer Register***/ 
+#define AMAZON_ASC_RBUF                    ((volatile u32*)(AMAZON_ASC+ 0x0024))
+#define AMAZON_ASC_RBUF_RD_VALUE(value)          (((( 1 << 9) - 1) & (value)) << 0)
+      
+/***ASC Autobaud Control Register***/ 
+#define AMAZON_ASC_ABCON                    ((volatile u32*)(AMAZON_ASC+ 0x0030))
+#define AMAZON_ASC_ABCON_RXINV                          (1 << 11)
+#define AMAZON_ASC_ABCON_TXINV                          (1 << 10)
+#define AMAZON_ASC_ABCON_ABEM(value)               (((( 1 << 2) - 1) & (value)) << 8)
+#define AMAZON_ASC_ABCON_FCDETEN                      (1 << 4)
+#define AMAZON_ASC_ABCON_ABDETEN                      (1 << 3)
+#define AMAZON_ASC_ABCON_ABSTEN                        (1 << 2)
+#define AMAZON_ASC_ABCON_AUREN                          (1 << 1)
+#define AMAZON_ASC_ABCON_ABEN                            (1 << 0)
+      
+/***Receive FIFO Control Register***/ 
+#define AMAZON_ASC_RXFCON                       ((volatile u32*)(AMAZON_ASC+ 0x0040))
+#define AMAZON_ASC_RXFCON_RXFITL(value)             (((( 1 << 6) - 1) & (value)) << 8)
+#define AMAZON_ASC_RXFCON_RXTMEN                        (1 << 2)
+#define AMAZON_ASC_RXFCON_RXFFLU                        (1 << 1)
+#define AMAZON_ASC_RXFCON_RXFEN                          (1 << 0)
+      
+/***Transmit FIFO Control Register***/ 
+#define AMAZON_ASC_TXFCON                       ((volatile u32*)(AMAZON_ASC+ 0x0044))
+#define AMAZON_ASC_TXFCON_TXFITL(value)             (((( 1 << 6) - 1) & (value)) << 8)
+#define AMAZON_ASC_TXFCON_TXTMEN                        (1 << 2)
+#define AMAZON_ASC_TXFCON_TXFFLU                        (1 << 1)
+#define AMAZON_ASC_TXFCON_TXFEN                          (1 << 0)
+      
+/***FIFO Status Register***/ 
+#define AMAZON_ASC_FSTAT                        ((volatile u32*)(AMAZON_ASC+ 0x0048))
+#define AMAZON_ASC_FSTAT_TXFFL(value)              (((( 1 << 6) - 1) & (value)) << 8)
+#define AMAZON_ASC_FSTAT_RXFFL(value)              (((( 1 << 6) - 1) & (value)) << 0)
+      
+/***ASC Write HW Modified Autobaud Control Register***/ 
+#define AMAZON_ASC_WHBABCON                 ((volatile u32*)(AMAZON_ASC+ 0x0054))
+#define AMAZON_ASC_WHBABCON_SETABEN                      (1 << 1)
+#define AMAZON_ASC_WHBABCON_CLRABEN                      (1 << 0)
+      
+/***ASC Autobaud Status Register***/ 
+#define AMAZON_ASC_ABSTAT                   ((volatile u32*)(AMAZON_ASC+ 0x0034))
+#define AMAZON_ASC_ABSTAT_DETWAIT                      (1 << 4)
+#define AMAZON_ASC_ABSTAT_SCCDET                        (1 << 3)
+#define AMAZON_ASC_ABSTAT_SCSDET                        (1 << 2)
+#define AMAZON_ASC_ABSTAT_FCCDET                        (1 << 1)
+#define AMAZON_ASC_ABSTAT_FCSDET                        (1 << 0)
+      
+/***ASC Write HW Modified Autobaud Status Register***/ 
+#define AMAZON_ASC_WHBABSTAT                 ((volatile u32*)(AMAZON_ASC+ 0x0058))
+#define AMAZON_ASC_WHBABSTAT_SETDETWAIT                (1 << 9)
+#define AMAZON_ASC_WHBABSTAT_CLRDETWAIT                (1 << 8)
+#define AMAZON_ASC_WHBABSTAT_SETSCCDET                  (1 << 7)
+#define AMAZON_ASC_WHBABSTAT_CLRSCCDET                  (1 << 6)
+#define AMAZON_ASC_WHBABSTAT_SETSCSDET                  (1 << 5)
+#define AMAZON_ASC_WHBABSTAT_CLRSCSDET                  (1 << 4)
+#define AMAZON_ASC_WHBABSTAT_SETFCCDET                  (1 << 3)
+#define AMAZON_ASC_WHBABSTAT_CLRFCCDET                  (1 << 2)
+#define AMAZON_ASC_WHBABSTAT_SETFCSDET                  (1 << 1)
+#define AMAZON_ASC_WHBABSTAT_CLRFCSDET                  (1 << 0)
+      
+/***ASC Clock Control Register***/ 
+#define AMAZON_ASC_CLC                      ((volatile u32*)(AMAZON_ASC+ 0x0000))
+#define AMAZON_ASC_CLC_RMC(value)                (((( 1 << 8) - 1) & (value)) << 8)
+#define AMAZON_ASC_CLC_DISS                            (1 << 1)
+#define AMAZON_ASC_CLC_DISR                            (1 << 0)                
+
+/***ASC IRNCR0 **/
+#define AMAZON_ASC_IRNCR0                      ((volatile u32*)(AMAZON_ASC+ 0x00FC))
+/***ASC IRNCR1 **/
+#define AMAZON_ASC_IRNCR1                      ((volatile u32*)(AMAZON_ASC+ 0x00F8))
+#define ASC_IRNCR_TIR  0x1
+#define ASC_IRNCR_RIR  0x2
+#define ASC_IRNCR_EIR  0x4
+/***********************************************************************/
+/*  Module      :  DMA register address and bits                       */
+/***********************************************************************/
+         
+#define AMAZON_DMA                             (KSEG1+0x10103000)
+/***********************************************************************/   
+#define AMAZON_DMA_CH_ON               AMAZON_DMA+0x28
+#define AMAZON_DMA_CH_RST                      AMAZON_DMA+0x2c
+#define AMAZON_DMA_CH0_ISR             AMAZON_DMA+0x30
+#define AMAZON_DMA_CH1_ISR             AMAZON_DMA+0x34
+#define AMAZON_DMA_CH2_ISR             AMAZON_DMA+0x38
+#define AMAZON_DMA_CH3_ISR                     AMAZON_DMA+0x3c
+#define AMAZON_DMA_CH4_ISR             AMAZON_DMA+0x40
+#define AMAZON_DMA_CH5_ISR             AMAZON_DMA+0x44
+#define AMAZON_DMA_CH6_ISR             AMAZON_DMA+0x48
+#define AMAZON_DMA_CH7_ISR             AMAZON_DMA+0x4c
+#define AMAZON_DMA_CH8_ISR             AMAZON_DMA+0x50
+#define AMAZON_DMA_CH9_ISR             AMAZON_DMA+0x54
+#define AMAZON_DMA_CH10_ISR            AMAZON_DMA+0x58
+#define AMAZON_DMA_CH11_ISR            AMAZON_DMA+0x5c
+#define AMAZON_DMA_CH0_MSK             AMAZON_DMA+0x60
+#define AMAZON_DMA_CH1_MSK             AMAZON_DMA+0x64
+#define AMAZON_DMA_CH2_MSK                     AMAZON_DMA+0x68
+#define AMAZON_DMA_CH3_MSK             AMAZON_DMA+0x6c
+#define AMAZON_DMA_CH4_MSK             AMAZON_DMA+0x70
+#define AMAZON_DMA_CH5_MSK             AMAZON_DMA+0x74
+#define AMAZON_DMA_CH6_MSK             AMAZON_DMA+0x78
+#define AMAZON_DMA_CH7_MSK             AMAZON_DMA+0x7c
+#define AMAZON_DMA_CH8_MSK             AMAZON_DMA+0x80
+#define AMAZON_DMA_CH9_MSK             AMAZON_DMA+0x84
+#define AMAZON_DMA_CH10_MSK            AMAZON_DMA+0x88
+#define AMAZON_DMA_CH11_MSK            AMAZON_DMA+0x8c
+#define AMAZON_DMA_Desc_BA             AMAZON_DMA+0x90
+#define AMAZON_DMA_CH0_DES_LEN         AMAZON_DMA+0x94
+#define AMAZON_DMA_CH1_DES_LEN         AMAZON_DMA+0x98
+#define AMAZON_DMA_CH2_DES_LEN         AMAZON_DMA+0x9c
+#define AMAZON_DMA_CH3_DES_LEN         AMAZON_DMA+0xa0
+#define AMAZON_DMA_CH4_DES_LEN         AMAZON_DMA+0xa4
+#define AMAZON_DMA_CH5_DES_LEN         AMAZON_DMA+0xa8
+#define AMAZON_DMA_CH6_DES_LEN         AMAZON_DMA+0xac
+#define AMAZON_DMA_CH7_DES_LEN         AMAZON_DMA+0xb0
+#define AMAZON_DMA_CH8_DES_LEN         AMAZON_DMA+0xb4
+#define AMAZON_DMA_CH9_DES_LEN         AMAZON_DMA+0xb8
+#define AMAZON_DMA_CH10_DES_LEN        AMAZON_DMA+0xbc
+#define AMAZON_DMA_CH11_DES_LEN        AMAZON_DMA+0xc0
+#define AMAZON_DMA_CH1_DES_OFST        AMAZON_DMA+0xc4
+#define AMAZON_DMA_CH2_DES_OFST        AMAZON_DMA+0xc8
+#define AMAZON_DMA_CH3_DES_OFST        AMAZON_DMA+0xcc
+#define AMAZON_DMA_CH4_DES_OFST        AMAZON_DMA+0xd0
+#define AMAZON_DMA_CH5_DES_OFST        AMAZON_DMA+0xd4
+#define AMAZON_DMA_CH6_DES_OFST        AMAZON_DMA+0xd8
+#define AMAZON_DMA_CH7_DES_OFST        AMAZON_DMA+0xdc
+#define AMAZON_DMA_CH8_DES_OFST        AMAZON_DMA+0xe0
+#define AMAZON_DMA_CH9_DES_OFST        AMAZON_DMA+0xe4
+#define AMAZON_DMA_CH10_DES_OFST       AMAZON_DMA+0xe8
+#define AMAZON_DMA_CH11_DES_OFST       AMAZON_DMA+0xec
+#define AMAZON_DMA_SW_BL               AMAZON_DMA+0xf0
+#define AMAZON_DMA_TPE_BL              AMAZON_DMA+0xf4
+#define AMAZON_DMA_DPlus2FPI_BL        AMAZON_DMA+0xf8
+#define AMAZON_DMA_GRX_BUF_LEN         AMAZON_DMA+0xfc
+#define AMAZON_DMA_DMA_ECON_REG        AMAZON_DMA+0x100
+#define AMAZON_DMA_POLLING_REG         AMAZON_DMA+0x104
+#define AMAZON_DMA_CH_WGT              AMAZON_DMA+0x108
+#define AMAZON_DMA_TX_WGT              AMAZON_DMA+0x10c
+#define AMAZON_DMA_DPLus2FPI_CLASS     AMAZON_DMA+0x110
+#define AMAZON_DMA_COMB_ISR            AMAZON_DMA+0x114
+
+//channel reset
+#define SWITCH1_RST_MASK       0x83    /* Switch1 channel mask */
+#define SWITCH2_RST_MASK       0x10C   /* Switch1 channel mask */
+#define TPE_RST_MASK           0x630   /* TPE channel mask */
+#define DPlus2FPI_RST_MASK     0x840   /*  DPlusFPI channel mask */
+
+//ISR
+#define DMA_ISR_RDERR                  0x20
+#define DMA_ISR_CMDCPT                 0x10
+#define DMA_ISR_CPT                    0x8
+#define DMA_ISR_DURR                   0x4
+#define DMA_ISR_EOP                    0x2
+#define DMA_DESC_BYTEOFF_SHIFT         23
+
+#define DMA_POLLING_ENABLE             0x80000000
+#define DMA_POLLING_CNT                        0x50    /*minimum 0x10, max 0xfff0*/
+
+/***********************************************************************/
+/*  Module      :  Debug register address and bits                     */
+/***********************************************************************/
+         
+#define AMAZON_DEBUG                        (KSEG1+0x1F106000)
+/***********************************************************************/   
+
+      
+/***MCD Break System Control Register***/ 
+#define AMAZON_DEBUG_MCD_BSCR                          ((volatile u32*)(AMAZON_DEBUG+ 0x0000))
+
+/***PMC Performance Counter Control Register0***/
+#define AMAZON_DEBUG_PMC_PCCR0                          ((volatile u32*)(AMAZON_DEBUG+ 0x0010))
+
+/***PMC Performance Counter Control Register1***/
+#define AMAZON_DEBUG_PMC_PCCR1                          ((volatile u32*)(AMAZON_DEBUG+ 0x0014))
+
+/***PMC Performance Counter Register0***/
+#define AMAZON_DEBUG_PMC_PCR0                                  ((volatile u32*)(AMAZON_DEBUG+ 0x0018))
+
+/*165001:henryhsu:20050603:Source modified by Bing Tao*/
+
+/***PMC Performance Counter Register1***/
+//#define AMAZON_DEBUG_PMC_PCR1                          ((volatile u32*)(AMAZON_DEBUG+ 0x0020))
+#define AMAZON_DEBUG_PMC_PCR1                            ((volatile u32*)(AMAZON_DEBUG+ 0x001c))
+
+/*165001*/
+
+
+
+/***MCD Suspend Mode Control Register***/
+#define AMAZON_DEBUG_MCD_SMCR                           ((volatile u32*)(AMAZON_DEBUG+ 0x0024))
+
+/***********************************************************************/
+/*  Module      :  GPIO register address and bits                     */
+/***********************************************************************/
+         
+#define AMAZON_GPIO                        (KSEG1+0x10100B00)
+/***********************************************************************/   
+
+      
+/***Port 0 Data Output Register (0010H)***/ 
+#define AMAZON_GPIO_P0_OUT                       ((volatile u32*)(AMAZON_GPIO+ 0x0010))                      
+      
+/***Port 1 Data Output Register (0040H)***/ 
+#define AMAZON_GPIO_P1_OUT                       ((volatile u32*)(AMAZON_GPIO+ 0x0040))                      
+      
+/***Port 0 Data Input Register (0014H)***/ 
+#define AMAZON_GPIO_P0_IN                        ((volatile u32*)(AMAZON_GPIO+ 0x0014))                      
+      
+/***Port 1 Data Input Register (0044H)***/ 
+#define AMAZON_GPIO_P1_IN                        ((volatile u32*)(AMAZON_GPIO+ 0x0044))
+                            
+/***Port 0 Direction Register (0018H)***/ 
+#define AMAZON_GPIO_P0_DIR                       ((volatile u32*)(AMAZON_GPIO+ 0x0018))
+      
+/***Port 1 Direction Register (0048H)***/ 
+#define AMAZON_GPIO_P1_DIR                       ((volatile u32*)(AMAZON_GPIO+ 0x0048))
+      
+/***Port 0 Alternate Function Select Register 0 (001C H) ***/
+#define AMAZON_GPIO_P0_ALTSEL0                    ((volatile u32*)(AMAZON_GPIO+ 0x001C))                      
+      
+/***Port 1 Alternate Function Select Register 0 (004C H) ***/
+#define AMAZON_GPIO_P1_ALTSEL0                    ((volatile u32*)(AMAZON_GPIO+ 0x004C))
+                      
+/***Port 0 Alternate Function Select Register 1 (0020 H) ***/
+#define AMAZON_GPIO_P0_ALTSEL1                    ((volatile u32*)(AMAZON_GPIO+ 0x0020))
+      
+/***Port 1 Alternate Function Select Register 0 (0050 H) ***/
+#define AMAZON_GPIO_P1_ALTSEL1                    ((volatile u32*)(AMAZON_GPIO+ 0x0050))
+      
+/***Port 0 Open Drain Control Register (0024H)***/ 
+#define AMAZON_GPIO_P0_OD                        ((volatile u32*)(AMAZON_GPIO+ 0x0024))                      
+      
+/***Port 1 Open Drain Control Register (0054H)***/ 
+#define AMAZON_GPIO_P1_OD                        ((volatile u32*)(AMAZON_GPIO+ 0x0054))
+                      
+/***Port 0 Input Schmitt-Trigger Off Register (0028 H) ***/
+#define AMAZON_GPIO_P0_STOFF                    ((volatile u32*)(AMAZON_GPIO+ 0x0028))
+      
+/***Port 1 Input Schmitt-Trigger Off Register (0058 H) ***/
+#define AMAZON_GPIO_P1_STOFF                    ((volatile u32*)(AMAZON_GPIO+ 0x0058))
+                      
+/***Port 0 Pull Up/Pull Down Select Register (002C H)***/ 
+#define AMAZON_GPIO_P0_PUDSEL                    ((volatile u32*)(AMAZON_GPIO+ 0x002C))
+                      
+/***Port 1 Pull Up/Pull Down Select Register (005C H)***/ 
+#define AMAZON_GPIO_P1_PUDSEL                    ((volatile u32*)(AMAZON_GPIO+ 0x005C))
+                      
+/***Port 0 Pull Up Device Enable Register (0030 H)***/ 
+#define AMAZON_GPIO_P0_PUDEN                    ((volatile u32*)(AMAZON_GPIO+ 0x0030))
+                      
+/***Port 1 Pull Up Device Enable Register (0060 H)***/ 
+#define AMAZON_GPIO_P1_PUDEN                    ((volatile u32*)(AMAZON_GPIO+ 0x0060))
+                                                                         
+/***********************************************************************/
+/*  Module      :  BIU register address and bits                       */
+/***********************************************************************/
+         
+#define AMAZON_BIU                          (KSEG1+0x1FA80000)
+/***********************************************************************/   
+
+      
+/***BIU Identification Register***/ 
+#define AMAZON_BIU_ID                       ((volatile u32*)(AMAZON_BIU+ 0x0000))
+#define AMAZON_BIU_ID_ARCH                            (1 << 16)
+#define AMAZON_BIU_ID_ID(value)                (((( 1 << 8) - 1) & (value)) << 8)
+#define AMAZON_BIU_ID_REV(value)                (((( 1 << 8) - 1) & (value)) << 0)
+      
+/***BIU Access Error Cause Register***/ 
+#define AMAZON_BIU_ERRCAUSE                 ((volatile u32*)(AMAZON_BIU+ 0x0100))
+#define AMAZON_BIU_ERRCAUSE_ERR                              (1 << 31)
+#define AMAZON_BIU_ERRCAUSE_PORT(value)               (((( 1 << 4) - 1) & (value)) << 16)
+#define AMAZON_BIU_ERRCAUSE_CAUSE(value)              (((( 1 << 2) - 1) & (value)) << 0)
+      
+/***BIU Access Error Address Register***/ 
+#define AMAZON_BIU_ERRADDR                  ((volatile u32*)(AMAZON_BIU+ 0x0108))
+#define AMAZON_BIU_ERRADDR_ADDR                
+         
+/***********************************************************************/
+/*  Module      :  ICU register address and bits                       */
+/***********************************************************************/
+         
+#define AMAZON_ICU                          (KSEG1+0x1F101000)
+/***********************************************************************/   
+
+      
+/***IM0 Interrupt Status Register***/ 
+#define AMAZON_ICU_IM0_ISR                      ((volatile u32*)(AMAZON_ICU+ 0x0010))
+#define AMAZON_ICU_IM0_ISR_IR(value)               (1 << (value))
+                      
+      
+/***IM1 Interrupt Status Register***/ 
+#define AMAZON_ICU_IM1_ISR                      ((volatile u32*)(AMAZON_ICU+ 0x0020))
+#define AMAZON_ICU_IM1_ISR_IR(value)               (1 << (value))
+                      
+      
+/***IM2 Interrupt Status Register***/ 
+#define AMAZON_ICU_IM2_ISR                      ((volatile u32*)(AMAZON_ICU+ 0x0030))
+#define AMAZON_ICU_IM2_ISR_IR(value)               (1 << (value))
+                      
+/***IM3 Interrupt Status Register***/
+#define AMAZON_ICU_IM3_ISR                      ((volatile u32*)(AMAZON_ICU+ 0x0040))
+#define AMAZON_ICU_IM3_ISR_IR(value)               (1 << (value))
+                                                                                       
+/***IM4 Interrupt Status Register***/
+#define AMAZON_ICU_IM4_ISR                      ((volatile u32*)(AMAZON_ICU+ 0x0050))
+#define AMAZON_ICU_IM4_ISR_IR(value)               (1 << (value))
+
+                       
+/***IM0 Interrupt Enable Register***/ 
+#define AMAZON_ICU_IM0_IER                      ((volatile u32*)(AMAZON_ICU+ 0x0014))
+#define AMAZON_ICU_IM0_IER_IR(value)               (1 << (value))
+                      
+      
+/***IM1 Interrupt Enable Register***/ 
+#define AMAZON_ICU_IM1_IER                      ((volatile u32*)(AMAZON_ICU+ 0x0024))
+#define AMAZON_ICU_IM1_IER_IR(value)               (1 << (value))
+                      
+      
+/***IM2 Interrupt Enable Register***/ 
+#define AMAZON_ICU_IM2_IER                      ((volatile u32*)(AMAZON_ICU+ 0x0034))
+#define AMAZON_ICU_IM2_IER_IR(value)               (1 << (value))
+                      
+/***IM3 Interrupt Enable Register***/
+#define AMAZON_ICU_IM3_IER                      ((volatile u32*)(AMAZON_ICU+ 0x0044))
+#define AMAZON_ICU_IM3_IER_IR(value)               (1 << (value))
+                                                                                       
+/***IM4 Interrupt Enable Register***/
+#define AMAZON_ICU_IM4_IER                      ((volatile u32*)(AMAZON_ICU+ 0x0054))
+#define AMAZON_ICU_IM4_IER_IR(value)               (1 << (value))
+
+            
+/***IM0 Interrupt Output Status Register***/ 
+#define AMAZON_ICU_IM0_IOSR                    ((volatile u32*)(AMAZON_ICU+ 0x0018))
+#define AMAZON_ICU_IM0_IOSR_IR(value)               (1 << (value))
+                      
+      
+/***IM1 Interrupt Output Status Register***/ 
+#define AMAZON_ICU_IM1_IOSR                    ((volatile u32*)(AMAZON_ICU+ 0x0028))
+#define AMAZON_ICU_IM1_IOSR_IR(value)               (1 << (value))
+                      
+      
+/***IM2 Interrupt Output Status Register***/ 
+#define AMAZON_ICU_IM2_IOSR                    ((volatile u32*)(AMAZON_ICU+ 0x0038))
+#define AMAZON_ICU_IM2_IOSR_IR(value)               (1 << (value))
+                      
+/***IM3 Interrupt Output Status Register***/
+#define AMAZON_ICU_IM3_IOSR                    ((volatile u32*)(AMAZON_ICU+ 0x0048))
+#define AMAZON_ICU_IM3_IOSR_IR(value)               (1 << (value))
+                                                                                       
+/***IM4 Interrupt Output Status Register***/
+#define AMAZON_ICU_IM4_IOSR                    ((volatile u32*)(AMAZON_ICU+ 0x0058))
+#define AMAZON_ICU_IM4_IOSR_IR(value)               (1 << (value))
+
+            
+/***IM0 Interrupt Request Set Register***/ 
+#define AMAZON_ICU_IM0_IRSR                    ((volatile u32*)(AMAZON_ICU+ 0x001c))
+#define AMAZON_ICU_IM0_IRSR_IR(value)               (1 << (value))
+                      
+      
+/***IM1 Interrupt Request Set Register***/ 
+#define AMAZON_ICU_IM1_IRSR                    ((volatile u32*)(AMAZON_ICU+ 0x002c))
+#define AMAZON_ICU_IM1_IRSR_IR(value)               (1 << (value))
+                      
+      
+/***IM2 Interrupt Request Set Register***/ 
+#define AMAZON_ICU_IM2_IRSR                    ((volatile u32*)(AMAZON_ICU+ 0x003c))
+#define AMAZON_ICU_IM2_IRSR_IR(value)               (1 << (value))
+                      
+/***IM3 Interrupt Request Set Register***/
+#define AMAZON_ICU_IM3_IRSR                    ((volatile u32*)(AMAZON_ICU+ 0x004c))
+#define AMAZON_ICU_IM3_IRSR_IR(value)               (1 << (value))
+                                                                                       
+/***IM4 Interrupt Request Set Register***/
+#define AMAZON_ICU_IM4_IRSR                    ((volatile u32*)(AMAZON_ICU+ 0x005c))
+#define AMAZON_ICU_IM4_IRSR_IR(value)               (1 << (value))
+
+/***Interrupt Vector Value Register***/
+#define AMAZON_ICU_IM_VEC                      ((volatile u32*)(AMAZON_ICU+ 0x0060))
+
+/***Interrupt Vector Value Mask***/
+#define AMAZON_ICU_IM0_VEC_MASK                0x0000001f
+#define AMAZON_ICU_IM1_VEC_MASK                0x000003e0
+#define AMAZON_ICU_IM2_VEC_MASK                0x00007c00
+#define AMAZON_ICU_IM3_VEC_MASK                0x000f8000
+#define AMAZON_ICU_IM4_VEC_MASK                0x01f00000
+
+/***DMA Interrupt Mask Value***/
+#define AMAZON_DMA_H_MASK                      0x00000fff
+                                                                                       
+/***External Interrupt Control Register***/
+#define AMAZON_ICU_EXTINTCR                ((volatile u32*)(AMAZON_ICU+ 0x0000))                                                                                    
+#define AMAZON_ICU_IRNICR                  ((volatile u32*)(AMAZON_ICU+ 0x0004))                                                                                       
+#define AMAZON_ICU_IRNCR                   ((volatile u32*)(AMAZON_ICU+ 0x0008))                                                                                       
+#define AMAZON_ICU_IRNEN                   ((volatile u32*)(AMAZON_ICU+ 0x000c))
+
+/***********************************************************************/
+/*  Module      :   PCI/Card-BUS/PC-Card register address and bits     */
+/***********************************************************************/
+         
+#define AMAZON_PCI                             (KSEG1+0x10105400)
+#define AMAZON_PCI_CFG_BASE                    (KSEG1+0x11000000)
+#define AMAZON_PCI_MEM_BASE                    (KSEG1+0x12000000)
+
+#define CLOCK_CONTROL                          AMAZON_PCI + 0x00000000
+#define ARB_CTRL_bit                           1
+#define IDENTIFICATION                                 AMAZON_PCI + 0x00000004
+#define SOFTRESET                              AMAZON_PCI + 0x00000010
+#define PCI_FPI_ERROR_ADDRESS                  AMAZON_PCI + 0x00000014
+#define FPI_PCI_ERROR_ADDRESS                  AMAZON_PCI + 0x00000018
+#define FPI_ERROR_TAG                          AMAZON_PCI + 0x0000001c
+#define IRR                                    AMAZON_PCI + 0x00000020
+#define IRA_IR                                 AMAZON_PCI + 0x00000024
+#define IRM                                    AMAZON_PCI + 0x00000028
+#define DMA_COMPLETE_BIT                       0
+#define PCI_POWER_CHANGE_BIT                   16
+#define PCI_MASTER0_BROKEN_INT_BIT             24
+#define PCI_MASTER1_BROKEN_INT_BIT             25
+#define PCI_MASTER2_BROKEN_INT_BIT             26
+#define EOI                                    AMAZON_PCI + 0x0000002c
+#define PCI_MODE                               AMAZON_PCI + 0x00000030
+#define PCI_MODE_cfgok_bit                     24
+#define DEVICE_VENDOR_ID                       AMAZON_PCI + 0x00000034
+#define SUBSYSTEM_VENDOR_ID                    AMAZON_PCI + 0x00000038
+#define POWER_MANAGEMENT                       AMAZON_PCI + 0x0000003c
+#define CLASS_CODE1                            AMAZON_PCI + 0x00000040
+#define BAR11_MASK                             AMAZON_PCI + 0x00000044
+#define BAR12_MASK                             AMAZON_PCI + 0x00000048
+#define BAR13_MASK                             AMAZON_PCI + 0x0000004c
+#define BAR14_MASK                             AMAZON_PCI + 0x00000050
+#define BAR15_MASK                             AMAZON_PCI + 0x00000054
+#define BAR16_MASK                             AMAZON_PCI + 0x00000058
+#define CARDBUS_CIS_POINTER1                   AMAZON_PCI + 0x0000005c
+#define SUBSYSTEM_ID1                                  AMAZON_PCI + 0x00000060
+#define PCI_ADDRESS_MAP_11                     AMAZON_PCI + 0x00000064
+#define PCI_ADDRESS_MAP_12                     AMAZON_PCI + 0x00000068
+#define PCI_ADDRESS_MAP_13                     AMAZON_PCI + 0x0000006c
+#define PCI_ADDRESS_MAP_14                     AMAZON_PCI + 0x00000070
+#define PCI_ADDRESS_MAP_15                     AMAZON_PCI + 0x00000074
+#define PCI_ADDRESS_MAP_16                     AMAZON_PCI + 0x00000078
+#define FPI_SEGMENT_ENABLE                             AMAZON_PCI + 0x0000007c
+#define CLASS_CODE2                            AMAZON_PCI + 0x00000080
+#define BAR21_MASK                             AMAZON_PCI + 0x00000084
+#define BAR22_MASK                             AMAZON_PCI + 0x00000088
+#define BAR23_MASK                             AMAZON_PCI + 0x0000008c
+#define BAR24_MASK                             AMAZON_PCI + 0x00000090
+#define BAR25_MASK                             AMAZON_PCI + 0x00000094
+#define BAR26_MASK                             AMAZON_PCI + 0x00000098
+#define CARDBUS_CIS_POINTER2                   AMAZON_PCI + 0x0000009c
+#define SUBSYSTEM_ID2                          AMAZON_PCI + 0x000000a0
+#define PCI_ADDRESS_MAP_21                     AMAZON_PCI + 0x000000a4
+#define PCI_ADDRESS_MAP_22                     AMAZON_PCI + 0x000000a8
+#define PCI_ADDRESS_MAP_23                     AMAZON_PCI + 0x000000ac
+#define PCI_ADDRESS_MAP_24                     AMAZON_PCI + 0x000000b0
+#define PCI_ADDRESS_MAP_25                     AMAZON_PCI + 0x000000b4
+#define PCI_ADDRESS_MAP_26                     AMAZON_PCI + 0x000000b8
+#define FPI_ADDRESS_MASK11LOW                  AMAZON_PCI + 0x000000bc
+#define FPI_ADDRESS_MAP_0                      AMAZON_PCI + 0x000000c0
+#define FPI_ADDRESS_MAP_1                      AMAZON_PCI + 0x000000c4
+#define FPI_ADDRESS_MAP_2                      AMAZON_PCI + 0x000000c8
+#define FPI_ADDRESS_MAP_3                      AMAZON_PCI + 0x000000cc
+#define FPI_ADDRESS_MAP_4                      AMAZON_PCI + 0x000000d0
+#define FPI_ADDRESS_MAP_5                      AMAZON_PCI + 0x000000d4
+#define FPI_ADDRESS_MAP_6                      AMAZON_PCI + 0x000000d8
+#define FPI_ADDRESS_MAP_7                      AMAZON_PCI + 0x000000dc
+#define FPI_ADDRESS_MAP_11LOW                  AMAZON_PCI + 0x000000e0
+#define FPI_ADDRESS_MAP_11HIGH                 AMAZON_PCI + 0x000000e4
+#define FPI_BURST_LENGTH                       AMAZON_PCI + 0x000000e8
+#define SET_PCI_SERR                           AMAZON_PCI + 0x000000ec
+#define DMA_FPI_START_ADDR                     AMAZON_PCI + 0x000000f0
+#define DMA_PCI_START_ADDR                     AMAZON_PCI + 0x000000f4
+#define DMA_TRANSFER_COUNT                     AMAZON_PCI + 0x000000f8
+#define DMA_CONTROL_STATUS                     AMAZON_PCI + 0x000000fc
+
+#define EXT_PCI1_CONFIG_SPACE_BASE_ADDR        AMAZON_PCI_CFG_BASE + 0x0800
+#define EXT_PCI2_CONFIG_SPACE_BASE_ADDR        AMAZON_PCI_CFG_BASE + 0x1000
+#define EXT_PCI3_CONFIG_SPACE_BASE_ADDR        AMAZON_PCI_CFG_BASE + 0x1800
+#define EXT_PCI4_CONFIG_SPACE_BASE_ADDR        AMAZON_PCI_CFG_BASE + 0x2000
+#define EXT_PCI5_CONFIG_SPACE_BASE_ADDR        AMAZON_PCI_CFG_BASE + 0x2800
+#define EXT_PCI6_CONFIG_SPACE_BASE_ADDR        AMAZON_PCI_CFG_BASE + 0x3000
+#define EXT_PCI7_CONFIG_SPACE_BASE_ADDR        AMAZON_PCI_CFG_BASE + 0x3800
+#define EXT_PCI8_CONFIG_SPACE_BASE_ADDR        AMAZON_PCI_CFG_BASE + 0x4000
+#define EXT_PCI9_CONFIG_SPACE_BASE_ADDR        AMAZON_PCI_CFG_BASE + 0x4800
+#define EXT_PCI10_CONFIG_SPACE_BASE_ADDR       AMAZON_PCI_CFG_BASE + 0x5000
+#define EXT_PCI11_CONFIG_SPACE_BASE_ADDR       AMAZON_PCI_CFG_BASE + 0x5800
+#define EXT_PCI12_CONFIG_SPACE_BASE_ADDR       AMAZON_PCI_CFG_BASE + 0x6000
+#define EXT_PCI13_CONFIG_SPACE_BASE_ADDR       AMAZON_PCI_CFG_BASE + 0x6800
+#define EXT_PCI14_CONFIG_SPACE_BASE_ADDR       AMAZON_PCI_CFG_BASE + 0x7000
+#define EXT_PCI15_CONFIG_SPACE_BASE_ADDR       AMAZON_PCI_CFG_BASE + 0x7800
+#define EXT_CARDBUS_CONFIG_SPACE_BASE_ADDR     AMAZON_PCI_CFG_BASE + 0XF000
+#define EXT_PCI_BAR1_ADDR                      0x10
+#define EXT_PCI_BAR2_ADDR                      0x14
+#define EXT_PCI_BAR3_ADDR                      0x18
+#define EXT_PCI_BAR4_ADDR                      0x1C
+#define EXT_PCI_BAR5_ADDR                      0x20
+#define EXT_PCI_BAR6_ADDR                      0x24
+                                                                                                             
+#define DEVICE_ID_VECDOR_ID_ADDR               AMAZON_PCI_CFG_BASE + 0x0
+#define STATUS_COMMAND_ADDR                    AMAZON_PCI_CFG_BASE + 0x4
+#define BUS_MASTER_ENABLE_BIT                  2
+#define MEM_SPACE_ENABLE_BIT                   1
+#define CLASS_CODE_REVISION_ADDR               AMAZON_PCI_CFG_BASE + 0x8
+#define BIST_HEADER_TYPE_LATENCY_CAHCE_ADDR    AMAZON_PCI_CFG_BASE + 0xC
+#define BAR1_ADDR                              AMAZON_PCI_CFG_BASE + 0x10
+#define BAR2_ADDR                              AMAZON_PCI_CFG_BASE + 0x14
+#define BAR3_ADDR                              AMAZON_PCI_CFG_BASE + 0x18
+#define BAR4_ADDR                              AMAZON_PCI_CFG_BASE + 0x1C
+#define BAR3_ADDR                              AMAZON_PCI_CFG_BASE + 0x18
+#define BAR4_ADDR                              AMAZON_PCI_CFG_BASE + 0x1C
+#define BAR5_ADDR                              AMAZON_PCI_CFG_BASE + 0x20
+#define BAR6_ADDR                              AMAZON_PCI_CFG_BASE + 0x24
+#define CARDBUS_CIS_POINTER_ADDR               AMAZON_PCI_CFG_BASE + 0x28
+#define SUBSYSTEM_ID_VENDOR_ID_ADDR            AMAZON_PCI_CFG_BASE + 0x2C
+#define EXPANSION_ROM_BASE_ADDR                AMAZON_PCI_CFG_BASE + 0x30
+#define CAPABILITIES_POINTER_ADDR              AMAZON_PCI_CFG_BASE + 0x34
+#define RESERVED_0x38                          AMAZON_PCI_CFG_BASE + 0x38
+#define MAX_LAT_MIN_GNT_INT_PIN_LINE_ADDR      AMAZON_PCI_CFG_BASE + 0x3C
+#define POWER_MNGT_NEXT_POINTER_CAP_ID_ADDR    AMAZON_PCI_CFG_BASE + 0x40
+#define POWER_MANAGEMENT_CTRL_STATUS_ADDR      AMAZON_PCI_CFG_BASE + 0x44
+#define RESERVED_0x48                          AMAZON_PCI_CFG_BASE + 0x48
+#define RESERVED_0x4C                          AMAZON_PCI_CFG_BASE + 0x4C
+#define ERROR_ADDR_PCI_FPI_ADDR                AMAZON_PCI_CFG_BASE + 0x50
+#define ERROR_ADdR_FPI_PCI_ADDR                AMAZON_PCI_CFG_BASE + 0x54
+#define ERROR_TAG_FPI_PCI_ADDR                 AMAZON_PCI_CFG_BASE + 0x58
+#define PCI_ARB_CTRL_STATUS_ADDR               AMAZON_PCI_CFG_BASE + 0x5C
+#define INTERNAL_ARB_ENABLE_BIT                0
+#define ARB_SCHEME_BIT                         1
+#define PCI_MASTER0_PRIOR_2BITS                2
+#define PCI_MASTER1_PRIOR_2BITS                4
+#define PCI_MASTER2_PRIOR_2BITS                6
+#define PCI_MASTER0_REQ_MASK_2BITS             8
+#define PCI_MASTER1_REQ_MASK_2BITS             10
+#define PCI_MASTER2_REQ_MASK_2BITS             12
+#define PCI_MASTER0_GNT_MASK_2BITS             14
+#define PCI_MASTER1_GNT_MASK_2BITS             16
+#define PCI_MASTER2_GNT_MASK_2BITS             18
+#define FPI_PCI_INT_STATUS_ADDR                AMAZON_PCI_CFG_BASE + 0x60
+#define FPI_PCI_INT_ACK_ADDR                   AMAZON_PCI_CFG_BASE + 0x64
+#define FPI_PCI_INT_MASK_ADDR                  AMAZON_PCI_CFG_BASE + 0x68
+#define CARDBUS_CTRL_STATUS_ADDR               AMAZON_PCI_CFG_BASE + 0x6C
+#define CARDBUS_CFRAME_ENABLE                  0
+                                                                                                             
+#define CLOCK_CONTROL_default                  0x00000000
+#define CLOCK_CONTROL_mask                     0x00000003
+                                                                                                             
+#define IDENTIFICATION_default                 0x0011C002
+#define IDENTIFICATION_mask                    0x00000000
+                                                                                                             
+#define SOFTRESET_default                      0x00000000
+// SOFTRESET bit 0 is writable but will be reset to 0 after software reset is over
+#define SOFTRESET_mask                         0x00000000
+                                                                                                             
+#define PCI_FPI_ERROR_ADDRESS_default          0xFFFFFFFF
+#define PCI_FPI_ERROR_ADDRESS_mask             0x00000000
+                                                                                                             
+#define FPI_PCI_ERROR_ADDRESS_default          0xFFFFFFFF
+#define FPI_PCI_ERROR_ADDRESS_mask             0x00000000
+                                                                                                             
+#define FPI_ERROR_TAG_default                  0x0000000F
+#define FPI_ERROR_TAG_mask                     0x00000000
+                                                                                                             
+#define IRR_default                            0x00000000
+#define IRR_mask                               0x07013b2F
+                                                                                                             
+#define IRA_IR_default                         0x00000000
+#define IRA_IR_mask                            0x07013b2F
+                                                                                                             
+#define IRM_default                            0x00000000
+#define IRM_mask                               0xFFFFFFFF
+                                                                                                             
+#define EOI_default                            0x00000000
+#define EOI_mask                               0x00000000
+                                                                                                             
+#define PCI_MODE_default                       0x01000103
+#define PCI_MODE_mask                          0x1107070F
+                                                                                                             
+#define DEVICE_VENDOR_ID_default               0x000C15D1
+#define DEVICE_VENDOR_ID_mask                  0xFFFFFFFF
+                                                                                                             
+#define SUBSYSTEM_VENDOR_ID_default            0x000015D1
+#define SUBSYSTEM_VENDOR_ID_mask               0x0000FFFF
+                                                                                                             
+#define POWER_MANAGEMENT_default               0x0000001B
+#define POWER_MANAGEMENT_mask                  0x0000001F
+                                                                                                             
+#define CLASS_CODE1_default                    0x00028000
+#define CLASS_CODE1_mask                       0x00FFFFFF
+                                                                                                             
+#define BAR11_MASK_default                     0x0FF00008
+#define BAR11_MASK_mask                        0x8FF00008
+                                                                                                             
+#define BAR12_MASK_default                     0x80001800
+#define BAR12_MASK_mask                        0x80001F08
+                                                                                                             
+#define BAR13_MASK_default                     0x8FF00008
+#define BAR13_MASK_mask                        0x8FF00008
+                                                                                                             
+#define BAR14_MASK_default                     0x8F000000
+#define BAR14_MASK_mask                        0x8FFFFF08
+                                                                                                             
+#define BAR15_MASK_default                     0x80000000
+#define BAR15_MASK_mask                        0x8FFFFF08
+                                                                                                             
+#define BAR16_MASK_default                     0x80000001
+// bit 0 and bit 3 is mutually exclusive
+#define BAR16_MASK_mask                        0x8FFFFFF9
+                                                                                                             
+#define CARDBUS_CIS_POINTER1_default           0x00000000
+#define CARDBUS_CIS_POINTER1_mask              0x03FFFFFF
+                                                                                                             
+#define SUBSYSTEM_ID1_default                  0x0000000C
+#define SUBSYSTEM_ID1_mask                     0x0000FFFF
+                                                                                                             
+#define PCI_ADDRESS_MAP_11_default             0x18000000
+#define PCI_ADDRESS_MAP_11_mask                0x7FFFFFF1
+                                                                                                             
+#define PCI_ADDRESS_MAP_12_default             0x18100000
+#define PCI_ADDRESS_MAP_12_mask                0x7FFFFF01
+                                                                                                             
+#define PCI_ADDRESS_MAP_13_default             0x18200000
+#define PCI_ADDRESS_MAP_13_mask                0x7FF00001
+                                                                                                             
+#define PCI_ADDRESS_MAP_14_default             0x70000000
+#define PCI_ADDRESS_MAP_14_mask                0x7FFFFF01
+                                                                                                               
+#define PCI_ADDRESS_MAP_15_default             0x00000001
+#define PCI_ADDRESS_MAP_15_mask                0x7FFFFF01
+                                                                                                             
+#define PCI_ADDRESS_MAP_16_default             0x60000000
+#define PCI_ADDRESS_MAP_16_mask                0x7FF00001
+                                                                                                             
+#define FPI_SEGMENT_ENABLE_default             0x000003FF
+#define FPI_SEGMENT_ENABLE_mask                0x000003FF
+                                                                                                             
+#define CLASS_CODE2_default                    0x00FF0000
+#define CLASS_CODE2_mask                       0x00FFFFFF
+                                                                                                             
+#define BAR21_MASK_default                     0x80000008
+#define BAR21_MASK_mask                        0x8FFFFFF8
+                                                                                                             
+#define BAR22_MASK_default                     0x80000008
+#define BAR22_MASK_mask                        0x80001F08
+                                                                                                             
+#define BAR23_MASK_default                     0x80000008
+#define BAR23_MASK_mask                        0x8FF00008
+                                                                                                             
+#define BAR24_MASK_default                     0x8FE00000
+#define BAR24_MASK_mask                        0x8FFFFF08
+                                                                                                             
+#define BAR25_MASK_default                     0x8FFFF000
+#define BAR25_MASK_mask                        0x8FFFFF08
+                                                                                                             
+#define BAR26_MASK_default                     0x8FFFFFE1
+#define BAR26_MASK_mask                        0x8FFFFFF1
+                                                                                                             
+#define CARDBUS_CIS_POINTER2_default           0x00000000
+#define CARDBUS_CIS_POINTER2_mask              0x03FFFFFF
+
+#define SUBSYSTEM_ID2_default                  0x0000000C
+#define SUBSYSTEM_ID2_mask                     0x0000FFFF
+                                                                                                             
+#define PCI_ADDRESS_MAP_21_default             0x3FE00000
+#define PCI_ADDRESS_MAP_21_mask                0x7FFFFFF1
+                                                                                                             
+#define PCI_ADDRESS_MAP_22_default             0x68000000
+#define PCI_ADDRESS_MAP_22_mask                0x7FFFFF01
+                                                                                                             
+#define PCI_ADDRESS_MAP_23_default             0x20000000
+#define PCI_ADDRESS_MAP_23_mask                0x7FF00001
+                                                                                                             
+#define PCI_ADDRESS_MAP_24_default             0x70000001
+#define PCI_ADDRESS_MAP_24_mask                0x7FFFFF01
+                                                                                                             
+#define PCI_ADDRESS_MAP_25_default             0x78000001
+#define PCI_ADDRESS_MAP_25_mask                0x7FFFFF01
+                                                                                                             
+#define PCI_ADDRESS_MAP_26_default             0x20000000
+#define PCI_ADDRESS_MAP_26_mask                0x7FF00001
+                                                                                                             
+#define FPI_ADDRESS_MASK11LOW_default          0x00000000
+#define FPI_ADDRESS_MASK11LOW_mask             0x00070000
+                                                                                                             
+#define FPI_ADDRESS_MAP_0_default              0x00000000
+#define FPI_ADDRESS_MAP_0_mask                 0xFFF00000
+                                                                                                             
+#define FPI_ADDRESS_MAP_1_default              0x10000000
+#define FPI_ADDRESS_MAP_1_mask                 0xFFF00000
+                                                                                                             
+#define FPI_ADDRESS_MAP_2_default              0x20000000
+#define FPI_ADDRESS_MAP_2_mask                 0xFFF00000
+
+#define FPI_ADDRESS_MAP_3_default              0x30000000
+#define FPI_ADDRESS_MAP_3_mask                 0xFFF00000
+                                                                                                             
+#define FPI_ADDRESS_MAP_4_default              0x40000000
+#define FPI_ADDRESS_MAP_4_mask                 0xFFF00000
+                                                                                                             
+#define FPI_ADDRESS_MAP_5_default              0x50000000
+#define FPI_ADDRESS_MAP_5_mask                 0xFFF00000
+                                                                                                             
+#define FPI_ADDRESS_MAP_6_default              0x60000000
+#define FPI_ADDRESS_MAP_6_mask                 0xFFF00000
+                                                                                                             
+#define FPI_ADDRESS_MAP_7_default              0x70000000
+#define FPI_ADDRESS_MAP_7_mask                 0xFFF00000
+                                                                                                             
+#define FPI_ADDRESS_MAP_11LOW_default          0xB0000000
+#define FPI_ADDRESS_MAP_11LOW_mask             0xFFFF0000
+                                                                                                             
+#define FPI_ADDRESS_MAP_11HIGH_default         0xB8000000
+#define FPI_ADDRESS_MAP_11HIGH_mask            0xFFF80000
+                                                                                                             
+#define FPI_BURST_LENGTH_default               0x00000000
+#define FPI_BURST_LENGTH_mask                  0x00000303
+                                                                                                             
+#define SET_PCI_SERR_default                   0x00000000
+#define SET_PCI_SERR_mask                      0x00000000
+                                                                                                             
+#define DMA_FPI_START_ADDRESS_default          0x00000000
+#define DMA_FPI_START_ADDRESS_mask             0xFFFFFFFF
+                                                                                                             
+#define DMA_PCI_START_ADDRESS_default          0x00000000
+#define DMA_PCI_START_ADDRESS_mask             0xFFFFFFFF
+                                                                                                             
+#define DMA_TRANSFER_COUNT_default             0x00000000
+#define DMA_TRANSFER_COUNT_mask                0x0000FFFF
+
+#define DMA_CONTROL_STATUS_default             0x00000000
+#define DMA_CONTROL_STATUS_mask                0x00000000   // bit 0,1 is writable
+
+/***********************************************************************/      
+#undef IKOS_MINI_BOOT          //don't run a full booting
+#ifdef CONFIG_USE_IKOS 
+#define CONFIG_USE_VENUS               //Faster, 10M CPU and 192k baudrate
+#ifdef CONFIG_USE_VENUS
+#define IKOS_CPU_SPEED         10000000                                                                                   
+#else
+#define IKOS_CPU_SPEED         180000  //IKOS is slow                                                                             
+#endif 
+#endif //CONFIG_USE_IKOS
+
+/* 165001:henryhsu:20050603:Source Modify form Bing Tao */
+
+#if defined(CONFIG_NET_WIRELESS_SPURS) || defined(CONFIG_NET_WIRELESS_SPURS_MODULE)
+#define EBU_PCI_SOFTWARE_ARBITOR
+#endif
+
+#define  AMAZON_B11
+#ifdef AMAZON_B11
+#define SWITCH_BUF_FPI_ADDR            (0x10110000)
+#define SWITCH_BUF_ADDR                        (KSEG1+SWITCH_BUF_FPI_ADDR)
+#define SWITCH_BUF_SIZE                        (0x2800)
+#define AMAZON_B11_CBM_QD_ADDR         (SWITCH_BUF_ADDR+0x0)
+#define AMAZON_B11_BOND_CELL_ADDR      (SWITCH_BUF_ADDR+0x000)
+#endif
+#define  AMAZON_REFERENCE_BOARD
+//for AMAZON ATM bonding application
+#ifdef AMAZON_REFERENCE_BOARD
+#define  GPIO_DETECT_LOW
+#else
+#undef  GPIO_DETECT_LOW
+#endif
+
+/* 165001 */
+
+#undef AMAZON_IKOS_DEBUG_MSG
+#undef AMAZON_INT_DEBUG_MSG
+#undef AMAZON_ATM_DEBUG_MSG
+#undef AMAZON_DMA_DEBUG_MSG
+#undef AMAZON_SW_DEBUG_MSG
+#undef AMAZON_WDT_DEBUG_MSG
+#undef AMAZON_MTD_DEBUG_MSG
+#undef AMAZON_SSC_DEBUG_MSG
+#undef AMAZON_MEI_DEBUG_MSG
+
+#ifdef AMAZON_IKOS_DEBUG_MSG
+#define AMAZON_IKOS_DMSG(fmt,args...) printk("%s:" fmt, __FUNCTION__, ##args)
+#else
+#define AMAZON_IKOS_DMSG(fmt,args...)
+#endif
+
+#ifdef AMAZON_WDT_DEBUG_MSG 
+#define AMAZON_WDT_DMSG(fmt, args...) printk( "%s: " fmt, __FUNCTION__ , ##args)
+#else 
+#define AMAZON_WDT_DMSG(fm,args...)
+#endif
+
+#ifdef AMAZON_SSC_DEBUG_MSG 
+#define AMAZON_SSC_DMSG(fmt, args...) printk( "%s: " fmt, __FUNCTION__ , ##args)
+#else 
+#define AMAZON_SSC_DMSG(fm,args...)
+#endif
+
+#ifdef AMAZON_DMA_DEBUG_MSG 
+#define AMAZON_DMA_DMSG(fmt, args...) printk( "%s: " fmt, __FUNCTION__ , ##args)
+#else 
+#define AMAZON_DMA_DMSG(fm,args...)
+#endif
+
+#ifdef AMAZON_ATM_DEBUG_MSG
+#define AMAZON_TPE_DMSG(fmt, args...) printk( "%s: " fmt, __FUNCTION__ , ##args)
+#else //not AMAZON_ATM_DEBUG
+#define        AMAZON_TPE_DMSG(fmt, args...)
+#endif //AMAZON_ATM_DEBUG
+
+#ifdef AMAZON_SW_DEBUG_MSG
+#define AMAZON_SW_DMSG(fmt,args...) printk("%s: " fmt, __FUNCTION__ , ##args)
+#else
+#define AMAZON_SW_DMSG(fmt,args...)
+#endif 
+
+#ifdef AMAZON_MTD_DEBUG_MSG
+#define AMAZON_MTD_DMSG(fmt,args...) printk("%s: " fmt, __FUNCTION__ , ##args)
+#else
+#define AMAZON_MTD_DMSG(fmt,args...)
+#endif 
+
+#ifdef AMAZON_INT_DEBUG_MSG
+#define AMAZON_INT_DMSG(x...) printk(x)
+#else
+#define AMAZON_INT_DMSG(x...)
+#endif 
+
+#ifdef AMAZON_MEI_DEBUG_MSG
+#define AMAZON_MEI_DMSG(fmt,args...) printk("%s:" fmt, __FUNCTION__, ##args)
+#else
+#define AMAZON_MEI_DMSG(fmt,args...)
+#endif
+
+#endif //AMAZON_H 
diff --git a/target/linux/amazon-2.6/files/include/asm-mips/amazon/amazon_dma.h b/target/linux/amazon-2.6/files/include/asm-mips/amazon/amazon_dma.h
new file mode 100644 (file)
index 0000000..63ab592
--- /dev/null
@@ -0,0 +1,148 @@
+#ifndef AMAZON_DMA_H
+#define AMAZON_DMA_H
+
+#define RCV_INT          1
+#define TX_BUF_FULL_INT  2
+#define TRANSMIT_CPT_INT 4
+
+#define QOS_DEFAULT_WGT 0x7fffffffUL;
+
+
+enum attr_t{
+   TX=0,
+   RX=1,
+   RESERVED=2,
+   DEFAULT=3,
+   
+};
+
+#ifdef CONFIG_CPU_LITTLE_ENDIAN
+typedef struct rx_desc{
+   u32 data_length:16;
+   volatile u32 reserved:7;
+   volatile u32 byte_offset:2; 
+   volatile u32 Burst_length_offset:3;
+   volatile u32 EoP:1;
+   volatile u32 Res:1;
+   volatile u32 C:1;
+   volatile u32 OWN:1;
+   volatile u32 Data_Pointer;
+   /*fix me:should be 28 bits here, 32 bits just for host simulatiuon purpose*/ 
+}_rx_desc; 
+
+
+typedef struct tx_desc{
+   volatile u32 data_length:16;
+   volatile u32 reserved1:7;
+   volatile u32 byte_offset:5;   
+   volatile u32 EoP:1;
+   volatile u32 SoP:1;
+   volatile u32 C:1;
+   volatile u32 OWN:1;
+   volatile u32 Data_Pointer;//fix me:should be 28 bits here
+}_tx_desc;
+#else //BIG
+typedef struct rx_desc{
+       union
+       {
+               struct
+               {
+                       volatile u32 OWN                        :1;
+                       volatile u32 C                          :1;
+                       volatile u32 SoP                        :1;
+                       volatile u32 EoP                        :1;
+                       volatile u32 Burst_length_offset        :3;
+                       volatile u32 byte_offset                :2; 
+                       volatile u32 reserve                    :7;
+                       volatile u32 data_length                :16;
+               }field;
+
+               volatile u32 word;
+       }status;
+       
+       volatile u32 Data_Pointer;
+}_rx_desc; 
+
+
+typedef struct tx_desc{
+       union
+       {
+               struct
+               {
+                       volatile u32 OWN                 :1;
+                       volatile u32 C                   :1;
+                       volatile u32 SoP                 :1;
+                       volatile u32 EoP                 :1;
+                       volatile u32 byte_offset         :5; 
+                       volatile u32 reserved            :7;
+                       volatile u32 data_length         :16;
+               }field;
+
+               volatile u32 word;
+       }status;
+       
+       volatile u32 Data_Pointer;
+}_tx_desc;
+
+#endif //ENDIAN
+
+struct dma_channel_info{
+  /*filled by driver, optional*/  
+    enum attr_t attr;/*TX or RX*/
+    int weight;
+    int desc_num;
+    int packet_size;
+    int control;/*on or off*/ 
+   
+    int desc_base;
+    int status;
+};
+
+typedef struct dma_channel_info _dma_channel_info;
+
+struct dma_device_info{
+   /*variables*/ 
+   /*filled by driver, compulsary*/
+    char device_name[15];
+    enum attr_t attr;/*default or else*/
+    int tx_burst_len;
+    int rx_burst_len;   
+    int logic_rx_chan_base;
+    int logic_tx_chan_base;
+    u8 on_ch_bit;
+   /*filled by driver, optional*/
+    int  weight;
+    int  current_tx_chan;
+    int  current_rx_chan;
+    int  num_tx_chan;
+    int  num_rx_chan; 
+    struct dma_channel_info tx_chan[2];
+    struct dma_channel_info rx_chan[4]; 
+    
+    /*functions, optional*/
+    u8* (*buffer_alloc)(int len,int* offset, void** opt);
+    int (*buffer_free)(u8* dataptr, void* opt);
+    int (*intr_handler)(struct dma_device_info* info, int status);
+    /*set by device, clear by dma*/
+    int ack;
+    void * priv;               /* used by peripheral driver only */
+};
+typedef struct dma_device_info _dma_device_info;
+
+int dma_device_register(struct dma_device_info* info);
+
+int dma_device_unregister(struct dma_device_info* info);
+
+int dma_device_read(struct dma_device_info* info, u8** dataptr, void** opt);
+
+int dma_device_write(struct dma_device_info* info, u8* dataptr, int len, void* opt);
+
+int dma_device_update(struct dma_device_info* info);
+
+void dma_device_update_rx(struct dma_device_info* dma_dev);
+
+void dma_device_update_tx(struct dma_device_info* dma_dev);
+
+void register_handler_sim(int (*handler)(int));
+#endif /* AMAZON_DMA_H */
diff --git a/target/linux/amazon-2.6/files/include/asm-mips/amazon/amazon_mei.h b/target/linux/amazon-2.6/files/include/asm-mips/amazon/amazon_mei.h
new file mode 100644 (file)
index 0000000..6ac8ab3
--- /dev/null
@@ -0,0 +1,220 @@
+#ifndef                _AMAZON_MEI_H
+#define                _AMAZON_MEI_H
+/////////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+#include "amazon_mei_app.h"
+
+#define AMAZON_MEI_DEBUG_ON
+#define AMAZON_MEI_CMV_EXTRA
+
+#define AMAZON_MEI_MAJOR       106
+
+/*
+**     Define where in ME Processor's memory map the Stratify chip lives
+*/
+#define MEI_SPACE_ACCESS       0xB0100C00
+
+#define MAXSWAPSIZE            8 * 1024        //8k *(32bits)
+//#define AMAZON_ADSL_IMAGESIZE  16*1024       // 16k * (32bits)
+
+
+//     Mailboxes
+#define MSG_LENGTH             16      // x16 bits
+#define YES_REPLY                      1
+#define NO_REPLY               0
+
+#define CMV_TIMEOUT            100     //jiffies
+#define MIB_INTERVAL           10000   //msec
+
+/***  Bit definitions ***/
+
+#define FALSE  0
+#define TRUE   1
+#define BIT0   1<<0
+#define BIT1   1<<1
+#define BIT2   1<<2
+#define BIT3   1<<3
+#define BIT4   1<<4
+#define BIT5   1<<5
+#define BIT6   1<<6
+#define BIT7   1<<7
+#define BIT8   1<<8
+#define BIT9   1<<9
+#define BIT10  1<<10
+#define BIT11  1<<11
+#define BIT12  1<<12
+#define BIT13  1<<13
+#define BIT14  1<<14
+#define BIT15  1<<15
+#define BIT16  1<<16
+#define BIT17  1<<17
+#define BIT18  1<<18
+#define BIT19  1<<19
+#define BIT20  1<<20
+#define BIT21  1<<21
+#define BIT22  1<<22
+#define BIT23  1<<23
+#define BIT24  1<<24
+#define BIT25  1<<25
+#define BIT26  1<<26
+#define BIT27  1<<27
+#define BIT28  1<<28
+#define BIT29  1<<29
+#define BIT30  1<<30
+#define BIT31  1<<31
+
+
+/***   Register address offsets, relative to MEI_SPACE_ADDRESS ***/
+#define MEI_DATA_XFR                           (0x0000 + MEI_SPACE_ACCESS)
+#define        MEI_VERSION                             (0x0200 + MEI_SPACE_ACCESS)     
+#define        ARC_GP_STAT                             (0x0204 + MEI_SPACE_ACCESS)     
+#define        MEI_XFR_ADDR                            (0x020C + MEI_SPACE_ACCESS)     
+#define        MEI_TO_ARC_INT                          (0x021C + MEI_SPACE_ACCESS)
+#define        ARC_TO_MEI_INT                          (0x0220 + MEI_SPACE_ACCESS)     
+#define        ARC_TO_MEI_INT_MASK                     (0x0224 + MEI_SPACE_ACCESS)     
+#define        MEI_DEBUG_WAD                           (0x0228 + MEI_SPACE_ACCESS)     
+#define MEI_DEBUG_RAD                          (0x022C + MEI_SPACE_ACCESS)     
+#define        MEI_DEBUG_DATA                          (0x0230 + MEI_SPACE_ACCESS)     
+#define        MEI_DEBUG_DEC                           (0x0234 + MEI_SPACE_ACCESS)     
+#define        MEI_CONTROL                             (0x0238 + MEI_SPACE_ACCESS)     
+#define        AT_CELLRDY_BC0                          (0x023C + MEI_SPACE_ACCESS)
+#define        AT_CELLRDY_BC1                          (0x0240 + MEI_SPACE_ACCESS)     
+#define        AR_CELLRDY_BC0                          (0x0244 + MEI_SPACE_ACCESS)     
+#define        AR_CELLRDY_BC1                          (0x0248 + MEI_SPACE_ACCESS)     
+#define        AAI_ACCESS                              (0x024C + MEI_SPACE_ACCESS)     
+#define        AAITXCB0                                (0x0300 + MEI_SPACE_ACCESS)     
+#define        AAITXCB1                                (0x0304 + MEI_SPACE_ACCESS)     
+#define        AAIRXCB0                                (0x0308 + MEI_SPACE_ACCESS)     
+#define        AAIRXCB1                                (0x030C + MEI_SPACE_ACCESS)     
+
+
+//     MEI_TO_ARC_INTERRUPT Register definitions
+#define        MEI_TO_ARC_INT1                 BIT3
+#define        MEI_TO_ARC_INT0                 BIT2
+#define MEI_TO_ARC_CS_DONE             BIT1
+#define        MEI_TO_ARC_MSGAV                BIT0
+
+//     ARC_TO_MEI_INTERRUPT Register definitions
+#define        ARC_TO_MEI_INT1                 BIT8
+#define        ARC_TO_MEI_INT0                 BIT7
+#define        ARC_TO_MEI_CS_REQ               BIT6
+#define        ARC_TO_MEI_DBG_DONE             BIT5
+#define        ARC_TO_MEI_MSGACK               BIT4
+#define        ARC_TO_MEI_NO_ACCESS            BIT3
+#define        ARC_TO_MEI_CHECK_AAITX          BIT2
+#define        ARC_TO_MEI_CHECK_AAIRX          BIT1
+#define        ARC_TO_MEI_MSGAV                BIT0
+
+//     ARC_TO_MEI_INTERRUPT_MASK Register definitions
+#define        GP_INT1_EN                      BIT8
+#define        GP_INT0_EN                      BIT7
+#define        CS_REQ_EN                       BIT6
+#define        DBG_DONE_EN                     BIT5
+#define        MSGACK_EN                       BIT4
+#define        NO_ACC_EN                       BIT3
+#define        AAITX_EN                        BIT2
+#define        AAIRX_EN                        BIT1
+#define        MSGAV_EN                        BIT0
+
+//     MEI_CONTROL Register definitions
+#define        INT_LEVEL                       BIT2
+#define        SOFT_RESET                      BIT1
+#define        HOST_MSTR                       BIT0
+
+//     MEI_DEBUG_DECODE Register definitions
+#define MEI_DEBUG_DEC_MASK             (0x3)
+#define MEI_DEBUG_DEC_AUX_MASK         (0x0)
+#define MEI_DEBUG_DEC_DMP1_MASK                (0x1)
+#define MEI_DEBUG_DEC_DMP2_MASK                (0x2)
+#define MEI_DEBUG_DEC_CORE_MASK         (0x3)
+
+
+//     ARC_TO_MEI_MAILBOX[11] is a special location used to indicate
+//     page swap requests.
+#define        MEI_TO_ARC_MAILBOX              (0x15FC0)
+#define MEI_TO_ARC_MAILBOXR            (0x15FEC)                       
+#define        ARC_TO_MEI_MAILBOX              (0x15F90)       
+#define ARC_MEI_MAILBOXR               (0x15FBC)
+
+// Codeswap request messages are indicated by setting BIT31 
+#define OMB_CODESWAP_MESSAGE_MSG_TYPE_MASK     (0x80000000)
+
+/*
+**     Swap page header
+*/
+//     Page must be loaded at boot time if size field has BIT31 set
+#define BOOT_FLAG      (BIT31)
+#define BOOT_FLAG_MASK ~BOOT_FLAG
+
+//     Swap page header describes size in 32-bit words, load location, and image offset
+//     for program and/or data segments
+typedef struct _arc_swp_page_hdr
+{
+       u32             p_offset;       //      Offset bytes of progseg from beginning of image
+       u32             p_dest;         //      Destination addr of progseg on processor
+       u32             p_size;         //      Size in 32-bitwords of program segment
+       u32             d_offset;       //      Offset bytes of dataseg from beginning of image
+       u32             d_dest;         //      Destination addr of dataseg on processor
+       u32             d_size;         //      Size in 32-bitwords of data segment
+}ARC_SWP_PAGE_HDR;
+
+
+/*
+**     Swap image header
+*/
+#define GET_PROG       0       //      Flag used for program mem segment
+#define GET_DATA       1       //      Flag used for data mem segment
+
+//     Image header contains size of image, checksum for image, and count of
+//     page headers. Following that are 'count' page headers followed by
+//     the code and/or data segments to be loaded
+typedef struct _arc_img_hdr
+{
+       u32                     size;           //      Size of binary image in bytes
+       u32                     checksum;       //      Checksum for image
+       u32                     count;          //      Count of swp pages in image
+       ARC_SWP_PAGE_HDR        page[1];        //      Should be "count" pages - '1' to make compiler happy
+}ARC_IMG_HDR;
+
+
+
+/*
+**     Native size for the Stratiphy interface is 32-bits. All reads and writes
+**     MUST be aligned on 32-bit boundaries. Trickery must be invoked to read word and/or
+**     byte data. Read routines are provided. Write routines are probably a bad idea, as the
+**     Arc has unrestrained, unseen access to the same memory, so a read-modify-write cycle
+**     could very well have unintended results.
+*/
+MEI_ERROR meiCMV(u16 *, int);                         // first arg is CMV to ARC, second to indicate whether need reply
+
+void meiLongwordWrite(u32 ul_address, u32 ul_data);
+void meiLongwordRead(u32 ul_address, u32 *pul_data);
+
+
+MEI_ERROR meiDMAWrite(u32 destaddr, u32 *databuff, u32 databuffsize);
+MEI_ERROR meiDebugWrite(u32 destaddr, u32 *databuff, u32 databuffsize);
+
+MEI_ERROR meiDMARead(u32 srcaddr, u32 *databuff, u32 databuffsize);
+MEI_ERROR meiDebugRead(u32 srcaddr, u32 *databuff, u32 databuffsize);
+
+void meiPollForDbgDone(void);
+
+void meiMailboxInterruptsDisable(void);
+void meiMailboxInterruptsEnable(void);
+
+MEI_ERROR meiMailboxWrite(u16 *msgsrcbuffer, u16 msgsize);
+MEI_ERROR meiMailboxRead(u16 *msgdestbuffer, u16 msgsize);
+
+int meiGetPage( u32 Page, u32 data, u32 MaxSize, u32 *Buffer, u32 *Dest);
+
+MEI_ERROR meiHaltArc(void);
+MEI_ERROR meiRunArc(void);
+
+MEI_ERROR meiDownloadBootCode(void);
+
+MEI_ERROR meiForceRebootAdslModem(void);
+
+void makeCMV(u8 opcode, u8 group, u16 address, u16 index, int size, u16 * data);
+
+#endif
+
diff --git a/target/linux/amazon-2.6/files/include/asm-mips/amazon/amazon_mei_app.h b/target/linux/amazon-2.6/files/include/asm-mips/amazon/amazon_mei_app.h
new file mode 100644 (file)
index 0000000..89700d9
--- /dev/null
@@ -0,0 +1,54 @@
+//509221:tc.chen 2005/09/22 Reset DFE added when MEI_TO_ARC_CS_DONE not cleared by ARC and Added AMAZON_MEI_DEBUG_MODE ioctl 
+
+#ifndef        _AMAZON_MEI_APP_H
+#define                _AMAZON_MEI_APP_H
+
+/////////////////////////////////////////////////////////////////////////////////////////////////////
+
+                //  ioctl control
+#define AMAZON_MEI_START                               300
+#define AMAZON_MEI_REPLY                               301
+#define AMAZON_MEI_NOREPLY                             302
+
+#define AMAZON_MEI_RESET                               303
+#define AMAZON_MEI_REBOOT                              304
+#define AMAZON_MEI_HALT                                        305
+#define AMAZON_MEI_CMV_WINHOST                         306
+#define AMAZON_MEI_CMV_READ                            307
+#define AMAZON_MEI_CMV_WRITE                           308
+#define AMAZON_MEI_MIB_DAEMON                          309
+#define AMAZON_MEI_SHOWTIME                            310
+#define AMAZON_MEI_REMOTE                              311
+#define AMAZON_MEI_READDEBUG                           312
+#define AMAZON_MEI_WRITEDEBUG                          313
+#define AMAZON_MEI_LOP                                 314
+
+#define AMAZON_MEI_PCM_SETUP                           315
+#define AMAZON_MEI_PCM_START_TIMER                     316
+#define AMAZON_MEI_PCM_STOP_TIMER                      317
+#define AMAZON_MEI_PCM_CHECK                           318
+#define AMAZON_MEI_GET_EOC_LEN                         319
+#define AMAZON_MEI_GET_EOC_DATA                                320
+#define AMAZON_MEI_PCM_GETDATA                         321
+#define AMAZON_MEI_PCM_GPIO                            322
+#define AMAZON_MEI_EOC_SEND                            323
+//MIB
+#define AMAZON_MIB_LO_ATUC                             324
+#define AMAZON_MIB_LO_ATUR                             325
+#define AMAZON_MEI_DOWNLOAD                            326
+
+#define AMAZON_MEI_DEBUG_MODE                          327 //509221:tc.chen
+#define LOOP_DIAGNOSTIC_MODE_COMPLETE                  328
+
+
+/***   Enums    ***/
+typedef enum mei_error
+{
+       MEI_SUCCESS = 0,
+       MEI_FAILURE = -1,
+       MEI_MAILBOX_FULL = -2,
+       MEI_MAILBOX_EMPTY = -3,
+        MEI_MAILBOX_TIMEOUT = -4,
+}MEI_ERROR;
+
+#endif
diff --git a/target/linux/amazon-2.6/files/include/asm-mips/amazon/amazon_mei_app_ioctl.h b/target/linux/amazon-2.6/files/include/asm-mips/amazon/amazon_mei_app_ioctl.h
new file mode 100644 (file)
index 0000000..d98f60b
--- /dev/null
@@ -0,0 +1,1169 @@
+// 603221:tc.chen 2006/03/21 added APIs to support the WEB related parameters for ADSL Statistics
+
+#ifndef __AMAZON_MEI_APP_IOCTL_H
+#define __AMAZON_MEI_APP_IOCTL_H
+
+#ifdef __KERNEL__
+#include "amazon_mei_ioctl.h"
+#endif
+
+/* Interface Name */
+//#define INTERFACE_NAME <define the interface>
+
+/* adslLineTable constants */
+#define GET_ADSL_LINE_CODE             1
+
+/* adslAtucPhysTable constants */
+#define GET_ADSL_ATUC_PHY              4
+
+/* adslAturPhysTable constants */
+#define GET_ADSL_ATUR_PHY              10
+
+/* adslAtucChanTable constants */
+#define GET_ADSL_ATUC_CHAN_INFO        15
+
+/* adslAturChanTable constants */
+#define GET_ADSL_ATUR_CHAN_INFO                18
+
+/* adslAtucPerfDataTable constants */
+#define GET_ADSL_ATUC_PERF_DATA                21
+
+/* adslAturPerfDataTable constants */
+#define GET_ADSL_ATUR_PERF_DATA                40
+
+/* adslAtucIntervalTable constants */
+#define GET_ADSL_ATUC_INTVL_INFO       60
+
+/* adslAturIntervalTable constants */
+#define GET_ADSL_ATUR_INTVL_INFO       65
+
+/* adslAtucChanPerfDataTable constants */
+#define GET_ADSL_ATUC_CHAN_PERF_DATA   70
+
+/* adslAturChanPerfDataTable constants */
+#define GET_ADSL_ATUR_CHAN_PERF_DATA   90
+
+/* adslAtucChanIntervalTable constants */
+#define GET_ADSL_ATUC_CHAN_INTVL_INFO  110
+
+/* adslAturChanIntervalTable constants */
+#define GET_ADSL_ATUR_CHAN_INTVL_INFO  115
+
+/* adslLineAlarmConfProfileTable constants */
+#define GET_ADSL_ALRM_CONF_PROF                120
+#define SET_ADSL_ALRM_CONF_PROF                121
+
+/* adslAturTrap constants */
+#define ADSL_ATUR_TRAPS                        135
+
+//////////////////  RFC-3440 //////////////
+
+#ifdef AMAZON_MEI_MIB_RFC3440
+/* adslLineExtTable */
+#define GET_ADSL_ATUC_LINE_EXT         201
+#define SET_ADSL_ATUC_LINE_EXT         203
+
+/* adslAtucPerfDateExtTable */
+#define GET_ADSL_ATUC_PERF_DATA_EXT    205
+
+/* adslAtucIntervalExtTable */
+#define GET_ADSL_ATUC_INTVL_EXT_INFO   221
+
+/* adslAturPerfDataExtTable */
+#define GET_ADSL_ATUR_PERF_DATA_EXT    225
+
+/* adslAturIntervalExtTable */
+#define GET_ADSL_ATUR_INTVL_EXT_INFO   233
+
+/* adslAlarmConfProfileExtTable */
+#define GET_ADSL_ALRM_CONF_PROF_EXT    235
+#define SET_ADSL_ALRM_CONF_PROF_EXT    236
+
+/* adslAturExtTrap */
+#define ADSL_ATUR_EXT_TRAPS            240
+
+#endif
+
+// 603221:tc.chen start
+/* The following constants are added to support the WEB related ADSL Statistics */
+
+/* adslLineStatus constants */
+#define GET_ADSL_LINE_STATUS   245
+
+/* adslLineRate constants */
+#define GET_ADSL_LINE_RATE             250
+
+/* adslLineInformation constants */
+#define GET_ADSL_LINE_INFO             255
+
+/* adslNearEndPerformanceStats constants */
+#define GET_ADSL_NEAREND_STATS 270
+
+/* adslFarEndPerformanceStats constants */
+#define GET_ADSL_FAREND_STATS  290
+
+// 603221:tc.chen end
+
+/* Loop diagnostics mode of the ADSL line related constants */
+#define GET_ADSL_LOOP_DIAGNOSTICS_MODE         295
+#define SET_ADSL_LOOP_DIAGNOSTICS_MODE         296
+#define IS_ADSL_LOOP_DIAGNOSTICS_MODE_COMPLETE 299
+
+/* Sub-carrier related parameters */
+#define GET_ADSL_ATUC_SUBCARRIER_STATS         297
+#define GET_ADSL_ATUR_SUBCARRIER_STATS         298
+#define GET_ADSL_LINE_INIT_STATS               150
+#define GET_ADSL_POWER_SPECTRAL_DENSITY                151
+
+
+///////////////////////////////////////////////////////////
+// makeCMV(Opcode, Group, Address, Index, Size, Data)
+
+/* adslLineCode Flags */
+#define LINE_CODE_FLAG                 0x1     /* BIT 0th position */
+
+/* adslAtucPhysTable Flags */
+#define ATUC_PHY_SER_NUM_FLAG          0x1     /* BIT 0th position */
+#define ATUC_PHY_SER_NUM_FLAG_MAKECMV1 makeCMV(H2D_CMV_READ, INFO, 57, 0, 12, data) 
+#define ATUC_PHY_SER_NUM_FLAG_MAKECMV2 makeCMV(H2D_CMV_READ, INFO, 57, 12, 4, data) 
+
+#define ATUC_PHY_VENDOR_ID_FLAG                0x2     /* BIT 1 */
+#define ATUC_PHY_VENDOR_ID_FLAG_MAKECMV        makeCMV(H2D_CMV_READ, INFO, 64, 0, 4, data)
+
+#define ATUC_PHY_VER_NUM_FLAG          0x4     /* BIT 2 */
+#define ATUC_PHY_VER_NUM_FLAG_MAKECMV  makeCMV(H2D_CMV_READ, INFO, 58, 0, 8, data)
+
+#define ATUC_CURR_STAT_FLAG            0x8     /* BIT 3 */
+
+#define ATUC_CURR_OUT_PWR_FLAG         0x10    /* BIT 4 */
+#define ATUC_CURR_OUT_PWR_FLAG_MAKECMV makeCMV(H2D_CMV_READ, INFO, 68, 5, 1, data)
+
+#define ATUC_CURR_ATTR_FLAG            0x20    /* BIT 5 */
+#define ATUC_CURR_ATTR_FLAG_MAKECMV    makeCMV(H2D_CMV_READ, INFO, 69, 0, 2, data)
+
+
+/* adslAturPhysTable   Flags */
+#define ATUR_PHY_SER_NUM_FLAG          0x1     /* BIT 0th position */
+#define ATUR_PHY_SER_NUM_FLAG_MAKECMV1 makeCMV(H2D_CMV_READ, INFO, 62, 0, 12, data)
+#define ATUR_PHY_SER_NUM_FLAG_MAKECMV2 makeCMV(H2D_CMV_READ, INFO, 62, 12, 4, data)
+
+#define ATUR_PHY_VENDOR_ID_FLAG                0x2     /* BIT 1 */
+#define ATUR_PHY_VENDOR_ID_FLAG_MAKECMV        makeCMV(H2D_CMV_READ, INFO, 65, 0, 4, data)
+
+#define ATUR_PHY_VER_NUM_FLAG          0x4     /* BIT 2 */
+#define ATUR_PHY_VER_NUM_FLAG_MAKECMV  makeCMV(H2D_CMV_READ, INFO, 61, 0, 8, data)
+
+#define ATUR_SNRMGN_FLAG               0x8
+#define ATUR_SNRMGN_FLAG_MAKECMV       makeCMV(H2D_CMV_READ, INFO, 68, 4, 1, data)
+
+#define ATUR_ATTN_FLAG                 0x10
+#define ATUR_ATTN_FLAG_MAKECMV         makeCMV(H2D_CMV_READ, INFO, 68, 2, 1, data)
+
+#define ATUR_CURR_STAT_FLAG            0x20    /* BIT 3 */
+
+#define ATUR_CURR_OUT_PWR_FLAG         0x40    /* BIT 4 */
+#define ATUR_CURR_OUT_PWR_FLAG_MAKECMV makeCMV(H2D_CMV_READ, INFO, 69, 5, 1, data)
+
+#define ATUR_CURR_ATTR_FLAG            0x80    /* BIT 5 */
+#define ATUR_CURR_ATTR_FLAG_MAKECMV    makeCMV(H2D_CMV_READ, INFO, 68, 0, 2, data)
+
+/* adslAtucChanTable Flags */
+#define ATUC_CHAN_INTLV_DELAY_FLAG     0x1     /* BIT 0th position */
+#define ATUC_CHAN_INTLV_DELAY_FLAG_MAKECMV     makeCMV(H2D_CMV_READ, RATE, 3, 1, 1, data)
+
+#define ATUC_CHAN_CURR_TX_RATE_FLAG    0x2     /* BIT 1 */
+#define ATUC_CHAN_CURR_TX_RATE_FLAG_MAKECMV    makeCMV(H2D_CMV_READ, RATE, 1, 0, 2, data)
+
+#define ATUC_CHAN_PREV_TX_RATE_FLAG    0x4     /* BIT 2 */
+
+/* adslAturChanTable Flags */
+#define ATUR_CHAN_INTLV_DELAY_FLAG     0x1     /* BIT 0th position */
+#define ATUR_CHAN_INTLV_DELAY_FLAG_MAKECMV     makeCMV(H2D_CMV_READ, RATE, 2, 1, 1, data)
+
+#define ATUR_CHAN_CURR_TX_RATE_FLAG    0x2     /* BIT 1 */
+#define ATUR_CHAN_CURR_TX_RATE_FLAG_MAKECMV    makeCMV(H2D_CMV_READ, RATE, 0, 0, 2, data)
+
+#define ATUR_CHAN_PREV_TX_RATE_FLAG    0x4     /* BIT 2 */
+
+#define ATUR_CHAN_CRC_BLK_LEN_FLAG     0x8     /* BIT 3 */
+
+/* adslAtucPerfDataTable Flags */
+#define ATUC_PERF_LOFS_FLAG            0x1     /* BIT 0th position */
+#define ATUC_PERF_LOSS_FLAG            0x2     /* BIT 1 */
+#define ATUC_PERF_LO_FLAG_MAKECMV              makeCMV(H2D_CMV_READ, PLAM, 0, 0, 1, data)
+#define ATUC_PERF_ESS_FLAG             0x4     /* BIT 2 */
+#define ATUC_PERF_ESS_FLAG_MAKECMV             makeCMV(H2D_CMV_READ, PLAM, 7, 0, 1, data) 
+#define ATUC_PERF_INITS_FLAG   0x8     /* BIT 3 */
+#define ATUC_PERF_VALID_INTVLS_FLAG    0x10 /* BIT 4 */
+#define ATUC_PERF_INVALID_INTVLS_FLAG  0x20 /* BIT 5 */
+#define ATUC_PERF_CURR_15MIN_TIME_ELAPSED_FLAG 0x40 /* BIT 6 */
+#define ATUC_PERF_CURR_15MIN_LOFS_FLAG         0x80     /* BIT 7 */
+#define ATUC_PERF_CURR_15MIN_LOSS_FLAG         0x100 /* BIT 8 */
+#define ATUC_PERF_CURR_15MIN_ESS_FLAG          0x200   /* BIT 9 */
+#define ATUC_PERF_CURR_15MIN_INIT_FLAG         0x400 /* BIT 10 */
+#define ATUC_PERF_CURR_1DAY_TIME_ELAPSED_FLAG 0x800 /* BIT 11 */
+#define ATUC_PERF_CURR_1DAY_LOFS_FLAG          0x1000 /* BIT 12 */
+#define ATUC_PERF_CURR_1DAY_LOSS_FLAG          0x2000 /* BIT 13 */
+#define ATUC_PERF_CURR_1DAY_ESS_FLAG           0x4000 /* BIT 14 */
+#define ATUC_PERF_CURR_1DAY_INIT_FLAG          0x8000 /* BIT 15 */
+#define ATUC_PERF_PREV_1DAY_MON_SEC_FLAG       0x10000 /* BIT 16 */
+#define ATUC_PERF_PREV_1DAY_LOFS_FLAG          0x20000 /* BIT 17 */
+#define ATUC_PERF_PREV_1DAY_LOSS_FLAG          0x40000 /* BIT 18 */
+#define ATUC_PERF_PREV_1DAY_ESS_FLAG           0x80000 /* BIT 19 */
+#define ATUC_PERF_PREV_1DAY_INITS_FLAG         0x100000 /* BIT 20 */
+
+/* adslAturPerfDataTable Flags */
+#define ATUR_PERF_LOFS_FLAG            0x1     /* BIT 0th position */
+#define ATUR_PERF_LOSS_FLAG            0x2     /* BIT 1 */
+#define ATUR_PERF_LPR_FLAG             0x4     /* BIT 2 */
+#define ATUR_PERF_LO_FLAG_MAKECMV              makeCMV(H2D_CMV_READ, PLAM, 1, 0, 1, data)
+#define ATUR_PERF_ESS_FLAG             0x8     /* BIT 3 */
+#define ATUR_PERF_ESS_FLAG_MAKECMV             makeCMV(H2D_CMV_READ, PLAM, 33, 0, 1, data)
+#define ATUR_PERF_VALID_INTVLS_FLAG    0x10 /* BIT 4 */
+#define ATUR_PERF_INVALID_INTVLS_FLAG  0x20 /* BIT 5 */
+#define ATUR_PERF_CURR_15MIN_TIME_ELAPSED_FLAG 0x40 /* BIT 6 */
+#define ATUR_PERF_CURR_15MIN_LOFS_FLAG         0x80     /* BIT 7 */
+#define ATUR_PERF_CURR_15MIN_LOSS_FLAG         0x100 /* BIT 8 */
+#define ATUR_PERF_CURR_15MIN_LPR_FLAG          0x200 /* BIT 9 */
+#define ATUR_PERF_CURR_15MIN_ESS_FLAG          0x400   /* BIT 10 */
+#define ATUR_PERF_CURR_1DAY_TIME_ELAPSED_FLAG  0x800 /* BIT 11 */
+#define ATUR_PERF_CURR_1DAY_LOFS_FLAG          0x1000 /* BIT 12 */
+#define ATUR_PERF_CURR_1DAY_LOSS_FLAG          0x2000 /* BIT 13 */
+#define ATUR_PERF_CURR_1DAY_LPR_FLAG           0x4000 /* BIT 14 */
+#define ATUR_PERF_CURR_1DAY_ESS_FLAG           0x8000 /* BIT 15 */
+#define ATUR_PERF_PREV_1DAY_MON_SEC_FLAG       0x10000 /* BIT 16 */
+#define ATUR_PERF_PREV_1DAY_LOFS_FLAG          0x20000 /* BIT 17 */
+#define ATUR_PERF_PREV_1DAY_LOSS_FLAG          0x40000 /* BIT 18 */
+#define ATUR_PERF_PREV_1DAY_LPR_FLAG           0x80000 /* BIT 19 */
+#define ATUR_PERF_PREV_1DAY_ESS_FLAG           0x100000 /* BIT 20 */
+
+/* adslAtucIntervalTable Flags */
+#define ATUC_INTVL_LOF_FLAG            0x1     /* BIT 0th position */
+#define ATUC_INTVL_LOS_FLAG            0x2     /* BIT 1 */
+#define ATUC_INTVL_ESS_FLAG            0x4     /* BIT 2 */
+#define ATUC_INTVL_INIT_FLAG           0x8   /* BIT 3 */
+#define ATUC_INTVL_VALID_DATA_FLAG     0x10 /* BIT 4 */
+
+/* adslAturIntervalTable Flags */
+#define ATUR_INTVL_LOF_FLAG            0x1     /* BIT 0th position */
+#define ATUR_INTVL_LOS_FLAG            0x2     /* BIT 1 */
+#define ATUR_INTVL_LPR_FLAG            0x4     /* BIT 2 */
+#define ATUR_INTVL_ESS_FLAG            0x8     /* BIT 3 */
+#define ATUR_INTVL_VALID_DATA_FLAG     0x10 /* BIT 4 */
+
+/* adslAtucChanPerfDataTable Flags */
+#define ATUC_CHAN_RECV_BLK_FLAG        0x01    /* BIT 0th position */
+#define ATUC_CHAN_TX_BLK_FLAG  0x02    /* BIT 1 */
+#define ATUC_CHAN_CORR_BLK_FLAG        0x04    /* BIT 2 */
+#define ATUC_CHAN_UNCORR_BLK_FLAG 0x08 /* BIT 3 */
+#define ATUC_CHAN_PERF_VALID_INTVL_FLAG 0x10 /* BIT 4 */
+#define ATUC_CHAN_PERF_INVALID_INTVL_FLAG 0x20 /* BIT 5 */
+#define ATUC_CHAN_PERF_CURR_15MIN_TIME_ELAPSED_FLAG 0x40 /* BIT 6 */
+#define ATUC_CHAN_PERF_CURR_15MIN_RECV_BLK_FLAG        0x80 /* BIT 7 */
+#define ATUC_CHAN_PERF_CURR_15MIN_TX_BLK_FLAG 0x100 /* BIT 8 */
+#define ATUC_CHAN_PERF_CURR_15MIN_CORR_BLK_FLAG 0x200 /* BIT 9 */
+#define ATUC_CHAN_PERF_CURR_15MIN_UNCORR_BLK_FLAG 0x400 /* BIT 10 */
+#define ATUC_CHAN_PERF_CURR_1DAY_TIME_ELAPSED_FLAG 0x800 /* BIT 11*/
+#define ATUC_CHAN_PERF_CURR_1DAY_RECV_BLK_FLAG 0x1000 /* BIT 12 */
+#define ATUC_CHAN_PERF_CURR_1DAY_TX_BLK_FLAG 0x2000 /* BIT 13 */
+#define ATUC_CHAN_PERF_CURR_1DAY_CORR_BLK_FLAG 0x4000 /* BIT 14 */
+#define ATUC_CHAN_PERF_CURR_1DAY_UNCORR_BLK_FLAG 0x8000 /* BIT 15 */
+#define ATUC_CHAN_PERF_PREV_1DAY_MONI_SEC_FLAG 0x10000 /* BIT 16 */
+#define ATUC_CHAN_PERF_PREV_1DAY_RECV_BLK_FLAG 0x20000 /* BIT 17 */
+#define ATUC_CHAN_PERF_PREV_1DAY_TX_BLK_FLAG 0x40000 /* BIT 18 */
+#define ATUC_CHAN_PERF_PREV_1DAY_CORR_BLK_FLAG 0x80000 /* BIT 19 */
+#define ATUC_CHAN_PERF_PREV_1DAY_UNCORR_BLK_FLAG 0x100000 /* BIT 20 */
+
+
+/* adslAturChanPerfDataTable Flags */
+#define ATUR_CHAN_RECV_BLK_FLAG   0x01         /* BIT 0th position */ 
+#define ATUR_CHAN_RECV_BLK_FLAG_MAKECMV_LSW            makeCMV(H2D_CMV_READ, PLAM, 20, 0, 1, data)
+#define ATUR_CHAN_RECV_BLK_FLAG_MAKECMV_MSW            makeCMV(H2D_CMV_READ, PLAM, 21, 0, 1, data)
+#define ATUR_CHAN_TX_BLK_FLAG     0x02         /* BIT 1 */
+#define ATUR_CHAN_TX_BLK_FLAG_MAKECMV_LSW              makeCMV(H2D_CMV_READ, PLAM, 20, 0, 1, data)
+#define ATUR_CHAN_TX_BLK_FLAG_MAKECMV_MSW              makeCMV(H2D_CMV_READ, PLAM, 21, 0, 1, data)
+#define ATUR_CHAN_CORR_BLK_FLAG   0x04         /* BIT 2 */
+#define ATUR_CHAN_CORR_BLK_FLAG_MAKECMV_INTL           makeCMV(H2D_CMV_READ, PLAM, 3, 0, 1, data)
+#define ATUR_CHAN_CORR_BLK_FLAG_MAKECMV_FAST           makeCMV(H2D_CMV_READ, PLAM, 3, 1, 1, data)
+#define ATUR_CHAN_UNCORR_BLK_FLAG 0x08         /* BIT 3 */
+#define ATUR_CHAN_UNCORR_BLK_FLAG_MAKECMV_INTL         makeCMV(H2D_CMV_READ, PLAM, 2, 0, 1, data)
+#define ATUR_CHAN_UNCORR_BLK_FLAG_MAKECMV_FAST         makeCMV(H2D_CMV_READ, PLAM, 2, 1, 1, data)
+#define ATUR_CHAN_PERF_VALID_INTVL_FLAG   0x10         /* BIT 4 */
+#define ATUR_CHAN_PERF_INVALID_INTVL_FLAG 0x20         /* BIT 5 */
+#define ATUR_CHAN_PERF_CURR_15MIN_TIME_ELAPSED_FLAG 0x40 /* BIT 6 */
+#define ATUR_CHAN_PERF_CURR_15MIN_RECV_BLK_FLAG    0x80   /* BIT 7 */
+#define ATUR_CHAN_PERF_CURR_15MIN_TX_BLK_FLAG      0x100 /* BIT 8 */
+#define ATUR_CHAN_PERF_CURR_15MIN_CORR_BLK_FLAG    0x200 /* BIT 9 */
+#define ATUR_CHAN_PERF_CURR_15MIN_UNCORR_BLK_FLAG  0x400 /* BIT 10 */
+#define ATUR_CHAN_PERF_CURR_1DAY_TIME_ELAPSED_FLAG 0x800 /* BIT 11 */
+#define ATUR_CHAN_PERF_CURR_1DAY_RECV_BLK_FLAG     0x1000 /* BIT 12 */
+#define ATUR_CHAN_PERF_CURR_1DAY_TX_BLK_FLAG       0x2000 /* BIT 13 */
+#define ATUR_CHAN_PERF_CURR_1DAY_CORR_BLK_FLAG     0x4000 /* BIT 14 */
+#define ATUR_CHAN_PERF_CURR_1DAY_UNCORR_BLK_FLAG   0x8000 /* BIT 15 */
+#define ATUR_CHAN_PERF_PREV_1DAY_MONI_SEC_FLAG     0x10000 /* BIT 16 */
+#define ATUR_CHAN_PERF_PREV_1DAY_RECV_BLK_FLAG     0x20000 /* BIT 17 */
+#define ATUR_CHAN_PERF_PREV_1DAY_TRANS_BLK_FLAG    0x40000 /* BIT 18 */
+#define ATUR_CHAN_PERF_PREV_1DAY_CORR_BLK_FLAG     0x80000 /* BIT 19 */
+#define ATUR_CHAN_PERF_PREV_1DAY_UNCORR_BLK_FLAG   0x100000 /* BIT 20 */
+
+/* adslAtucChanIntervalTable Flags */
+#define ATUC_CHAN_INTVL_NUM_FLAG               0x1     /* BIT 0th position */
+#define ATUC_CHAN_INTVL_RECV_BLK_FLAG                  0x2     /* BIT 1 */
+#define ATUC_CHAN_INTVL_TX_BLK_FLAG            0x4     /* BIT 2 */
+#define ATUC_CHAN_INTVL_CORR_BLK_FLAG          0x8     /* BIT 3 */
+#define ATUC_CHAN_INTVL_UNCORR_BLK_FLAG        0x10    /* BIT 4 */
+#define ATUC_CHAN_INTVL_VALID_DATA_FLAG        0x20    /* BIT 5 */
+
+/* adslAturChanIntervalTable Flags */
+#define ATUR_CHAN_INTVL_NUM_FLAG               0x1     /* BIT 0th Position */
+#define ATUR_CHAN_INTVL_RECV_BLK_FLAG                  0x2     /* BIT 1 */
+#define ATUR_CHAN_INTVL_TX_BLK_FLAG            0x4     /* BIT 2 */
+#define ATUR_CHAN_INTVL_CORR_BLK_FLAG          0x8     /* BIT 3 */
+#define ATUR_CHAN_INTVL_UNCORR_BLK_FLAG        0x10    /* BIT 4 */
+#define ATUR_CHAN_INTVL_VALID_DATA_FLAG        0x20    /* BIT 5 */
+
+/* adslLineAlarmConfProfileTable Flags */
+#define ATUC_THRESH_15MIN_LOFS_FLAG            0x01   /* BIT 0th position */
+#define ATUC_THRESH_15MIN_LOSS_FLAG            0x02   /* BIT 1 */
+#define ATUC_THRESH_15MIN_ESS_FLAG             0x04   /* BIT 2 */
+#define ATUC_THRESH_FAST_RATEUP_FLAG           0x08   /* BIT 3 */
+#define ATUC_THRESH_INTERLEAVE_RATEUP_FLAG     0x10   /* BIT 4 */
+#define ATUC_THRESH_FAST_RATEDOWN_FLAG         0x20     /* BIT 5 */
+#define ATUC_THRESH_INTERLEAVE_RATEDOWN_FLAG           0x40    /* BIT 6 */
+#define ATUC_INIT_FAILURE_TRAP_ENABLE_FLAG     0x80    /* BIT 7 */
+#define ATUR_THRESH_15MIN_LOFS_FLAG            0x100   /* BIT 8 */
+#define ATUR_THRESH_15MIN_LOSS_FLAG            0x200   /* BIT 9 */
+#define ATUR_THRESH_15MIN_LPRS_FLAG                    0x400   /* BIT 10 */
+#define ATUR_THRESH_15MIN_ESS_FLAG             0x800           /* BIT 11 */
+#define ATUR_THRESH_FAST_RATEUP_FLAG           0x1000          /* BIT 12 */
+#define ATUR_THRESH_INTERLEAVE_RATEUP_FLAG     0x2000          /* BIT 13 */
+#define ATUR_THRESH_FAST_RATEDOWN_FLAG         0x4000  /* BIT 14 */
+#define ATUR_THRESH_INTERLEAVE_RATEDOWN_FLAG   0x8000          /* BIT 15 */
+#define LINE_ALARM_CONF_PROFILE_ROWSTATUS_FLAG  0x10000        /* BIT 16 */
+
+
+/* adslAturTraps Flags */
+#define ATUC_PERF_LOFS_THRESH_FLAG             0x1     /* BIT 0th position */
+#define ATUC_PERF_LOSS_THRESH_FLAG             0x2     /* BIT 1 */
+#define ATUC_PERF_ESS_THRESH_FLAG              0x4     /* BIT 2 */
+#define ATUC_RATE_CHANGE_FLAG                  0x8     /* BIT 3 */
+#define ATUR_PERF_LOFS_THRESH_FLAG             0x10    /* BIT 4 */
+#define ATUR_PERF_LOSS_THRESH_FLAG             0x20    /* BIT 5 */
+#define ATUR_PERF_LPRS_THRESH_FLAG             0x40    /* BIT 6 */
+#define ATUR_PERF_ESS_THRESH_FLAG              0x80    /* BIT 7 */
+#define ATUR_RATE_CHANGE_FLAG                  0x100   /* BIT 8 */
+
+//RFC- 3440 FLAG DEFINITIONS
+
+#ifdef AMAZON_MEI_MIB_RFC3440
+/* adslLineExtTable flags */
+#define ATUC_LINE_TRANS_CAP_FLAG               0x1             /* BIT 0th position */
+#define ATUC_LINE_TRANS_CAP_FLAG_MAKECMV       makeCMV(H2D_CMV_READ,INFO, 67, 0, 1, data)
+#define ATUC_LINE_TRANS_CONFIG_FLAG            0x2             /* BIT 1 */
+#define ATUC_LINE_TRANS_CONFIG_FLAG_MAKECMV    makeCMV(H2D_CMV_READ,INFO, 67, 0, 1, data)
+#define ATUC_LINE_TRANS_CONFIG_FLAG_MAKECMV_WR makeCMV(H2D_CMV_WRITE,INFO, 67, 0, 1, data)
+#define ATUC_LINE_TRANS_ACTUAL_FLAG            0x4             /* BIT 2 */
+#define ATUC_LINE_TRANS_ACTUAL_FLAG_MAKECMV    makeCMV(H2D_CMV_READ,STAT, 1, 0, 1, data)
+#define LINE_GLITE_POWER_STATE_FLAG            0x8             /* BIT 3 */
+#define LINE_GLITE_POWER_STATE_FLAG_MAKECMV    makeCMV(H2D_CMV_READ,STAT, 0, 0, 1, data) 
+
+/* adslAtucPerfDataExtTable flags */
+#define ATUC_PERF_STAT_FASTR_FLAG         0x1 /* BIT 0th position */
+#define ATUC_PERF_STAT_FASTR_FLAG_MAKECMV      makeCMV(H2D_CMV_READ, STAT, 0, 0, 1, data)
+#define ATUC_PERF_STAT_FAILED_FASTR_FLAG 0x2 /* BIT 1 */
+#define ATUC_PERF_STAT_FAILED_FASTR_FLAG_MAKECMV       makeCMV(H2D_CMV_READ, STAT, 0, 0, 1, data)
+#define ATUC_PERF_STAT_SESL_FLAG          0X4  /* BIT 2 */
+#define ATUC_PERF_STAT_SESL_FLAG_MAKECMV       makeCMV(H2D_CMV_READ, PLAM, 8, 0, 1, data)
+#define ATUC_PERF_STAT_UASL_FLAG                  0X8  /* BIT 3 */
+#define ATUC_PERF_STAT_UASL_FLAG_MAKECMV       makeCMV(H2D_CMV_READ, PLAM, 10, 0, 1, data)
+#define ATUC_PERF_CURR_15MIN_FASTR_FLAG           0X10 /* BIT 4 */
+#define ATUC_PERF_CURR_15MIN_FAILED_FASTR_FLAG 0X20    /* BIT 5 */
+#define ATUC_PERF_CURR_15MIN_SESL_FLAG          0X40   /* BIT 6 */
+#define ATUC_PERF_CURR_15MIN_UASL_FLAG             0X80        /* BIT 7 */
+#define ATUC_PERF_CURR_1DAY_FASTR_FLAG             0X100       /* BIT 8 */
+#define ATUC_PERF_CURR_1DAY_FAILED_FASTR_FLAG  0X200   /* BIT 9 */
+#define ATUC_PERF_CURR_1DAY_SESL_FLAG                  0X400   /* BIT 10 */
+#define ATUC_PERF_CURR_1DAY_UASL_FLAG                  0X800   /* BIT 11 */
+#define ATUC_PERF_PREV_1DAY_FASTR_FLAG              0X1000 /* BIT 12 */
+#define ATUC_PERF_PREV_1DAY_FAILED_FASTR_FLAG  0X2000 /* BIT 13 */
+#define ATUC_PERF_PREV_1DAY_SESL_FLAG                  0X4000 /* BIT 14 */
+#define ATUC_PERF_PREV_1DAY_UASL_FLAG                  0X8000 /* BIT 15 */
+
+/* adslAturPerfDataExtTable */
+#define ATUR_PERF_STAT_SESL_FLAG               0X1 /* BIT 0th position */
+#define ATUR_PERF_STAT_SESL_FLAG_MAKECMV       makeCMV(H2D_CMV_READ, PLAM, 34, 0, 1, data)     
+#define ATUR_PERF_STAT_UASL_FLAG               0X2 /* BIT 1 */
+#define ATUR_PERF_STAT_UASL_FLAG_MAKECMV       makeCMV(H2D_CMV_READ, PLAM, 36, 0, 1, data)
+#define ATUR_PERF_CURR_15MIN_SESL_FLAG         0X4 /* BIT 2 */
+#define ATUR_PERF_CURR_15MIN_UASL_FLAG         0X8 /* BIT 3 */
+#define ATUR_PERF_CURR_1DAY_SESL_FLAG          0X10 /* BIT 4 */
+#define ATUR_PERF_CURR_1DAY_UASL_FLAG          0X20 /* BIT 5 */
+#define ATUR_PERF_PREV_1DAY_SESL_FLAG          0X40 /* BIT 6 */
+#define ATUR_PERF_PREV_1DAY_UASL_FLAG          0X80 /* BIT 7 */
+
+/* adslAutcIntervalExtTable flags */
+#define ATUC_INTERVAL_FASTR_FLAG               0x1 /* Bit 0 */         
+#define ATUC_INTERVAL_FAILED_FASTR_FLAG                0x2 /* Bit 1 */         
+#define ATUC_INTERVAL_SESL_FLAG                        0x4 /* Bit 2 */         
+#define ATUC_INTERVAL_UASL_FLAG                        0x8 /* Bit 3 */         
+
+/* adslAturIntervalExtTable */
+#define ATUR_INTERVAL_SESL_FLAG                0X1 /* BIT 0th position */
+#define ATUR_INTERVAL_UASL_FLAG                0X2 /* BIT 1 */
+
+/* adslAlarmConfProfileExtTable */
+#define ATUC_THRESH_15MIN_FAILED_FASTR_FLAG 0X1/* BIT 0th position */
+#define ATUC_THRESH_15MIN_SESL_FLAG             0X2 /* BIT 1 */
+#define ATUC_THRESH_15MIN_UASL_FLAG             0X4 /* BIT 2 */
+#define ATUR_THRESH_15MIN_SESL_FLAG             0X8 /* BIT 3 */
+#define ATUR_THRESH_15MIN_UASL_FLAG             0X10 /* BIT 4 */
+
+/* adslAturExtTraps */
+#define ATUC_15MIN_FAILED_FASTR_TRAP_FLAG      0X1 /* BIT 0th position */
+#define ATUC_15MIN_SESL_TRAP_FLAG               0X2 /* BIT 1 */
+#define ATUC_15MIN_UASL_TRAP_FLAG               0X4 /* BIT 2 */
+#define ATUR_15MIN_SESL_TRAP_FLAG               0X8 /* BIT 3 */
+#define ATUR_15MIN_UASL_TRAP_FLAG               0X10 /* BIT 4 */
+
+// 603221:tc.chen start        
+/* adslLineStatus Flags */
+#define LINE_STAT_MODEM_STATUS_FLAG     0x1 /* BIT 0th position */
+#define LINE_STAT_MODEM_STATUS_FLAG_MAKECMV makeCMV(H2D_CMV_READ, STAT, 0, 0, 1, data)
+#define LINE_STAT_MODE_SEL_FLAG         0x2 /* BIT 1 */
+#define LINE_STAT_MODE_SEL_FLAG_MAKECMV makeCMV(H2D_CMV_READ, STAT, 1, 0, 1, data)
+#define LINE_STAT_TRELLCOD_ENABLE_FLAG 0x4 /* BIT 2 */
+#define LINE_STAT_TRELLCOD_ENABLE_FLAG_MAKECMV makeCMV(H2D_CMV_READ, OPTN, 2, 0, 1, data)
+#define LINE_STAT_LATENCY_FLAG          0x8 /* BIT 3 */
+#define LINE_STAT_LATENCY_FLAG_MAKECMV makeCMV(H2D_CMV_READ, STAT, 12, 0, 1, data)
+
+/* adslLineRate Flags */
+#define LINE_RATE_DATA_RATEDS_FLAG     0x1 /* BIT 0th position */
+#define LINE_RATE_DATA_RATEDS_FLAG_ADSL1_LP0_MAKECMV makeCMV(H2D_CMV_READ, RATE, 1, 0, 2, data)
+#define LINE_RATE_DATA_RATEDS_FLAG_ADSL1_LP1_MAKECMV makeCMV(H2D_CMV_READ, RATE, 1, 2, 2, data)
+
+
+#define LINE_RATE_DATA_RATEDS_FLAG_ADSL2_RP_LP0_MAKECMV makeCMV(H2D_CMV_READ, CNFG, 12, 0, 1, data)
+#define LINE_RATE_DATA_RATEDS_FLAG_ADSL2_MP_LP0_MAKECMV makeCMV(H2D_CMV_READ, CNFG, 13, 0, 1, data)
+#define LINE_RATE_DATA_RATEDS_FLAG_ADSL2_LP_LP0_MAKECMV makeCMV(H2D_CMV_READ, CNFG, 14, 0, 1, data)
+#define LINE_RATE_DATA_RATEDS_FLAG_ADSL2_TP_LP0_MAKECMV makeCMV(H2D_CMV_READ, CNFG, 15, 0, 1, data)
+#define LINE_RATE_DATA_RATEDS_FLAG_ADSL2_KP_LP0_MAKECMV makeCMV(H2D_CMV_READ, CNFG, 17, 0, 2, data)
+
+#define LINE_RATE_DATA_RATEDS_FLAG_ADSL2_RP_LP1_MAKECMV makeCMV(H2D_CMV_READ, CNFG, 12, 1, 1, data)
+#define LINE_RATE_DATA_RATEDS_FLAG_ADSL2_MP_LP1_MAKECMV makeCMV(H2D_CMV_READ, CNFG, 13, 1, 1, data)
+#define LINE_RATE_DATA_RATEDS_FLAG_ADSL2_LP_LP1_MAKECMV makeCMV(H2D_CMV_READ, CNFG, 14, 1, 1, data)
+#define LINE_RATE_DATA_RATEDS_FLAG_ADSL2_TP_LP1_MAKECMV makeCMV(H2D_CMV_READ, CNFG, 15, 1, 1, data)
+#define LINE_RATE_DATA_RATEDS_FLAG_ADSL2_KP_LP1_MAKECMV makeCMV(H2D_CMV_READ, CNFG, 17, 2, 2, data)
+
+#define LINE_RATE_DATA_RATEUS_FLAG     0x2 /* BIT 1 */
+#define LINE_RATE_DATA_RATEUS_FLAG_ADSL1_LP0_MAKECMV makeCMV(H2D_CMV_READ, RATE, 0, 0, 2, data)
+#define LINE_RATE_DATA_RATEUS_FLAG_ADSL1_LP1_MAKECMV makeCMV(H2D_CMV_READ, RATE, 0, 2, 2, data)
+
+
+#define LINE_RATE_DATA_RATEUS_FLAG_ADSL2_RP_LP0_MAKECMV makeCMV(H2D_CMV_READ, CNFG, 23, 0, 1, data)
+#define LINE_RATE_DATA_RATEUS_FLAG_ADSL2_MP_LP0_MAKECMV makeCMV(H2D_CMV_READ, CNFG, 24, 0, 1, data)
+#define LINE_RATE_DATA_RATEUS_FLAG_ADSL2_LP_LP0_MAKECMV makeCMV(H2D_CMV_READ, CNFG, 25, 0, 1, data)
+#define LINE_RATE_DATA_RATEUS_FLAG_ADSL2_TP_LP0_MAKECMV makeCMV(H2D_CMV_READ, CNFG, 26, 0, 1, data)
+#define LINE_RATE_DATA_RATEUS_FLAG_ADSL2_KP_LP0_MAKECMV makeCMV(H2D_CMV_READ, CNFG, 28, 0, 2, data)
+
+#define LINE_RATE_DATA_RATEUS_FLAG_ADSL2_RP_LP1_MAKECMV makeCMV(H2D_CMV_READ, CNFG, 23, 1, 1, data)
+#define LINE_RATE_DATA_RATEUS_FLAG_ADSL2_MP_LP1_MAKECMV makeCMV(H2D_CMV_READ, CNFG, 24, 1, 1, data)
+#define LINE_RATE_DATA_RATEUS_FLAG_ADSL2_LP_LP1_MAKECMV makeCMV(H2D_CMV_READ, CNFG, 25, 1, 1, data)
+#define LINE_RATE_DATA_RATEUS_FLAG_ADSL2_TP_LP1_MAKECMV makeCMV(H2D_CMV_READ, CNFG, 26, 1, 1, data)
+#define LINE_RATE_DATA_RATEUS_FLAG_ADSL2_KP_LP1_MAKECMV makeCMV(H2D_CMV_READ, CNFG, 28, 2, 2, data)
+
+#define LINE_RATE_ATTNDRDS_FLAG        0x4 /* BIT 2 */
+#define LINE_RATE_ATTNDRDS_FLAG_MAKECMV makeCMV(H2D_CMV_READ, INFO, 68, 4, 2, data)
+
+#define LINE_RATE_ATTNDRUS_FLAG                0x8 /* BIT 3 */
+#define LINE_RATE_ATTNDRUS_FLAG_MAKECMV makeCMV(H2D_CMV_READ, INFO, 69, 4, 2, data)
+
+/* adslLineInformation Flags */
+#define LINE_INFO_INTLV_DEPTHDS_FLAG   0x1 /* BIT 0th position */
+#define LINE_INFO_INTLV_DEPTHDS_FLAG_LP0_MAKECMV       makeCMV(H2D_CMV_READ, CNFG, 27, 0, 1, data)
+#define LINE_INFO_INTLV_DEPTHDS_FLAG_LP1_MAKECMV       makeCMV(H2D_CMV_READ, CNFG, 27, 1, 1, data)
+#define LINE_INFO_INTLV_DEPTHUS_FLAG   0x2 /* BIT 1 */
+#define LINE_INFO_INTLV_DEPTHUS_FLAG_LP0_MAKECMV       makeCMV(H2D_CMV_READ, CNFG, 16, 0, 1, data)
+#define LINE_INFO_INTLV_DEPTHUS_FLAG_LP1_MAKECMV       makeCMV(H2D_CMV_READ, CNFG, 16, 1, 1, data)
+#define LINE_INFO_LATNDS_FLAG          0x4 /* BIT 2 */
+#define LINE_INFO_LATNDS_FLAG_MAKECMV  makeCMV(H2D_CMV_READ, INFO, 68, 1, 1, data)
+#define LINE_INFO_LATNUS_FLAG          0x8 /* BIT 3 */
+#define LINE_INFO_LATNUS_FLAG_MAKECMV  makeCMV(H2D_CMV_READ, INFO, 69, 1, 1, data)
+#define LINE_INFO_SATNDS_FLAG                  0x10 /* BIT 4 */
+#define LINE_INFO_SATNDS_FLAG_MAKECMV  makeCMV(H2D_CMV_READ, INFO, 68, 2, 1, data)
+#define LINE_INFO_SATNUS_FLAG                  0x20 /* BIT 5 */
+#define LINE_INFO_SATNUS_FLAG_MAKECMV  makeCMV(H2D_CMV_READ, INFO, 69, 2, 1, data)
+#define LINE_INFO_SNRMNDS_FLAG                 0x40 /* BIT 6 */
+#define LINE_INFO_SNRMNDS_FLAG_ADSL1_MAKECMV   makeCMV(H2D_CMV_READ, INFO, 68, 3, 1, data)
+#define LINE_INFO_SNRMNDS_FLAG_ADSL2_MAKECMV   makeCMV(H2D_CMV_READ, RATE, 3, 0, 1, data)
+#define LINE_INFO_SNRMNDS_FLAG_ADSL2PLUS_MAKECMV       makeCMV(H2D_CMV_READ, PLAM, 46, 0, 1, data)
+#define LINE_INFO_SNRMNUS_FLAG                 0x80 /* BIT 7 */
+#define LINE_INFO_SNRMNUS_FLAG_MAKECMV makeCMV(H2D_CMV_READ, INFO, 69, 3, 1, data)
+#define LINE_INFO_ACATPDS_FLAG         0x100 /* BIT 8 */
+#define LINE_INFO_ACATPDS_FLAG_MAKECMV makeCMV(H2D_CMV_READ, INFO, 68, 6, 1, data)
+#define LINE_INFO_ACATPUS_FLAG         0x200 /* BIT 9 */
+#define LINE_INFO_ACATPUS_FLAG_MAKECMV makeCMV(H2D_CMV_READ, INFO, 69, 6, 1, data)
+
+/* adslNearEndPerformanceStats Flags */
+#define NEAREND_PERF_SUPERFRAME_FLAG_LSW_MAKECMV       makeCMV(H2D_CMV_READ, PLAM, 20, 0, 1, data)
+#define NEAREND_PERF_SUPERFRAME_FLAG_MSW_MAKECMV       makeCMV(H2D_CMV_READ, PLAM, 21, 0, 1, data)
+#define NEAREND_PERF_SUPERFRAME_FLAG   0x1 /* BIT 0th position */
+#define NEAREND_PERF_LOS_FLAG_MAKECMV  makeCMV(H2D_CMV_READ, PLAM, 0, 0, 1, data)
+#define NEAREND_PERF_LOS_FLAG          0x2 /* BIT 1 */
+#define NEAREND_PERF_LOF_FLAG          0x4 /* BIT 2 */
+#define NEAREND_PERF_LPR_FLAG          0x8 /* BIT 3 */
+#define NEAREND_PERF_NCD_FLAG          0x10 /* BIT 4 */
+#define NEAREND_PERF_LCD_FLAG          0x20 /* BIT 5 */
+#define NEAREND_PERF_CRC_FLAG          0x40 /* BIT 6 */
+#define NEAREND_PERF_CRC_FLAG_LP0_MAKECMV      makeCMV(H2D_CMV_READ, PLAM, 2, 0, 1, data)
+#define NEAREND_PERF_CRC_FLAG_LP1_MAKECMV      makeCMV(H2D_CMV_READ, PLAM, 2, 1, 1, data)
+#define NEAREND_PERF_RSCORR_FLAG_LP0_MAKECMV   makeCMV(H2D_CMV_READ, PLAM, 3, 0, 1, data)
+#define NEAREND_PERF_RSCORR_FLAG_LP1_MAKECMV   makeCMV(H2D_CMV_READ, PLAM, 3, 1, 1, data)
+#define NEAREND_PERF_RSCORR_FLAG       0x80 /* BIT 7 */
+#define NEAREND_PERF_FECS_FLAG_MAKECMV makeCMV(H2D_CMV_READ, PLAM, 6, 0, 1, data)
+#define NEAREND_PERF_FECS_FLAG         0x100 /* BIT 8 */
+#define NEAREND_PERF_ES_FLAG_MAKECMV   makeCMV(H2D_CMV_READ, PLAM, 7, 0, 1, data)
+#define NEAREND_PERF_ES_FLAG           0x200 /* BIT 9 */
+#define NEAREND_PERF_SES_FLAG_MAKECMV  makeCMV(H2D_CMV_READ, PLAM, 8, 0, 1, data)
+#define NEAREND_PERF_SES_FLAG          0x400 /* BIT 10 */
+#define NEAREND_PERF_LOSS_FLAG_MAKECMV makeCMV(H2D_CMV_READ, PLAM, 9, 0, 1, data)
+#define NEAREND_PERF_LOSS_FLAG         0x800 /* BIT 11 */
+#define NEAREND_PERF_UAS_FLAG_MAKECMV  makeCMV(H2D_CMV_READ, PLAM, 10, 0, 1, data)
+#define NEAREND_PERF_UAS_FLAG          0x1000 /* BIT 12 */
+#define NEAREND_PERF_HECERR_FLAG_BC0_MAKECMV   makeCMV(H2D_CMV_READ, PLAM, 11, 0, 2, data)
+#define NEAREND_PERF_HECERR_FLAG_BC1_MAKECMV   makeCMV(H2D_CMV_READ, PLAM, 11, 2, 2, data)
+#define NEAREND_PERF_HECERR_FLAG               0x2000 /* BIT 13 */
+
+/* adslFarEndPerformanceStats Flags */
+#define FAREND_PERF_LOS_FLAG_MAKECMV   makeCMV(H2D_CMV_READ, PLAM, 1, 0, 1, data)
+#define FAREND_PERF_LOS_FLAG   0x1 /* BIT 0th position */
+#define FAREND_PERF_LOF_FLAG   0x2 /* BIT 1 */
+#define FAREND_PERF_LPR_FLAG   0x4 /* BIT 2 */
+#define FAREND_PERF_NCD_FLAG   0x8 /* BIT 3 */
+#define FAREND_PERF_LCD_FLAG   0x10 /* BIT 4 */
+#define FAREND_PERF_CRC_FLAG_LP0_MAKECMV       makeCMV(H2D_CMV_READ, PLAM, 24, 0, 1, data)
+#define FAREND_PERF_CRC_FLAG_LP1_MAKECMV       makeCMV(H2D_CMV_READ, PLAM, 24, 1, 1, data)
+#define FAREND_PERF_CRC_FLAG   0x20 /* BIT 5 */
+#define FAREND_PERF_RSCORR_FLAG_LP0_MAKECMV    makeCMV(H2D_CMV_READ, PLAM, 28, 0, 1, data)
+#define FAREND_PERF_RSCORR_FLAG_LP1_MAKECMV    makeCMV(H2D_CMV_READ, PLAM, 28, 1, 1, data)
+#define FAREND_PERF_RSCORR_FLAG        0x40 /* BIT 6 */
+#define FAREND_PERF_FECS_FLAG_MAKECMV  makeCMV(H2D_CMV_READ, PLAM, 32, 0, 1, data)
+#define FAREND_PERF_FECS_FLAG  0x80 /* BIT 7 */
+#define FAREND_PERF_ES_FLAG_MAKECMV    makeCMV(H2D_CMV_READ, PLAM, 33, 0, 1, data)
+#define FAREND_PERF_ES_FLAG    0x100 /* BIT 8 */
+#define FAREND_PERF_SES_FLAG_MAKECMV   makeCMV(H2D_CMV_READ, PLAM, 34, 0, 1, data)
+#define FAREND_PERF_SES_FLAG   0x200 /* BIT 9 */
+#define FAREND_PERF_LOSS_FLAG_MAKECMV  makeCMV(H2D_CMV_READ, PLAM, 35, 0, 1, data)
+#define FAREND_PERF_LOSS_FLAG  0x400 /* BIT 10 */
+#define FAREND_PERF_UAS_FLAG_MAKECMV   makeCMV(H2D_CMV_READ, PLAM, 36, 0, 1, data)
+#define FAREND_PERF_UAS_FLAG   0x800 /* BIT 11 */
+#define FAREND_PERF_HECERR_FLAG_BC0_MAKECMV    makeCMV(H2D_CMV_READ, PLAM, 37, 0, 2, data)
+#define FAREND_PERF_HECERR_FLAG_BC1_MAKECMV    makeCMV(H2D_CMV_READ, PLAM, 37, 2, 2, data)
+#define FAREND_PERF_HECERR_FLAG        0x1000 /* BIT 12 */
+// 603221:tc.chen end
+/* TR-69 related additional parameters - defines */
+/* Defines for  struct adslATURSubcarrierInfo */
+#define        NEAREND_HLINSC  0x1
+#define NEAREND_HLINSC_MAKECMV(mode)           makeCMV(mode, INFO, 71, 2, 1, data)
+#define        NEAREND_HLINPS  0x2
+#define NEAREND_HLINPS_MAKECMV(mode,idx,size)  makeCMV(mode, INFO, 73, idx, size, data)
+#define        NEAREND_HLOGMT  0x4
+#define NEAREND_HLOGMT_MAKECMV(mode)           makeCMV(mode, INFO, 80, 0, 1, data)
+#define NEAREND_HLOGPS 0x8
+#define NEAREND_HLOGPS_MAKECMV(mode,idx,size)  makeCMV(mode, INFO, 75, idx, size, data)
+#define NEAREND_QLNMT  0x10
+#define NEAREND_QLNMT_MAKECMV(mode)            makeCMV(mode, INFO, 80, 1, 1, data)
+#define        NEAREND_QLNPS   0x20
+#define NEAREND_QLNPS_MAKECMV(mode,idx,size)   makeCMV(mode, INFO, 77, idx, size, data)
+#define        NEAREND_SNRMT   0x40
+#define NEAREND_SNRMT_MAKECMV(mode)            makeCMV(mode, INFO, 80, 2, 1, data)
+#define        NEAREND_SNRPS   0x80
+#define NEAREND_SNRPS_MAKECMV(mode,idx,size)   makeCMV(mode, INFO, 78, idx, size, data)
+#define        NEAREND_BITPS   0x100
+#define NEAREND_BITPS_MAKECMV(mode,idx,size)   makeCMV(mode, INFO, 22, idx, size, data)
+#define        NEAREND_GAINPS  0x200
+#define NEAREND_GAINPS_MAKECMV(mode,idx,size)  makeCMV(mode, INFO, 24, idx, size, data)
+
+/* Defines for  struct adslATUCSubcarrierInfo */
+#define         FAREND_HLINSC  0x1
+#define  FAREND_HLINSC_MAKECMV(mode)           makeCMV(mode, INFO, 70, 0, 1, data)
+#define         FAREND_HLINPS  0x2
+#define  FAREND_HLINPS_MAKECMV(mode,idx,size)  makeCMV(mode, INFO, 72, idx, size, data)
+#define         FAREND_HLOGMT  0x4
+#define  FAREND_HLOGMT_MAKECMV(mode)           makeCMV(mode, INFO, 79, 0, 1, data)
+#define  FAREND_HLOGPS 0x8
+#define  FAREND_HLOGPS_MAKECMV(mode,idx,size)  makeCMV(mode, INFO, 74, idx, size, data)
+#define  FAREND_QLNMT  0x10
+#define  FAREND_QLNMT_MAKECMV(mode)            makeCMV(mode, INFO, 79, 1, 1, data)
+#define         FAREND_QLNPS   0x20
+#define  FAREND_QLNPS_MAKECMV(mode,idx,size)   makeCMV(mode, INFO, 76, idx, size, data)
+#define         FAREND_SNRMT   0x40
+#define  FAREND_SNRMT_MAKECMV(mode)            makeCMV(mode, INFO, 79, 2, 1, data)
+#define         FAREND_SNRPS   0x80
+#define  FAREND_SNRPS_MAKECMV(mode,idx,size)   makeCMV(mode, INFO, 10, idx, size, data)
+#define         FAREND_BITPS   0x100
+#define  FAREND_BITPS_MAKECMV(mode,idx,size)   makeCMV(mode, INFO, 23, idx, size, data)
+#define         FAREND_GAINPS  0x200
+#define  FAREND_GAINPS_MAKECMV(mode,idx,size)  makeCMV(mode, INFO, 25, idx, size, data)
+
+
+// GET_ADSL_POWER_SPECTRAL_DENSITY
+#define NOMPSD_US_MAKECMV      makeCMV(H2D_CMV_READ, INFO, 102, 0, 1, data)
+#define NOMPSD_DS_MAKECMV      makeCMV(H2D_CMV_READ, INFO, 102, 1, 1, data)
+#define PCB_US_MAKECMV         makeCMV(H2D_CMV_READ, INFO, 102, 6, 1, data)
+#define PCB_DS_MAKECMV         makeCMV(H2D_CMV_READ, INFO, 102, 7, 1, data)
+#define        RMSGI_US_MAKECMV        makeCMV(H2D_CMV_READ, INFO, 102, 10, 1, data)
+#define        RMSGI_DS_MAKECMV        makeCMV(H2D_CMV_READ, INFO, 102, 11, 1, data)
+
+
+#endif
+/////////////////////////////////////////////////Macro Definitions ? FLAG Setting & Testing
+
+#define SET_FLAG(flags, flag_val)   ((*flags) = ((*flags) | flag_val))
+//     -- This macro sets the flags with the flag_val. Here flags is passed as a pointer
+
+#define IS_FLAG_SET(flags, test_flag)  (((*flags) & (test_flag)) == (test_flag)? test_flag:0)
+//     -- This macro verifies whether test_flag has been set in flags. Here flags is passed as a pointer
+
+
+#define CLR_FLAG(flags, flag_bit)      ((*flags) = (*flags) & (~flag_bit))
+//     -- This macro resets the specified flag_bit in the flags. Here flags is passed as a pointer
+
+
+////////////////////////////////////////////////DATA STRUCTURES ORGANIZATION
+       
+//Here are the data structures used for accessing mib parameters. The ioctl call includes the third parameter as a void pointer. This parameter has to be type-casted in the driver code to the corresponding structure depending upon the command type. For Ex: consider the ioctl used to get the adslLineCode type, ioctl(fd,GET_ADSL_LINE_CODE,void *struct_adslLineTableEntry). In the driver code we check on the type of the command, i.e GET_ADSL_LINE_CODE and type-cast the void pointer to struct adslLineTableEntry type.
+       //
+#define u32 unsigned int
+#define u16 unsigned short
+#define s16 short
+#define u8 unsigned char
+
+
+typedef u32 AdslPerfTimeElapsed;
+typedef u32 AdslPerfPrevDayCount;
+typedef u32 PerfCurrentCount;
+typedef u32 PerfIntervalCount;
+typedef u32 AdslPerfCurrDayCount;
+
+
+//ioctl(int fd, GET_ADSL_LINE_CODE, void *struct_adslLineTableEntry)
+
+typedef struct adslLineTableEntry {
+       int ifIndex;
+       int adslLineCode;
+       u8 flags;
+} adslLineTableEntry;
+
+#ifdef AMAZON_MEI_MIB_RFC3440
+typedef struct adslLineExtTableEntry {
+       int ifIndex;
+       u16 adslLineTransAtucCap;
+       u16 adslLineTransAtucConfig;
+       u16 adslLineTransAtucActual;
+       int adslLineGlitePowerState;
+       u32 flags;
+}adslLineExtTableEntry;
+#endif
+//ioctl(int fd, GET_ADSL_ATUC_PHY, void  *struct_adslAtucPhysEntry)
+
+typedef struct adslVendorId {
+       u16     country_code;
+       u_char  provider_id[4];  /* Ascii characters */
+       u_char  revision_info[2];
+}adslVendorId;
+
+
+typedef struct adslAtucPhysEntry {
+       int ifIndex;
+       char serial_no[32];
+       union {
+               char vendor_id[16];
+               adslVendorId vendor_info;
+       } vendor_id;
+
+       char version_no[16];
+       u32 status;
+       int outputPwr;
+       u32 attainableRate;
+       u8 flags;
+} adslAtucPhysEntry;
+
+
+//ioctl(int fd, GET_ADSL_ATUR_PHY, void  *struct_adslAturPhysEntry)
+
+typedef struct adslAturPhysEntry {
+       int ifIndex;
+       char serial_no[32];
+       union {
+       char vendor_id[16];
+               adslVendorId vendor_info;
+       } vendor_id;
+       char version_no[16];
+       int SnrMgn;
+       u32 Attn;
+       u32 status;
+       int outputPwr;
+       u32 attainableRate;
+       u8 flags;
+} adslAturPhysEntry;
+
+
+//ioctl(int fd, GET_ADSL_ATUC_CHAN_INFO, void *struct_adslAtucChanInfo)
+
+typedef struct adslAtucChanInfo {
+       int ifIndex;
+       u32 interleaveDelay;
+       u32 currTxRate;
+       u32 prevTxRate;
+       u8 flags;
+} adslAtucChanInfo;
+
+
+//ioctl(int fd, GET_ADSL_ATUR_CHAN_INFO, void *struct_adslAturChanInfo)
+
+typedef struct adslAturChanInfo {
+       int ifIndex;
+       u32 interleaveDelay;
+       u32 currTxRate;
+       u32 prevTxRate;
+       u32 crcBlkLen;
+       u8 flags;
+} adslAturChanInfo;
+
+
+//ioctl(int fd, GET_ADSL_ATUC_PERF_DATA,  void *struct_atucPerfDataEntry)
+
+typedef struct atucPerfDataEntry
+{
+   int                 ifIndex;
+   u32                         adslAtucPerfLofs;             
+   u32                         adslAtucPerfLoss;             
+   u32                         adslAtucPerfESs;                 
+   u32                         adslAtucPerfInits;
+   int                         adslAtucPerfValidIntervals;
+   int                         adslAtucPerfInvalidIntervals;
+   AdslPerfTimeElapsed         adslAtucPerfCurr15MinTimeElapsed;
+   PerfCurrentCount    adslAtucPerfCurr15MinLofs;
+   PerfCurrentCount    adslAtucPerfCurr15MinLoss;
+   PerfCurrentCount    adslAtucPerfCurr15MinESs;
+   PerfCurrentCount    adslAtucPerfCurr15MinInits;
+   AdslPerfTimeElapsed         adslAtucPerfCurr1DayTimeElapsed;
+   AdslPerfCurrDayCount adslAtucPerfCurr1DayLofs;
+   AdslPerfCurrDayCount adslAtucPerfCurr1DayLoss;
+   AdslPerfCurrDayCount adslAtucPerfCurr1DayESs;
+   AdslPerfCurrDayCount adslAtucPerfCurr1DayInits;
+   int                         adslAtucPerfPrev1DayMoniSecs;
+   AdslPerfPrevDayCount adslAtucPerfPrev1DayLofs;
+   AdslPerfPrevDayCount adslAtucPerfPrev1DayLoss;
+   AdslPerfPrevDayCount adslAtucPerfPrev1DayESs;
+   AdslPerfPrevDayCount adslAtucPerfPrev1DayInits;
+   u32                 flags;
+} atucPerfDataEntry;
+
+#ifdef AMAZON_MEI_MIB_RFC3440
+typedef struct atucPerfDataExtEntry
+ {
+  int ifIndex;
+  u32 adslAtucPerfStatFastR;
+  u32 adslAtucPerfStatFailedFastR;
+  u32 adslAtucPerfStatSesL;
+  u32 adslAtucPerfStatUasL;
+  u32 adslAtucPerfCurr15MinFastR;
+  u32 adslAtucPerfCurr15MinFailedFastR;
+  u32 adslAtucPerfCurr15MinSesL;
+  u32 adslAtucPerfCurr15MinUasL;
+  u32 adslAtucPerfCurr1DayFastR;
+  u32 adslAtucPerfCurr1DayFailedFastR;
+  u32 adslAtucPerfCurr1DaySesL;
+  u32 adslAtucPerfCurr1DayUasL;
+  u32 adslAtucPerfPrev1DayFastR;
+  u32 adslAtucPerfPrev1DayFailedFastR;
+  u32 adslAtucPerfPrev1DaySesL;
+  u32 adslAtucPerfPrev1DayUasL;
+  u32  flags;
+} atucPerfDataExtEntry; 
+
+#endif
+//ioctl(int fd, GET_ADSL_ATUR_PERF_DATA, void *struct_aturPerfDataEntry)
+
+typedef struct aturPerfDataEntry
+{
+   int                 ifIndex;
+   u32                         adslAturPerfLofs;             
+   u32                         adslAturPerfLoss;             
+   u32                         adslAturPerfLprs;                 
+   u32                         adslAturPerfESs;
+   int                         adslAturPerfValidIntervals;
+   int                         adslAturPerfInvalidIntervals;
+   AdslPerfTimeElapsed         adslAturPerfCurr15MinTimeElapsed;
+   PerfCurrentCount    adslAturPerfCurr15MinLofs;
+   PerfCurrentCount    adslAturPerfCurr15MinLoss;
+   PerfCurrentCount    adslAturPerfCurr15MinLprs;
+   PerfCurrentCount    adslAturPerfCurr15MinESs;
+   AdslPerfTimeElapsed         adslAturPerfCurr1DayTimeElapsed;
+   AdslPerfCurrDayCount adslAturPerfCurr1DayLofs;
+   AdslPerfCurrDayCount adslAturPerfCurr1DayLoss;
+   AdslPerfCurrDayCount adslAturPerfCurr1DayLprs;
+   AdslPerfCurrDayCount adslAturPerfCurr1DayESs;
+   int                         adslAturPerfPrev1DayMoniSecs;
+   AdslPerfPrevDayCount adslAturPerfPrev1DayLofs;
+   AdslPerfPrevDayCount adslAturPerfPrev1DayLoss;
+   AdslPerfPrevDayCount adslAturPerfPrev1DayLprs;
+   AdslPerfPrevDayCount adslAturPerfPrev1DayESs;
+   u32                 flags;
+} aturPerfDataEntry;
+
+#ifdef AMAZON_MEI_MIB_RFC3440
+typedef struct aturPerfDataExtEntry
+ {
+  int ifIndex;
+  u32 adslAturPerfStatSesL;
+  u32 adslAturPerfStatUasL;
+  u32 adslAturPerfCurr15MinSesL;
+  u32 adslAturPerfCurr15MinUasL;
+  u32 adslAturPerfCurr1DaySesL;
+  u32 adslAturPerfCurr1DayUasL;
+  u32 adslAturPerfPrev1DaySesL;
+  u32 adslAturPerfPrev1DayUasL;
+  u32  flags;
+} aturPerfDataExtEntry;
+#endif
+//ioctl(int fd, GET_ADSL_ATUC_INTVL_INFO, void *struct_adslAtucInvtInfo)
+
+typedef struct adslAtucIntvlInfo {
+       int ifIndex;
+        int IntervalNumber;
+       PerfIntervalCount intervalLOF;
+       PerfIntervalCount intervalLOS;
+       PerfIntervalCount intervalES;
+       PerfIntervalCount intervalInits; 
+       int intervalValidData;
+       u8 flags;
+} adslAtucIntvlInfo;
+
+#ifdef AMAZON_MEI_MIB_RFC3440
+typedef struct adslAtucInvtlExtInfo
+ {
+  int ifIndex;
+  int IntervalNumber;
+  u32 adslAtucIntervalFastR;
+  u32 adslAtucIntervalFailedFastR;
+  u32 adslAtucIntervalSesL;
+  u32 adslAtucIntervalUasL;
+  u32  flags;
+} adslAtucInvtlExtInfo;
+#endif
+//ioctl(int fd, GET_ADSL_ATUR_INTVL_INFO, void *struct_adslAturInvtlInfo)
+
+typedef struct adslAturIntvlInfo {
+       int ifIndex;
+        int IntervalNumber;
+       PerfIntervalCount intervalLOF;
+       PerfIntervalCount intervalLOS;
+       PerfIntervalCount intervalLPR;
+       PerfIntervalCount intervalES;
+       int intervalValidData;
+       u8 flags;
+} adslAturIntvlInfo;
+
+#ifdef AMAZON_MEI_MIB_RFC3440
+typedef struct adslAturInvtlExtInfo
+ {
+  int ifIndex;
+  int IntervalNumber;
+  u32 adslAturIntervalSesL;
+  u32 adslAturIntervalUasL;
+  u32  flags;
+} adslAturInvtlExtInfo;
+#endif
+//ioctl(int fd, GET_ADSL_ATUC_CHAN_PERF_DATA,  void *struct_atucChannelPerfDataEntry)
+
+typedef struct atucChannelPerfDataEntry
+{
+   int                 ifIndex;
+   u32                         adslAtucChanReceivedBlks;             
+   u32                         adslAtucChanTransmittedBlks;             
+   u32                         adslAtucChanCorrectedBlks;                 
+   u32                         adslAtucChanUncorrectBlks;
+   int                         adslAtucChanPerfValidIntervals;
+   int                         adslAtucChanPerfInvalidIntervals;
+   AdslPerfTimeElapsed         adslAtucChanPerfCurr15MinTimeElapsed;
+   PerfCurrentCount    adslAtucChanPerfCurr15MinReceivedBlks;
+   PerfCurrentCount    adslAtucChanPerfCurr15MinTransmittedBlks;
+   PerfCurrentCount    adslAtucChanPerfCurr15MinCorrectedBlks;
+   PerfCurrentCount    adslAtucChanPerfCurr15MinUncorrectBlks;
+   AdslPerfTimeElapsed  adslAtucChanPerfCurr1DayTimeElapsed;
+   AdslPerfCurrDayCount adslAtucChanPerfCurr1DayReceivedBlks;
+   AdslPerfCurrDayCount adslAtucChanPerfCurr1DayTransmittedBlks;
+   AdslPerfCurrDayCount adslAtucChanPerfCurr1DayCorrectedBlks;
+   AdslPerfCurrDayCount adslAtucChanPerfCurr1DayUncorrectBlks;
+   int                  adslAtucChanPerfPrev1DayMoniSecs;
+   AdslPerfPrevDayCount adslAtucChanPerfPrev1DayReceivedBlks;
+   AdslPerfPrevDayCount adslAtucChanPerfPrev1DayTransmittedBlks;
+   AdslPerfPrevDayCount adslAtucChanPerfPrev1DayCorrectedBlks;
+   AdslPerfPrevDayCount adslAtucChanPerfPrev1DayUncorrectBlks;
+   u32                 flags;
+}atucChannelPerfDataEntry;
+
+
+//ioctl(int fd, GET_ADSL_ATUR_CHAN_PERF_DATA,  void *struct_aturChannelPerfDataEntry)
+
+typedef struct aturChannelPerfDataEntry
+{
+   int                 ifIndex;
+   u32                         adslAturChanReceivedBlks;             
+   u32                         adslAturChanTransmittedBlks;             
+   u32                         adslAturChanCorrectedBlks;                 
+   u32                         adslAturChanUncorrectBlks;
+   int                         adslAturChanPerfValidIntervals;
+   int                         adslAturChanPerfInvalidIntervals;
+   AdslPerfTimeElapsed         adslAturChanPerfCurr15MinTimeElapsed;
+   PerfCurrentCount    adslAturChanPerfCurr15MinReceivedBlks;
+   PerfCurrentCount    adslAturChanPerfCurr15MinTransmittedBlks;
+   PerfCurrentCount    adslAturChanPerfCurr15MinCorrectedBlks;
+   PerfCurrentCount    adslAturChanPerfCurr15MinUncorrectBlks;
+   AdslPerfTimeElapsed  adslAturChanPerfCurr1DayTimeElapsed;
+   AdslPerfCurrDayCount adslAturChanPerfCurr1DayReceivedBlks;
+   AdslPerfCurrDayCount adslAturChanPerfCurr1DayTransmittedBlks;
+   AdslPerfCurrDayCount adslAturChanPerfCurr1DayCorrectedBlks;
+   AdslPerfCurrDayCount adslAturChanPerfCurr1DayUncorrectBlks;
+   int                  adslAturChanPerfPrev1DayMoniSecs;
+   AdslPerfPrevDayCount adslAturChanPerfPrev1DayReceivedBlks;
+   AdslPerfPrevDayCount adslAturChanPerfPrev1DayTransmittedBlks;
+   AdslPerfPrevDayCount adslAturChanPerfPrev1DayCorrectedBlks;
+   AdslPerfPrevDayCount adslAturChanPerfPrev1DayUncorrectBlks;
+   u32                 flags;
+} aturChannelPerfDataEntry;
+
+
+//ioctl(int fd, GET_ADSL_ATUC_CHAN_INTVL_INFO, void *struct_adslAtucChanIntvlInfo)
+
+typedef struct adslAtucChanIntvlInfo {
+       int ifIndex;
+        int IntervalNumber;
+       PerfIntervalCount chanIntervalRecvdBlks;
+       PerfIntervalCount chanIntervalXmitBlks;
+       PerfIntervalCount chanIntervalCorrectedBlks;
+       PerfIntervalCount chanIntervalUncorrectBlks;
+       int intervalValidData;
+       u8 flags;
+} adslAtucChanIntvlInfo;
+
+
+//ioctl(int fd, GET_ADSL_ATUR_CHAN_INTVL_INFO, void *struct_adslAturChanIntvlInfo)
+
+typedef struct adslAturChanIntvlInfo {
+       int ifIndex;
+        int IntervalNumber;
+       PerfIntervalCount chanIntervalRecvdBlks;
+       PerfIntervalCount chanIntervalXmitBlks;
+       PerfIntervalCount chanIntervalCorrectedBlks;
+       PerfIntervalCount chanIntervalUncorrectBlks;
+       int intervalValidData;
+       u8 flags;
+} adslAturChanIntvlInfo;
+
+
+//ioctl(int fd, GET_ADSL_ALRM_CONF_PROF,  void *struct_adslLineAlarmConfProfileEntry)
+//ioctl(int fd, SET_ADSL_ALRM_CONF_PROF,  void *struct_adslLineAlarmConfProfileEntry)
+
+typedef struct  adslLineAlarmConfProfileEntry
+ {
+  unsigned char adslLineAlarmConfProfileName[32];
+    int        adslAtucThresh15MinLofs;
+    int        adslAtucThresh15MinLoss;
+    int        adslAtucThresh15MinESs;
+    u32        adslAtucThreshFastRateUp;
+    u32        adslAtucThreshInterleaveRateUp;
+    u32        adslAtucThreshFastRateDown;
+    u32        adslAtucThreshInterleaveRateDown;
+    int        adslAtucInitFailureTrapEnable;
+    int        adslAturThresh15MinLofs;
+    int        adslAturThresh15MinLoss;
+    int        adslAturThresh15MinLprs;
+    int        adslAturThresh15MinESs;
+    u32        adslAturThreshFastRateUp;
+    u32        adslAturThreshInterleaveRateUp;
+    u32        adslAturThreshFastRateDown;
+    u32        adslAturThreshInterleaveRateDown;
+    int        adslLineAlarmConfProfileRowStatus;
+    u32        flags;
+} adslLineAlarmConfProfileEntry;
+
+#ifdef AMAZON_MEI_MIB_RFC3440
+typedef struct adslLineAlarmConfProfileExtEntry
+ {
+  u8  adslLineAlarmConfProfileExtName[32];
+  u32 adslAtucThreshold15MinFailedFastR;
+  u32 adslAtucThreshold15MinSesL;
+  u32 adslAtucThreshold15MinUasL;
+  u32 adslAturThreshold15MinSesL;
+  u32 adslAturThreshold15MinUasL;
+  u32  flags;
+} adslLineAlarmConfProfileExtEntry;
+#endif
+//TRAPS
+
+// 603221:tc.chen start
+/* The following Data Sturctures are added to support the WEB related parameters for ADSL Statistics */
+typedef struct  adslLineStatus
+ {
+    int        adslModemStatus;
+    u32        adslModeSelected;
+    int        adslAtucThresh15MinESs;
+    int        adslTrellisCodeEnable;
+    int        adslLatency;
+    u8 flags;
+ } adslLineStatusInfo;
+
+typedef struct  adslLineRate
+ {
+    u32        adslDataRateds;
+    u32        adslDataRateus;
+    u32        adslATTNDRds;   
+    u32        adslATTNDRus;   
+    u8         flags;
+ } adslLineRateInfo;
+
+typedef struct  adslLineInfo
+ {
+    u32        adslInterleaveDepthds;
+    u32        adslInterleaveDepthus;
+    u32        adslLATNds;
+    u32        adslLATNus;
+    u32        adslSATNds;
+    u32        adslSATNus;
+    int                adslSNRMds;
+    int                adslSNRMus;
+    int                adslACATPds;
+    int                adslACATPus;
+    u32        flags;
+ } adslLineInfo;
+
+typedef struct  adslNearEndPerfStats
+ {
+    u32        adslSuperFrames; 
+    u32        adslneLOS;
+    u32        adslneLOF;
+    u32        adslneLPR;
+    u32        adslneNCD;
+    u32        adslneLCD;
+    u32        adslneCRC;
+    u32                adslneRSCorr;
+    u32                adslneFECS;
+    u32                adslneES;
+    u32                adslneSES;
+    u32                adslneLOSS;
+    u32                adslneUAS;
+    u32                adslneHECErrors;
+    u32                flags;
+ } adslNearEndPerfStats;
+
+typedef struct  adslFarEndPerfStats
+ {
+    u32        adslfeLOS;
+    u32        adslfeLOF;
+    u32        adslfeLPR;
+    u32        adslfeNCD;
+    u32        adslfeLCD;
+    u32        adslfeCRC;
+    u32                adslfeRSCorr;
+    u32                adslfeFECS;
+    u32                adslfeES;
+    u32                adslfeSES;
+    u32                adslfeLOSS;
+    u32                adslfeUAS;
+    u32                adslfeHECErrors;
+    u32                flags;
+ } adslFarEndPerfStats;
+// 603221:tc.chen end
+
+/* The number of tones (and hence indexes) is dependent on the ADSL mode - G.992.1, G.992.2, G.992.3, * G.992.4 and G.992.5 */
+typedef struct adslATURSubcarrierInfo {
+       int     ifindex;
+       u16     HLINSCds;
+       u16     HLINpsds[1024];/* Even index = real part; Odd Index
+                                   = imaginary part for each tone */
+       u16     HLOGMTds;
+       u16     HLOGpsds[512];
+       u16     QLNMTds;
+       u16     QLNpsds[512];
+       u16     SNRMTds;
+       u16     SNRpsds[512];  
+       u16     BITpsds[512];
+       u16     GAINpsds[512];
+       u16     flags;
+}adslATURSubcarrierInfo;
+
+typedef struct adslATUCSubcarrierInfo {
+       int     ifindex;
+       u16     HLINSCus;
+       u16     HLINpsus[128];/* Even index = real part; Odd Index
+                                   = imaginary part for each tone */
+       u16     HLOGMTus;
+       u16     HLOGpsus[64];
+       u16     QLNMTus;
+       u16     QLNpsus[64]; 
+       u16     SNRMTus;
+       u16     SNRpsus[64];  
+       u16     BITpsus[64];
+       u16     GAINpsus[64];
+       u16     flags;
+}adslATUCSubcarrierInfo;
+
+#ifndef u_int16
+#define u_int16 u16
+#endif
+
+typedef struct adslInitStats {
+       u_int16 FullInitializationCount;
+       u_int16 FailedFullInitializationCount;
+       u_int16 LINIT_Errors;
+       u_int16 Init_Timeouts;
+}adslInitStats;
+
+typedef struct adslPowerSpectralDensity {
+       int     ACTPSDds;
+       int     ACTPSDus;
+}adslPowerSpectralDensity;
+
+
+//ioctl(int fd, ADSL_ATUR_TRAPS, void  *uint16_flags)
+typedef union structpts {
+       adslLineTableEntry * adslLineTableEntry_pt;
+       adslAtucPhysEntry * adslAtucPhysEntry_pt;
+       adslAturPhysEntry * adslAturPhysEntry_pt;
+       adslAtucChanInfo * adslAtucChanInfo_pt;
+       adslAturChanInfo * adslAturChanInfo_pt;
+       atucPerfDataEntry * atucPerfDataEntry_pt;
+       aturPerfDataEntry * aturPerfDataEntry_pt;
+       adslAtucIntvlInfo * adslAtucIntvlInfo_pt;
+       adslAturIntvlInfo * adslAturIntvlInfo_pt;
+       atucChannelPerfDataEntry * atucChannelPerfDataEntry_pt;
+       aturChannelPerfDataEntry * aturChannelPerfDataEntry_pt;
+       adslAtucChanIntvlInfo * adslAtucChanIntvlInfo_pt;
+       adslAturChanIntvlInfo * adslAturChanIntvlInfo_pt;
+       adslLineAlarmConfProfileEntry * adslLineAlarmConfProfileEntry_pt;
+       // RFC 3440
+       
+    #ifdef AMAZON_MEI_MIB_RFC3440
+       adslLineExtTableEntry * adslLineExtTableEntry_pt;
+       atucPerfDataExtEntry * atucPerfDataExtEntry_pt;
+       adslAtucInvtlExtInfo * adslAtucInvtlExtInfo_pt;
+       aturPerfDataExtEntry * aturPerfDataExtEntry_pt;
+       adslAturInvtlExtInfo * adslAturInvtlExtInfo_pt;
+       adslLineAlarmConfProfileExtEntry * adslLineAlarmConfProfileExtEntry_pt;
+    #endif 
+// 603221:tc.chen start
+       adslLineStatusInfo      * adslLineStatusInfo_pt;
+       adslLineRateInfo        * adslLineRateInfo_pt;
+       adslLineInfo            * adslLineInfo_pt;
+       adslNearEndPerfStats    * adslNearEndPerfStats_pt;
+       adslFarEndPerfStats     * adslFarEndPerfStats_pt;
+// 603221:tc.chen end
+       adslATUCSubcarrierInfo  * adslATUCSubcarrierInfo_pt;
+       adslATURSubcarrierInfo  * adslATURSubcarrierInfo_pt;
+       adslPowerSpectralDensity * adslPowerSpectralDensity_pt;
+}structpts;
+
+#endif /* ] __AMAZON_MEI_APP_IOCTL_H */
diff --git a/target/linux/amazon-2.6/files/include/asm-mips/amazon/amazon_mei_ioctl.h b/target/linux/amazon-2.6/files/include/asm-mips/amazon/amazon_mei_ioctl.h
new file mode 100644 (file)
index 0000000..02a150e
--- /dev/null
@@ -0,0 +1,757 @@
+//509221:tc.chen 2005/09/22 Reset DFE added when MEI_TO_ARC_CS_DONE not cleared by ARC and Added AMAZON_MEI_DEBUG_MODE ioctl 
+#ifndef         _AMAZON_MEI_IOCTL_H
+#define                _AMAZON_MEI_IOCTL_H
+
+/////////////////////////////////////////////////////////////////////////////////////////////////////
+#define PCM_BUFF_SIZE          1024 //bytes
+//  interrupt numbers
+
+#ifndef                _AMAZON_ADSL_APP
+
+typedef struct pcm_data_struct{
+       u16 S;
+       u16 temp;
+       u16 LSW;
+       u16 MSW;
+       u16 len;
+       u16 rdindex;
+       u16 wrindex;
+       u16 flow;
+       
+       int finish;
+       u8 buff[PCM_BUFF_SIZE]; 
+       int point;
+}pcm_data_struct;
+
+typedef struct amazon_clreoc_pkt{
+       struct list_head list;
+       u8 * command;           //point to clreoc command data
+       int len;                //command length
+}amazon_clreoc_pkt;
+
+// Number of intervals
+#define INTERVAL_NUM                                   192 //two days
+typedef struct amazon_mei_mib{
+       struct list_head list;
+       struct timeval start_time;      //start of current interval
+       
+       int AtucPerfLof;
+       int AtucPerfLos;
+       int AtucPerfEs;
+       int AtucPerfInit;
+       
+       int AturPerfLof;
+       int AturPerfLos;
+       int AturPerfLpr;
+       int AturPerfEs;
+       
+       int AturChanPerfRxBlk;
+       int AturChanPerfTxBlk;
+       int AturChanPerfCorrBlk;
+       int AturChanPerfUncorrBlk;
+       
+       //RFC-3440
+       int AtucPerfStatFastR;
+       int AtucPerfStatFailedFastR;
+       int AtucPerfStatSesL;
+       int AtucPerfStatUasL;
+       int AturPerfStatSesL;
+       int AturPerfStatUasL;
+}amazon_mei_mib;
+
+typedef struct adslChanPrevTxRate{
+       u32 adslAtucChanPrevTxRate;
+       u32 adslAturChanPrevTxRate;
+}adslChanPrevTxRate;
+
+typedef struct adslPhysCurrStatus{
+       u32 adslAtucCurrStatus;
+       u32 adslAturCurrStatus;
+}adslPhysCurrStatus;
+
+typedef struct ChanType{
+       int interleave;
+       int fast;
+// 603221:tc.chen start
+       int bearchannel0;
+       int bearchannel1;
+// 603221:tc.chen end
+}ChanType;
+
+typedef struct mib_previous_read{
+       u16 ATUC_PERF_ESS;
+       u16 ATUR_PERF_ESS;
+       u32 ATUR_CHAN_RECV_BLK;
+       u16 ATUR_CHAN_CORR_BLK_INTL;
+       u16 ATUR_CHAN_CORR_BLK_FAST;
+       u16 ATUR_CHAN_UNCORR_BLK_INTL;
+       u16 ATUR_CHAN_UNCORR_BLK_FAST;
+       u16 ATUC_PERF_STAT_FASTR;
+       u16 ATUC_PERF_STAT_FAILED_FASTR;
+       u16 ATUC_PERF_STAT_SESL;
+       u16 ATUC_PERF_STAT_UASL;
+       u16 ATUR_PERF_STAT_SESL;
+}mib_previous_read;
+
+typedef struct mib_flags_pretime{
+       struct timeval ATUC_PERF_LOSS_PTIME;
+       struct timeval ATUC_PERF_LOFS_PTIME;
+       struct timeval ATUR_PERF_LOSS_PTIME;
+       struct timeval ATUR_PERF_LOFS_PTIME;
+       struct timeval ATUR_PERF_LPR_PTIME;
+}mib_flags_pretime;
+
+                //  cmv message structures
+#define        MP_PAYLOAD_SIZE                                 12
+typedef        struct mpmessage{
+       u16     iFunction;
+       u16     iGroup;
+       u16     iAddress;
+       u16     iIndex;
+       u16     iPayload[MP_PAYLOAD_SIZE];
+}MPMessage;
+#endif
+
+
+typedef struct meireg{
+       u32 iAddress;
+       u32 iData;
+}meireg;
+
+#define MEIDEBUG_BUFFER_SIZES 50
+typedef struct meidebug{
+       u32 iAddress;
+       u32 iCount;
+       u32 buffer[MEIDEBUG_BUFFER_SIZES];
+}meidebug;
+
+//==============================================================================
+// Group definitions                                                              
+//==============================================================================
+#define OPTN                    5
+#define CNFG                    8
+#define CNTL                    1
+#define STAT                    2
+#define RATE                    6
+#define PLAM                    7
+#define INFO                    3
+#define TEST                   4
+//==============================================================================
+// Opcode definitions
+//==============================================================================
+#define H2D_CMV_READ                            0x00
+#define H2D_CMV_WRITE                           0x04
+#define H2D_CMV_INDICATE_REPLY                  0x10
+#define H2D_ERROR_OPCODE_UNKNOWN               0x20
+#define H2D_ERROR_CMV_UNKNOWN                  0x30
+
+#define D2H_CMV_READ_REPLY                             0x01
+#define D2H_CMV_WRITE_REPLY                     0x05
+#define D2H_CMV_INDICATE                        0x11
+#define D2H_ERROR_OPCODE_UNKNOWN                0x21
+#define D2H_ERROR_CMV_UNKNOWN                   0x31
+#define D2H_ERROR_CMV_READ_NOT_AVAILABLE        0x41
+#define D2H_ERROR_CMV_WRITE_ONLY                0x51
+#define D2H_ERROR_CMV_READ_ONLY                 0x61
+
+#define H2D_DEBUG_READ_DM                       0x02
+#define H2D_DEBUG_READ_PM                       0x06
+#define H2D_DEBUG_WRITE_DM                      0x0a
+#define H2D_DEBUG_WRITE_PM                      0x0e
+
+#define D2H_DEBUG_READ_DM_REPLY                0x03
+#define D2H_DEBUG_READ_FM_REPLY                0x07
+#define D2H_DEBUG_WRITE_DM_REPLY               0x0b
+#define D2H_DEBUG_WRITE_FM_REPLY               0x0f
+#define D2H_ERROR_ADDR_UNKNOWN                 0x33
+
+#define D2H_AUTONOMOUS_MODEM_READY_MSG         0xf1
+//==============================================================================
+// INFO register address field definitions
+//==============================================================================
+
+#define INFO_TxState                                   0
+#define INFO_RxState                                   1
+#define INFO_TxNextState                               2
+#define INFO_RxNextState                               3
+#define INFO_TxStateJumpFrom                           4
+#define INFO_RxStateJumpFrom                           5
+
+#define INFO_ReverbSnrBuf                              8
+#define INFO_ReverbEchoSnrBuf                          9
+#define INFO_MedleySnrBuf                              10
+#define INFO_RxShowtimeSnrBuf                          11
+#define INFO_DECdelay                                  12
+#define INFO_DECExponent                               13
+#define INFO_DECTaps                                   14
+#define INFO_AECdelay                                  15
+#define INFO_AECExponent                               16
+#define INFO_AECTaps                                   17
+#define INFO_TDQExponent                               18
+#define INFO_TDQTaps                                   19
+#define INFO_FDQExponent                               20
+#define INFO_FDQTaps                                   21
+#define INFO_USBat                                     22
+#define INFO_DSBat                                     23
+#define INFO_USFineGains                               24
+#define INFO_DSFineGains                               25
+#define INFO_BitloadFirstChannel                       26
+#define INFO_BitloadLastChannel                                27
+#define INFO_PollEOCData                               28              // CO specific
+#define INFO_CSNRMargin                                        29              // CO specific
+#define INFO_RCMsgs1                                   30
+#define INFO_RMsgs1                                    31
+#define INFO_RMsgRA                                    32
+#define INFO_RCMsgRA                                   33
+#define INFO_RMsg2                                     34
+#define INFO_RCMsg2                                    35
+#define INFO_BitLoadOK                                 36
+#define INFO_RCRates1                                  37
+#define INFO_RRates1Tab                                        38
+#define INFO_RMsgs1Tab                                 39
+#define INFO_RMsgRATab                                 40
+#define INFO_RRatesRA                                  41
+#define INFO_RCRatesRA                                 42
+#define INFO_RRates2                                   43
+#define INFO_RCRates2                                  44
+#define INFO_PackedRMsg2                               45
+#define INFO_RxBitSwapFlag                             46
+#define INFO_TxBitSwapFlag                             47
+#define INFO_ShowtimeSNRUpdateCount                    48
+#define INFO_ShowtimeFDQUpdateCount                    49
+#define INFO_ShowtimeDECUpdateCount                    50
+#define INFO_CopyRxBuffer                              51
+#define INFO_RxToneBuf                                 52
+#define INFO_TxToneBuf                                  53
+#define INFO_Version                                   54
+#define INFO_TimeStamp                                  55
+#define INFO_feVendorID                                        56
+#define INFO_feSerialNum                               57
+#define INFO_feVersionNum                              58
+#define INFO_BulkMemory                                        59      //Points to start of bulk memory
+#define INFO_neVendorID                                 60
+#define INFO_neVersionNum                              61
+#define INFO_neSerialNum                               62
+
+//==============================================================================
+// RATE register address field definitions
+//==============================================================================
+
+
+#define RATE_UsRate                                    0
+#define RATE_DsRate                                    1
+
+
+//==============================================================================
+// PLAM (Physical Layer Management) register address field definitions
+//     (See G997.1 for reference)
+//==============================================================================
+
+
+       //                                      ///
+       // Failure Flags        ///
+       //                                      ///
+
+#define PLAM_NearEndFailureFlags               0
+#define PLAM_FarEndFailureFlags                        1
+
+       //                                                                      ///
+       // Near End Failure Flags Bit Definitions       ///
+       //                                                                      ///
+
+// ADSL Failures ///
+#define PLAM_LOS_FailureBit                            0x0001
+#define PLAM_LOF_FailureBit                            0x0002
+#define PLAM_LPR_FailureBit                            0x0004
+#define PLAM_RFI_FailureBit                            0x0008
+
+// ATM Failures ///
+#define PLAM_NCD_LP0_FailureBit                                0x0010
+#define PLAM_NCD_LP1_FailureBit                                0x0020
+#define PLAM_LCD_LP0_FailureBit                                0x0040
+#define PLAM_LCD_LP1_FailureBit                                0x0080
+
+#define PLAM_NCD_BC0_FailureBit                                0x0100
+#define PLAM_NCD_BC1_FailureBit                                0x0200
+#define PLAM_LCD_BC0_FailureBit                                0x0400
+#define PLAM_LCD_BC1_FailureBit                                0x0800
+       //                                              ///
+       // Performance Counts   ///
+       //                                              ///
+
+#define PLAM_NearEndCrcCnt                             2
+#define PLAM_CorrectedRSErrors                         3
+
+#define PLAM_NearEndECSCnt                             6
+#define PLAM_NearEndESCnt                              7
+#define PLAM_NearEndSESCnt                             8
+#define PLAM_NearEndLOSSCnt                            9
+#define PLAM_NearEndUASLCnt                            10
+
+#define PLAM_NearEndHECErrCnt                          11
+
+#define PLAM_NearEndHECTotCnt                          16
+#define PLAM_NearEndCellTotCnt                         18
+#define PLAM_NearEndSfCntLSW                           20
+#define PLAM_NearEndSfCntMSW                           21
+
+#define PLAM_FarEndFebeCnt                             24
+
+#define PLAM_FarEndFecCnt                              28
+
+#define PLAM_FarEndFECSCnt                             32
+#define PLAM_FarEndESCnt                               33
+#define PLAM_FarEndSESCnt                              34
+#define PLAM_FarEndLOSSCnt                             35
+#define PLAM_FarEndUASLCnt                             36
+
+#define PLAM_FarEndHECErrCnt                           37
+
+#define PLAM_FarEndHECTotCnt                           41
+
+#define PLAM_FarEndCellTotCnt                          43
+
+#define PLAM_LineAttn                                  45
+#define PLAM_SNRMargin                                 46
+
+
+//==============================================================================
+// CNTL register address and bit field definitions
+//==============================================================================
+
+
+#define CNTL_ModemControl                              0
+
+#define CNTL_ModemReset                                        0x0
+#define CNTL_ModemStart                                        0x2
+
+
+//==============================================================================
+// STAT register address and bit field definitions
+//==============================================================================
+
+#define STAT_MacroState                                        0
+#define STAT_Mode                                      1
+#define STAT_DMTFramingMode                            2
+#define STAT_SleepState                                        3
+#define STAT_Misc                                      4
+#define STAT_FailureState                              5
+
+////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+ // STAT_OLRStatus provides status of OLR
+ //16-bit STAT_OLRStatus_DS
+ //  [1:0]     :       OLR status 00=IDLE,  01=OLR_IN_PROGRESS, 10=OLR_Completed, 11=OLR_Aborted
+ //  [3:2]:            Reserved
+ //  [5:4]:            OLR_Type (1:bitswap; 2: DRR; 3: SRA)
+ //  [7:6]:            Reserved
+ //  [10:8]:           >0=Request. 0=not.   For DS, # of request transmissions/retransmissions (3 bits).
+ //  [11]:             1=Receive Response, 0=not
+ //  [15:12]:  Reserved
+ //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+ ///
+#define STAT_OLRStatus_DS                              6
+
+////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+ // STAT_OLRStatus provides status of OLR
+ // 16-bit STAT_OLRStatus_US CMV
+ //  [1:0]     :       OLR status 00=IDLE,  01=OLR_IN_PROGRESS, 10=OLR_Completed, 11=OLR_Aborted
+ //  [3:2]:            Reserved
+ //  [5:4]:            OLR_Type (1:bitswap; 2: DRR; 3: SRA)
+ //  [7:6]:            Reserved
+ //  [8]:              1=Request Received. 0=not.
+ //  [10:9]:     Reserved
+ //  [11]:             1=Response Sent, 0=not
+ //  [15:12]:  Reserved
+ //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+///
+#define STAT_OLRStatus_US                              7
+
+////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+ // STAT_PMStatus provides status of PM
+ // 16-bit STAT_PMStatus CMV
+ //  [1:0]     :       PM Status 00=IDLE,  01=PM_IN_PROGRESS, 10=PM_Completed, 11=PM_Aborted
+ //  [2] :             0=ATU_R initiated PM; 1 = ATU_C initiated PM
+ //  [3]:              Reserved
+ //  [5:4]:            PM_Type (1:Simple Request; 2: L2 request; 3: L2 trim)
+ //  [7:6]:            Reserved
+ //  [10:8]:           >0=Request. 0=not.   # of request transmissions/retransmissions (3 bits).
+ //  [11]:             1=Response, 0=not
+ //  [15:12]:  Reserved
+ //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+ ///
+#define STAT_PMStatus                                  8
+
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+ // 16-bit STAT_OLRError_DS, STAT_OLRError_US, STAT_PMError
+ // [3:0]:          OLR/PM response reason code
+ // [7:4]:            OLR/PM Internal error code
+ // [15:8]:         OLR/PM Reserved for future
+ //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+ ///
+#define STAT_OLRError_DS                               9
+#define STAT_OLRError_US                               10
+#define STAT_PMError                                   11
+
+
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+// STAT_MacroState
+// MacroState reflects the high level state of the modem
+
+#define STAT_InitState                         0x0000
+#define STAT_ReadyState                                0x0001
+#define STAT_FailState                         0x0002
+#define STAT_IdleState                         0x0003
+#define STAT_QuietState                                0x0004
+#define STAT_GhsState                          0x0005
+#define STAT_FullInitState                     0x0006
+#define STAT_ShowTimeState                     0x0007
+#define STAT_FastRetrainState                  0x0008
+#define STAT_LoopDiagMode                      0x0009
+#define STAT_ShortInit                         0x000A     // Bis short initialization ///
+
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+// STAT_Mode
+// ConfigurationMode indicates the mode of the current ADSL Link. In general, a modem may use
+// G.Hs or some other mechanism to negotiate the specific mode of operation.
+// The OPTN_modeControl CMV is used to select a set of desired modes.
+// The STAT_Mode CMV indicates which mode was actually selected.
+
+#define STAT_ConfigMode_T1413                  0x0001
+#define STAT_ConfigMode_G992_2_AB              0x0002
+#define STAT_ConfigMode_G992_1_A               0x0004
+#define STAT_ConfigMode_G992_1_B               0x0008
+#define STAT_ConfigMode_G992_1_C               0x0010
+#define STAT_ConfigMode_G992_2_C               0x0020
+
+#define STAT_ConfigMode_G992_3_A               0x0100
+#define STAT_ConfigMode_G992_3_B               0x0200
+#define STAT_ConfigMode_G992_3_I               0x0400
+#define STAT_ConfigMode_G992_3_J               0x0800
+#define STAT_ConfigMode_G992_3_L               0x1000
+
+#define STAT_ConfigMode_G992_4_A               0x2000
+#define STAT_ConfigMode_G992_4_I               0x4000
+
+#define STAT_ConfigMode_G992_5                 0x8000
+
+
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+// STAT_DMTFramingMode
+// FramingMode indicates the DMT framing mde negotiated during initialization. The framing mode
+// status is not applicable in BIS mode and its value is undefined
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+#define STAT_FramingModeMask                   0x0003
+
+
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+// STAT_Misc
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+#define STAT_OverlappedSpectrum                0x0008
+#define STAT_TCM                       0x0010
+#define STAT_TDQ_at_1104               0x0020
+#define STAT_T1413_Signal_Detected     0x0040
+#define STAT_AnnexL_US_Mask1_PSD       0x1000  //indicate we actually selected G992.3 AnnexL US PSD mask1
+#define STAT_AnnexL_US_Mask2_PSD       0x2000  //indicate we actually selected G992.3 AnnexL US PSD mask2
+
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+// STAT_FailureState
+// when the MacroSTate indicates the fail state, FailureState provides a failure code
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+
+#define E_CODE_NO_ERROR                                                                0
+#define E_CODE_BAT_TX                                                          1               // TX BAT table is incorrect */
+#define E_CODE_BAT_RX                                                          2               //  RX BAT table is incorrect */
+#define E_CODE_PROFILE                                                         3               //  profile is not selected in fast retrain */
+#define E_CODE_TX_AOC_FIFO_OVERFLOW                                            4
+#define E_CODE_TRUNCATE_FR                                                     5               //Fast Retrain truncated due to no stored profiles*/
+#define E_CODE_BITLOAD                                                         6               //  bit loading fails */
+#define E_CODE_ST_ERROR                                                                7               //  showtime CRC error */
+#define E_CODE_RESERVED                                                                8       //  using parameters reserved by the ITU-T */
+#define E_CODE_C_TONES                                                         9               //  detected C_TONES */
+#define E_CODE_CODESWAP_ERR                                                    10      //  codeswap not finished in time */
+#define E_CODE_FIFO_OVERFLOW                                                   11      // we have run out of fifo space */
+#define E_CODE_C_BG_DECODE_ERR                                                 12      // error in decoding C-BG message */
+#define E_CODE_C_RATES2_DECODE_ERR                                             13      // error in decoding C-MSGS2 and C-RATES2 */
+#define E_CODE_RCMedleyRx_C_SEGUE2_Failure                                     14              //  Timeout after RCMedleyRx waiting for C_SEGUE2 */
+#define E_CODE_RReverbRATx_C_SEGUE2_Failure                                    15              //  Timeout after RReverbRATx waiting for C_SEGUE2 */
+#define E_CODE_RReverb3Tx_C_SEGUE1_Failure                                     16              //  Timeout after RReverb3Tx waiting for C_SEGUE1 */
+#define E_CODE_RCCRC2Rx_C_RATES1_DECOD_ERR                                     17              //  Received CRC not equal to computed CRC */
+#define E_CODE_RCCRC1Rx_C_RATES1_DECOD_ERR                                     18              //  Received CRC not equal to computed CRC */
+#define E_CODE_RReverb5Tx_C_SEGUE2_Failure                                     19              //  Timeout after RReverb5Tx waiting for C_SEGUE2 */
+#define E_CODE_RReverb6Tx_C_SEGUE3_Failure                                     20              //  Timeout after RReverb6Tx waiting for C_SEGUE3 */
+#define E_CODE_RSegue5Tx_C_SEGUE3_Failure                                      21              //  Timeout after RSegue5Tx waiting for C_SEGUE3 */
+#define E_CODE_RCReverb5Rx_C_SEGUE_Failure                                     22              //  Timeout after RCReverb5Rx waiting for C_SEGUE */
+#define E_CODE_RCReverbRARx_C_SEGUE2_Failure                                   23              //  Timeout after RCReverbRARx waiting for C_SEGUE2 */
+#define E_CODE_RCCRC4Rx_CMSGS2_DECOD_ERR                                       24              //  Received CRC not equal to computed CRC */
+#define E_CODE_RCCRC5Rx_C_BG_DECOD_ERR                                         25              //  Received CRC not equal to computed CRC */
+#define E_CODE_RCCRC3Rx_DECOD_ERR                                              26              //  Received CRC not equal to computed CRC */
+#define E_CODE_RCPilot3_DEC_PATH_DEL_TIMEOUT                                   27              //  DEC Path Delay timeout */
+#define E_CODE_RCPilot3_DEC_TRAINING_TIMEOUT                                   28              //  DEC Training timeout */
+#define E_CODE_RCReverb3Rx_C_SEGUE1_Failure                                    29              //  Timeout after RCReverb3Rx waiting for C_SEGUE1 */
+#define E_CODE_RCReverb2Rx_SignalEnd_Failure                                   30              //  Timeout waiting for the end of RCReverb2Rx signal */
+#define E_CODE_RQuiet2_SignalEnd_Failure                                       31              //  Timeout waiting for the end of RQuiet2 signal */
+#define E_CODE_RCReverbFR1Rx_Failure                                           32              //  Timeout waiting for the end of RCReverbFR1Rx signal */
+#define E_CODE_RCPilotFR1Rx_SignalEnd_Failure                                  33              //  Timeout waiting for the end of RCPilotFR1Rx signal */
+#define E_CODE_RCReverbFR2Rx_C_Segue_Failure                                   34              //  Timeout after RCReverbFR2Rx waiting for C_SEGUE */
+#define E_CODE_RCReverbFR5Rx_SignalEnd_TIMEOUT                                 35              //  Timeout waiting for the end of RCReverbFR5Rx signal */
+#define E_CODE_RCReverbFR6Rx_C_SEGUE_Failure                                   36              //  Timeout after RCReverbFR6Rx waiting for C_SEGUE */
+#define E_CODE_RCReverbFR8Rx_C_SEGUE_FR4_Failure                               37              //  Timeout after RCReverbFR8Rx waiting for C_SEGUE_FR4 */
+#define E_CODE_RCReverbFR8Rx_No_PROFILE                                                38              //  Timeout since no profile was selected */
+#define E_CODE_RCReverbFR8Rx_SignalEnd_TIMEOUT                                 39              //  Timeout waiting for the end of RCReverbFR8Rx signal */
+#define E_CODE_RCCRCFR1_DECOD_ERR                                              40              //  Received CRC not equal to computed CRC */
+#define E_CODE_RCRecovRx_SingnalEnd_TIMEOUT                                    41              //  Timeout waiting for the end of RCRecovRx signal */
+#define E_CODE_RSegueFR5Tx_TX_Not_Ready_TIMEOUT                                        42              //  Timeout after RSegueFR5Tx waiting for C_SEGUE2 */
+#define E_CODE_RRecovTx_SignalEnd_TIMEOUT                                      43              //  Timeout waiting for the end of RRecovTx signal */
+#define E_CODE_RCMedleyFRRx_C_SEGUE2_Failure                                   44              //  Timeout after RCMedleyFRRx waiting for C_SEGUE2 */
+#define E_CODE_CONFIGURATION_PARAMETERS_ERROR                                  45              // one of the configuration parameters do not meet the standard */
+#define E_CODE_BAD_MEM_ACCESS                                                  46
+#define E_CODE_BAD_INSTRUCTION_ACCESS                                          47
+#define E_CODE_TX_EOC_FIFO_OVERFLOW                                            48
+#define E_CODE_RX_EOC_FIFO_OVERFLOW                                            49
+#define E_CODE_GHS_CD_FLAG_TIME_OUT                                            50      // Timeout when transmitting Flag in handshake cleardown */
+
+
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+//STAT_OLRStatus:
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+#define STAT_OLRPM_IDLE                                 0x0000
+#define STAT_OLRPM_IN_PROGRESS                          0x0001
+#define STAT_OLRPM_COMPLETE                             0x0002
+#define STAT_OLRPM_ABORTED                              0x0003
+#define STAT_OLRPM_RESPONSE                            0x0800
+
+#define STAT_OLR_BITSWAP                                0x0010
+#define STAT_OLR_DRR                                   0x0020
+#define STAT_OLR_SRA                                   0x0030
+
+//STAT_PMStatus_US:
+#define STAT_PM_CO_REQ                                  0x0004
+#define STAT_PM_SIMPLE_REQ                              0x0010
+#define STAT_PM_L2_REQ                                 0x0020
+#define STAT_PM_L2_TRIM_REQ                            0x0030
+
+// STAT_OLRError_DS, STAT_OLRError_US
+//4 bit response reason code:
+#define RESP_BUSY                                      0x01
+#define RESP_INVALID_PARAMETERS                                0x02
+#define RESP_NOT_ENABLED                               0x03
+#define RESP_NOT_SUPPORTED                             0x04
+
+//4 bit internal error code (common for OLR and PM)
+#define REQ_INVALID_BiGi                               0x10
+#define REQ_INVALID_Lp                                 0x20
+#define REQ_INVALID_Bpn                                        0x30
+#define REQ_INVALID_FRAMING_CONSTRAINT                 0x40
+#define REQ_NOT_IN_L0_STATE                            0x50
+#define REQ_NOT_IN_L2_STATE                            0x60
+#define REQ_INVALID_PCB                                        0x70
+#define REQ_VIOLATES_MARGIN                            0x80
+
+//STAT_PMError
+//4 bit response reason code:
+#define RESP_STATE_NOT_DESIRED                          0x03
+#define RESP_INFEASIBLE_PARAMETERS                      0x04
+
+
+
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+// OPTN register address and bit field definitions
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+#define OPTN_ModeControl                               0
+#define OPTN_DMTLnkCtl                                 1
+// Reserved                                            2
+#define OPTN_GhsControl                                        3
+// Reserved                                            4
+#define OPTN_PwrManControl                             5
+#define OPTN_AnnexControl                              6
+#define OPTN_ModeControl1                              7
+// Reserved                                            8
+#define OPTN_StateMachineCtrl                          9
+// Reserved                                            10
+// Reserved                                            11
+#define OPTN_BisLinkControl                            12
+#define OPTN_ATMAddrConfig                             13
+#define OPTN_ATMNumCellConfig                          14
+
+// Mode control defines the allowable operating modes of an ADSL link. In general, a modem may ///
+// use G.Hs or some other mechanism to negotiate the specific mode of operation. ///
+// The OPTN_ModeControl CMV is used to select a set of desired modes ///
+// The STAT_ModeControl CMV indicates which mode was actually selected ///
+
+// OPTN_ModeControl
+#define OPTN_ConfigMode_T1413                  0x0001
+#define OPTN_ConfigMode_G992_2_AB              0x0002
+#define OPTN_ConfigMode_G992_1_A               0x0004
+#define OPTN_ConfigMode_G992_1_B               0x0008
+#define OPTN_ConfigMode_G992_1_C               0x0010
+#define OPTN_ConfigMode_G992_2_C               0x0020
+
+#define OPTN_ConfigMode_G992_3_A               0x0100
+#define OPTN_ConfigMode_G992_3_B               0x0200
+#define OPTN_ConfigMode_G992_3_I               0x0400
+#define OPTN_ConfigMode_G992_3_J               0x0800
+#define OPTN_ConfigMode_G992_3_L               0x1000
+
+#define OPTN_ConfigMode_G992_4_A               0x2000
+#define OPTN_ConfigMode_G992_4_I               0x4000
+
+#define OPTN_ConfigMode_G992_5                 0x8000
+
+// OPTN_PwrManControl
+#define OPTN_PwrManWakeUpGhs                   0x1
+#define OPTN_PwrManWakeUpFR                    0x2
+
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+// OPTN_DMT Link Control
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+#define OPTN_DMT_DualLatency_Dis                0x200
+#define OPTN_DMT_S_Dis                          0x100
+#define OPTN_DMT_FRAMINGMODE                   0x1
+#define OPTN_DMT_FRAMINGMODE_MASK              0x7
+
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+// OPTN_BIS Link Control
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+#define OPTN_BisLinkContrl_LineProbeDis         0x1
+#define OPTN_BisLinkContrl_DSBlackBitsEn        0x2
+#define OPTN_BisLinkContrl_DiagnosticModeEn     0x4
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+// OPTN_GhsControl
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+//
+// for OPTN_GhsControl, we will assign 16bit word as follows
+// bit 0~3: set the control over which start(initial) message CPE will send:
+//
+//             BIT: 2  1  0
+//                      0  0  1  CLR
+//                      0  1  0  MR
+//                      0  1  1  MS
+//                      1  0  0  MP
+//
+//  // bit 4~6: set the control over which message will be sent when we get at lease one CL/CLR exchange
+//        BIT: 5  4
+//                  0  1  MS
+//                      1  0  MR
+//                      1  1  MP
+//
+//  // bit 15: RT initiated G.hs sample sessions one through eight.  Session one is default.
+//        BIT: 15
+//                       1  means session one
+//
+///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+#define OPTN_GHS_ST_GHS                                        0x8000
+#define OPTN_GHS_INIT_MASK                             0x000F
+#define OPTN_GHS_RESP_MASK                             0x00F0
+
+#define OPTN_RTInitTxMsg_CLR                           0x0001
+#define OPTN_RTInitTxMsg_MR                            0x0002
+#define OPTN_RTInitTxMsg_MS                            0x0003
+#define OPTN_RTInitTxMsg_MP                            0x0004
+
+#define OPTN_RTRespTxMsg_MS                            0x0010
+#define OPTN_RTRespTxMsg_MR                            0x0020
+#define OPTN_RTRespTxMsg_MP                            0x0030
+
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+//     OPTN_AnnexControl
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+
+// G.992.3 Annex A/L1/L2 US PSD Mask preferred
+
+#define OPTN_G992_3_AnnexA_PreferredModeMask           0x3000
+#define OPTN_G992_3_AnnexA_PreferredModeA              0x0000         // default AnnexA PSD mask ///
+#define OPTN_G992_3_AnnexA_PreferredModeL1             0x1000             // AnnexL wide spectrum upstream PSD mask ///
+#define OPTN_G992_3_AnnexA_PreferredModeL2             0x2000             // AnnexL narrow spectrum upstream PSD mask ///
+
+
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+//OPTN_ATMAddrConfig
+// Bits 4:0            are Utopia address for BC1
+// Bits 9:5            are Utopia address for BC0
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+#define OPTN_UTPADDR_BC1                               0x001F
+#define OPTN_UTPADDR_BC0                               0x03E0
+
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+//OPTN_ATMNumCellConfig
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+#define OPTN_BC1_NUM_CELL_PAGES                                0x000F // Bits 0:3 ///
+#define OPTN_BC0_NUM_CELL_PAGES                                0x00F0 // Bits 4:7 ///
+
+
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+// CNFG register address field ///
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+///////////////////////////////////////////
+// these cmvs are used by bis handshake ///
+///////////////////////////////////////////
+
+// Each of the CNFG_TPS entries points to a structure of type (TPS_TC_BearerChannel_t)
+#define CNFG_TPS_TC_DS0                                        0
+#define CNFG_TPS_TC_DS1                                        1
+#define CNFG_TPS_TC_US0                                        2
+#define CNFG_TPS_TC_US1                                        3
+
+#define CNFG_HDLC_Overhead_Requirements                        4
+
+// Each of the CNFG_PMS entries points to a structure of type (PMS_TC_LatencyPath_t)
+#define CNFG_PMS_TC_DS0                                        5
+#define CNFG_PMS_TC_DS1                                        6
+#define CNFG_PMS_TC_US0                                        7
+#define CNFG_PMS_TC_US1                                        8
+
+// CNFG_PMD_PARAMETERS points to a structure of type (PMD_params_t)
+#define CNFG_PMD_PARAMETERS                            9
+
+////////////////////////////////////////////////////////////
+// these cmvs are used by bis training and showtime code ///
+////////////////////////////////////////////////////////////
+
+////////////////
+// Tx Config ///
+////////////////
+#define CNFG_tx_Cnfg_Nbc                               10
+#define CNFG_tx_Cnfg_Nlp                               11
+#define CNFG_tx_Cnfg_Rp                                        12
+#define CNFG_tx_Cnfg_Mp                                        13
+#define CNFG_tx_Cnfg_Lp                                        14
+#define CNFG_tx_Cnfg_Tp                                        15
+#define CNFG_tx_Cnfg_Dp                                        16
+#define CNFG_tx_Cnfg_Bpn                               17
+#define CNFG_tx_Cnfg_FramingMode                       18
+#define CNFG_tx_Cnfg_MSGLp                             19
+#define CNFG_tx_Cnfg_MSGc                              20
+
+
+////////////////
+// Rx Config ///
+////////////////
+#define CNFG_rx_Cnfg_Nbc                               21
+#define CNFG_rx_Cnfg_Nlp                               22
+#define CNFG_rx_Cnfg_Rp                                        23
+#define CNFG_rx_Cnfg_Mp                                        24
+#define CNFG_rx_Cnfg_Lp                                        25
+#define CNFG_rx_Cnfg_Tp                                        26
+#define CNFG_rx_Cnfg_Dp                                        27
+#define CNFG_rx_Cnfg_Bpn                               28
+#define CNFG_rx_Cnfg_FramingMode                       29
+#define CNFG_rx_Cnfg_MSGLp                             30
+#define CNFG_rx_Cnfg_MSGc                              31
+
+#define CNFG_tx_Cnfg_BCnToLPp                          32
+#define CNFG_rx_Cnfg_BCnToLPp                          33
+
+
+
+#endif
+
diff --git a/target/linux/amazon-2.6/files/include/asm-mips/amazon/amazon_sw.h b/target/linux/amazon-2.6/files/include/asm-mips/amazon/amazon_sw.h
new file mode 100644 (file)
index 0000000..3b73b53
--- /dev/null
@@ -0,0 +1,176 @@
+#ifndef AMAZON_SW_H
+#define AMAZON_SW_H
+#define SET_ETH_SPEED_AUTO   SIOCDEVPRIVATE
+#define SET_ETH_SPEED_10     SIOCDEVPRIVATE+1
+#define SET_ETH_SPEED_100    SIOCDEVPRIVATE+2
+#define SET_ETH_DUPLEX_AUTO  SIOCDEVPRIVATE+3
+#define SET_ETH_DUPLEX_HALF  SIOCDEVPRIVATE+4
+#define SET_ETH_DUPLEX_FULL  SIOCDEVPRIVATE+5
+#define SET_ETH_REG          SIOCDEVPRIVATE+6          
+#define VLAN_TOOLS           SIOCDEVPRIVATE+7
+#define MAC_TABLE_TOOLS      SIOCDEVPRIVATE+8 
+
+
+/*===mac table commands==*/
+#define RESET_MAC_TABLE     0
+#define READ_MAC_ENTRY    1
+#define WRITE_MAC_ENTRY   2
+#define ADD_MAC_ENTRY     3
+
+/*====vlan commands===*/
+
+#define CHANGE_VLAN_CTRL     0
+#define READ_VLAN_ENTRY      1
+#define UPDATE_VLAN_ENTRY    2
+#define CLEAR_VLAN_ENTRY     3
+#define RESET_VLAN_TABLE     4
+#define ADD_VLAN_ENTRY       5
+
+/* 
+** MDIO constants.
+*/
+
+#define MDIO_BASE_STATUS_REG                0x1
+#define MDIO_BASE_CONTROL_REG               0x0
+#define MDIO_PHY_ID_HIGH_REG                0x2
+#define MDIO_PHY_ID_LOW_REG                 0x3
+#define MDIO_BC_NEGOTIATE                0x0200
+#define MDIO_BC_FULL_DUPLEX_MASK         0x0100
+#define MDIO_BC_AUTO_NEG_MASK            0x1000
+#define MDIO_BC_SPEED_SELECT_MASK        0x2000
+#define MDIO_STATUS_100_FD               0x4000
+#define MDIO_STATUS_100_HD               0x2000
+#define MDIO_STATUS_10_FD                0x1000
+#define MDIO_STATUS_10_HD                0x0800
+#define MDIO_STATUS_SPEED_DUPLEX_MASK   0x7800
+#define MDIO_ADVERTISMENT_REG               0x4
+#define MDIO_ADVERT_100_FD                0x100
+#define MDIO_ADVERT_100_HD                0x080
+#define MDIO_ADVERT_10_FD                 0x040
+#define MDIO_ADVERT_10_HD                 0x020
+#define MDIO_LINK_UP_MASK                   0x4
+#define MDIO_START                          0x1
+#define MDIO_READ                           0x2
+#define MDIO_WRITE                          0x1
+#define MDIO_PREAMBLE              0xfffffffful
+
+#define PHY_RESET                        0x8000 
+#define AUTO_NEGOTIATION_ENABLE          0X1000
+#define AUTO_NEGOTIATION_COMPLETE          0x20
+#define RESTART_AUTO_NEGOTIATION          0X200
+
+
+#define PHY0_ADDR    0
+#define PHY1_ADDR    1
+#define P1M          0
+
+#define AMAZON_SW_REG32(reg_num) *((volatile u32*)(reg_num))
+
+#define OK 0;
+
+#ifdef CONFIG_CPU_LITTLE_ENDIAN
+typedef struct mac_table_entry{
+   u64 mac_address:48;
+   u64 p0:1;
+   u64 p1:1;
+   u64 p2:1;
+   u64 cr:1;
+   u64 ma_st:3;
+   u64 res:9;
+}_mac_table_entry;
+
+typedef struct IFX_Switch_VLanTableEntry{
+    u32 vlan_id:12;
+    u32 mp0:1;
+    u32 mp1:1;
+    u32 mp2:1;
+    u32 v:1;
+    u32 res:16;
+}_IFX_Switch_VLanTableEntry;
+
+typedef struct mac_table_req{
+    int cmd;
+    int index;
+    u32 data;
+    u64 entry_value;
+}_mac_table_req;
+
+#else //not CONFIG_CPU_LITTLE_ENDIAN
+typedef struct mac_table_entry{
+   u64 mac_address:48;
+   u64 p0:1;
+   u64 p1:1;
+   u64 p2:1;
+   u64 cr:1;
+   u64 ma_st:3;
+   u64 res:9;
+}_mac_table_entry;
+
+typedef struct IFX_Switch_VLanTableEntry{
+    u32 vlan_id:12;
+    u32 mp0:1;
+    u32 mp1:1;
+    u32 mp2:1;
+    u32 v:1;
+    u32 res:16;
+}_IFX_Switch_VLanTableEntry;
+
+
+typedef struct mac_table_req{
+    int cmd;
+    int index;
+    u32 data;
+    u64 entry_value;
+}_mac_table_req;
+
+#endif //CONFIG_CPU_LITTLE_ENDIAN
+
+
+
+typedef struct vlan_req{
+    int cmd;
+    int index;
+    u32 data;
+    u32 entry_value;
+}_vlan_req;
+
+typedef struct data_req{
+    int index;
+    u32 value;
+}_data_req;
+
+enum duplex
+{
+   half,
+   full,
+   autoneg
+};
+
+struct switch_priv {
+    struct net_device_stats stats;
+    int rx_packetlen;
+    u8 *rx_packetdata;
+    int rx_status;
+    int tx_packetlen;
+#ifdef CONFIG_NET_HW_FLOWCONTROL    
+    int fc_bit;
+#endif //CONFIG_NET_HW_FLOWCONTROL    
+    u8 *tx_packetdata;
+    int tx_status;
+    struct dma_device_info *dma_device;
+    struct sk_buff *skb;
+    spinlock_t lock;
+    int mdio_phy_addr;
+    int current_speed;
+    int current_speed_selection;
+    int rx_queue_len;
+    int full_duplex;
+    enum duplex current_duplex;
+};
+
+#endif //AMAZON_SW_H
+
+
+
+
+
diff --git a/target/linux/amazon-2.6/files/include/asm-mips/amazon/amazon_tpe.h b/target/linux/amazon-2.6/files/include/asm-mips/amazon/amazon_tpe.h
new file mode 100644 (file)
index 0000000..a64e6f9
--- /dev/null
@@ -0,0 +1,258 @@
+#ifndef AMAZON_TPE_H
+#define AMAZON_TPE_H
+#include <linux/atm.h>
+#include <linux/atmdev.h>
+#include <linux/netdevice.h>
+#include <linux/ioctl.h>
+
+#ifdef CONFIG_IFX_ATM_MIB
+/* For ATM-MIB lists */
+#include <linux/list.h>
+#endif
+#include <asm/amazon/atm_mib.h>
+
+/* CBM Queue arranagement
+ * Q0: free cells pool
+ * Q1~ Q15: upstream queues
+ * Q16: QAM downstream
+ * Q17~Q31: downstream queues
+ */
+#define        AMAZON_ATM_MAX_QUEUE_NUM        32
+#define        AMAZON_ATM_PORT_NUM             2
+#define        AMAZON_ATM_FREE_CELLS           4000
+#define        AMAZON_ATM_MAX_VCC_NUM          (AMAZON_ATM_MAX_QUEUE_NUM/2 - 1)
+#define AMAZON_AAL0_SDU                (ATM_AAL0_SDU+4)                                //one more word for status
+#define CBM_RX_OFFSET                  16                                              //offset from the same q for tx
+#define        AMAZON_ATM_OAM_Q_ID             16
+#define        AMAZON_ATM_RM_Q_ID              16
+#define        AMAZON_ATM_OTHER_Q_ID           16
+#define        CBM_DEFAULT_Q_OFFSET            1
+#define        HTUTIMEOUT                      0xffff//timeoutofhtutocbm
+#define        QSB_WFQ_NONUBR_MAX              0x3f00
+#define        QSB_WFQ_UBR_BYPASS              0x3fff
+#define        QSB_TP_TS_MAX                   65472
+#define        QSB_TAUS_MAX                    64512
+#define QSB_GCR_MIN                    18
+#define HTU_RAM_ACCESS_MAX             1024//maxium time for HTU RAM access
+
+#define SWIE_LOCK              1
+#define        PROC_ATM                1
+#define        PROC_MIB                2
+#define PROC_VCC               3
+#define PROC_AAL5               4
+#define PROC_CBM                5
+#define PROC_HTU                6
+#define PROC_QSB                7
+#define PROC_SWIE               8
+
+/***************** internal data structure ********************/
+typedef int (*push_back_t)(struct atm_vcc *vcc,struct sk_buff *skb,int err) ;
+/* Device private data */
+typedef struct{
+       u8      padding_byte;
+       u32     tx_max_sdu;
+       u32     rx_max_sdu;
+       u32     cnt_cpy;                //no. of packets that need a copy due to alignment
+}amazon_aal5_dev_t;
+
+typedef struct{
+       u32     max_q_off;              //maxium queues used in real scenario
+       u32     nrt_thr;
+       u32     clp0_thr;
+       u32     clp1_thr;
+       u32     free_cell_cnt;
+#ifdef CONFIG_USE_VENUS        
+       u8 *    qd_addr_free;   //to work around a bug, bit15 of QDOFF address should be 1
+#endif
+       u8 *    qd_addr;
+       u8 *    mem_addr;
+       u8      allocated;
+}amazon_cbm_dev_t;
+
+typedef struct{
+
+}amazon_htu_dev_t;
+
+typedef struct{
+       u32     tau;                    //cell delay variation due to concurrency(?)
+       u32     tstepc;                 //time step, all legal values are 1,2,4
+       u32     sbl;                    //scheduler burse length (for PHY)
+}amazon_qsb_dev_t;
+
+typedef struct{
+       u32     qid;                    //QID of the current extraction queue
+       struct semaphore in_sem;        // Software-Insertion semaphore
+       volatile long   lock;           //lock that avoids race contions between SWIN and SWEX
+       wait_queue_head_t sleep;        //wait queue for SWIE and SWEX
+       u32 sw;                 //status word
+}amazon_swie_dev_t;
+
+//AAL5 MIB Counter
+typedef struct{
+       u32     tx,rx;                  //number AAL5 CPCS PDU from/to higher-layer
+       u32     tx_err,rx_err;          //ifInErrors and ifOutErros
+       u32     tx_drop,rx_drop;        //discarded received packets due to mm shortage
+       u32     htu_unp;                //number of unknown received cells
+       u32     rx_cnt_h;               //number of octets received, high 32 bits
+       u32     rx_cnt_l;               //number of octets received, low 32 bits
+       u32     tx_cnt_h;               //number of octets transmitted, high 32 bits
+       u32     tx_cnt_l;               //number of octets transmitted, low 32 bits
+       u32     tx_ppd;                 //number of cells for AAL5 upstream PPD discards
+       u64     rx_cells;               //number of cells for downstream
+       u64     tx_cells;               //number of cells for upstream
+       u32     rx_err_cells;           //number of cells dropped due to uncorrectable HEC errors
+}amazon_mib_counter_t;
+
+
+
+typedef enum {QS_PKT,QS_LEN,QS_ERR,QS_HW_DROP,QS_SW_DROP,QS_MAX} qs_t;
+//queue statics no. of packet received / sent
+//queue statics no. of bytes received / sent
+//queue statics no. of packets with error
+//queue statics no. of packets dropped by hw
+//queue statics no. of packets dropped by sw
+
+typedef struct{
+       push_back_t push;               //call back function
+       struct atm_vcc * vcc;           //opened vcc
+       struct timeval access_time;     //time when last F4/F5 user cells arrive
+       int     free;                   //whether this queue is occupied, 0: occupied, 1: free
+       u32     aal5VccCrcErrors;       //MIB counter
+       u32     aal5VccOverSizedSDUs;   //MIB counter
+
+#if defined(AMAZON_ATM_DEBUG) || defined (CONFIG_IFX_ATM_MIB)
+       u32     qs[QS_MAX];
+#endif 
+}amazon_atm_queue_t;
+
+
+typedef struct{
+       int     enable;         //enable / disable
+       u32     max_conn;       //maximum number of connections per port
+       u32     tx_max_cr;      //Remaining cellrate for this device for tx direction
+       u32     tx_rem_cr;      //Remaining cellrate for this device for tx direction
+       u32     tx_cur_cr;      //Current cellrate for this device for tx direction
+}amazon_atm_port_t;
+
+typedef struct{
+       amazon_aal5_dev_t       aal5;
+       amazon_cbm_dev_t        cbm;
+       amazon_htu_dev_t        htu;
+       amazon_qsb_dev_t        qsb;
+       amazon_swie_dev_t       swie;
+       amazon_mib_counter_t    mib_counter;
+       amazon_atm_queue_t      queues[AMAZON_ATM_MAX_QUEUE_NUM];
+       amazon_atm_port_t       ports[AMAZON_ATM_PORT_NUM];
+       atomic_t                dma_tx_free_0;//TX_CH0 has availabe descriptors
+} amazon_atm_dev_t;
+
+struct oam_last_activity{
+       u8                      vpi;    //vpi for this connection       
+       u16                     vci;    //vci for t his connection
+       struct timeval          stamp;  //time when last F4/F5 user cells arrive
+       struct oam_last_activity * next;//for link list purpose
+};
+
+typedef union{
+#ifdef CONFIG_CPU_LITTLE_ENDIAN
+       struct{
+               u32     tprs            :16;
+               u32     twfq            :14;
+               u32     vbr             :1;
+               u32     reserved        :1;
+       }bit;
+       u32 w0;
+#else
+       struct{
+               u32     reserved        :1;
+               u32     vbr             :1;
+               u32     twfq            :14;
+               u32     tprs            :16;
+       }bit;
+       u32 w0;
+#endif
+
+}qsb_qptl_t;
+
+typedef union{
+#ifdef CONFIG_CPU_LITTLE_ENDIAN
+       struct{
+               u32     ts              :16;
+               u32     taus            :16;
+       }bit;
+       u32 w0;
+#else
+       struct{
+               u32     taus            :16;
+               u32     ts              :16;
+       }bit;
+       u32 w0;
+#endif
+}qsb_qvpt_t;
+
+
+
+struct amazon_atm_cell_header {
+#ifdef CONFIG_CPU_LITTLE_ENDIAN
+       struct{
+               u32 clp         :1;     // Cell Loss Priority
+               u32 pti         :3;     // Payload Type Identifier
+               u32 vci         :16;    // Virtual Channel Identifier
+               u32 vpi         :8;     // Vitual Path Identifier
+               u32 gfc         :4;     // Generic Flow Control
+               }bit;
+#else
+       struct{
+               u32 gfc         :4;     // Generic Flow Control
+               u32 vpi         :8;     // Vitual Path Identifier
+               u32 vci         :16;    // Virtual Channel Identifier
+               u32 pti         :3;     // Payload Type Identifier
+               u32 clp         :1;     // Cell Loss Priority
+               }bit;
+#endif
+};
+
+
+/************************ Function Declarations **************************/
+amazon_atm_dev_t *     amazon_atm_create(void);
+int    amazon_atm_open(struct atm_vcc *vcc,push_back_t);
+int    amazon_atm_send(struct atm_vcc *vcc,struct sk_buff *skb);
+int    amazon_atm_send_oam(struct atm_vcc *vcc,void *cell, int flags);
+void   amazon_atm_close(struct atm_vcc *vcc);
+void   amazon_atm_cleanup(void);
+const struct oam_last_activity* get_oam_time_stamp(void);
+
+//mib-related
+int amazon_atm_cell_mib(atm_cell_ifEntry_t * to,u32 itf);
+int amazon_atm_aal5_mib(atm_aal5_ifEntry_t * to);
+int amazon_atm_vcc_mib(struct atm_vcc *vcc,atm_aal5_vcc_t * to);
+int amazon_atm_vcc_mib_x(int vpi, int vci,atm_aal5_vcc_t* to);
+
+#define        AMAZON_WRITE_REGISTER_L(data,addr)      do{ *((volatile u32*)(addr)) = (u32)(data); wmb();} while (0)
+#define AMAZON_READ_REGISTER_L(addr)   (*((volatile u32*)(addr)))
+/******************************* ioctl stuff****************************************/
+#define NUM(dev)    (MINOR(dev) & 0xf)
+/*
+ * Ioctl definitions
+ */
+/* Use 'o' as magic number */
+#define AMAZON_ATM_IOC_MAGIC  'o'
+/* MIB_CELL: get atm cell level mib counter
+ * MIB_AAL5: get aal5 mib counter
+ * MIB_VCC: get vcc mib counter
+ */
+typedef struct{
+       int vpi;
+       int vci;
+       atm_aal5_vcc_t mib_vcc;
+}atm_aal5_vcc_x_t;
+#define AMAZON_ATM_MIB_CELL            _IOWR(AMAZON_ATM_IOC_MAGIC,  0, atm_cell_ifEntry_t)
+#define AMAZON_ATM_MIB_AAL5            _IOWR(AMAZON_ATM_IOC_MAGIC,  1, atm_aal5_ifEntry_t)
+#define AMAZON_ATM_MIB_VCC             _IOWR(AMAZON_ATM_IOC_MAGIC,  2, atm_aal5_vcc_x_t)
+#define AMAZON_ATM_IOC_MAXNR   3
+
+//sockopt
+#define        SO_AMAZON_ATM_MIB_VCC           __SO_ENCODE(SOL_ATM,5,atm_aal5_vcc_t)
+
+#endif // AMAZON_TPE_H
+
diff --git a/target/linux/amazon-2.6/files/include/asm-mips/amazon/amazon_wdt.h b/target/linux/amazon-2.6/files/include/asm-mips/amazon/amazon_wdt.h
new file mode 100644 (file)
index 0000000..775dabc
--- /dev/null
@@ -0,0 +1,23 @@
+#ifndef AMAZON_WDT_H
+#define AMAZON_WDT_H
+#ifdef __KERNEL__
+typedef struct wdt_dev{
+      char name[16];
+      int major;
+      int minor;
+      
+      int full;
+      char buff[10];
+}wdt_dev;
+#define AMAZON_WDT_REG32(addr) (*((volatile u32*)(addr))) 
+#endif //__KERNEL__
+
+//AMAZON_WDT_IOC_START: start the WDT timer (must provide a initial timeout value)
+//AMAZON_WDT_IOC_STOP: stop the WDT
+//AMAZON_WDT_IOC_PING: reload the timer to initial value (must happend after a AMAZON_WDT_IOC_START)
+#define AMAZON_WDT_IOC_MAGIC   0xc0
+#define AMAZON_WDT_IOC_START   _IOW( AMAZON_WDT_IOC_MAGIC,0, int)
+#define AMAZON_WDT_IOC_STOP    _IO( AMAZON_WDT_IOC_MAGIC,1)
+#define AMAZON_WDT_IOC_PING    _IO( AMAZON_WDT_IOC_MAGIC,2)
+
+#endif //AMAZON_WDT_H
diff --git a/target/linux/amazon-2.6/files/include/asm-mips/amazon/atm_defines.h b/target/linux/amazon-2.6/files/include/asm-mips/amazon/atm_defines.h
new file mode 100644 (file)
index 0000000..8adda20
--- /dev/null
@@ -0,0 +1,540 @@
+#ifndef ATM_DEFINES_H
+#define        ATM_DEFINES_H
+                       
+//Registers Base Address
+#define IO_BASE_ADDR                           0xA0000000
+#define        AAL5_BASE_ADDRESS                       0x10104400+IO_BASE_ADDR
+#define        CBM_BASE_ADDRESS                        0x10104000+IO_BASE_ADDR
+#define        HTU_BASE_ADDRESS                        0x10105100+IO_BASE_ADDR
+#define        QSB_BASE_ADDRESS                        0x10105000+IO_BASE_ADDR
+#define        SWIE_BASE_ADDRESS                       0x10105200+IO_BASE_ADDR
+
+//AAL5 Registers
+#define        AAL5_SISR0_ADDR                         AAL5_BASE_ADDRESS+0x20
+#define        AAL5_SIMR0_ADDR                         AAL5_BASE_ADDRESS+0x24
+#define        AAL5_SISR1_ADDR                         AAL5_BASE_ADDRESS+0x28
+#define        AAL5_SIMR1_ADDR                         AAL5_BASE_ADDRESS+0x2C
+#define        AAL5_SMFL_ADDR                          AAL5_BASE_ADDRESS+0x30
+#define        AAL5_SATMHD_ADDR                        AAL5_BASE_ADDRESS+0x34
+#define        AAL5_SCON_ADDR                          AAL5_BASE_ADDRESS+0x38
+#define        AAL5_SCMD_ADDR                          AAL5_BASE_ADDRESS+0x3C
+#define        AAL5_RISR0_ADDR                         AAL5_BASE_ADDRESS+0x40
+#define        AAL5_RIMR0_ADDR                         AAL5_BASE_ADDRESS+0x44
+#define        AAL5_RISR1_ADDR                         AAL5_BASE_ADDRESS+0x48
+#define        AAL5_RIMR1_ADDR                         AAL5_BASE_ADDRESS+0x4C
+#define        AAL5_RMFL_ADDR                          AAL5_BASE_ADDRESS+0x50
+#define        AAL5_RINTINF0_ADDR                      AAL5_BASE_ADDRESS+0x54
+#define        AAL5_RINTINF1_ADDR                      AAL5_BASE_ADDRESS+0x58
+#define        AAL5_RES5C_ADDR                         AAL5_BASE_ADDRESS+0x5C
+#define AAL5_RIOL_ADDR                         AAL5_BASE_ADDRESS+0x60
+#define        AAL5_RIOM_ADDR                          AAL5_BASE_ADDRESS+0x64
+#define        AAL5_SOOL_ADDR                          AAL5_BASE_ADDRESS+0x68
+#define        AAL5_SOOM_ADDR                          AAL5_BASE_ADDRESS+0x6C
+#define        AAL5_RES70_ADDR                         AAL5_BASE_ADDRESS+0x70
+#define        AAL5_RES74_ADDR                         AAL5_BASE_ADDRESS+0x74
+#define        AAL5_RES78_ADDR                         AAL5_BASE_ADDRESS+0x78
+#define        AAL5_RES7C_ADDR                         AAL5_BASE_ADDRESS+0x7C
+#define        AAL5_RES80_ADDR                         AAL5_BASE_ADDRESS+0x80
+#define        AAL5_RES84_ADDR                         AAL5_BASE_ADDRESS+0x84
+#define        AAL5_RES88_ADDR                         AAL5_BASE_ADDRESS+0x88
+#define        AAL5_RES8C_ADDR                         AAL5_BASE_ADDRESS+0x8C
+#define        AAL5_RES90_ADDR                         AAL5_BASE_ADDRESS+0x90
+#define        AAL5_RES94_ADDR                         AAL5_BASE_ADDRESS+0x94
+#define        AAL5_RES98_ADDR                         AAL5_BASE_ADDRESS+0x98
+#define        AAL5_RES9C_ADDR                         AAL5_BASE_ADDRESS+0x9C
+#define        AAL5_RESA0_ADDR                         AAL5_BASE_ADDRESS+0xA0
+#define        AAL5_RESA4_ADDR                         AAL5_BASE_ADDRESS+0xA4
+#define        AAL5_RESA8_ADDR                         AAL5_BASE_ADDRESS+0xA8
+#define        AAL5_RESAC_ADDR                         AAL5_BASE_ADDRESS+0xAC
+#define        AAL5_RESB0_ADDR                         AAL5_BASE_ADDRESS+0xB0
+#define        AAL5_RESB4_ADDR                         AAL5_BASE_ADDRESS+0xB4
+#define        AAL5_RESB8_ADDR                         AAL5_BASE_ADDRESS+0xB8
+#define        AAL5_RESBC_ADDR                         AAL5_BASE_ADDRESS+0xBC
+#define        AAL5_RESC0_ADDR                         AAL5_BASE_ADDRESS+0xC0
+#define        AAL5_RESC4_ADDR                         AAL5_BASE_ADDRESS+0xC4
+#define        AAL5_RESC8_ADDR                         AAL5_BASE_ADDRESS+0xC8
+#define        AAL5_RESCC_ADDR                         AAL5_BASE_ADDRESS+0xCC
+#define        AAL5_RESD0_ADDR                         AAL5_BASE_ADDRESS+0xD0
+#define        AAL5_RESD4_ADDR                         AAL5_BASE_ADDRESS+0xD4
+#define        AAL5_RESD8_ADDR                         AAL5_BASE_ADDRESS+0xD8
+#define        AAL5_RESDC_ADDR                         AAL5_BASE_ADDRESS+0xDC
+#define        AAL5_RESE0_ADDR                         AAL5_BASE_ADDRESS+0xE0
+#define        AAL5_RESE4_ADDR                         AAL5_BASE_ADDRESS+0xE4
+#define        AAL5_RESE8_ADDR                         AAL5_BASE_ADDRESS+0xE8
+#define        AAL5_RESEC_ADDR                         AAL5_BASE_ADDRESS+0xEC
+#define        AAL5_SSRC0_ADDR                         AAL5_BASE_ADDRESS+0xF0
+#define        AAL5_SSRC1_ADDR                         AAL5_BASE_ADDRESS+0xF4
+#define        AAL5_RSRC0_ADDR                         AAL5_BASE_ADDRESS+0xF8
+#define        AAL5_RSRC1_ADDR                         AAL5_BASE_ADDRESS+0xFC
+
+#define        AAL5S_ISR_QID_MASK                      0xFF000000
+#define        AAL5S_ISR_SAB                           0x00000100
+#define        AAL5S_ISR_SE                            0x00000080
+#define        AAL5S_ISR_MFLE                          0x00000040
+#define        AAL5S_ISR_SBE0                          0x00000020
+#define        AAL5S_ISR_SEG0                          0x00000010
+#define        AAL5S_ISR_TAB                           0x00000004
+
+#define        AAL5_SIMR_MASK                          0x000001c7
+#define        AAL5_SIMR_SAB                           0x00000100
+#define        AAL5_SIMR_SE                            0x00000080
+#define        AAL5_SIMR_MFLE                          0x00000040
+#define        AAL5_SIMR_TAB                           0x00000004
+#define        AAL5_SIMR_SBE0                          0x00000002
+#define        AAL5_SIMR_SEG0                          0x00000001
+
+#define        AAL5_SCMD_SEQCOUNT_MASK                 0x0000ff00
+#define        AAL5_SCMD_MODE_POLL                     0x00000008
+#define        AAL5_SCMD_MODE_COUNT                    0x00000000
+#define        AAL5_SCMD_AS                            0x00000004
+#define        AAL5_SCMD_SS                            0x00000002
+#define        AAL5_SCMD_AR                            0x00000001
+
+#define        AAL5R_ISR_CID_MASK                      0xFF000000//ConnectionID
+#define        AAL5R_ISR_DBC_MASK                      0x00FF0000//DiscardedByteCounter
+#define        AAL5R_ISR_END                           0x00002000//End
+#define        AAL5R_ISR_ICID                          0x00001000//InvalidConnectionID
+#define        AAL5R_ISR_CLP                           0x00000800//CellLossPriority
+#define        AAL5R_ISR_CGST                          0x00000400//Congestion
+#define        AAL5R_ISR_UUE                           0x00000200//CPCSUUError
+#define        AAL5R_ISR_CPIE                          0x00000100//CPIError
+#define        AAL5R_ISR_FE                            0x00000080//FrameEnd
+#define        AAL5R_ISR_MFLE                          0x00000040//MaximumFrameLengthExceeded
+#define        AAL5R_ISR_DBCE                          0x00000020//DiscardedByteCounterExceeded
+#define        AAL5R_ISR_CRC                           0x00000010//CRCError
+#define        AAL5R_ISR_ILEN                          0x00000008//InvalidLength
+#define        AAL5R_ISR_RAB                           0x00000004//ReceiveAbort
+
+#define        AAL5_RIMR1_MASK                         0x00003ffc
+#define        AAL5_RIMR1_END                          0x00002000//End
+#define        AAL5_RIMR1_ICID                         0x00001000//InvalidConnectionID
+#define        AAL5_RIMR1_CLP                          0x00000800//CellLossPriority
+#define        AAL5_RIMR1_CGST                         0x00000400//Congestion
+#define        AAL5_RIMR1_UUE                          0x00000200//CPCSUUError
+#define        AAL5_RIMR1_CPIE                         0x00000100//CPIError
+#define        AAL5_RIMR1_FE                           0x00000080//FrameEnd
+#define        AAL5_RIMR1_MFLE                         0x00000040//MaximumFrameLengthExceeded
+#define        AAL5_RIMR1_DBCE                         0x00000020//DiscardedByteCounterExceeded
+#define        AAL5_RIMR1_CRC                          0x00000010//CRCError
+#define        AAL5_RIMR1_ILEN                         0x00000008//InvalidLength
+#define        AAL5_RIMR1_RAB                          0x00000004//ReceiveAbort
+
+//AAL5 Reassambly Errors
+#define AAL5_STW1_MASK                         0x33//Error mask
+#define AAL5_STW0_MASK                         0x5c//Error mask
+#define AAL5_STW0_BE                           0x3//padding bytes mask
+#define        AAL5_STW1_CBM                           0x20//Transfer from CBM to A5R abnormally ended
+#define        AAL5_STW1_CH                            0x10//Invalid Channel number error
+#define        AAL5_STW1_CLP                           0x8//CLP value of cells in packet is 1
+#define        AAL5_STW1_CG                            0x4//Cell in packet expired congestion
+#define        AAL5_STW1_UU                            0x2//CPCS-UU value error
+#define        AAL5_STW1_CPI                           0x1//CPI value error
+#define        AAL5_STW0_FE                            0x80//Frame end
+#define        AAL5_STW0_MFL                           0x40//Maximum frame length error
+#define        AAL5_STW0_CRC                           0x10//CRC error
+#define        AAL5_STW0_IL                            0x8//Invalid length
+#define        AAL5_STW0_RA                            0x4//Received abort
+
+
+
+//CBM Registers
+#define        CBM_NRTTHR_ADDR                 CBM_BASE_ADDRESS+0x10//NonRealTimeThreshold
+#define        CBM_CLP0THR_ADDR                CBM_BASE_ADDRESS+0x14//CLP0Threshold
+#define        CBM_CLP1THR_ADDR                CBM_BASE_ADDRESS+0x18//CLP1Threshold
+#define        CBM_QDOFF_ADDR                  CBM_BASE_ADDRESS+0x1C//QueueDescriptorOffset
+#define        CBM_CFG_ADDR                    CBM_BASE_ADDRESS+0x20//Configuration
+#define        CBM_HWEXPAR0_ADDR               CBM_BASE_ADDRESS+0x24//HWExtractParameter0
+#define        CBM_RES28_ADDR                  CBM_BASE_ADDRESS+0x28
+#define        CBM_WMSTAT0_ADDR                CBM_BASE_ADDRESS+0x2C
+#define        CBM_HWEXCMD_ADDR                CBM_BASE_ADDRESS+0x30//HWExtractCommand0
+#define        CBM_RES34_ADDR                  CBM_BASE_ADDRESS+0x34
+#define        CBM_HWEXSTAT0_ADDR              CBM_BASE_ADDRESS+0x38//HWExtractStatus0
+#define        CBM_RES3C_ADDR                  CBM_BASE_ADDRESS+0x3C
+#define        CBM_RES40_ADDR                  CBM_BASE_ADDRESS+0x40
+#define        CBM_CNT_ADDR                    CBM_BASE_ADDRESS+0x44//CellCount
+#define        CBM_RES48_ADDR                  CBM_BASE_ADDRESS+0x48
+#define        CBM_LFR_ADDR                    CBM_BASE_ADDRESS+0x4C//PointertolastCellinfreeCellQueue
+#define        CBM_FFR_ADDR                    CBM_BASE_ADDRESS+0x50//PointertofirstCellinfreeCellQueue
+#define        CBM_RES54_ADDR                  CBM_BASE_ADDRESS+0x54
+#define        CBM_RES58_ADDR                  CBM_BASE_ADDRESS+0x58
+#define        CBM_RES5C_ADDR                  CBM_BASE_ADDRESS+0x5C
+#define        CBM_RES60_ADDR                  CBM_BASE_ADDRESS+0x60
+#define        CBM_RES64_ADDR                  CBM_BASE_ADDRESS+0x64
+#define        CBM_RES68_ADDR                  CBM_BASE_ADDRESS+0x68
+#define        CBM_RES6C_ADDR                  CBM_BASE_ADDRESS+0x6C
+#define        CBM_RES70_ADDR                  CBM_BASE_ADDRESS+0x70
+#define        CBM_RES74_ADDR                  CBM_BASE_ADDRESS+0x74
+#define        CBM_RES78_ADDR                  CBM_BASE_ADDRESS+0x78
+#define        CBM_RES7C_ADDR                  CBM_BASE_ADDRESS+0x7C
+#define        CBM_RES80_ADDR                  CBM_BASE_ADDRESS+0x80
+#define        CBM_RES84_ADDR                  CBM_BASE_ADDRESS+0x84
+#define        CBM_RES88_ADDR                  CBM_BASE_ADDRESS+0x88
+#define        CBM_RES8C_ADDR                  CBM_BASE_ADDRESS+0x8C
+#define        CBM_RES90_ADDR                  CBM_BASE_ADDRESS+0x90
+#define        CBM_RES94_ADDR                  CBM_BASE_ADDRESS+0x94
+#define        CBM_RES98_ADDR                  CBM_BASE_ADDRESS+0x98
+#define        CBM_RES9C_ADDR                  CBM_BASE_ADDRESS+0x9C
+#define        CBM_RESA0_ADDR                  CBM_BASE_ADDRESS+0xA0
+#define        CBM_RESA4_ADDR                  CBM_BASE_ADDRESS+0xA4
+#define        CBM_RESA8_ADDR                  CBM_BASE_ADDRESS+0xA8
+#define        CBM_RESAC_ADDR                  CBM_BASE_ADDRESS+0xAC
+#define        CBM_RESB0_ADDR                  CBM_BASE_ADDRESS+0xB0
+#define        CBM_RESB4_ADDR                  CBM_BASE_ADDRESS+0xB4
+#define        CBM_RESB8_ADDR                  CBM_BASE_ADDRESS+0xB8
+#define        CBM_RESBC_ADDR                  CBM_BASE_ADDRESS+0xBC
+#define        CBM_INTINF0_ADDR                CBM_BASE_ADDRESS+0xC0//InterruptInfo0
+#define        CBM_INTCMD_ADDR                 CBM_BASE_ADDRESS+0xC4//InterruptCommand0
+#define        CBM_IMR0_ADDR                   CBM_BASE_ADDRESS+0xC8//InterruptMask
+#define        CBM_SRC0_ADDR                   CBM_BASE_ADDRESS+0xCC//ServiceRequestControl
+#define        CBM_RESD0_ADDR                  CBM_BASE_ADDRESS+0xD0
+#define        CBM_RESD4_ADDR                  CBM_BASE_ADDRESS+0xD4
+#define        CBM_RESD8_ADDR                  CBM_BASE_ADDRESS+0xD8
+#define        CBM_RESDC_ADDR                  CBM_BASE_ADDRESS+0xDC
+#define        CBM_RESE0_ADDR                  CBM_BASE_ADDRESS+0xE0
+#define        CBM_AAL5IDIS_ADDR               CBM_BASE_ADDRESS+0xE4//MIB-No.EPDdiscardedpacketsupstream
+#define        CBM_AAL5ODIS_ADDR               CBM_BASE_ADDRESS+0xE8//MIB-No.PPDdiscardedpacketsupstream
+#define        CBM_RESEC_ADDR                  CBM_BASE_ADDRESS+0xEC
+#define        CBM_RESF0_ADDR                  CBM_BASE_ADDRESS+0xF0
+#define        CBM_RESF4_ADDR                  CBM_BASE_ADDRESS+0xF4
+#define        CBM_RESF8_ADDR                  CBM_BASE_ADDRESS+0xF8
+#define        CBM_RESFC_ADDR                  CBM_BASE_ADDRESS+0xFC
+
+//CBMCFG
+#define        CBM_CFG_INTLCK0EN               0x00000008
+#define        CBM_CFG_INT0HLT                 0x00000004
+#define        CBM_CFG_START                   0x00000001
+
+#define        CBM_HWEXPAR_PN_A5               0x00002000
+#define        CBM_HWEXPAR_PN_CM               0x00000000
+#define        CBM_HWEXPAR_SUBADD_PORTMASK     0x00000070
+#define        CBM_HWEXPAR_SUBADD_ADU          0x00000000
+#define        CBM_HWEXPAR_SUBADD_AAL2         0x00000080
+#define        CBM_HWEXPAR_SUBADD_SWIE         0x00000100
+
+#define        CBM_HWEXCMD_SFE2                0x00000100
+#define        CBM_HWEXCMD_FE2                 0x00000080
+#define        CBM_HWEXCMD_SCE2                0x00000040
+#define        CBM_HWEXCMD_SFE1                0x00000020
+#define        CBM_HWEXCMD_FE1                 0x00000010
+#define        CBM_HWEXCMD_SCE1                0x00000008
+#define        CBM_HWEXCMD_SFE0                0x00000004
+#define        CBM_HWEXCMD_FE0                 0x00000002
+#define        CBM_HWEXCMD_SCE0                0x00000001
+
+#define        CBM_INTINF0_QID_MASK            0xFF000000
+#define        CBM_INTINF0_ORIGIN_MASK         0x00F00000
+#define        CBM_INTINF0_EF                  0x00004000
+#define        CBM_INTINF0_ACA                 0x00002000
+#define        CBM_INTINF0_ERR                 0x00001000
+#define        CBM_INTINF0_DISC                0x00000800
+#define        CBM_INTINF0_QSBV                0x00000400
+#define        CBM_INTINF0_Q0E                 0x00000200
+#define        CBM_INTINF0_Q0I                 0x00000100
+#define        CBM_INTINF0_RDE                 0x00000080
+#define        CBM_INTINF0_OPF                 0x00000040
+#define        CBM_INTINF0_NFCA                0x00000020
+#define        CBM_INTINF0_CLP1TR              0x00000010
+#define        CBM_INTINF0_CLP0TR              0x00000008
+#define        CBM_INTINF0_NRTTR               0x00000004
+#define        CBM_INTINF0_QFD                 0x00000002
+#define        CBM_INTINF0_QTR                 0x00000001
+#define CBM_INTINF0_QID_SHIFT          24
+//CBM QD Word 3
+#define        CBM_QD_W3_QOS_0                 0x00000000
+#define        CBM_QD_W3_QOS_1                 0x40000000
+#define        CBM_QD_W3_QOS_2                 0x80000000
+#define        CBM_QD_W3_QOS_3                 0xc0000000
+
+#define        CBM_QD_W3_DIR_UP                0x20000000
+#define        CBM_QD_W3_DIR_DOWN              0x00000000
+
+#define        CBM_QD_W3_CLPt                  0x10000000
+#define        CBM_QD_W3_RT                    0x08000000
+#define        CBM_QD_W3_AAL5                  0x04000000
+
+#define        CBM_QD_W3_INT_NOINT             0x00000000
+#define        CBM_QD_W3_INT_ACA               0x01000000
+#define        CBM_QD_W3_INT_EOF               0x02000000
+#define        CBM_QD_W3_INT_BOTH              0x03000000
+
+#define        CBM_QD_W3_THRESHOLD_MASK        0x00ff0000
+#define CBM_QD_W3_WM_EN                        0x00000010
+#define        CBM_QD_W3_HCR                   0x00000008
+#define        CBM_QD_W3_SBID_MASK             0x00000001
+
+#define        CBM_QD_W3_THRESHOLD_SHIFT       16
+
+//WATER MARK STATUS
+#define        CBM_WM_NRT_MASK                 0x00040000
+#define        CBM_WM_CLP0_MASK                0x00020000
+#define        CBM_WM_CLP1_MASK                0x00010000
+
+//CBMNRTTHR, CBMCLP0THR, CBMCLP0THR
+#define CBM_NRT_WM_NONE                        0x00000000//no water mark
+#define CBM_WM_3_1                     0x00010000//3/4 to set, 1/4 to release
+#define CBM_WM_3_2                     0x00020000//3/4 to set, 2/4 to release
+#define CBM_WM_2_1                     0x00030000//2/4 to set, 1/4 to release
+#define CBM_THR_MASK                   0x0000FFFF
+
+#define        CBM_IMR_MASK                    0x0000fbff
+#define        CBM_IMR_reserved                0xFFFF0400
+#define        CBM_IMR_RFULL                   0x00008000//EndofFrame
+#define        CBM_IMR_EF                      0x00004000//EndofFrame
+#define        CBM_IMR_ACA                     0x00002000//AnyCellArrived
+#define        CBM_IMR_ERR                     0x00001000//FPI Error
+#define        CBM_IMR_DISC                    0x00000800//Discard
+#define        CBM_IMR_reserved1               0x00000400//reserved
+#define        CBM_IMR_Q0E                     0x00000200//Queue0Extract
+#define        CBM_IMR_Q0I                     0x00000100//Queue0Insert
+#define        CBM_IMR_RDE                     0x00000080//ReadEmptyQueue
+#define        CBM_IMR_OPF                     0x00000040//OncePerFrame
+#define        CBM_IMR_NFCA                    0x00000020//NoFreeCellAvailable
+#define        CBM_IMR_CLP1TR                  0x00000010//CLP1ThresholdReached
+#define        CBM_IMR_CLP0TR                  0x00000008//CLP0ThresholdReached
+#define        CBM_IMR_NRTTR                   0x00000004//NonRealTimeThresholdReached
+#define        CBM_IMR_QFD                     0x00000002//QueueFrameDiscard
+#define        CBM_IMR_QTR                     0x00000001//QueueThresholdReached
+
+#define        CBM_EXSTAT_FB                   0x00000010
+#define        CBM_EXSTAT_SCB                  0x00000008
+#define        CBM_EXSTAT_Q0                   0x00000004
+#define        CBM_EXSTAT_RDE                  0x00000002
+#define        CBM_EXSTAT_QV                   0x00000001
+
+//HTU Registers
+#define        HTU_RX0_ADDR                    HTU_BASE_ADDRESS+0x10
+#define        HTU_RX1_ADDR                    HTU_BASE_ADDRESS+0x14
+#define        HTU_RES18_ADDR                  HTU_BASE_ADDRESS+0x18
+#define        HTU_RES1C_ADDR                  HTU_BASE_ADDRESS+0x1C
+#define        HTU_RES20_ADDR                  HTU_BASE_ADDRESS+0x20
+#define        HTU_RES24_ADDR                  HTU_BASE_ADDRESS+0x24
+#define        HTU_RES28_ADDR                  HTU_BASE_ADDRESS+0x28
+#define        HTU_RES2C_ADDR                  HTU_BASE_ADDRESS+0x2C
+#define        HTU_PCF0PAT_ADDR                HTU_BASE_ADDRESS+0x30
+#define        HTU_PCF1PAT_ADDR                HTU_BASE_ADDRESS+0x34
+#define        HTU_RES38_ADDR                  HTU_BASE_ADDRESS+0x38
+#define        HTU_RES3C_ADDR                  HTU_BASE_ADDRESS+0x3C
+#define        HTU_RES40_ADDR                  HTU_BASE_ADDRESS+0x40
+#define        HTU_RES44_ADDR                  HTU_BASE_ADDRESS+0x44
+#define        HTU_RES48_ADDR                  HTU_BASE_ADDRESS+0x48
+#define        HTU_RES4C_ADDR                  HTU_BASE_ADDRESS+0x4C
+#define        HTU_PCF0MASK_ADDR               HTU_BASE_ADDRESS+0x50
+#define        HTU_PCF1MASK_ADDR               HTU_BASE_ADDRESS+0x54
+#define        HTU_RES58_ADDR                  HTU_BASE_ADDRESS+0x58
+#define        HTU_RES5C_ADDR                  HTU_BASE_ADDRESS+0x5C
+#define        HTU_RES60_ADDR                  HTU_BASE_ADDRESS+0x60
+#define        HTU_RES64_ADDR                  HTU_BASE_ADDRESS+0x64
+#define        HTU_RES68_ADDR                  HTU_BASE_ADDRESS+0x68
+#define        HTU_RES6C_ADDR                  HTU_BASE_ADDRESS+0x6C
+#define        HTU_TIMEOUT_ADDR                HTU_BASE_ADDRESS+0x70
+#define        HTU_DESTOAM_ADDR                HTU_BASE_ADDRESS+0x74
+#define        HTU_DESTRM_ADDR                 HTU_BASE_ADDRESS+0x78
+#define        HTU_DESTOTHER_ADDR              HTU_BASE_ADDRESS+0x7C
+#define        HTU_CFG_ADDR                    HTU_BASE_ADDRESS+0x80
+#define        HTU_RES84_ADDR                  HTU_BASE_ADDRESS+0x84
+#define        HTU_RES88_ADDR                  HTU_BASE_ADDRESS+0x88
+#define        HTU_RES8C_ADDR                  HTU_BASE_ADDRESS+0x8C
+#define        HTU_INFNOENTRY_ADDR             HTU_BASE_ADDRESS+0x90
+#define        HTU_INFTIMEOUT_ADDR             HTU_BASE_ADDRESS+0x94
+#define        HTU_RES98_STAT                  HTU_BASE_ADDRESS+0x98
+#define        HTU_RES9C_ADDR                  HTU_BASE_ADDRESS+0x9C
+#define        HTU_MIBCIUP                     HTU_BASE_ADDRESS+0xA0//MIB Counter In Unknown Protoc Register
+#define        HTU_CNTTIMEOUT_ADDR             HTU_BASE_ADDRESS+0xA4
+#define        HTU_RESA8_ADDR                  HTU_BASE_ADDRESS+0xA8
+#define        HTU_RESAC_ADDR                  HTU_BASE_ADDRESS+0xAC
+#define        HTU_RAMADDR_ADDR                HTU_BASE_ADDRESS+0xB0
+#define        HTU_RAMCMD_ADDR                 HTU_BASE_ADDRESS+0xB4
+#define        HTU_RAMSTAT_ADDR                HTU_BASE_ADDRESS+0xB8
+#define        HTU_RESBC_ADDR                  HTU_BASE_ADDRESS+0xBC
+#define        HTU_RAMDAT1_ADDR                HTU_BASE_ADDRESS+0xC0
+#define        HTU_RAMDAT2_ADDR                HTU_BASE_ADDRESS+0xC4
+#define        HTU_RESCC_ADDR                  HTU_BASE_ADDRESS+0xCC
+#define        HTU_RESD0_ADDR                  HTU_BASE_ADDRESS+0xD0
+#define        HTU_RESD4_ADDR                  HTU_BASE_ADDRESS+0xD4
+#define        HTU_RESD8_ADDR                  HTU_BASE_ADDRESS+0xD8
+#define        HTU_RESDC_ADDR                  HTU_BASE_ADDRESS+0xDC
+#define        HTU_RESE0_ADDR                  HTU_BASE_ADDRESS+0xE0
+#define        HTU_RESE4_ADDR                  HTU_BASE_ADDRESS+0xE4
+#define        HTU_IMR0_ADDR                   HTU_BASE_ADDRESS+0xE8
+#define        HTU_RESEC_ADDR                  HTU_BASE_ADDRESS+0xEC
+#define        HTU_ISR0_ADDR                   HTU_BASE_ADDRESS+0xF0
+#define        HTU_RESF4_ADDR                  HTU_BASE_ADDRESS+0xF4
+#define        HTU_SRC0_ADDR                   HTU_BASE_ADDRESS+0xF8
+#define        HTU_RESFC_ADDR                  HTU_BASE_ADDRESS+0xFC
+
+//HTU_CFG
+#define        HTU_CFG_START                   0x00000001
+
+#define        HTU_RAMCMD_RMW                  0x00000004
+#define        HTU_RAMCMD_RD                   0x00000002
+#define        HTU_RAMCMD_WR                   0x00000001
+
+#define        HTU_RAMDAT1_VCON                0x00000080//validconnection
+#define        HTU_RAMDAT1_VCT                 0x00000040//vcivalueistransparent
+#define        HTU_RAMDAT1_QIDS                0x00000020//qid selects a cell in cbm
+#define        HTU_RAMDAT1_VCI3                0x00000010//vci3->oamqueue
+#define        HTU_RAMDAT1_VCI4                0x00000008//vci4->oamqueue
+#define        HTU_RAMDAT1_VCI6                0x00000004//vci6->rmqueue
+#define        HTU_RAMDAT1_PTI4                0x00000002//pti4->oamqueue
+#define        HTU_RAMDAT1_PTI5                0x00000001//pti5->oamqueue
+
+#define        HTU_RAMDAT2_PTI6                0x00000800
+#define        HTU_RAMDAT2_PTI7                0x00000400
+#define        HTU_RAMDAT2_F4U                 0x00000200
+#define        HTU_RAMDAT2_F5U                 0x00000100
+#define HTU_RAMDAT2_QID_MASK           0x000000ff
+
+#define        HTU_ISR_NE                      0x00000001
+#define        HTU_ISR_TORD                    0x00000002
+#define        HTU_ISR_IT                      0x00000008
+#define        HTU_ISR_OTOC                    0x00000010
+#define        HTU_ISR_ONEC                    0x00000020
+#define        HTU_ISR_PNE                     0x00000040
+#define        HTU_ISR_PT                      0x00000080
+#define        HTU_ISR_MASK                    0x000000ff
+
+
+//QSB Registers
+#define        QSB_BIP0_ADDR                   QSB_BASE_ADDRESS+0x00
+#define        QSB_BIP1_ADDR                   QSB_BASE_ADDRESS+0x04
+#define        QSB_BIP2_ADDR                   QSB_BASE_ADDRESS+0x08
+#define        QSB_BIP3_ADDR                   QSB_BASE_ADDRESS+0x0C
+#define        QSB_RSVP_ADDR                   QSB_BASE_ADDRESS+0x10
+#define        QSB_TNOW_ADDR                   QSB_BASE_ADDRESS+0x14
+#define        QSB_TNOWCYC_ADDR                QSB_BASE_ADDRESS+0x18
+#define        QSB_TAU_ADDR                    QSB_BASE_ADDRESS+0x1C
+#define        QSB_L1BRS_ADDR                  QSB_BASE_ADDRESS+0x20
+#define        QSB_SBL_ADDR                    QSB_BASE_ADDRESS+0x24
+#define        QSB_CONFIG_ADDR                 QSB_BASE_ADDRESS+0x28
+#define        QSB_RTM_ADDR                    QSB_BASE_ADDRESS+0x2C
+#define        QSB_RTD_ADDR                    QSB_BASE_ADDRESS+0x30
+#define        QSB_RAMAC_ADDR                  QSB_BASE_ADDRESS+0x34
+#define        QSB_ISR_ADDR                    QSB_BASE_ADDRESS+0x38
+#define        QSB_IMR_ADDR                    QSB_BASE_ADDRESS+0x3C
+#define        QSB_SRC_ADDR                    QSB_BASE_ADDRESS+0x40
+
+#define        QSB_TABLESEL_QVPT               8
+#define        QSB_TABLESEL_QPT                1
+#define        QSB_TABLESEL_SCT                2
+#define        QSB_TABLESEL_SPT                3
+#define        QSB_TABLESEL_CALENDARWFQ        4/*notusedbyFW*/
+#define        QSB_TABLESEL_L2WFQ              5/*notusedbyFW*/
+#define        QSB_TABLESEL_CALENDARRS         6/*notusedbyFW*/
+#define        QSB_TABLESEL_L2BITMAPRS         7/*notusedbyFW*/
+#define        QSB_TABLESEL_SHIFT              24
+#define        QSB_TWFQ_MASK                   0x3FFF0000
+#define        QSB_TPRS_MASK                   0x0000FFFF
+#define        QSB_SBID_MASK                   0xF
+#define        QSB_TWFQ_SHIFT                  16
+#define        QSB_SCDRATE_MASK                0x00007FFF
+#define        QSB_SBVALID_MASK                0x80000000
+
+#define        QSB_ISR_WFQLE                   0x00000001
+#define        QSB_ISR_WFQBE                   0x00000002
+#define        QSB_ISR_RSLE                    0x00000004
+#define        QSB_ISR_RSBE                    0x00000008
+#define        QSB_ISR_MUXOV                   0x00000010
+#define        QSB_ISR_CDVOV                   0x00000020
+#define        QSB_ISR_PARAMI                  0x00000040
+#define        QSB_ISR_SLOSS                   0x00000080
+#define        QSB_ISR_IIPS                    0x00000100
+
+#define        QSB_IMR_WFQLE                   0x00000001
+#define        QSB_IMR_WFQBE                   0x00000002
+#define        QSB_IMR_RSLE                    0x00000004
+#define        QSB_IMR_RSBE                    0x00000008
+#define        QSB_IMR_MUXOV                   0x00000010
+#define        QSB_IMR_CDVOV                   0x00000020
+#define        QSB_IMR_PARAMI                  0x00000040
+#define        QSB_IMR_SLOSS                   0x00000080
+#define        QSB_IMR_IIPS                    0x00000100
+
+#define        QSB_READ                        0x0
+#define        QSB_WRITE                       0x80000000
+#define        QSB_READ_ALL                    0xFFFFFFFF
+
+#if 1 //some bug with QSB access mask
+#define        QSB_QPT_SET_MASK                0x0
+#define QSB_QVPT_SET_MASK              0x0
+#define        QSB_SET_SCT_MASK                0x0
+#define        QSB_SET_SPT_MASK                0x0
+#define        QSB_SET_SPT_SBVALID_MASK        0x7FFFFFFF
+#else //some bug with QSB access mask
+#define        QSB_QPT_SET_MASK                0x80000000
+#define QSB_QVPT_SET_MASK              0x0
+#define        QSB_SET_SCT_MASK                0xFFFFFFE0
+#define        QSB_SET_SPT_MASK                0x7FF8C000
+#define        QSB_SET_SPT_SBVALID_MASK        0x7FFFFFFF
+#endif //some bug with QSB access mask
+
+#define        QSB_SPT_SBVALID                 0x80000000
+
+#define        QSB_RAMAC_REG_LOW               0x0
+#define        QSB_RAMAC_REG_HIGH              0x00010000
+
+#define        SRC_SRE_ENABLE                  0x1000
+#define SRC_CLRR                       0x4000  //request clear bit
+
+
+
+//SWIE Registers
+#define        SWIE_IQID_ADDR                  SWIE_BASE_ADDRESS+0x0c//SWIEInsertQueueDescriptor
+#define        SWIE_ICMD_ADDR                  SWIE_BASE_ADDRESS+0x10//SWIEInsertCommand
+#define        SWIE_ISTAT_ADDR                 SWIE_BASE_ADDRESS+0x14//SWIEInsertStatus
+#define        SWIE_ESTAT_ADDR                 SWIE_BASE_ADDRESS+0x18//SWIEExtractStatus
+#define        SWIE_ISRC_ADDR                  SWIE_BASE_ADDRESS+0x74//SWIEInsertServiceRequestControl
+#define        SWIE_ESRC_ADDR                  SWIE_BASE_ADDRESS+0x78//SWIEExtractServiceRequestControl
+#define        SWIE_ICELL_ADDR                 SWIE_BASE_ADDRESS+0x80//SWIEInsertCell(0x80-0xb4)
+#define        SWIE_ECELL_ADDR                 SWIE_BASE_ADDRESS+0xc0//SWIEExtractCell(0xc0-0xf4)
+
+#define SWIE_ISTAT_DONE                        0x1
+#define SWIE_ESTAT_DONE                        0x1
+#define        SWIE_ICMD_START                 0x00000001//Startcommandforinsertion
+#define        SWIE_CBM_SCE0                   CBM_HWEXCMD_SCE0//CBMcommandforSingle-Cell-Extract
+#define        SWIE_CBM_PID_SUBADDR            0x00001000//CBMPortIDandSubAddressforUTOPIA
+
+//Extracted cell format
+//52bytes AAL0 PDU + "Input cell additional data"(14bits)
+#define SWIE_ADDITION_DATA_MASK                0x7fff
+#define SWIE_EPORT_MASK                        0x7000//Source ID (000 AUB0, 001 AUB1)
+#define SWIE_EF4USER_MASK              0x800
+#define SWIE_EF5USER_MASK              0x400
+#define SWIE_EOAM_MASK                 0x200
+#define SWIE_EAUU_MASK                 0x100
+#define SWIE_EVCI3_MASK                        0x80
+#define SWIE_EVCI4_MASK                        0x40
+#define SWIE_EVCI6_MASK                        0x20
+#define SWIE_EPTI4_MASK                        0x10
+#define SWIE_EPTI5_MASK                        0x8
+#define SWIE_EPTI6_MASK                        0x4
+#define SWIE_EPTI7_MASK                        0x2
+#define SWIE_ECRC10ERROR_MASK          0x1
+
+#define CBM_CELL_SIZE                  0x40
+#define CBM_QD_SIZE                    0x10
+#define        AAL5R_TRAILER_LEN               12
+#define AAL5S_INBOUND_HEADER           8
+
+//constants
+//TODO: to be finalized by system guys
+//DMA QOS defined by ATM QoS Service type
+#define DMA_RX_CH0                     0
+#define DMA_RX_CH1                     1
+#define DMA_TX_CH0                     0
+#define DMA_TX_CH1                     1
+#define CBR_DMA_QOS                    CBM_QD_W3_QOS_0
+#define VBR_RT_DMA_QOS                 CBM_QD_W3_QOS_0
+#define VBR_NRT_DMA_QOS                        CBM_QD_W3_QOS_0
+#define UBR_PLUS_DMA_QOS               CBM_QD_W3_QOS_0
+#define UBR_DMA_QOS                    CBM_QD_W3_QOS_0
+
+#define        SRC_TOS_MIPS                    0
+#define        AAL5R_SRPN                      0x00000006//a5rneedshigherprioritythanDR
+#define        AAL5S_SRPN                      0x00000005
+#define        CBM_MIPS_SRPN                   0x00000004
+#define        QSB_SRPN                        0x00000023
+#define        HTU_SRPN1                       0x00000022
+#define        HTU_SRPN0                       0x00000021
+
+#endif //ATM_DEFINES_H
+
diff --git a/target/linux/amazon-2.6/files/include/asm-mips/amazon/atm_mib.h b/target/linux/amazon-2.6/files/include/asm-mips/amazon/atm_mib.h
new file mode 100644 (file)
index 0000000..f863342
--- /dev/null
@@ -0,0 +1,142 @@
+#ifndef AMAZON_ATM_MIB_H
+#define AMAZON_ATM_MIB_H
+
+#ifdef CONFIG_IFX_ATM_MIB
+#include <asm/types.h>
+#ifdef __KERNEL__
+#include <linux/list.h>
+#endif
+#endif /* CONFIG_IFX_ATM_MIB */
+
+#ifndef __KERNEL__
+#include <atmMIB/local_list.h>
+typedef unsigned int __u32;
+#endif
+
+typedef struct{
+       __u32   ifHCInOctets_h;
+       __u32   ifHCInOctets_l;
+       __u32   ifHCOutOctets_h;
+       __u32   ifHCOutOctets_l;
+       __u32   ifInErrors;
+       __u32   ifInUnknownProtos;
+       __u32   ifOutErrors;
+}atm_cell_ifEntry_t;
+
+typedef struct{
+       __u32   ifHCInOctets_h;
+       __u32   ifHCInOctets_l;
+       __u32   ifHCOutOctets_h;
+       __u32   ifHCOutOctets_l;
+       __u32   ifInUcastPkts;
+       __u32   ifOutUcastPkts;
+       __u32   ifInErrors;
+       __u32   ifInDiscards;
+       __u32   ifOutErros;
+       __u32   ifOutDiscards;
+}atm_aal5_ifEntry_t;
+
+typedef struct{
+       __u32   aal5VccCrcErrors;
+       __u32   aal5VccSarTimeOuts;//no timer support yet
+       __u32   aal5VccOverSizedSDUs;
+}atm_aal5_vcc_t;
+
+#if defined(CONFIG_IFX_ATM_MIB) || defined(IFX_CONFIG_SNMP_ATM_MIB)
+/* ATM-MIB data structures */
+typedef struct atmIfConfEntry {
+       int ifIndex;
+    int atmInterfaceMaxVpcs;
+    int atmInterfaceMaxVccs;
+    int atmInterfaceConfVpcs;
+    int atmInterfaceConfVccs;
+    int atmInterfaceMaxActiveVpiBits;
+    int atmInterfaceMaxActiveVciBits;
+    int atmInterfaceIlmiVpi;
+    int atmInterfaceIlmiVci;
+    int atmInterfaceAddressType;
+    char atmInterfaceAdminAddress[40];
+    unsigned long atmInterfaceMyNeighborIpAddress;
+    char atmInterfaceMyNeighborIfName[20];
+    int atmInterfaceCurrentMaxVpiBits;
+    int atmInterfaceCurrentMaxVciBits;
+    char atmInterfaceSubscrAddress[40];
+    int flags;
+}atmIfConfEntry;
+
+typedef struct atmTrafficDescParamEntry {
+       /* Following three parameters are used to update VCC QoS values */
+       int ifIndex;
+       short atmVclvpi;
+       int atmVclvci;
+
+       unsigned int atmTrafficParamIndex;
+       unsigned char   traffic_class;  
+       int     max_pcr;
+       /* Subramani: Added min_pcr */
+       int     min_pcr;
+       int     cdv;
+       int     scr;
+       int     mbs;
+       int atmTrafficRowStatus;
+       int atmTrafficFrameDiscard;
+       struct list_head vpivci_head;
+       struct list_head list;
+}atmTrafficDescParamEntry;
+
+
+typedef struct  atmVclEntry {
+       int ifIndex;
+       short atmVclvpi;
+       int atmVclvci;
+       char vpivci[20];
+       int  atmVclAdminStatus;
+       int atmVclOperStatus;
+       unsigned long atmVclLastChange;
+       struct atmTrafficDescParamEntry *atmVclRxTrafficPtr;
+       struct atmTrafficDescParamEntry *atmVclTxTrafficPtr;
+       unsigned char atmVccAalType;
+       unsigned int atmVccAal5TxSduSize;
+       unsigned int atmVccAal5RxSduSize;
+       int atmVccAal5Encap;
+       int atmVclRowStatus;
+       int atmVclCastType;
+       int atmVclConnKind;
+       struct list_head list;
+       int flags;
+}atmVclEntry;
+
+
+typedef union union_atmptrs {
+       struct atmIfConfEntry *atmIfConfEntry_ptr;
+       struct atmTrafficDescParamEntry *atmTrafficDescParamEntry_ptr;
+       struct atmVclEntry *atmVclEntry_ptr;
+}union_atmptrs;
+
+/* ATM Character device major number */
+#define ATM_MEI_MAJOR  107
+
+/* Protocol Constants */
+#define IFX_PROTO_RAW               0
+#define IFX_PROTO_BR2684            1
+#define IFX_PROTO_PPPOATM           2
+#define IFX_PROTO_CLIP              3
+
+/* IOCTL Command Set for ATM-MIB */
+#define GET_ATM_IF_CONF_DATA  0x0AB0
+#define SET_ATM_IF_CONF_DATA  0x0AB1
+
+#define SET_ATM_QOS_DATA      0x0BC0
+
+#define GET_ATM_VCL_DATA      0x0CD0
+#define SET_ATM_VCL_DATA      0x0CD1
+
+#define FIND_VCC_IN_KERNEL       0x0DE0
+
+/* User defined flags for VCL Table */
+#define ATMVCCAAL5CPCSTRANSMITSDUSIZE  9  
+#define ATMVCCAAL5CPCSRECEIVESDUSIZE   10 
+
+#endif /* CONFIG_IFX_ATM_MIB || IFX_CONFIG_SNMP_ATM_MIB */
+
+#endif //AMAZON_ATM_MIB_H
diff --git a/target/linux/amazon-2.6/files/include/asm-mips/amazon/ifx_peripheral_definitions.h b/target/linux/amazon-2.6/files/include/asm-mips/amazon/ifx_peripheral_definitions.h
new file mode 100644 (file)
index 0000000..65f14e4
--- /dev/null
@@ -0,0 +1,96 @@
+//*************************************************************************
+//* Summary of definitions which are used in each peripheral              *
+//*************************************************************************
+
+#ifndef peripheral_definitions_h
+#define peripheral_definitions_h
+
+typedef unsigned char          UINT8;
+typedef signed char            INT8;
+typedef unsigned short         UINT16;
+typedef signed short           INT16;
+typedef unsigned int           UINT32;
+typedef signed int             INT32;
+typedef unsigned long long     UINT64;
+typedef signed long long       INT64;
+
+#define REG8( addr )             (*(volatile UINT8 *) (addr))
+#define REG16( addr )            (*(volatile UINT16 *)(addr))
+#define REG32( addr )            (*(volatile UINT32 *)(addr))
+#define REG64( addr )            (*(volatile UINT64 *)(addr))
+
+/* define routine to set FPI access in Supervisor Mode */
+#define IFX_SUPERVISOR_ON()                         REG32(FB0_CFG) = 0x01
+/* Supervisor mode ends, following functions will be done in User mode */
+#define IFX_SUPERVISOR_OFF()                        REG32(FB0_CFG) = 0x00
+/* Supervisor mode ends, following functions will be done in User mode */
+#define IFX_SUPERVISOR_MODE()                       REG32(FB0_CFG)
+/* Supervisor mode ends, following functions will be done in User mode */
+#define IFX_SUPERVISOR_SET(svm)                     REG32(FB0_CFG) = svm
+/* enable all Interrupts in IIU */
+//#define IFX_ENABLE_IRQ(irq_mask, im_base)           REG32(im_base | IIU_MASK) = irq_mask
+///* get all high priority interrupt bits in IIU */
+//#define IFX_GET_IRQ_MASKED(im_base)                 REG32(im_base | IIU_IRMASKED)
+///* signal ends of interrupt to IIU */
+//#define IFX_CLEAR_DIRECT_IRQ(irq_bit, im_base)      REG32(im_base | IIU_IR) = irq_bit
+///* force IIU interrupt register */
+//#define IFX_FORCE_IIU_REGISTER(data, im_base)       REG32(im_base | IIU_IRDEBUG) = data
+///* get all bits of interrupt register */
+//#define IFX_GET_IRQ_UNMASKED(im_base)               REG32(im_base | IIU_IR)
+/* insert a NOP instruction */
+#define NOP                                     _nop()
+/* CPU goes to power down mode until interrupt occurs */
+#define IFX_CPU_SLEEP                               _sleep()
+/* enable all interrupts to CPU */
+#define IFX_CPU_ENABLE_ALL_INTERRUPT                sys_enable_int()
+/* get all low priority interrupt bits in peripheral */
+#define IFX_GET_LOW_PRIO_IRQ(int_reg)               REG32(int_reg)
+/* clear low priority interrupt bit in peripheral */
+#define IFX_CLEAR_LOW_PRIO_IRQ(irq_bit, int_reg)    REG32(int_reg) = irq_bit
+/* write FPI bus */
+#define WRITE_FPI_BYTE(data, addr)              REG8(addr) = data
+#define WRITE_FPI_16BIT(data, addr)             REG16(addr) = data
+#define WRITE_FPI_32BIT(data, addr)             REG32(addr) = data
+/* read FPI bus */
+#define READ_FPI_BYTE(addr)                     REG8(addr)
+#define READ_FPI_16BIT(addr)                    REG16(addr)
+#define READ_FPI_32BIT(addr)                    REG32(addr)
+/* write peripheral register */
+#define WRITE_PERIPHERAL_REGISTER(data, addr)   REG32(addr) = data 
+
+#ifdef CONFIG_CPU_LITTLE_ENDIAN
+#define WRITE_PERIPHERAL_REGISTER_16(data, addr) REG16(addr) = data
+#define WRITE_PERIPHERAL_REGISTER_8(data, addr) REG8(addr) = data
+#else //not CONFIG_CPU_LITTLE_ENDIAN
+#define WRITE_PERIPHERAL_REGISTER_16(data, addr) REG16(addr+2) = data
+#define WRITE_PERIPHERAL_REGISTER_8(data, addr) REG8(addr+3) = data
+#endif //CONFIG_CPU_LITTLE_ENDIAN
+
+/* read peripheral register */
+#define READ_PERIPHERAL_REGISTER(addr)          REG32(addr)
+
+/* read/modify(or)/write peripheral register */
+#define RMW_OR_PERIPHERAL_REGISTER(data, addr) REG32(addr) = REG32(addr) | data
+/* read/modify(and)/write peripheral register */
+#define RMW_AND_PERIPHERAL_REGISTER(data, addr)        REG32(addr) = REG32(addr) & (UINT32)data
+
+/* CPU-independent mnemonic constants */
+/* CLC register bits */
+#define IFX_CLC_ENABLE                0x00000000
+#define IFX_CLC_DISABLE               0x00000001
+#define IFX_CLC_DISABLE_STATUS        0x00000002
+#define IFX_CLC_SUSPEND_ENABLE        0x00000004
+#define IFX_CLC_CLOCK_OFF_DISABLE     0x00000008
+#define IFX_CLC_OVERWRITE_SPEN_FSOE   0x00000010
+#define IFX_CLC_FAST_CLOCK_SWITCH_OFF 0x00000020
+#define IFX_CLC_RUN_DIVIDER_MASK      0x0000FF00
+#define IFX_CLC_RUN_DIVIDER_OFFSET    8
+#define IFX_CLC_SLEEP_DIVIDER_MASK    0x00FF0000
+#define IFX_CLC_SLEEP_DIVIDER_OFFSET  16
+#define IFX_CLC_SPECIFIC_DIVIDER_MASK 0x00FF0000
+#define IFX_CLC_SPECIFIC_DIVIDER_OFFSET 24
+
+/* number of cycles to wait for interrupt service routine to be called */
+#define WAIT_CYCLES   50
+
+#endif /* PERIPHERAL_DEFINITIONS_H not yet defined */
diff --git a/target/linux/amazon-2.6/files/include/asm-mips/amazon/ifx_ssc.h b/target/linux/amazon-2.6/files/include/asm-mips/amazon/ifx_ssc.h
new file mode 100644 (file)
index 0000000..e5d73ad
--- /dev/null
@@ -0,0 +1,263 @@
+/*
+ * ifx_ssc.h defines some data sructures used in ifx_ssc.c
+ *
+ * Copyright (C) 2004 Michael Schoenenborn (IFX COM TI BT)
+ *
+ *
+ */
+
+#ifndef __IFX_SSC_H
+#define __IFX_SSC_H
+#ifdef __KERNEL__
+#include <asm/amazon/ifx_ssc_defines.h>
+#endif  //__KERNEL__
+
+#define PORT_CNT               1       // assume default value
+
+/* symbolic constants to be used in SSC routines */
+
+// ### TO DO: bad performance
+#define IFX_SSC_TXFIFO_ITL     1
+#define IFX_SSC_RXFIFO_ITL     1
+
+
+
+struct ifx_ssc_statistics{
+       unsigned int  abortErr;   /* abort error */       
+       unsigned int  modeErr;    /* master/slave mode error */       
+       unsigned int  txOvErr;    /* TX Overflow error */         
+       unsigned int  txUnErr;    /* TX Underrun error */         
+       unsigned int  rxOvErr;    /* RX Overflow error */         
+       unsigned int  rxUnErr;    /* RX Underrun error */
+       unsigned int  rxBytes;
+       unsigned int  txBytes;
+};
+
+
+struct ifx_ssc_hwopts {
+       unsigned int  AbortErrDetect :1;   /* Abort Error detection (in slave mode) */
+       unsigned int  rxOvErrDetect  :1;   /* Receive Overflow Error detection */
+       unsigned int  rxUndErrDetect :1;   /* Receive Underflow Error detection */
+       unsigned int  txOvErrDetect  :1;   /* Transmit Overflow Error detection */
+       unsigned int  txUndErrDetect :1;   /* Transmit Underflow Error detection */
+       unsigned int  echoMode       :1;   /* Echo mode */
+       unsigned int  loopBack       :1;   /* Loopback mode */
+       unsigned int  idleValue      :1;   /* Idle value */
+       unsigned int  clockPolarity  :1;   /* Idle clock is high or low */
+       unsigned int  clockPhase     :1;   /* Tx on trailing or leading edge*/
+       unsigned int  headingControl :1;   /* LSB first or MSB first */
+       unsigned int  dataWidth      :6;   /* from 2 up to 32 bits */
+       unsigned int  masterSelect   :1;   /* Master or Slave mode */
+       unsigned int  modeRxTx       :2;   /* rx/tx mode */
+       unsigned int  gpoCs          :8;   /* choose outputs to use for chip select */
+       unsigned int  gpoInv         :8;   /* invert GPO outputs */
+};
+
+
+struct ifx_ssc_frm_opts {
+       bool            FrameEnable;    // SFCON.SFEN
+       unsigned int    DataLength;     // SFCON.DLEN
+       unsigned int    PauseLength;    // SFCON.PLEN
+       unsigned int    IdleData;       // SFCON.IDAT
+       unsigned int    IdleClock;      // SFCON.ICLK
+       bool            StopAfterPause; // SFCON.STOP
+};
+
+struct ifx_ssc_frm_status {
+       bool            DataBusy;       // SFSTAT.DBSY
+       bool            PauseBusy;      // SFSTAT.PBSY
+       unsigned int    DataCount;      // SFSTAT.DCNT
+       unsigned int    PauseCount;     // SFSTAT.PCNT
+       bool            EnIntAfterData; // SFCON.IBEN
+       bool            EnIntAfterPause;// SFCON.IAEN
+};
+
+typedef struct {
+       char    *buf;
+       size_t  len;
+} ifx_ssc_buf_item_t;
+
+
+// data structures for batch execution
+typedef union {
+       struct {
+               bool            save_options;
+       } init;
+       ifx_ssc_buf_item_t      read;
+       ifx_ssc_buf_item_t      write;
+       ifx_ssc_buf_item_t      rd_wr;
+       unsigned int    set_baudrate;
+       struct ifx_ssc_frm_opts set_frm;
+       unsigned int    set_gpo;
+       struct ifx_ssc_hwopts set_hwopts;
+}ifx_ssc_batch_cmd_param;
+
+struct ifx_ssc_batch_list {
+       unsigned int                    cmd;
+       ifx_ssc_batch_cmd_param         cmd_param;
+       struct ifx_ssc_batch_list       *next;
+};
+
+#ifdef __KERNEL__
+#define IFX_SSC_IS_MASTER(p) ((p)->opts.masterSelect == SSC_MASTER_MODE)
+
+
+struct ifx_ssc_port{
+       unsigned long           mapbase;
+       struct ifx_ssc_hwopts   opts;
+       struct ifx_ssc_statistics stats;
+       struct ifx_ssc_frm_status frm_status;
+       struct ifx_ssc_frm_opts frm_opts;
+       /* wait queue for ifx_ssc_read() */
+       wait_queue_head_t       rwait, pwait;
+        int                    port_nr;
+       char                    port_is_open; /* exclusive open  - boolean */
+//     int no_of_bits; /* number of _valid_ bits */
+//     int elem_size; /* shift for element (no of bytes)*/
+       /* buffer and pointers to the read/write position */
+       char                    *rxbuf; /* buffer for RX */
+        char                    *rxbuf_end; /* buffer end pointer for RX */
+       volatile char           *rxbuf_ptr; /* buffer write pointer for RX */
+       char                    *txbuf; /* buffer for TX */
+        char                    *txbuf_end; /* buffer end pointer for TX */
+       volatile char           *txbuf_ptr; /* buffer read pointer for TX */
+       unsigned int            baud;
+       /* each channel has its own interrupts */
+       /* (transmit/receive/error/frame) */
+       unsigned int txirq, rxirq, errirq, frmirq;
+};
+/* default values for SSC configuration */
+// values of CON
+#define IFX_SSC_DEF_IDLE_DATA       1  /* enable */
+#define IFX_SSC_DEF_BYTE_VALID_CTL  1  /* enable */
+#define IFX_SSC_DEF_DATA_WIDTH      32 /* bits */
+#define IFX_SSC_DEF_ABRT_ERR_DETECT 0  /* disable */
+#define IFX_SSC_DEF_RO_ERR_DETECT   1  /* enable */
+#define IFX_SSC_DEF_RU_ERR_DETECT   0  /* disable */
+#define IFX_SSC_DEF_TO_ERR_DETECT   0  /* disable */
+#define IFX_SSC_DEF_TU_ERR_DETECT   0  /* disable */
+#define IFX_SSC_DEF_LOOP_BACK       0  /* disable */
+#define IFX_SSC_DEF_ECHO_MODE       0  /* disable */
+#define IFX_SSC_DEF_CLOCK_POLARITY  0  /* low */
+#define IFX_SSC_DEF_CLOCK_PHASE     1  /* 0: shift on leading edge, latch on trailling edge, 1, otherwise */
+#define IFX_SSC_DEF_HEADING_CONTROL IFX_SSC_MSB_FIRST
+#define IFX_SSC_DEF_MODE_RXTX      IFX_SSC_MODE_RXTX
+// other values
+#define IFX_SSC_DEF_MASTERSLAVE            IFX_SSC_MASTER_MODE /* master */
+#define IFX_SSC_DEF_BAUDRATE       1000000
+#define IFX_SSC_DEF_RMC                    0x10
+
+#define IFX_SSC_DEF_TXFIFO_FL       8
+#define IFX_SSC_DEF_RXFIFO_FL       1
+
+#if 1 //TODO
+#define IFX_SSC_DEF_GPO_CS         2   /* no chip select */
+#define IFX_SSC_DEF_GPO_INV        0   /* no chip select */
+#else
+#error "what is ur Chip Select???"
+#endif
+#define IFX_SSC_DEF_SFCON          0   /* no serial framing */
+#if 0
+#define IFX_SSC_DEF_IRNEN          IFX_SSC_T_BIT | /* enable all int's */\
+                                   IFX_SSC_R_BIT | IFX_SSC_E_BIT | IFX_SSC_F_BIT
+#endif
+#define IFX_SSC_DEF_IRNEN          IFX_SSC_T_BIT | /* enable all int's */\
+                                   IFX_SSC_R_BIT | IFX_SSC_E_BIT
+#endif /* __KERNEL__ */
+
+// batch execution commands
+#define IFX_SSC_BATCH_CMD_INIT         1
+#define IFX_SSC_BATCH_CMD_READ         2
+#define IFX_SSC_BATCH_CMD_WRITE                3
+#define IFX_SSC_BATCH_CMD_RD_WR                4
+#define IFX_SSC_BATCH_CMD_SET_BAUDRATE 5
+#define IFX_SSC_BATCH_CMD_SET_HWOPTS   6
+#define IFX_SSC_BATCH_CMD_SET_FRM      7
+#define IFX_SSC_BATCH_CMD_SET_GPO      8
+#define IFX_SSC_BATCH_CMD_FIFO_FLUSH   9
+//#define IFX_SSC_BATCH_CMD_   
+//#define IFX_SSC_BATCH_CMD_   
+#define IFX_SSC_BATCH_CMD_END_EXEC     0
+/* Macros to configure SSC hardware */
+/* headingControl: */
+#define IFX_SSC_LSB_FIRST            0
+#define IFX_SSC_MSB_FIRST            1
+/* dataWidth: */
+#define IFX_SSC_MIN_DATA_WIDTH       2
+#define IFX_SSC_MAX_DATA_WIDTH       32
+/* master/slave mode select */
+#define IFX_SSC_MASTER_MODE          1
+#define IFX_SSC_SLAVE_MODE           0
+/* rx/tx mode */
+// ### TO DO: !!! ATTENTION! Hardware dependency => move to ifx_ssc_defines.h
+#define IFX_SSC_MODE_RXTX           0
+#define IFX_SSC_MODE_RX                     1
+#define IFX_SSC_MODE_TX                     2
+#define IFX_SSC_MODE_OFF            3
+#define IFX_SSC_MODE_MASK           IFX_SSC_MODE_RX | IFX_SSC_MODE_TX
+
+/* GPO values */
+#define IFX_SSC_MAX_GPO_OUT         7
+
+#define IFX_SSC_RXREQ_BLOCK_SIZE     32768
+
+/***********************/
+/* defines for ioctl's */
+/***********************/
+#define IFX_SSC_IOCTL_MAGIC     'S'
+/* read out the statistics */
+#define IFX_SSC_STATS_READ _IOR(IFX_SSC_IOCTL_MAGIC, 1, struct ifx_ssc_statistics)
+/* clear the statistics */
+#define IFX_SSC_STATS_RESET _IO(IFX_SSC_IOCTL_MAGIC, 2)
+/* set the baudrate */
+#define IFX_SSC_BAUD_SET _IOW(IFX_SSC_IOCTL_MAGIC, 3, unsigned int)
+/* get the current baudrate */
+#define IFX_SSC_BAUD_GET _IOR(IFX_SSC_IOCTL_MAGIC, 4, unsigned int)
+/* set hardware options */
+#define IFX_SSC_HWOPTS_SET _IOW(IFX_SSC_IOCTL_MAGIC, 5, struct ifx_ssc_hwopts)
+/* get the current hardware options */
+#define IFX_SSC_HWOPTS_GET _IOR(IFX_SSC_IOCTL_MAGIC, 6, struct ifx_ssc_hwopts)
+/* set transmission mode */
+#define IFX_SSC_RXTX_MODE_SET _IOW(IFX_SSC_IOCTL_MAGIC, 7, unsigned int)
+/* get the current transmission mode */
+#define IFX_SSC_RXTX_MODE_GET _IOR(IFX_SSC_IOCTL_MAGIC, 8, unsigned int)
+/* abort transmission */
+#define IFX_SSC_ABORT _IO(IFX_SSC_IOCTL_MAGIC, 9)
+#define IFX_SSC_FIFO_FLUSH _IO(IFX_SSC_IOCTL_MAGIC, 9)
+
+/* set general purpose outputs */
+#define IFX_SSC_GPO_OUT_SET _IOW(IFX_SSC_IOCTL_MAGIC, 32, unsigned int)
+/* clear general purpose outputs */
+#define IFX_SSC_GPO_OUT_CLR _IOW(IFX_SSC_IOCTL_MAGIC, 33, unsigned int)
+/* get general purpose outputs */
+#define IFX_SSC_GPO_OUT_GET _IOR(IFX_SSC_IOCTL_MAGIC, 34, unsigned int)
+
+/*** serial framing ***/
+/* get status of serial framing */
+#define IFX_SSC_FRM_STATUS_GET _IOR(IFX_SSC_IOCTL_MAGIC, 48, struct ifx_ssc_frm_status)
+/* get counter reload values and control bits */
+#define IFX_SSC_FRM_CONTROL_GET _IOR(IFX_SSC_IOCTL_MAGIC, 49, struct ifx_ssc_frm_opts)
+/* set counter reload values and control bits */
+#define IFX_SSC_FRM_CONTROL_SET _IOW(IFX_SSC_IOCTL_MAGIC, 50, struct ifx_ssc_frm_opts)
+
+
+/*** batch execution ***/
+/* do batch execution */
+#define IFX_SSC_BATCH_EXEC _IOW(IFX_SSC_IOCTL_MAGIC, 64, struct ifx_ssc_batch_list)
+
+
+#ifdef __KERNEL__
+// routines from ifx_ssc.c
+// ### TO DO
+/* kernel interface for read and write */
+ssize_t ifx_ssc_kread(int, char *, size_t);
+ssize_t ifx_ssc_kwrite(int, const char *, size_t);
+
+#ifdef CONFIG_IFX_VP_KERNEL_TEST
+void ifx_ssc_tc(void);
+#endif // CONFIG_IFX_VP_KERNEL_TEST
+
+#endif //__KERNEL__
+#endif // __IFX_SSC_H
+
diff --git a/target/linux/amazon-2.6/files/include/asm-mips/amazon/ifx_ssc_defines.h b/target/linux/amazon-2.6/files/include/asm-mips/amazon/ifx_ssc_defines.h
new file mode 100644 (file)
index 0000000..46157dc
--- /dev/null
@@ -0,0 +1,552 @@
+#ifndef IFX_SSC_DEFINES_H
+#define IFX_SSC_DEFINES_H
+
+#include "ifx_peripheral_definitions.h"
+
+/* maximum SSC FIFO size */
+#define IFX_SSC_MAX_FIFO_SIZE 32
+
+/* register map of SSC  */
+
+/* address of the Clock Control Register of the SSC */
+#define IFX_SSC_CLC                 0x00000000
+/* IFX_SSC_CLC register is significant in bits 23 downto 8 and in bits 5, 3, 2, 0  
+   bit 1 is hardware modified*/
+#define IFX_SSC_CLC_readmask  0x00FFFFEF
+#define IFX_SSC_CLC_writemask 0x00FFFF3D
+#define IFX_SSC_CLC_hwmask    0x00000002
+#define IFX_SSC_CLC_dontcare (IFX_SSC_CLC_readmask & IFX_SSC_CLC_writemask & ~IFX_SSC_CLC_hwmask)
+
+/* address of Port Input Select Register of the SSC */
+#define IFX_SSC_PISEL 0x00000004
+/* IFX_SSC_PISEL register is significant in lowest three bits only */
+#define IFX_SSC_PISEL_readmask  0x00000007
+#define IFX_SSC_PISEL_writemask 0x00000007
+#define IFX_SSC_PISEL_hwmask    0x00000000
+#define IFX_SSC_PISEL_dontcare (IFX_SSC_PISEL_readmask & IFX_SSC_PISEL_writemask & ~IFX_SSC_PISEL_hwmask)
+
+/* address of Identification Register of the SSC */
+#define IFX_SSC_ID 0x00000008
+/* IFX_SSC_ID register is significant in no bit */
+#define IFX_SSC_ID_readmask  0x0000FF3F
+#define IFX_SSC_ID_writemask 0x00000000
+#define IFX_SSC_ID_hwmask    0x00000000
+#define IFX_SSC_ID_dontcare (IFX_SSC_ID_readmask & IFX_SSC_ID_writemask & ~IFX_SSC_ID_hwmask)
+
+/* address of the Control Register of the SSC */
+#define IFX_SSC_CON            0x00000010
+/* IFX_SSC_CON register is significant in bits 23:22, 20:16 and 12:0 */
+#define IFX_SSC_CON_readmask  0x01DF1FFF
+#define IFX_SSC_CON_writemask 0x01DF1FFF
+#define IFX_SSC_CON_hwmask    0x00000000
+#define IFX_SSC_CON_dontcare (IFX_SSC_CON_readmask & IFX_SSC_CON_writemask & ~IFX_SSC_CON_hwmask)
+
+
+/* address of the Status Register of the SSC */
+#define IFX_SSC_STATE          0x00000014
+/* IFX_SSC_STATE register is readable in bits 30:28, 26:24, 20:16, 12:7 and 2:0
+   all bits except 1:0 are hardware modified */
+#define IFX_SSC_STATE_readmask  0x771F3F87
+#define IFX_SSC_STATE_writemask 0x00000000
+#define IFX_SSC_STATE_hwmask    0x771F3F84
+#define IFX_SSC_STATE_dontcare (IFX_SSC_STATE_readmask & IFX_SSC_STATE_writemask & ~IFX_SSC_STATE_hwmask)
+
+/* address of the Write Hardware Modified Control Register Bits of the SSC */
+#define IFX_SSC_WHBSTATE            0x00000018
+/* IFX_SSC_WHBSTATE register is write only */
+#define IFX_SSC_WHBSTATE_readmask  0x00000000
+#define IFX_SSC_WHBSTATE_writemask 0x0000FFFF
+#define IFX_SSC_WHBSTATE_hwmask    0x00000000
+#define IFX_SSC_WHBSTATE_dontcare (IFX_SSC_WHBSTATE_readmask & IFX_SSC_WHBSTATE_writemask & ~IFX_SSC_WHBSTATE_hwmask)
+
+/* address of the Baudrate Timer Reload Register of the SSC */
+#define IFX_SSC_BR              0x00000040
+/* IFX_SSC_BR register is significant in  bit 15 downto 0*/
+#define IFX_SSC_BR_readmask  0x0000FFFF
+#define IFX_SSC_BR_writemask 0x0000FFFF
+#define IFX_SSC_BR_hwmask    0x00000000
+#define IFX_SSC_BR_dontcare (IFX_SSC_BR_readmask & IFX_SSC_BR_writemask & ~IFX_SSC_BR_hwmask)
+
+/* address of the Baudrate Timer Status Register of the SSC */
+#define IFX_SSC_BRSTAT              0x00000044
+/* IFX_SSC_BRSTAT register is significant in  bit 15 downto 0*/
+#define IFX_SSC_BRSTAT_readmask  0x0000FFFF
+#define IFX_SSC_BRSTAT_writemask 0x00000000
+#define IFX_SSC_BRSTAT_hwmask    0x0000FFFF
+#define IFX_SSC_BRSTAT_dontcare (IFX_SSC_BRSTAT_readmask & IFX_SSC_BRSTAT_writemask & ~IFX_SSC_BRSTAT_hwmask)
+
+/* address of the Transmitter Buffer Register of the SSC */
+#define IFX_SSC_TB              0x00000020
+/* IFX_SSC_TB register is significant in  bit 31 downto 0*/
+#define IFX_SSC_TB_readmask  0xFFFFFFFF
+#define IFX_SSC_TB_writemask 0xFFFFFFFF
+#define IFX_SSC_TB_hwmask    0x00000000
+#define IFX_SSC_TB_dontcare (IFX_SSC_TB_readmask & IFX_SSC_TB_writemask & ~IFX_SSC_TB_hwmask)
+
+/* address of the Reciver Buffer Register of the SSC */
+#define IFX_SSC_RB              0x00000024
+/* IFX_SSC_RB register is significant in no bits*/
+#define IFX_SSC_RB_readmask  0xFFFFFFFF
+#define IFX_SSC_RB_writemask 0x00000000
+#define IFX_SSC_RB_hwmask    0xFFFFFFFF
+#define IFX_SSC_RB_dontcare (IFX_SSC_RB_readmask & IFX_SSC_RB_writemask & ~IFX_SSC_RB_hwmask)
+
+/* address of the Receive FIFO Control Register of the SSC */
+#define IFX_SSC_RXFCON              0x00000030
+/* IFX_SSC_RXFCON register is significant in bit 13 downto 8 and bit 1 downto 0 */
+#define IFX_SSC_RXFCON_readmask  0x00003F03
+#define IFX_SSC_RXFCON_writemask 0x00003F03
+#define IFX_SSC_RXFCON_hwmask    0x00000000
+#define IFX_SSC_RXFCON_dontcare (IFX_SSC_RXFCON_readmask & IFX_SSC_RXFCON_writemask & ~IFX_SSC_RXFCON_hwmask)
+
+/* address of the Transmit FIFO Control Register of the SSC */
+#define IFX_SSC_TXFCON              0x00000034
+/* IFX_SSC_TXFCON register is significant in bit 13 downto 8 and bit 1 downto 0 */
+#define IFX_SSC_TXFCON_readmask  0x00003F03
+#define IFX_SSC_TXFCON_writemask 0x00003F03
+#define IFX_SSC_TXFCON_hwmask    0x00000000
+#define IFX_SSC_TXFCON_dontcare (IFX_SSC_TXFCON_readmask & IFX_SSC_TXFCON_writemask & ~IFX_SSC_TXFCON_hwmask)
+
+/* address of the FIFO Status Register of the SSC */
+#define IFX_SSC_FSTAT               0x00000038
+/* IFX_SSC_FSTAT register is significant in no bit*/
+#define IFX_SSC_FSTAT_readmask  0x00003F3F
+#define IFX_SSC_FSTAT_writemask 0x00000000
+#define IFX_SSC_FSTAT_hwmask    0x00003F3F
+#define IFX_SSC_FSTAT_dontcare (IFX_SSC_FSTAT_readmask & IFX_SSC_FSTAT_writemask & ~IFX_SSC_FSTAT_hwmask)
+
+/* address of the Data Frame Control register of the SSC */
+#define IFX_SSC_SFCON               0x00000060
+#define IFX_SSC_SFCON_readmask  0xFFDFFFFD
+#define IFX_SSC_SFCON_writemask 0xFFDFFFFD
+#define IFX_SSC_SFCON_hwmask    0x00000000
+#define IFX_SSC_SFCON_dontcare (IFX_SSC_SFCON_readmask & IFX_SSC_SFCON_writemask & ~IFX_SSC_SFCON_hwmask)
+
+/* address of the Data Frame Status register of the SSC */
+#define IFX_SSC_SFSTAT               0x00000064
+#define IFX_SSC_SFSTAT_readmask  0xFFC0FFF3
+#define IFX_SSC_SFSTAT_writemask 0x00000000
+#define IFX_SSC_SFSTAT_hwmask    0xFFC0FFF3
+#define IFX_SSC_SFSTAT_dontcare (IFX_SSC_SFSTAT_readmask & IFX_SSC_SFSTAT_writemask & ~IFX_SSC_SFSTAT_hwmask)
+
+/* address of the General Purpose Output Control register of the SSC */
+#define IFX_SSC_GPOCON               0x00000070
+#define IFX_SSC_GPOCON_readmask  0x0000FFFF
+#define IFX_SSC_GPOCON_writemask 0x0000FFFF
+#define IFX_SSC_GPOCON_hwmask    0x00000000
+#define IFX_SSC_GPOCON_dontcare (IFX_SSC_GPOCON_readmask & IFX_SSC_GPOCON_writemask & ~IFX_SSC_GPOCON_hwmask)
+
+/* address of the General Purpose Output Status register of the SSC */
+#define IFX_SSC_GPOSTAT               0x00000074
+#define IFX_SSC_GPOSTAT_readmask  0x000000FF
+#define IFX_SSC_GPOSTAT_writemask 0x00000000
+#define IFX_SSC_GPOSTAT_hwmask    0x00000000
+#define IFX_SSC_GPOSTAT_dontcare (IFX_SSC_GPOSTAT_readmask & IFX_SSC_GPOSTAT_writemask & ~IFX_SSC_GPOSTAT_hwmask)
+
+/* address of the Force GPO Status register of the SSC */
+#define IFX_SSC_WHBGPOSTAT               0x00000078
+#define IFX_SSC_WHBGPOSTAT_readmask  0x00000000
+#define IFX_SSC_WHBGPOSTAT_writemask 0x0000FFFF
+#define IFX_SSC_WHBGPOSTAT_hwmask    0x00000000
+#define IFX_SSC_WHBGPOSTAT_dontcare (IFX_SSC_WHBGPOSTAT_readmask & IFX_SSC_WHBGPOSTAT_writemask & ~IFX_SSC_WHBGPOSTAT_hwmask)
+
+/* address of the Receive Request Register of the SSC */
+#define IFX_SSC_RXREQ               0x00000080
+#define IFX_SSC_RXREQ_readmask  0x0000FFFF
+#define IFX_SSC_RXREQ_writemask 0x0000FFFF
+#define IFX_SSC_RXREQ_hwmask    0x00000000
+#define IFX_SSC_RXREQ_dontcare (IFX_SSC_RXREQ_readmask & IFX_SSC_RXREQ_writemask & ~IFX_SSC_RXREQ_hwmask)
+
+/* address of the Receive Count Register of the SSC */
+#define IFX_SSC_RXCNT               0x00000084
+#define IFX_SSC_RXCNT_readmask  0x0000FFFF
+#define IFX_SSC_RXCNT_writemask 0x00000000
+#define IFX_SSC_RXCNT_hwmask    0x0000FFFF
+#define IFX_SSC_RXCNT_dontcare (IFX_SSC_RXCNT_readmask & IFX_SSC_RXCNT_writemask & ~IFX_SSC_RXCNT_hwmask)
+
+/* address of the DMA Configuration Register of the SSC */
+#define IFX_SSC_DMACON               0x000000EC
+#define IFX_SSC_DMACON_readmask  0x0000FFFF
+#define IFX_SSC_DMACON_writemask 0x00000000
+#define IFX_SSC_DMACON_hwmask    0x0000FFFF
+#define IFX_SSC_DMACON_dontcare (IFX_SSC_DMACON_readmask & IFX_SSC_DMACON_writemask & ~IFX_SSC_DMACON_hwmask)
+
+//------------------------------------------------------
+// interrupt register for enabling interrupts, mask register of irq_reg
+#define IFX_SSC_IRN_EN 0xF4
+// read/write
+#define IFX_SSC_IRN_EN_readmask  0x0000000F
+#define IFX_SSC_IRN_EN_writemask 0x0000000F
+#define IFX_SSC_IRN_EN_hwmask    0x00000000
+#define IFX_SSC_IRN_EN_dontcare  (IFX_SSC_IRN_EN_readmask & IFX_SSC_IRN_EN_writemask & ~IFX_SSC_IRN_EN_hwmask)
+
+// interrupt register for accessing interrupts
+#define IFX_SSC_IRN_CR                0xF8
+// read/write
+#define IFX_SSC_IRN_CR_readmask  0x0000000F
+#define IFX_SSC_IRN_CR_writemask 0x0000000F
+#define IFX_SSC_IRN_CR_hwmask    0x0000000F
+#define IFX_SSC_IRN_CR_dontcare  (IFX_SSC_IRN_CR_readmask & IFX_SSC_IRN_CR_writemask & ~IFX_SSC_IRN_CR_hwmask)
+
+// interrupt register for stimulating interrupts
+#define IFX_SSC_IRN_ICR                  0xFC
+// read/write
+#define IFX_SSC_IRN_ICR_readmask  0x0000000F
+#define IFX_SSC_IRN_ICR_writemask 0x0000000F
+#define IFX_SSC_IRN_ICR_hwmask    0x00000000
+#define IFX_SSC_IRN_ICR_dontcare  (IFX_SSC_IRN_ICR_readmask & IFX_SSC_IRN_ICR_writemask & ~IFX_SSC_IRN_ICR_hwmask)
+
+//---------------------------------------------------------------------
+// Number of IRQs and bitposition of IRQ
+#define IFX_SSC_NUM_IRQ           4
+#define IFX_SSC_T_BIT       0x00000001
+#define IFX_SSC_R_BIT       0x00000002
+#define IFX_SSC_E_BIT       0x00000004
+#define IFX_SSC_F_BIT       0x00000008
+
+/* bit masks for SSC registers */
+
+/* ID register */
+#define IFX_SSC_PERID_REV_MASK      0x0000001F
+#define IFX_SSC_PERID_CFG_MASK      0x00000020
+#define IFX_SSC_PERID_ID_MASK       0x0000FF00
+#define IFX_SSC_PERID_REV_OFFSET    0
+#define IFX_SSC_PERID_CFG_OFFSET    5
+#define IFX_SSC_PERID_ID_OFFSET     8
+#define IFX_SSC_PERID_ID            0x45
+#define IFX_SSC_PERID_DMA_ON        0x00000020
+#define IFX_SSC_PERID_RXFS_MASK     0x003F0000
+#define IFX_SSC_PERID_RXFS_OFFSET   16
+#define IFX_SSC_PERID_TXFS_MASK     0x3F000000
+#define IFX_SSC_PERID_TXFS_OFFSET   24
+
+/* PISEL register */
+#define IFX_SSC_PISEL_MASTER_IN_A       0x0000
+#define IFX_SSC_PISEL_MASTER_IN_B       0x0001
+#define IFX_SSC_PISEL_SLAVE_IN_A        0x0000
+#define IFX_SSC_PISEL_SLAVE_IN_B        0x0002
+#define IFX_SSC_PISEL_CLOCK_IN_A        0x0000
+#define IFX_SSC_PISEL_CLOCK_IN_B        0x0004
+
+
+/* IFX_SSC_CON register */
+#define IFX_SSC_CON_ECHO_MODE_ON       0x01000000
+#define IFX_SSC_CON_ECHO_MODE_OFF      0x00000000
+#define IFX_SSC_CON_IDLE_HIGH          0x00800000
+#define IFX_SSC_CON_IDLE_LOW           0x00000000
+#define IFX_SSC_CON_ENABLE_BYTE_VALID  0x00400000
+#define IFX_SSC_CON_DISABLE_BYTE_VALID 0x00000000
+#define IFX_SSC_CON_DATA_WIDTH_OFFSET  16
+#define IFX_SSC_CON_DATA_WIDTH_MASK    0x001F0000
+#define IFX_SSC_ENCODE_DATA_WIDTH(width) (((width - 1) << IFX_SSC_CON_DATA_WIDTH_OFFSET) & IFX_SSC_CON_DATA_WIDTH_MASK)
+
+#define IFX_SSC_CON_RESET_ON_BAUDERR   0x00002000
+#define IFX_SSC_CON_GO_ON_ON_BAUDERR   0x00000000
+
+#define IFX_SSC_CON_RX_UFL_CHECK       0x00001000
+#define IFX_SSC_CON_RX_UFL_IGNORE      0x00000000
+#define IFX_SSC_CON_TX_UFL_CHECK       0x00000800
+#define IFX_SSC_CON_TX_UFL_IGNORE      0x00000000
+#define IFX_SSC_CON_ABORT_ERR_CHECK    0x00000400
+#define IFX_SSC_CON_ABORT_ERR_IGNORE   0x00000000
+#define IFX_SSC_CON_RX_OFL_CHECK       0x00000200
+#define IFX_SSC_CON_RX_OFL_IGNORE      0x00000000
+#define IFX_SSC_CON_TX_OFL_CHECK       0x00000100
+#define IFX_SSC_CON_TX_OFL_IGNORE      0x00000000
+#define IFX_SSC_CON_ALL_ERR_CHECK      0x00001F00
+#define IFX_SSC_CON_ALL_ERR_IGNORE     0x00000000
+
+#define IFX_SSC_CON_LOOPBACK_MODE      0x00000080
+#define IFX_SSC_CON_NO_LOOPBACK        0x00000000
+#define IFX_SSC_CON_HALF_DUPLEX        0x00000080
+#define IFX_SSC_CON_FULL_DUPLEX        0x00000000
+#define IFX_SSC_CON_CLOCK_FALL         0x00000040
+#define IFX_SSC_CON_CLOCK_RISE         0x00000000
+#define IFX_SSC_CON_SHIFT_THEN_LATCH   0x00000000
+#define IFX_SSC_CON_LATCH_THEN_SHIFT   0x00000020
+#define IFX_SSC_CON_MSB_FIRST          0x00000010
+#define IFX_SSC_CON_LSB_FIRST          0x00000000
+#define IFX_SSC_CON_ENABLE_CSB         0x00000008
+#define IFX_SSC_CON_DISABLE_CSB        0x00000000
+#define IFX_SSC_CON_INVERT_CSB         0x00000004
+#define IFX_SSC_CON_TRUE_CSB           0x00000000
+#define IFX_SSC_CON_RX_OFF             0x00000002
+#define IFX_SSC_CON_RX_ON              0x00000000
+#define IFX_SSC_CON_TX_OFF             0x00000001
+#define IFX_SSC_CON_TX_ON              0x00000000
+
+
+/* IFX_SSC_STATE register */
+#define IFX_SSC_STATE_RX_BYTE_VALID_OFFSET 28
+#define IFX_SSC_STATE_RX_BYTE_VALID_MASK   0x70000000
+#define IFX_SSC_DECODE_RX_BYTE_VALID(con_state) ((con_state & IFX_SSC_STATE_RX_BYTE_VALID_MASK) >> IFX_SSC_STATE_RX_BYTE_VALID_OFFSET)
+#define IFX_SSC_STATE_TX_BYTE_VALID_OFFSET 24
+#define IFX_SSC_STATE_TX_BYTE_VALID_MASK   0x07000000
+#define IFX_SSC_DECODE_TX_BYTE_VALID(con_state) ((con_state & IFX_SSC_STATE_TX_BYTE_VALID_MASK) >> IFX_SSC_STATE_TX_BYTE_VALID_OFFSET)
+#define IFX_SSC_STATE_BIT_COUNT_OFFSET     16
+#define IFX_SSC_STATE_BIT_COUNT_MASK       0x001F0000
+#define IFX_SSC_DECODE_DATA_WIDTH(con_state) (((con_state & IFX_SSC_STATE_BIT_COUNT_MASK) >> IFX_SSC_STATE_BIT_COUNT_OFFSET) + 1)
+#define IFX_SSC_STATE_BUSY                 0x00002000
+#define IFX_SSC_STATE_RX_UFL               0x00001000
+#define IFX_SSC_STATE_TX_UFL               0x00000800
+#define IFX_SSC_STATE_ABORT_ERR            0x00000400
+#define IFX_SSC_STATE_RX_OFL               0x00000200
+#define IFX_SSC_STATE_TX_OFL               0x00000100
+#define IFX_SSC_STATE_MODE_ERR             0x00000080
+#define IFX_SSC_STATE_SLAVE_IS_SELECTED    0x00000004
+#define IFX_SSC_STATE_IS_MASTER            0x00000002
+#define IFX_SSC_STATE_IS_ENABLED           0x00000001
+                             
+/* WHBSTATE register */
+#define IFX_SSC_WHBSTATE_DISABLE_SSC        0x0001
+#define IFX_SSC_WHBSTATE_CONFIGURATION_MODE 0x0001
+#define IFX_SSC_WHBSTATE_CLR_ENABLE         0x0001
+
+#define IFX_SSC_WHBSTATE_ENABLE_SSC         0x0002
+#define IFX_SSC_WHBSTATE_RUN_MODE           0x0002
+#define IFX_SSC_WHBSTATE_SET_ENABLE         0x0002
+
+#define IFX_SSC_WHBSTATE_SLAVE_MODE         0x0004
+#define IFX_SSC_WHBSTATE_CLR_MASTER_SELECT  0x0004
+
+#define IFX_SSC_WHBSTATE_MASTER_MODE        0x0008
+#define IFX_SSC_WHBSTATE_SET_MASTER_SELECT  0x0008
+
+#define IFX_SSC_WHBSTATE_CLR_RX_UFL_ERROR   0x0010
+#define IFX_SSC_WHBSTATE_SET_RX_UFL_ERROR   0x0020
+
+#define IFX_SSC_WHBSTATE_CLR_MODE_ERROR     0x0040
+#define IFX_SSC_WHBSTATE_SET_MODE_ERROR     0x0080
+
+#define IFX_SSC_WHBSTATE_CLR_TX_OFL_ERROR   0x0100
+#define IFX_SSC_WHBSTATE_CLR_RX_OFL_ERROR   0x0200
+#define IFX_SSC_WHBSTATE_CLR_ABORT_ERROR    0x0400
+#define IFX_SSC_WHBSTATE_CLR_TX_UFL_ERROR   0x0800
+#define IFX_SSC_WHBSTATE_SET_TX_OFL_ERROR   0x1000
+#define IFX_SSC_WHBSTATE_SET_RX_OFL_ERROR   0x2000
+#define IFX_SSC_WHBSTATE_SET_ABORT_ERROR    0x4000
+#define IFX_SSC_WHBSTATE_SET_TX_UFL_ERROR   0x8000
+#define IFX_SSC_WHBSTATE_CLR_ALL_ERROR      0x0F50
+#define IFX_SSC_WHBSTATE_SET_ALL_ERROR      0xF0A0
+
+/* BR register */
+#define IFX_SSC_BR_BAUDRATE_OFFSET      0
+#define IFX_SSC_BR_BAUDRATE_MASK        0xFFFF
+
+/* BR_STAT register */
+#define IFX_SSC_BRSTAT_BAUDTIMER_OFFSET      0
+#define IFX_SSC_BRSTAT_BAUDTIMER_MASK        0xFFFF
+
+/* TB register */
+#define IFX_SSC_TB_DATA_OFFSET      0
+#define IFX_SSC_TB_DATA_MASK        0xFFFFFFFF
+
+/* RB register */
+#define IFX_SSC_RB_DATA_OFFSET      0
+#define IFX_SSC_RB_DATA_MASK        0xFFFFFFFF
+
+
+/* RXFCON and TXFCON registers */
+#define IFX_SSC_XFCON_FIFO_DISABLE      0x0000
+#define IFX_SSC_XFCON_FIFO_ENABLE       0x0001
+#define IFX_SSC_XFCON_FIFO_FLUSH        0x0002
+#define IFX_SSC_XFCON_ITL_MASK          0x00003F00
+#define IFX_SSC_XFCON_ITL_OFFSET        8
+
+/* FSTAT register */
+#define IFX_SSC_FSTAT_RECEIVED_WORDS_OFFSET  0
+#define IFX_SSC_FSTAT_RECEIVED_WORDS_MASK    0x003F
+#define IFX_SSC_FSTAT_TRANSMIT_WORDS_OFFSET  8
+#define IFX_SSC_FSTAT_TRANSMIT_WORDS_MASK    0x3F00
+
+/* GPOCON register */
+#define IFX_SSC_GPOCON_INVOUT0_POS      0
+#define IFX_SSC_GPOCON_INV_OUT0         0x00000001
+#define IFX_SSC_GPOCON_TRUE_OUT0        0x00000000
+#define IFX_SSC_GPOCON_INVOUT1_POS      1
+#define IFX_SSC_GPOCON_INV_OUT1         0x00000002
+#define IFX_SSC_GPOCON_TRUE_OUT1        0x00000000
+#define IFX_SSC_GPOCON_INVOUT2_POS      2
+#define IFX_SSC_GPOCON_INV_OUT2         0x00000003
+#define IFX_SSC_GPOCON_TRUE_OUT2        0x00000000
+#define IFX_SSC_GPOCON_INVOUT3_POS      3
+#define IFX_SSC_GPOCON_INV_OUT3         0x00000008
+#define IFX_SSC_GPOCON_TRUE_OUT3        0x00000000
+#define IFX_SSC_GPOCON_INVOUT4_POS      4
+#define IFX_SSC_GPOCON_INV_OUT4         0x00000010
+#define IFX_SSC_GPOCON_TRUE_OUT4        0x00000000
+#define IFX_SSC_GPOCON_INVOUT5_POS      5
+#define IFX_SSC_GPOCON_INV_OUT5         0x00000020
+#define IFX_SSC_GPOCON_TRUE_OUT5        0x00000000
+#define IFX_SSC_GPOCON_INVOUT6_POS      6
+#define IFX_SSC_GPOCON_INV_OUT6         0x00000040
+#define IFX_SSC_GPOCON_TRUE_OUT6        0x00000000
+#define IFX_SSC_GPOCON_INVOUT7_POS      7
+#define IFX_SSC_GPOCON_INV_OUT7         0x00000080
+#define IFX_SSC_GPOCON_TRUE_OUT7        0x00000000
+#define IFX_SSC_GPOCON_INV_OUT_ALL      0x000000FF
+#define IFX_SSC_GPOCON_TRUE_OUT_ALL     0x00000000
+
+#define IFX_SSC_GPOCON_ISCSB0_POS       8
+#define IFX_SSC_GPOCON_IS_CSB0          0x00000100
+#define IFX_SSC_GPOCON_IS_GPO0          0x00000000
+#define IFX_SSC_GPOCON_ISCSB1_POS       9
+#define IFX_SSC_GPOCON_IS_CSB1          0x00000200
+#define IFX_SSC_GPOCON_IS_GPO1          0x00000000
+#define IFX_SSC_GPOCON_ISCSB2_POS       10
+#define IFX_SSC_GPOCON_IS_CSB2          0x00000400
+#define IFX_SSC_GPOCON_IS_GPO2          0x00000000
+#define IFX_SSC_GPOCON_ISCSB3_POS       11
+#define IFX_SSC_GPOCON_IS_CSB3          0x00000800
+#define IFX_SSC_GPOCON_IS_GPO3          0x00000000
+#define IFX_SSC_GPOCON_ISCSB4_POS       12
+#define IFX_SSC_GPOCON_IS_CSB4          0x00001000
+#define IFX_SSC_GPOCON_IS_GPO4          0x00000000
+#define IFX_SSC_GPOCON_ISCSB5_POS       13
+#define IFX_SSC_GPOCON_IS_CSB5          0x00002000
+#define IFX_SSC_GPOCON_IS_GPO5          0x00000000
+#define IFX_SSC_GPOCON_ISCSB6_POS       14
+#define IFX_SSC_GPOCON_IS_CSB6          0x00004000
+#define IFX_SSC_GPOCON_IS_GPO6          0x00000000
+#define IFX_SSC_GPOCON_ISCSB7_POS       15
+#define IFX_SSC_GPOCON_IS_CSB7          0x00008000
+#define IFX_SSC_GPOCON_IS_GPO7          0x00000000
+#define IFX_SSC_GPOCON_IS_CSB_ALL       0x0000FF00
+#define IFX_SSC_GPOCON_IS_GPO_ALL       0x00000000
+
+/* GPOSTAT register */
+#define IFX_SSC_GPOSTAT_OUT0            0x00000001
+#define IFX_SSC_GPOSTAT_OUT1            0x00000002
+#define IFX_SSC_GPOSTAT_OUT2            0x00000004
+#define IFX_SSC_GPOSTAT_OUT3            0x00000008
+#define IFX_SSC_GPOSTAT_OUT4            0x00000010
+#define IFX_SSC_GPOSTAT_OUT5            0x00000020
+#define IFX_SSC_GPOSTAT_OUT6            0x00000040
+#define IFX_SSC_GPOSTAT_OUT7            0x00000080
+#define IFX_SSC_GPOSTAT_OUT_ALL         0x000000FF
+
+/* WHBGPOSTAT register */
+#define IFX_SSC_WHBGPOSTAT_CLROUT0_POS  0
+#define IFX_SSC_WHBGPOSTAT_CLR_OUT0     0x00000001
+#define IFX_SSC_WHBGPOSTAT_CLROUT1_POS  1
+#define IFX_SSC_WHBGPOSTAT_CLR_OUT1     0x00000002
+#define IFX_SSC_WHBGPOSTAT_CLROUT2_POS  2
+#define IFX_SSC_WHBGPOSTAT_CLR_OUT2     0x00000004
+#define IFX_SSC_WHBGPOSTAT_CLROUT3_POS  3
+#define IFX_SSC_WHBGPOSTAT_CLR_OUT3     0x00000008
+#define IFX_SSC_WHBGPOSTAT_CLROUT4_POS  4
+#define IFX_SSC_WHBGPOSTAT_CLR_OUT4     0x00000010
+#define IFX_SSC_WHBGPOSTAT_CLROUT5_POS  5
+#define IFX_SSC_WHBGPOSTAT_CLR_OUT5     0x00000020
+#define IFX_SSC_WHBGPOSTAT_CLROUT6_POS  6
+#define IFX_SSC_WHBGPOSTAT_CLR_OUT6     0x00000040
+#define IFX_SSC_WHBGPOSTAT_CLROUT7_POS  7
+#define IFX_SSC_WHBGPOSTAT_CLR_OUT7     0x00000080
+#define IFX_SSC_WHBGPOSTAT_CLR_OUT_ALL  0x000000FF
+
+#define IFX_SSC_WHBGPOSTAT_OUT0_POS  0
+#define IFX_SSC_WHBGPOSTAT_OUT1_POS  1
+#define IFX_SSC_WHBGPOSTAT_OUT2_POS  2
+#define IFX_SSC_WHBGPOSTAT_OUT3_POS  3
+#define IFX_SSC_WHBGPOSTAT_OUT4_POS  4
+#define IFX_SSC_WHBGPOSTAT_OUT5_POS  5
+#define IFX_SSC_WHBGPOSTAT_OUT6_POS  6
+#define IFX_SSC_WHBGPOSTAT_OUT7_POS  7
+
+
+#define IFX_SSC_WHBGPOSTAT_SETOUT0_POS  8
+#define IFX_SSC_WHBGPOSTAT_SET_OUT0     0x00000100
+#define IFX_SSC_WHBGPOSTAT_SETOUT1_POS  9
+#define IFX_SSC_WHBGPOSTAT_SET_OUT1     0x00000200
+#define IFX_SSC_WHBGPOSTAT_SETOUT2_POS  10
+#define IFX_SSC_WHBGPOSTAT_SET_OUT2     0x00000400
+#define IFX_SSC_WHBGPOSTAT_SETOUT3_POS  11
+#define IFX_SSC_WHBGPOSTAT_SET_OUT3     0x00000800
+#define IFX_SSC_WHBGPOSTAT_SETOUT4_POS  12
+#define IFX_SSC_WHBGPOSTAT_SET_OUT4     0x00001000
+#define IFX_SSC_WHBGPOSTAT_SETOUT5_POS  13
+#define IFX_SSC_WHBGPOSTAT_SET_OUT5     0x00002000
+#define IFX_SSC_WHBGPOSTAT_SETOUT6_POS  14
+#define IFX_SSC_WHBGPOSTAT_SET_OUT6     0x00004000
+#define IFX_SSC_WHBGPOSTAT_SETOUT7_POS  15
+#define IFX_SSC_WHBGPOSTAT_SET_OUT7     0x00008000
+#define IFX_SSC_WHBGPOSTAT_SET_OUT_ALL  0x0000FF00
+
+/* SFCON register */
+#define IFX_SSC_SFCON_SF_ENABLE                0x00000001
+#define IFX_SSC_SFCON_SF_DISABLE               0x00000000
+#define IFX_SSC_SFCON_FIR_ENABLE_BEFORE_PAUSE  0x00000004
+#define IFX_SSC_SFCON_FIR_DISABLE_BEFORE_PAUSE 0x00000000
+#define IFX_SSC_SFCON_FIR_ENABLE_AFTER_PAUSE   0x00000008
+#define IFX_SSC_SFCON_FIR_DISABLE_AFTER_PAUSE  0x00000000
+#define IFX_SSC_SFCON_DATA_LENGTH_MASK         0x0000FFF0
+#define IFX_SSC_SFCON_DATA_LENGTH_OFFSET       4
+#define IFX_SSC_SFCON_PAUSE_DATA_MASK          0x00030000
+#define IFX_SSC_SFCON_PAUSE_DATA_OFFSET        16
+#define IFX_SSC_SFCON_PAUSE_DATA_0             0x00000000
+#define IFX_SSC_SFCON_PAUSE_DATA_1             0x00010000
+#define IFX_SSC_SFCON_PAUSE_DATA_IDLE          0x00020000
+#define IFX_SSC_SFCON_PAUSE_CLOCK_MASK         0x000C0000
+#define IFX_SSC_SFCON_PAUSE_CLOCK_OFFSET       18
+#define IFX_SSC_SFCON_PAUSE_CLOCK_0            0x00000000
+#define IFX_SSC_SFCON_PAUSE_CLOCK_1            0x00040000
+#define IFX_SSC_SFCON_PAUSE_CLOCK_IDLE         0x00080000
+#define IFX_SSC_SFCON_PAUSE_CLOCK_RUN          0x000C0000
+#define IFX_SSC_SFCON_STOP_AFTER_PAUSE         0x00100000
+#define IFX_SSC_SFCON_CONTINUE_AFTER_PAUSE     0x00000000
+#define IFX_SSC_SFCON_PAUSE_LENGTH_MASK        0xFFC00000
+#define IFX_SSC_SFCON_PAUSE_LENGTH_OFFSET      22
+#define IFX_SSC_SFCON_DATA_LENGTH_MAX         4096
+#define IFX_SSC_SFCON_PAUSE_LENGTH_MAX        1024
+
+#define IFX_SSC_SFCON_EXTRACT_DATA_LENGTH(sfcon)  ((sfcon & IFX_SSC_SFCON_DATA_LENGTH_MASK) >> IFX_SSC_SFCON_DATA_LENGTH_OFFSET)
+#define IFX_SSC_SFCON_EXTRACT_PAUSE_LENGTH(sfcon) ((sfcon & IFX_SSC_SFCON_PAUSE_LENGTH_MASK) >> IFX_SSC_SFCON_PAUSE_LENGTH_OFFSET)
+#define IFX_SSC_SFCON_SET_DATA_LENGTH(value)      ((value << IFX_SSC_SFCON_DATA_LENGTH_OFFSET) & IFX_SSC_SFCON_DATA_LENGTH_MASK)
+#define IFX_SSC_SFCON_SET_PAUSE_LENGTH(value)      ((value << IFX_SSC_SFCON_PAUSE_LENGTH_OFFSET) & IFX_SSC_SFCON_PAUSE_LENGTH_MASK)
+
+/* SFSTAT register */
+#define IFX_SSC_SFSTAT_IN_DATA            0x00000001
+#define IFX_SSC_SFSTAT_IN_PAUSE           0x00000002
+#define IFX_SSC_SFSTAT_DATA_COUNT_MASK    0x0000FFF0
+#define IFX_SSC_SFSTAT_DATA_COUNT_OFFSET  4
+#define IFX_SSC_SFSTAT_PAUSE_COUNT_MASK   0xFFF00000
+#define IFX_SSC_SFSTAT_PAUSE_COUNT_OFFSET 20
+
+#define IFX_SSC_SFSTAT_EXTRACT_DATA_COUNT(sfstat) ((sfstat & IFX_SSC_SFSTAT_DATA_COUNT_MASK) >> IFX_SSC_SFSTAT_DATA_COUNT_OFFSET)
+#define IFX_SSC_SFSTAT_EXTRACT_PAUSE_COUNT(sfstat) ((sfstat & IFX_SSC_SFSTAT_PAUSE_COUNT_MASK) >> IFX_SSC_SFSTAT_PAUSE_COUNT_OFFSET)
+
+/* RXREQ register */
+#define IFX_SSC_RXREQ_RXCOUNT_MASK       0x0000FFFF
+#define IFX_SSC_RXREQ_RXCOUNT_OFFSET     0
+
+/* RXCNT register */
+#define IFX_SSC_RXCNT_TODO_MASK       0x0000FFFF
+#define IFX_SSC_RXCNT_TODO_OFFSET     0
+
+/* DMACON register */
+#define IFX_SSC_DMACON_RXON           0x00000001
+#define IFX_SSC_DMACON_RXOFF          0x00000000
+#define IFX_SSC_DMACON_TXON           0x00000002
+#define IFX_SSC_DMACON_TXOFF          0x00000000
+#define IFX_SSC_DMACON_DMAON          0x00000003
+#define IFX_SSC_DMACON_DMAOFF         0x00000000
+#define IFX_SSC_DMACON_CLASS_MASK     0x0000000C
+#define IFX_SSC_DMACON_CLASS_OFFSET   2
+
+/* register access macros */ 
+#define ifx_ssc_fstat_received_words(status)    (status & 0x003F)
+#define ifx_ssc_fstat_words_to_transmit(status) ((status & 0x3F00) >> 8)
+
+#define ifx_ssc_change_status(data, addr)  WRITE_PERIPHERAL_REGISTER(data, (PHYS_OFFSET + addr + IFX_SSC_WHBSTATE))
+#define ifx_ssc_set_config(data, addr)     WRITE_PERIPHERAL_REGISTER(data, (PHYS_OFFSET + addr + IFX_SSC_CON))
+#define ifx_ssc_get_config(addr)           READ_PERIPHERAL_REGISTER((PHYS_OFFSET + addr + IFX_SSC_CON))
+#define ifx_ssc_get_status(addr)           READ_PERIPHERAL_REGISTER((PHYS_OFFSET + addr + IFX_SSC_STATE))
+#define ifx_ssc_receive(addr)              READ_PERIPHERAL_REGISTER((PHYS_OFFSET + addr + IFX_SSC_RB))
+#define ifx_ssc_transmit(data, addr)       WRITE_PERIPHERAL_REGISTER(data, (PHYS_OFFSET + addr + IFX_SSC_TB))
+#define ifx_ssc_fifo_status(addr)          READ_PERIPHERAL_REGISTER((PHYS_OFFSET + addr + IFX_SSC_FSTAT))
+#define ifx_ssc_set_baudrate(data, addr)   WRITE_PERIPHERAL_REGISTER(data, (PHYS_OFFSET + addr + IFX_SSC_BR))
+
+#define ifx_ssc_extract_rx_fifo_size(id)   ((id & IFX_SSC_PERID_RXFS_MASK) >> IFX_SSC_PERID_RXFS_OFFSET)
+#define ifx_ssc_extract_tx_fifo_size(id)   ((id & IFX_SSC_PERID_TXFS_MASK) >> IFX_SSC_PERID_TXFS_OFFSET)
+
+#endif
diff --git a/target/linux/amazon-2.6/files/include/asm-mips/amazon/irq.h b/target/linux/amazon-2.6/files/include/asm-mips/amazon/irq.h
new file mode 100644 (file)
index 0000000..c575dd6
--- /dev/null
@@ -0,0 +1,200 @@
+/* irq.h - AMAZON interrupts */
+
+#ifndef __AMAZON_IRQ
+#define __AMAZON_IRQ
+
+/************************************************************************
+ *  Interrupt information
+*************************************************************************/
+
+/* these vectors are to handle the interrupts from the internal AMAZON
+   interrupt controller. THe INT_NUM values are really just indices into
+   an array and are set up so that we can use the INT_NUM as a shift
+   to calculate a mask value. */
+#define INT_NUM_IRQ0           8
+#define INT_NUM_IM0_IRL0       (INT_NUM_IRQ0 + 0) 
+#define INT_NUM_IM0_IRL1       (INT_NUM_IRQ0 + 1) 
+#define INT_NUM_IM0_IRL2       (INT_NUM_IRQ0 + 2) 
+#define INT_NUM_IM0_IRL3       (INT_NUM_IRQ0 + 3) 
+#define INT_NUM_IM0_IRL4       (INT_NUM_IRQ0 + 4) 
+#define INT_NUM_IM0_IRL5       (INT_NUM_IRQ0 + 5) 
+#define INT_NUM_IM0_IRL6       (INT_NUM_IRQ0 + 6) 
+#define INT_NUM_IM0_IRL7       (INT_NUM_IRQ0 + 7) 
+#define INT_NUM_IM0_IRL8       (INT_NUM_IRQ0 + 8) 
+#define INT_NUM_IM0_IRL9       (INT_NUM_IRQ0 + 9) 
+#define INT_NUM_IM0_IRL10      (INT_NUM_IRQ0 + 10) 
+#define INT_NUM_IM0_IRL11      (INT_NUM_IRQ0 + 11) 
+#define INT_NUM_IM0_IRL12      (INT_NUM_IRQ0 + 12) 
+#define INT_NUM_IM0_IRL13      (INT_NUM_IRQ0 + 13) 
+#define INT_NUM_IM0_IRL14      (INT_NUM_IRQ0 + 14) 
+#define INT_NUM_IM0_IRL15      (INT_NUM_IRQ0 + 15) 
+#define INT_NUM_IM0_IRL16      (INT_NUM_IRQ0 + 16) 
+#define INT_NUM_IM0_IRL17      (INT_NUM_IRQ0 + 17) 
+#define INT_NUM_IM0_IRL18      (INT_NUM_IRQ0 + 18) 
+#define INT_NUM_IM0_IRL19      (INT_NUM_IRQ0 + 19) 
+#define INT_NUM_IM0_IRL20      (INT_NUM_IRQ0 + 20) 
+#define INT_NUM_IM0_IRL21      (INT_NUM_IRQ0 + 21) 
+#define INT_NUM_IM0_IRL22      (INT_NUM_IRQ0 + 22) 
+#define INT_NUM_IM0_IRL23      (INT_NUM_IRQ0 + 23) 
+#define INT_NUM_IM0_IRL24      (INT_NUM_IRQ0 + 24) 
+#define INT_NUM_IM0_IRL25      (INT_NUM_IRQ0 + 25) 
+#define INT_NUM_IM0_IRL26      (INT_NUM_IRQ0 + 26) 
+#define INT_NUM_IM0_IRL27      (INT_NUM_IRQ0 + 27) 
+#define INT_NUM_IM0_IRL28      (INT_NUM_IRQ0 + 28) 
+#define INT_NUM_IM0_IRL29      (INT_NUM_IRQ0 + 29) 
+#define INT_NUM_IM0_IRL30      (INT_NUM_IRQ0 + 30) 
+#define INT_NUM_IM0_IRL31      (INT_NUM_IRQ0 + 31) 
+
+#define INT_NUM_IM1_IRL0       (INT_NUM_IRQ0 + 32) 
+#define INT_NUM_IM1_IRL1       (INT_NUM_IM1_IRL0 + 1) 
+#define INT_NUM_IM1_IRL2       (INT_NUM_IM1_IRL0 + 2) 
+#define INT_NUM_IM1_IRL3       (INT_NUM_IM1_IRL0 + 3) 
+#define INT_NUM_IM1_IRL4       (INT_NUM_IM1_IRL0 + 4) 
+#define INT_NUM_IM1_IRL5       (INT_NUM_IM1_IRL0 + 5) 
+#define INT_NUM_IM1_IRL6       (INT_NUM_IM1_IRL0 + 6) 
+#define INT_NUM_IM1_IRL7       (INT_NUM_IM1_IRL0 + 7) 
+#define INT_NUM_IM1_IRL8       (INT_NUM_IM1_IRL0 + 8) 
+#define INT_NUM_IM1_IRL9       (INT_NUM_IM1_IRL0 + 9) 
+#define INT_NUM_IM1_IRL10      (INT_NUM_IM1_IRL0 + 10) 
+#define INT_NUM_IM1_IRL11      (INT_NUM_IM1_IRL0 + 11) 
+#define INT_NUM_IM1_IRL12      (INT_NUM_IM1_IRL0 + 12) 
+#define INT_NUM_IM1_IRL13      (INT_NUM_IM1_IRL0 + 13) 
+#define INT_NUM_IM1_IRL14      (INT_NUM_IM1_IRL0 + 14) 
+#define INT_NUM_IM1_IRL15      (INT_NUM_IM1_IRL0 + 15) 
+#define INT_NUM_IM1_IRL16       (INT_NUM_IM1_IRL0 + 16) 
+#define INT_NUM_IM1_IRL17      (INT_NUM_IM1_IRL0 + 17) 
+#define INT_NUM_IM1_IRL18      (INT_NUM_IM1_IRL0 + 18) 
+#define INT_NUM_IM1_IRL19      (INT_NUM_IM1_IRL0 + 19) 
+#define INT_NUM_IM1_IRL20      (INT_NUM_IM1_IRL0 + 20) 
+#define INT_NUM_IM1_IRL21      (INT_NUM_IM1_IRL0 + 21) 
+#define INT_NUM_IM1_IRL22      (INT_NUM_IM1_IRL0 + 22) 
+#define INT_NUM_IM1_IRL23      (INT_NUM_IM1_IRL0 + 23) 
+#define INT_NUM_IM1_IRL24      (INT_NUM_IM1_IRL0 + 24) 
+#define INT_NUM_IM1_IRL25      (INT_NUM_IM1_IRL0 + 25) 
+#define INT_NUM_IM1_IRL26      (INT_NUM_IM1_IRL0 + 26) 
+#define INT_NUM_IM1_IRL27      (INT_NUM_IM1_IRL0 + 27) 
+#define INT_NUM_IM1_IRL28      (INT_NUM_IM1_IRL0 + 28) 
+#define INT_NUM_IM1_IRL29      (INT_NUM_IM1_IRL0 + 29) 
+#define INT_NUM_IM1_IRL30      (INT_NUM_IM1_IRL0 + 30) 
+#define INT_NUM_IM1_IRL31      (INT_NUM_IM1_IRL0 + 31) 
+
+#define INT_NUM_IM2_IRL0       (INT_NUM_IRQ0 + 64) 
+#define INT_NUM_IM2_IRL1       (INT_NUM_IM2_IRL0 + 1) 
+#define INT_NUM_IM2_IRL2       (INT_NUM_IM2_IRL0 + 2) 
+#define INT_NUM_IM2_IRL3       (INT_NUM_IM2_IRL0 + 3) 
+#define INT_NUM_IM2_IRL4       (INT_NUM_IM2_IRL0 + 4) 
+#define INT_NUM_IM2_IRL5       (INT_NUM_IM2_IRL0 + 5) 
+#define INT_NUM_IM2_IRL6       (INT_NUM_IM2_IRL0 + 6) 
+#define INT_NUM_IM2_IRL7       (INT_NUM_IM2_IRL0 + 7) 
+#define INT_NUM_IM2_IRL8       (INT_NUM_IM2_IRL0 + 8) 
+#define INT_NUM_IM2_IRL9       (INT_NUM_IM2_IRL0 + 9) 
+#define INT_NUM_IM2_IRL10      (INT_NUM_IM2_IRL0 + 10) 
+#define INT_NUM_IM2_IRL11      (INT_NUM_IM2_IRL0 + 11) 
+#define INT_NUM_IM2_IRL12      (INT_NUM_IM2_IRL0 + 12) 
+#define INT_NUM_IM2_IRL13      (INT_NUM_IM2_IRL0 + 13) 
+#define INT_NUM_IM2_IRL14      (INT_NUM_IM2_IRL0 + 14) 
+#define INT_NUM_IM2_IRL15      (INT_NUM_IM2_IRL0 + 15) 
+#define INT_NUM_IM2_IRL16      (INT_NUM_IM2_IRL0 + 16) 
+#define INT_NUM_IM2_IRL17      (INT_NUM_IM2_IRL0 + 17) 
+#define INT_NUM_IM2_IRL18      (INT_NUM_IM2_IRL0 + 18) 
+#define INT_NUM_IM2_IRL19      (INT_NUM_IM2_IRL0 + 19) 
+#define INT_NUM_IM2_IRL20      (INT_NUM_IM2_IRL0 + 20) 
+#define INT_NUM_IM2_IRL21      (INT_NUM_IM2_IRL0 + 21) 
+#define INT_NUM_IM2_IRL22      (INT_NUM_IM2_IRL0 + 22) 
+#define INT_NUM_IM2_IRL23      (INT_NUM_IM2_IRL0 + 23) 
+#define INT_NUM_IM2_IRL24      (INT_NUM_IM2_IRL0 + 24) 
+#define INT_NUM_IM2_IRL25      (INT_NUM_IM2_IRL0 + 25) 
+#define INT_NUM_IM2_IRL26      (INT_NUM_IM2_IRL0 + 26) 
+#define INT_NUM_IM2_IRL27      (INT_NUM_IM2_IRL0 + 27) 
+#define INT_NUM_IM2_IRL28      (INT_NUM_IM2_IRL0 + 28) 
+#define INT_NUM_IM2_IRL29      (INT_NUM_IM2_IRL0 + 29) 
+#define INT_NUM_IM2_IRL30      (INT_NUM_IM2_IRL0 + 30) 
+#define INT_NUM_IM2_IRL31      (INT_NUM_IM2_IRL0 + 31) 
+
+#define INT_NUM_IM3_IRL0       (INT_NUM_IRQ0 + 96) 
+#define INT_NUM_IM3_IRL1       (INT_NUM_IM3_IRL0 + 1) 
+#define INT_NUM_IM3_IRL2       (INT_NUM_IM3_IRL0 + 2) 
+#define INT_NUM_IM3_IRL3       (INT_NUM_IM3_IRL0 + 3) 
+#define INT_NUM_IM3_IRL4       (INT_NUM_IM3_IRL0 + 4) 
+#define INT_NUM_IM3_IRL5       (INT_NUM_IM3_IRL0 + 5) 
+#define INT_NUM_IM3_IRL6       (INT_NUM_IM3_IRL0 + 6) 
+#define INT_NUM_IM3_IRL7       (INT_NUM_IM3_IRL0 + 7) 
+#define INT_NUM_IM3_IRL8       (INT_NUM_IM3_IRL0 + 8) 
+#define INT_NUM_IM3_IRL9       (INT_NUM_IM3_IRL0 + 9) 
+#define INT_NUM_IM3_IRL10      (INT_NUM_IM3_IRL0 + 10) 
+#define INT_NUM_IM3_IRL11      (INT_NUM_IM3_IRL0 + 11) 
+#define INT_NUM_IM3_IRL12      (INT_NUM_IM3_IRL0 + 12) 
+#define INT_NUM_IM3_IRL13      (INT_NUM_IM3_IRL0 + 13) 
+#define INT_NUM_IM3_IRL14      (INT_NUM_IM3_IRL0 + 14) 
+#define INT_NUM_IM3_IRL15      (INT_NUM_IM3_IRL0 + 15) 
+#define INT_NUM_IM3_IRL16      (INT_NUM_IM3_IRL0 + 16) 
+#define INT_NUM_IM3_IRL17      (INT_NUM_IM3_IRL0 + 17) 
+#define INT_NUM_IM3_IRL18      (INT_NUM_IM3_IRL0 + 18) 
+#define INT_NUM_IM3_IRL19      (INT_NUM_IM3_IRL0 + 19) 
+#define INT_NUM_IM3_IRL20      (INT_NUM_IM3_IRL0 + 20) 
+#define INT_NUM_IM3_IRL21      (INT_NUM_IM3_IRL0 + 21) 
+#define INT_NUM_IM3_IRL22      (INT_NUM_IM3_IRL0 + 22) 
+#define INT_NUM_IM3_IRL23      (INT_NUM_IM3_IRL0 + 23) 
+#define INT_NUM_IM3_IRL24      (INT_NUM_IM3_IRL0 + 24) 
+#define INT_NUM_IM3_IRL25      (INT_NUM_IM3_IRL0 + 25) 
+#define INT_NUM_IM3_IRL26      (INT_NUM_IM3_IRL0 + 26) 
+#define INT_NUM_IM3_IRL27      (INT_NUM_IM3_IRL0 + 27) 
+#define INT_NUM_IM3_IRL28      (INT_NUM_IM3_IRL0 + 28) 
+#define INT_NUM_IM3_IRL29      (INT_NUM_IM3_IRL0 + 29) 
+#define INT_NUM_IM3_IRL30      (INT_NUM_IM3_IRL0 + 30) 
+#define INT_NUM_IM3_IRL31      (INT_NUM_IM3_IRL0 + 31) 
+
+#define INT_NUM_IM4_IRL0       (INT_NUM_IRQ0 + 128) 
+#define INT_NUM_IM4_IRL1       (INT_NUM_IM4_IRL0 + 1) 
+#define INT_NUM_IM4_IRL2       (INT_NUM_IM4_IRL0 + 2) 
+#define INT_NUM_IM4_IRL3       (INT_NUM_IM4_IRL0 + 3) 
+#define INT_NUM_IM4_IRL4       (INT_NUM_IM4_IRL0 + 4) 
+#define INT_NUM_IM4_IRL5       (INT_NUM_IM4_IRL0 + 5) 
+#define INT_NUM_IM4_IRL6       (INT_NUM_IM4_IRL0 + 6) 
+#define INT_NUM_IM4_IRL7       (INT_NUM_IM4_IRL0 + 7) 
+#define INT_NUM_IM4_IRL8       (INT_NUM_IM4_IRL0 + 8) 
+#define INT_NUM_IM4_IRL9       (INT_NUM_IM4_IRL0 + 9) 
+#define INT_NUM_IM4_IRL10      (INT_NUM_IM4_IRL0 + 10) 
+#define INT_NUM_IM4_IRL11      (INT_NUM_IM4_IRL0 + 11) 
+#define INT_NUM_IM4_IRL12      (INT_NUM_IM4_IRL0 + 12) 
+#define INT_NUM_IM4_IRL13      (INT_NUM_IM4_IRL0 + 13) 
+#define INT_NUM_IM4_IRL14      (INT_NUM_IM4_IRL0 + 14) 
+#define INT_NUM_IM4_IRL15      (INT_NUM_IM4_IRL0 + 15) 
+#define INT_NUM_IM4_IRL16      (INT_NUM_IM4_IRL0 + 16) 
+#define INT_NUM_IM4_IRL17      (INT_NUM_IM4_IRL0 + 17) 
+#define INT_NUM_IM4_IRL18      (INT_NUM_IM4_IRL0 + 18) 
+#define INT_NUM_IM4_IRL19      (INT_NUM_IM4_IRL0 + 19) 
+#define INT_NUM_IM4_IRL20      (INT_NUM_IM4_IRL0 + 20) 
+#define INT_NUM_IM4_IRL21      (INT_NUM_IM4_IRL0 + 21) 
+#define INT_NUM_IM4_IRL22      (INT_NUM_IM4_IRL0 + 22) 
+#define INT_NUM_IM4_IRL23      (INT_NUM_IM4_IRL0 + 23) 
+#define INT_NUM_IM4_IRL24      (INT_NUM_IM4_IRL0 + 24) 
+#define INT_NUM_IM4_IRL25      (INT_NUM_IM4_IRL0 + 25) 
+#define INT_NUM_IM4_IRL26      (INT_NUM_IM4_IRL0 + 26) 
+#define INT_NUM_IM4_IRL27      (INT_NUM_IM4_IRL0 + 27) 
+#define INT_NUM_IM4_IRL28      (INT_NUM_IM4_IRL0 + 28) 
+#define INT_NUM_IM4_IRL29      (INT_NUM_IM4_IRL0 + 29) 
+#define INT_NUM_IM4_IRL30      (INT_NUM_IM4_IRL0 + 30) 
+#define INT_NUM_IM4_IRL31      (INT_NUM_IM4_IRL0 + 31) 
+
+/****** Interrupt Assigments ***********/
+#define AMAZON_DMA_INT         INT_NUM_IM0_IRL0
+#define IFX_SSC_TIR            INT_NUM_IM0_IRL29
+#define IFX_SSC_RIR            INT_NUM_IM0_IRL30
+#define IFX_SSC_EIR            INT_NUM_IM0_IRL31
+
+#define        AMAZON_MEI_INT          INT_NUM_IM2_IRL8
+
+#define AMAZONASC_TIR          INT_NUM_IM4_IRL15/* TX interrupt */
+#define AMAZONASC_RIR          INT_NUM_IM4_IRL16/* RX interrupt */
+#define AMAZONASC_EIR          INT_NUM_IM4_IRL17/* ERROR interrupt */
+
+#define AMAZON_TIMER6_INT      INT_NUM_IM1_IRL23
+
+#define        AMAZON_SWIE_INT         INT_NUM_IM3_IRL8
+#define        AMAZON_CBM_INT          INT_NUM_IM3_IRL9
+#define        AMAZON_AAL5_INT         INT_NUM_IM3_IRL10
+#define        AMAZON_HTU_INT          INT_NUM_IM3_IRL11
+#define        AMAZON_QSB_INT          INT_NUM_IM3_IRL12
+#define MIPS_CPU_TIMER_IRQ     7
+#endif /* __AMAZON_IRQ */
diff --git a/target/linux/amazon-2.6/files/include/asm-mips/amazon/model.h b/target/linux/amazon-2.6/files/include/asm-mips/amazon/model.h
new file mode 100644 (file)
index 0000000..4e43ab5
--- /dev/null
@@ -0,0 +1,29 @@
+#ifndef AMAZON_MODEL_H
+#define AMAZON_MODEL_H
+/******************************************************************************
+       Copyright (c) 2002, Infineon Technologies.  All rights reserved.
+
+                               No Warranty
+   Because the program is licensed free of charge, there is no warranty for
+   the program, to the extent permitted by applicable law.  Except when
+   otherwise stated in writing the copyright holders and/or other parties
+   provide the program "as is" without warranty of any kind, either
+   expressed or implied, including, but not limited to, the implied
+   warranties of merchantability and fitness for a particular purpose. The
+   entire risk as to the quality and performance of the program is with
+   you.  should the program prove defective, you assume the cost of all
+   necessary servicing, repair or correction.
+
+   In no event unless required by applicable law or agreed to in writing
+   will any copyright holder, or any other party who may modify and/or
+   redistribute the program as permitted above, be liable to you for
+   damages, including any general, special, incidental or consequential
+   damages arising out of the use or inability to use the program
+   (including but not limited to loss of data or data being rendered
+   inaccurate or losses sustained by you or third parties or a failure of
+   the program to operate with any other programs), even if such holder or
+   other party has been advised of the possibility of such damages.
+******************************************************************************/
+#define BOARD_SYSTEM_TYPE              "AMAZON"
+#define SYSTEM_MODEL_NAME              "Amazon Gateway Package 3.2 Version"
+#endif
diff --git a/target/linux/amazon-2.6/files/include/asm-mips/amazon/port.h b/target/linux/amazon-2.6/files/include/asm-mips/amazon/port.h
new file mode 100644 (file)
index 0000000..2182579
--- /dev/null
@@ -0,0 +1,72 @@
+/*
+ * ########################################################################
+ *
+ *  This program is free software; you can distribute it and/or modify it
+ *  under the terms of the GNU General Public License (Version 2) as
+ *  published by the Free Software Foundation.
+ *
+ *  This program is distributed in the hope it will be useful, but WITHOUT
+ *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ *  for more details.
+ *
+ *  You should have received a copy of the GNU General Public License along
+ *  with this program; if not, write to the Free Software Foundation, Inc.,
+ *  59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
+ *
+ * ########################################################################
+ *
+ * port.h
+ *
+ * Global Amazon port driver header file
+ *
+ */
+
+/* Modification history */
+/* 21Jun2004   btxu    Generate from Inca_IP project */
+
+#ifndef PORT_H
+#define PORT_H
+
+struct amazon_port_ioctl_parm {
+       int port;
+       int pin;
+       int value;
+};
+#define AMAZON_PORT_IOC_MAGIC  0xbf
+#define AMAZON_PORT_IOCOD      _IOW( AMAZON_PORT_IOC_MAGIC,0,struct amazon_port_ioctl_parm)
+#define AMAZON_PORT_IOCPUDSEL  _IOW( AMAZON_PORT_IOC_MAGIC,1,struct amazon_port_ioctl_parm)
+#define AMAZON_PORT_IOCPUDEN   _IOW( AMAZON_PORT_IOC_MAGIC,2,struct amazon_port_ioctl_parm)
+#define AMAZON_PORT_IOCSTOFF   _IOW( AMAZON_PORT_IOC_MAGIC,3,struct amazon_port_ioctl_parm)
+#define AMAZON_PORT_IOCDIR     _IOW( AMAZON_PORT_IOC_MAGIC,4,struct amazon_port_ioctl_parm)
+#define AMAZON_PORT_IOCOUTPUT  _IOW( AMAZON_PORT_IOC_MAGIC,5,struct amazon_port_ioctl_parm)
+#define AMAZON_PORT_IOCINPUT   _IOWR(AMAZON_PORT_IOC_MAGIC,6,struct amazon_port_ioctl_parm)
+#define AMAZON_PORT_IOCALTSEL0  _IOW( AMAZON_PORT_IOC_MAGIC,7,struct amazon_port_ioctl_parm)
+#define AMAZON_PORT_IOCALTSEL1  _IOW( AMAZON_PORT_IOC_MAGIC,8,struct amazon_port_ioctl_parm)
+
+int amazon_port_reserve_pin(int port, int pin, int module_id);
+int amazon_port_free_pin(int port, int pin, int module_id);
+int amazon_port_set_open_drain(int port, int pin, int module_id);
+int amazon_port_clear_open_drain(int port, int pin, int module_id);
+int amazon_port_set_pudsel(int port, int pin, int module_id);
+int amazon_port_clear_pudsel(int port, int pin, int module_id);
+int amazon_port_set_puden(int port, int pin, int module_id);
+int amazon_port_clear_puden(int port, int pin, int module_id);
+int amazon_port_set_stoff(int port, int pin, int module_id);
+int amazon_port_clear_stoff(int port, int pin, int module_id);
+int amazon_port_set_dir_out(int port, int pin, int module_id);
+int amazon_port_set_dir_in(int port, int pin, int module_id);
+int amazon_port_set_output(int port, int pin, int module_id);
+int amazon_port_clear_output(int port, int pin, int module_id);
+int amazon_port_get_input(int port, int pin, int module_id);
+
+int amazon_port_set_altsel0(int port, int pin, int module_id);
+int amazon_port_clear_altsel0(int port, int pin, int module_id);
+int amazon_port_set_altsel1(int port, int pin, int module_id);
+int amazon_port_clear_altsel1(int port, int pin, int module_id);
+
+
+#endif /* PORT_H */
+
+
diff --git a/target/linux/amazon-2.6/files/include/asm-mips/amazon/serial.h b/target/linux/amazon-2.6/files/include/asm-mips/amazon/serial.h
new file mode 100644 (file)
index 0000000..3ff3efc
--- /dev/null
@@ -0,0 +1,146 @@
+/* incaAscSio.h - (AMAZON) ASC UART tty driver header */
+
+#ifndef __AMAZON_ASC_H
+#define __AMAZON_ASC_H
+
+/* channel operating modes */
+#define        ASCOPT_CSIZE    0x00000003
+#define        ASCOPT_CS7      0x00000001
+#define        ASCOPT_CS8      0x00000002
+#define        ASCOPT_PARENB   0x00000004
+#define        ASCOPT_STOPB    0x00000008
+#define        ASCOPT_PARODD   0x00000010
+#define        ASCOPT_CREAD    0x00000020
+
+#define ASC_OPTIONS            (ASCOPT_CREAD | ASCOPT_CS8)
+
+/* ASC input select (0 or 1) */
+#define CONSOLE_TTY    0
+
+/* use fractional divider for baudrate settings */
+#define AMAZONASC_USE_FDV
+
+#ifdef AMAZONASC_USE_FDV
+   #define AMAZONASC_FDV_LOW_BAUDRATE        71
+#ifdef CONFIG_USE_IKOS
+   #define AMAZONASC_FDV_HIGH_BAUDRATE       443      
+#else
+   #define AMAZONASC_FDV_HIGH_BAUDRATE       498      
+#endif //CONFIG_USE_IKOS
+#endif /*AMAZONASC_USE_FDV*/
+
+
+#define AMAZONASC_TXFIFO_FL       1
+#define AMAZONASC_RXFIFO_FL       1
+#define AMAZONASC_TXFIFO_FULL     16
+
+/* interrupt lines masks for the ASC device interrupts*/
+/* change these macroses if it's necessary */
+#define AMAZONASC_IRQ_LINE_ALL        0x000F0000  /* all IRQs */
+
+#define AMAZONASC_IRQ_LINE_TIR            0x00010000      /* TIR - Tx */
+#define AMAZONASC_IRQ_LINE_RIR            0x00020000      /* RIR - Rx */
+#define AMAZONASC_IRQ_LINE_EIR            0x00040000      /* EIR - Err */
+#define AMAZONASC_IRQ_LINE_TBIR           0x00080000      /* TBIR - Tx Buf*/
+
+/* CLC register's bits and bitfields */
+#define ASCCLC_DISR        0x00000001
+#define ASCCLC_DISS        0x00000002
+#define ASCCLC_RMCMASK     0x0000FF00
+#define ASCCLC_RMCOFFSET   8
+
+/* CON register's bits and bitfields */
+#define ASCCON_MODEMASK 0x0007
+    #define ASCCON_M_8SYNC          0x0
+    #define ASCCON_M_8ASYNC         0x1
+    #define ASCCON_M_8IRDAASYNC     0x2
+    #define ASCCON_M_7ASYNCPAR      0x3
+    #define ASCCON_M_9ASYNC         0x4
+    #define ASCCON_M_8WAKEUPASYNC   0x5
+    #define ASCCON_M_8ASYNCPAR      0x7
+#define ASCCON_STP      0x0008
+#define ASCCON_REN      0x0010
+#define ASCCON_PEN      0x0020
+#define ASCCON_FEN      0x0040
+#define ASCCON_OEN      0x0080
+#define ASCCON_PE       0x0100
+#define ASCCON_FE       0x0200
+#define ASCCON_OE       0x0400
+#define ASCCON_FDE      0x0800
+#define ASCCON_ODD      0x1000
+#define ASCCON_BRS      0x2000
+#define ASCCON_LB       0x4000
+#define ASCCON_R        0x8000
+#define ASCCON_ANY     (ASCCON_PE|ASCCON_FE|ASCCON_OE)
+
+/* WHBCON register's bits and bitfields */
+#define ASCWHBCON_CLRREN    0x0010
+#define ASCWHBCON_SETREN    0x0020
+#define ASCWHBCON_CLRPE     0x0100
+#define ASCWHBCON_CLRFE     0x0200
+#define ASCWHBCON_CLROE     0x0400
+#define ASCWHBCON_SETPE     0x0800
+#define ASCWHBCON_SETFE     0x1000
+#define ASCWHBCON_SETOE     0x2000
+
+/* ABCON register's bits and bitfields */
+#define ASCABCON_ABEN       0x0001
+#define ASCABCON_AUREN      0x0002
+#define ASCABCON_ABSTEN     0x0004
+#define ASCABCON_ABDETEN    0x0008
+#define ASCABCON_FCDETEN    0x0010
+#define ASCABCON_EMMASK     0x0300
+    #define ASCABCON_EMOFF          8
+        #define ASCABCON_EM_DISAB       0x0
+        #define ASCABCON_EM_DURAB       0x1
+        #define ASCABCON_EM_ALWAYS      0x2
+#define ASCABCON_TXINV      0x0400
+#define ASCABCON_RXINV      0x0800
+
+/* FDV register mask, offset and bitfields*/
+#define ASCFDV_VALUE_MASK     0x000001FF
+
+/* WHBABCON register's bits and bitfields */
+#define ASCWHBABCON_SETABEN     0x0001
+#define ASCWHBABCON_CLRABEN     0x0002
+
+/* ABSTAT register's bits and bitfields */
+#define ASCABSTAT_FCSDET    0x0001
+#define ASCABSTAT_FCCDET    0x0002
+#define ASCABSTAT_SCSDET    0x0004
+#define ASCABSTAT_SCCDET    0x0008
+#define ASCABSTAT_DETWAIT   0x0010
+
+/* WHBABSTAT register's bits and bitfields */
+#define ASCWHBABSTAT_CLRFCSDET  0x0001
+#define ASCWHBABSTAT_SETFCSDET  0x0002
+#define ASCWHBABSTAT_CLRFCCDET  0x0004
+#define ASCWHBABSTAT_SETFCCDET  0x0008
+#define ASCWHBABSTAT_CLRSCSDET  0x0010
+#define ASCWHBABSTAT_SETSCSDET  0x0020
+#define ASCWHBABSTAT_SETSCCDET  0x0040
+#define ASCWHBABSTAT_CLRSCCDET  0x0080
+#define ASCWHBABSTAT_CLRDETWAIT 0x0100
+#define ASCWHBABSTAT_SETDETWAIT 0x0200
+
+/* TXFCON register's bits and bitfields */
+#define ASCTXFCON_TXFEN         0x0001
+#define ASCTXFCON_TXFFLU        0x0002
+#define ASCTXFCON_TXTMEN        0x0004
+#define ASCTXFCON_TXFITLMASK    0x3F00
+#define ASCTXFCON_TXFITLOFF     8
+
+/* RXFCON register's bits and bitfields */
+#define ASCRXFCON_RXFEN         0x0001
+#define ASCRXFCON_RXFFLU        0x0002
+#define ASCRXFCON_RXTMEN        0x0004
+#define ASCRXFCON_RXFITLMASK    0x3F00
+#define ASCRXFCON_RXFITLOFF     8
+
+/* FSTAT register's bits and bitfields */
+#define ASCFSTAT_RXFFLMASK      0x003F
+#define ASCFSTAT_TXFFLMASK      0x3F00
+#define ASCFSTAT_TXFFLOFF       8
+
+#endif /* __AMAZON_ASC_H */
+
diff --git a/target/linux/amazon-2.6/files/include/asm-mips/mach-amazon/irq.h b/target/linux/amazon-2.6/files/include/asm-mips/mach-amazon/irq.h
new file mode 100644 (file)
index 0000000..e72b7d5
--- /dev/null
@@ -0,0 +1,7 @@
+#ifndef __AMAZON_IRQ_H
+#define __AMAZON_IRQ_H
+
+#define NR_IRQS      256
+#include_next <irq.h>
+
+#endif
diff --git a/target/linux/amazon-2.6/files/include/asm-mips/mach-amazon/mangle-port.h b/target/linux/amazon-2.6/files/include/asm-mips/mach-amazon/mangle-port.h
new file mode 100644 (file)
index 0000000..9aefebb
--- /dev/null
@@ -0,0 +1,52 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2003, 2004 Ralf Baechle
+ */
+#ifndef __ASM_MACH_GENERIC_MANGLE_PORT_H
+#define __ASM_MACH_GENERIC_MANGLE_PORT_H
+
+#define __swizzle_addr_b(port) (port)
+#define __swizzle_addr_w(port) ((port) ^ 2)
+#define __swizzle_addr_l(port) (port)
+#define __swizzle_addr_q(port) (port)
+
+/*
+ * Sane hardware offers swapping of PCI/ISA I/O space accesses in hardware;
+ * less sane hardware forces software to fiddle with this...
+ *
+ * Regardless, if the host bus endianness mismatches that of PCI/ISA, then
+ * you can't have the numerical value of data and byte addresses within
+ * multibyte quantities both preserved at the same time.  Hence two
+ * variations of functions: non-prefixed ones that preserve the value
+ * and prefixed ones that preserve byte addresses.  The latters are
+ * typically used for moving raw data between a peripheral and memory (cf.
+ * string I/O functions), hence the "__mem_" prefix.
+ */
+#if defined(CONFIG_SWAP_IO_SPACE)
+
+# define ioswabb(a,x)          (x)
+# define __mem_ioswabb(a,x)    (x)
+# define ioswabw(a,x)          le16_to_cpu(x)
+# define __mem_ioswabw(a,x)    (x)
+# define ioswabl(a,x)          le32_to_cpu(x)
+# define __mem_ioswabl(a,x)    (x)
+# define ioswabq(a,x)          le64_to_cpu(x)
+# define __mem_ioswabq(a,x)    (x)
+
+#else
+
+# define ioswabb(a,x)          (x)
+# define __mem_ioswabb(a,x)    (x)
+# define ioswabw(a,x)          (x)
+# define __mem_ioswabw(a,x)    cpu_to_le16(x)
+# define ioswabl(a,x)          (x)
+# define __mem_ioswabl(a,x)    cpu_to_le32(x)
+# define ioswabq(a,x)          (x)
+# define __mem_ioswabq(a,x)    cpu_to_le32(x)
+
+#endif
+
+#endif /* __ASM_MACH_GENERIC_MANGLE_PORT_H */
diff --git a/target/linux/amazon-2.6/image/Makefile b/target/linux/amazon-2.6/image/Makefile
new file mode 100644 (file)
index 0000000..c749560
--- /dev/null
@@ -0,0 +1,30 @@
+# 
+# Copyright (C) 2006 OpenWrt.org
+#
+# This is free software, licensed under the GNU General Public License v2.
+# See /LICENSE for more information.
+#
+include $(TOPDIR)/rules.mk
+include $(INCLUDE_DIR)/image.mk
+
+define Image/BuildKernel
+       $(STAGING_DIR)/bin/lzma e $(KDIR)/vmlinux $(KDIR)/vmlinux.lzma
+       mkimage -A mips -O linux -T kernel -C lzma -a 0x80002000 -e \
+               0x80002000 \
+               -n 'MIPS OpenWrt Linux-$(LINUX_VERSION)' \
+               -d $(KDIR)/vmlinux.lzma $(KDIR)/uImage
+
+       cp $(KDIR)/uImage $(BIN_DIR)/openwrt-$(BOARD)-$(KERNEL)-uImage
+endef
+
+define Image/Build/squashfs
+    $(call prepare_generic_squashfs,$(BIN_DIR)/openwrt-$(BOARD)-$(KERNEL)-$(1).image)
+endef
+
+define Image/Build
+       cat $(KDIR)/uImage $(KDIR)/root.$(1) > $(BIN_DIR)/openwrt-$(BOARD)-$(KERNEL)-$(1).image
+       $(call Image/Build/$(1),$(1))
+endef
+
+
+$(eval $(call BuildImage))
diff --git a/target/linux/amazon-2.6/patches/100-board.patch b/target/linux/amazon-2.6/patches/100-board.patch
new file mode 100644 (file)
index 0000000..9b29141
--- /dev/null
@@ -0,0 +1,63 @@
+diff -urN linux.old/arch/mips/Kconfig linux.dev/arch/mips/Kconfig
+--- linux.old/arch/mips/Kconfig        2007-02-02 23:55:52.912446784 +0100
++++ linux.dev/arch/mips/Kconfig        2007-02-03 21:50:25.262027104 +0100
+@@ -145,6 +145,17 @@
+         note that a kernel built with this option selected will not be
+         able to run on normal units.
++config AMAZON
++      bool "Amazon support (EXPERIMENTAL)"
++      depends on EXPERIMENTAL
++      select DMA_NONCOHERENT
++      select IRQ_CPU
++      select SYS_HAS_CPU_MIPS32_R1
++      select HAVE_STD_PC_SERIAL_PORT
++      select SYS_SUPPORTS_BIG_ENDIAN
++      select SYS_SUPPORTS_32BIT_KERNEL
++      select SYS_HAS_EARLY_PRINTK
++
+ config MIPS_COBALT
+       bool "Cobalt Server"
+       select DMA_NONCOHERENT
+@@ -766,6 +776,7 @@
+ endchoice
++source "arch/mips/amazon/Kconfig"
+ source "arch/mips/ddb5xxx/Kconfig"
+ source "arch/mips/gt64120/ev64120/Kconfig"
+ source "arch/mips/jazz/Kconfig"
+diff -urN linux.old/arch/mips/Makefile linux.dev/arch/mips/Makefile
+--- linux.old/arch/mips/Makefile       2007-02-02 23:55:52.913446632 +0100
++++ linux.dev/arch/mips/Makefile       2007-02-03 17:40:29.193776000 +0100
+@@ -267,6 +267,13 @@
+ load-$(CONFIG_MIPS_XXS1500)   += 0xffffffff80100000
+ #
++# Infineon AMAZON
++#
++core-$(CONFIG_AMAZON)         += arch/mips/amazon/
++cflags-$(CONFIG_AMAZON)       += -Iinclude/asm-mips/mach-amazon
++load-$(CONFIG_AMAZON)         += 0xffffffff80002000
++
++#
+ # Cobalt Server
+ #
+ core-$(CONFIG_MIPS_COBALT)    += arch/mips/cobalt/
+diff -urN linux.old/include/asm-mips/bootinfo.h linux.dev/include/asm-mips/bootinfo.h
+--- linux.old/include/asm-mips/bootinfo.h      2007-02-02 23:55:52.913446632 +0100
++++ linux.dev/include/asm-mips/bootinfo.h      2007-02-03 17:51:02.531494032 +0100
+@@ -212,6 +212,12 @@
+ #define MACH_GROUP_NEC_EMMA2RH 25     /* NEC EMMA2RH (was 23)         */
+ #define  MACH_NEC_MARKEINS    0       /* NEC EMMA2RH Mark-eins        */
++/*
++ * Valid machtype for group ATHEROS
++ */
++#define MACH_GROUP_INFINEON   27
++#define MACH_INFINEON_AMAZON  0
++
+ #define CL_SIZE                       COMMAND_LINE_SIZE
+ const char *get_system_type(void);
+
diff --git a/target/linux/amazon-2.6/patches/110-char_drivers.patch b/target/linux/amazon-2.6/patches/110-char_drivers.patch
new file mode 100644 (file)
index 0000000..7394964
--- /dev/null
@@ -0,0 +1,12 @@
+Index: linux-2.6.21.5/drivers/char/Makefile
+===================================================================
+--- linux-2.6.21.5.orig/drivers/char/Makefile  2007-06-24 07:44:10.606341712 +0200
++++ linux-2.6.21.5/drivers/char/Makefile       2007-06-24 07:44:46.633864696 +0200
+@@ -103,6 +103,7 @@
+ obj-$(CONFIG_HANGCHECK_TIMER) += hangcheck-timer.o
+ obj-$(CONFIG_TCG_TPM)         += tpm/
++obj-$(CONFIG_AMAZONE_WDT) += amazone_wdt.o
+ # Files generated that shall be removed upon make clean
+ clean-files := consolemap_deftbl.c defkeymap.c
diff --git a/target/linux/amazon-2.6/patches/130-mtd_drivers.patch b/target/linux/amazon-2.6/patches/130-mtd_drivers.patch
new file mode 100644 (file)
index 0000000..31f8164
--- /dev/null
@@ -0,0 +1,9 @@
+Index: linux-2.6.21.5/drivers/mtd/maps/Makefile
+===================================================================
+--- linux-2.6.21.5.orig/drivers/mtd/maps/Makefile      2007-06-24 07:55:22.138253344 +0200
++++ linux-2.6.21.5/drivers/mtd/maps/Makefile   2007-06-24 07:56:58.207648576 +0200
+@@ -72,3 +72,4 @@
+ obj-$(CONFIG_MTD_OMAP_NOR)    += omap_nor.o
+ obj-$(CONFIG_MTD_MTX1)                += mtx-1_flash.o
+ obj-$(CONFIG_MTD_TQM834x)     += tqm834x.o
++obj-$(CONFIG_AMAZON_MTD)      += amazon.o
diff --git a/target/linux/amazon-2.6/patches/140-net_drivers.patch b/target/linux/amazon-2.6/patches/140-net_drivers.patch
new file mode 100644 (file)
index 0000000..65a0e44
--- /dev/null
@@ -0,0 +1,10 @@
+Index: linux-2.6.21.5/drivers/net/Makefile
+===================================================================
+--- linux-2.6.21.5.orig/drivers/net/Makefile   2007-06-24 09:03:20.308277264 +0200
++++ linux-2.6.21.5/drivers/net/Makefile        2007-06-24 09:05:13.560060376 +0200
+@@ -219,3 +219,5 @@
+ obj-$(CONFIG_FS_ENET) += fs_enet/
+ obj-$(CONFIG_NETXEN_NIC) += netxen/
++
++obj-$(CONFIG_AMAZON_NET_SW) += amazon_sw.o
diff --git a/target/linux/amazon-2.6/patches/150-serial_driver.patch b/target/linux/amazon-2.6/patches/150-serial_driver.patch
new file mode 100644 (file)
index 0000000..802c5c2
--- /dev/null
@@ -0,0 +1,12 @@
+Index: linux-2.6.21.5/drivers/serial/Makefile
+===================================================================
+--- linux-2.6.21.5.orig/drivers/serial/Makefile        2007-06-24 10:51:45.005412992 +0200
++++ linux-2.6.21.5/drivers/serial/Makefile     2007-06-24 10:51:54.885910928 +0200
+@@ -5,6 +5,7 @@
+ #
+ obj-$(CONFIG_SERIAL_CORE) += serial_core.o
++obj-$(CONFIG_AMAZON_ASC_UART) += amazon_asc.o
+ obj-$(CONFIG_SERIAL_21285) += 21285.o
+ obj-$(CONFIG_SERIAL_8250) += 8250.o
+ obj-$(CONFIG_SERIAL_8250_PNP) += 8250_pnp.o
diff --git a/target/linux/amazon-2.6/patches/160-cfi-swap.patch b/target/linux/amazon-2.6/patches/160-cfi-swap.patch
new file mode 100644 (file)
index 0000000..9e20f05
--- /dev/null
@@ -0,0 +1,14 @@
+--- linux-2.6.21.5/drivers/mtd/chips/cfi_cmdset_0002.c 2007-07-23 23:15:50.403369508 +0200
++++ linux-2.6.21.5.orig/drivers/mtd/chips/cfi_cmdset_0002.c    2007-07-23 23:26:43.028560499 +0200
+@@ -1007,7 +1007,9 @@
+       int ret = 0;
+       map_word oldd;
+       int retry_cnt = 0;
+-
++#ifdef CONFIG_AMAZON
++      adr ^= 2;
++#endif
+       adr += chip->start;
+       spin_lock(chip->mutex);
+