amazon: update amazon target to kernel 3.3
authorHauke Mehrtens <hauke@hauke-m.de>
Sun, 13 May 2012 15:10:40 +0000 (15:10 +0000)
committerHauke Mehrtens <hauke@hauke-m.de>
Sun, 13 May 2012 15:10:40 +0000 (15:10 +0000)
This is just compile tested, my device is currently not working.

SVN-Revision: 31706

28 files changed:
target/linux/amazon/Makefile
target/linux/amazon/config-2.6.37 [deleted file]
target/linux/amazon/config-3.3 [new file with mode: 0644]
target/linux/amazon/files/arch/mips/amazon/interrupt.c
target/linux/amazon/files/drivers/mtd/maps/amazon.c
target/linux/amazon/files/drivers/net/admmod.c [deleted file]
target/linux/amazon/files/drivers/net/amazon_sw.c [deleted file]
target/linux/amazon/files/drivers/net/ethernet/admmod.c [new file with mode: 0644]
target/linux/amazon/files/drivers/net/ethernet/amazon_sw.c [new file with mode: 0644]
target/linux/amazon/files/drivers/serial/amazon_asc.c [deleted file]
target/linux/amazon/files/drivers/tty/serial/amazon_asc.c [new file with mode: 0644]
target/linux/amazon/files/drivers/watchdog/amazon_wdt.c
target/linux/amazon/patches-2.6.37/000-mips-bad-intctl.patch [deleted file]
target/linux/amazon/patches-2.6.37/010-mips_clocksource_init_war.patch [deleted file]
target/linux/amazon/patches-2.6.37/017-wdt-driver.patch [deleted file]
target/linux/amazon/patches-2.6.37/100-board.patch [deleted file]
target/linux/amazon/patches-2.6.37/130-mtd_drivers.patch [deleted file]
target/linux/amazon/patches-2.6.37/140-net_drivers.patch [deleted file]
target/linux/amazon/patches-2.6.37/150-serial_driver.patch [deleted file]
target/linux/amazon/patches-2.6.37/160-cfi-swap.patch [deleted file]
target/linux/amazon/patches-3.3/000-mips-bad-intctl.patch [new file with mode: 0644]
target/linux/amazon/patches-3.3/010-mips_clocksource_init_war.patch [new file with mode: 0644]
target/linux/amazon/patches-3.3/017-wdt-driver.patch [new file with mode: 0644]
target/linux/amazon/patches-3.3/100-board.patch [new file with mode: 0644]
target/linux/amazon/patches-3.3/130-mtd_drivers.patch [new file with mode: 0644]
target/linux/amazon/patches-3.3/140-net_drivers.patch [new file with mode: 0644]
target/linux/amazon/patches-3.3/150-serial_driver.patch [new file with mode: 0644]
target/linux/amazon/patches-3.3/160-cfi-swap.patch [new file with mode: 0644]

index e90fc4c8bd554528a038cda87e41793e82bed501..bfab52e506dffd949dd3f7a1b2f55ca22b066368 100644 (file)
@@ -10,7 +10,7 @@ ARCH:=mips
 BOARD:=amazon
 BOARDNAME:=Infineon Amazon
 FEATURES:=squashfs jffs2 broken
-LINUX_VERSION:=2.6.37.6
+LINUX_VERSION:=3.3.5
 
 include $(INCLUDE_DIR)/target.mk
 
diff --git a/target/linux/amazon/config-2.6.37 b/target/linux/amazon/config-2.6.37
deleted file mode 100644 (file)
index ca76524..0000000
+++ /dev/null
@@ -1,111 +0,0 @@
-CONFIG_ADM6996_SUPPORT=y
-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_ARCH_HIBERNATION_POSSIBLE=y
-# CONFIG_ARCH_PHYS_ADDR_T_64BIT is not set
-CONFIG_ARCH_POPULATES_NODE_MAP=y
-# CONFIG_ARCH_SUPPORTS_MSI is not set
-CONFIG_ARCH_SUPPORTS_OPROFILE=y
-CONFIG_ARCH_SUSPEND_POSSIBLE=y
-# CONFIG_AUTO_IRQ_AFFINITY is not set
-CONFIG_CEVT_R4K=y
-CONFIG_CEVT_R4K_LIB=y
-CONFIG_CMDLINE="console=ttyS0,115200 rootfstype=squashfs,jffs2 init=/bin/sh"
-CONFIG_CMDLINE_BOOL=y
-CONFIG_CMDLINE_OVERRIDE=y
-CONFIG_CPU_BIG_ENDIAN=y
-CONFIG_CPU_HAS_PREFETCH=y
-CONFIG_CPU_HAS_SYNC=y
-CONFIG_CPU_MIPS32=y
-# CONFIG_CPU_MIPS32_R1 is not set
-CONFIG_CPU_MIPS32_R2=y
-CONFIG_CPU_MIPSR2=y
-CONFIG_CPU_SUPPORTS_32BIT_KERNEL=y
-CONFIG_CPU_SUPPORTS_HIGHMEM=y
-CONFIG_CSRC_R4K=y
-CONFIG_CSRC_R4K_LIB=y
-CONFIG_DECOMPRESS_LZMA=y
-CONFIG_DMA_NONCOHERENT=y
-CONFIG_EARLY_PRINTK=y
-# CONFIG_FSNOTIFY is not set
-CONFIG_GENERIC_ATOMIC64=y
-CONFIG_GENERIC_CLOCKEVENTS=y
-CONFIG_GENERIC_CLOCKEVENTS_BUILD=y
-CONFIG_GENERIC_CMOS_UPDATE=y
-CONFIG_GENERIC_FIND_LAST_BIT=y
-CONFIG_GENERIC_FIND_NEXT_BIT=y
-# CONFIG_GENERIC_HARDIRQS_NO_DEPRECATED is not set
-CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
-# CONFIG_GENERIC_PENDING_IRQ is not set
-# CONFIG_HARDIRQS_SW_RESEND is not set
-CONFIG_HARDWARE_WATCHPOINTS=y
-CONFIG_HAS_DMA=y
-CONFIG_HAS_IOMEM=y
-CONFIG_HAS_IOPORT=y
-CONFIG_HAVE_ARCH_KGDB=y
-CONFIG_HAVE_C_RECORDMCOUNT=y
-CONFIG_HAVE_DMA_API_DEBUG=y
-CONFIG_HAVE_DMA_ATTRS=y
-CONFIG_HAVE_DYNAMIC_FTRACE=y
-CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y
-CONFIG_HAVE_FUNCTION_GRAPH_TRACER=y
-CONFIG_HAVE_FUNCTION_TRACER=y
-CONFIG_HAVE_FUNCTION_TRACE_MCOUNT_TEST=y
-CONFIG_HAVE_GENERIC_DMA_COHERENT=y
-CONFIG_HAVE_GENERIC_HARDIRQS=y
-CONFIG_HAVE_IDE=y
-CONFIG_HAVE_OPROFILE=y
-CONFIG_HAVE_PERF_EVENTS=y
-# CONFIG_HAVE_SPARSE_IRQ is not set
-CONFIG_HAVE_STD_PC_SERIAL_PORT=y
-CONFIG_HW_HAS_PCI=y
-CONFIG_HW_RANDOM=y
-CONFIG_INITRAMFS_SOURCE=""
-CONFIG_IRQ_CPU=y
-# CONFIG_IRQ_PER_CPU is not set
-CONFIG_KALLSYMS=y
-CONFIG_LOONGSON_UART_BASE=y
-CONFIG_MACH_NO_WESTBRIDGE=y
-CONFIG_MIPS=y
-CONFIG_MIPS_L1_CACHE_SHIFT=5
-# CONFIG_MIPS_MACHINE is not set
-CONFIG_MIPS_MT_DISABLED=y
-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_CFI_ADV_OPTIONS=y
-# CONFIG_MTD_CFI_GEOMETRY is not set
-# CONFIG_MTD_CFI_INTELEXT is not set
-CONFIG_MTD_PHYSMAP=y
-CONFIG_MTD_REDBOOT_DIRECTORY_BLOCK=-3
-CONFIG_MTD_REDBOOT_PARTS=y
-CONFIG_NEED_DMA_MAP_STATE=y
-CONFIG_NEED_PER_CPU_KM=y
-# CONFIG_NET_PCI is not set
-CONFIG_PAGEFLAGS_EXTENDED=y
-CONFIG_PCI=y
-CONFIG_PCI_DOMAINS=y
-CONFIG_PERF_USE_VMALLOC=y
-# CONFIG_PREEMPT_RCU is not set
-# CONFIG_QUOTACTL is not set
-# CONFIG_SCSI_DMA is not set
-# CONFIG_SERIAL_8250 is not set
-CONFIG_SWAP_IO_SPACE=y
-CONFIG_SYS_HAS_CPU_MIPS32_R1=y
-CONFIG_SYS_HAS_CPU_MIPS32_R2=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_USB_SUPPORT=y
-CONFIG_ZONE_DMA_FLAG=0
diff --git a/target/linux/amazon/config-3.3 b/target/linux/amazon/config-3.3
new file mode 100644 (file)
index 0000000..e34f87b
--- /dev/null
@@ -0,0 +1,113 @@
+CONFIG_ADM6996_SUPPORT=y
+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_BINFMT_ELF_RANDOMIZE_PIE=y
+CONFIG_ARCH_DISCARD_MEMBLOCK=y
+# CONFIG_ARCH_DMA_ADDR_T_64BIT is not set
+# CONFIG_ARCH_HAS_ILOG2_U32 is not set
+# CONFIG_ARCH_HAS_ILOG2_U64 is not set
+CONFIG_ARCH_HIBERNATION_POSSIBLE=y
+# CONFIG_ARCH_PHYS_ADDR_T_64BIT is not set
+# CONFIG_ARCH_SUPPORTS_MSI is not set
+CONFIG_ARCH_SUSPEND_POSSIBLE=y
+CONFIG_BCMA_POSSIBLE=y
+CONFIG_CEVT_R4K=y
+CONFIG_CEVT_R4K_LIB=y
+CONFIG_CMDLINE="console=ttyS0,115200 rootfstype=squashfs,jffs2 init=/bin/sh"
+CONFIG_CMDLINE_BOOL=y
+CONFIG_CMDLINE_OVERRIDE=y
+CONFIG_CPU_BIG_ENDIAN=y
+CONFIG_CPU_HAS_PREFETCH=y
+CONFIG_CPU_HAS_SYNC=y
+CONFIG_CPU_MIPS32=y
+# CONFIG_CPU_MIPS32_R1 is not set
+CONFIG_CPU_MIPS32_R2=y
+CONFIG_CPU_MIPSR2=y
+CONFIG_CPU_SUPPORTS_32BIT_KERNEL=y
+CONFIG_CPU_SUPPORTS_HIGHMEM=y
+CONFIG_CSRC_R4K=y
+CONFIG_CSRC_R4K_LIB=y
+CONFIG_DECOMPRESS_LZMA=y
+CONFIG_DMA_NONCOHERENT=y
+CONFIG_EARLY_PRINTK=y
+CONFIG_GENERIC_ATOMIC64=y
+CONFIG_GENERIC_CLOCKEVENTS=y
+CONFIG_GENERIC_CLOCKEVENTS_BUILD=y
+CONFIG_GENERIC_CMOS_UPDATE=y
+# CONFIG_GENERIC_CPU_DEVICES is not set
+CONFIG_GENERIC_IRQ_SHOW=y
+CONFIG_GENERIC_PCI_IOMAP=y
+CONFIG_HARDWARE_WATCHPOINTS=y
+CONFIG_HAS_DMA=y
+CONFIG_HAS_IOMEM=y
+CONFIG_HAS_IOPORT=y
+CONFIG_HAVE_ARCH_JUMP_LABEL=y
+CONFIG_HAVE_ARCH_KGDB=y
+CONFIG_HAVE_C_RECORDMCOUNT=y
+CONFIG_HAVE_DMA_API_DEBUG=y
+CONFIG_HAVE_DMA_ATTRS=y
+CONFIG_HAVE_DYNAMIC_FTRACE=y
+CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y
+CONFIG_HAVE_FUNCTION_GRAPH_TRACER=y
+CONFIG_HAVE_FUNCTION_TRACER=y
+CONFIG_HAVE_FUNCTION_TRACE_MCOUNT_TEST=y
+CONFIG_HAVE_GENERIC_DMA_COHERENT=y
+CONFIG_HAVE_GENERIC_HARDIRQS=y
+CONFIG_HAVE_IDE=y
+CONFIG_HAVE_IRQ_WORK=y
+CONFIG_HAVE_MEMBLOCK=y
+CONFIG_HAVE_MEMBLOCK_NODE_MAP=y
+CONFIG_HAVE_OPROFILE=y
+CONFIG_HAVE_PERF_EVENTS=y
+CONFIG_HAVE_STD_PC_SERIAL_PORT=y
+CONFIG_HW_HAS_PCI=y
+CONFIG_HW_RANDOM=y
+CONFIG_INITRAMFS_SOURCE=""
+CONFIG_IRQ_CPU=y
+CONFIG_IRQ_FORCED_THREADING=y
+CONFIG_KALLSYMS=y
+# CONFIG_MINIX_FS_NATIVE_ENDIAN is not set
+CONFIG_MIPS=y
+CONFIG_MIPS_L1_CACHE_SHIFT=5
+# CONFIG_MIPS_MACHINE is not set
+CONFIG_MIPS_MT_DISABLED=y
+# CONFIG_MLX4_CORE 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_CFI_ADV_OPTIONS=y
+# CONFIG_MTD_CFI_GEOMETRY is not set
+# CONFIG_MTD_CFI_INTELEXT is not set
+CONFIG_MTD_PHYSMAP=y
+CONFIG_MTD_REDBOOT_DIRECTORY_BLOCK=-3
+CONFIG_MTD_REDBOOT_PARTS=y
+CONFIG_NEED_DMA_MAP_STATE=y
+CONFIG_NEED_PER_CPU_KM=y
+CONFIG_NO_GENERIC_PCI_IOPORT_MAP=y
+CONFIG_PAGEFLAGS_EXTENDED=y
+CONFIG_PCI=y
+CONFIG_PCI_DOMAINS=y
+CONFIG_PERF_USE_VMALLOC=y
+# CONFIG_PREEMPT_RCU is not set
+# CONFIG_QUOTACTL is not set
+# CONFIG_SCSI_DMA is not set
+# CONFIG_SERIAL_8250 is not set
+CONFIG_SWAP_IO_SPACE=y
+CONFIG_SYS_HAS_CPU_MIPS32_R1=y
+CONFIG_SYS_HAS_CPU_MIPS32_R2=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_USB_ARCH_HAS_XHCI=y
+CONFIG_USB_SUPPORT=y
+CONFIG_XZ_DEC=y
+CONFIG_ZONE_DMA_FLAG=0
index e264ca759267e9aec0d9196942c4f4e8e88bc61d..05ff1ee75acf453e5aff0075002d3813fe9b1a01 100644 (file)
 #include <asm/irq.h>
 #include <asm/time.h>
 
-static void amazon_disable_irq(unsigned int irq_nr)
+static void amazon_disable_irq(struct irq_data *d)
 {
        int i;
        u32 amazon_ier = AMAZON_ICU_IM0_IER;
+       unsigned int irq_nr = d->irq;
 
        if (irq_nr <= INT_NUM_IM0_IRL11 && irq_nr >= INT_NUM_IM0_IRL0)
                amazon_writel(amazon_readl(amazon_ier) & (~(AMAZON_DMA_H_MASK)), amazon_ier);
@@ -53,11 +54,12 @@ static void amazon_disable_irq(unsigned int irq_nr)
        }       
 }
 
-static void amazon_mask_and_ack_irq(unsigned int irq_nr)
+static void amazon_mask_and_ack_irq(struct irq_data *d)
 {
        int i;
        u32 amazon_ier = AMAZON_ICU_IM0_IER;
        u32 amazon_isr = AMAZON_ICU_IM0_ISR;
+       unsigned int irq_nr = d->irq;
 
        if (irq_nr <= INT_NUM_IM0_IRL11 && irq_nr >= INT_NUM_IM0_IRL0){
                amazon_writel(amazon_readl(amazon_ier) & (~(AMAZON_DMA_H_MASK)), amazon_ier);
@@ -77,10 +79,11 @@ static void amazon_mask_and_ack_irq(unsigned int irq_nr)
        }
 }
 
-static void amazon_enable_irq(unsigned int irq_nr)
+static void amazon_enable_irq(struct irq_data *d)
 {
        int i;
        u32 amazon_ier = AMAZON_ICU_IM0_IER;
+       unsigned int irq_nr = d->irq;
 
        if (irq_nr <= INT_NUM_IM0_IRL11 && irq_nr >= INT_NUM_IM0_IRL0)
                amazon_writel(amazon_readl(amazon_ier) | AMAZON_DMA_H_MASK, amazon_ier);
@@ -96,29 +99,21 @@ static void amazon_enable_irq(unsigned int irq_nr)
        }
 }
 
-static unsigned int amazon_startup_irq(unsigned int irq)
+static unsigned int amazon_startup_irq(struct irq_data *d)
 {
-       amazon_enable_irq(irq);
+       amazon_enable_irq(d);
        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 irq_chip amazon_irq_type = {
        .name = "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
+       .irq_startup = amazon_startup_irq,
+       .irq_enable = amazon_enable_irq,
+       .irq_disable = amazon_disable_irq,
+       .irq_unmask = amazon_enable_irq,
+       .irq_ack = amazon_mask_and_ack_irq,
+       .irq_mask = amazon_disable_irq,
+       .irq_mask_ack = amazon_mask_and_ack_irq,
 };
 
 /* Cascaded interrupts from IM0-4 */
@@ -178,7 +173,7 @@ void __init arch_init_irq(void)
        }
 
        for (i = INT_NUM_IRQ0; i <= INT_NUM_IM4_IRL31; i++)
-               set_irq_chip_and_handler(i, &amazon_irq_type,
+               irq_set_chip_and_handler(i, &amazon_irq_type,
                        handle_level_irq);
 
        set_c0_status(IE_IRQ0 | IE_IRQ1 | IE_IRQ2 | IE_IRQ3 | IE_IRQ4 | IE_IRQ5);
index 55bfe32372810acb8cd8c5bc265268c9e45f826d..568f7d828da92a39d17cd01f20aabe9da6ea4c90 100644 (file)
@@ -118,7 +118,7 @@ int find_uImage_size(unsigned long start_offset)
        return temp + 0x40;
 }
 
-static int __init amazon_mtd_probe(struct platform_device *dev)
+static int amazon_mtd_probe(struct platform_device *dev)
 {
        unsigned long uimage_size;
        struct mtd_info *mymtd = NULL;
@@ -167,7 +167,7 @@ static int __init amazon_mtd_probe(struct platform_device *dev)
                amazon_partitions[2].size = mymtd->size - amazon_partitions[2].offset - (2 * mymtd->erasesize);
        }
 
-       add_mtd_partitions(mymtd, parts, 3);
+       mtd_device_register(mymtd, parts, 3);
 
        printk(KERN_INFO "amazon_mtd: added %s flash with %dMB\n",
                amazon_map.name, ((int)mymtd->size) >> 20);
diff --git a/target/linux/amazon/files/drivers/net/admmod.c b/target/linux/amazon/files/drivers/net/admmod.c
deleted file mode 100644 (file)
index 473a1f6..0000000
+++ /dev/null
@@ -1,1494 +0,0 @@
-/******************************************************************************
-     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/version.h>
-#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)
-{
-    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)
-{
-    return 0;
-}
-
-/* IOCTL function */
-
-#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,36))
-static long adm_ioctl(struct file *filp, unsigned int cmd, unsigned long args)
-#else
-static int adm_ioctl(struct inode *inode, struct file *filp, unsigned int cmd, unsigned long args)
-#endif
-{
-    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,
-#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,36))
-    unlocked_ioctl: adm_ioctl
-#else
-    ioctl: adm_ioctl
-#endif
-};
-
-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/files/drivers/net/amazon_sw.c b/target/linux/amazon/files/drivers/net/amazon_sw.c
deleted file mode 100644 (file)
index 54a7062..0000000
+++ /dev/null
@@ -1,899 +0,0 @@
-/*
- *   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>
-// copyright 2009 hauke mehrtens <hauke@hauke-m.de>
-
-
-// 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 <linux/platform_device.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);
-
-static struct net_device *switch_devs[2];
-
-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(KERN_INFO "amazon_mii0: 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 *) netdev_priv(dev);
-       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 *) netdev_priv(dev);
-       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 *) netdev_priv(dev);
-       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(KERN_WARNING "amazon_mii0: 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 *) netdev_priv(dev);
-       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 *) netdev_priv(dev);
-#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 = netdev_priv(dev);
-       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 *) netdev_priv(dev);
-
-       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 *) netdev_priv(dev);
-       priv->stats.tx_errors++;
-       netif_wake_queue(dev);
-       return;
-}
-
-void negotiate(struct net_device *dev)
-{
-       struct switch_priv *priv = (struct switch_priv *) netdev_priv(dev);
-       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 *) netdev_priv(dev);
-       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 *) netdev_priv(dev);
-       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 *) netdev_priv(dev);
-       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 *) netdev_priv(dev);
-       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(KERN_WARNING "amazon_mii0: packet too large %d\n", len);
-               goto switch_hw_receive_err_exit;
-       }
-
-       /* remove CRC */
-       len -= 4;
-       if (skb == NULL) {
-               printk(KERN_WARNING "amazon_mii0: cannot restore pointer\n");
-               goto switch_hw_receive_err_exit;
-       }
-       if (len > (skb->end - skb->tail)) {
-               printk(KERN_WARNING "amazon_mii0: 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 = 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, struct net_device *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;
-       } else {
-               num_tx_chan = 1;
-               num_rx_chan = 2;
-       }
-       dma_dev->priv = dev;
-
-       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;
-}
-
-static const struct net_device_ops amazon_mii_ops = {
-       .ndo_init               = switch_init,
-       .ndo_open               = switch_open,
-       .ndo_stop               = switch_release,
-       .ndo_start_xmit         = switch_tx,
-       .ndo_do_ioctl           = switch_ioctl,
-       .ndo_get_stats          = switch_stats,
-       .ndo_change_mtu         = switch_change_mtu,
-       .ndo_set_mac_address            = switch_set_mac_address,
-       .ndo_tx_timeout         = switch_tx_timeout,
-};
-
-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(KERN_INFO "amazon_mii0: %s up using ", dev->name);
-       dev->watchdog_timeo = timeout;
-
-       priv = netdev_priv(dev);
-       priv->dma_device = (struct dma_device_info *) kmalloc(sizeof(struct dma_device_info), GFP_KERNEL);
-       if (priv->num == 0) {
-               sprintf(priv->dma_device->device_name, "switch1");
-       } else if (priv->num == 1) {
-               sprintf(priv->dma_device->device_name, "switch2");
-       }
-       printk("\"%s\"\n", priv->dma_device->device_name);
-       init_dma_device(priv->dma_device, dev);
-       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) priv->num;
-       } else {
-               for (i = 0; i < 6; i++) {
-                       dev->dev_addr[i] = my_ethaddr[i];
-               }
-               dev->dev_addr[5] += +(unsigned char) priv->num;
-       }
-       return OK;
-}
-
-static int amazon_mii_probe(struct platform_device *dev)
-{
-       int i = 0, result, device_present = 0;
-       struct switch_priv *priv;
-
-       for (i = 0; i < AMAZON_SW_INT_NO; i++) {
-               switch_devs[i] = alloc_etherdev(sizeof(struct switch_priv));
-               switch_devs[i]->netdev_ops = &amazon_mii_ops;
-               strcpy(switch_devs[i]->name, "eth%d");
-               priv = (struct switch_priv *) netdev_priv(switch_devs[i]);
-               priv->num = i;
-               if ((result = register_netdev(switch_devs[i])))
-                       printk(KERN_WARNING "amazon_mii0: error %i registering device \"%s\"\n", result, switch_devs[i]->name);
-               else
-                       device_present++;
-       }
-       amazon_sw_chip_init();
-       return device_present ? 0 : -ENODEV;
-}
-
-static int amazon_mii_remove(struct platform_device *dev)
-{
-       int i;
-       struct switch_priv *priv;
-       for (i = 0; i < AMAZON_SW_INT_NO; i++) {
-               priv = netdev_priv(switch_devs[i]);
-               if (priv->dma_device) {
-                       dma_device_unregister(priv->dma_device);
-                       kfree(priv->dma_device);
-               }
-               kfree(netdev_priv(switch_devs[i]));
-               unregister_netdev(switch_devs[i]);
-       }
-       return 0;
-}
-
-static struct platform_driver amazon_mii_driver = {
-       .probe = amazon_mii_probe,
-       .remove = amazon_mii_remove,
-       .driver = {
-               .name = "amazon_mii0",
-               .owner = THIS_MODULE,
-       },
-};
-
-static int __init amazon_mii_init(void)
-{
-       int ret = platform_driver_register(&amazon_mii_driver);
-       if (ret)
-               printk(KERN_WARNING "amazon_mii0: Error registering platfom driver!\n");
-       return ret;
-}
-
-static void __exit amazon_mii_cleanup(void)
-{
-       platform_driver_unregister(&amazon_mii_driver);
-}
-
-module_init(amazon_mii_init);
-module_exit(amazon_mii_cleanup);
-
-MODULE_LICENSE("GPL");
-MODULE_AUTHOR("Wu Qi Ming");
-MODULE_DESCRIPTION("ethernet driver for AMAZON boards");
-
diff --git a/target/linux/amazon/files/drivers/net/ethernet/admmod.c b/target/linux/amazon/files/drivers/net/ethernet/admmod.c
new file mode 100644 (file)
index 0000000..a11ee1d
--- /dev/null
@@ -0,0 +1,1493 @@
+/******************************************************************************
+     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/version.h>
+#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)
+{
+    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)
+{
+    return 0;
+}
+
+/* IOCTL function */
+
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,36))
+static long adm_ioctl(struct file *filp, unsigned int cmd, unsigned long args)
+#else
+static int adm_ioctl(struct inode *inode, struct file *filp, unsigned int cmd, unsigned long args)
+#endif
+{
+    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 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,
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,36))
+    unlocked_ioctl: adm_ioctl
+#else
+    ioctl: adm_ioctl
+#endif
+};
+
+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/files/drivers/net/ethernet/amazon_sw.c b/target/linux/amazon/files/drivers/net/ethernet/amazon_sw.c
new file mode 100644 (file)
index 0000000..d18b439
--- /dev/null
@@ -0,0 +1,899 @@
+/*
+ *   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>
+// copyright 2009 hauke mehrtens <hauke@hauke-m.de>
+
+
+// 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 <linux/platform_device.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 *************************************/
+static 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);
+
+static struct net_device *switch_devs[2];
+
+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(KERN_INFO "amazon_mii0: 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 *) netdev_priv(dev);
+       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 *) netdev_priv(dev);
+       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 *) netdev_priv(dev);
+       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(KERN_WARNING "amazon_mii0: 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 *) netdev_priv(dev);
+       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 *) netdev_priv(dev);
+#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 = netdev_priv(dev);
+       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 *) netdev_priv(dev);
+
+       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 *) netdev_priv(dev);
+       priv->stats.tx_errors++;
+       netif_wake_queue(dev);
+       return;
+}
+
+void negotiate(struct net_device *dev)
+{
+       struct switch_priv *priv = (struct switch_priv *) netdev_priv(dev);
+       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 *) netdev_priv(dev);
+       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 *) netdev_priv(dev);
+       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 *) netdev_priv(dev);
+       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 *) netdev_priv(dev);
+       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(KERN_WARNING "amazon_mii0: packet too large %d\n", len);
+               goto switch_hw_receive_err_exit;
+       }
+
+       /* remove CRC */
+       len -= 4;
+       if (skb == NULL) {
+               printk(KERN_WARNING "amazon_mii0: cannot restore pointer\n");
+               goto switch_hw_receive_err_exit;
+       }
+       if (len > (skb->end - skb->tail)) {
+               printk(KERN_WARNING "amazon_mii0: 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 = 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, struct net_device *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;
+       } else {
+               num_tx_chan = 1;
+               num_rx_chan = 2;
+       }
+       dma_dev->priv = dev;
+
+       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;
+}
+
+static const struct net_device_ops amazon_mii_ops = {
+       .ndo_init               = switch_init,
+       .ndo_open               = switch_open,
+       .ndo_stop               = switch_release,
+       .ndo_start_xmit         = switch_tx,
+       .ndo_do_ioctl           = switch_ioctl,
+       .ndo_get_stats          = switch_stats,
+       .ndo_change_mtu         = switch_change_mtu,
+       .ndo_set_mac_address            = switch_set_mac_address,
+       .ndo_tx_timeout         = switch_tx_timeout,
+};
+
+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(KERN_INFO "amazon_mii0: %s up using ", dev->name);
+       dev->watchdog_timeo = timeout;
+
+       priv = netdev_priv(dev);
+       priv->dma_device = (struct dma_device_info *) kmalloc(sizeof(struct dma_device_info), GFP_KERNEL);
+       if (priv->num == 0) {
+               sprintf(priv->dma_device->device_name, "switch1");
+       } else if (priv->num == 1) {
+               sprintf(priv->dma_device->device_name, "switch2");
+       }
+       printk("\"%s\"\n", priv->dma_device->device_name);
+       init_dma_device(priv->dma_device, dev);
+       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) priv->num;
+       } else {
+               for (i = 0; i < 6; i++) {
+                       dev->dev_addr[i] = my_ethaddr[i];
+               }
+               dev->dev_addr[5] += +(unsigned char) priv->num;
+       }
+       return OK;
+}
+
+static int amazon_mii_probe(struct platform_device *dev)
+{
+       int i = 0, result, device_present = 0;
+       struct switch_priv *priv;
+
+       for (i = 0; i < AMAZON_SW_INT_NO; i++) {
+               switch_devs[i] = alloc_etherdev(sizeof(struct switch_priv));
+               switch_devs[i]->netdev_ops = &amazon_mii_ops;
+               strcpy(switch_devs[i]->name, "eth%d");
+               priv = (struct switch_priv *) netdev_priv(switch_devs[i]);
+               priv->num = i;
+               if ((result = register_netdev(switch_devs[i])))
+                       printk(KERN_WARNING "amazon_mii0: error %i registering device \"%s\"\n", result, switch_devs[i]->name);
+               else
+                       device_present++;
+       }
+       amazon_sw_chip_init();
+       return device_present ? 0 : -ENODEV;
+}
+
+static int amazon_mii_remove(struct platform_device *dev)
+{
+       int i;
+       struct switch_priv *priv;
+       for (i = 0; i < AMAZON_SW_INT_NO; i++) {
+               priv = netdev_priv(switch_devs[i]);
+               if (priv->dma_device) {
+                       dma_device_unregister(priv->dma_device);
+                       kfree(priv->dma_device);
+               }
+               kfree(netdev_priv(switch_devs[i]));
+               unregister_netdev(switch_devs[i]);
+       }
+       return 0;
+}
+
+static struct platform_driver amazon_mii_driver = {
+       .probe = amazon_mii_probe,
+       .remove = amazon_mii_remove,
+       .driver = {
+               .name = "amazon_mii0",
+               .owner = THIS_MODULE,
+       },
+};
+
+static int __init amazon_mii_init(void)
+{
+       int ret = platform_driver_register(&amazon_mii_driver);
+       if (ret)
+               printk(KERN_WARNING "amazon_mii0: Error registering platfom driver!\n");
+       return ret;
+}
+
+static void __exit amazon_mii_cleanup(void)
+{
+       platform_driver_unregister(&amazon_mii_driver);
+}
+
+module_init(amazon_mii_init);
+module_exit(amazon_mii_cleanup);
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Wu Qi Ming");
+MODULE_DESCRIPTION("ethernet driver for AMAZON boards");
+
diff --git a/target/linux/amazon/files/drivers/serial/amazon_asc.c b/target/linux/amazon/files/drivers/serial/amazon_asc.c
deleted file mode 100644 (file)
index 4492086..0000000
+++ /dev/null
@@ -1,711 +0,0 @@
-/*
- *  Driver for AMAZONASC serial ports
- *
- *  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
- *
- * Copyright (C) 2004 Infineon IFAP DC COM CPE
- * Copyright (C) 2007 Felix Fietkau <nbd@openwrt.org>
- * Copyright (C) 2007 John Crispin <blogic@openwrt.org>
- */
-
-#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 <linux/platform_device.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
-
-#include <linux/serial_core.h>
-
-#define UART_NR                1
-
-#define UART_DUMMY_UER_RX 1
-
-#define SERIAL_AMAZONASC_MAJOR TTY_MAJOR
-#define CALLOUT_AMAZONASC_MAJOR        TTYAUX_MAJOR
-#define SERIAL_AMAZONASC_MINOR 64
-#define SERIAL_AMAZONASC_NR    UART_NR
-
-static void amazonasc_tx_chars(struct uart_port *port);
-static struct uart_port amazonasc_ports[UART_NR];
-static struct uart_driver amazonasc_reg;
-static unsigned int uartclk = 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_writel(ASCWHBCON_CLRREN, AMAZON_ASC_WHBCON);
-}
-
-static void amazonasc_enable_ms(struct uart_port *port)
-{
-       /* no modem signals */
-       return;
-}
-
-#include <linux/version.h>
-
-static void
-amazonasc_rx_chars(struct uart_port *port)
-{
-#if (LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 31))
-       struct tty_struct *tty = port->state->port.tty;
-#else
-       struct tty_struct *tty = port->info->port.tty;
-#endif
-       unsigned int ch = 0, rsr = 0, fifocnt;
-
-       fifocnt = amazon_readl(AMAZON_ASC_FSTAT) & ASCFSTAT_RXFFLMASK;
-       while (fifocnt--)
-       {
-               u8 flag = TTY_NORMAL;
-               ch = amazon_readl(AMAZON_ASC_RBUF);
-               rsr = (amazon_readl(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++;
-                               amazon_writel_masked(AMAZON_ASC_WHBCON, ASCWHBCON_CLRPE, ASCWHBCON_CLRPE);
-                       } else if (rsr & ASCCON_FE) {
-                               port->icount.frame++;
-                               amazon_writel_masked(AMAZON_ASC_WHBCON, ASCWHBCON_CLRFE, ASCWHBCON_CLRFE);
-                       }
-                       if (rsr & ASCCON_OE) {
-                               port->icount.overrun++;
-                               amazon_writel_masked(AMAZON_ASC_WHBCON, ASCWHBCON_CLROE, 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)
-{
-#if (LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 31))
-       struct circ_buf *xmit = &port->state->xmit;
-#else
-       struct circ_buf *xmit = &port->info->xmit;
-#endif
-
-       if (uart_tx_stopped(port)) {
-               amazonasc_stop_tx(port);
-               return;
-       }
-       
-       while (((amazon_readl(AMAZON_ASC_FSTAT) & ASCFSTAT_TXFFLMASK)
-                       >> ASCFSTAT_TXFFLOFF) != AMAZONASC_TXFIFO_FULL)
-       {
-               if (port->x_char) {
-                       amazon_writel(port->x_char, AMAZON_ASC_TBUF);
-                       port->icount.tx++;
-                       port->x_char = 0;
-                       continue;
-               }
-
-               if (uart_circ_empty(xmit))
-                       break;
-
-               amazon_writel(xmit->buf[xmit->tail], AMAZON_ASC_TBUF);
-               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_writel(ASC_IRNCR_TIR, AMAZON_ASC_IRNCR1);
-       amazonasc_start_tx(port);
-
-       /* clear any pending interrupts */
-       amazon_writel_masked(AMAZON_ASC_WHBCON, 
-                       (ASCWHBCON_CLRPE | ASCWHBCON_CLRFE | ASCWHBCON_CLROE), 
-                       (ASCWHBCON_CLRPE | ASCWHBCON_CLRFE | ASCWHBCON_CLROE));
-
-       return IRQ_HANDLED;
-}
-
-static irqreturn_t amazonasc_er_int(int irq, void *port)
-{
-       /* clear any pending interrupts */
-       amazon_writel_masked(AMAZON_ASC_WHBCON, 
-                       (ASCWHBCON_CLRPE | ASCWHBCON_CLRFE | ASCWHBCON_CLROE), 
-                       (ASCWHBCON_CLRPE | ASCWHBCON_CLRFE | ASCWHBCON_CLROE));
-       
-       return IRQ_HANDLED;
-}
-
-static irqreturn_t amazonasc_rx_int(int irq, void *port)
-{
-       amazon_writel(ASC_IRNCR_RIR, AMAZON_ASC_IRNCR1);
-       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_readl(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;
-
-       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
-        */
-        amazon_writel_masked(AMAZON_GPIO_P1_DIR, 0x18, 0x10);  //P1.4 output, P1.3 input
-        amazon_writel_masked(AMAZON_GPIO_P1_ALTSEL0, 0x18, 0x18);              //ALTSETL0 11
-        amazon_writel_masked(AMAZON_GPIO_P1_ALTSEL1, 0x18, 0);         //ALTSETL1 00
-        amazon_writel_masked(AMAZON_GPIO_P1_OD, 0x18, 0x10);
-       
-       /* set up the CLC */
-       amazon_writel_masked(AMAZON_ASC_CLC, AMAZON_ASC_CLC_DISS, 0);
-       amazon_writel_masked(AMAZON_ASC_CLC, ASCCLC_RMCMASK, 1 << ASCCLC_RMCOFFSET);
-       
-       /* asynchronous mode */
-       con = ASCCON_M_8ASYNC | ASCCON_FEN | ASCCON_OEN | ASCCON_PEN;
-       
-       /* choose the line - there's only one */
-       amazon_writel(0, AMAZON_ASC_PISEL);
-       amazon_writel(((AMAZONASC_TXFIFO_FL << ASCTXFCON_TXFITLOFF) & ASCTXFCON_TXFITLMASK) | ASCTXFCON_TXFEN | ASCTXFCON_TXFFLU, 
-               AMAZON_ASC_TXFCON);
-       amazon_writel(((AMAZONASC_RXFIFO_FL << ASCRXFCON_RXFITLOFF) & ASCRXFCON_RXFITLMASK) | ASCRXFCON_RXFEN | ASCRXFCON_RXFFLU, 
-               AMAZON_ASC_RXFCON);
-       wmb();
-       
-       amazon_writel_masked(AMAZON_ASC_CON, con, con);
-
-       retval = request_irq(AMAZONASC_RIR, amazonasc_rx_int, 0, "asc_rx", port);
-       if (retval){
-               printk("failed to request amazonasc_rx_int\n");
-               return retval;
-       }
-       retval = request_irq(AMAZONASC_TIR, amazonasc_tx_int, 0, "asc_tx", port);
-       if (retval){
-               printk("failed to request amazonasc_tx_int\n");
-               goto err1;
-       }
-
-       retval = request_irq(AMAZONASC_EIR, amazonasc_er_int, 0, "asc_er", port);
-       if (retval){
-               printk("failed to request amazonasc_er_int\n");
-               goto err2;
-       }
-       
-       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_irq(AMAZONASC_RIR, port);
-       free_irq(AMAZONASC_TIR, port);
-       free_irq(AMAZONASC_EIR, port);
-       /*
-        * disable the baudrate generator to disable the ASC
-        */
-       amazon_writel(0, AMAZON_ASC_CON);
-
-       /* flush and then disable the fifos */
-       amazon_writel_masked(AMAZON_ASC_RXFCON, ASCRXFCON_RXFFLU, ASCRXFCON_RXFFLU);
-       amazon_writel_masked(AMAZON_ASC_RXFCON, ASCRXFCON_RXFEN, 0);
-       amazon_writel_masked(AMAZON_ASC_TXFCON, ASCTXFCON_TXFFLU, ASCTXFCON_TXFFLU);
-       amazon_writel_masked(AMAZON_ASC_TXFCON, ASCTXFCON_TXFEN, 0);
-}
-
-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;
-       
-       port->ignore_status_mask = 0;
-       if (iflag & IGNPAR)
-               port->ignore_status_mask |= ASCCON_FE | ASCCON_PE;
-       
-       if (iflag & IGNBRK) {
-               /*
-                * 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_writel(con, AMAZON_ASC_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 */
-       amazon_writel_masked(AMAZON_ASC_CON, ASCCON_R, 0);
-       /* make sure the fractional divider is off */
-       amazon_writel_masked(AMAZON_ASC_CON, ASCCON_FDE, 0);
-       /* set up to use divisor of 2 */
-       amazon_writel_masked(AMAZON_ASC_CON, ASCCON_BRS, 0);
-       /* now we can write the new baudrate into the register */
-       amazon_writel(quot, AMAZON_ASC_BTR);
-       /* turn the baudrate generator back on */
-       amazon_writel_masked(AMAZON_ASC_CON, ASCCON_R, ASCCON_R);
-
-       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;
-       local_irq_save(flags);
-       for (i = 0; i < count;)
-       {
-               /* wait until the FIFO is not full */
-               do
-               {
-                       fifocnt = (amazon_readl(AMAZON_ASC_FSTAT) & ASCFSTAT_TXFFLMASK)
-                                       >> ASCFSTAT_TXFFLOFF;
-               } while (fifocnt == AMAZONASC_TXFIFO_FULL);
-               if (s[i] == '\0')
-               {
-                       break;
-               }
-               if (s[i] == '\n')
-               {
-                       amazon_writel('\r', AMAZON_ASC_TBUF);
-                       do
-                       {
-                               fifocnt = (amazon_readl(AMAZON_ASC_FSTAT) &
-                               ASCFSTAT_TXFFLMASK) >> ASCFSTAT_TXFFLOFF;
-                       } while (fifocnt == AMAZONASC_TXFIFO_FULL);
-               }
-               amazon_writel(s[i], AMAZON_ASC_TBUF);
-               i++;
-       } 
-
-       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_readl(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_readl(AMAZON_ASC_BTR) + 1;
-               
-               /* this gets hairy if the fractional divider is used */
-               if (lcr_h & ASCCON_FDE)
-               {
-                       div = 1;
-                       fdiv = amazon_readl(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 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 amazon_asc_probe(struct platform_device *dev)
-{
-       unsigned char res;
-       uart_register_driver(&amazonasc_reg);
-       res = uart_add_one_port(&amazonasc_reg, &amazonasc_ports[0]);
-       return res;
-}
-
-static int amazon_asc_remove(struct platform_device *dev)
-{
-       uart_unregister_driver(&amazonasc_reg);
-       return 0;
-}
-
-static struct platform_driver amazon_asc_driver = {
-       .probe = amazon_asc_probe,
-       .remove = amazon_asc_remove,
-       .driver = {
-               .name = "amazon_asc",
-               .owner = THIS_MODULE,
-       },
-};
-
-static int __init amazon_asc_init(void)
-{
-       int ret = platform_driver_register(&amazon_asc_driver);
-       if (ret)
-               printk(KERN_WARNING "amazon_asc: error registering platfom driver!\n");
-       return ret;
-}
-
-static void __exit amazon_asc_cleanup(void)
-{
-       platform_driver_unregister(&amazon_asc_driver);
-}
-
-module_init(amazon_asc_init);
-module_exit(amazon_asc_cleanup);
-
-MODULE_AUTHOR("Gary Jennejohn, Felix Fietkau, John Crispin");
-MODULE_DESCRIPTION("MIPS AMAZONASC serial port driver");
-MODULE_LICENSE("GPL");
-
diff --git a/target/linux/amazon/files/drivers/tty/serial/amazon_asc.c b/target/linux/amazon/files/drivers/tty/serial/amazon_asc.c
new file mode 100644 (file)
index 0000000..4492086
--- /dev/null
@@ -0,0 +1,711 @@
+/*
+ *  Driver for AMAZONASC serial ports
+ *
+ *  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
+ *
+ * Copyright (C) 2004 Infineon IFAP DC COM CPE
+ * Copyright (C) 2007 Felix Fietkau <nbd@openwrt.org>
+ * Copyright (C) 2007 John Crispin <blogic@openwrt.org>
+ */
+
+#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 <linux/platform_device.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
+
+#include <linux/serial_core.h>
+
+#define UART_NR                1
+
+#define UART_DUMMY_UER_RX 1
+
+#define SERIAL_AMAZONASC_MAJOR TTY_MAJOR
+#define CALLOUT_AMAZONASC_MAJOR        TTYAUX_MAJOR
+#define SERIAL_AMAZONASC_MINOR 64
+#define SERIAL_AMAZONASC_NR    UART_NR
+
+static void amazonasc_tx_chars(struct uart_port *port);
+static struct uart_port amazonasc_ports[UART_NR];
+static struct uart_driver amazonasc_reg;
+static unsigned int uartclk = 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_writel(ASCWHBCON_CLRREN, AMAZON_ASC_WHBCON);
+}
+
+static void amazonasc_enable_ms(struct uart_port *port)
+{
+       /* no modem signals */
+       return;
+}
+
+#include <linux/version.h>
+
+static void
+amazonasc_rx_chars(struct uart_port *port)
+{
+#if (LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 31))
+       struct tty_struct *tty = port->state->port.tty;
+#else
+       struct tty_struct *tty = port->info->port.tty;
+#endif
+       unsigned int ch = 0, rsr = 0, fifocnt;
+
+       fifocnt = amazon_readl(AMAZON_ASC_FSTAT) & ASCFSTAT_RXFFLMASK;
+       while (fifocnt--)
+       {
+               u8 flag = TTY_NORMAL;
+               ch = amazon_readl(AMAZON_ASC_RBUF);
+               rsr = (amazon_readl(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++;
+                               amazon_writel_masked(AMAZON_ASC_WHBCON, ASCWHBCON_CLRPE, ASCWHBCON_CLRPE);
+                       } else if (rsr & ASCCON_FE) {
+                               port->icount.frame++;
+                               amazon_writel_masked(AMAZON_ASC_WHBCON, ASCWHBCON_CLRFE, ASCWHBCON_CLRFE);
+                       }
+                       if (rsr & ASCCON_OE) {
+                               port->icount.overrun++;
+                               amazon_writel_masked(AMAZON_ASC_WHBCON, ASCWHBCON_CLROE, 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)
+{
+#if (LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 31))
+       struct circ_buf *xmit = &port->state->xmit;
+#else
+       struct circ_buf *xmit = &port->info->xmit;
+#endif
+
+       if (uart_tx_stopped(port)) {
+               amazonasc_stop_tx(port);
+               return;
+       }
+       
+       while (((amazon_readl(AMAZON_ASC_FSTAT) & ASCFSTAT_TXFFLMASK)
+                       >> ASCFSTAT_TXFFLOFF) != AMAZONASC_TXFIFO_FULL)
+       {
+               if (port->x_char) {
+                       amazon_writel(port->x_char, AMAZON_ASC_TBUF);
+                       port->icount.tx++;
+                       port->x_char = 0;
+                       continue;
+               }
+
+               if (uart_circ_empty(xmit))
+                       break;
+
+               amazon_writel(xmit->buf[xmit->tail], AMAZON_ASC_TBUF);
+               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_writel(ASC_IRNCR_TIR, AMAZON_ASC_IRNCR1);
+       amazonasc_start_tx(port);
+
+       /* clear any pending interrupts */
+       amazon_writel_masked(AMAZON_ASC_WHBCON, 
+                       (ASCWHBCON_CLRPE | ASCWHBCON_CLRFE | ASCWHBCON_CLROE), 
+                       (ASCWHBCON_CLRPE | ASCWHBCON_CLRFE | ASCWHBCON_CLROE));
+
+       return IRQ_HANDLED;
+}
+
+static irqreturn_t amazonasc_er_int(int irq, void *port)
+{
+       /* clear any pending interrupts */
+       amazon_writel_masked(AMAZON_ASC_WHBCON, 
+                       (ASCWHBCON_CLRPE | ASCWHBCON_CLRFE | ASCWHBCON_CLROE), 
+                       (ASCWHBCON_CLRPE | ASCWHBCON_CLRFE | ASCWHBCON_CLROE));
+       
+       return IRQ_HANDLED;
+}
+
+static irqreturn_t amazonasc_rx_int(int irq, void *port)
+{
+       amazon_writel(ASC_IRNCR_RIR, AMAZON_ASC_IRNCR1);
+       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_readl(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;
+
+       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
+        */
+        amazon_writel_masked(AMAZON_GPIO_P1_DIR, 0x18, 0x10);  //P1.4 output, P1.3 input
+        amazon_writel_masked(AMAZON_GPIO_P1_ALTSEL0, 0x18, 0x18);              //ALTSETL0 11
+        amazon_writel_masked(AMAZON_GPIO_P1_ALTSEL1, 0x18, 0);         //ALTSETL1 00
+        amazon_writel_masked(AMAZON_GPIO_P1_OD, 0x18, 0x10);
+       
+       /* set up the CLC */
+       amazon_writel_masked(AMAZON_ASC_CLC, AMAZON_ASC_CLC_DISS, 0);
+       amazon_writel_masked(AMAZON_ASC_CLC, ASCCLC_RMCMASK, 1 << ASCCLC_RMCOFFSET);
+       
+       /* asynchronous mode */
+       con = ASCCON_M_8ASYNC | ASCCON_FEN | ASCCON_OEN | ASCCON_PEN;
+       
+       /* choose the line - there's only one */
+       amazon_writel(0, AMAZON_ASC_PISEL);
+       amazon_writel(((AMAZONASC_TXFIFO_FL << ASCTXFCON_TXFITLOFF) & ASCTXFCON_TXFITLMASK) | ASCTXFCON_TXFEN | ASCTXFCON_TXFFLU, 
+               AMAZON_ASC_TXFCON);
+       amazon_writel(((AMAZONASC_RXFIFO_FL << ASCRXFCON_RXFITLOFF) & ASCRXFCON_RXFITLMASK) | ASCRXFCON_RXFEN | ASCRXFCON_RXFFLU, 
+               AMAZON_ASC_RXFCON);
+       wmb();
+       
+       amazon_writel_masked(AMAZON_ASC_CON, con, con);
+
+       retval = request_irq(AMAZONASC_RIR, amazonasc_rx_int, 0, "asc_rx", port);
+       if (retval){
+               printk("failed to request amazonasc_rx_int\n");
+               return retval;
+       }
+       retval = request_irq(AMAZONASC_TIR, amazonasc_tx_int, 0, "asc_tx", port);
+       if (retval){
+               printk("failed to request amazonasc_tx_int\n");
+               goto err1;
+       }
+
+       retval = request_irq(AMAZONASC_EIR, amazonasc_er_int, 0, "asc_er", port);
+       if (retval){
+               printk("failed to request amazonasc_er_int\n");
+               goto err2;
+       }
+       
+       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_irq(AMAZONASC_RIR, port);
+       free_irq(AMAZONASC_TIR, port);
+       free_irq(AMAZONASC_EIR, port);
+       /*
+        * disable the baudrate generator to disable the ASC
+        */
+       amazon_writel(0, AMAZON_ASC_CON);
+
+       /* flush and then disable the fifos */
+       amazon_writel_masked(AMAZON_ASC_RXFCON, ASCRXFCON_RXFFLU, ASCRXFCON_RXFFLU);
+       amazon_writel_masked(AMAZON_ASC_RXFCON, ASCRXFCON_RXFEN, 0);
+       amazon_writel_masked(AMAZON_ASC_TXFCON, ASCTXFCON_TXFFLU, ASCTXFCON_TXFFLU);
+       amazon_writel_masked(AMAZON_ASC_TXFCON, ASCTXFCON_TXFEN, 0);
+}
+
+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;
+       
+       port->ignore_status_mask = 0;
+       if (iflag & IGNPAR)
+               port->ignore_status_mask |= ASCCON_FE | ASCCON_PE;
+       
+       if (iflag & IGNBRK) {
+               /*
+                * 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_writel(con, AMAZON_ASC_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 */
+       amazon_writel_masked(AMAZON_ASC_CON, ASCCON_R, 0);
+       /* make sure the fractional divider is off */
+       amazon_writel_masked(AMAZON_ASC_CON, ASCCON_FDE, 0);
+       /* set up to use divisor of 2 */
+       amazon_writel_masked(AMAZON_ASC_CON, ASCCON_BRS, 0);
+       /* now we can write the new baudrate into the register */
+       amazon_writel(quot, AMAZON_ASC_BTR);
+       /* turn the baudrate generator back on */
+       amazon_writel_masked(AMAZON_ASC_CON, ASCCON_R, ASCCON_R);
+
+       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;
+       local_irq_save(flags);
+       for (i = 0; i < count;)
+       {
+               /* wait until the FIFO is not full */
+               do
+               {
+                       fifocnt = (amazon_readl(AMAZON_ASC_FSTAT) & ASCFSTAT_TXFFLMASK)
+                                       >> ASCFSTAT_TXFFLOFF;
+               } while (fifocnt == AMAZONASC_TXFIFO_FULL);
+               if (s[i] == '\0')
+               {
+                       break;
+               }
+               if (s[i] == '\n')
+               {
+                       amazon_writel('\r', AMAZON_ASC_TBUF);
+                       do
+                       {
+                               fifocnt = (amazon_readl(AMAZON_ASC_FSTAT) &
+                               ASCFSTAT_TXFFLMASK) >> ASCFSTAT_TXFFLOFF;
+                       } while (fifocnt == AMAZONASC_TXFIFO_FULL);
+               }
+               amazon_writel(s[i], AMAZON_ASC_TBUF);
+               i++;
+       } 
+
+       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_readl(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_readl(AMAZON_ASC_BTR) + 1;
+               
+               /* this gets hairy if the fractional divider is used */
+               if (lcr_h & ASCCON_FDE)
+               {
+                       div = 1;
+                       fdiv = amazon_readl(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 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 amazon_asc_probe(struct platform_device *dev)
+{
+       unsigned char res;
+       uart_register_driver(&amazonasc_reg);
+       res = uart_add_one_port(&amazonasc_reg, &amazonasc_ports[0]);
+       return res;
+}
+
+static int amazon_asc_remove(struct platform_device *dev)
+{
+       uart_unregister_driver(&amazonasc_reg);
+       return 0;
+}
+
+static struct platform_driver amazon_asc_driver = {
+       .probe = amazon_asc_probe,
+       .remove = amazon_asc_remove,
+       .driver = {
+               .name = "amazon_asc",
+               .owner = THIS_MODULE,
+       },
+};
+
+static int __init amazon_asc_init(void)
+{
+       int ret = platform_driver_register(&amazon_asc_driver);
+       if (ret)
+               printk(KERN_WARNING "amazon_asc: error registering platfom driver!\n");
+       return ret;
+}
+
+static void __exit amazon_asc_cleanup(void)
+{
+       platform_driver_unregister(&amazon_asc_driver);
+}
+
+module_init(amazon_asc_init);
+module_exit(amazon_asc_cleanup);
+
+MODULE_AUTHOR("Gary Jennejohn, Felix Fietkau, John Crispin");
+MODULE_DESCRIPTION("MIPS AMAZONASC serial port driver");
+MODULE_LICENSE("GPL");
+
index 89f1e2281c2d4d1f4ab8cdbebbbf49b897284b68..b18296b794ed4d6ac62d43e45a9102e1023f6018 100644 (file)
@@ -215,7 +215,7 @@ static struct file_operations wdt_fops = {
        release:        wdt_release,    
 };
 
-static int __init amazon_wdt_probe(struct platform_device *dev)
+static int amazon_wdt_probe(struct platform_device *dev)
 {
        int result = result = register_chrdev(0, "watchdog", &wdt_fops);
        
diff --git a/target/linux/amazon/patches-2.6.37/000-mips-bad-intctl.patch b/target/linux/amazon/patches-2.6.37/000-mips-bad-intctl.patch
deleted file mode 100644 (file)
index f89e078..0000000
+++ /dev/null
@@ -1,33 +0,0 @@
---- a/arch/mips/kernel/traps.c
-+++ b/arch/mips/kernel/traps.c
-@@ -1578,7 +1578,16 @@ void __cpuinit per_cpu_trap_init(void)
-       if (cpu_has_mips_r2) {
-               cp0_compare_irq_shift = CAUSEB_TI - CAUSEB_IP;
-               cp0_compare_irq = (read_c0_intctl() >> INTCTLB_IPTI) & 7;
-+              if (!cp0_compare_irq)
-+                      cp0_compare_irq = CP0_LEGACY_COMPARE_IRQ;
-+
-               cp0_perfcount_irq = (read_c0_intctl() >> INTCTLB_IPPCI) & 7;
-+              if (!cp0_perfcount_irq)
-+                      cp0_perfcount_irq = CP0_LEGACY_PERFCNT_IRQ;
-+
-+              if (arch_fixup_c0_irqs)
-+                      arch_fixup_c0_irqs();
-+
-               if (cp0_perfcount_irq == cp0_compare_irq)
-                       cp0_perfcount_irq = -1;
-       } else {
---- a/arch/mips/include/asm/irq.h
-+++ b/arch/mips/include/asm/irq.h
-@@ -138,9 +138,11 @@ extern void free_irqno(unsigned int irq)
-  * IE7.  Since R2 their number has to be read from the c0_intctl register.
-  */
- #define CP0_LEGACY_COMPARE_IRQ 7
-+#define CP0_LEGACY_PERFCNT_IRQ 7
- extern int cp0_compare_irq;
- extern int cp0_compare_irq_shift;
- extern int cp0_perfcount_irq;
-+extern void __weak arch_fixup_c0_irqs(void);
- #endif /* _ASM_IRQ_H */
diff --git a/target/linux/amazon/patches-2.6.37/010-mips_clocksource_init_war.patch b/target/linux/amazon/patches-2.6.37/010-mips_clocksource_init_war.patch
deleted file mode 100644 (file)
index 7078b37..0000000
+++ /dev/null
@@ -1,33 +0,0 @@
---- a/arch/mips/kernel/cevt-r4k.c
-+++ b/arch/mips/kernel/cevt-r4k.c
-@@ -23,6 +23,22 @@
- #ifndef CONFIG_MIPS_MT_SMTC
-+/*
-+ * Compare interrupt can be routed and latched outside the core,
-+ * so a single execution hazard barrier may not be enough to give
-+ * it time to clear as seen in the Cause register.  4 time the
-+ * pipeline depth seems reasonably conservative, and empirically
-+ * works better in configurations with high CPU/bus clock ratios.
-+ */
-+
-+#define compare_change_hazard() \
-+      do { \
-+              irq_disable_hazard(); \
-+              irq_disable_hazard(); \
-+              irq_disable_hazard(); \
-+              irq_disable_hazard(); \
-+      } while (0)
-+
- static int mips_next_event(unsigned long delta,
-                            struct clock_event_device *evt)
- {
-@@ -32,6 +48,7 @@ static int mips_next_event(unsigned long
-       cnt = read_c0_count();
-       cnt += delta;
-       write_c0_compare(cnt);
-+      compare_change_hazard();
-       res = ((int)(read_c0_count() - cnt) >= 0) ? -ETIME : 0;
-       return res;
- }
diff --git a/target/linux/amazon/patches-2.6.37/017-wdt-driver.patch b/target/linux/amazon/patches-2.6.37/017-wdt-driver.patch
deleted file mode 100644 (file)
index 63da655..0000000
+++ /dev/null
@@ -1,10 +0,0 @@
---- a/drivers/watchdog/Makefile
-+++ b/drivers/watchdog/Makefile
-@@ -119,6 +119,7 @@ obj-$(CONFIG_AR7_WDT) += ar7_wdt.o
- obj-$(CONFIG_TXX9_WDT) += txx9wdt.o
- obj-$(CONFIG_OCTEON_WDT) += octeon-wdt.o
- octeon-wdt-y := octeon-wdt-main.o octeon-wdt-nmi.o
-+obj-$(CONFIG_AMAZON_WDT) += amazon_wdt.o
- # PARISC Architecture
diff --git a/target/linux/amazon/patches-2.6.37/100-board.patch b/target/linux/amazon/patches-2.6.37/100-board.patch
deleted file mode 100644 (file)
index 15f367f..0000000
+++ /dev/null
@@ -1,53 +0,0 @@
---- a/arch/mips/Kconfig
-+++ b/arch/mips/Kconfig
-@@ -102,6 +102,22 @@ config BCM63XX
-       help
-        Support for BCM63XX based boards
-+config AMAZON
-+      bool "Amazon support (EXPERIMENTAL)"
-+      depends on EXPERIMENTAL
-+      select DMA_NONCOHERENT
-+      select IRQ_CPU
-+      select CEVT_R4K
-+      select CSRC_R4K
-+      select SYS_HAS_CPU_MIPS32_R1
-+      select SYS_HAS_CPU_MIPS32_R2
-+      select HAVE_STD_PC_SERIAL_PORT
-+      select SYS_SUPPORTS_BIG_ENDIAN
-+      select SYS_SUPPORTS_32BIT_KERNEL
-+      select SYS_HAS_EARLY_PRINTK
-+      select HW_HAS_PCI
-+      select SWAP_IO_SPACE
-+
- config MIPS_COBALT
-       bool "Cobalt Server"
-       select CEVT_R4K
-@@ -716,6 +732,7 @@ config CAVIUM_OCTEON_REFERENCE_BOARD
- endchoice
-+source "arch/mips/amazon/Kconfig"
- source "arch/mips/alchemy/Kconfig"
- source "arch/mips/bcm63xx/Kconfig"
- source "arch/mips/jazz/Kconfig"
---- a/arch/mips/Kbuild.platforms
-+++ b/arch/mips/Kbuild.platforms
-@@ -5,6 +5,7 @@ platforms += ar7
- platforms += bcm47xx
- platforms += bcm63xx
- platforms += cavium-octeon
-+platforms += amazon
- platforms += cobalt
- platforms += dec
- platforms += emma
---- /dev/null
-+++ b/arch/mips/amazon/Platform
-@@ -0,0 +1,7 @@
-+#
-+# Infineon AMAZON boards
-+#
-+platform-$(CONFIG_AMAZON)     += amazon/
-+cflags-$(CONFIG_AMAZON)       +=                                      \
-+              -I$(srctree)/arch/mips/include/asm/mach-amazon
-+load-$(CONFIG_AMAZON)         := 0xffffffff80002000
diff --git a/target/linux/amazon/patches-2.6.37/130-mtd_drivers.patch b/target/linux/amazon/patches-2.6.37/130-mtd_drivers.patch
deleted file mode 100644 (file)
index b13a837..0000000
+++ /dev/null
@@ -1,7 +0,0 @@
---- a/drivers/mtd/maps/Makefile
-+++ b/drivers/mtd/maps/Makefile
-@@ -59,3 +59,4 @@ obj-$(CONFIG_MTD_RBTX4939)   += rbtx4939-f
- obj-$(CONFIG_MTD_VMU)         += vmu-flash.o
- obj-$(CONFIG_MTD_GPIO_ADDR)   += gpio-addr-flash.o
- obj-$(CONFIG_MTD_BCM963XX)    += bcm963xx-flash.o
-+obj-$(CONFIG_AMAZON_MTD)      += amazon.o
diff --git a/target/linux/amazon/patches-2.6.37/140-net_drivers.patch b/target/linux/amazon/patches-2.6.37/140-net_drivers.patch
deleted file mode 100644 (file)
index 49dc3c8..0000000
+++ /dev/null
@@ -1,9 +0,0 @@
---- a/drivers/net/Makefile
-+++ b/drivers/net/Makefile
-@@ -302,3 +302,6 @@ obj-$(CONFIG_CAIF) += caif/
- obj-$(CONFIG_OCTEON_MGMT_ETHERNET) += octeon/
- obj-$(CONFIG_PCH_GBE) += pch_gbe/
- obj-$(CONFIG_TILE_NET) += tile/
-+
-+obj-$(CONFIG_AMAZON_NET_SW) += amazon_sw.o
-+obj-$(CONFIG_ADM6996_SUPPORT) += admmod.o
diff --git a/target/linux/amazon/patches-2.6.37/150-serial_driver.patch b/target/linux/amazon/patches-2.6.37/150-serial_driver.patch
deleted file mode 100644 (file)
index 8b7741c..0000000
+++ /dev/null
@@ -1,10 +0,0 @@
---- a/drivers/serial/Makefile
-+++ b/drivers/serial/Makefile
-@@ -3,6 +3,7 @@
- #
- obj-$(CONFIG_SERIAL_CORE) += serial_core.o
-+obj-$(CONFIG_AMAZON_ASC_UART) += amazon_asc.o
- obj-$(CONFIG_SERIAL_21285) += 21285.o
- # These Sparc drivers have to appear before others such as 8250
diff --git a/target/linux/amazon/patches-2.6.37/160-cfi-swap.patch b/target/linux/amazon/patches-2.6.37/160-cfi-swap.patch
deleted file mode 100644 (file)
index 65ce661..0000000
+++ /dev/null
@@ -1,56 +0,0 @@
---- a/drivers/mtd/chips/cfi_cmdset_0002.c
-+++ b/drivers/mtd/chips/cfi_cmdset_0002.c
-@@ -1166,6 +1166,9 @@ static int __xipram do_write_oneword(str
-       int retry_cnt = 0;
-       adr += chip->start;
-+#ifdef CONFIG_AMAZON
-+      adr ^= 2;
-+#endif
-       mutex_lock(&chip->mutex);
-       ret = get_chip(map, chip, adr, FL_WRITING);
-@@ -1433,7 +1436,11 @@ static int __xipram do_write_buffer(stru
-       z = 0;
-       while(z < words * map_bankwidth(map)) {
-               datum = map_word_load(map, buf);
-+#ifdef CONFIG_AMAZON
-+              map_write(map, datum, (adr + z) ^ 0x2);
-+#else
-               map_write(map, datum, adr + z);
-+#endif
-               z += map_bankwidth(map);
-               buf += map_bankwidth(map);
-@@ -1678,6 +1685,9 @@ static int __xipram do_erase_oneblock(st
-       int ret = 0;
-       adr += chip->start;
-+#ifdef CONFIG_AMAZON
-+      adr ^= 2;
-+#endif
-       mutex_lock(&chip->mutex);
-       ret = get_chip(map, chip, adr, FL_ERASING);
-@@ -1806,6 +1816,10 @@ static int do_atmel_lock(struct map_info
-       struct cfi_private *cfi = map->fldrv_priv;
-       int ret;
-+#ifdef CONFIG_AMAZON
-+      adr ^= 2;
-+#endif
-+
-       mutex_lock(&chip->mutex);
-       ret = get_chip(map, chip, adr + chip->start, FL_LOCKING);
-       if (ret)
-@@ -1842,6 +1856,10 @@ static int do_atmel_unlock(struct map_in
-       struct cfi_private *cfi = map->fldrv_priv;
-       int ret;
-+#ifdef CONFIG_AMAZON
-+      adr ^= 2;
-+#endif
-+
-       mutex_lock(&chip->mutex);
-       ret = get_chip(map, chip, adr + chip->start, FL_UNLOCKING);
-       if (ret)
diff --git a/target/linux/amazon/patches-3.3/000-mips-bad-intctl.patch b/target/linux/amazon/patches-3.3/000-mips-bad-intctl.patch
new file mode 100644 (file)
index 0000000..0aa3778
--- /dev/null
@@ -0,0 +1,33 @@
+--- a/arch/mips/kernel/traps.c
++++ b/arch/mips/kernel/traps.c
+@@ -1593,7 +1593,16 @@ void __cpuinit per_cpu_trap_init(void)
+       if (cpu_has_mips_r2) {
+               cp0_compare_irq_shift = CAUSEB_TI - CAUSEB_IP;
+               cp0_compare_irq = (read_c0_intctl() >> INTCTLB_IPTI) & 7;
++              if (!cp0_compare_irq)
++                      cp0_compare_irq = CP0_LEGACY_COMPARE_IRQ;
++
+               cp0_perfcount_irq = (read_c0_intctl() >> INTCTLB_IPPCI) & 7;
++              if (!cp0_perfcount_irq)
++                      cp0_perfcount_irq = CP0_LEGACY_PERFCNT_IRQ;
++
++              if (arch_fixup_c0_irqs)
++                      arch_fixup_c0_irqs();
++
+               if (cp0_perfcount_irq == cp0_compare_irq)
+                       cp0_perfcount_irq = -1;
+       } else {
+--- a/arch/mips/include/asm/irq.h
++++ b/arch/mips/include/asm/irq.h
+@@ -139,9 +139,11 @@ extern void free_irqno(unsigned int irq)
+  * IE7.  Since R2 their number has to be read from the c0_intctl register.
+  */
+ #define CP0_LEGACY_COMPARE_IRQ 7
++#define CP0_LEGACY_PERFCNT_IRQ 7
+ extern int cp0_compare_irq;
+ extern int cp0_compare_irq_shift;
+ extern int cp0_perfcount_irq;
++extern void __weak arch_fixup_c0_irqs(void);
+ #endif /* _ASM_IRQ_H */
diff --git a/target/linux/amazon/patches-3.3/010-mips_clocksource_init_war.patch b/target/linux/amazon/patches-3.3/010-mips_clocksource_init_war.patch
new file mode 100644 (file)
index 0000000..7078b37
--- /dev/null
@@ -0,0 +1,33 @@
+--- a/arch/mips/kernel/cevt-r4k.c
++++ b/arch/mips/kernel/cevt-r4k.c
+@@ -23,6 +23,22 @@
+ #ifndef CONFIG_MIPS_MT_SMTC
++/*
++ * Compare interrupt can be routed and latched outside the core,
++ * so a single execution hazard barrier may not be enough to give
++ * it time to clear as seen in the Cause register.  4 time the
++ * pipeline depth seems reasonably conservative, and empirically
++ * works better in configurations with high CPU/bus clock ratios.
++ */
++
++#define compare_change_hazard() \
++      do { \
++              irq_disable_hazard(); \
++              irq_disable_hazard(); \
++              irq_disable_hazard(); \
++              irq_disable_hazard(); \
++      } while (0)
++
+ static int mips_next_event(unsigned long delta,
+                            struct clock_event_device *evt)
+ {
+@@ -32,6 +48,7 @@ static int mips_next_event(unsigned long
+       cnt = read_c0_count();
+       cnt += delta;
+       write_c0_compare(cnt);
++      compare_change_hazard();
+       res = ((int)(read_c0_count() - cnt) >= 0) ? -ETIME : 0;
+       return res;
+ }
diff --git a/target/linux/amazon/patches-3.3/017-wdt-driver.patch b/target/linux/amazon/patches-3.3/017-wdt-driver.patch
new file mode 100644 (file)
index 0000000..005ee71
--- /dev/null
@@ -0,0 +1,10 @@
+--- a/drivers/watchdog/Makefile
++++ b/drivers/watchdog/Makefile
+@@ -132,6 +132,7 @@ obj-$(CONFIG_TXX9_WDT) += txx9wdt.o
+ obj-$(CONFIG_OCTEON_WDT) += octeon-wdt.o
+ octeon-wdt-y := octeon-wdt-main.o octeon-wdt-nmi.o
+ obj-$(CONFIG_LANTIQ_WDT) += lantiq_wdt.o
++obj-$(CONFIG_AMAZON_WDT) += amazon_wdt.o
+ # PARISC Architecture
diff --git a/target/linux/amazon/patches-3.3/100-board.patch b/target/linux/amazon/patches-3.3/100-board.patch
new file mode 100644 (file)
index 0000000..b743052
--- /dev/null
@@ -0,0 +1,53 @@
+--- a/arch/mips/Kconfig
++++ b/arch/mips/Kconfig
+@@ -120,6 +120,22 @@ config BCM63XX
+       help
+        Support for BCM63XX based boards
++config AMAZON
++      bool "Amazon support (EXPERIMENTAL)"
++      depends on EXPERIMENTAL
++      select DMA_NONCOHERENT
++      select IRQ_CPU
++      select CEVT_R4K
++      select CSRC_R4K
++      select SYS_HAS_CPU_MIPS32_R1
++      select SYS_HAS_CPU_MIPS32_R2
++      select HAVE_STD_PC_SERIAL_PORT
++      select SYS_SUPPORTS_BIG_ENDIAN
++      select SYS_SUPPORTS_32BIT_KERNEL
++      select SYS_HAS_EARLY_PRINTK
++      select HW_HAS_PCI
++      select SWAP_IO_SPACE
++
+ config MIPS_COBALT
+       bool "Cobalt Server"
+       select CEVT_R4K
+@@ -813,6 +829,7 @@ config NLM_XLP_BOARD
+ endchoice
++source "arch/mips/amazon/Kconfig"
+ source "arch/mips/alchemy/Kconfig"
+ source "arch/mips/ath79/Kconfig"
+ source "arch/mips/bcm47xx/Kconfig"
+--- a/arch/mips/Kbuild.platforms
++++ b/arch/mips/Kbuild.platforms
+@@ -6,6 +6,7 @@ platforms += ath79
+ platforms += bcm47xx
+ platforms += bcm63xx
+ platforms += cavium-octeon
++platforms += amazon
+ platforms += cobalt
+ platforms += dec
+ platforms += emma
+--- /dev/null
++++ b/arch/mips/amazon/Platform
+@@ -0,0 +1,7 @@
++#
++# Infineon AMAZON boards
++#
++platform-$(CONFIG_AMAZON)     += amazon/
++cflags-$(CONFIG_AMAZON)       +=                                      \
++              -I$(srctree)/arch/mips/include/asm/mach-amazon
++load-$(CONFIG_AMAZON)         := 0xffffffff80002000
diff --git a/target/linux/amazon/patches-3.3/130-mtd_drivers.patch b/target/linux/amazon/patches-3.3/130-mtd_drivers.patch
new file mode 100644 (file)
index 0000000..6ce28e3
--- /dev/null
@@ -0,0 +1,7 @@
+--- a/drivers/mtd/maps/Makefile
++++ b/drivers/mtd/maps/Makefile
+@@ -57,3 +57,4 @@ obj-$(CONFIG_MTD_VMU)                += vmu-flash.o
+ obj-$(CONFIG_MTD_GPIO_ADDR)   += gpio-addr-flash.o
+ obj-$(CONFIG_MTD_LATCH_ADDR)  += latch-addr-flash.o
+ obj-$(CONFIG_MTD_LANTIQ)      += lantiq-flash.o
++obj-$(CONFIG_AMAZON_MTD)      += amazon.o
diff --git a/target/linux/amazon/patches-3.3/140-net_drivers.patch b/target/linux/amazon/patches-3.3/140-net_drivers.patch
new file mode 100644 (file)
index 0000000..9c840e6
--- /dev/null
@@ -0,0 +1,9 @@
+--- a/drivers/net/ethernet/Makefile
++++ b/drivers/net/ethernet/Makefile
+@@ -74,3 +74,6 @@ obj-$(CONFIG_NET_VENDOR_TUNDRA) += tundr
+ obj-$(CONFIG_NET_VENDOR_VIA) += via/
+ obj-$(CONFIG_NET_VENDOR_XILINX) += xilinx/
+ obj-$(CONFIG_NET_VENDOR_XIRCOM) += xircom/
++
++obj-$(CONFIG_AMAZON_NET_SW) += amazon_sw.o
++obj-$(CONFIG_ADM6996_SUPPORT) += admmod.o
diff --git a/target/linux/amazon/patches-3.3/150-serial_driver.patch b/target/linux/amazon/patches-3.3/150-serial_driver.patch
new file mode 100644 (file)
index 0000000..c6e7f39
--- /dev/null
@@ -0,0 +1,7 @@
+--- a/drivers/tty/serial/Makefile
++++ b/drivers/tty/serial/Makefile
+@@ -78,3 +78,4 @@ obj-$(CONFIG_SERIAL_LANTIQ)  += lantiq.o
+ obj-$(CONFIG_SERIAL_XILINX_PS_UART) += xilinx_uartps.o
+ obj-$(CONFIG_SERIAL_SIRFSOC) += sirfsoc_uart.o
+ obj-$(CONFIG_SERIAL_AR933X)   += ar933x_uart.o
++obj-$(CONFIG_AMAZON_ASC_UART) += amazon_asc.o
diff --git a/target/linux/amazon/patches-3.3/160-cfi-swap.patch b/target/linux/amazon/patches-3.3/160-cfi-swap.patch
new file mode 100644 (file)
index 0000000..4a0009e
--- /dev/null
@@ -0,0 +1,56 @@
+--- a/drivers/mtd/chips/cfi_cmdset_0002.c
++++ b/drivers/mtd/chips/cfi_cmdset_0002.c
+@@ -1152,6 +1152,9 @@ static int __xipram do_write_oneword(str
+       int retry_cnt = 0;
+       adr += chip->start;
++#ifdef CONFIG_AMAZON
++      adr ^= 2;
++#endif
+       mutex_lock(&chip->mutex);
+       ret = get_chip(map, chip, adr, FL_WRITING);
+@@ -1420,7 +1423,11 @@ static int __xipram do_write_buffer(stru
+       z = 0;
+       while(z < words * map_bankwidth(map)) {
+               datum = map_word_load(map, buf);
++#ifdef CONFIG_AMAZON
++              map_write(map, datum, (adr + z) ^ 0x2);
++#else
+               map_write(map, datum, adr + z);
++#endif
+               z += map_bankwidth(map);
+               buf += map_bankwidth(map);
+@@ -1665,6 +1672,9 @@ static int __xipram do_erase_oneblock(st
+       int ret = 0;
+       adr += chip->start;
++#ifdef CONFIG_AMAZON
++      adr ^= 2;
++#endif
+       mutex_lock(&chip->mutex);
+       ret = get_chip(map, chip, adr, FL_ERASING);
+@@ -1793,6 +1803,10 @@ static int do_atmel_lock(struct map_info
+       struct cfi_private *cfi = map->fldrv_priv;
+       int ret;
++#ifdef CONFIG_AMAZON
++      adr ^= 2;
++#endif
++
+       mutex_lock(&chip->mutex);
+       ret = get_chip(map, chip, adr + chip->start, FL_LOCKING);
+       if (ret)
+@@ -1828,6 +1842,10 @@ static int do_atmel_unlock(struct map_in
+       struct cfi_private *cfi = map->fldrv_priv;
+       int ret;
++#ifdef CONFIG_AMAZON
++      adr ^= 2;
++#endif
++
+       mutex_lock(&chip->mutex);
+       ret = get_chip(map, chip, adr + chip->start, FL_UNLOCKING);
+       if (ret)