aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSteffen Sledz <sledz@dresearch.de>2009-03-27 18:14:37 +0100
committerSteffen Sledz <sledz@dresearch.de>2009-03-27 18:14:37 +0100
commitbb9b5dd8f35d0f7404a29c0a873bab88c039e712 (patch)
treec464d31871e0258c8b5a4a122e6f2f132d8d41de
parent8b70868d1facb867fdd17af6fb6ffc59f91870c0 (diff)
downloadopenembedded-bb9b5dd8f35d0f7404a29c0a873bab88c039e712.tar.gz
openembedded-bb9b5dd8f35d0f7404a29c0a873bab88c039e712.tar.bz2
openembedded-bb9b5dd8f35d0f7404a29c0a873bab88c039e712.zip
hipox: new machine added (derived from oxnas)
-rw-r--r--MAINTAINERS2
-rw-r--r--conf/machine/hipox.conf20
-rw-r--r--recipes/forte/forte_0.3.bb3
-rw-r--r--recipes/linux/linux-2.6.24/hipox/defconfig1232
-rw-r--r--recipes/linux/linux-2.6.24/hipox/hipox-mach-type.patch7
-rw-r--r--recipes/linux/linux-2.6.24/hipox/hipox-pci-config-delay.patch56
-rw-r--r--recipes/linux/linux-2.6.24/hipox/hipox-pci-max-size.patch21
-rw-r--r--recipes/linux/linux-2.6.24/hipox/hipox-uart.patch176
-rw-r--r--recipes/linux/linux-2.6.24/hipox/hipox.patch57804
-rw-r--r--recipes/linux/linux_2.6.24.bb11
10 files changed, 59329 insertions, 3 deletions
diff --git a/MAINTAINERS b/MAINTAINERS
index d740f0e9a2..c4185abd60 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -243,7 +243,7 @@ Recipes: directfb, php
Person: Steffen Sledz
Mail: sledz@dresearch.de
-Machines: oxnas
+Machines: oxnas, hipox
Recipes: forte
Person: Stelios Koroneos
diff --git a/conf/machine/hipox.conf b/conf/machine/hipox.conf
new file mode 100644
index 0000000000..728ad2bb0d
--- /dev/null
+++ b/conf/machine/hipox.conf
@@ -0,0 +1,20 @@
+#@TYPE: Machine
+#@NAME: OXE810 based HydraIP device
+#@DESCRIPTION: Machine configuration for DResearch OXE810 based HydraIP device
+
+TARGET_ARCH = "arm"
+
+MACHINE_FEATURES = "kernel26 ext2 pci usbhost ethernet serial raid uboot"
+
+SERIAL_CONSOLE = "115200 ttyS0"
+
+PREFERRED_PROVIDER_virtual/kernel = "linux"
+
+KERNEL_IMAGETYPE = "uImage"
+
+PREFERRED_VERSION_u-boot = "1.1.2"
+UBOOT_LOADADDRESS = "0x48008000"
+UBOOT_ENTRYPOINT = "0x48008000"
+UBOOT_ARCH = "arm"
+
+require conf/machine/include/tune-arm926ejs.inc
diff --git a/recipes/forte/forte_0.3.bb b/recipes/forte/forte_0.3.bb
index c434fb39b8..399b22a038 100644
--- a/recipes/forte/forte_0.3.bb
+++ b/recipes/forte/forte_0.3.bb
@@ -1,8 +1,9 @@
require forte.inc
-PR = "r0"
+PR = "r1"
DEFAULT_PREFERENCE_oxnas = "1"
+DEFAULT_PREFERENCE_hipox = "1"
SRC_URI = "http://kent.dl.sourceforge.net/sourceforge/fordiac/forte-0.3.zip \
file://forte-0.3-patch_20081008.diff;patch=1"
diff --git a/recipes/linux/linux-2.6.24/hipox/defconfig b/recipes/linux/linux-2.6.24/hipox/defconfig
new file mode 100644
index 0000000000..68f5ff001b
--- /dev/null
+++ b/recipes/linux/linux-2.6.24/hipox/defconfig
@@ -0,0 +1,1232 @@
+#
+# Automatically generated make config: don't edit
+# Linux kernel version: 2.6.24.4
+# Fri Oct 17 14:41:04 2008
+#
+CONFIG_ARM=y
+CONFIG_SYS_SUPPORTS_APM_EMULATION=y
+# CONFIG_GENERIC_GPIO is not set
+# CONFIG_GENERIC_TIME is not set
+# CONFIG_GENERIC_CLOCKEVENTS is not set
+CONFIG_MMU=y
+# CONFIG_NO_IOPORT is not set
+CONFIG_GENERIC_HARDIRQS=y
+CONFIG_STACKTRACE_SUPPORT=y
+CONFIG_LOCKDEP_SUPPORT=y
+CONFIG_TRACE_IRQFLAGS_SUPPORT=y
+CONFIG_HARDIRQS_SW_RESEND=y
+CONFIG_GENERIC_IRQ_PROBE=y
+CONFIG_RWSEM_GENERIC_SPINLOCK=y
+# CONFIG_ARCH_HAS_ILOG2_U32 is not set
+# CONFIG_ARCH_HAS_ILOG2_U64 is not set
+CONFIG_GENERIC_HWEIGHT=y
+CONFIG_GENERIC_CALIBRATE_DELAY=y
+CONFIG_ZONE_DMA=y
+CONFIG_VECTORS_BASE=0xffff0000
+CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
+
+#
+# General setup
+#
+CONFIG_EXPERIMENTAL=y
+CONFIG_BROKEN_ON_SMP=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
+CONFIG_LOCALVERSION=""
+CONFIG_LOCALVERSION_AUTO=y
+CONFIG_SWAP=y
+CONFIG_SYSVIPC=y
+CONFIG_SYSVIPC_SYSCTL=y
+# CONFIG_POSIX_MQUEUE is not set
+# CONFIG_BSD_PROCESS_ACCT is not set
+# CONFIG_TASKSTATS is not set
+# CONFIG_USER_NS is not set
+# CONFIG_PID_NS is not set
+# CONFIG_AUDIT is not set
+# CONFIG_IKCONFIG is not set
+CONFIG_LOG_BUF_SHIFT=14
+# CONFIG_CGROUPS is not set
+# CONFIG_FAIR_GROUP_SCHED is not set
+CONFIG_SYSFS_DEPRECATED=y
+# CONFIG_RELAY is not set
+CONFIG_BLK_DEV_INITRD=y
+CONFIG_INITRAMFS_SOURCE=""
+# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
+CONFIG_SYSCTL=y
+# CONFIG_EMBEDDED is not set
+CONFIG_UID16=y
+CONFIG_SYSCTL_SYSCALL=y
+CONFIG_KALLSYMS=y
+# CONFIG_KALLSYMS_EXTRA_PASS is not set
+CONFIG_HOTPLUG=y
+CONFIG_PRINTK=y
+CONFIG_BUG=y
+CONFIG_ELF_CORE=y
+CONFIG_BASE_FULL=y
+CONFIG_FUTEX=y
+CONFIG_ANON_INODES=y
+CONFIG_EPOLL=y
+CONFIG_SIGNALFD=y
+CONFIG_EVENTFD=y
+CONFIG_SHMEM=y
+CONFIG_VM_EVENT_COUNTERS=y
+CONFIG_SLAB=y
+# CONFIG_SLUB is not set
+# CONFIG_SLOB is not set
+CONFIG_SLABINFO=y
+CONFIG_RT_MUTEXES=y
+# CONFIG_TINY_SHMEM is not set
+CONFIG_BASE_SMALL=0
+CONFIG_MODULES=y
+CONFIG_MODULE_UNLOAD=y
+# CONFIG_MODULE_FORCE_UNLOAD is not set
+# CONFIG_MODVERSIONS is not set
+# CONFIG_MODULE_SRCVERSION_ALL is not set
+# CONFIG_KMOD is not set
+CONFIG_BLOCK=y
+# CONFIG_LBD is not set
+# CONFIG_BLK_DEV_IO_TRACE is not set
+# CONFIG_LSF is not set
+# CONFIG_BLK_DEV_BSG is not set
+
+#
+# IO Schedulers
+#
+CONFIG_IOSCHED_NOOP=y
+CONFIG_IOSCHED_AS=y
+CONFIG_IOSCHED_DEADLINE=y
+CONFIG_IOSCHED_CFQ=y
+CONFIG_DEFAULT_AS=y
+# CONFIG_DEFAULT_DEADLINE is not set
+# CONFIG_DEFAULT_CFQ is not set
+# CONFIG_DEFAULT_NOOP is not set
+CONFIG_DEFAULT_IOSCHED="anticipatory"
+
+#
+# System Type
+#
+# CONFIG_ARCH_AAEC2000 is not set
+# CONFIG_ARCH_INTEGRATOR is not set
+# CONFIG_ARCH_REALVIEW is not set
+# CONFIG_ARCH_VERSATILE is not set
+# CONFIG_ARCH_AT91 is not set
+# CONFIG_ARCH_CLPS7500 is not set
+# CONFIG_ARCH_CLPS711X is not set
+# CONFIG_ARCH_CO285 is not set
+# CONFIG_ARCH_EBSA110 is not set
+# CONFIG_ARCH_EP93XX is not set
+# CONFIG_ARCH_FOOTBRIDGE is not set
+# CONFIG_ARCH_NETX is not set
+# CONFIG_ARCH_H720X is not set
+# CONFIG_ARCH_IMX is not set
+# CONFIG_ARCH_IOP13XX is not set
+# CONFIG_ARCH_IOP32X is not set
+# CONFIG_ARCH_IOP33X is not set
+# CONFIG_ARCH_IXP23XX is not set
+# CONFIG_ARCH_IXP2000 is not set
+# CONFIG_ARCH_IXP4XX is not set
+# CONFIG_ARCH_L7200 is not set
+# CONFIG_ARCH_KS8695 is not set
+# CONFIG_ARCH_NS9XXX is not set
+# CONFIG_ARCH_MXC is not set
+# CONFIG_ARCH_PNX4008 is not set
+# CONFIG_ARCH_PXA is not set
+# CONFIG_ARCH_RPC is not set
+# CONFIG_ARCH_SA1100 is not set
+# CONFIG_ARCH_S3C2410 is not set
+# CONFIG_ARCH_SHARK is not set
+# CONFIG_ARCH_LH7A40X is not set
+# CONFIG_ARCH_DAVINCI is not set
+# CONFIG_ARCH_OMAP is not set
+CONFIG_ARCH_HIPOX=y
+
+#
+# Boot options
+#
+
+#
+# Power management
+#
+
+#
+# Oxford Semiconductor NAS Options
+#
+# CONFIG_ARCH_HIPOX_FPGA is not set
+CONFIG_NOMINAL_PLL400_FREQ=733333333
+CONFIG_NOMINAL_RPSCLK_FREQ=25000000
+# CONFIG_HIPOX_VERSION_0X800 is not set
+CONFIG_HIPOX_VERSION_0X810=y
+# CONFIG_HIPOX_VERSION_0X850 is not set
+# CONFIG_ARCH_HIPOX_UART1 is not set
+CONFIG_ARCH_HIPOX_UART2=y
+# CONFIG_ARCH_HIPOX_UART2_MODEM is not set
+# CONFIG_ARCH_HIPOX_UART3 is not set
+# CONFIG_ARCH_HIPOX_PCI_REQGNT_0 is not set
+# CONFIG_ARCH_HIPOX_PCI_REQGNT_1 is not set
+# CONFIG_ARCH_HIPOX_PCI_REQGNT_2 is not set
+# CONFIG_ARCH_HIPOX_PCI_REQGNT_3 is not set
+# CONFIG_ARCH_HIPOX_PCI_CLKOUT_0 is not set
+# CONFIG_ARCH_HIPOX_PCI_CLKOUT_1 is not set
+# CONFIG_ARCH_HIPOX_PCI_CLKOUT_2 is not set
+# CONFIG_ARCH_HIPOX_PCI_CLKOUT_3 is not set
+# CONFIG_HIPOX_PCI_RESET is not set
+# CONFIG_HIPOX_SATA_POWER_1 is not set
+# CONFIG_HIPOX_SATA_POWER_2 is not set
+CONFIG_FORCE_MAX_ZONEORDER=10
+CONFIG_SRAM_NUM_PAGES=32
+CONFIG_SUPPORT_LEON=y
+CONFIG_LEON_PAGES=2
+CONFIG_LEON_COPRO=y
+CONFIG_LEON_OFFLOAD_TX=y
+# CONFIG_LEON_RESERVE_DMA_CHANNEL is not set
+CONFIG_LEON_OFFLOAD_TSO=y
+# CONFIG_LEON_START_EARLY is not set
+CONFIG_LEON_POWER_BUTTON_MONITOR=m
+CONFIG_HIPOX_POWER_BUTTON_GPIO=4
+CONFIG_USER_RECOVERY_BUTTON_MONITOR=y
+CONFIG_HIPOX_USER_RECOVERY_BUTTON_GPIO=32
+# CONFIG_HIPOX_DDR_MON is not set
+# CONFIG_HIPOX_AHB_MON is not set
+# CONFIG_HIPOX_CACHE_LOCKDOWN is not set
+# CONFIG_DO_MEM_TEST is not set
+# CONFIG_CRYPTO_OXAESLRW is not set
+CONFIG_DESCRIPTORS_PAGES=6
+CONFIG_ARCH_HIPOX_NUM_GMAC_DESCRIPTORS=192
+CONFIG_ARCH_HIPOX_MAX_SATA_SG_ENTRIES=256
+CONFIG_TACHO_THERM_AND_FAN=m
+# CONFIG_GPIO_TEST is not set
+CONFIG_HIPOX_RTC=y
+# CONFIG_I2S is not set
+# CONFIG_DPE_TEST is not set
+# CONFIG_HIPOX_INSTRUMENT_COPIES is not set
+# CONFIG_HIPOX_DMA_COPIES is not set
+# CONFIG_HIPOX_AHB_MONITOR_MODULE is not set
+# CONFIG_HIPOX_USB_TEST_MODES is not set
+# CONFIG_LEDS_TRIGGER_SATA_DISK is not set
+# CONFIG_HIPOX_LED_TEST is not set
+CONFIG_HIPOX_I2C_SDA=6
+CONFIG_HIPOX_I2C_SCL=7
+# CONFIG_HIPOX_USB_PORTA_POWER_CONTROL is not set
+# CONFIG_HIPOX_USB_PORTB_POWER_CONTROL is not set
+# CONFIG_HIPOX_USB_PORTC_POWER_CONTROL is not set
+# CONFIG_HIPOX_USB_OVERCURRENT_POLARITY_NEGATIVE is not set
+# CONFIG_HIPOX_USB_POWER_SWITCH_POLARITY_NEGATIVE is not set
+# CONFIG_WDC_FAN_HIPOX800 is not set
+# CONFIG_HIPOX_MAP_SRAM is not set
+# CONFIG_HIPOX_SUID_INHERIT is not set
+# CONFIG_HIPOX_USB_HUB_SUPPORT is not set
+
+#
+# Processor Type
+#
+CONFIG_CPU_32=y
+CONFIG_CPU_ARM926T=y
+CONFIG_CPU_32v5=y
+CONFIG_CPU_ABRT_EV5TJ=y
+CONFIG_CPU_CACHE_VIVT=y
+CONFIG_CPU_COPY_V4WB=y
+CONFIG_CPU_TLB_V4WBI=y
+CONFIG_CPU_CP15=y
+CONFIG_CPU_CP15_MMU=y
+
+#
+# Processor Features
+#
+CONFIG_ARM_THUMB=y
+# CONFIG_CPU_ICACHE_DISABLE is not set
+# CONFIG_CPU_DCACHE_DISABLE is not set
+# CONFIG_CPU_DCACHE_WRITETHROUGH is not set
+# CONFIG_CPU_CACHE_ROUND_ROBIN is not set
+# CONFIG_OUTER_CACHE is not set
+
+#
+# Bus support
+#
+CONFIG_ARM_AMBA=y
+CONFIG_PCI=y
+CONFIG_PCI_SYSCALL=y
+# CONFIG_ARCH_SUPPORTS_MSI is not set
+CONFIG_PCI_LEGACY=y
+# CONFIG_PCCARD is not set
+
+#
+# Kernel Features
+#
+# CONFIG_TICK_ONESHOT is not set
+# CONFIG_PREEMPT is not set
+# CONFIG_NO_IDLE_HZ is not set
+CONFIG_HZ=100
+CONFIG_AEABI=y
+# CONFIG_OABI_COMPAT is not set
+# CONFIG_ARCH_DISCONTIGMEM_ENABLE is not set
+CONFIG_SELECT_MEMORY_MODEL=y
+CONFIG_FLATMEM_MANUAL=y
+# CONFIG_DISCONTIGMEM_MANUAL is not set
+# CONFIG_SPARSEMEM_MANUAL is not set
+CONFIG_FLATMEM=y
+CONFIG_FLAT_NODE_MEM_MAP=y
+# CONFIG_SPARSEMEM_STATIC is not set
+# CONFIG_SPARSEMEM_VMEMMAP_ENABLE is not set
+CONFIG_SPLIT_PTLOCK_CPUS=4096
+# CONFIG_RESOURCES_64BIT is not set
+CONFIG_ZONE_DMA_FLAG=1
+CONFIG_BOUNCE=y
+CONFIG_VIRT_TO_BUS=y
+CONFIG_ALIGNMENT_TRAP=y
+
+#
+# Boot options
+#
+CONFIG_ZBOOT_ROM_TEXT=0x0
+CONFIG_ZBOOT_ROM_BSS=0x0
+CONFIG_CMDLINE=""
+# CONFIG_XIP_KERNEL is not set
+# CONFIG_KEXEC is not set
+
+#
+# Floating point emulation
+#
+
+#
+# At least one emulation must be selected
+#
+# CONFIG_VFP is not set
+
+#
+# Userspace binary formats
+#
+CONFIG_BINFMT_ELF=y
+# CONFIG_BINFMT_AOUT is not set
+# CONFIG_BINFMT_MISC is not set
+
+#
+# Power management options
+#
+# CONFIG_PM is not set
+CONFIG_SUSPEND_UP_POSSIBLE=y
+
+#
+# Networking
+#
+CONFIG_NET=y
+
+#
+# Networking options
+#
+CONFIG_PACKET=y
+CONFIG_PACKET_MMAP=y
+CONFIG_UNIX=y
+CONFIG_XFRM=y
+# CONFIG_XFRM_USER is not set
+# CONFIG_XFRM_SUB_POLICY is not set
+# CONFIG_XFRM_MIGRATE is not set
+# CONFIG_NET_KEY is not set
+CONFIG_INET=y
+CONFIG_IP_MULTICAST=y
+# CONFIG_IP_ADVANCED_ROUTER is not set
+CONFIG_IP_FIB_HASH=y
+# CONFIG_IP_PNP is not set
+# CONFIG_NET_IPIP is not set
+# CONFIG_NET_IPGRE is not set
+# CONFIG_IP_MROUTE is not set
+# CONFIG_ARPD is not set
+# CONFIG_SYN_COOKIES is not set
+# CONFIG_INET_AH is not set
+# CONFIG_INET_ESP is not set
+# CONFIG_INET_IPCOMP is not set
+# CONFIG_INET_XFRM_TUNNEL is not set
+# CONFIG_INET_TUNNEL is not set
+CONFIG_INET_XFRM_MODE_TRANSPORT=y
+CONFIG_INET_XFRM_MODE_TUNNEL=y
+CONFIG_INET_XFRM_MODE_BEET=y
+# CONFIG_INET_LRO is not set
+CONFIG_INET_DIAG=y
+CONFIG_INET_TCP_DIAG=y
+# CONFIG_TCP_CONG_ADVANCED is not set
+CONFIG_TCP_CONG_CUBIC=y
+CONFIG_DEFAULT_TCP_CONG="cubic"
+# CONFIG_TCP_MD5SIG is not set
+# CONFIG_IP_VS is not set
+# CONFIG_IPV6 is not set
+# CONFIG_INET6_XFRM_TUNNEL is not set
+# CONFIG_INET6_TUNNEL is not set
+# CONFIG_NETLABEL is not set
+# CONFIG_NETWORK_SECMARK is not set
+CONFIG_NETFILTER=y
+# CONFIG_NETFILTER_DEBUG is not set
+
+#
+# Core Netfilter Configuration
+#
+# CONFIG_NETFILTER_NETLINK is not set
+# CONFIG_NF_CONNTRACK_ENABLED is not set
+# CONFIG_NF_CONNTRACK is not set
+# CONFIG_NETFILTER_XTABLES is not set
+
+#
+# IP: Netfilter Configuration
+#
+# CONFIG_IP_NF_QUEUE is not set
+# CONFIG_IP_NF_IPTABLES is not set
+# CONFIG_IP_NF_ARPTABLES is not set
+# CONFIG_IP_DCCP is not set
+# CONFIG_IP_SCTP is not set
+# CONFIG_TIPC is not set
+# CONFIG_ATM is not set
+# CONFIG_BRIDGE is not set
+# CONFIG_VLAN_8021Q is not set
+# CONFIG_DECNET is not set
+# CONFIG_LLC2 is not set
+# CONFIG_IPX is not set
+# CONFIG_ATALK is not set
+# CONFIG_X25 is not set
+# CONFIG_LAPB is not set
+# CONFIG_ECONET is not set
+# CONFIG_WAN_ROUTER is not set
+# CONFIG_NET_SCHED is not set
+
+#
+# Network testing
+#
+# CONFIG_NET_PKTGEN is not set
+# CONFIG_HAMRADIO is not set
+# CONFIG_IRDA is not set
+# CONFIG_BT is not set
+# CONFIG_AF_RXRPC is not set
+
+#
+# Wireless
+#
+# CONFIG_CFG80211 is not set
+CONFIG_WIRELESS_EXT=y
+# CONFIG_MAC80211 is not set
+# CONFIG_IEEE80211 is not set
+# CONFIG_RFKILL is not set
+# CONFIG_NET_9P is not set
+
+#
+# Device Drivers
+#
+
+#
+# Generic Driver Options
+#
+CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
+CONFIG_STANDALONE=y
+CONFIG_PREVENT_FIRMWARE_BUILD=y
+CONFIG_FW_LOADER=y
+# CONFIG_SYS_HYPERVISOR is not set
+# CONFIG_CONNECTOR is not set
+# CONFIG_MTD is not set
+# CONFIG_PARPORT is not set
+CONFIG_BLK_DEV=y
+# CONFIG_BLK_CPQ_DA is not set
+# CONFIG_BLK_CPQ_CISS_DA is not set
+# CONFIG_BLK_DEV_DAC960 is not set
+# CONFIG_BLK_DEV_UMEM is not set
+# CONFIG_BLK_DEV_COW_COMMON is not set
+CONFIG_BLK_DEV_LOOP=y
+# CONFIG_BLK_DEV_CRYPTOLOOP is not set
+# CONFIG_BLK_DEV_NBD is not set
+# CONFIG_BLK_DEV_SX8 is not set
+# CONFIG_BLK_DEV_UB is not set
+CONFIG_BLK_DEV_RAM=y
+CONFIG_BLK_DEV_RAM_COUNT=16
+CONFIG_BLK_DEV_RAM_SIZE=10240
+CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024
+# CONFIG_CDROM_PKTCDVD is not set
+# CONFIG_ATA_OVER_ETH is not set
+# CONFIG_MISC_DEVICES is not set
+# CONFIG_IDE is not set
+
+#
+# SCSI device support
+#
+# CONFIG_RAID_ATTRS is not set
+CONFIG_SCSI=y
+CONFIG_SCSI_DMA=y
+# CONFIG_SCSI_TGT is not set
+# CONFIG_SCSI_NETLINK is not set
+CONFIG_SCSI_PROC_FS=y
+
+#
+# SCSI support type (disk, tape, CD-ROM)
+#
+CONFIG_BLK_DEV_SD=y
+# CONFIG_CHR_DEV_ST is not set
+# CONFIG_CHR_DEV_OSST is not set
+# CONFIG_BLK_DEV_SR is not set
+# CONFIG_CHR_DEV_SG is not set
+# CONFIG_CHR_DEV_SCH is not set
+
+#
+# Some SCSI devices (e.g. CD jukebox) support multiple LUNs
+#
+CONFIG_SCSI_MULTI_LUN=y
+# CONFIG_SCSI_CONSTANTS is not set
+# CONFIG_SCSI_LOGGING is not set
+# CONFIG_SCSI_SCAN_ASYNC is not set
+CONFIG_SCSI_WAIT_SCAN=m
+
+#
+# SCSI Transports
+#
+# CONFIG_SCSI_SPI_ATTRS is not set
+# CONFIG_SCSI_FC_ATTRS is not set
+# CONFIG_SCSI_ISCSI_ATTRS is not set
+# CONFIG_SCSI_SAS_LIBSAS is not set
+# CONFIG_SCSI_SRP_ATTRS is not set
+CONFIG_SCSI_LOWLEVEL=y
+# CONFIG_ISCSI_TCP is not set
+# CONFIG_BLK_DEV_3W_XXXX_RAID is not set
+# CONFIG_SCSI_3W_9XXX is not set
+# CONFIG_SCSI_ACARD is not set
+# CONFIG_SCSI_AACRAID is not set
+# CONFIG_SCSI_AIC7XXX is not set
+# CONFIG_SCSI_AIC7XXX_OLD is not set
+# CONFIG_SCSI_AIC79XX is not set
+# CONFIG_SCSI_AIC94XX is not set
+# CONFIG_SCSI_DPT_I2O is not set
+# CONFIG_SCSI_ADVANSYS is not set
+# CONFIG_SCSI_ARCMSR is not set
+# CONFIG_MEGARAID_NEWGEN is not set
+# CONFIG_MEGARAID_LEGACY is not set
+# CONFIG_MEGARAID_SAS is not set
+# CONFIG_SCSI_HPTIOP is not set
+# CONFIG_SCSI_DMX3191D is not set
+# CONFIG_SCSI_FUTURE_DOMAIN is not set
+# CONFIG_SCSI_IPS is not set
+# CONFIG_SCSI_INITIO is not set
+# CONFIG_SCSI_INIA100 is not set
+# CONFIG_SCSI_STEX is not set
+# CONFIG_SCSI_SYM53C8XX_2 is not set
+# CONFIG_SCSI_IPR is not set
+# CONFIG_SCSI_QLOGIC_1280 is not set
+# CONFIG_SCSI_QLA_FC is not set
+# CONFIG_SCSI_QLA_ISCSI is not set
+# CONFIG_SCSI_LPFC is not set
+# CONFIG_SCSI_DC395x is not set
+# CONFIG_SCSI_DC390T is not set
+# CONFIG_SCSI_NSP32 is not set
+# CONFIG_SCSI_DEBUG is not set
+# CONFIG_SCSI_SRP is not set
+CONFIG_ATA=y
+# CONFIG_ATA_NONSTANDARD is not set
+# CONFIG_SATA_AHCI is not set
+# CONFIG_SATA_SVW is not set
+# CONFIG_ATA_PIIX is not set
+# CONFIG_SATA_MV is not set
+# CONFIG_SATA_NV is not set
+# CONFIG_PDC_ADMA is not set
+# CONFIG_SATA_QSTOR is not set
+# CONFIG_SATA_PROMISE is not set
+# CONFIG_SATA_SX4 is not set
+# CONFIG_SATA_SIL is not set
+# CONFIG_SATA_SIL24 is not set
+# CONFIG_SATA_SIS is not set
+# CONFIG_SATA_ULI is not set
+# CONFIG_SATA_VIA is not set
+# CONFIG_SATA_VITESSE is not set
+# CONFIG_SATA_INIC162X is not set
+CONFIG_SATA_OX810=y
+# CONFIG_SATA_HIPOX_SINGLE_SATA is not set
+# CONFIG_SATA_HIPOX_DISK_LIGHT is not set
+# CONFIG_PATA_ALI is not set
+# CONFIG_PATA_AMD is not set
+# CONFIG_PATA_ARTOP is not set
+# CONFIG_PATA_ATIIXP is not set
+# CONFIG_PATA_CMD640_PCI is not set
+# CONFIG_PATA_CMD64X is not set
+# CONFIG_PATA_CS5520 is not set
+# CONFIG_PATA_CS5530 is not set
+# CONFIG_PATA_CYPRESS is not set
+# CONFIG_PATA_EFAR is not set
+# CONFIG_ATA_GENERIC is not set
+# CONFIG_PATA_HPT366 is not set
+# CONFIG_PATA_HPT37X is not set
+# CONFIG_PATA_HPT3X2N is not set
+# CONFIG_PATA_HPT3X3 is not set
+# CONFIG_PATA_IT821X is not set
+# CONFIG_PATA_IT8213 is not set
+# CONFIG_PATA_JMICRON is not set
+# CONFIG_PATA_TRIFLEX is not set
+# CONFIG_PATA_MARVELL is not set
+# CONFIG_PATA_MPIIX is not set
+# CONFIG_PATA_OLDPIIX is not set
+# CONFIG_PATA_NETCELL is not set
+# CONFIG_PATA_NS87410 is not set
+# CONFIG_PATA_NS87415 is not set
+# CONFIG_PATA_OPTI is not set
+# CONFIG_PATA_OPTIDMA is not set
+# CONFIG_PATA_PDC_OLD is not set
+# CONFIG_PATA_RADISYS is not set
+# CONFIG_PATA_RZ1000 is not set
+# CONFIG_PATA_SC1200 is not set
+# CONFIG_PATA_SERVERWORKS is not set
+# CONFIG_PATA_PDC2027X is not set
+# CONFIG_PATA_SIL680 is not set
+# CONFIG_PATA_SIS is not set
+# CONFIG_PATA_VIA is not set
+# CONFIG_PATA_WINBOND is not set
+CONFIG_MD=y
+CONFIG_BLK_DEV_MD=y
+CONFIG_MD_LINEAR=y
+# CONFIG_MD_RAID0 is not set
+CONFIG_MD_RAID1=y
+# CONFIG_MD_RAID10 is not set
+# CONFIG_MD_RAID456 is not set
+# CONFIG_MD_MULTIPATH is not set
+# CONFIG_MD_FAULTY is not set
+CONFIG_BLK_DEV_DM=y
+# CONFIG_DM_DEBUG is not set
+CONFIG_DM_CRYPT=y
+# CONFIG_DM_SNAPSHOT is not set
+# CONFIG_DM_MIRROR is not set
+# CONFIG_DM_ZERO is not set
+# CONFIG_DM_MULTIPATH is not set
+# CONFIG_DM_DELAY is not set
+# CONFIG_DM_UEVENT is not set
+# CONFIG_FUSION is not set
+
+#
+# IEEE 1394 (FireWire) support
+#
+# CONFIG_FIREWIRE is not set
+# CONFIG_IEEE1394 is not set
+# CONFIG_I2O is not set
+CONFIG_NETDEVICES=y
+# CONFIG_NETDEVICES_MULTIQUEUE is not set
+# CONFIG_DUMMY is not set
+# CONFIG_BONDING is not set
+# CONFIG_MACVLAN is not set
+# CONFIG_EQUALIZER is not set
+# CONFIG_TUN is not set
+# CONFIG_VETH is not set
+# CONFIG_ARCNET is not set
+# CONFIG_NET_ETHERNET is not set
+CONFIG_MII=y
+CONFIG_NETDEV_1000=y
+# CONFIG_ACENIC is not set
+# CONFIG_DL2K is not set
+# CONFIG_E1000 is not set
+# CONFIG_E1000E is not set
+# CONFIG_IP1000 is not set
+# CONFIG_NS83820 is not set
+# CONFIG_HAMACHI is not set
+# CONFIG_YELLOWFIN is not set
+# CONFIG_R8169 is not set
+# CONFIG_SIS190 is not set
+# CONFIG_SKGE is not set
+# CONFIG_SKY2 is not set
+# CONFIG_SK98LIN is not set
+# CONFIG_VIA_VELOCITY is not set
+# CONFIG_TIGON3 is not set
+# CONFIG_BNX2 is not set
+# CONFIG_QLA3XXX is not set
+# CONFIG_ATL1 is not set
+CONFIG_SYNOPSYS_GMAC=y
+# CONFIG_NETDEV_10000 is not set
+# CONFIG_TR is not set
+
+#
+# Wireless LAN
+#
+# CONFIG_WLAN_PRE80211 is not set
+# CONFIG_WLAN_80211 is not set
+
+#
+# USB Network Adapters
+#
+# CONFIG_USB_CATC is not set
+# CONFIG_USB_KAWETH is not set
+# CONFIG_USB_PEGASUS is not set
+# CONFIG_USB_RTL8150 is not set
+# CONFIG_USB_USBNET is not set
+# CONFIG_WAN is not set
+# CONFIG_FDDI is not set
+# CONFIG_HIPPI is not set
+# CONFIG_PPP is not set
+# CONFIG_SLIP is not set
+# CONFIG_NET_FC is not set
+# CONFIG_SHAPER is not set
+# CONFIG_NETCONSOLE is not set
+# CONFIG_NETPOLL is not set
+# CONFIG_NET_POLL_CONTROLLER is not set
+# CONFIG_ISDN is not set
+
+#
+# Input device support
+#
+CONFIG_INPUT=y
+# CONFIG_INPUT_FF_MEMLESS is not set
+# CONFIG_INPUT_POLLDEV is not set
+
+#
+# Userland interfaces
+#
+CONFIG_INPUT_MOUSEDEV=y
+# CONFIG_INPUT_MOUSEDEV_PSAUX is not set
+CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024
+CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
+# CONFIG_INPUT_JOYDEV is not set
+# CONFIG_INPUT_EVDEV is not set
+# CONFIG_INPUT_EVBUG is not set
+
+#
+# Input Device Drivers
+#
+# CONFIG_INPUT_KEYBOARD is not set
+# CONFIG_INPUT_MOUSE is not set
+# CONFIG_INPUT_JOYSTICK is not set
+# CONFIG_INPUT_TABLET is not set
+# CONFIG_INPUT_TOUCHSCREEN is not set
+# CONFIG_INPUT_MISC is not set
+
+#
+# Hardware I/O ports
+#
+# CONFIG_SERIO is not set
+# CONFIG_GAMEPORT is not set
+
+#
+# Character devices
+#
+CONFIG_VT=y
+CONFIG_VT_CONSOLE=y
+CONFIG_HW_CONSOLE=y
+# CONFIG_VT_HW_CONSOLE_BINDING is not set
+# CONFIG_SERIAL_NONSTANDARD is not set
+
+#
+# Serial drivers
+#
+CONFIG_SERIAL_8250=y
+CONFIG_SERIAL_8250_CONSOLE=y
+CONFIG_SERIAL_8250_PCI=y
+CONFIG_SERIAL_8250_NR_UARTS=4
+CONFIG_SERIAL_8250_RUNTIME_UARTS=4
+# CONFIG_SERIAL_8250_EXTENDED is not set
+
+#
+# Non-8250 serial port support
+#
+# CONFIG_SERIAL_AMBA_PL010 is not set
+# CONFIG_SERIAL_AMBA_PL011 is not set
+CONFIG_SERIAL_CORE=y
+CONFIG_SERIAL_CORE_CONSOLE=y
+# CONFIG_SERIAL_JSM is not set
+CONFIG_UNIX98_PTYS=y
+# CONFIG_LEGACY_PTYS is not set
+# CONFIG_IPMI_HANDLER is not set
+CONFIG_HW_RANDOM=m
+# CONFIG_NVRAM is not set
+# CONFIG_R3964 is not set
+# CONFIG_APPLICOM is not set
+# CONFIG_RAW_DRIVER is not set
+# CONFIG_TCG_TPM is not set
+CONFIG_DEVPORT=y
+CONFIG_I2C=m
+CONFIG_I2C_BOARDINFO=y
+# CONFIG_I2C_CHARDEV is not set
+
+#
+# I2C Algorithms
+#
+CONFIG_I2C_ALGOBIT=m
+# CONFIG_I2C_ALGOPCF is not set
+# CONFIG_I2C_ALGOPCA is not set
+# CONFIG_I2C_ALGOOXSEMI is not set
+
+#
+# I2C Hardware Bus support
+#
+# CONFIG_I2C_ALI1535 is not set
+# CONFIG_I2C_ALI1563 is not set
+# CONFIG_I2C_ALI15X3 is not set
+# CONFIG_I2C_AMD756 is not set
+# CONFIG_I2C_AMD8111 is not set
+# CONFIG_I2C_I801 is not set
+# CONFIG_I2C_I810 is not set
+# CONFIG_I2C_PIIX4 is not set
+# CONFIG_I2C_NFORCE2 is not set
+CONFIG_I2C_HIPOX_BITBASH=m
+# CONFIG_I2C_OCORES is not set
+# CONFIG_I2C_PARPORT_LIGHT is not set
+# CONFIG_I2C_PROSAVAGE is not set
+# CONFIG_I2C_SAVAGE4 is not set
+# CONFIG_I2C_SIMTEC is not set
+# CONFIG_I2C_SIS5595 is not set
+# CONFIG_I2C_SIS630 is not set
+# CONFIG_I2C_SIS96X is not set
+# CONFIG_I2C_TAOS_EVM is not set
+# CONFIG_I2C_STUB is not set
+# CONFIG_I2C_TINY_USB is not set
+# CONFIG_I2C_VIA is not set
+# CONFIG_I2C_VIAPRO is not set
+# CONFIG_I2C_VOODOO3 is not set
+
+#
+# Miscellaneous I2C Chip support
+#
+# CONFIG_SENSORS_DS1337 is not set
+# CONFIG_SENSORS_DS1374 is not set
+# CONFIG_DS1682 is not set
+# CONFIG_SENSORS_EEPROM is not set
+# CONFIG_SENSORS_PCF8574 is not set
+# CONFIG_SENSORS_PCA9539 is not set
+# CONFIG_SENSORS_PCF8591 is not set
+# CONFIG_SENSORS_MAX6875 is not set
+# CONFIG_SENSORS_TSL2550 is not set
+# CONFIG_I2C_DEBUG_CORE is not set
+# CONFIG_I2C_DEBUG_ALGO is not set
+# CONFIG_I2C_DEBUG_BUS is not set
+# CONFIG_I2C_DEBUG_CHIP is not set
+
+#
+# SPI support
+#
+# CONFIG_SPI is not set
+# CONFIG_SPI_MASTER is not set
+# CONFIG_W1 is not set
+# CONFIG_POWER_SUPPLY is not set
+# CONFIG_HWMON is not set
+# CONFIG_WATCHDOG is not set
+
+#
+# Sonics Silicon Backplane
+#
+CONFIG_SSB_POSSIBLE=y
+# CONFIG_SSB is not set
+
+#
+# Multifunction device drivers
+#
+# CONFIG_MFD_SM501 is not set
+
+#
+# Multimedia devices
+#
+# CONFIG_VIDEO_DEV is not set
+# CONFIG_DVB_CORE is not set
+CONFIG_DAB=y
+# CONFIG_USB_DABUSB is not set
+
+#
+# Graphics support
+#
+# CONFIG_DRM is not set
+# CONFIG_VGASTATE is not set
+CONFIG_VIDEO_OUTPUT_CONTROL=m
+# CONFIG_FB is not set
+# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
+
+#
+# Display device support
+#
+# CONFIG_DISPLAY_SUPPORT is not set
+
+#
+# Console display driver support
+#
+# CONFIG_VGA_CONSOLE is not set
+CONFIG_DUMMY_CONSOLE=y
+
+#
+# Sound
+#
+# CONFIG_SOUND is not set
+# CONFIG_HID_SUPPORT is not set
+CONFIG_USB_SUPPORT=y
+CONFIG_USB_ARCH_HAS_HCD=y
+CONFIG_USB_ARCH_HAS_OHCI=y
+CONFIG_USB_ARCH_HAS_EHCI=y
+CONFIG_USB=y
+# CONFIG_USB_DEBUG is not set
+
+#
+# Miscellaneous USB options
+#
+CONFIG_USB_DEVICEFS=y
+CONFIG_USB_DEVICE_CLASS=y
+# CONFIG_USB_DYNAMIC_MINORS is not set
+# CONFIG_USB_OTG is not set
+
+#
+# USB Host Controller Drivers
+#
+CONFIG_USB_EHCI_HCD=m
+# CONFIG_USB_EHCI_SPLIT_ISO is not set
+CONFIG_USB_EHCI_ROOT_HUB_TT=y
+# CONFIG_USB_EHCI_TT_NEWSCHED is not set
+# CONFIG_USB_ISP116X_HCD is not set
+# CONFIG_USB_OHCI_HCD is not set
+# CONFIG_USB_UHCI_HCD is not set
+# CONFIG_USB_SL811_HCD is not set
+# CONFIG_USB_R8A66597_HCD is not set
+
+#
+# USB Device Class drivers
+#
+# CONFIG_USB_ACM is not set
+# CONFIG_USB_PRINTER is not set
+
+#
+# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support'
+#
+
+#
+# may also be needed; see USB_STORAGE Help for more information
+#
+CONFIG_USB_STORAGE=m
+# CONFIG_USB_STORAGE_DEBUG is not set
+# CONFIG_USB_STORAGE_DATAFAB is not set
+# CONFIG_USB_STORAGE_FREECOM is not set
+# CONFIG_USB_STORAGE_ISD200 is not set
+# CONFIG_USB_STORAGE_DPCM is not set
+# CONFIG_USB_STORAGE_USBAT is not set
+# CONFIG_USB_STORAGE_SDDR09 is not set
+# CONFIG_USB_STORAGE_SDDR55 is not set
+# CONFIG_USB_STORAGE_JUMPSHOT is not set
+# CONFIG_USB_STORAGE_ALAUDA is not set
+# CONFIG_USB_STORAGE_KARMA is not set
+# CONFIG_USB_LIBUSUAL is not set
+
+#
+# USB Imaging devices
+#
+# CONFIG_USB_MDC800 is not set
+# CONFIG_USB_MICROTEK is not set
+# CONFIG_USB_MON is not set
+
+#
+# USB port drivers
+#
+
+#
+# USB Serial Converter support
+#
+# CONFIG_USB_SERIAL is not set
+
+#
+# USB Miscellaneous drivers
+#
+# CONFIG_USB_EMI62 is not set
+# CONFIG_USB_EMI26 is not set
+# CONFIG_USB_ADUTUX is not set
+# CONFIG_USB_AUERSWALD is not set
+# CONFIG_USB_RIO500 is not set
+# CONFIG_USB_LEGOTOWER is not set
+# CONFIG_USB_LCD is not set
+# CONFIG_USB_BERRY_CHARGE is not set
+# CONFIG_USB_LED is not set
+# CONFIG_USB_CYPRESS_CY7C63 is not set
+# CONFIG_USB_CYTHERM is not set
+# CONFIG_USB_PHIDGET is not set
+# CONFIG_USB_IDMOUSE is not set
+# CONFIG_USB_FTDI_ELAN is not set
+# CONFIG_USB_APPLEDISPLAY is not set
+# CONFIG_USB_SISUSBVGA is not set
+# CONFIG_USB_LD is not set
+# CONFIG_USB_TRANCEVIBRATOR is not set
+# CONFIG_USB_IOWARRIOR is not set
+CONFIG_USB_TEST=m
+
+#
+# USB DSL modem support
+#
+
+#
+# USB Gadget Support
+#
+# CONFIG_USB_GADGET is not set
+# CONFIG_MMC is not set
+# CONFIG_NEW_LEDS is not set
+CONFIG_RTC_LIB=y
+CONFIG_RTC_CLASS=m
+
+#
+# RTC interfaces
+#
+CONFIG_RTC_INTF_SYSFS=y
+CONFIG_RTC_INTF_PROC=y
+CONFIG_RTC_INTF_DEV=y
+# CONFIG_RTC_INTF_DEV_UIE_EMUL is not set
+# CONFIG_RTC_DRV_TEST is not set
+
+#
+# I2C RTC drivers
+#
+CONFIG_RTC_DRV_DS1307=m
+# CONFIG_RTC_DRV_DS1374 is not set
+# CONFIG_RTC_DRV_DS1672 is not set
+# CONFIG_RTC_DRV_MAX6900 is not set
+# CONFIG_RTC_DRV_RS5C372 is not set
+# CONFIG_RTC_DRV_ISL1208 is not set
+# CONFIG_RTC_DRV_X1205 is not set
+# CONFIG_RTC_DRV_PCF8563 is not set
+# CONFIG_RTC_DRV_PCF8583 is not set
+# CONFIG_RTC_DRV_M41T80 is not set
+
+#
+# SPI RTC drivers
+#
+
+#
+# Platform RTC drivers
+#
+# CONFIG_RTC_DRV_CMOS is not set
+# CONFIG_RTC_DRV_DS1553 is not set
+# CONFIG_RTC_DRV_STK17TA8 is not set
+# CONFIG_RTC_DRV_DS1742 is not set
+# CONFIG_RTC_DRV_M48T86 is not set
+# CONFIG_RTC_DRV_M48T59 is not set
+# CONFIG_RTC_DRV_V3020 is not set
+
+#
+# on-CPU RTC drivers
+#
+# CONFIG_RTC_DRV_PL031 is not set
+# CONFIG_DMADEVICES is not set
+
+#
+# File systems
+#
+CONFIG_EXT2_FS=y
+# CONFIG_EXT2_FS_XATTR is not set
+# CONFIG_EXT2_FS_XIP is not set
+CONFIG_EXT3_FS=y
+# CONFIG_EXT3_FS_XATTR is not set
+# CONFIG_EXT4DEV_FS is not set
+CONFIG_JBD=y
+# CONFIG_REISERFS_FS is not set
+# CONFIG_JFS_FS is not set
+CONFIG_FS_POSIX_ACL=y
+CONFIG_XFS_FS=y
+# CONFIG_XFS_QUOTA is not set
+# CONFIG_XFS_SECURITY is not set
+# CONFIG_XFS_POSIX_ACL is not set
+# CONFIG_XFS_RT is not set
+# CONFIG_GFS2_FS is not set
+# CONFIG_OCFS2_FS is not set
+# CONFIG_MINIX_FS is not set
+# CONFIG_ROMFS_FS is not set
+CONFIG_INOTIFY=y
+CONFIG_INOTIFY_USER=y
+# CONFIG_QUOTA is not set
+CONFIG_DNOTIFY=y
+# CONFIG_AUTOFS_FS is not set
+# CONFIG_AUTOFS4_FS is not set
+CONFIG_FUSE_FS=y
+
+#
+# CD-ROM/DVD Filesystems
+#
+# CONFIG_ISO9660_FS is not set
+# CONFIG_UDF_FS is not set
+
+#
+# DOS/FAT/NT Filesystems
+#
+CONFIG_FAT_FS=y
+CONFIG_MSDOS_FS=y
+CONFIG_VFAT_FS=m
+CONFIG_FAT_DEFAULT_CODEPAGE=437
+CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1"
+CONFIG_NTFS_FS=m
+# CONFIG_NTFS_DEBUG is not set
+# CONFIG_NTFS_RW is not set
+
+#
+# Pseudo filesystems
+#
+CONFIG_PROC_FS=y
+CONFIG_PROC_SYSCTL=y
+CONFIG_SYSFS=y
+CONFIG_TMPFS=y
+# CONFIG_HUGETLB_PAGE is not set
+# CONFIG_CONFIGFS_FS is not set
+
+#
+# Miscellaneous filesystems
+#
+# CONFIG_ADFS_FS is not set
+# CONFIG_AFFS_FS is not set
+# CONFIG_HFS_FS is not set
+CONFIG_HFSPLUS_FS=m
+# CONFIG_BEFS_FS is not set
+# CONFIG_BFS_FS is not set
+# CONFIG_EFS_FS is not set
+# CONFIG_CRAMFS is not set
+# CONFIG_VXFS_FS is not set
+# CONFIG_HPFS_FS is not set
+# CONFIG_QNX4FS_FS is not set
+# CONFIG_SYSV_FS is not set
+# CONFIG_UFS_FS is not set
+CONFIG_NETWORK_FILESYSTEMS=y
+# CONFIG_NFS_FS is not set
+CONFIG_NFSD=m
+CONFIG_NFSD_V2_ACL=y
+CONFIG_NFSD_V3=y
+CONFIG_NFSD_V3_ACL=y
+# CONFIG_NFSD_V4 is not set
+CONFIG_NFSD_TCP=y
+CONFIG_LOCKD=m
+CONFIG_LOCKD_V4=y
+CONFIG_EXPORTFS=m
+CONFIG_NFS_ACL_SUPPORT=m
+CONFIG_NFS_COMMON=y
+CONFIG_SUNRPC=m
+# CONFIG_SUNRPC_BIND34 is not set
+# CONFIG_RPCSEC_GSS_KRB5 is not set
+# CONFIG_RPCSEC_GSS_SPKM3 is not set
+# CONFIG_SMB_FS is not set
+# CONFIG_CIFS is not set
+# CONFIG_NCP_FS is not set
+# CONFIG_CODA_FS is not set
+# CONFIG_AFS_FS is not set
+
+#
+# Partition Types
+#
+CONFIG_PARTITION_ADVANCED=y
+# CONFIG_ACORN_PARTITION is not set
+# CONFIG_OSF_PARTITION is not set
+# CONFIG_AMIGA_PARTITION is not set
+# CONFIG_ATARI_PARTITION is not set
+CONFIG_MAC_PARTITION=y
+CONFIG_MSDOS_PARTITION=y
+# CONFIG_BSD_DISKLABEL is not set
+# CONFIG_MINIX_SUBPARTITION is not set
+# CONFIG_SOLARIS_X86_PARTITION is not set
+# CONFIG_UNIXWARE_DISKLABEL is not set
+CONFIG_LDM_PARTITION=y
+# CONFIG_LDM_DEBUG is not set
+# CONFIG_SGI_PARTITION is not set
+# CONFIG_ULTRIX_PARTITION is not set
+# CONFIG_SUN_PARTITION is not set
+# CONFIG_KARMA_PARTITION is not set
+CONFIG_EFI_PARTITION=y
+# CONFIG_SYSV68_PARTITION is not set
+CONFIG_NLS=y
+CONFIG_NLS_DEFAULT="iso8859-1"
+CONFIG_NLS_CODEPAGE_437=m
+# CONFIG_NLS_CODEPAGE_737 is not set
+# CONFIG_NLS_CODEPAGE_775 is not set
+# CONFIG_NLS_CODEPAGE_850 is not set
+# CONFIG_NLS_CODEPAGE_852 is not set
+# CONFIG_NLS_CODEPAGE_855 is not set
+# CONFIG_NLS_CODEPAGE_857 is not set
+# CONFIG_NLS_CODEPAGE_860 is not set
+# CONFIG_NLS_CODEPAGE_861 is not set
+# CONFIG_NLS_CODEPAGE_862 is not set
+# CONFIG_NLS_CODEPAGE_863 is not set
+# CONFIG_NLS_CODEPAGE_864 is not set
+# CONFIG_NLS_CODEPAGE_865 is not set
+# CONFIG_NLS_CODEPAGE_866 is not set
+# CONFIG_NLS_CODEPAGE_869 is not set
+# CONFIG_NLS_CODEPAGE_936 is not set
+# CONFIG_NLS_CODEPAGE_950 is not set
+# CONFIG_NLS_CODEPAGE_932 is not set
+# CONFIG_NLS_CODEPAGE_949 is not set
+# CONFIG_NLS_CODEPAGE_874 is not set
+# CONFIG_NLS_ISO8859_8 is not set
+# CONFIG_NLS_CODEPAGE_1250 is not set
+# CONFIG_NLS_CODEPAGE_1251 is not set
+# CONFIG_NLS_ASCII is not set
+CONFIG_NLS_ISO8859_1=m
+# CONFIG_NLS_ISO8859_2 is not set
+# CONFIG_NLS_ISO8859_3 is not set
+# CONFIG_NLS_ISO8859_4 is not set
+# CONFIG_NLS_ISO8859_5 is not set
+# CONFIG_NLS_ISO8859_6 is not set
+# CONFIG_NLS_ISO8859_7 is not set
+# CONFIG_NLS_ISO8859_9 is not set
+# CONFIG_NLS_ISO8859_13 is not set
+# CONFIG_NLS_ISO8859_14 is not set
+# CONFIG_NLS_ISO8859_15 is not set
+# CONFIG_NLS_KOI8_R is not set
+# CONFIG_NLS_KOI8_U is not set
+CONFIG_NLS_UTF8=y
+# CONFIG_DLM is not set
+# CONFIG_INSTRUMENTATION is not set
+
+#
+# Kernel hacking
+#
+# CONFIG_PRINTK_TIME is not set
+CONFIG_ENABLE_WARN_DEPRECATED=y
+CONFIG_ENABLE_MUST_CHECK=y
+# CONFIG_MAGIC_SYSRQ is not set
+# CONFIG_UNUSED_SYMBOLS is not set
+# CONFIG_DEBUG_FS is not set
+# CONFIG_HEADERS_CHECK is not set
+# CONFIG_DEBUG_KERNEL is not set
+CONFIG_DEBUG_BUGVERBOSE=y
+CONFIG_FRAME_POINTER=y
+# CONFIG_SAMPLES is not set
+# CONFIG_DEBUG_USER is not set
+
+#
+# Security options
+#
+# CONFIG_KEYS is not set
+CONFIG_SECURITY=y
+# CONFIG_SECURITY_NETWORK is not set
+# CONFIG_SECURITY_CAPABILITIES is not set
+CONFIG_SECURITY_TRUSTEES=y
+# CONFIG_SECURITY_TRUSTEES_DEBUG is not set
+CONFIG_CRYPTO=y
+CONFIG_CRYPTO_ALGAPI=y
+CONFIG_CRYPTO_BLKCIPHER=y
+CONFIG_CRYPTO_MANAGER=y
+# CONFIG_CRYPTO_HMAC is not set
+# CONFIG_CRYPTO_XCBC is not set
+# CONFIG_CRYPTO_NULL is not set
+# CONFIG_CRYPTO_MD4 is not set
+# CONFIG_CRYPTO_MD5 is not set
+# CONFIG_CRYPTO_SHA1 is not set
+# CONFIG_CRYPTO_SHA256 is not set
+# CONFIG_CRYPTO_SHA512 is not set
+# CONFIG_CRYPTO_WP512 is not set
+# CONFIG_CRYPTO_TGR192 is not set
+# CONFIG_CRYPTO_GF128MUL is not set
+CONFIG_CRYPTO_ECB=m
+CONFIG_CRYPTO_CBC=y
+CONFIG_CRYPTO_PCBC=m
+# CONFIG_CRYPTO_LRW is not set
+# CONFIG_CRYPTO_XTS is not set
+# CONFIG_CRYPTO_CRYPTD is not set
+# CONFIG_CRYPTO_DES is not set
+# CONFIG_CRYPTO_FCRYPT is not set
+# CONFIG_CRYPTO_BLOWFISH is not set
+# CONFIG_CRYPTO_TWOFISH is not set
+# CONFIG_CRYPTO_SERPENT is not set
+CONFIG_CRYPTO_AES=m
+# CONFIG_CRYPTO_CAST5 is not set
+# CONFIG_CRYPTO_CAST6 is not set
+# CONFIG_CRYPTO_TEA is not set
+CONFIG_CRYPTO_ARC4=m
+# CONFIG_CRYPTO_KHAZAD is not set
+# CONFIG_CRYPTO_ANUBIS is not set
+# CONFIG_CRYPTO_SEED is not set
+# CONFIG_CRYPTO_DEFLATE is not set
+CONFIG_CRYPTO_MICHAEL_MIC=m
+# CONFIG_CRYPTO_CRC32C is not set
+# CONFIG_CRYPTO_CAMELLIA is not set
+# CONFIG_CRYPTO_TEST is not set
+# CONFIG_CRYPTO_AUTHENC is not set
+CONFIG_CRYPTO_HW=y
+
+#
+# Library routines
+#
+CONFIG_BITREVERSE=y
+CONFIG_CRC_CCITT=y
+# CONFIG_CRC16 is not set
+# CONFIG_CRC_ITU_T is not set
+CONFIG_CRC32=y
+# CONFIG_CRC7 is not set
+# CONFIG_LIBCRC32C is not set
+CONFIG_PLIST=y
+CONFIG_HAS_IOMEM=y
+CONFIG_HAS_IOPORT=y
+CONFIG_HAS_DMA=y
diff --git a/recipes/linux/linux-2.6.24/hipox/hipox-mach-type.patch b/recipes/linux/linux-2.6.24/hipox/hipox-mach-type.patch
new file mode 100644
index 0000000000..e879af415e
--- /dev/null
+++ b/recipes/linux/linux-2.6.24/hipox/hipox-mach-type.patch
@@ -0,0 +1,7 @@
+--- linux-2.6.24/arch/arm/tools/mach-types.orig 2009-03-27 08:58:44.000000000 +0100
++++ linux-2.6.24/arch/arm/tools/mach-types 2009-03-27 09:00:25.000000000 +0100
+@@ -1367,3 +1367,4 @@
+ csb726 MACH_CSB726 CSB726 1359
+ tik27 MACH_TIK27 TIK27 1360
+ mx_uc7420 MACH_MX_UC7420 MX_UC7420 1361
++hipox MACH_HIPOX HIPOX 2151
diff --git a/recipes/linux/linux-2.6.24/hipox/hipox-pci-config-delay.patch b/recipes/linux/linux-2.6.24/hipox/hipox-pci-config-delay.patch
new file mode 100644
index 0000000000..6b7fd9e0b2
--- /dev/null
+++ b/recipes/linux/linux-2.6.24/hipox/hipox-pci-config-delay.patch
@@ -0,0 +1,56 @@
+--- linux-2.6.24.org/arch/arm/mach-hipox/pci.c 2009-03-09 14:26:43.000000000 +0100
++++ linux-2.6.24/arch/arm/mach-hipox/pci.c 2009-03-09 14:31:12.000000000 +0100
+@@ -25,6 +25,7 @@
+ #include <linux/interrupt.h>
+ #include <linux/init.h>
+ #include <linux/delay.h>
++#include <linux/jiffies.h>
+
+ #include <asm/io.h>
+ #include <asm/hardware.h>
+@@ -71,6 +72,12 @@
+
+ extern spinlock_t hipox_gpio_spinlock;
+
++#ifdef CONFIG_HIPOX_PCI_RESET
++static unsigned long pci_trhfa_startwait = 0;
++static unsigned long pci_trhfa_msec = 0;
++static unsigned long pci_trhfa_timeout = 0;
++#endif // CONFIG_HIPOX_PCI_RESET
++
+ #define PCI_BUS_NONMEM_START 0x00000000
+ #define PCI_BUS_NONMEM_SIZE 0x00080000
+
+@@ -505,6 +512,15 @@
+ struct pci_bus *hipox_pci_scan_bus(int nr, struct pci_sys_data *sys)
+ {
+ // printk(KERN_DEBUG "PCI: hipox_pci_scan_bus\n");
++
++#ifdef CONFIG_HIPOX_PCI_RESET
++ printk(KERN_DEBUG "PCI: hipox_pci_scan_bus now it's %lu, still waiting till %lu to become ready for config\n", jiffies, pci_trhfa_timeout);
++ if (time_after_eq(jiffies + msecs_to_jiffies(pci_trhfa_msec), pci_trhfa_timeout)) /* ensure not wrap */
++ while(time_before(jiffies, pci_trhfa_timeout))
++ udelay(100);
++ printk(KERN_DEBUG "PCI: hipox_pci_scan_bus waited from %lu to %lu to become ready for config\n", pci_trhfa_startwait, jiffies);
++#endif // CONFIG_HIPOX_PCI_RESET
++
+ return pci_scan_bus(sys->busnr, &hipox_pci_ops, sys);
+ }
+
+@@ -651,6 +667,16 @@
+
+ static int __init hipox_pci_init(void)
+ {
++#ifdef CONFIG_HIPOX_PCI_RESET
++ // CPU has reset PCI bus via GPIO.
++ // According to PCI spec, we have to wait for 2^25 PCI clocks to meet
++ // the PCI timing parameter Trhfa (RST# high to first access).
++ pci_trhfa_startwait = jiffies;
++ pci_trhfa_msec = 1000; // 1 sec should be fine for 33MHz
++ pci_trhfa_timeout = jiffies + msecs_to_jiffies(pci_trhfa_msec);
++ printk(KERN_DEBUG "PCI: hipox_pci_init now it's %lu, will wait till %lu to become ready for config\n", pci_trhfa_startwait, pci_trhfa_timeout);
++#endif // CONFIG_HIPOX_PCI_RESET
++
+ pci_common_init(&hipox_pci);
+ return 0;
+ }
diff --git a/recipes/linux/linux-2.6.24/hipox/hipox-pci-max-size.patch b/recipes/linux/linux-2.6.24/hipox/hipox-pci-max-size.patch
new file mode 100644
index 0000000000..bd261af5a3
--- /dev/null
+++ b/recipes/linux/linux-2.6.24/hipox/hipox-pci-max-size.patch
@@ -0,0 +1,21 @@
+diff -Nurd linux-2.6.24.orig//arch/arm/mach-hipox/pci.c linux-2.6.24/arch/arm/mach-hipox/pci.c
+--- linux-2.6.24.orig//arch/arm/mach-hipox/pci.c 2009-03-10 20:29:02.000000000 +0100
++++ linux-2.6.24/arch/arm/mach-hipox/pci.c 2009-03-10 21:10:47.000000000 +0100
+@@ -78,12 +78,14 @@
+ static unsigned long pci_trhfa_timeout = 0;
+ #endif // CONFIG_HIPOX_PCI_RESET
+
++// processor allows up to 8MB PCI address ranges maximum by design
++// we split this up to 4MB prefetchable and 4MB non-prefetchable
++
+ #define PCI_BUS_NONMEM_START 0x00000000
+-#define PCI_BUS_NONMEM_SIZE 0x00080000
+-
++#define PCI_BUS_NONMEM_SIZE 0x00400000
+
+ #define PCI_BUS_PREMEM_START PCI_BUS_NONMEM_START + PCI_BUS_NONMEM_SIZE
+-#define PCI_BUS_PREMEM_SIZE 0x00080000
++#define PCI_BUS_PREMEM_SIZE 0x00400000
+
+ #define SYNOPSYS_PCI_MEMORY_BASE_ADDRESS PCI_BASE_ADDRESS_0
+ #define SYNOPSYS_PCI_DUAL_CYCLE_BASE_ADDRESS PCI_BASE_ADDRESS_2
diff --git a/recipes/linux/linux-2.6.24/hipox/hipox-uart.patch b/recipes/linux/linux-2.6.24/hipox/hipox-uart.patch
new file mode 100644
index 0000000000..f8a2a6c960
--- /dev/null
+++ b/recipes/linux/linux-2.6.24/hipox/hipox-uart.patch
@@ -0,0 +1,176 @@
+diff -Nurd linux-2.6.24.org/arch/arm/configs/hipox_810_eabi_dse_defconfig linux-2.6.24/arch/arm/configs/hipox_810_eabi_dse_defconfig
+--- linux-2.6.24.org/arch/arm/configs/hipox_810_eabi_dse_defconfig 2009-02-05 12:06:15.000000000 +0100
++++ linux-2.6.24/arch/arm/configs/hipox_810_eabi_dse_defconfig 2009-02-05 12:08:36.000000000 +0100
+@@ -160,6 +160,8 @@
+ # CONFIG_HIPOX_VERSION_0X850 is not set
+ # CONFIG_ARCH_HIPOX_UART1 is not set
+ CONFIG_ARCH_HIPOX_UART2=y
++CONFIG_ARCH_HIPOX_UART2_DEBUG=y
++CONFIG_ARCH_HIPOX_UART2_BOOTPROGRESS=y
+ # CONFIG_ARCH_HIPOX_UART2_MODEM is not set
+ # CONFIG_ARCH_HIPOX_UART3 is not set
+ # CONFIG_ARCH_HIPOX_PCI_REQGNT_0 is not set
+diff -Nurd linux-2.6.24.org/arch/arm/configs/hipox_810_eabi_upgrade_defconfig linux-2.6.24/arch/arm/configs/hipox_810_eabi_upgrade_defconfig
+--- linux-2.6.24.org/arch/arm/configs/hipox_810_eabi_upgrade_defconfig 2009-02-05 12:06:15.000000000 +0100
++++ linux-2.6.24/arch/arm/configs/hipox_810_eabi_upgrade_defconfig 2009-02-05 12:08:36.000000000 +0100
+@@ -152,6 +152,8 @@
+ # CONFIG_HIPOX_VERSION_0X850 is not set
+ # CONFIG_ARCH_HIPOX_UART1 is not set
+ CONFIG_ARCH_HIPOX_UART2=y
++CONFIG_ARCH_HIPOX_UART2_DEBUG=y
++CONFIG_ARCH_HIPOX_UART2_BOOTPROGRESS=y
+ # CONFIG_ARCH_HIPOX_UART2_MODEM is not set
+ # CONFIG_ARCH_HIPOX_UART3 is not set
+ # CONFIG_ARCH_HIPOX_PCI_REQGNT_0 is not set
+diff -Nurd linux-2.6.24.org/arch/arm/configs/hipox_810_eabi_wd_eval_defconfig linux-2.6.24/arch/arm/configs/hipox_810_eabi_wd_eval_defconfig
+--- linux-2.6.24.org/arch/arm/configs/hipox_810_eabi_wd_eval_defconfig 2009-02-05 12:06:15.000000000 +0100
++++ linux-2.6.24/arch/arm/configs/hipox_810_eabi_wd_eval_defconfig 2009-02-05 12:08:36.000000000 +0100
+@@ -160,6 +160,8 @@
+ # CONFIG_HIPOX_VERSION_0X850 is not set
+ # CONFIG_ARCH_HIPOX_UART1 is not set
+ CONFIG_ARCH_HIPOX_UART2=y
++CONFIG_ARCH_HIPOX_UART2_DEBUG=y
++CONFIG_ARCH_HIPOX_UART2_BOOTPROGRESS=y
+ # CONFIG_ARCH_HIPOX_UART2_MODEM is not set
+ # CONFIG_ARCH_HIPOX_UART3 is not set
+ # CONFIG_ARCH_HIPOX_UART4 is not set
+diff -Nurd linux-2.6.24.org/arch/arm/configs/hipox_810_eabi_wd_prod_defconfig linux-2.6.24/arch/arm/configs/hipox_810_eabi_wd_prod_defconfig
+--- linux-2.6.24.org/arch/arm/configs/hipox_810_eabi_wd_prod_defconfig 2009-02-05 12:06:15.000000000 +0100
++++ linux-2.6.24/arch/arm/configs/hipox_810_eabi_wd_prod_defconfig 2009-02-05 12:08:36.000000000 +0100
+@@ -158,6 +158,8 @@
+ # CONFIG_HIPOX_VERSION_0X850 is not set
+ # CONFIG_ARCH_HIPOX_UART1 is not set
+ CONFIG_ARCH_HIPOX_UART2=y
++CONFIG_ARCH_HIPOX_UART2_DEBUG=y
++CONFIG_ARCH_HIPOX_UART2_BOOTPROGRESS=y
+ # CONFIG_ARCH_HIPOX_UART2_MODEM is not set
+ # CONFIG_ARCH_HIPOX_UART3 is not set
+ # CONFIG_ARCH_HIPOX_UART4 is not set
+diff -Nurd linux-2.6.24.org/arch/arm/mach-hipox/Kconfig linux-2.6.24/arch/arm/mach-hipox/Kconfig
+--- linux-2.6.24.org/arch/arm/mach-hipox/Kconfig 2009-02-05 12:06:15.000000000 +0100
++++ linux-2.6.24/arch/arm/mach-hipox/Kconfig 2009-02-05 12:08:34.000000000 +0100
+@@ -66,6 +66,20 @@
+ UARTs will be mapped to ttySn numbers from UART1 to UART4, only
+ including those UARTs selected to be present
+
++config ARCH_HIPOX_UART1_DEBUG
++ bool "Use UART1 as debug channel"
++ depends on ARCH_HIPOX_UART1
++ default n
++ help
++ This enables UART1 to be usable as debug channel.
++
++config ARCH_HIPOX_UART1_BOOTPROGRESS
++ bool "Display boot progress over UART1"
++ depends on ARCH_HIPOX_UART1
++ default n
++ help
++ This enables displaying boot progress over UART1.
++
+ config ARCH_HIPOX_UART1_MODEM
+ bool "Support UART1 modem control lines"
+ depends on ARCH_HIPOX_UART1
+@@ -81,6 +95,20 @@
+ UARTs will be mapped to ttySn numbers from UART1 to UART4, only
+ including those UARTs selected to be present
+
++config ARCH_HIPOX_UART2_DEBUG
++ bool "Use UART2 as debug channel"
++ depends on ARCH_HIPOX_UART2
++ default n
++ help
++ This enables UART2 to be usable as debug channel.
++
++config ARCH_HIPOX_UART2_BOOTPROGRESS
++ bool "Display boot progress over UART2"
++ depends on ARCH_HIPOX_UART2
++ default n
++ help
++ This enables displaying boot progress over UART2.
++
+ config ARCH_HIPOX_UART2_MODEM
+ bool "Support UART2 modem control lines"
+ depends on ARCH_HIPOX_UART2
+@@ -96,6 +124,20 @@
+ UARTs will be mapped to ttySn numbers from UART1 to UART4, only
+ including those UARTs selected to be present
+
++config ARCH_HIPOX_UART3_DEBUG
++ bool "Use UART3 as debug channel"
++ depends on ARCH_HIPOX_UART3
++ default n
++ help
++ This enables UART3 to be usable as debug channel.
++
++config ARCH_HIPOX_UART3_BOOTPROGRESS
++ bool "Display boot progress over UART3"
++ depends on ARCH_HIPOX_UART3
++ default n
++ help
++ This enables displaying boot progress over UART3.
++
+ config ARCH_HIPOX_UART3_MODEM
+ bool "Support UART3 modem control lines"
+ depends on ARCH_HIPOX_UART3
+@@ -114,6 +156,20 @@
+ UART4 always has its modem control lines available on external pins
+ when selected (overlaying PCI functions)
+
++config ARCH_HIPOX_UART4_DEBUG
++ bool "Use UART4 as debug channel"
++ depends on ARCH_HIPOX_UART4
++ default n
++ help
++ This enables UART4 to be usable as debug channel.
++
++config ARCH_HIPOX_UART4_BOOTPROGRESS
++ bool "Display boot progress over UART4"
++ depends on ARCH_HIPOX_UART4
++ default n
++ help
++ This enables displaying boot progress over UART4.
++
+ config ARCH_HIPOX_PCI_REQGNT_0
+ bool "Enable req/gnt for PCI device 0"
+ depends on PCI
+diff -Nurd linux-2.6.24.org/include/asm-arm/arch-hipox/debug-macro.S linux-2.6.24/include/asm-arm/arch-hipox/debug-macro.S
+--- linux-2.6.24.org/include/asm-arm/arch-hipox/debug-macro.S 2009-02-05 12:06:19.000000000 +0100
++++ linux-2.6.24/include/asm-arm/arch-hipox/debug-macro.S 2009-02-05 12:08:34.000000000 +0100
+@@ -14,13 +14,13 @@
+ .macro addruart,rx
+ mrc p15, 0, \rx, c1, c0
+ tst \rx, #1 @ MMU enabled?
+-#ifdef CONFIG_ARCH_HIPOX_UART1
++#ifdef CONFIG_ARCH_HIPOX_UART1_DEBUG
+ ldreq \rx, =UART_1_BASE_PA @ physical base address
+ ldrne \rx, =UART_1_BASE @ virtual address
+-#elif CONFIG_ARCH_HIPOX_UART2
++#elif CONFIG_ARCH_HIPOX_UART2_DEBUG
+ ldreq \rx, =UART_2_BASE_PA @ physical base address
+ ldrne \rx, =UART_2_BASE @ virtual address
+-#elif CONFIG_ARCH_HIPOX_UART3
++#elif CONFIG_ARCH_HIPOX_UART3_DEBUG
+ ldreq \rx, =UART_3_BASE_PA @ physical base address
+ ldrne \rx, =UART_3_BASE @ virtual address
+ #else
+diff -Nurd linux-2.6.24.org/include/asm-arm/arch-hipox/uncompress.h linux-2.6.24/include/asm-arm/arch-hipox/uncompress.h
+--- linux-2.6.24.org/include/asm-arm/arch-hipox/uncompress.h 2009-02-05 12:06:19.000000000 +0100
++++ linux-2.6.24/include/asm-arm/arch-hipox/uncompress.h 2009-02-05 12:08:34.000000000 +0100
+@@ -12,13 +12,13 @@
+
+ static inline void putc(int c)
+ {
+-#ifdef CONFIG_ARCH_HIPOX_UART1
++#ifdef CONFIG_ARCH_HIPOX_UART1_BOOTPROGRESS
+ static volatile unsigned char* uart = (volatile unsigned char*)UART_1_BASE_PA;
+-#elif defined(CONFIG_ARCH_HIPOX_UART2)
++#elif defined(CONFIG_ARCH_HIPOX_UART2_BOOTPROGRESS)
+ static volatile unsigned char* uart = (volatile unsigned char*)UART_2_BASE_PA;
+-#elif defined(CONFIG_ARCH_HIPOX_UART3)
++#elif defined(CONFIG_ARCH_HIPOX_UART3_BOOTPROGRESS)
+ static volatile unsigned char* uart = (volatile unsigned char*)UART_3_BASE_PA;
+-#elif defined(CONFIG_ARCH_HIPOX_UART4)
++#elif defined(CONFIG_ARCH_HIPOX_UART4_BOOTPROGRESS)
+ static volatile unsigned char* uart = (volatile unsigned char*)UART_4_BASE_PA;
+ #else
+ #define NO_UART
diff --git a/recipes/linux/linux-2.6.24/hipox/hipox.patch b/recipes/linux/linux-2.6.24/hipox/hipox.patch
new file mode 100644
index 0000000000..686876fb1e
--- /dev/null
+++ b/recipes/linux/linux-2.6.24/hipox/hipox.patch
@@ -0,0 +1,57804 @@
+diff -Nurd linux-2.6.24/.gitignore linux-2.6.24-oxe810/.gitignore
+--- linux-2.6.24/.gitignore 2008-01-24 23:58:37.000000000 +0100
++++ linux-2.6.24-oxe810/.gitignore 1970-01-01 01:00:00.000000000 +0100
+@@ -1,54 +0,0 @@
+-#
+-# NOTE! Don't add files that are generated in specific
+-# subdirectories here. Add them in the ".gitignore" file
+-# in that subdirectory instead.
+-#
+-# Normal rules
+-#
+-.*
+-*.o
+-*.o.*
+-*.a
+-*.s
+-*.ko
+-*.so
+-*.so.dbg
+-*.mod.c
+-*.i
+-*.lst
+-*.symtypes
+-
+-#
+-# Top-level generic files
+-#
+-tags
+-TAGS
+-vmlinux*
+-!vmlinux.lds.S
+-System.map
+-Module.symvers
+-!.gitignore
+-
+-#
+-# Generated include files
+-#
+-include/asm
+-include/asm-*/asm-offsets.h
+-include/config
+-include/linux/autoconf.h
+-include/linux/compile.h
+-include/linux/version.h
+-include/linux/utsrelease.h
+-
+-# stgit generated dirs
+-patches-*
+-
+-# quilt's files
+-patches
+-series
+-
+-# cscope files
+-cscope.*
+-
+-*.orig
+-*.rej
+diff -Nurd linux-2.6.24/.mailmap linux-2.6.24-oxe810/.mailmap
+--- linux-2.6.24/.mailmap 2008-01-24 23:58:37.000000000 +0100
++++ linux-2.6.24-oxe810/.mailmap 1970-01-01 01:00:00.000000000 +0100
+@@ -1,98 +0,0 @@
+-#
+-# This list is used by git-shortlog to fix a few botched name translations
+-# in the git archive, either because the author's full name was messed up
+-# and/or not always written the same way, making contributions from the
+-# same person appearing not to be so or badly displayed.
+-#
+-# repo-abbrev: /pub/scm/linux/kernel/git/
+-#
+-
+-Aaron Durbin <adurbin@google.com>
+-Adam Oldham <oldhamca@gmail.com>
+-Adam Radford <aradford@gmail.com>
+-Adrian Bunk <bunk@stusta.de>
+-Alan Cox <alan@lxorguk.ukuu.org.uk>
+-Alan Cox <root@hraefn.swansea.linux.org.uk>
+-Aleksey Gorelov <aleksey_gorelov@phoenix.com>
+-Al Viro <viro@ftp.linux.org.uk>
+-Al Viro <viro@zenIV.linux.org.uk>
+-Andreas Herrmann <aherrman@de.ibm.com>
+-Andrew Morton <akpm@osdl.org>
+-Andrew Vasquez <andrew.vasquez@qlogic.com>
+-Andy Adamson <andros@citi.umich.edu>
+-Arnaud Patard <arnaud.patard@rtp-net.org>
+-Arnd Bergmann <arnd@arndb.de>
+-Axel Dyks <xl@xlsigned.net>
+-Ben Gardner <bgardner@wabtec.com>
+-Ben M Cahill <ben.m.cahill@intel.com>
+-Björn Steinbrink <B.Steinbrink@gmx.de>
+-Brian Avery <b.avery@hp.com>
+-Brian King <brking@us.ibm.com>
+-Christoph Hellwig <hch@lst.de>
+-Corey Minyard <minyard@acm.org>
+-David Brownell <david-b@pacbell.net>
+-David Woodhouse <dwmw2@shinybook.infradead.org>
+-Domen Puncer <domen@coderock.org>
+-Douglas Gilbert <dougg@torque.net>
+-Ed L. Cashin <ecashin@coraid.com>
+-Evgeniy Polyakov <johnpol@2ka.mipt.ru>
+-Felipe W Damasio <felipewd@terra.com.br>
+-Felix Kuhling <fxkuehl@gmx.de>
+-Felix Moeller <felix@derklecks.de>
+-Filipe Lautert <filipe@icewall.org>
+-Franck Bui-Huu <vagabon.xyz@gmail.com>
+-Frank Zago <fzago@systemfabricworks.com>
+-Greg Kroah-Hartman <greg@echidna.(none)>
+-Greg Kroah-Hartman <gregkh@suse.de>
+-Greg Kroah-Hartman <greg@kroah.com>
+-Henk Vergonet <Henk.Vergonet@gmail.com>
+-Henrik Kretzschmar <henne@nachtwindheim.de>
+-Herbert Xu <herbert@gondor.apana.org.au>
+-Jacob Shin <Jacob.Shin@amd.com>
+-James Bottomley <jejb@mulgrave.(none)>
+-James Bottomley <jejb@titanic.il.steeleye.com>
+-James E Wilson <wilson@specifix.com>
+-James Ketrenos <jketreno@io.(none)>
+-Jean Tourrilhes <jt@hpl.hp.com>
+-Jeff Garzik <jgarzik@pretzel.yyz.us>
+-Jens Axboe <axboe@suse.de>
+-Jens Osterkamp <Jens.Osterkamp@de.ibm.com>
+-John Stultz <johnstul@us.ibm.com>
+-Juha Yrjola <at solidboot.com>
+-Juha Yrjola <juha.yrjola@nokia.com>
+-Juha Yrjola <juha.yrjola@solidboot.com>
+-Kay Sievers <kay.sievers@vrfy.org>
+-Kenneth W Chen <kenneth.w.chen@intel.com>
+-Koushik <raghavendra.koushik@neterion.com>
+-Leonid I Ananiev <leonid.i.ananiev@intel.com>
+-Linas Vepstas <linas@austin.ibm.com>
+-Matthieu CASTET <castet.matthieu@free.fr>
+-Michael Buesch <mb@bu3sch.de>
+-Michael Buesch <mbuesch@freenet.de>
+-Michel Dänzer <michel@tungstengraphics.com>
+-Mitesh shah <mshah@teja.com>
+-Morten Welinder <terra@gnome.org>
+-Morten Welinder <welinder@anemone.rentec.com>
+-Morten Welinder <welinder@darter.rentec.com>
+-Morten Welinder <welinder@troll.com>
+-Nguyen Anh Quynh <aquynh@gmail.com>
+-Paolo 'Blaisorblade' Giarrusso <blaisorblade@yahoo.it>
+-Patrick Mochel <mochel@digitalimplant.org>
+-Peter A Jonsson <pj@ludd.ltu.se>
+-Praveen BP <praveenbp@ti.com>
+-Rajesh Shah <rajesh.shah@intel.com>
+-Ralf Baechle <ralf@linux-mips.org>
+-Ralf Wildenhues <Ralf.Wildenhues@gmx.de>
+-Rémi Denis-Courmont <rdenis@simphalempin.com>
+-Rudolf Marek <R.Marek@sh.cvut.cz>
+-Rui Saraiva <rmps@joel.ist.utl.pt>
+-Sachin P Sant <ssant@in.ibm.com>
+-Sam Ravnborg <sam@mars.ravnborg.org>
+-Simon Kelley <simon@thekelleys.org.uk>
+-Stéphane Witzmann <stephane.witzmann@ubpmes.univ-bpclermont.fr>
+-Stephen Hemminger <shemminger@osdl.org>
+-Tejun Heo <htejun@gmail.com>
+-Thomas Graf <tgraf@suug.ch>
+-Tony Luck <tony.luck@intel.com>
+-Tsuneo Yoshioka <Tsuneo.Yoshioka@f-secure.com>
+-Valdis Kletnieks <Valdis.Kletnieks@vt.edu>
+diff -Nurd linux-2.6.24/Documentation/video4linux/CARDLIST.cx23885 linux-2.6.24-oxe810/Documentation/video4linux/CARDLIST.cx23885
+--- linux-2.6.24/Documentation/video4linux/CARDLIST.cx23885 2008-01-24 23:58:37.000000000 +0100
++++ linux-2.6.24-oxe810/Documentation/video4linux/CARDLIST.cx23885 2008-06-11 17:47:23.000000000 +0200
+@@ -1,5 +1,5 @@
+ 0 -> UNKNOWN/GENERIC [0070:3400]
+ 1 -> Hauppauge WinTV-HVR1800lp [0070:7600]
+- 2 -> Hauppauge WinTV-HVR1800 [0070:7800,0070:7801]
++ 2 -> Hauppauge WinTV-HVR1800 [0070:7800,0070:7801,0070:7809]
+ 3 -> Hauppauge WinTV-HVR1250 [0070:7911]
+ 4 -> DViCO FusionHDTV5 Express [18ac:d500]
+diff -Nurd linux-2.6.24/Makefile linux-2.6.24-oxe810/Makefile
+--- linux-2.6.24/Makefile 2008-01-24 23:58:37.000000000 +0100
++++ linux-2.6.24-oxe810/Makefile 2008-06-11 17:50:34.000000000 +0200
+@@ -1,8 +1,8 @@
+ VERSION = 2
+ PATCHLEVEL = 6
+ SUBLEVEL = 24
+-EXTRAVERSION =
+-NAME = Arr Matey! A Hairy Bilge Rat!
++EXTRAVERSION = .4
++NAME = Err Metey! A Heury Beelge-a Ret!
+
+ # *DOCUMENTATION*
+ # To see a list of typical targets execute "make help"
+@@ -190,8 +190,8 @@
+ # Default value for CROSS_COMPILE is not to prefix executables
+ # Note: Some architectures assign CROSS_COMPILE in their arch/*/Makefile
+
+-ARCH ?= $(SUBARCH)
+-CROSS_COMPILE ?=
++ARCH ?= arm
++CROSS_COMPILE ?= arm-linux-uclibcgnueabi-
+
+ # Architecture as present in compile.h
+ UTS_MACHINE := $(ARCH)
+diff -Nurd linux-2.6.24/arch/arm/Kconfig linux-2.6.24-oxe810/arch/arm/Kconfig
+--- linux-2.6.24/arch/arm/Kconfig 2008-01-24 23:58:37.000000000 +0100
++++ linux-2.6.24-oxe810/arch/arm/Kconfig 2008-06-11 17:47:58.000000000 +0200
+@@ -409,6 +409,10 @@
+ help
+ Support for TI's OMAP platform (OMAP1 and OMAP2).
+
++config ARCH_HIPOX
++ bool "Oxford Semiconductor NAS SoC"
++ help
++ This enables support for Oxsemi NAS SoC
+ endchoice
+
+ source "arch/arm/mach-clps711x/Kconfig"
+@@ -461,6 +465,8 @@
+
+ source "arch/arm/mach-versatile/Kconfig"
+
++source "arch/arm/mach-hipox/Kconfig"
++
+ source "arch/arm/mach-aaec2000/Kconfig"
+
+ source "arch/arm/mach-realview/Kconfig"
+@@ -537,7 +543,7 @@
+ bool
+
+ config PCI
+- bool "PCI support" if ARCH_INTEGRATOR_AP || ARCH_VERSATILE_PB || ARCH_IXP4XX || ARCH_KS8695 || MACH_ARMCORE
++ bool "PCI support" if ARCH_INTEGRATOR_AP || ARCH_VERSATILE_PB || ARCH_IXP4XX || ARCH_KS8695 || MACH_ARMCORE || ARCH_HIPOX
+ help
+ Find out whether you have a PCI motherboard. PCI is the name of a
+ bus system, i.e. the way the CPU talks to the other stuff inside
+@@ -653,11 +659,13 @@
+ to have accurate timekeeping with dynamic tick.
+
+ config HZ
+- int
++ int "Kernel timer tick rate"
+ default 128 if ARCH_L7200
+ default 200 if ARCH_EBSA110 || ARCH_S3C2410
+ default OMAP_32K_TIMER_HZ if ARCH_OMAP && OMAP_32K_TIMER
+ default 100
++ help
++ Sets the number of timer tick interrupts per second
+
+ config AEABI
+ bool "Use the ARM EABI to compile the kernel"
+@@ -1010,7 +1018,7 @@
+ if PCMCIA || ARCH_CLPS7500 || ARCH_IOP32X || ARCH_IOP33X || ARCH_IXP4XX \
+ || ARCH_L7200 || ARCH_LH7A40X || ARCH_PXA || ARCH_RPC \
+ || ARCH_S3C2410 || ARCH_SA1100 || ARCH_SHARK || FOOTBRIDGE \
+- || ARCH_IXP23XX
++ || ARCH_IXP23XX || ARCH_HIPOX
+ source "drivers/ide/Kconfig"
+ endif
+
+diff -Nurd linux-2.6.24/arch/arm/Makefile linux-2.6.24-oxe810/arch/arm/Makefile
+--- linux-2.6.24/arch/arm/Makefile 2008-01-24 23:58:37.000000000 +0100
++++ linux-2.6.24-oxe810/arch/arm/Makefile 2008-06-11 17:47:58.000000000 +0200
+@@ -127,6 +127,7 @@
+ machine-$(CONFIG_ARCH_VERSATILE) := versatile
+ machine-$(CONFIG_ARCH_IMX) := imx
+ machine-$(CONFIG_ARCH_H720X) := h720x
++ machine-$(CONFIG_ARCH_HIPOX) := hipox
+ machine-$(CONFIG_ARCH_AAEC2000) := aaec2000
+ machine-$(CONFIG_ARCH_REALVIEW) := realview
+ machine-$(CONFIG_ARCH_AT91) := at91
+diff -Nurd linux-2.6.24/arch/arm/configs/hipox_810_eabi_dse_defconfig linux-2.6.24-oxe810/arch/arm/configs/hipox_810_eabi_dse_defconfig
+--- linux-2.6.24/arch/arm/configs/hipox_810_eabi_dse_defconfig 1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.24-oxe810/arch/arm/configs/hipox_810_eabi_dse_defconfig 2008-06-11 17:47:52.000000000 +0200
+@@ -0,0 +1,1233 @@
++#
++# Automatically generated make config: don't edit
++# Linux kernel version: 2.6.24.4
++# Mon Jun 2 12:34:33 2008
++#
++CONFIG_ARM=y
++CONFIG_SYS_SUPPORTS_APM_EMULATION=y
++# CONFIG_GENERIC_GPIO is not set
++# CONFIG_GENERIC_TIME is not set
++# CONFIG_GENERIC_CLOCKEVENTS is not set
++CONFIG_MMU=y
++# CONFIG_NO_IOPORT is not set
++CONFIG_GENERIC_HARDIRQS=y
++CONFIG_STACKTRACE_SUPPORT=y
++CONFIG_LOCKDEP_SUPPORT=y
++CONFIG_TRACE_IRQFLAGS_SUPPORT=y
++CONFIG_HARDIRQS_SW_RESEND=y
++CONFIG_GENERIC_IRQ_PROBE=y
++CONFIG_RWSEM_GENERIC_SPINLOCK=y
++# CONFIG_ARCH_HAS_ILOG2_U32 is not set
++# CONFIG_ARCH_HAS_ILOG2_U64 is not set
++CONFIG_GENERIC_HWEIGHT=y
++CONFIG_GENERIC_CALIBRATE_DELAY=y
++CONFIG_ZONE_DMA=y
++CONFIG_VECTORS_BASE=0xffff0000
++CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
++
++#
++# General setup
++#
++CONFIG_EXPERIMENTAL=y
++CONFIG_BROKEN_ON_SMP=y
++CONFIG_INIT_ENV_ARG_LIMIT=32
++CONFIG_LOCALVERSION=""
++CONFIG_LOCALVERSION_AUTO=y
++CONFIG_SWAP=y
++CONFIG_SYSVIPC=y
++CONFIG_SYSVIPC_SYSCTL=y
++# CONFIG_POSIX_MQUEUE is not set
++# CONFIG_BSD_PROCESS_ACCT is not set
++# CONFIG_TASKSTATS is not set
++# CONFIG_USER_NS is not set
++# CONFIG_PID_NS is not set
++# CONFIG_AUDIT is not set
++# CONFIG_IKCONFIG is not set
++CONFIG_LOG_BUF_SHIFT=14
++# CONFIG_CGROUPS is not set
++# CONFIG_FAIR_GROUP_SCHED is not set
++# CONFIG_FAIR_USER_SCHED is not set
++# CONFIG_FAIR_CGROUP_SCHED is not set
++CONFIG_SYSFS_DEPRECATED=y
++# CONFIG_RELAY is not set
++CONFIG_BLK_DEV_INITRD=y
++CONFIG_INITRAMFS_SOURCE=""
++# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
++CONFIG_SYSCTL=y
++# CONFIG_EMBEDDED is not set
++CONFIG_UID16=y
++CONFIG_SYSCTL_SYSCALL=y
++CONFIG_KALLSYMS=y
++# CONFIG_KALLSYMS_EXTRA_PASS is not set
++CONFIG_HOTPLUG=y
++CONFIG_PRINTK=y
++CONFIG_BUG=y
++CONFIG_ELF_CORE=y
++CONFIG_BASE_FULL=y
++CONFIG_FUTEX=y
++CONFIG_ANON_INODES=y
++CONFIG_EPOLL=y
++CONFIG_SIGNALFD=y
++CONFIG_EVENTFD=y
++CONFIG_SHMEM=y
++CONFIG_VM_EVENT_COUNTERS=y
++CONFIG_SLAB=y
++# CONFIG_SLUB is not set
++# CONFIG_SLOB is not set
++CONFIG_SLABINFO=y
++CONFIG_RT_MUTEXES=y
++# CONFIG_TINY_SHMEM is not set
++CONFIG_BASE_SMALL=0
++CONFIG_MODULES=y
++CONFIG_MODULE_UNLOAD=y
++# CONFIG_MODULE_FORCE_UNLOAD is not set
++# CONFIG_MODVERSIONS is not set
++# CONFIG_MODULE_SRCVERSION_ALL is not set
++# CONFIG_KMOD is not set
++CONFIG_BLOCK=y
++# CONFIG_LBD is not set
++# CONFIG_BLK_DEV_IO_TRACE is not set
++# CONFIG_LSF is not set
++# CONFIG_BLK_DEV_BSG is not set
++
++#
++# IO Schedulers
++#
++CONFIG_IOSCHED_NOOP=y
++CONFIG_IOSCHED_AS=y
++CONFIG_IOSCHED_DEADLINE=y
++CONFIG_IOSCHED_CFQ=y
++CONFIG_DEFAULT_AS=y
++# CONFIG_DEFAULT_DEADLINE is not set
++# CONFIG_DEFAULT_CFQ is not set
++# CONFIG_DEFAULT_NOOP is not set
++CONFIG_DEFAULT_IOSCHED="anticipatory"
++
++#
++# System Type
++#
++# CONFIG_ARCH_AAEC2000 is not set
++# CONFIG_ARCH_INTEGRATOR is not set
++# CONFIG_ARCH_REALVIEW is not set
++# CONFIG_ARCH_VERSATILE is not set
++# CONFIG_ARCH_AT91 is not set
++# CONFIG_ARCH_CLPS7500 is not set
++# CONFIG_ARCH_CLPS711X is not set
++# CONFIG_ARCH_CO285 is not set
++# CONFIG_ARCH_EBSA110 is not set
++# CONFIG_ARCH_EP93XX is not set
++# CONFIG_ARCH_FOOTBRIDGE is not set
++# CONFIG_ARCH_NETX is not set
++# CONFIG_ARCH_H720X is not set
++# CONFIG_ARCH_IMX is not set
++# CONFIG_ARCH_IOP13XX is not set
++# CONFIG_ARCH_IOP32X is not set
++# CONFIG_ARCH_IOP33X is not set
++# CONFIG_ARCH_IXP23XX is not set
++# CONFIG_ARCH_IXP2000 is not set
++# CONFIG_ARCH_IXP4XX is not set
++# CONFIG_ARCH_L7200 is not set
++# CONFIG_ARCH_KS8695 is not set
++# CONFIG_ARCH_NS9XXX is not set
++# CONFIG_ARCH_MXC is not set
++# CONFIG_ARCH_PNX4008 is not set
++# CONFIG_ARCH_PXA is not set
++# CONFIG_ARCH_RPC is not set
++# CONFIG_ARCH_SA1100 is not set
++# CONFIG_ARCH_S3C2410 is not set
++# CONFIG_ARCH_SHARK is not set
++# CONFIG_ARCH_LH7A40X is not set
++# CONFIG_ARCH_DAVINCI is not set
++# CONFIG_ARCH_OMAP is not set
++CONFIG_ARCH_HIPOX=y
++
++#
++# Boot options
++#
++
++#
++# Power management
++#
++
++#
++# Oxford Semiconductor NAS Options
++#
++# CONFIG_ARCH_HIPOX_FPGA is not set
++CONFIG_NOMINAL_PLL400_FREQ=733333333
++CONFIG_NOMINAL_RPSCLK_FREQ=25000000
++# CONFIG_HIPOX_VERSION_0X800 is not set
++CONFIG_HIPOX_VERSION_0X810=y
++# CONFIG_HIPOX_VERSION_0X850 is not set
++# CONFIG_ARCH_HIPOX_UART1 is not set
++CONFIG_ARCH_HIPOX_UART2=y
++# CONFIG_ARCH_HIPOX_UART2_MODEM is not set
++# CONFIG_ARCH_HIPOX_UART3 is not set
++# CONFIG_ARCH_HIPOX_PCI_REQGNT_0 is not set
++# CONFIG_ARCH_HIPOX_PCI_REQGNT_1 is not set
++# CONFIG_ARCH_HIPOX_PCI_REQGNT_2 is not set
++# CONFIG_ARCH_HIPOX_PCI_REQGNT_3 is not set
++# CONFIG_ARCH_HIPOX_PCI_CLKOUT_0 is not set
++# CONFIG_ARCH_HIPOX_PCI_CLKOUT_1 is not set
++# CONFIG_ARCH_HIPOX_PCI_CLKOUT_2 is not set
++# CONFIG_ARCH_HIPOX_PCI_CLKOUT_3 is not set
++# CONFIG_HIPOX_PCI_RESET is not set
++CONFIG_FORCE_MAX_ZONEORDER=10
++CONFIG_SRAM_NUM_PAGES=32
++CONFIG_SUPPORT_LEON=y
++CONFIG_LEON_PAGES=2
++CONFIG_LEON_COPRO=y
++CONFIG_LEON_OFFLOAD_TX=y
++# CONFIG_LEON_RESERVE_DMA_CHANNEL is not set
++CONFIG_LEON_OFFLOAD_TSO=y
++# CONFIG_LEON_START_EARLY is not set
++CONFIG_LEON_POWER_BUTTON_MONITOR=m
++CONFIG_HIPOX_POWER_BUTTON_GPIO=4
++CONFIG_USER_RECOVERY_BUTTON_MONITOR=y
++CONFIG_HIPOX_USER_RECOVERY_BUTTON_GPIO=32
++# CONFIG_HIPOX_DDR_MON is not set
++# CONFIG_HIPOX_AHB_MON is not set
++# CONFIG_HIPOX_CACHE_LOCKDOWN is not set
++# CONFIG_DO_MEM_TEST is not set
++# CONFIG_CRYPTO_OXAESLRW is not set
++CONFIG_DESCRIPTORS_PAGES=6
++CONFIG_ARCH_HIPOX_NUM_GMAC_DESCRIPTORS=192
++CONFIG_ARCH_HIPOX_MAX_SATA_SG_ENTRIES=256
++CONFIG_TACHO_THERM_AND_FAN=m
++# CONFIG_GPIO_TEST is not set
++CONFIG_HIPOX_RTC=m
++# CONFIG_I2S is not set
++# CONFIG_DPE_TEST is not set
++# CONFIG_HIPOX_INSTRUMENT_COPIES is not set
++# CONFIG_HIPOX_DMA_COPIES is not set
++# CONFIG_HIPOX_AHB_MONITOR_MODULE is not set
++# CONFIG_HIPOX_USB_TEST_MODES is not set
++# CONFIG_HIPOX_FRONT_LAMP_CONTROL is not set
++# CONFIG_LEDS_TRIGGER_SATA_DISK is not set
++# CONFIG_HIPOX_LED_TEST is not set
++CONFIG_HIPOX_I2C_SDA=6
++CONFIG_HIPOX_I2C_SCL=7
++# CONFIG_HIPOX_USB_PORTA_POWER_CONTROL is not set
++# CONFIG_HIPOX_USB_PORTB_POWER_CONTROL is not set
++# CONFIG_HIPOX_USB_PORTC_POWER_CONTROL is not set
++# CONFIG_HIPOX_USB_OVERCURRENT_POLARITY_NEGATIVE is not set
++# CONFIG_HIPOX_USB_POWER_SWITCH_POLARITY_NEGATIVE is not set
++# CONFIG_WDC_FAN_HIPOX800 is not set
++# CONFIG_HIPOX_MAP_SRAM is not set
++# CONFIG_HIPOX_SUID_INHERIT is not set
++# CONFIG_HIPOX_USB_HUB_SUPPORT is not set
++
++#
++# Processor Type
++#
++CONFIG_CPU_32=y
++CONFIG_CPU_ARM926T=y
++CONFIG_CPU_32v5=y
++CONFIG_CPU_ABRT_EV5TJ=y
++CONFIG_CPU_CACHE_VIVT=y
++CONFIG_CPU_COPY_V4WB=y
++CONFIG_CPU_TLB_V4WBI=y
++CONFIG_CPU_CP15=y
++CONFIG_CPU_CP15_MMU=y
++
++#
++# Processor Features
++#
++CONFIG_ARM_THUMB=y
++# CONFIG_CPU_ICACHE_DISABLE is not set
++# CONFIG_CPU_DCACHE_DISABLE is not set
++# CONFIG_CPU_DCACHE_WRITETHROUGH is not set
++# CONFIG_CPU_CACHE_ROUND_ROBIN is not set
++# CONFIG_OUTER_CACHE is not set
++
++#
++# Bus support
++#
++CONFIG_ARM_AMBA=y
++CONFIG_PCI=y
++CONFIG_PCI_SYSCALL=y
++# CONFIG_ARCH_SUPPORTS_MSI is not set
++CONFIG_PCI_LEGACY=y
++# CONFIG_PCCARD is not set
++
++#
++# Kernel Features
++#
++# CONFIG_TICK_ONESHOT is not set
++# CONFIG_PREEMPT is not set
++# CONFIG_NO_IDLE_HZ is not set
++CONFIG_HZ=100
++CONFIG_AEABI=y
++# CONFIG_OABI_COMPAT is not set
++# CONFIG_ARCH_DISCONTIGMEM_ENABLE is not set
++CONFIG_SELECT_MEMORY_MODEL=y
++CONFIG_FLATMEM_MANUAL=y
++# CONFIG_DISCONTIGMEM_MANUAL is not set
++# CONFIG_SPARSEMEM_MANUAL is not set
++CONFIG_FLATMEM=y
++CONFIG_FLAT_NODE_MEM_MAP=y
++# CONFIG_SPARSEMEM_STATIC is not set
++# CONFIG_SPARSEMEM_VMEMMAP_ENABLE is not set
++CONFIG_SPLIT_PTLOCK_CPUS=4096
++# CONFIG_RESOURCES_64BIT is not set
++CONFIG_ZONE_DMA_FLAG=1
++CONFIG_BOUNCE=y
++CONFIG_VIRT_TO_BUS=y
++CONFIG_ALIGNMENT_TRAP=y
++
++#
++# Boot options
++#
++CONFIG_ZBOOT_ROM_TEXT=0x0
++CONFIG_ZBOOT_ROM_BSS=0x0
++CONFIG_CMDLINE=""
++# CONFIG_XIP_KERNEL is not set
++# CONFIG_KEXEC is not set
++
++#
++# Floating point emulation
++#
++
++#
++# At least one emulation must be selected
++#
++# CONFIG_VFP is not set
++
++#
++# Userspace binary formats
++#
++CONFIG_BINFMT_ELF=y
++# CONFIG_BINFMT_AOUT is not set
++# CONFIG_BINFMT_MISC is not set
++
++#
++# Power management options
++#
++# CONFIG_PM is not set
++CONFIG_SUSPEND_UP_POSSIBLE=y
++
++#
++# Networking
++#
++CONFIG_NET=y
++
++#
++# Networking options
++#
++CONFIG_PACKET=y
++CONFIG_PACKET_MMAP=y
++CONFIG_UNIX=y
++CONFIG_XFRM=y
++# CONFIG_XFRM_USER is not set
++# CONFIG_XFRM_SUB_POLICY is not set
++# CONFIG_XFRM_MIGRATE is not set
++# CONFIG_NET_KEY is not set
++CONFIG_INET=y
++CONFIG_IP_MULTICAST=y
++# CONFIG_IP_ADVANCED_ROUTER is not set
++CONFIG_IP_FIB_HASH=y
++# CONFIG_IP_PNP is not set
++# CONFIG_NET_IPIP is not set
++# CONFIG_NET_IPGRE is not set
++# CONFIG_IP_MROUTE is not set
++# CONFIG_ARPD is not set
++# CONFIG_SYN_COOKIES is not set
++# CONFIG_INET_AH is not set
++# CONFIG_INET_ESP is not set
++# CONFIG_INET_IPCOMP is not set
++# CONFIG_INET_XFRM_TUNNEL is not set
++# CONFIG_INET_TUNNEL is not set
++CONFIG_INET_XFRM_MODE_TRANSPORT=y
++CONFIG_INET_XFRM_MODE_TUNNEL=y
++CONFIG_INET_XFRM_MODE_BEET=y
++# CONFIG_INET_LRO is not set
++CONFIG_INET_DIAG=y
++CONFIG_INET_TCP_DIAG=y
++# CONFIG_TCP_CONG_ADVANCED is not set
++CONFIG_TCP_CONG_CUBIC=y
++CONFIG_DEFAULT_TCP_CONG="cubic"
++# CONFIG_TCP_MD5SIG is not set
++# CONFIG_IP_VS is not set
++# CONFIG_IPV6 is not set
++# CONFIG_INET6_XFRM_TUNNEL is not set
++# CONFIG_INET6_TUNNEL is not set
++# CONFIG_NETLABEL is not set
++# CONFIG_NETWORK_SECMARK is not set
++CONFIG_NETFILTER=y
++# CONFIG_NETFILTER_DEBUG is not set
++
++#
++# Core Netfilter Configuration
++#
++# CONFIG_NETFILTER_NETLINK is not set
++# CONFIG_NF_CONNTRACK_ENABLED is not set
++# CONFIG_NF_CONNTRACK is not set
++# CONFIG_NETFILTER_XTABLES is not set
++
++#
++# IP: Netfilter Configuration
++#
++# CONFIG_IP_NF_QUEUE is not set
++# CONFIG_IP_NF_IPTABLES is not set
++# CONFIG_IP_NF_ARPTABLES is not set
++# CONFIG_IP_DCCP is not set
++# CONFIG_IP_SCTP is not set
++# CONFIG_TIPC is not set
++# CONFIG_ATM is not set
++# CONFIG_BRIDGE is not set
++# CONFIG_VLAN_8021Q is not set
++# CONFIG_DECNET is not set
++# CONFIG_LLC2 is not set
++# CONFIG_IPX is not set
++# CONFIG_ATALK is not set
++# CONFIG_X25 is not set
++# CONFIG_LAPB is not set
++# CONFIG_ECONET is not set
++# CONFIG_WAN_ROUTER is not set
++# CONFIG_NET_SCHED is not set
++
++#
++# Network testing
++#
++# CONFIG_NET_PKTGEN is not set
++# CONFIG_HAMRADIO is not set
++# CONFIG_IRDA is not set
++# CONFIG_BT is not set
++# CONFIG_AF_RXRPC is not set
++
++#
++# Wireless
++#
++# CONFIG_CFG80211 is not set
++CONFIG_WIRELESS_EXT=y
++# CONFIG_MAC80211 is not set
++# CONFIG_IEEE80211 is not set
++# CONFIG_RFKILL is not set
++# CONFIG_NET_9P is not set
++
++#
++# Device Drivers
++#
++
++#
++# Generic Driver Options
++#
++CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
++CONFIG_STANDALONE=y
++CONFIG_PREVENT_FIRMWARE_BUILD=y
++CONFIG_FW_LOADER=y
++# CONFIG_SYS_HYPERVISOR is not set
++# CONFIG_CONNECTOR is not set
++# CONFIG_MTD is not set
++# CONFIG_PARPORT is not set
++CONFIG_BLK_DEV=y
++# CONFIG_BLK_CPQ_DA is not set
++# CONFIG_BLK_CPQ_CISS_DA is not set
++# CONFIG_BLK_DEV_DAC960 is not set
++# CONFIG_BLK_DEV_UMEM is not set
++# CONFIG_BLK_DEV_COW_COMMON is not set
++CONFIG_BLK_DEV_LOOP=y
++# CONFIG_BLK_DEV_CRYPTOLOOP is not set
++# CONFIG_BLK_DEV_NBD is not set
++# CONFIG_BLK_DEV_SX8 is not set
++# CONFIG_BLK_DEV_UB is not set
++CONFIG_BLK_DEV_RAM=y
++CONFIG_BLK_DEV_RAM_COUNT=16
++CONFIG_BLK_DEV_RAM_SIZE=10240
++CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024
++# CONFIG_CDROM_PKTCDVD is not set
++# CONFIG_ATA_OVER_ETH is not set
++# CONFIG_MISC_DEVICES is not set
++# CONFIG_IDE is not set
++
++#
++# SCSI device support
++#
++# CONFIG_RAID_ATTRS is not set
++CONFIG_SCSI=y
++CONFIG_SCSI_DMA=y
++# CONFIG_SCSI_TGT is not set
++# CONFIG_SCSI_NETLINK is not set
++CONFIG_SCSI_PROC_FS=y
++
++#
++# SCSI support type (disk, tape, CD-ROM)
++#
++CONFIG_BLK_DEV_SD=y
++# CONFIG_CHR_DEV_ST is not set
++# CONFIG_CHR_DEV_OSST is not set
++# CONFIG_BLK_DEV_SR is not set
++# CONFIG_CHR_DEV_SG is not set
++# CONFIG_CHR_DEV_SCH is not set
++
++#
++# Some SCSI devices (e.g. CD jukebox) support multiple LUNs
++#
++CONFIG_SCSI_MULTI_LUN=y
++# CONFIG_SCSI_CONSTANTS is not set
++# CONFIG_SCSI_LOGGING is not set
++# CONFIG_SCSI_SCAN_ASYNC is not set
++CONFIG_SCSI_WAIT_SCAN=m
++
++#
++# SCSI Transports
++#
++# CONFIG_SCSI_SPI_ATTRS is not set
++# CONFIG_SCSI_FC_ATTRS is not set
++# CONFIG_SCSI_ISCSI_ATTRS is not set
++# CONFIG_SCSI_SAS_LIBSAS is not set
++# CONFIG_SCSI_SRP_ATTRS is not set
++CONFIG_SCSI_LOWLEVEL=y
++# CONFIG_ISCSI_TCP is not set
++# CONFIG_BLK_DEV_3W_XXXX_RAID is not set
++# CONFIG_SCSI_3W_9XXX is not set
++# CONFIG_SCSI_ACARD is not set
++# CONFIG_SCSI_AACRAID is not set
++# CONFIG_SCSI_AIC7XXX is not set
++# CONFIG_SCSI_AIC7XXX_OLD is not set
++# CONFIG_SCSI_AIC79XX is not set
++# CONFIG_SCSI_AIC94XX is not set
++# CONFIG_SCSI_DPT_I2O is not set
++# CONFIG_SCSI_ADVANSYS is not set
++# CONFIG_SCSI_ARCMSR is not set
++# CONFIG_MEGARAID_NEWGEN is not set
++# CONFIG_MEGARAID_LEGACY is not set
++# CONFIG_MEGARAID_SAS is not set
++# CONFIG_SCSI_HPTIOP is not set
++# CONFIG_SCSI_DMX3191D is not set
++# CONFIG_SCSI_FUTURE_DOMAIN is not set
++# CONFIG_SCSI_IPS is not set
++# CONFIG_SCSI_INITIO is not set
++# CONFIG_SCSI_INIA100 is not set
++# CONFIG_SCSI_STEX is not set
++# CONFIG_SCSI_SYM53C8XX_2 is not set
++# CONFIG_SCSI_IPR is not set
++# CONFIG_SCSI_QLOGIC_1280 is not set
++# CONFIG_SCSI_QLA_FC is not set
++# CONFIG_SCSI_QLA_ISCSI is not set
++# CONFIG_SCSI_LPFC is not set
++# CONFIG_SCSI_DC395x is not set
++# CONFIG_SCSI_DC390T is not set
++# CONFIG_SCSI_NSP32 is not set
++# CONFIG_SCSI_DEBUG is not set
++# CONFIG_SCSI_SRP is not set
++CONFIG_ATA=y
++# CONFIG_ATA_NONSTANDARD is not set
++# CONFIG_SATA_AHCI is not set
++# CONFIG_SATA_SVW is not set
++# CONFIG_ATA_PIIX is not set
++# CONFIG_SATA_MV is not set
++# CONFIG_SATA_NV is not set
++# CONFIG_PDC_ADMA is not set
++# CONFIG_SATA_QSTOR is not set
++# CONFIG_SATA_PROMISE is not set
++# CONFIG_SATA_SX4 is not set
++# CONFIG_SATA_SIL is not set
++# CONFIG_SATA_SIL24 is not set
++# CONFIG_SATA_SIS is not set
++# CONFIG_SATA_ULI is not set
++# CONFIG_SATA_VIA is not set
++# CONFIG_SATA_VITESSE is not set
++# CONFIG_SATA_INIC162X is not set
++CONFIG_SATA_OX810=y
++# CONFIG_SATA_HIPOX_SINGLE_SATA is not set
++# CONFIG_SATA_HIPOX_DISK_LIGHT is not set
++# CONFIG_PATA_ALI is not set
++# CONFIG_PATA_AMD is not set
++# CONFIG_PATA_ARTOP is not set
++# CONFIG_PATA_ATIIXP is not set
++# CONFIG_PATA_CMD640_PCI is not set
++# CONFIG_PATA_CMD64X is not set
++# CONFIG_PATA_CS5520 is not set
++# CONFIG_PATA_CS5530 is not set
++# CONFIG_PATA_CYPRESS is not set
++# CONFIG_PATA_EFAR is not set
++# CONFIG_ATA_GENERIC is not set
++# CONFIG_PATA_HPT366 is not set
++# CONFIG_PATA_HPT37X is not set
++# CONFIG_PATA_HPT3X2N is not set
++# CONFIG_PATA_HPT3X3 is not set
++# CONFIG_PATA_IT821X is not set
++# CONFIG_PATA_IT8213 is not set
++# CONFIG_PATA_JMICRON is not set
++# CONFIG_PATA_TRIFLEX is not set
++# CONFIG_PATA_MARVELL is not set
++# CONFIG_PATA_MPIIX is not set
++# CONFIG_PATA_OLDPIIX is not set
++# CONFIG_PATA_NETCELL is not set
++# CONFIG_PATA_NS87410 is not set
++# CONFIG_PATA_NS87415 is not set
++# CONFIG_PATA_OPTI is not set
++# CONFIG_PATA_OPTIDMA is not set
++# CONFIG_PATA_PDC_OLD is not set
++# CONFIG_PATA_RADISYS is not set
++# CONFIG_PATA_RZ1000 is not set
++# CONFIG_PATA_SC1200 is not set
++# CONFIG_PATA_SERVERWORKS is not set
++# CONFIG_PATA_PDC2027X is not set
++# CONFIG_PATA_SIL680 is not set
++# CONFIG_PATA_SIS is not set
++# CONFIG_PATA_VIA is not set
++# CONFIG_PATA_WINBOND is not set
++CONFIG_MD=y
++CONFIG_BLK_DEV_MD=y
++CONFIG_MD_LINEAR=y
++# CONFIG_MD_RAID0 is not set
++CONFIG_MD_RAID1=y
++# CONFIG_MD_RAID10 is not set
++# CONFIG_MD_RAID456 is not set
++# CONFIG_MD_MULTIPATH is not set
++# CONFIG_MD_FAULTY is not set
++CONFIG_BLK_DEV_DM=y
++# CONFIG_DM_DEBUG is not set
++CONFIG_DM_CRYPT=y
++# CONFIG_DM_SNAPSHOT is not set
++# CONFIG_DM_MIRROR is not set
++# CONFIG_DM_ZERO is not set
++# CONFIG_DM_MULTIPATH is not set
++# CONFIG_DM_DELAY is not set
++# CONFIG_DM_UEVENT is not set
++# CONFIG_FUSION is not set
++
++#
++# IEEE 1394 (FireWire) support
++#
++# CONFIG_FIREWIRE is not set
++# CONFIG_IEEE1394 is not set
++# CONFIG_I2O is not set
++CONFIG_NETDEVICES=y
++# CONFIG_NETDEVICES_MULTIQUEUE is not set
++# CONFIG_DUMMY is not set
++# CONFIG_BONDING is not set
++# CONFIG_MACVLAN is not set
++# CONFIG_EQUALIZER is not set
++# CONFIG_TUN is not set
++# CONFIG_VETH is not set
++# CONFIG_ARCNET is not set
++# CONFIG_NET_ETHERNET is not set
++CONFIG_MII=y
++CONFIG_NETDEV_1000=y
++# CONFIG_ACENIC is not set
++# CONFIG_DL2K is not set
++# CONFIG_E1000 is not set
++# CONFIG_E1000E is not set
++# CONFIG_IP1000 is not set
++# CONFIG_NS83820 is not set
++# CONFIG_HAMACHI is not set
++# CONFIG_YELLOWFIN is not set
++# CONFIG_R8169 is not set
++# CONFIG_SIS190 is not set
++# CONFIG_SKGE is not set
++# CONFIG_SKY2 is not set
++# CONFIG_SK98LIN is not set
++# CONFIG_VIA_VELOCITY is not set
++# CONFIG_TIGON3 is not set
++# CONFIG_BNX2 is not set
++# CONFIG_QLA3XXX is not set
++# CONFIG_ATL1 is not set
++CONFIG_SYNOPSYS_GMAC=y
++# CONFIG_NETDEV_10000 is not set
++# CONFIG_TR is not set
++
++#
++# Wireless LAN
++#
++# CONFIG_WLAN_PRE80211 is not set
++# CONFIG_WLAN_80211 is not set
++
++#
++# USB Network Adapters
++#
++# CONFIG_USB_CATC is not set
++# CONFIG_USB_KAWETH is not set
++# CONFIG_USB_PEGASUS is not set
++# CONFIG_USB_RTL8150 is not set
++# CONFIG_USB_USBNET is not set
++# CONFIG_WAN is not set
++# CONFIG_FDDI is not set
++# CONFIG_HIPPI is not set
++# CONFIG_PPP is not set
++# CONFIG_SLIP is not set
++# CONFIG_NET_FC is not set
++# CONFIG_SHAPER is not set
++# CONFIG_NETCONSOLE is not set
++# CONFIG_NETPOLL is not set
++# CONFIG_NET_POLL_CONTROLLER is not set
++# CONFIG_ISDN is not set
++
++#
++# Input device support
++#
++CONFIG_INPUT=y
++# CONFIG_INPUT_FF_MEMLESS is not set
++# CONFIG_INPUT_POLLDEV is not set
++
++#
++# Userland interfaces
++#
++CONFIG_INPUT_MOUSEDEV=y
++# CONFIG_INPUT_MOUSEDEV_PSAUX is not set
++CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024
++CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
++# CONFIG_INPUT_JOYDEV is not set
++# CONFIG_INPUT_EVDEV is not set
++# CONFIG_INPUT_EVBUG is not set
++
++#
++# Input Device Drivers
++#
++# CONFIG_INPUT_KEYBOARD is not set
++# CONFIG_INPUT_MOUSE is not set
++# CONFIG_INPUT_JOYSTICK is not set
++# CONFIG_INPUT_TABLET is not set
++# CONFIG_INPUT_TOUCHSCREEN is not set
++# CONFIG_INPUT_MISC is not set
++
++#
++# Hardware I/O ports
++#
++# CONFIG_SERIO is not set
++# CONFIG_GAMEPORT is not set
++
++#
++# Character devices
++#
++CONFIG_VT=y
++CONFIG_VT_CONSOLE=y
++CONFIG_HW_CONSOLE=y
++# CONFIG_VT_HW_CONSOLE_BINDING is not set
++# CONFIG_SERIAL_NONSTANDARD is not set
++
++#
++# Serial drivers
++#
++CONFIG_SERIAL_8250=y
++CONFIG_SERIAL_8250_CONSOLE=y
++CONFIG_SERIAL_8250_PCI=y
++CONFIG_SERIAL_8250_NR_UARTS=4
++CONFIG_SERIAL_8250_RUNTIME_UARTS=4
++# CONFIG_SERIAL_8250_EXTENDED is not set
++
++#
++# Non-8250 serial port support
++#
++# CONFIG_SERIAL_AMBA_PL010 is not set
++# CONFIG_SERIAL_AMBA_PL011 is not set
++CONFIG_SERIAL_CORE=y
++CONFIG_SERIAL_CORE_CONSOLE=y
++# CONFIG_SERIAL_JSM is not set
++CONFIG_UNIX98_PTYS=y
++# CONFIG_LEGACY_PTYS is not set
++# CONFIG_IPMI_HANDLER is not set
++CONFIG_HW_RANDOM=m
++# CONFIG_NVRAM is not set
++# CONFIG_R3964 is not set
++# CONFIG_APPLICOM is not set
++# CONFIG_RAW_DRIVER is not set
++# CONFIG_TCG_TPM is not set
++CONFIG_DEVPORT=y
++CONFIG_I2C=m
++CONFIG_I2C_BOARDINFO=y
++# CONFIG_I2C_CHARDEV is not set
++
++#
++# I2C Algorithms
++#
++CONFIG_I2C_ALGOBIT=m
++# CONFIG_I2C_ALGOPCF is not set
++# CONFIG_I2C_ALGOPCA is not set
++# CONFIG_I2C_ALGOOXSEMI is not set
++
++#
++# I2C Hardware Bus support
++#
++# CONFIG_I2C_ALI1535 is not set
++# CONFIG_I2C_ALI1563 is not set
++# CONFIG_I2C_ALI15X3 is not set
++# CONFIG_I2C_AMD756 is not set
++# CONFIG_I2C_AMD8111 is not set
++# CONFIG_I2C_I801 is not set
++# CONFIG_I2C_I810 is not set
++# CONFIG_I2C_PIIX4 is not set
++# CONFIG_I2C_NFORCE2 is not set
++CONFIG_I2C_HIPOX_BITBASH=m
++# CONFIG_I2C_OCORES is not set
++# CONFIG_I2C_PARPORT_LIGHT is not set
++# CONFIG_I2C_PROSAVAGE is not set
++# CONFIG_I2C_SAVAGE4 is not set
++# CONFIG_I2C_SIMTEC is not set
++# CONFIG_I2C_SIS5595 is not set
++# CONFIG_I2C_SIS630 is not set
++# CONFIG_I2C_SIS96X is not set
++# CONFIG_I2C_TAOS_EVM is not set
++# CONFIG_I2C_STUB is not set
++# CONFIG_I2C_TINY_USB is not set
++# CONFIG_I2C_VIA is not set
++# CONFIG_I2C_VIAPRO is not set
++# CONFIG_I2C_VOODOO3 is not set
++
++#
++# Miscellaneous I2C Chip support
++#
++# CONFIG_SENSORS_DS1337 is not set
++# CONFIG_SENSORS_DS1374 is not set
++# CONFIG_DS1682 is not set
++# CONFIG_SENSORS_EEPROM is not set
++# CONFIG_SENSORS_PCF8574 is not set
++# CONFIG_SENSORS_PCA9539 is not set
++# CONFIG_SENSORS_PCF8591 is not set
++# CONFIG_SENSORS_MAX6875 is not set
++# CONFIG_SENSORS_TSL2550 is not set
++# CONFIG_I2C_DEBUG_CORE is not set
++# CONFIG_I2C_DEBUG_ALGO is not set
++# CONFIG_I2C_DEBUG_BUS is not set
++# CONFIG_I2C_DEBUG_CHIP is not set
++
++#
++# SPI support
++#
++# CONFIG_SPI is not set
++# CONFIG_SPI_MASTER is not set
++# CONFIG_W1 is not set
++# CONFIG_POWER_SUPPLY is not set
++# CONFIG_HWMON is not set
++# CONFIG_WATCHDOG is not set
++
++#
++# Sonics Silicon Backplane
++#
++CONFIG_SSB_POSSIBLE=y
++# CONFIG_SSB is not set
++
++#
++# Multifunction device drivers
++#
++# CONFIG_MFD_SM501 is not set
++
++#
++# Multimedia devices
++#
++# CONFIG_VIDEO_DEV is not set
++# CONFIG_DVB_CORE is not set
++CONFIG_DAB=y
++# CONFIG_USB_DABUSB is not set
++
++#
++# Graphics support
++#
++# CONFIG_DRM is not set
++# CONFIG_VGASTATE is not set
++CONFIG_VIDEO_OUTPUT_CONTROL=m
++# CONFIG_FB is not set
++# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
++
++#
++# Display device support
++#
++# CONFIG_DISPLAY_SUPPORT is not set
++
++#
++# Console display driver support
++#
++# CONFIG_VGA_CONSOLE is not set
++CONFIG_DUMMY_CONSOLE=y
++
++#
++# Sound
++#
++# CONFIG_SOUND is not set
++# CONFIG_HID_SUPPORT is not set
++CONFIG_USB_SUPPORT=y
++CONFIG_USB_ARCH_HAS_HCD=y
++CONFIG_USB_ARCH_HAS_OHCI=y
++CONFIG_USB_ARCH_HAS_EHCI=y
++CONFIG_USB=m
++# CONFIG_USB_DEBUG is not set
++
++#
++# Miscellaneous USB options
++#
++CONFIG_USB_DEVICEFS=y
++CONFIG_USB_DEVICE_CLASS=y
++# CONFIG_USB_DYNAMIC_MINORS is not set
++# CONFIG_USB_OTG is not set
++
++#
++# USB Host Controller Drivers
++#
++CONFIG_USB_EHCI_HCD=m
++# CONFIG_USB_EHCI_SPLIT_ISO is not set
++CONFIG_USB_EHCI_ROOT_HUB_TT=y
++# CONFIG_USB_EHCI_TT_NEWSCHED is not set
++# CONFIG_USB_ISP116X_HCD is not set
++# CONFIG_USB_OHCI_HCD is not set
++# CONFIG_USB_UHCI_HCD is not set
++# CONFIG_USB_SL811_HCD is not set
++# CONFIG_USB_R8A66597_HCD is not set
++
++#
++# USB Device Class drivers
++#
++# CONFIG_USB_ACM is not set
++# CONFIG_USB_PRINTER is not set
++
++#
++# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support'
++#
++
++#
++# may also be needed; see USB_STORAGE Help for more information
++#
++CONFIG_USB_STORAGE=m
++# CONFIG_USB_STORAGE_DEBUG is not set
++# CONFIG_USB_STORAGE_DATAFAB is not set
++# CONFIG_USB_STORAGE_FREECOM is not set
++# CONFIG_USB_STORAGE_ISD200 is not set
++# CONFIG_USB_STORAGE_DPCM is not set
++# CONFIG_USB_STORAGE_USBAT is not set
++# CONFIG_USB_STORAGE_SDDR09 is not set
++# CONFIG_USB_STORAGE_SDDR55 is not set
++# CONFIG_USB_STORAGE_JUMPSHOT is not set
++# CONFIG_USB_STORAGE_ALAUDA is not set
++# CONFIG_USB_STORAGE_KARMA is not set
++# CONFIG_USB_LIBUSUAL is not set
++
++#
++# USB Imaging devices
++#
++# CONFIG_USB_MDC800 is not set
++# CONFIG_USB_MICROTEK is not set
++# CONFIG_USB_MON is not set
++
++#
++# USB port drivers
++#
++
++#
++# USB Serial Converter support
++#
++# CONFIG_USB_SERIAL is not set
++
++#
++# USB Miscellaneous drivers
++#
++# CONFIG_USB_EMI62 is not set
++# CONFIG_USB_EMI26 is not set
++# CONFIG_USB_ADUTUX is not set
++# CONFIG_USB_AUERSWALD is not set
++# CONFIG_USB_RIO500 is not set
++# CONFIG_USB_LEGOTOWER is not set
++# CONFIG_USB_LCD is not set
++# CONFIG_USB_BERRY_CHARGE is not set
++# CONFIG_USB_LED is not set
++# CONFIG_USB_CYPRESS_CY7C63 is not set
++# CONFIG_USB_CYTHERM is not set
++# CONFIG_USB_PHIDGET is not set
++# CONFIG_USB_IDMOUSE is not set
++# CONFIG_USB_FTDI_ELAN is not set
++# CONFIG_USB_APPLEDISPLAY is not set
++# CONFIG_USB_SISUSBVGA is not set
++# CONFIG_USB_LD is not set
++# CONFIG_USB_TRANCEVIBRATOR is not set
++# CONFIG_USB_IOWARRIOR is not set
++CONFIG_USB_TEST=m
++
++#
++# USB DSL modem support
++#
++
++#
++# USB Gadget Support
++#
++# CONFIG_USB_GADGET is not set
++# CONFIG_MMC is not set
++# CONFIG_NEW_LEDS is not set
++CONFIG_RTC_LIB=y
++CONFIG_RTC_CLASS=m
++
++#
++# RTC interfaces
++#
++CONFIG_RTC_INTF_SYSFS=y
++CONFIG_RTC_INTF_PROC=y
++CONFIG_RTC_INTF_DEV=y
++# CONFIG_RTC_INTF_DEV_UIE_EMUL is not set
++# CONFIG_RTC_DRV_TEST is not set
++
++#
++# I2C RTC drivers
++#
++CONFIG_RTC_DRV_DS1307=m
++# CONFIG_RTC_DRV_DS1374 is not set
++# CONFIG_RTC_DRV_DS1672 is not set
++# CONFIG_RTC_DRV_MAX6900 is not set
++# CONFIG_RTC_DRV_RS5C372 is not set
++# CONFIG_RTC_DRV_ISL1208 is not set
++# CONFIG_RTC_DRV_X1205 is not set
++# CONFIG_RTC_DRV_PCF8563 is not set
++# CONFIG_RTC_DRV_PCF8583 is not set
++# CONFIG_RTC_DRV_M41T80 is not set
++
++#
++# SPI RTC drivers
++#
++
++#
++# Platform RTC drivers
++#
++# CONFIG_RTC_DRV_CMOS is not set
++# CONFIG_RTC_DRV_DS1553 is not set
++# CONFIG_RTC_DRV_STK17TA8 is not set
++# CONFIG_RTC_DRV_DS1742 is not set
++# CONFIG_RTC_DRV_M48T86 is not set
++# CONFIG_RTC_DRV_M48T59 is not set
++# CONFIG_RTC_DRV_V3020 is not set
++
++#
++# on-CPU RTC drivers
++#
++# CONFIG_RTC_DRV_PL031 is not set
++# CONFIG_DMADEVICES is not set
++
++#
++# File systems
++#
++CONFIG_EXT2_FS=y
++# CONFIG_EXT2_FS_XATTR is not set
++# CONFIG_EXT2_FS_XIP is not set
++CONFIG_EXT3_FS=y
++# CONFIG_EXT3_FS_XATTR is not set
++# CONFIG_EXT4DEV_FS is not set
++CONFIG_JBD=y
++# CONFIG_REISERFS_FS is not set
++# CONFIG_JFS_FS is not set
++CONFIG_FS_POSIX_ACL=y
++CONFIG_XFS_FS=y
++# CONFIG_XFS_QUOTA is not set
++# CONFIG_XFS_SECURITY is not set
++# CONFIG_XFS_POSIX_ACL is not set
++# CONFIG_XFS_RT is not set
++# CONFIG_GFS2_FS is not set
++# CONFIG_OCFS2_FS is not set
++# CONFIG_MINIX_FS is not set
++# CONFIG_ROMFS_FS is not set
++CONFIG_INOTIFY=y
++CONFIG_INOTIFY_USER=y
++# CONFIG_QUOTA is not set
++CONFIG_DNOTIFY=y
++# CONFIG_AUTOFS_FS is not set
++# CONFIG_AUTOFS4_FS is not set
++CONFIG_FUSE_FS=y
++
++#
++# CD-ROM/DVD Filesystems
++#
++# CONFIG_ISO9660_FS is not set
++# CONFIG_UDF_FS is not set
++
++#
++# DOS/FAT/NT Filesystems
++#
++CONFIG_FAT_FS=y
++CONFIG_MSDOS_FS=y
++CONFIG_VFAT_FS=m
++CONFIG_FAT_DEFAULT_CODEPAGE=437
++CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1"
++CONFIG_NTFS_FS=m
++# CONFIG_NTFS_DEBUG is not set
++# CONFIG_NTFS_RW is not set
++
++#
++# Pseudo filesystems
++#
++CONFIG_PROC_FS=y
++CONFIG_PROC_SYSCTL=y
++CONFIG_SYSFS=y
++# CONFIG_TMPFS is not set
++# CONFIG_HUGETLB_PAGE is not set
++# CONFIG_CONFIGFS_FS is not set
++
++#
++# Miscellaneous filesystems
++#
++# CONFIG_ADFS_FS is not set
++# CONFIG_AFFS_FS is not set
++# CONFIG_HFS_FS is not set
++CONFIG_HFSPLUS_FS=m
++# CONFIG_BEFS_FS is not set
++# CONFIG_BFS_FS is not set
++# CONFIG_EFS_FS is not set
++# CONFIG_CRAMFS is not set
++# CONFIG_VXFS_FS is not set
++# CONFIG_HPFS_FS is not set
++# CONFIG_QNX4FS_FS is not set
++# CONFIG_SYSV_FS is not set
++# CONFIG_UFS_FS is not set
++CONFIG_NETWORK_FILESYSTEMS=y
++# CONFIG_NFS_FS is not set
++CONFIG_NFSD=m
++CONFIG_NFSD_V2_ACL=y
++CONFIG_NFSD_V3=y
++CONFIG_NFSD_V3_ACL=y
++# CONFIG_NFSD_V4 is not set
++CONFIG_NFSD_TCP=y
++CONFIG_LOCKD=m
++CONFIG_LOCKD_V4=y
++CONFIG_EXPORTFS=m
++CONFIG_NFS_ACL_SUPPORT=m
++CONFIG_NFS_COMMON=y
++CONFIG_SUNRPC=m
++# CONFIG_SUNRPC_BIND34 is not set
++# CONFIG_RPCSEC_GSS_KRB5 is not set
++# CONFIG_RPCSEC_GSS_SPKM3 is not set
++# CONFIG_SMB_FS is not set
++# CONFIG_CIFS is not set
++# CONFIG_NCP_FS is not set
++# CONFIG_CODA_FS is not set
++# CONFIG_AFS_FS is not set
++
++#
++# Partition Types
++#
++CONFIG_PARTITION_ADVANCED=y
++# CONFIG_ACORN_PARTITION is not set
++# CONFIG_OSF_PARTITION is not set
++# CONFIG_AMIGA_PARTITION is not set
++# CONFIG_ATARI_PARTITION is not set
++CONFIG_MAC_PARTITION=y
++CONFIG_MSDOS_PARTITION=y
++# CONFIG_BSD_DISKLABEL is not set
++# CONFIG_MINIX_SUBPARTITION is not set
++# CONFIG_SOLARIS_X86_PARTITION is not set
++# CONFIG_UNIXWARE_DISKLABEL is not set
++CONFIG_LDM_PARTITION=y
++# CONFIG_LDM_DEBUG is not set
++# CONFIG_SGI_PARTITION is not set
++# CONFIG_ULTRIX_PARTITION is not set
++# CONFIG_SUN_PARTITION is not set
++# CONFIG_KARMA_PARTITION is not set
++CONFIG_EFI_PARTITION=y
++# CONFIG_SYSV68_PARTITION is not set
++CONFIG_NLS=y
++CONFIG_NLS_DEFAULT="iso8859-1"
++CONFIG_NLS_CODEPAGE_437=m
++# CONFIG_NLS_CODEPAGE_737 is not set
++# CONFIG_NLS_CODEPAGE_775 is not set
++# CONFIG_NLS_CODEPAGE_850 is not set
++# CONFIG_NLS_CODEPAGE_852 is not set
++# CONFIG_NLS_CODEPAGE_855 is not set
++# CONFIG_NLS_CODEPAGE_857 is not set
++# CONFIG_NLS_CODEPAGE_860 is not set
++# CONFIG_NLS_CODEPAGE_861 is not set
++# CONFIG_NLS_CODEPAGE_862 is not set
++# CONFIG_NLS_CODEPAGE_863 is not set
++# CONFIG_NLS_CODEPAGE_864 is not set
++# CONFIG_NLS_CODEPAGE_865 is not set
++# CONFIG_NLS_CODEPAGE_866 is not set
++# CONFIG_NLS_CODEPAGE_869 is not set
++# CONFIG_NLS_CODEPAGE_936 is not set
++# CONFIG_NLS_CODEPAGE_950 is not set
++# CONFIG_NLS_CODEPAGE_932 is not set
++# CONFIG_NLS_CODEPAGE_949 is not set
++# CONFIG_NLS_CODEPAGE_874 is not set
++# CONFIG_NLS_ISO8859_8 is not set
++# CONFIG_NLS_CODEPAGE_1250 is not set
++# CONFIG_NLS_CODEPAGE_1251 is not set
++# CONFIG_NLS_ASCII is not set
++CONFIG_NLS_ISO8859_1=m
++# CONFIG_NLS_ISO8859_2 is not set
++# CONFIG_NLS_ISO8859_3 is not set
++# CONFIG_NLS_ISO8859_4 is not set
++# CONFIG_NLS_ISO8859_5 is not set
++# CONFIG_NLS_ISO8859_6 is not set
++# CONFIG_NLS_ISO8859_7 is not set
++# CONFIG_NLS_ISO8859_9 is not set
++# CONFIG_NLS_ISO8859_13 is not set
++# CONFIG_NLS_ISO8859_14 is not set
++# CONFIG_NLS_ISO8859_15 is not set
++# CONFIG_NLS_KOI8_R is not set
++# CONFIG_NLS_KOI8_U is not set
++CONFIG_NLS_UTF8=y
++# CONFIG_DLM is not set
++# CONFIG_INSTRUMENTATION is not set
++
++#
++# Kernel hacking
++#
++# CONFIG_PRINTK_TIME is not set
++CONFIG_ENABLE_WARN_DEPRECATED=y
++CONFIG_ENABLE_MUST_CHECK=y
++# CONFIG_MAGIC_SYSRQ is not set
++# CONFIG_UNUSED_SYMBOLS is not set
++# CONFIG_DEBUG_FS is not set
++# CONFIG_HEADERS_CHECK is not set
++# CONFIG_DEBUG_KERNEL is not set
++CONFIG_DEBUG_BUGVERBOSE=y
++CONFIG_FRAME_POINTER=y
++# CONFIG_SAMPLES is not set
++# CONFIG_DEBUG_USER is not set
++
++#
++# Security options
++#
++# CONFIG_KEYS is not set
++CONFIG_SECURITY=y
++# CONFIG_SECURITY_NETWORK is not set
++# CONFIG_SECURITY_CAPABILITIES is not set
++CONFIG_SECURITY_TRUSTEES=y
++# CONFIG_SECURITY_TRUSTEES_DEBUG is not set
++CONFIG_CRYPTO=y
++CONFIG_CRYPTO_ALGAPI=y
++CONFIG_CRYPTO_BLKCIPHER=y
++CONFIG_CRYPTO_MANAGER=y
++# CONFIG_CRYPTO_HMAC is not set
++# CONFIG_CRYPTO_XCBC is not set
++# CONFIG_CRYPTO_NULL is not set
++# CONFIG_CRYPTO_MD4 is not set
++# CONFIG_CRYPTO_MD5 is not set
++# CONFIG_CRYPTO_SHA1 is not set
++# CONFIG_CRYPTO_SHA256 is not set
++# CONFIG_CRYPTO_SHA512 is not set
++# CONFIG_CRYPTO_WP512 is not set
++# CONFIG_CRYPTO_TGR192 is not set
++# CONFIG_CRYPTO_GF128MUL is not set
++CONFIG_CRYPTO_ECB=m
++CONFIG_CRYPTO_CBC=y
++CONFIG_CRYPTO_PCBC=m
++# CONFIG_CRYPTO_LRW is not set
++# CONFIG_CRYPTO_XTS is not set
++# CONFIG_CRYPTO_CRYPTD is not set
++# CONFIG_CRYPTO_DES is not set
++# CONFIG_CRYPTO_FCRYPT is not set
++# CONFIG_CRYPTO_BLOWFISH is not set
++# CONFIG_CRYPTO_TWOFISH is not set
++# CONFIG_CRYPTO_SERPENT is not set
++CONFIG_CRYPTO_AES=m
++# CONFIG_CRYPTO_CAST5 is not set
++# CONFIG_CRYPTO_CAST6 is not set
++# CONFIG_CRYPTO_TEA is not set
++CONFIG_CRYPTO_ARC4=m
++# CONFIG_CRYPTO_KHAZAD is not set
++# CONFIG_CRYPTO_ANUBIS is not set
++# CONFIG_CRYPTO_SEED is not set
++# CONFIG_CRYPTO_DEFLATE is not set
++CONFIG_CRYPTO_MICHAEL_MIC=m
++# CONFIG_CRYPTO_CRC32C is not set
++# CONFIG_CRYPTO_CAMELLIA is not set
++# CONFIG_CRYPTO_TEST is not set
++# CONFIG_CRYPTO_AUTHENC is not set
++CONFIG_CRYPTO_HW=y
++
++#
++# Library routines
++#
++CONFIG_BITREVERSE=y
++CONFIG_CRC_CCITT=y
++# CONFIG_CRC16 is not set
++# CONFIG_CRC_ITU_T is not set
++CONFIG_CRC32=y
++# CONFIG_CRC7 is not set
++# CONFIG_LIBCRC32C is not set
++CONFIG_PLIST=y
++CONFIG_HAS_IOMEM=y
++CONFIG_HAS_IOPORT=y
++CONFIG_HAS_DMA=y
+diff -Nurd linux-2.6.24/arch/arm/configs/hipox_810_eabi_upgrade_defconfig linux-2.6.24-oxe810/arch/arm/configs/hipox_810_eabi_upgrade_defconfig
+--- linux-2.6.24/arch/arm/configs/hipox_810_eabi_upgrade_defconfig 1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.24-oxe810/arch/arm/configs/hipox_810_eabi_upgrade_defconfig 2008-06-11 17:47:52.000000000 +0200
+@@ -0,0 +1,901 @@
++#
++# Automatically generated make config: don't edit
++# Linux kernel version: 2.6.24.4
++# Thu May 15 10:43:48 2008
++#
++CONFIG_ARM=y
++CONFIG_SYS_SUPPORTS_APM_EMULATION=y
++# CONFIG_GENERIC_GPIO is not set
++# CONFIG_GENERIC_TIME is not set
++# CONFIG_GENERIC_CLOCKEVENTS is not set
++CONFIG_MMU=y
++# CONFIG_NO_IOPORT is not set
++CONFIG_GENERIC_HARDIRQS=y
++CONFIG_STACKTRACE_SUPPORT=y
++CONFIG_LOCKDEP_SUPPORT=y
++CONFIG_TRACE_IRQFLAGS_SUPPORT=y
++CONFIG_HARDIRQS_SW_RESEND=y
++CONFIG_GENERIC_IRQ_PROBE=y
++CONFIG_RWSEM_GENERIC_SPINLOCK=y
++# CONFIG_ARCH_HAS_ILOG2_U32 is not set
++# CONFIG_ARCH_HAS_ILOG2_U64 is not set
++CONFIG_GENERIC_HWEIGHT=y
++CONFIG_GENERIC_CALIBRATE_DELAY=y
++CONFIG_ZONE_DMA=y
++CONFIG_VECTORS_BASE=0xffff0000
++CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
++
++#
++# General setup
++#
++CONFIG_EXPERIMENTAL=y
++CONFIG_BROKEN_ON_SMP=y
++CONFIG_INIT_ENV_ARG_LIMIT=32
++CONFIG_LOCALVERSION=""
++CONFIG_LOCALVERSION_AUTO=y
++CONFIG_SWAP=y
++CONFIG_SYSVIPC=y
++CONFIG_SYSVIPC_SYSCTL=y
++# CONFIG_BSD_PROCESS_ACCT is not set
++# CONFIG_USER_NS is not set
++# CONFIG_PID_NS is not set
++# CONFIG_IKCONFIG is not set
++CONFIG_LOG_BUF_SHIFT=14
++# CONFIG_CGROUPS is not set
++CONFIG_FAIR_GROUP_SCHED=y
++CONFIG_FAIR_USER_SCHED=y
++# CONFIG_FAIR_CGROUP_SCHED is not set
++CONFIG_SYSFS_DEPRECATED=y
++# CONFIG_RELAY is not set
++CONFIG_BLK_DEV_INITRD=y
++CONFIG_INITRAMFS_SOURCE=""
++# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
++CONFIG_SYSCTL=y
++# CONFIG_EMBEDDED is not set
++CONFIG_UID16=y
++CONFIG_SYSCTL_SYSCALL=y
++CONFIG_KALLSYMS=y
++# CONFIG_KALLSYMS_EXTRA_PASS is not set
++CONFIG_HOTPLUG=y
++CONFIG_PRINTK=y
++CONFIG_BUG=y
++CONFIG_ELF_CORE=y
++CONFIG_BASE_FULL=y
++CONFIG_FUTEX=y
++CONFIG_ANON_INODES=y
++CONFIG_EPOLL=y
++CONFIG_SIGNALFD=y
++CONFIG_EVENTFD=y
++CONFIG_SHMEM=y
++CONFIG_VM_EVENT_COUNTERS=y
++CONFIG_SLAB=y
++# CONFIG_SLUB is not set
++# CONFIG_SLOB is not set
++CONFIG_SLABINFO=y
++CONFIG_RT_MUTEXES=y
++# CONFIG_TINY_SHMEM is not set
++CONFIG_BASE_SMALL=0
++# CONFIG_MODULES is not set
++CONFIG_BLOCK=y
++# CONFIG_LBD is not set
++# CONFIG_BLK_DEV_IO_TRACE is not set
++# CONFIG_LSF is not set
++# CONFIG_BLK_DEV_BSG is not set
++
++#
++# IO Schedulers
++#
++CONFIG_IOSCHED_NOOP=y
++CONFIG_IOSCHED_AS=y
++CONFIG_IOSCHED_DEADLINE=y
++CONFIG_IOSCHED_CFQ=y
++CONFIG_DEFAULT_AS=y
++# CONFIG_DEFAULT_DEADLINE is not set
++# CONFIG_DEFAULT_CFQ is not set
++# CONFIG_DEFAULT_NOOP is not set
++CONFIG_DEFAULT_IOSCHED="anticipatory"
++
++#
++# System Type
++#
++# CONFIG_ARCH_AAEC2000 is not set
++# CONFIG_ARCH_INTEGRATOR is not set
++# CONFIG_ARCH_REALVIEW is not set
++# CONFIG_ARCH_VERSATILE is not set
++# CONFIG_ARCH_AT91 is not set
++# CONFIG_ARCH_CLPS7500 is not set
++# CONFIG_ARCH_CLPS711X is not set
++# CONFIG_ARCH_CO285 is not set
++# CONFIG_ARCH_EBSA110 is not set
++# CONFIG_ARCH_EP93XX is not set
++# CONFIG_ARCH_FOOTBRIDGE is not set
++# CONFIG_ARCH_NETX is not set
++# CONFIG_ARCH_H720X is not set
++# CONFIG_ARCH_IMX is not set
++# CONFIG_ARCH_IOP13XX is not set
++# CONFIG_ARCH_IOP32X is not set
++# CONFIG_ARCH_IOP33X is not set
++# CONFIG_ARCH_IXP23XX is not set
++# CONFIG_ARCH_IXP2000 is not set
++# CONFIG_ARCH_IXP4XX is not set
++# CONFIG_ARCH_L7200 is not set
++# CONFIG_ARCH_KS8695 is not set
++# CONFIG_ARCH_NS9XXX is not set
++# CONFIG_ARCH_MXC is not set
++# CONFIG_ARCH_PNX4008 is not set
++# CONFIG_ARCH_PXA is not set
++# CONFIG_ARCH_RPC is not set
++# CONFIG_ARCH_SA1100 is not set
++# CONFIG_ARCH_S3C2410 is not set
++# CONFIG_ARCH_SHARK is not set
++# CONFIG_ARCH_LH7A40X is not set
++# CONFIG_ARCH_DAVINCI is not set
++# CONFIG_ARCH_OMAP is not set
++CONFIG_ARCH_HIPOX=y
++
++#
++# Boot options
++#
++
++#
++# Power management
++#
++
++#
++# Oxford Semiconductor NAS Options
++#
++# CONFIG_ARCH_HIPOX_FPGA is not set
++CONFIG_NOMINAL_PLL400_FREQ=733333333
++CONFIG_NOMINAL_RPSCLK_FREQ=25000000
++# CONFIG_HIPOX_VERSION_0X800 is not set
++CONFIG_HIPOX_VERSION_0X810=y
++# CONFIG_HIPOX_VERSION_0X850 is not set
++# CONFIG_ARCH_HIPOX_UART1 is not set
++CONFIG_ARCH_HIPOX_UART2=y
++# CONFIG_ARCH_HIPOX_UART2_MODEM is not set
++# CONFIG_ARCH_HIPOX_UART3 is not set
++# CONFIG_ARCH_HIPOX_PCI_REQGNT_0 is not set
++# CONFIG_ARCH_HIPOX_PCI_REQGNT_1 is not set
++# CONFIG_ARCH_HIPOX_PCI_REQGNT_2 is not set
++# CONFIG_ARCH_HIPOX_PCI_REQGNT_3 is not set
++# CONFIG_ARCH_HIPOX_PCI_CLKOUT_0 is not set
++# CONFIG_ARCH_HIPOX_PCI_CLKOUT_1 is not set
++# CONFIG_ARCH_HIPOX_PCI_CLKOUT_2 is not set
++# CONFIG_ARCH_HIPOX_PCI_CLKOUT_3 is not set
++# CONFIG_HIPOX_PCI_RESET is not set
++CONFIG_FORCE_MAX_ZONEORDER=10
++CONFIG_SRAM_NUM_PAGES=32
++CONFIG_SUPPORT_LEON=y
++CONFIG_LEON_PAGES=2
++# CONFIG_LEON_COPRO is not set
++# CONFIG_LEON_START_EARLY is not set
++CONFIG_LEON_POWER_BUTTON_MONITOR=y
++CONFIG_HIPOX_POWER_BUTTON_GPIO=4
++CONFIG_USER_RECOVERY_BUTTON_MONITOR=y
++CONFIG_HIPOX_USER_RECOVERY_BUTTON_GPIO=32
++# CONFIG_HIPOX_DDR_MON is not set
++# CONFIG_HIPOX_AHB_MON is not set
++# CONFIG_HIPOX_CACHE_LOCKDOWN is not set
++# CONFIG_DO_MEM_TEST is not set
++# CONFIG_CRYPTO_OXAESLRW is not set
++CONFIG_DESCRIPTORS_PAGES=6
++CONFIG_ARCH_HIPOX_NUM_GMAC_DESCRIPTORS=192
++CONFIG_ARCH_HIPOX_MAX_SATA_SG_ENTRIES=256
++# CONFIG_TACHO_THERM_AND_FAN is not set
++# CONFIG_GPIO_TEST is not set
++# CONFIG_HIPOX_RTC is not set
++# CONFIG_I2S is not set
++# CONFIG_DPE_TEST is not set
++# CONFIG_HIPOX_INSTRUMENT_COPIES is not set
++# CONFIG_HIPOX_DMA_COPIES is not set
++# CONFIG_HIPOX_AHB_MONITOR_MODULE is not set
++# CONFIG_HIPOX_USB_TEST_MODES is not set
++# CONFIG_LEDS_TRIGGER_SATA_DISK is not set
++# CONFIG_HIPOX_LED_TEST is not set
++CONFIG_HIPOX_I2C_SDA=6
++CONFIG_HIPOX_I2C_SCL=7
++# CONFIG_HIPOX_USB_PORTA_POWER_CONTROL is not set
++# CONFIG_HIPOX_USB_PORTB_POWER_CONTROL is not set
++# CONFIG_HIPOX_USB_PORTC_POWER_CONTROL is not set
++# CONFIG_HIPOX_USB_OVERCURRENT_POLARITY_NEGATIVE is not set
++# CONFIG_HIPOX_USB_POWER_SWITCH_POLARITY_NEGATIVE is not set
++# CONFIG_WDC_FAN_HIPOX800 is not set
++# CONFIG_HIPOX_MAP_SRAM is not set
++# CONFIG_HIPOX_SUID_INHERIT is not set
++
++#
++# Processor Type
++#
++CONFIG_CPU_32=y
++CONFIG_CPU_ARM926T=y
++CONFIG_CPU_32v5=y
++CONFIG_CPU_ABRT_EV5TJ=y
++CONFIG_CPU_CACHE_VIVT=y
++CONFIG_CPU_COPY_V4WB=y
++CONFIG_CPU_TLB_V4WBI=y
++CONFIG_CPU_CP15=y
++CONFIG_CPU_CP15_MMU=y
++
++#
++# Processor Features
++#
++CONFIG_ARM_THUMB=y
++# CONFIG_CPU_ICACHE_DISABLE is not set
++# CONFIG_CPU_DCACHE_DISABLE is not set
++# CONFIG_CPU_DCACHE_WRITETHROUGH is not set
++# CONFIG_CPU_CACHE_ROUND_ROBIN is not set
++# CONFIG_OUTER_CACHE is not set
++
++#
++# Bus support
++#
++CONFIG_ARM_AMBA=y
++CONFIG_PCI=y
++CONFIG_PCI_SYSCALL=y
++# CONFIG_ARCH_SUPPORTS_MSI is not set
++CONFIG_PCI_LEGACY=y
++# CONFIG_PCCARD is not set
++
++#
++# Kernel Features
++#
++# CONFIG_TICK_ONESHOT is not set
++# CONFIG_PREEMPT is not set
++# CONFIG_NO_IDLE_HZ is not set
++CONFIG_HZ=100
++CONFIG_AEABI=y
++# CONFIG_OABI_COMPAT is not set
++# CONFIG_ARCH_DISCONTIGMEM_ENABLE is not set
++CONFIG_SELECT_MEMORY_MODEL=y
++CONFIG_FLATMEM_MANUAL=y
++# CONFIG_DISCONTIGMEM_MANUAL is not set
++# CONFIG_SPARSEMEM_MANUAL is not set
++CONFIG_FLATMEM=y
++CONFIG_FLAT_NODE_MEM_MAP=y
++# CONFIG_SPARSEMEM_STATIC is not set
++# CONFIG_SPARSEMEM_VMEMMAP_ENABLE is not set
++CONFIG_SPLIT_PTLOCK_CPUS=4096
++# CONFIG_RESOURCES_64BIT is not set
++CONFIG_ZONE_DMA_FLAG=1
++CONFIG_BOUNCE=y
++CONFIG_VIRT_TO_BUS=y
++CONFIG_ALIGNMENT_TRAP=y
++
++#
++# Boot options
++#
++CONFIG_ZBOOT_ROM_TEXT=0x0
++CONFIG_ZBOOT_ROM_BSS=0x0
++CONFIG_CMDLINE=""
++# CONFIG_XIP_KERNEL is not set
++# CONFIG_KEXEC is not set
++
++#
++# Floating point emulation
++#
++
++#
++# At least one emulation must be selected
++#
++CONFIG_VFP=y
++
++#
++# Userspace binary formats
++#
++CONFIG_BINFMT_ELF=y
++# CONFIG_BINFMT_AOUT is not set
++# CONFIG_BINFMT_MISC is not set
++
++#
++# Power management options
++#
++# CONFIG_PM is not set
++CONFIG_SUSPEND_UP_POSSIBLE=y
++
++#
++# Networking
++#
++# CONFIG_NET is not set
++
++#
++# Device Drivers
++#
++
++#
++# Generic Driver Options
++#
++CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
++CONFIG_STANDALONE=y
++CONFIG_PREVENT_FIRMWARE_BUILD=y
++# CONFIG_FW_LOADER is not set
++# CONFIG_SYS_HYPERVISOR is not set
++# CONFIG_MTD is not set
++# CONFIG_PARPORT is not set
++CONFIG_BLK_DEV=y
++# CONFIG_BLK_CPQ_DA is not set
++# CONFIG_BLK_CPQ_CISS_DA is not set
++# CONFIG_BLK_DEV_DAC960 is not set
++# CONFIG_BLK_DEV_UMEM is not set
++# CONFIG_BLK_DEV_COW_COMMON is not set
++CONFIG_BLK_DEV_LOOP=y
++# CONFIG_BLK_DEV_CRYPTOLOOP is not set
++# CONFIG_BLK_DEV_SX8 is not set
++CONFIG_BLK_DEV_RAM=y
++CONFIG_BLK_DEV_RAM_COUNT=1
++CONFIG_BLK_DEV_RAM_SIZE=10240
++CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024
++# CONFIG_CDROM_PKTCDVD is not set
++# CONFIG_MISC_DEVICES is not set
++# CONFIG_IDE is not set
++
++#
++# SCSI device support
++#
++# CONFIG_RAID_ATTRS is not set
++CONFIG_SCSI=y
++CONFIG_SCSI_DMA=y
++# CONFIG_SCSI_TGT is not set
++# CONFIG_SCSI_NETLINK is not set
++CONFIG_SCSI_PROC_FS=y
++
++#
++# SCSI support type (disk, tape, CD-ROM)
++#
++CONFIG_BLK_DEV_SD=y
++# CONFIG_CHR_DEV_ST is not set
++# CONFIG_CHR_DEV_OSST is not set
++# CONFIG_BLK_DEV_SR is not set
++# CONFIG_CHR_DEV_SG is not set
++# CONFIG_CHR_DEV_SCH is not set
++
++#
++# Some SCSI devices (e.g. CD jukebox) support multiple LUNs
++#
++CONFIG_SCSI_MULTI_LUN=y
++# CONFIG_SCSI_CONSTANTS is not set
++# CONFIG_SCSI_LOGGING is not set
++# CONFIG_SCSI_SCAN_ASYNC is not set
++
++#
++# SCSI Transports
++#
++# CONFIG_SCSI_SPI_ATTRS is not set
++# CONFIG_SCSI_FC_ATTRS is not set
++# CONFIG_SCSI_SAS_LIBSAS is not set
++# CONFIG_SCSI_SRP_ATTRS is not set
++CONFIG_SCSI_LOWLEVEL=y
++# CONFIG_BLK_DEV_3W_XXXX_RAID is not set
++# CONFIG_SCSI_3W_9XXX is not set
++# CONFIG_SCSI_ACARD is not set
++# CONFIG_SCSI_AACRAID is not set
++# CONFIG_SCSI_AIC7XXX is not set
++# CONFIG_SCSI_AIC7XXX_OLD is not set
++# CONFIG_SCSI_AIC79XX is not set
++# CONFIG_SCSI_AIC94XX is not set
++# CONFIG_SCSI_DPT_I2O is not set
++# CONFIG_SCSI_ADVANSYS is not set
++# CONFIG_SCSI_ARCMSR is not set
++# CONFIG_MEGARAID_NEWGEN is not set
++# CONFIG_MEGARAID_LEGACY is not set
++# CONFIG_MEGARAID_SAS is not set
++# CONFIG_SCSI_HPTIOP is not set
++# CONFIG_SCSI_DMX3191D is not set
++# CONFIG_SCSI_FUTURE_DOMAIN is not set
++# CONFIG_SCSI_IPS is not set
++# CONFIG_SCSI_INITIO is not set
++# CONFIG_SCSI_INIA100 is not set
++# CONFIG_SCSI_STEX is not set
++# CONFIG_SCSI_SYM53C8XX_2 is not set
++# CONFIG_SCSI_IPR is not set
++# CONFIG_SCSI_QLOGIC_1280 is not set
++# CONFIG_SCSI_QLA_FC is not set
++# CONFIG_SCSI_LPFC is not set
++# CONFIG_SCSI_DC395x is not set
++# CONFIG_SCSI_DC390T is not set
++# CONFIG_SCSI_NSP32 is not set
++# CONFIG_SCSI_DEBUG is not set
++# CONFIG_SCSI_SRP is not set
++CONFIG_ATA=y
++# CONFIG_ATA_NONSTANDARD is not set
++# CONFIG_SATA_AHCI is not set
++# CONFIG_SATA_SVW is not set
++# CONFIG_ATA_PIIX is not set
++# CONFIG_SATA_MV is not set
++# CONFIG_SATA_NV is not set
++# CONFIG_PDC_ADMA is not set
++# CONFIG_SATA_QSTOR is not set
++# CONFIG_SATA_PROMISE is not set
++# CONFIG_SATA_SX4 is not set
++# CONFIG_SATA_SIL is not set
++# CONFIG_SATA_SIL24 is not set
++# CONFIG_SATA_SIS is not set
++# CONFIG_SATA_ULI is not set
++# CONFIG_SATA_VIA is not set
++# CONFIG_SATA_VITESSE is not set
++# CONFIG_SATA_INIC162X is not set
++CONFIG_SATA_OX810=y
++# CONFIG_SATA_HIPOX_SINGLE_SATA is not set
++# CONFIG_SATA_HIPOX_DISK_LIGHT is not set
++# CONFIG_PATA_ALI is not set
++# CONFIG_PATA_AMD is not set
++# CONFIG_PATA_ARTOP is not set
++# CONFIG_PATA_ATIIXP is not set
++# CONFIG_PATA_CMD640_PCI is not set
++# CONFIG_PATA_CMD64X is not set
++# CONFIG_PATA_CS5520 is not set
++# CONFIG_PATA_CS5530 is not set
++# CONFIG_PATA_CYPRESS is not set
++# CONFIG_PATA_EFAR is not set
++# CONFIG_ATA_GENERIC is not set
++# CONFIG_PATA_HPT366 is not set
++# CONFIG_PATA_HPT37X is not set
++# CONFIG_PATA_HPT3X2N is not set
++# CONFIG_PATA_HPT3X3 is not set
++# CONFIG_PATA_IT821X is not set
++# CONFIG_PATA_IT8213 is not set
++# CONFIG_PATA_JMICRON is not set
++# CONFIG_PATA_TRIFLEX is not set
++# CONFIG_PATA_MARVELL is not set
++# CONFIG_PATA_MPIIX is not set
++# CONFIG_PATA_OLDPIIX is not set
++# CONFIG_PATA_NETCELL is not set
++# CONFIG_PATA_NS87410 is not set
++# CONFIG_PATA_NS87415 is not set
++# CONFIG_PATA_OPTI is not set
++# CONFIG_PATA_OPTIDMA is not set
++# CONFIG_PATA_PDC_OLD is not set
++# CONFIG_PATA_RADISYS is not set
++# CONFIG_PATA_RZ1000 is not set
++# CONFIG_PATA_SC1200 is not set
++# CONFIG_PATA_SERVERWORKS is not set
++# CONFIG_PATA_PDC2027X is not set
++# CONFIG_PATA_SIL680 is not set
++# CONFIG_PATA_SIS is not set
++# CONFIG_PATA_VIA is not set
++# CONFIG_PATA_WINBOND is not set
++CONFIG_MD=y
++CONFIG_BLK_DEV_MD=y
++CONFIG_MD_LINEAR=y
++# CONFIG_MD_RAID0 is not set
++CONFIG_MD_RAID1=y
++# CONFIG_MD_RAID10 is not set
++# CONFIG_MD_RAID456 is not set
++# CONFIG_MD_MULTIPATH is not set
++# CONFIG_MD_FAULTY is not set
++CONFIG_BLK_DEV_DM=y
++# CONFIG_DM_DEBUG is not set
++# CONFIG_DM_CRYPT is not set
++# CONFIG_DM_SNAPSHOT is not set
++# CONFIG_DM_MIRROR is not set
++# CONFIG_DM_ZERO is not set
++# CONFIG_DM_MULTIPATH is not set
++# CONFIG_DM_DELAY is not set
++# CONFIG_DM_UEVENT is not set
++# CONFIG_FUSION is not set
++
++#
++# IEEE 1394 (FireWire) support
++#
++# CONFIG_FIREWIRE is not set
++# CONFIG_IEEE1394 is not set
++# CONFIG_I2O is not set
++
++#
++# Input device support
++#
++CONFIG_INPUT=y
++# CONFIG_INPUT_FF_MEMLESS is not set
++# CONFIG_INPUT_POLLDEV is not set
++
++#
++# Userland interfaces
++#
++CONFIG_INPUT_MOUSEDEV=y
++# CONFIG_INPUT_MOUSEDEV_PSAUX is not set
++CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024
++CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
++# CONFIG_INPUT_JOYDEV is not set
++# CONFIG_INPUT_EVDEV is not set
++# CONFIG_INPUT_EVBUG is not set
++
++#
++# Input Device Drivers
++#
++# CONFIG_INPUT_KEYBOARD is not set
++# CONFIG_INPUT_MOUSE is not set
++# CONFIG_INPUT_JOYSTICK is not set
++# CONFIG_INPUT_TABLET is not set
++# CONFIG_INPUT_TOUCHSCREEN is not set
++# CONFIG_INPUT_MISC is not set
++
++#
++# Hardware I/O ports
++#
++# CONFIG_SERIO is not set
++# CONFIG_GAMEPORT is not set
++
++#
++# Character devices
++#
++CONFIG_VT=y
++CONFIG_VT_CONSOLE=y
++CONFIG_HW_CONSOLE=y
++# CONFIG_VT_HW_CONSOLE_BINDING is not set
++# CONFIG_SERIAL_NONSTANDARD is not set
++
++#
++# Serial drivers
++#
++CONFIG_SERIAL_8250=y
++CONFIG_SERIAL_8250_CONSOLE=y
++CONFIG_SERIAL_8250_PCI=y
++CONFIG_SERIAL_8250_NR_UARTS=4
++CONFIG_SERIAL_8250_RUNTIME_UARTS=4
++# CONFIG_SERIAL_8250_EXTENDED is not set
++
++#
++# Non-8250 serial port support
++#
++# CONFIG_SERIAL_AMBA_PL010 is not set
++# CONFIG_SERIAL_AMBA_PL011 is not set
++CONFIG_SERIAL_CORE=y
++CONFIG_SERIAL_CORE_CONSOLE=y
++# CONFIG_SERIAL_JSM is not set
++CONFIG_UNIX98_PTYS=y
++# CONFIG_LEGACY_PTYS is not set
++# CONFIG_IPMI_HANDLER is not set
++CONFIG_HW_RANDOM=y
++# CONFIG_NVRAM is not set
++# CONFIG_R3964 is not set
++# CONFIG_APPLICOM is not set
++# CONFIG_RAW_DRIVER is not set
++# CONFIG_TCG_TPM is not set
++CONFIG_DEVPORT=y
++CONFIG_I2C=y
++CONFIG_I2C_BOARDINFO=y
++# CONFIG_I2C_CHARDEV is not set
++
++#
++# I2C Algorithms
++#
++CONFIG_I2C_ALGOBIT=y
++# CONFIG_I2C_ALGOPCF is not set
++# CONFIG_I2C_ALGOPCA is not set
++# CONFIG_I2C_ALGOOXSEMI is not set
++
++#
++# I2C Hardware Bus support
++#
++# CONFIG_I2C_ALI1535 is not set
++# CONFIG_I2C_ALI1563 is not set
++# CONFIG_I2C_ALI15X3 is not set
++# CONFIG_I2C_AMD756 is not set
++# CONFIG_I2C_AMD8111 is not set
++# CONFIG_I2C_I801 is not set
++# CONFIG_I2C_I810 is not set
++# CONFIG_I2C_PIIX4 is not set
++# CONFIG_I2C_NFORCE2 is not set
++CONFIG_I2C_HIPOX_BITBASH=y
++# CONFIG_I2C_OCORES is not set
++# CONFIG_I2C_PARPORT_LIGHT is not set
++# CONFIG_I2C_PROSAVAGE is not set
++# CONFIG_I2C_SAVAGE4 is not set
++# CONFIG_I2C_SIMTEC is not set
++# CONFIG_I2C_SIS5595 is not set
++# CONFIG_I2C_SIS630 is not set
++# CONFIG_I2C_SIS96X is not set
++# CONFIG_I2C_TAOS_EVM is not set
++# CONFIG_I2C_VIA is not set
++# CONFIG_I2C_VIAPRO is not set
++# CONFIG_I2C_VOODOO3 is not set
++
++#
++# Miscellaneous I2C Chip support
++#
++# CONFIG_SENSORS_DS1337 is not set
++# CONFIG_SENSORS_DS1374 is not set
++# CONFIG_DS1682 is not set
++# CONFIG_SENSORS_EEPROM is not set
++# CONFIG_SENSORS_PCF8574 is not set
++# CONFIG_SENSORS_PCA9539 is not set
++# CONFIG_SENSORS_PCF8591 is not set
++# CONFIG_SENSORS_MAX6875 is not set
++# CONFIG_SENSORS_TSL2550 is not set
++# CONFIG_I2C_DEBUG_CORE is not set
++# CONFIG_I2C_DEBUG_ALGO is not set
++# CONFIG_I2C_DEBUG_BUS is not set
++# CONFIG_I2C_DEBUG_CHIP is not set
++
++#
++# SPI support
++#
++# CONFIG_SPI is not set
++# CONFIG_SPI_MASTER is not set
++# CONFIG_W1 is not set
++# CONFIG_POWER_SUPPLY is not set
++# CONFIG_HWMON is not set
++# CONFIG_WATCHDOG is not set
++
++#
++# Sonics Silicon Backplane
++#
++CONFIG_SSB_POSSIBLE=y
++# CONFIG_SSB is not set
++
++#
++# Multifunction device drivers
++#
++# CONFIG_MFD_SM501 is not set
++
++#
++# Multimedia devices
++#
++# CONFIG_VIDEO_DEV is not set
++CONFIG_DAB=y
++
++#
++# Graphics support
++#
++# CONFIG_DRM is not set
++# CONFIG_VGASTATE is not set
++CONFIG_VIDEO_OUTPUT_CONTROL=y
++# CONFIG_FB is not set
++# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
++
++#
++# Display device support
++#
++# CONFIG_DISPLAY_SUPPORT is not set
++
++#
++# Console display driver support
++#
++# CONFIG_VGA_CONSOLE is not set
++CONFIG_DUMMY_CONSOLE=y
++
++#
++# Sound
++#
++# CONFIG_SOUND is not set
++# CONFIG_HID_SUPPORT is not set
++# CONFIG_USB_SUPPORT is not set
++# CONFIG_MMC is not set
++# CONFIG_NEW_LEDS is not set
++CONFIG_RTC_LIB=y
++CONFIG_RTC_CLASS=y
++CONFIG_RTC_HCTOSYS=y
++CONFIG_RTC_HCTOSYS_DEVICE="rtc0"
++# CONFIG_RTC_DEBUG is not set
++
++#
++# RTC interfaces
++#
++CONFIG_RTC_INTF_SYSFS=y
++CONFIG_RTC_INTF_PROC=y
++CONFIG_RTC_INTF_DEV=y
++# CONFIG_RTC_INTF_DEV_UIE_EMUL is not set
++# CONFIG_RTC_DRV_TEST is not set
++
++#
++# I2C RTC drivers
++#
++CONFIG_RTC_DRV_DS1307=y
++# CONFIG_RTC_DRV_DS1374 is not set
++# CONFIG_RTC_DRV_DS1672 is not set
++# CONFIG_RTC_DRV_MAX6900 is not set
++# CONFIG_RTC_DRV_RS5C372 is not set
++# CONFIG_RTC_DRV_ISL1208 is not set
++# CONFIG_RTC_DRV_X1205 is not set
++# CONFIG_RTC_DRV_PCF8563 is not set
++# CONFIG_RTC_DRV_PCF8583 is not set
++# CONFIG_RTC_DRV_M41T80 is not set
++
++#
++# SPI RTC drivers
++#
++
++#
++# Platform RTC drivers
++#
++# CONFIG_RTC_DRV_CMOS is not set
++# CONFIG_RTC_DRV_DS1553 is not set
++# CONFIG_RTC_DRV_STK17TA8 is not set
++# CONFIG_RTC_DRV_DS1742 is not set
++# CONFIG_RTC_DRV_M48T86 is not set
++# CONFIG_RTC_DRV_M48T59 is not set
++# CONFIG_RTC_DRV_V3020 is not set
++
++#
++# on-CPU RTC drivers
++#
++# CONFIG_RTC_DRV_PL031 is not set
++# CONFIG_DMADEVICES is not set
++
++#
++# File systems
++#
++CONFIG_EXT2_FS=y
++# CONFIG_EXT2_FS_XATTR is not set
++# CONFIG_EXT2_FS_XIP is not set
++CONFIG_EXT3_FS=y
++# CONFIG_EXT3_FS_XATTR is not set
++# CONFIG_EXT4DEV_FS is not set
++CONFIG_JBD=y
++# CONFIG_REISERFS_FS is not set
++# CONFIG_JFS_FS is not set
++# CONFIG_FS_POSIX_ACL is not set
++# CONFIG_XFS_FS is not set
++# CONFIG_GFS2_FS is not set
++# CONFIG_MINIX_FS is not set
++# CONFIG_ROMFS_FS is not set
++# CONFIG_INOTIFY is not set
++# CONFIG_QUOTA is not set
++# CONFIG_DNOTIFY is not set
++# CONFIG_AUTOFS_FS is not set
++# CONFIG_AUTOFS4_FS is not set
++# CONFIG_FUSE_FS is not set
++
++#
++# CD-ROM/DVD Filesystems
++#
++# CONFIG_ISO9660_FS is not set
++# CONFIG_UDF_FS is not set
++
++#
++# DOS/FAT/NT Filesystems
++#
++# CONFIG_MSDOS_FS is not set
++# CONFIG_VFAT_FS is not set
++# CONFIG_NTFS_FS is not set
++
++#
++# Pseudo filesystems
++#
++CONFIG_PROC_FS=y
++CONFIG_PROC_SYSCTL=y
++CONFIG_SYSFS=y
++# CONFIG_TMPFS is not set
++# CONFIG_HUGETLB_PAGE is not set
++# CONFIG_CONFIGFS_FS is not set
++
++#
++# Miscellaneous filesystems
++#
++# CONFIG_ADFS_FS is not set
++# CONFIG_AFFS_FS is not set
++# CONFIG_HFS_FS is not set
++# CONFIG_HFSPLUS_FS is not set
++# CONFIG_BEFS_FS is not set
++# CONFIG_BFS_FS is not set
++# CONFIG_EFS_FS is not set
++# CONFIG_CRAMFS is not set
++# CONFIG_VXFS_FS is not set
++# CONFIG_HPFS_FS is not set
++# CONFIG_QNX4FS_FS is not set
++# CONFIG_SYSV_FS is not set
++# CONFIG_UFS_FS is not set
++
++#
++# Partition Types
++#
++# CONFIG_PARTITION_ADVANCED is not set
++CONFIG_MSDOS_PARTITION=y
++CONFIG_NLS=y
++CONFIG_NLS_DEFAULT="iso8859-1"
++CONFIG_NLS_CODEPAGE_437=y
++# CONFIG_NLS_CODEPAGE_737 is not set
++# CONFIG_NLS_CODEPAGE_775 is not set
++# CONFIG_NLS_CODEPAGE_850 is not set
++# CONFIG_NLS_CODEPAGE_852 is not set
++# CONFIG_NLS_CODEPAGE_855 is not set
++# CONFIG_NLS_CODEPAGE_857 is not set
++# CONFIG_NLS_CODEPAGE_860 is not set
++# CONFIG_NLS_CODEPAGE_861 is not set
++# CONFIG_NLS_CODEPAGE_862 is not set
++# CONFIG_NLS_CODEPAGE_863 is not set
++# CONFIG_NLS_CODEPAGE_864 is not set
++# CONFIG_NLS_CODEPAGE_865 is not set
++# CONFIG_NLS_CODEPAGE_866 is not set
++# CONFIG_NLS_CODEPAGE_869 is not set
++# CONFIG_NLS_CODEPAGE_936 is not set
++# CONFIG_NLS_CODEPAGE_950 is not set
++# CONFIG_NLS_CODEPAGE_932 is not set
++# CONFIG_NLS_CODEPAGE_949 is not set
++# CONFIG_NLS_CODEPAGE_874 is not set
++# CONFIG_NLS_ISO8859_8 is not set
++# CONFIG_NLS_CODEPAGE_1250 is not set
++# CONFIG_NLS_CODEPAGE_1251 is not set
++# CONFIG_NLS_ASCII is not set
++CONFIG_NLS_ISO8859_1=y
++# CONFIG_NLS_ISO8859_2 is not set
++# CONFIG_NLS_ISO8859_3 is not set
++# CONFIG_NLS_ISO8859_4 is not set
++# CONFIG_NLS_ISO8859_5 is not set
++# CONFIG_NLS_ISO8859_6 is not set
++# CONFIG_NLS_ISO8859_7 is not set
++# CONFIG_NLS_ISO8859_9 is not set
++# CONFIG_NLS_ISO8859_13 is not set
++# CONFIG_NLS_ISO8859_14 is not set
++# CONFIG_NLS_ISO8859_15 is not set
++# CONFIG_NLS_KOI8_R is not set
++# CONFIG_NLS_KOI8_U is not set
++CONFIG_NLS_UTF8=y
++# CONFIG_INSTRUMENTATION is not set
++
++#
++# Kernel hacking
++#
++# CONFIG_PRINTK_TIME is not set
++# CONFIG_ENABLE_WARN_DEPRECATED is not set
++# CONFIG_ENABLE_MUST_CHECK is not set
++# CONFIG_MAGIC_SYSRQ is not set
++# CONFIG_UNUSED_SYMBOLS is not set
++# CONFIG_DEBUG_FS is not set
++# CONFIG_HEADERS_CHECK is not set
++# CONFIG_DEBUG_KERNEL is not set
++CONFIG_DEBUG_BUGVERBOSE=y
++CONFIG_FRAME_POINTER=y
++# CONFIG_SAMPLES is not set
++# CONFIG_DEBUG_USER is not set
++
++#
++# Security options
++#
++# CONFIG_KEYS is not set
++# CONFIG_SECURITY is not set
++# CONFIG_SECURITY_FILE_CAPABILITIES is not set
++CONFIG_CRYPTO=y
++CONFIG_CRYPTO_ALGAPI=y
++CONFIG_CRYPTO_BLKCIPHER=y
++CONFIG_CRYPTO_MANAGER=y
++# CONFIG_CRYPTO_HMAC is not set
++# CONFIG_CRYPTO_XCBC is not set
++# CONFIG_CRYPTO_NULL is not set
++# CONFIG_CRYPTO_MD4 is not set
++# CONFIG_CRYPTO_MD5 is not set
++# CONFIG_CRYPTO_SHA1 is not set
++# CONFIG_CRYPTO_SHA256 is not set
++# CONFIG_CRYPTO_SHA512 is not set
++# CONFIG_CRYPTO_WP512 is not set
++# CONFIG_CRYPTO_TGR192 is not set
++# CONFIG_CRYPTO_GF128MUL is not set
++# CONFIG_CRYPTO_ECB is not set
++CONFIG_CRYPTO_CBC=y
++# CONFIG_CRYPTO_PCBC is not set
++# CONFIG_CRYPTO_LRW is not set
++# CONFIG_CRYPTO_XTS is not set
++# CONFIG_CRYPTO_CRYPTD is not set
++# CONFIG_CRYPTO_DES is not set
++# CONFIG_CRYPTO_FCRYPT is not set
++# CONFIG_CRYPTO_BLOWFISH is not set
++# CONFIG_CRYPTO_TWOFISH is not set
++# CONFIG_CRYPTO_SERPENT is not set
++# CONFIG_CRYPTO_AES is not set
++# CONFIG_CRYPTO_CAST5 is not set
++# CONFIG_CRYPTO_CAST6 is not set
++# CONFIG_CRYPTO_TEA is not set
++# CONFIG_CRYPTO_ARC4 is not set
++# CONFIG_CRYPTO_KHAZAD is not set
++# CONFIG_CRYPTO_ANUBIS is not set
++# CONFIG_CRYPTO_SEED is not set
++# CONFIG_CRYPTO_DEFLATE is not set
++# CONFIG_CRYPTO_MICHAEL_MIC is not set
++# CONFIG_CRYPTO_CRC32C is not set
++# CONFIG_CRYPTO_CAMELLIA is not set
++# CONFIG_CRYPTO_AUTHENC is not set
++# CONFIG_CRYPTO_HW is not set
++
++#
++# Library routines
++#
++CONFIG_BITREVERSE=y
++CONFIG_CRC_CCITT=y
++# CONFIG_CRC16 is not set
++# CONFIG_CRC_ITU_T is not set
++CONFIG_CRC32=y
++# CONFIG_CRC7 is not set
++# CONFIG_LIBCRC32C is not set
++CONFIG_PLIST=y
++CONFIG_HAS_IOMEM=y
++CONFIG_HAS_IOPORT=y
++CONFIG_HAS_DMA=y
+diff -Nurd linux-2.6.24/arch/arm/configs/hipox_810_eabi_wd_eval_defconfig linux-2.6.24-oxe810/arch/arm/configs/hipox_810_eabi_wd_eval_defconfig
+--- linux-2.6.24/arch/arm/configs/hipox_810_eabi_wd_eval_defconfig 1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.24-oxe810/arch/arm/configs/hipox_810_eabi_wd_eval_defconfig 2008-06-11 17:47:52.000000000 +0200
+@@ -0,0 +1,1096 @@
++#
++# Automatically generated make config: don't edit
++# Linux kernel version: 2.6.24.4
++# Mon Jun 2 12:33:10 2008
++#
++CONFIG_ARM=y
++CONFIG_SYS_SUPPORTS_APM_EMULATION=y
++# CONFIG_GENERIC_GPIO is not set
++# CONFIG_GENERIC_TIME is not set
++# CONFIG_GENERIC_CLOCKEVENTS is not set
++CONFIG_MMU=y
++# CONFIG_NO_IOPORT is not set
++CONFIG_GENERIC_HARDIRQS=y
++CONFIG_STACKTRACE_SUPPORT=y
++CONFIG_LOCKDEP_SUPPORT=y
++CONFIG_TRACE_IRQFLAGS_SUPPORT=y
++CONFIG_HARDIRQS_SW_RESEND=y
++CONFIG_GENERIC_IRQ_PROBE=y
++CONFIG_RWSEM_GENERIC_SPINLOCK=y
++# CONFIG_ARCH_HAS_ILOG2_U32 is not set
++# CONFIG_ARCH_HAS_ILOG2_U64 is not set
++CONFIG_GENERIC_HWEIGHT=y
++CONFIG_GENERIC_CALIBRATE_DELAY=y
++CONFIG_ZONE_DMA=y
++CONFIG_VECTORS_BASE=0xffff0000
++CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
++
++#
++# General setup
++#
++CONFIG_EXPERIMENTAL=y
++CONFIG_BROKEN_ON_SMP=y
++CONFIG_INIT_ENV_ARG_LIMIT=32
++CONFIG_LOCALVERSION=""
++CONFIG_LOCALVERSION_AUTO=y
++CONFIG_SWAP=y
++CONFIG_SYSVIPC=y
++CONFIG_SYSVIPC_SYSCTL=y
++# CONFIG_POSIX_MQUEUE is not set
++# CONFIG_BSD_PROCESS_ACCT is not set
++# CONFIG_TASKSTATS is not set
++# CONFIG_USER_NS is not set
++# CONFIG_PID_NS is not set
++# CONFIG_AUDIT is not set
++# CONFIG_IKCONFIG is not set
++CONFIG_LOG_BUF_SHIFT=14
++# CONFIG_CGROUPS is not set
++# CONFIG_FAIR_GROUP_SCHED is not set
++# CONFIG_FAIR_USER_SCHED is not set
++# CONFIG_FAIR_CGROUP_SCHED is not set
++CONFIG_SYSFS_DEPRECATED=y
++# CONFIG_RELAY is not set
++CONFIG_BLK_DEV_INITRD=y
++CONFIG_INITRAMFS_SOURCE=""
++# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
++CONFIG_SYSCTL=y
++# CONFIG_EMBEDDED is not set
++CONFIG_UID16=y
++CONFIG_SYSCTL_SYSCALL=y
++CONFIG_KALLSYMS=y
++# CONFIG_KALLSYMS_EXTRA_PASS is not set
++CONFIG_HOTPLUG=y
++CONFIG_PRINTK=y
++CONFIG_BUG=y
++CONFIG_ELF_CORE=y
++CONFIG_BASE_FULL=y
++CONFIG_FUTEX=y
++CONFIG_ANON_INODES=y
++CONFIG_EPOLL=y
++CONFIG_SIGNALFD=y
++CONFIG_EVENTFD=y
++CONFIG_SHMEM=y
++CONFIG_VM_EVENT_COUNTERS=y
++CONFIG_SLAB=y
++# CONFIG_SLUB is not set
++# CONFIG_SLOB is not set
++CONFIG_SLABINFO=y
++CONFIG_RT_MUTEXES=y
++# CONFIG_TINY_SHMEM is not set
++CONFIG_BASE_SMALL=0
++CONFIG_MODULES=y
++CONFIG_MODULE_UNLOAD=y
++# CONFIG_MODULE_FORCE_UNLOAD is not set
++# CONFIG_MODVERSIONS is not set
++# CONFIG_MODULE_SRCVERSION_ALL is not set
++# CONFIG_KMOD is not set
++CONFIG_BLOCK=y
++# CONFIG_LBD is not set
++# CONFIG_BLK_DEV_IO_TRACE is not set
++# CONFIG_LSF is not set
++# CONFIG_BLK_DEV_BSG is not set
++
++#
++# IO Schedulers
++#
++CONFIG_IOSCHED_NOOP=y
++CONFIG_IOSCHED_AS=y
++CONFIG_IOSCHED_DEADLINE=y
++CONFIG_IOSCHED_CFQ=y
++CONFIG_DEFAULT_AS=y
++# CONFIG_DEFAULT_DEADLINE is not set
++# CONFIG_DEFAULT_CFQ is not set
++# CONFIG_DEFAULT_NOOP is not set
++CONFIG_DEFAULT_IOSCHED="anticipatory"
++
++#
++# System Type
++#
++# CONFIG_ARCH_AAEC2000 is not set
++# CONFIG_ARCH_INTEGRATOR is not set
++# CONFIG_ARCH_REALVIEW is not set
++# CONFIG_ARCH_VERSATILE is not set
++# CONFIG_ARCH_AT91 is not set
++# CONFIG_ARCH_CLPS7500 is not set
++# CONFIG_ARCH_CLPS711X is not set
++# CONFIG_ARCH_CO285 is not set
++# CONFIG_ARCH_EBSA110 is not set
++# CONFIG_ARCH_EP93XX is not set
++# CONFIG_ARCH_FOOTBRIDGE is not set
++# CONFIG_ARCH_NETX is not set
++# CONFIG_ARCH_H720X is not set
++# CONFIG_ARCH_IMX is not set
++# CONFIG_ARCH_IOP13XX is not set
++# CONFIG_ARCH_IOP32X is not set
++# CONFIG_ARCH_IOP33X is not set
++# CONFIG_ARCH_IXP23XX is not set
++# CONFIG_ARCH_IXP2000 is not set
++# CONFIG_ARCH_IXP4XX is not set
++# CONFIG_ARCH_L7200 is not set
++# CONFIG_ARCH_KS8695 is not set
++# CONFIG_ARCH_NS9XXX is not set
++# CONFIG_ARCH_MXC is not set
++# CONFIG_ARCH_PNX4008 is not set
++# CONFIG_ARCH_PXA is not set
++# CONFIG_ARCH_RPC is not set
++# CONFIG_ARCH_SA1100 is not set
++# CONFIG_ARCH_S3C2410 is not set
++# CONFIG_ARCH_SHARK is not set
++# CONFIG_ARCH_LH7A40X is not set
++# CONFIG_ARCH_DAVINCI is not set
++# CONFIG_ARCH_OMAP is not set
++CONFIG_ARCH_HIPOX=y
++
++#
++# Boot options
++#
++
++#
++# Power management
++#
++
++#
++# Oxford Semiconductor NAS Options
++#
++# CONFIG_ARCH_HIPOX_FPGA is not set
++CONFIG_NOMINAL_PLL400_FREQ=733333333
++CONFIG_NOMINAL_RPSCLK_FREQ=25000000
++# CONFIG_HIPOX_VERSION_0X800 is not set
++CONFIG_HIPOX_VERSION_0X810=y
++# CONFIG_HIPOX_VERSION_0X850 is not set
++# CONFIG_ARCH_HIPOX_UART1 is not set
++CONFIG_ARCH_HIPOX_UART2=y
++# CONFIG_ARCH_HIPOX_UART2_MODEM is not set
++# CONFIG_ARCH_HIPOX_UART3 is not set
++# CONFIG_ARCH_HIPOX_UART4 is not set
++CONFIG_FORCE_MAX_ZONEORDER=10
++CONFIG_SRAM_NUM_PAGES=32
++CONFIG_SUPPORT_LEON=y
++CONFIG_LEON_PAGES=2
++CONFIG_LEON_COPRO=y
++CONFIG_LEON_OFFLOAD_TX=y
++# CONFIG_LEON_RESERVE_DMA_CHANNEL is not set
++CONFIG_LEON_OFFLOAD_TSO=y
++# CONFIG_LEON_START_EARLY is not set
++CONFIG_LEON_POWER_BUTTON_MONITOR=m
++CONFIG_HIPOX_POWER_BUTTON_GPIO=4
++CONFIG_USER_RECOVERY_BUTTON_MONITOR=y
++CONFIG_HIPOX_USER_RECOVERY_BUTTON_GPIO=28
++# CONFIG_HIPOX_DDR_MON is not set
++# CONFIG_HIPOX_AHB_MON is not set
++# CONFIG_HIPOX_CACHE_LOCKDOWN is not set
++# CONFIG_DO_MEM_TEST is not set
++# CONFIG_CRYPTO_OXAESLRW is not set
++CONFIG_DESCRIPTORS_PAGES=6
++CONFIG_ARCH_HIPOX_NUM_GMAC_DESCRIPTORS=192
++CONFIG_ARCH_HIPOX_MAX_SATA_SG_ENTRIES=256
++CONFIG_TACHO_THERM_AND_FAN=m
++# CONFIG_GPIO_TEST is not set
++CONFIG_HIPOX_RTC=m
++# CONFIG_I2S is not set
++# CONFIG_DPE_TEST is not set
++# CONFIG_HIPOX_INSTRUMENT_COPIES is not set
++# CONFIG_HIPOX_DMA_COPIES is not set
++# CONFIG_HIPOX_AHB_MONITOR_MODULE is not set
++# CONFIG_HIPOX_USB_TEST_MODES is not set
++# CONFIG_HIPOX_FRONT_LAMP_CONTROL is not set
++# CONFIG_LEDS_TRIGGER_SATA_DISK is not set
++# CONFIG_HIPOX_LED_TEST is not set
++CONFIG_HIPOX_I2C_SDA=3
++CONFIG_HIPOX_I2C_SCL=2
++CONFIG_HIPOX_USB_PORTA_POWER_CONTROL=y
++# CONFIG_HIPOX_USB_PORTB_POWER_CONTROL is not set
++# CONFIG_HIPOX_USB_PORTC_POWER_CONTROL is not set
++CONFIG_HIPOX_USB_OVERCURRENT_POLARITY_NEGATIVE=y
++CONFIG_HIPOX_USB_POWER_SWITCH_POLARITY_NEGATIVE=y
++# CONFIG_WDC_FAN_HIPOX800 is not set
++# CONFIG_HIPOX_MAP_SRAM is not set
++# CONFIG_HIPOX_SUID_INHERIT is not set
++# CONFIG_HIPOX_USB_HUB_SUPPORT is not set
++
++#
++# Processor Type
++#
++CONFIG_CPU_32=y
++CONFIG_CPU_ARM926T=y
++CONFIG_CPU_32v5=y
++CONFIG_CPU_ABRT_EV5TJ=y
++CONFIG_CPU_CACHE_VIVT=y
++CONFIG_CPU_COPY_V4WB=y
++CONFIG_CPU_TLB_V4WBI=y
++CONFIG_CPU_CP15=y
++CONFIG_CPU_CP15_MMU=y
++
++#
++# Processor Features
++#
++CONFIG_ARM_THUMB=y
++# CONFIG_CPU_ICACHE_DISABLE is not set
++# CONFIG_CPU_DCACHE_DISABLE is not set
++# CONFIG_CPU_DCACHE_WRITETHROUGH is not set
++# CONFIG_CPU_CACHE_ROUND_ROBIN is not set
++# CONFIG_OUTER_CACHE is not set
++
++#
++# Bus support
++#
++CONFIG_ARM_AMBA=y
++# CONFIG_PCI is not set
++# CONFIG_PCI_SYSCALL is not set
++# CONFIG_ARCH_SUPPORTS_MSI is not set
++# CONFIG_PCCARD is not set
++
++#
++# Kernel Features
++#
++# CONFIG_TICK_ONESHOT is not set
++# CONFIG_PREEMPT is not set
++# CONFIG_NO_IDLE_HZ is not set
++CONFIG_HZ=100
++CONFIG_AEABI=y
++# CONFIG_OABI_COMPAT is not set
++# CONFIG_ARCH_DISCONTIGMEM_ENABLE is not set
++CONFIG_SELECT_MEMORY_MODEL=y
++CONFIG_FLATMEM_MANUAL=y
++# CONFIG_DISCONTIGMEM_MANUAL is not set
++# CONFIG_SPARSEMEM_MANUAL is not set
++CONFIG_FLATMEM=y
++CONFIG_FLAT_NODE_MEM_MAP=y
++# CONFIG_SPARSEMEM_STATIC is not set
++# CONFIG_SPARSEMEM_VMEMMAP_ENABLE is not set
++CONFIG_SPLIT_PTLOCK_CPUS=4096
++# CONFIG_RESOURCES_64BIT is not set
++CONFIG_ZONE_DMA_FLAG=1
++CONFIG_BOUNCE=y
++CONFIG_VIRT_TO_BUS=y
++CONFIG_ALIGNMENT_TRAP=y
++
++#
++# Boot options
++#
++CONFIG_ZBOOT_ROM_TEXT=0x0
++CONFIG_ZBOOT_ROM_BSS=0x0
++CONFIG_CMDLINE=""
++# CONFIG_XIP_KERNEL is not set
++# CONFIG_KEXEC is not set
++
++#
++# Floating point emulation
++#
++
++#
++# At least one emulation must be selected
++#
++# CONFIG_VFP is not set
++
++#
++# Userspace binary formats
++#
++CONFIG_BINFMT_ELF=y
++# CONFIG_BINFMT_AOUT is not set
++# CONFIG_BINFMT_MISC is not set
++
++#
++# Power management options
++#
++# CONFIG_PM is not set
++CONFIG_SUSPEND_UP_POSSIBLE=y
++
++#
++# Networking
++#
++CONFIG_NET=y
++
++#
++# Networking options
++#
++CONFIG_PACKET=y
++CONFIG_PACKET_MMAP=y
++CONFIG_UNIX=y
++CONFIG_XFRM=y
++# CONFIG_XFRM_USER is not set
++# CONFIG_XFRM_SUB_POLICY is not set
++# CONFIG_XFRM_MIGRATE is not set
++# CONFIG_NET_KEY is not set
++CONFIG_INET=y
++CONFIG_IP_MULTICAST=y
++# CONFIG_IP_ADVANCED_ROUTER is not set
++CONFIG_IP_FIB_HASH=y
++# CONFIG_IP_PNP is not set
++# CONFIG_NET_IPIP is not set
++# CONFIG_NET_IPGRE is not set
++# CONFIG_IP_MROUTE is not set
++# CONFIG_ARPD is not set
++# CONFIG_SYN_COOKIES is not set
++# CONFIG_INET_AH is not set
++# CONFIG_INET_ESP is not set
++# CONFIG_INET_IPCOMP is not set
++# CONFIG_INET_XFRM_TUNNEL is not set
++# CONFIG_INET_TUNNEL is not set
++CONFIG_INET_XFRM_MODE_TRANSPORT=y
++CONFIG_INET_XFRM_MODE_TUNNEL=y
++CONFIG_INET_XFRM_MODE_BEET=y
++# CONFIG_INET_LRO is not set
++CONFIG_INET_DIAG=y
++CONFIG_INET_TCP_DIAG=y
++# CONFIG_TCP_CONG_ADVANCED is not set
++CONFIG_TCP_CONG_CUBIC=y
++CONFIG_DEFAULT_TCP_CONG="cubic"
++# CONFIG_TCP_MD5SIG is not set
++# CONFIG_IP_VS is not set
++# CONFIG_IPV6 is not set
++# CONFIG_INET6_XFRM_TUNNEL is not set
++# CONFIG_INET6_TUNNEL is not set
++# CONFIG_NETLABEL is not set
++# CONFIG_NETWORK_SECMARK is not set
++CONFIG_NETFILTER=y
++# CONFIG_NETFILTER_DEBUG is not set
++
++#
++# Core Netfilter Configuration
++#
++# CONFIG_NETFILTER_NETLINK is not set
++# CONFIG_NF_CONNTRACK_ENABLED is not set
++# CONFIG_NF_CONNTRACK is not set
++# CONFIG_NETFILTER_XTABLES is not set
++
++#
++# IP: Netfilter Configuration
++#
++# CONFIG_IP_NF_QUEUE is not set
++# CONFIG_IP_NF_IPTABLES is not set
++# CONFIG_IP_NF_ARPTABLES is not set
++# CONFIG_IP_DCCP is not set
++# CONFIG_IP_SCTP is not set
++# CONFIG_TIPC is not set
++# CONFIG_ATM is not set
++# CONFIG_BRIDGE is not set
++# CONFIG_VLAN_8021Q is not set
++# CONFIG_DECNET is not set
++# CONFIG_LLC2 is not set
++# CONFIG_IPX is not set
++# CONFIG_ATALK is not set
++# CONFIG_X25 is not set
++# CONFIG_LAPB is not set
++# CONFIG_ECONET is not set
++# CONFIG_WAN_ROUTER is not set
++# CONFIG_NET_SCHED is not set
++
++#
++# Network testing
++#
++# CONFIG_NET_PKTGEN is not set
++# CONFIG_HAMRADIO is not set
++# CONFIG_IRDA is not set
++# CONFIG_BT is not set
++# CONFIG_AF_RXRPC is not set
++
++#
++# Wireless
++#
++# CONFIG_CFG80211 is not set
++CONFIG_WIRELESS_EXT=y
++# CONFIG_MAC80211 is not set
++# CONFIG_IEEE80211 is not set
++# CONFIG_RFKILL is not set
++# CONFIG_NET_9P is not set
++
++#
++# Device Drivers
++#
++
++#
++# Generic Driver Options
++#
++CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
++CONFIG_STANDALONE=y
++CONFIG_PREVENT_FIRMWARE_BUILD=y
++CONFIG_FW_LOADER=y
++# CONFIG_SYS_HYPERVISOR is not set
++# CONFIG_CONNECTOR is not set
++# CONFIG_MTD is not set
++# CONFIG_PARPORT is not set
++CONFIG_BLK_DEV=y
++# CONFIG_BLK_DEV_COW_COMMON is not set
++CONFIG_BLK_DEV_LOOP=y
++# CONFIG_BLK_DEV_CRYPTOLOOP is not set
++# CONFIG_BLK_DEV_NBD is not set
++# CONFIG_BLK_DEV_UB is not set
++CONFIG_BLK_DEV_RAM=y
++CONFIG_BLK_DEV_RAM_COUNT=16
++CONFIG_BLK_DEV_RAM_SIZE=10240
++CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024
++# CONFIG_CDROM_PKTCDVD is not set
++# CONFIG_ATA_OVER_ETH is not set
++# CONFIG_MISC_DEVICES is not set
++# CONFIG_IDE is not set
++
++#
++# SCSI device support
++#
++# CONFIG_RAID_ATTRS is not set
++CONFIG_SCSI=y
++CONFIG_SCSI_DMA=y
++# CONFIG_SCSI_TGT is not set
++# CONFIG_SCSI_NETLINK is not set
++CONFIG_SCSI_PROC_FS=y
++
++#
++# SCSI support type (disk, tape, CD-ROM)
++#
++CONFIG_BLK_DEV_SD=y
++# CONFIG_CHR_DEV_ST is not set
++# CONFIG_CHR_DEV_OSST is not set
++# CONFIG_BLK_DEV_SR is not set
++# CONFIG_CHR_DEV_SG is not set
++# CONFIG_CHR_DEV_SCH is not set
++
++#
++# Some SCSI devices (e.g. CD jukebox) support multiple LUNs
++#
++CONFIG_SCSI_MULTI_LUN=y
++# CONFIG_SCSI_CONSTANTS is not set
++# CONFIG_SCSI_LOGGING is not set
++# CONFIG_SCSI_SCAN_ASYNC is not set
++CONFIG_SCSI_WAIT_SCAN=m
++
++#
++# SCSI Transports
++#
++# CONFIG_SCSI_SPI_ATTRS is not set
++# CONFIG_SCSI_FC_ATTRS is not set
++# CONFIG_SCSI_ISCSI_ATTRS is not set
++# CONFIG_SCSI_SAS_LIBSAS is not set
++# CONFIG_SCSI_SRP_ATTRS is not set
++CONFIG_SCSI_LOWLEVEL=y
++# CONFIG_ISCSI_TCP is not set
++# CONFIG_SCSI_DEBUG is not set
++CONFIG_ATA=y
++# CONFIG_ATA_NONSTANDARD is not set
++CONFIG_SATA_OX810=y
++# CONFIG_SATA_HIPOX_SINGLE_SATA is not set
++# CONFIG_SATA_HIPOX_DISK_LIGHT is not set
++CONFIG_MD=y
++CONFIG_BLK_DEV_MD=y
++CONFIG_MD_LINEAR=y
++# CONFIG_MD_RAID0 is not set
++CONFIG_MD_RAID1=y
++# CONFIG_MD_RAID10 is not set
++# CONFIG_MD_RAID456 is not set
++# CONFIG_MD_MULTIPATH is not set
++# CONFIG_MD_FAULTY is not set
++CONFIG_BLK_DEV_DM=y
++# CONFIG_DM_DEBUG is not set
++CONFIG_DM_CRYPT=y
++# CONFIG_DM_SNAPSHOT is not set
++# CONFIG_DM_MIRROR is not set
++# CONFIG_DM_ZERO is not set
++# CONFIG_DM_MULTIPATH is not set
++# CONFIG_DM_DELAY is not set
++# CONFIG_DM_UEVENT is not set
++CONFIG_NETDEVICES=y
++# CONFIG_NETDEVICES_MULTIQUEUE is not set
++# CONFIG_DUMMY is not set
++# CONFIG_BONDING is not set
++# CONFIG_MACVLAN is not set
++# CONFIG_EQUALIZER is not set
++# CONFIG_TUN is not set
++# CONFIG_VETH is not set
++# CONFIG_NET_ETHERNET is not set
++CONFIG_MII=y
++CONFIG_NETDEV_1000=y
++CONFIG_SYNOPSYS_GMAC=y
++# CONFIG_NETDEV_10000 is not set
++
++#
++# Wireless LAN
++#
++# CONFIG_WLAN_PRE80211 is not set
++# CONFIG_WLAN_80211 is not set
++
++#
++# USB Network Adapters
++#
++# CONFIG_USB_CATC is not set
++# CONFIG_USB_KAWETH is not set
++# CONFIG_USB_PEGASUS is not set
++# CONFIG_USB_RTL8150 is not set
++# CONFIG_USB_USBNET is not set
++# CONFIG_WAN is not set
++# CONFIG_PPP is not set
++# CONFIG_SLIP is not set
++# CONFIG_SHAPER is not set
++# CONFIG_NETCONSOLE is not set
++# CONFIG_NETPOLL is not set
++# CONFIG_NET_POLL_CONTROLLER is not set
++# CONFIG_ISDN is not set
++
++#
++# Input device support
++#
++CONFIG_INPUT=y
++# CONFIG_INPUT_FF_MEMLESS is not set
++# CONFIG_INPUT_POLLDEV is not set
++
++#
++# Userland interfaces
++#
++CONFIG_INPUT_MOUSEDEV=y
++# CONFIG_INPUT_MOUSEDEV_PSAUX is not set
++CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024
++CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
++# CONFIG_INPUT_JOYDEV is not set
++# CONFIG_INPUT_EVDEV is not set
++# CONFIG_INPUT_EVBUG is not set
++
++#
++# Input Device Drivers
++#
++# CONFIG_INPUT_KEYBOARD is not set
++# CONFIG_INPUT_MOUSE is not set
++# CONFIG_INPUT_JOYSTICK is not set
++# CONFIG_INPUT_TABLET is not set
++# CONFIG_INPUT_TOUCHSCREEN is not set
++# CONFIG_INPUT_MISC is not set
++
++#
++# Hardware I/O ports
++#
++# CONFIG_SERIO is not set
++# CONFIG_GAMEPORT is not set
++
++#
++# Character devices
++#
++CONFIG_VT=y
++CONFIG_VT_CONSOLE=y
++CONFIG_HW_CONSOLE=y
++# CONFIG_VT_HW_CONSOLE_BINDING is not set
++# CONFIG_SERIAL_NONSTANDARD is not set
++
++#
++# Serial drivers
++#
++CONFIG_SERIAL_8250=y
++CONFIG_SERIAL_8250_CONSOLE=y
++CONFIG_SERIAL_8250_NR_UARTS=4
++CONFIG_SERIAL_8250_RUNTIME_UARTS=4
++# CONFIG_SERIAL_8250_EXTENDED is not set
++
++#
++# Non-8250 serial port support
++#
++# CONFIG_SERIAL_AMBA_PL010 is not set
++# CONFIG_SERIAL_AMBA_PL011 is not set
++CONFIG_SERIAL_CORE=y
++CONFIG_SERIAL_CORE_CONSOLE=y
++CONFIG_UNIX98_PTYS=y
++# CONFIG_LEGACY_PTYS is not set
++# CONFIG_IPMI_HANDLER is not set
++CONFIG_HW_RANDOM=m
++# CONFIG_NVRAM is not set
++# CONFIG_R3964 is not set
++# CONFIG_RAW_DRIVER is not set
++# CONFIG_TCG_TPM is not set
++CONFIG_I2C=m
++CONFIG_I2C_BOARDINFO=y
++# CONFIG_I2C_CHARDEV is not set
++
++#
++# I2C Algorithms
++#
++CONFIG_I2C_ALGOBIT=m
++# CONFIG_I2C_ALGOPCF is not set
++# CONFIG_I2C_ALGOPCA is not set
++# CONFIG_I2C_ALGOOXSEMI is not set
++
++#
++# I2C Hardware Bus support
++#
++CONFIG_I2C_HIPOX_BITBASH=m
++# CONFIG_I2C_OCORES is not set
++# CONFIG_I2C_PARPORT_LIGHT is not set
++# CONFIG_I2C_SIMTEC is not set
++# CONFIG_I2C_TAOS_EVM is not set
++# CONFIG_I2C_STUB is not set
++# CONFIG_I2C_TINY_USB is not set
++
++#
++# Miscellaneous I2C Chip support
++#
++# CONFIG_SENSORS_DS1337 is not set
++# CONFIG_SENSORS_DS1374 is not set
++# CONFIG_DS1682 is not set
++# CONFIG_SENSORS_EEPROM is not set
++# CONFIG_SENSORS_PCF8574 is not set
++# CONFIG_SENSORS_PCA9539 is not set
++# CONFIG_SENSORS_PCF8591 is not set
++# CONFIG_SENSORS_MAX6875 is not set
++# CONFIG_SENSORS_TSL2550 is not set
++# CONFIG_I2C_DEBUG_CORE is not set
++# CONFIG_I2C_DEBUG_ALGO is not set
++# CONFIG_I2C_DEBUG_BUS is not set
++# CONFIG_I2C_DEBUG_CHIP is not set
++
++#
++# SPI support
++#
++# CONFIG_SPI is not set
++# CONFIG_SPI_MASTER is not set
++# CONFIG_W1 is not set
++# CONFIG_POWER_SUPPLY is not set
++# CONFIG_HWMON is not set
++# CONFIG_WATCHDOG is not set
++
++#
++# Sonics Silicon Backplane
++#
++CONFIG_SSB_POSSIBLE=y
++# CONFIG_SSB is not set
++
++#
++# Multifunction device drivers
++#
++# CONFIG_MFD_SM501 is not set
++
++#
++# Multimedia devices
++#
++# CONFIG_VIDEO_DEV is not set
++# CONFIG_DVB_CORE is not set
++CONFIG_DAB=y
++# CONFIG_USB_DABUSB is not set
++
++#
++# Graphics support
++#
++# CONFIG_VGASTATE is not set
++CONFIG_VIDEO_OUTPUT_CONTROL=m
++# CONFIG_FB is not set
++# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
++
++#
++# Display device support
++#
++# CONFIG_DISPLAY_SUPPORT is not set
++
++#
++# Console display driver support
++#
++# CONFIG_VGA_CONSOLE is not set
++CONFIG_DUMMY_CONSOLE=y
++
++#
++# Sound
++#
++# CONFIG_SOUND is not set
++# CONFIG_HID_SUPPORT is not set
++CONFIG_USB_SUPPORT=y
++CONFIG_USB_ARCH_HAS_HCD=y
++CONFIG_USB_ARCH_HAS_OHCI=y
++CONFIG_USB_ARCH_HAS_EHCI=y
++CONFIG_USB=m
++# CONFIG_USB_DEBUG is not set
++
++#
++# Miscellaneous USB options
++#
++CONFIG_USB_DEVICEFS=y
++CONFIG_USB_DEVICE_CLASS=y
++# CONFIG_USB_DYNAMIC_MINORS is not set
++# CONFIG_USB_OTG is not set
++
++#
++# USB Host Controller Drivers
++#
++CONFIG_USB_EHCI_HCD=m
++# CONFIG_USB_EHCI_SPLIT_ISO is not set
++CONFIG_USB_EHCI_ROOT_HUB_TT=y
++# CONFIG_USB_EHCI_TT_NEWSCHED is not set
++# CONFIG_USB_ISP116X_HCD is not set
++# CONFIG_USB_OHCI_HCD is not set
++# CONFIG_USB_SL811_HCD is not set
++# CONFIG_USB_R8A66597_HCD is not set
++
++#
++# USB Device Class drivers
++#
++# CONFIG_USB_ACM is not set
++# CONFIG_USB_PRINTER is not set
++
++#
++# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support'
++#
++
++#
++# may also be needed; see USB_STORAGE Help for more information
++#
++CONFIG_USB_STORAGE=m
++# CONFIG_USB_STORAGE_DEBUG is not set
++# CONFIG_USB_STORAGE_DATAFAB is not set
++# CONFIG_USB_STORAGE_FREECOM is not set
++# CONFIG_USB_STORAGE_ISD200 is not set
++# CONFIG_USB_STORAGE_DPCM is not set
++# CONFIG_USB_STORAGE_USBAT is not set
++# CONFIG_USB_STORAGE_SDDR09 is not set
++# CONFIG_USB_STORAGE_SDDR55 is not set
++# CONFIG_USB_STORAGE_JUMPSHOT is not set
++# CONFIG_USB_STORAGE_ALAUDA is not set
++# CONFIG_USB_STORAGE_KARMA is not set
++# CONFIG_USB_LIBUSUAL is not set
++
++#
++# USB Imaging devices
++#
++# CONFIG_USB_MDC800 is not set
++# CONFIG_USB_MICROTEK is not set
++# CONFIG_USB_MON is not set
++
++#
++# USB port drivers
++#
++
++#
++# USB Serial Converter support
++#
++# CONFIG_USB_SERIAL is not set
++
++#
++# USB Miscellaneous drivers
++#
++# CONFIG_USB_EMI62 is not set
++# CONFIG_USB_EMI26 is not set
++# CONFIG_USB_ADUTUX is not set
++# CONFIG_USB_AUERSWALD is not set
++# CONFIG_USB_RIO500 is not set
++# CONFIG_USB_LEGOTOWER is not set
++# CONFIG_USB_LCD is not set
++# CONFIG_USB_BERRY_CHARGE is not set
++# CONFIG_USB_LED is not set
++# CONFIG_USB_CYPRESS_CY7C63 is not set
++# CONFIG_USB_CYTHERM is not set
++# CONFIG_USB_PHIDGET is not set
++# CONFIG_USB_IDMOUSE is not set
++# CONFIG_USB_FTDI_ELAN is not set
++# CONFIG_USB_APPLEDISPLAY is not set
++# CONFIG_USB_SISUSBVGA is not set
++# CONFIG_USB_LD is not set
++# CONFIG_USB_TRANCEVIBRATOR is not set
++# CONFIG_USB_IOWARRIOR is not set
++CONFIG_USB_TEST=m
++
++#
++# USB DSL modem support
++#
++
++#
++# USB Gadget Support
++#
++# CONFIG_USB_GADGET is not set
++# CONFIG_MMC is not set
++CONFIG_NEW_LEDS=y
++CONFIG_LEDS_CLASS=y
++
++#
++# LED drivers
++#
++CONFIG_WDC_LEDS_HIPOX800=m
++# CONFIG_HIPOX_WD810_LEDS is not set
++
++#
++# LED Triggers
++#
++CONFIG_LEDS_TRIGGERS=y
++# CONFIG_LEDS_TRIGGER_TIMER is not set
++CONFIG_WDC_LEDS_TRIGGER_SATA_DISK=y
++# CONFIG_LEDS_TRIGGER_HEARTBEAT is not set
++CONFIG_RTC_LIB=y
++CONFIG_RTC_CLASS=m
++
++#
++# RTC interfaces
++#
++CONFIG_RTC_INTF_SYSFS=y
++CONFIG_RTC_INTF_PROC=y
++CONFIG_RTC_INTF_DEV=y
++# CONFIG_RTC_INTF_DEV_UIE_EMUL is not set
++# CONFIG_RTC_DRV_TEST is not set
++
++#
++# I2C RTC drivers
++#
++CONFIG_RTC_DRV_DS1307=m
++# CONFIG_RTC_DRV_DS1374 is not set
++# CONFIG_RTC_DRV_DS1672 is not set
++# CONFIG_RTC_DRV_MAX6900 is not set
++# CONFIG_RTC_DRV_RS5C372 is not set
++# CONFIG_RTC_DRV_ISL1208 is not set
++# CONFIG_RTC_DRV_X1205 is not set
++# CONFIG_RTC_DRV_PCF8563 is not set
++# CONFIG_RTC_DRV_PCF8583 is not set
++# CONFIG_RTC_DRV_M41T80 is not set
++
++#
++# SPI RTC drivers
++#
++
++#
++# Platform RTC drivers
++#
++# CONFIG_RTC_DRV_CMOS is not set
++# CONFIG_RTC_DRV_DS1553 is not set
++# CONFIG_RTC_DRV_STK17TA8 is not set
++# CONFIG_RTC_DRV_DS1742 is not set
++# CONFIG_RTC_DRV_M48T86 is not set
++# CONFIG_RTC_DRV_M48T59 is not set
++# CONFIG_RTC_DRV_V3020 is not set
++
++#
++# on-CPU RTC drivers
++#
++# CONFIG_RTC_DRV_PL031 is not set
++# CONFIG_DMADEVICES is not set
++
++#
++# File systems
++#
++CONFIG_EXT2_FS=y
++# CONFIG_EXT2_FS_XATTR is not set
++# CONFIG_EXT2_FS_XIP is not set
++CONFIG_EXT3_FS=y
++# CONFIG_EXT3_FS_XATTR is not set
++# CONFIG_EXT4DEV_FS is not set
++CONFIG_JBD=y
++# CONFIG_REISERFS_FS is not set
++# CONFIG_JFS_FS is not set
++CONFIG_FS_POSIX_ACL=y
++CONFIG_XFS_FS=y
++# CONFIG_XFS_QUOTA is not set
++# CONFIG_XFS_SECURITY is not set
++# CONFIG_XFS_POSIX_ACL is not set
++# CONFIG_XFS_RT is not set
++# CONFIG_GFS2_FS is not set
++# CONFIG_OCFS2_FS is not set
++# CONFIG_MINIX_FS is not set
++# CONFIG_ROMFS_FS is not set
++CONFIG_INOTIFY=y
++CONFIG_INOTIFY_USER=y
++# CONFIG_QUOTA is not set
++CONFIG_DNOTIFY=y
++# CONFIG_AUTOFS_FS is not set
++# CONFIG_AUTOFS4_FS is not set
++CONFIG_FUSE_FS=y
++
++#
++# CD-ROM/DVD Filesystems
++#
++# CONFIG_ISO9660_FS is not set
++# CONFIG_UDF_FS is not set
++
++#
++# DOS/FAT/NT Filesystems
++#
++CONFIG_FAT_FS=y
++CONFIG_MSDOS_FS=y
++CONFIG_VFAT_FS=m
++CONFIG_FAT_DEFAULT_CODEPAGE=437
++CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1"
++CONFIG_NTFS_FS=m
++# CONFIG_NTFS_DEBUG is not set
++# CONFIG_NTFS_RW is not set
++
++#
++# Pseudo filesystems
++#
++CONFIG_PROC_FS=y
++CONFIG_PROC_SYSCTL=y
++CONFIG_SYSFS=y
++# CONFIG_TMPFS is not set
++# CONFIG_HUGETLB_PAGE is not set
++# CONFIG_CONFIGFS_FS is not set
++
++#
++# Miscellaneous filesystems
++#
++# CONFIG_ADFS_FS is not set
++# CONFIG_AFFS_FS is not set
++# CONFIG_HFS_FS is not set
++CONFIG_HFSPLUS_FS=m
++# CONFIG_BEFS_FS is not set
++# CONFIG_BFS_FS is not set
++# CONFIG_EFS_FS is not set
++# CONFIG_CRAMFS is not set
++# CONFIG_VXFS_FS is not set
++# CONFIG_HPFS_FS is not set
++# CONFIG_QNX4FS_FS is not set
++# CONFIG_SYSV_FS is not set
++# CONFIG_UFS_FS is not set
++CONFIG_NETWORK_FILESYSTEMS=y
++# CONFIG_NFS_FS is not set
++CONFIG_NFSD=m
++CONFIG_NFSD_V2_ACL=y
++CONFIG_NFSD_V3=y
++CONFIG_NFSD_V3_ACL=y
++# CONFIG_NFSD_V4 is not set
++CONFIG_NFSD_TCP=y
++CONFIG_LOCKD=m
++CONFIG_LOCKD_V4=y
++CONFIG_EXPORTFS=m
++CONFIG_NFS_ACL_SUPPORT=m
++CONFIG_NFS_COMMON=y
++CONFIG_SUNRPC=m
++# CONFIG_SUNRPC_BIND34 is not set
++# CONFIG_RPCSEC_GSS_KRB5 is not set
++# CONFIG_RPCSEC_GSS_SPKM3 is not set
++# CONFIG_SMB_FS is not set
++# CONFIG_CIFS is not set
++# CONFIG_NCP_FS is not set
++# CONFIG_CODA_FS is not set
++# CONFIG_AFS_FS is not set
++
++#
++# Partition Types
++#
++CONFIG_PARTITION_ADVANCED=y
++# CONFIG_ACORN_PARTITION is not set
++# CONFIG_OSF_PARTITION is not set
++# CONFIG_AMIGA_PARTITION is not set
++# CONFIG_ATARI_PARTITION is not set
++CONFIG_MAC_PARTITION=y
++CONFIG_MSDOS_PARTITION=y
++# CONFIG_BSD_DISKLABEL is not set
++# CONFIG_MINIX_SUBPARTITION is not set
++# CONFIG_SOLARIS_X86_PARTITION is not set
++# CONFIG_UNIXWARE_DISKLABEL is not set
++CONFIG_LDM_PARTITION=y
++# CONFIG_LDM_DEBUG is not set
++# CONFIG_SGI_PARTITION is not set
++# CONFIG_ULTRIX_PARTITION is not set
++# CONFIG_SUN_PARTITION is not set
++# CONFIG_KARMA_PARTITION is not set
++CONFIG_EFI_PARTITION=y
++# CONFIG_SYSV68_PARTITION is not set
++CONFIG_NLS=y
++CONFIG_NLS_DEFAULT="iso8859-1"
++CONFIG_NLS_CODEPAGE_437=m
++# CONFIG_NLS_CODEPAGE_737 is not set
++# CONFIG_NLS_CODEPAGE_775 is not set
++# CONFIG_NLS_CODEPAGE_850 is not set
++# CONFIG_NLS_CODEPAGE_852 is not set
++# CONFIG_NLS_CODEPAGE_855 is not set
++# CONFIG_NLS_CODEPAGE_857 is not set
++# CONFIG_NLS_CODEPAGE_860 is not set
++# CONFIG_NLS_CODEPAGE_861 is not set
++# CONFIG_NLS_CODEPAGE_862 is not set
++# CONFIG_NLS_CODEPAGE_863 is not set
++# CONFIG_NLS_CODEPAGE_864 is not set
++# CONFIG_NLS_CODEPAGE_865 is not set
++# CONFIG_NLS_CODEPAGE_866 is not set
++# CONFIG_NLS_CODEPAGE_869 is not set
++# CONFIG_NLS_CODEPAGE_936 is not set
++# CONFIG_NLS_CODEPAGE_950 is not set
++# CONFIG_NLS_CODEPAGE_932 is not set
++# CONFIG_NLS_CODEPAGE_949 is not set
++# CONFIG_NLS_CODEPAGE_874 is not set
++# CONFIG_NLS_ISO8859_8 is not set
++# CONFIG_NLS_CODEPAGE_1250 is not set
++# CONFIG_NLS_CODEPAGE_1251 is not set
++# CONFIG_NLS_ASCII is not set
++CONFIG_NLS_ISO8859_1=m
++# CONFIG_NLS_ISO8859_2 is not set
++# CONFIG_NLS_ISO8859_3 is not set
++# CONFIG_NLS_ISO8859_4 is not set
++# CONFIG_NLS_ISO8859_5 is not set
++# CONFIG_NLS_ISO8859_6 is not set
++# CONFIG_NLS_ISO8859_7 is not set
++# CONFIG_NLS_ISO8859_9 is not set
++# CONFIG_NLS_ISO8859_13 is not set
++# CONFIG_NLS_ISO8859_14 is not set
++# CONFIG_NLS_ISO8859_15 is not set
++# CONFIG_NLS_KOI8_R is not set
++# CONFIG_NLS_KOI8_U is not set
++CONFIG_NLS_UTF8=y
++# CONFIG_DLM is not set
++# CONFIG_INSTRUMENTATION is not set
++
++#
++# Kernel hacking
++#
++# CONFIG_PRINTK_TIME is not set
++CONFIG_ENABLE_WARN_DEPRECATED=y
++CONFIG_ENABLE_MUST_CHECK=y
++# CONFIG_MAGIC_SYSRQ is not set
++# CONFIG_UNUSED_SYMBOLS is not set
++# CONFIG_DEBUG_FS is not set
++# CONFIG_HEADERS_CHECK is not set
++# CONFIG_DEBUG_KERNEL is not set
++CONFIG_DEBUG_BUGVERBOSE=y
++CONFIG_FRAME_POINTER=y
++# CONFIG_SAMPLES is not set
++# CONFIG_DEBUG_USER is not set
++
++#
++# Security options
++#
++# CONFIG_KEYS is not set
++CONFIG_SECURITY=y
++# CONFIG_SECURITY_NETWORK is not set
++# CONFIG_SECURITY_CAPABILITIES is not set
++CONFIG_SECURITY_TRUSTEES=y
++# CONFIG_SECURITY_TRUSTEES_DEBUG is not set
++CONFIG_CRYPTO=y
++CONFIG_CRYPTO_ALGAPI=y
++CONFIG_CRYPTO_BLKCIPHER=y
++CONFIG_CRYPTO_MANAGER=y
++# CONFIG_CRYPTO_HMAC is not set
++# CONFIG_CRYPTO_XCBC is not set
++# CONFIG_CRYPTO_NULL is not set
++# CONFIG_CRYPTO_MD4 is not set
++# CONFIG_CRYPTO_MD5 is not set
++# CONFIG_CRYPTO_SHA1 is not set
++# CONFIG_CRYPTO_SHA256 is not set
++# CONFIG_CRYPTO_SHA512 is not set
++# CONFIG_CRYPTO_WP512 is not set
++# CONFIG_CRYPTO_TGR192 is not set
++# CONFIG_CRYPTO_GF128MUL is not set
++CONFIG_CRYPTO_ECB=m
++CONFIG_CRYPTO_CBC=y
++CONFIG_CRYPTO_PCBC=m
++# CONFIG_CRYPTO_LRW is not set
++# CONFIG_CRYPTO_XTS is not set
++# CONFIG_CRYPTO_CRYPTD is not set
++# CONFIG_CRYPTO_DES is not set
++# CONFIG_CRYPTO_FCRYPT is not set
++# CONFIG_CRYPTO_BLOWFISH is not set
++# CONFIG_CRYPTO_TWOFISH is not set
++# CONFIG_CRYPTO_SERPENT is not set
++CONFIG_CRYPTO_AES=m
++# CONFIG_CRYPTO_CAST5 is not set
++# CONFIG_CRYPTO_CAST6 is not set
++# CONFIG_CRYPTO_TEA is not set
++CONFIG_CRYPTO_ARC4=m
++# CONFIG_CRYPTO_KHAZAD is not set
++# CONFIG_CRYPTO_ANUBIS is not set
++# CONFIG_CRYPTO_SEED is not set
++# CONFIG_CRYPTO_DEFLATE is not set
++CONFIG_CRYPTO_MICHAEL_MIC=m
++# CONFIG_CRYPTO_CRC32C is not set
++# CONFIG_CRYPTO_CAMELLIA is not set
++# CONFIG_CRYPTO_TEST is not set
++# CONFIG_CRYPTO_AUTHENC is not set
++CONFIG_CRYPTO_HW=y
++
++#
++# Library routines
++#
++CONFIG_BITREVERSE=y
++CONFIG_CRC_CCITT=y
++# CONFIG_CRC16 is not set
++# CONFIG_CRC_ITU_T is not set
++CONFIG_CRC32=y
++# CONFIG_CRC7 is not set
++# CONFIG_LIBCRC32C is not set
++CONFIG_PLIST=y
++CONFIG_HAS_IOMEM=y
++CONFIG_HAS_IOPORT=y
++CONFIG_HAS_DMA=y
+diff -Nurd linux-2.6.24/arch/arm/configs/hipox_810_eabi_wd_prod_defconfig linux-2.6.24-oxe810/arch/arm/configs/hipox_810_eabi_wd_prod_defconfig
+--- linux-2.6.24/arch/arm/configs/hipox_810_eabi_wd_prod_defconfig 1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.24-oxe810/arch/arm/configs/hipox_810_eabi_wd_prod_defconfig 2008-06-11 17:47:52.000000000 +0200
+@@ -0,0 +1,1108 @@
++#
++# Automatically generated make config: don't edit
++# Linux kernel version: 2.6.24.4
++# Thu Jun 5 16:08:07 2008
++#
++CONFIG_ARM=y
++CONFIG_SYS_SUPPORTS_APM_EMULATION=y
++# CONFIG_GENERIC_GPIO is not set
++# CONFIG_GENERIC_TIME is not set
++# CONFIG_GENERIC_CLOCKEVENTS is not set
++CONFIG_MMU=y
++# CONFIG_NO_IOPORT is not set
++CONFIG_GENERIC_HARDIRQS=y
++CONFIG_STACKTRACE_SUPPORT=y
++CONFIG_LOCKDEP_SUPPORT=y
++CONFIG_TRACE_IRQFLAGS_SUPPORT=y
++CONFIG_HARDIRQS_SW_RESEND=y
++CONFIG_GENERIC_IRQ_PROBE=y
++CONFIG_RWSEM_GENERIC_SPINLOCK=y
++# CONFIG_ARCH_HAS_ILOG2_U32 is not set
++# CONFIG_ARCH_HAS_ILOG2_U64 is not set
++CONFIG_GENERIC_HWEIGHT=y
++CONFIG_GENERIC_CALIBRATE_DELAY=y
++CONFIG_ZONE_DMA=y
++CONFIG_VECTORS_BASE=0xffff0000
++CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
++
++#
++# General setup
++#
++CONFIG_EXPERIMENTAL=y
++CONFIG_BROKEN_ON_SMP=y
++CONFIG_INIT_ENV_ARG_LIMIT=32
++CONFIG_LOCALVERSION=""
++CONFIG_LOCALVERSION_AUTO=y
++CONFIG_SWAP=y
++CONFIG_SYSVIPC=y
++CONFIG_SYSVIPC_SYSCTL=y
++# CONFIG_POSIX_MQUEUE is not set
++# CONFIG_BSD_PROCESS_ACCT is not set
++# CONFIG_TASKSTATS is not set
++# CONFIG_USER_NS is not set
++# CONFIG_PID_NS is not set
++# CONFIG_AUDIT is not set
++# CONFIG_IKCONFIG is not set
++CONFIG_LOG_BUF_SHIFT=14
++# CONFIG_CGROUPS is not set
++# CONFIG_FAIR_GROUP_SCHED is not set
++CONFIG_SYSFS_DEPRECATED=y
++# CONFIG_RELAY is not set
++CONFIG_BLK_DEV_INITRD=y
++CONFIG_INITRAMFS_SOURCE=""
++# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
++CONFIG_SYSCTL=y
++# CONFIG_EMBEDDED is not set
++CONFIG_UID16=y
++CONFIG_SYSCTL_SYSCALL=y
++CONFIG_KALLSYMS=y
++# CONFIG_KALLSYMS_EXTRA_PASS is not set
++CONFIG_HOTPLUG=y
++CONFIG_PRINTK=y
++CONFIG_BUG=y
++CONFIG_ELF_CORE=y
++CONFIG_BASE_FULL=y
++CONFIG_FUTEX=y
++CONFIG_ANON_INODES=y
++CONFIG_EPOLL=y
++CONFIG_SIGNALFD=y
++CONFIG_EVENTFD=y
++CONFIG_SHMEM=y
++CONFIG_VM_EVENT_COUNTERS=y
++CONFIG_SLAB=y
++# CONFIG_SLUB is not set
++# CONFIG_SLOB is not set
++CONFIG_SLABINFO=y
++CONFIG_RT_MUTEXES=y
++# CONFIG_TINY_SHMEM is not set
++CONFIG_BASE_SMALL=0
++CONFIG_MODULES=y
++CONFIG_MODULE_UNLOAD=y
++# CONFIG_MODULE_FORCE_UNLOAD is not set
++# CONFIG_MODVERSIONS is not set
++# CONFIG_MODULE_SRCVERSION_ALL is not set
++# CONFIG_KMOD is not set
++CONFIG_BLOCK=y
++# CONFIG_LBD is not set
++# CONFIG_BLK_DEV_IO_TRACE is not set
++# CONFIG_LSF is not set
++# CONFIG_BLK_DEV_BSG is not set
++
++#
++# IO Schedulers
++#
++CONFIG_IOSCHED_NOOP=y
++CONFIG_IOSCHED_AS=y
++CONFIG_IOSCHED_DEADLINE=y
++CONFIG_IOSCHED_CFQ=y
++CONFIG_DEFAULT_AS=y
++# CONFIG_DEFAULT_DEADLINE is not set
++# CONFIG_DEFAULT_CFQ is not set
++# CONFIG_DEFAULT_NOOP is not set
++CONFIG_DEFAULT_IOSCHED="anticipatory"
++
++#
++# System Type
++#
++# CONFIG_ARCH_AAEC2000 is not set
++# CONFIG_ARCH_INTEGRATOR is not set
++# CONFIG_ARCH_REALVIEW is not set
++# CONFIG_ARCH_VERSATILE is not set
++# CONFIG_ARCH_AT91 is not set
++# CONFIG_ARCH_CLPS7500 is not set
++# CONFIG_ARCH_CLPS711X is not set
++# CONFIG_ARCH_CO285 is not set
++# CONFIG_ARCH_EBSA110 is not set
++# CONFIG_ARCH_EP93XX is not set
++# CONFIG_ARCH_FOOTBRIDGE is not set
++# CONFIG_ARCH_NETX is not set
++# CONFIG_ARCH_H720X is not set
++# CONFIG_ARCH_IMX is not set
++# CONFIG_ARCH_IOP13XX is not set
++# CONFIG_ARCH_IOP32X is not set
++# CONFIG_ARCH_IOP33X is not set
++# CONFIG_ARCH_IXP23XX is not set
++# CONFIG_ARCH_IXP2000 is not set
++# CONFIG_ARCH_IXP4XX is not set
++# CONFIG_ARCH_L7200 is not set
++# CONFIG_ARCH_KS8695 is not set
++# CONFIG_ARCH_NS9XXX is not set
++# CONFIG_ARCH_MXC is not set
++# CONFIG_ARCH_PNX4008 is not set
++# CONFIG_ARCH_PXA is not set
++# CONFIG_ARCH_RPC is not set
++# CONFIG_ARCH_SA1100 is not set
++# CONFIG_ARCH_S3C2410 is not set
++# CONFIG_ARCH_SHARK is not set
++# CONFIG_ARCH_LH7A40X is not set
++# CONFIG_ARCH_DAVINCI is not set
++# CONFIG_ARCH_OMAP is not set
++CONFIG_ARCH_HIPOX=y
++
++#
++# Boot options
++#
++
++#
++# Power management
++#
++
++#
++# Oxford Semiconductor NAS Options
++#
++# CONFIG_ARCH_HIPOX_FPGA is not set
++CONFIG_NOMINAL_PLL400_FREQ=733333333
++CONFIG_NOMINAL_RPSCLK_FREQ=25000000
++# CONFIG_HIPOX_VERSION_0X800 is not set
++CONFIG_HIPOX_VERSION_0X810=y
++# CONFIG_HIPOX_VERSION_0X850 is not set
++# CONFIG_ARCH_HIPOX_UART1 is not set
++CONFIG_ARCH_HIPOX_UART2=y
++# CONFIG_ARCH_HIPOX_UART2_MODEM is not set
++# CONFIG_ARCH_HIPOX_UART3 is not set
++# CONFIG_ARCH_HIPOX_UART4 is not set
++CONFIG_HIPOX_SATA_POWER_1=y
++CONFIG_HIPOX_SATA_POWER_GPIO_1=31
++CONFIG_HIPOX_SATA_POWER_2=y
++CONFIG_HIPOX_SATA_POWER_GPIO_2=32
++CONFIG_FORCE_MAX_ZONEORDER=10
++CONFIG_SRAM_NUM_PAGES=32
++CONFIG_SUPPORT_LEON=y
++CONFIG_LEON_PAGES=2
++CONFIG_LEON_COPRO=y
++CONFIG_LEON_OFFLOAD_TX=y
++# CONFIG_LEON_RESERVE_DMA_CHANNEL is not set
++CONFIG_LEON_OFFLOAD_TSO=y
++# CONFIG_LEON_START_EARLY is not set
++CONFIG_LEON_POWER_BUTTON_MONITOR=m
++CONFIG_HIPOX_POWER_BUTTON_GPIO=0
++CONFIG_USER_RECOVERY_BUTTON_MONITOR=y
++CONFIG_HIPOX_USER_RECOVERY_BUTTON_GPIO=4
++# CONFIG_HIPOX_DDR_MON is not set
++# CONFIG_HIPOX_AHB_MON is not set
++# CONFIG_HIPOX_CACHE_LOCKDOWN is not set
++# CONFIG_DO_MEM_TEST is not set
++# CONFIG_CRYPTO_OXAESLRW is not set
++CONFIG_DESCRIPTORS_PAGES=6
++CONFIG_ARCH_HIPOX_NUM_GMAC_DESCRIPTORS=192
++CONFIG_ARCH_HIPOX_MAX_SATA_SG_ENTRIES=256
++CONFIG_TACHO_THERM_AND_FAN=m
++# CONFIG_GPIO_TEST is not set
++CONFIG_HIPOX_RTC=m
++# CONFIG_I2S is not set
++# CONFIG_DPE_TEST is not set
++# CONFIG_HIPOX_INSTRUMENT_COPIES is not set
++# CONFIG_HIPOX_DMA_COPIES is not set
++# CONFIG_HIPOX_AHB_MONITOR_MODULE is not set
++# CONFIG_HIPOX_USB_TEST_MODES is not set
++# CONFIG_HIPOX_FRONT_LAMP_CONTROL is not set
++# CONFIG_LEDS_TRIGGER_SATA_DISK is not set
++# CONFIG_HIPOX_LED_TEST is not set
++CONFIG_HIPOX_I2C_SDA=3
++CONFIG_HIPOX_I2C_SCL=2
++CONFIG_HIPOX_USB_PORTA_POWER_CONTROL=y
++# CONFIG_HIPOX_USB_PORTB_POWER_CONTROL is not set
++# CONFIG_HIPOX_USB_PORTC_POWER_CONTROL is not set
++CONFIG_HIPOX_USB_OVERCURRENT_POLARITY_NEGATIVE=y
++CONFIG_HIPOX_USB_POWER_SWITCH_POLARITY_NEGATIVE=y
++# CONFIG_WDC_FAN_HIPOX800 is not set
++# CONFIG_HIPOX_MAP_SRAM is not set
++# CONFIG_HIPOX_SUID_INHERIT is not set
++CONFIG_HIPOX_USB_HUB_SUPPORT=y
++CONFIG_HIPOX_USB_CKOUT=y
++CONFIG_HIPOX_USB_HUB_RESET_CONTROL=y
++CONFIG_HIPOX_USB_HUB_RESET_GPIO=27
++CONFIG_HIPOX_USB_HUB_RESET_ACTIVE_HIGH=0
++CONFIG_HIPOX_USB_HUB_RESET_TOGGLE=y
++CONFIG_HIPOX_USB_HUB_RESET_PERIOD_MS=100
++
++#
++# Processor Type
++#
++CONFIG_CPU_32=y
++CONFIG_CPU_ARM926T=y
++CONFIG_CPU_32v5=y
++CONFIG_CPU_ABRT_EV5TJ=y
++CONFIG_CPU_CACHE_VIVT=y
++CONFIG_CPU_COPY_V4WB=y
++CONFIG_CPU_TLB_V4WBI=y
++CONFIG_CPU_CP15=y
++CONFIG_CPU_CP15_MMU=y
++
++#
++# Processor Features
++#
++CONFIG_ARM_THUMB=y
++# CONFIG_CPU_ICACHE_DISABLE is not set
++# CONFIG_CPU_DCACHE_DISABLE is not set
++# CONFIG_CPU_DCACHE_WRITETHROUGH is not set
++# CONFIG_CPU_CACHE_ROUND_ROBIN is not set
++# CONFIG_OUTER_CACHE is not set
++
++#
++# Bus support
++#
++CONFIG_ARM_AMBA=y
++# CONFIG_PCI is not set
++# CONFIG_PCI_SYSCALL is not set
++# CONFIG_ARCH_SUPPORTS_MSI is not set
++# CONFIG_PCCARD is not set
++
++#
++# Kernel Features
++#
++# CONFIG_TICK_ONESHOT is not set
++# CONFIG_PREEMPT is not set
++# CONFIG_NO_IDLE_HZ is not set
++CONFIG_HZ=100
++CONFIG_AEABI=y
++CONFIG_OABI_COMPAT=y
++# CONFIG_ARCH_DISCONTIGMEM_ENABLE is not set
++CONFIG_SELECT_MEMORY_MODEL=y
++CONFIG_FLATMEM_MANUAL=y
++# CONFIG_DISCONTIGMEM_MANUAL is not set
++# CONFIG_SPARSEMEM_MANUAL is not set
++CONFIG_FLATMEM=y
++CONFIG_FLAT_NODE_MEM_MAP=y
++# CONFIG_SPARSEMEM_STATIC is not set
++# CONFIG_SPARSEMEM_VMEMMAP_ENABLE is not set
++CONFIG_SPLIT_PTLOCK_CPUS=4096
++# CONFIG_RESOURCES_64BIT is not set
++CONFIG_ZONE_DMA_FLAG=1
++CONFIG_BOUNCE=y
++CONFIG_VIRT_TO_BUS=y
++CONFIG_ALIGNMENT_TRAP=y
++
++#
++# Boot options
++#
++CONFIG_ZBOOT_ROM_TEXT=0x0
++CONFIG_ZBOOT_ROM_BSS=0x0
++CONFIG_CMDLINE=""
++# CONFIG_XIP_KERNEL is not set
++# CONFIG_KEXEC is not set
++
++#
++# Floating point emulation
++#
++
++#
++# At least one emulation must be selected
++#
++# CONFIG_FPE_NWFPE is not set
++# CONFIG_FPE_FASTFPE is not set
++# CONFIG_VFP is not set
++
++#
++# Userspace binary formats
++#
++CONFIG_BINFMT_ELF=y
++# CONFIG_BINFMT_AOUT is not set
++# CONFIG_BINFMT_MISC is not set
++
++#
++# Power management options
++#
++# CONFIG_PM is not set
++CONFIG_SUSPEND_UP_POSSIBLE=y
++
++#
++# Networking
++#
++CONFIG_NET=y
++
++#
++# Networking options
++#
++CONFIG_PACKET=y
++CONFIG_PACKET_MMAP=y
++CONFIG_UNIX=y
++CONFIG_XFRM=y
++# CONFIG_XFRM_USER is not set
++# CONFIG_XFRM_SUB_POLICY is not set
++# CONFIG_XFRM_MIGRATE is not set
++# CONFIG_NET_KEY is not set
++CONFIG_INET=y
++CONFIG_IP_MULTICAST=y
++# CONFIG_IP_ADVANCED_ROUTER is not set
++CONFIG_IP_FIB_HASH=y
++# CONFIG_IP_PNP is not set
++# CONFIG_NET_IPIP is not set
++# CONFIG_NET_IPGRE is not set
++# CONFIG_IP_MROUTE is not set
++# CONFIG_ARPD is not set
++# CONFIG_SYN_COOKIES is not set
++# CONFIG_INET_AH is not set
++# CONFIG_INET_ESP is not set
++# CONFIG_INET_IPCOMP is not set
++# CONFIG_INET_XFRM_TUNNEL is not set
++# CONFIG_INET_TUNNEL is not set
++CONFIG_INET_XFRM_MODE_TRANSPORT=y
++CONFIG_INET_XFRM_MODE_TUNNEL=y
++CONFIG_INET_XFRM_MODE_BEET=y
++# CONFIG_INET_LRO is not set
++CONFIG_INET_DIAG=y
++CONFIG_INET_TCP_DIAG=y
++# CONFIG_TCP_CONG_ADVANCED is not set
++CONFIG_TCP_CONG_CUBIC=y
++CONFIG_DEFAULT_TCP_CONG="cubic"
++# CONFIG_TCP_MD5SIG is not set
++# CONFIG_IP_VS is not set
++# CONFIG_IPV6 is not set
++# CONFIG_INET6_XFRM_TUNNEL is not set
++# CONFIG_INET6_TUNNEL is not set
++# CONFIG_NETLABEL is not set
++# CONFIG_NETWORK_SECMARK is not set
++CONFIG_NETFILTER=y
++# CONFIG_NETFILTER_DEBUG is not set
++
++#
++# Core Netfilter Configuration
++#
++# CONFIG_NETFILTER_NETLINK is not set
++# CONFIG_NF_CONNTRACK_ENABLED is not set
++# CONFIG_NF_CONNTRACK is not set
++# CONFIG_NETFILTER_XTABLES is not set
++
++#
++# IP: Netfilter Configuration
++#
++# CONFIG_IP_NF_QUEUE is not set
++# CONFIG_IP_NF_IPTABLES is not set
++# CONFIG_IP_NF_ARPTABLES is not set
++# CONFIG_IP_DCCP is not set
++# CONFIG_IP_SCTP is not set
++# CONFIG_TIPC is not set
++# CONFIG_ATM is not set
++# CONFIG_BRIDGE is not set
++# CONFIG_VLAN_8021Q is not set
++# CONFIG_DECNET is not set
++# CONFIG_LLC2 is not set
++# CONFIG_IPX is not set
++# CONFIG_ATALK is not set
++# CONFIG_X25 is not set
++# CONFIG_LAPB is not set
++# CONFIG_ECONET is not set
++# CONFIG_WAN_ROUTER is not set
++# CONFIG_NET_SCHED is not set
++
++#
++# Network testing
++#
++# CONFIG_NET_PKTGEN is not set
++# CONFIG_HAMRADIO is not set
++# CONFIG_IRDA is not set
++# CONFIG_BT is not set
++# CONFIG_AF_RXRPC is not set
++
++#
++# Wireless
++#
++# CONFIG_CFG80211 is not set
++CONFIG_WIRELESS_EXT=y
++# CONFIG_MAC80211 is not set
++# CONFIG_IEEE80211 is not set
++# CONFIG_RFKILL is not set
++# CONFIG_NET_9P is not set
++
++#
++# Device Drivers
++#
++
++#
++# Generic Driver Options
++#
++CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
++CONFIG_STANDALONE=y
++CONFIG_PREVENT_FIRMWARE_BUILD=y
++CONFIG_FW_LOADER=y
++# CONFIG_SYS_HYPERVISOR is not set
++# CONFIG_CONNECTOR is not set
++# CONFIG_MTD is not set
++# CONFIG_PARPORT is not set
++CONFIG_BLK_DEV=y
++# CONFIG_BLK_DEV_COW_COMMON is not set
++CONFIG_BLK_DEV_LOOP=y
++# CONFIG_BLK_DEV_CRYPTOLOOP is not set
++# CONFIG_BLK_DEV_NBD is not set
++# CONFIG_BLK_DEV_UB is not set
++CONFIG_BLK_DEV_RAM=y
++CONFIG_BLK_DEV_RAM_COUNT=16
++CONFIG_BLK_DEV_RAM_SIZE=10240
++CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024
++# CONFIG_CDROM_PKTCDVD is not set
++# CONFIG_ATA_OVER_ETH is not set
++# CONFIG_MISC_DEVICES is not set
++# CONFIG_IDE is not set
++
++#
++# SCSI device support
++#
++# CONFIG_RAID_ATTRS is not set
++CONFIG_SCSI=y
++CONFIG_SCSI_DMA=y
++# CONFIG_SCSI_TGT is not set
++# CONFIG_SCSI_NETLINK is not set
++CONFIG_SCSI_PROC_FS=y
++
++#
++# SCSI support type (disk, tape, CD-ROM)
++#
++CONFIG_BLK_DEV_SD=y
++# CONFIG_CHR_DEV_ST is not set
++# CONFIG_CHR_DEV_OSST is not set
++# CONFIG_BLK_DEV_SR is not set
++# CONFIG_CHR_DEV_SG is not set
++# CONFIG_CHR_DEV_SCH is not set
++
++#
++# Some SCSI devices (e.g. CD jukebox) support multiple LUNs
++#
++CONFIG_SCSI_MULTI_LUN=y
++# CONFIG_SCSI_CONSTANTS is not set
++# CONFIG_SCSI_LOGGING is not set
++# CONFIG_SCSI_SCAN_ASYNC is not set
++CONFIG_SCSI_WAIT_SCAN=m
++
++#
++# SCSI Transports
++#
++# CONFIG_SCSI_SPI_ATTRS is not set
++# CONFIG_SCSI_FC_ATTRS is not set
++# CONFIG_SCSI_ISCSI_ATTRS is not set
++# CONFIG_SCSI_SAS_LIBSAS is not set
++# CONFIG_SCSI_SRP_ATTRS is not set
++CONFIG_SCSI_LOWLEVEL=y
++# CONFIG_ISCSI_TCP is not set
++# CONFIG_SCSI_DEBUG is not set
++CONFIG_ATA=y
++# CONFIG_ATA_NONSTANDARD is not set
++CONFIG_SATA_OX810=y
++# CONFIG_SATA_HIPOX_SINGLE_SATA is not set
++# CONFIG_SATA_HIPOX_DISK_LIGHT is not set
++CONFIG_MD=y
++CONFIG_BLK_DEV_MD=y
++CONFIG_MD_LINEAR=y
++CONFIG_MD_RAID0=y
++CONFIG_MD_RAID1=y
++# CONFIG_MD_RAID10 is not set
++# CONFIG_MD_RAID456 is not set
++# CONFIG_MD_MULTIPATH is not set
++# CONFIG_MD_FAULTY is not set
++CONFIG_BLK_DEV_DM=y
++# CONFIG_DM_DEBUG is not set
++CONFIG_DM_CRYPT=y
++# CONFIG_DM_SNAPSHOT is not set
++# CONFIG_DM_MIRROR is not set
++# CONFIG_DM_ZERO is not set
++# CONFIG_DM_MULTIPATH is not set
++# CONFIG_DM_DELAY is not set
++# CONFIG_DM_UEVENT is not set
++CONFIG_NETDEVICES=y
++# CONFIG_NETDEVICES_MULTIQUEUE is not set
++# CONFIG_DUMMY is not set
++# CONFIG_BONDING is not set
++# CONFIG_MACVLAN is not set
++# CONFIG_EQUALIZER is not set
++# CONFIG_TUN is not set
++# CONFIG_VETH is not set
++# CONFIG_NET_ETHERNET is not set
++CONFIG_MII=y
++CONFIG_NETDEV_1000=y
++CONFIG_SYNOPSYS_GMAC=y
++# CONFIG_NETDEV_10000 is not set
++
++#
++# Wireless LAN
++#
++# CONFIG_WLAN_PRE80211 is not set
++# CONFIG_WLAN_80211 is not set
++
++#
++# USB Network Adapters
++#
++# CONFIG_USB_CATC is not set
++# CONFIG_USB_KAWETH is not set
++# CONFIG_USB_PEGASUS is not set
++# CONFIG_USB_RTL8150 is not set
++# CONFIG_USB_USBNET is not set
++# CONFIG_WAN is not set
++# CONFIG_PPP is not set
++# CONFIG_SLIP is not set
++# CONFIG_SHAPER is not set
++# CONFIG_NETCONSOLE is not set
++# CONFIG_NETPOLL is not set
++# CONFIG_NET_POLL_CONTROLLER is not set
++# CONFIG_ISDN is not set
++
++#
++# Input device support
++#
++CONFIG_INPUT=y
++# CONFIG_INPUT_FF_MEMLESS is not set
++# CONFIG_INPUT_POLLDEV is not set
++
++#
++# Userland interfaces
++#
++CONFIG_INPUT_MOUSEDEV=y
++# CONFIG_INPUT_MOUSEDEV_PSAUX is not set
++CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024
++CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
++# CONFIG_INPUT_JOYDEV is not set
++# CONFIG_INPUT_EVDEV is not set
++# CONFIG_INPUT_EVBUG is not set
++
++#
++# Input Device Drivers
++#
++# CONFIG_INPUT_KEYBOARD is not set
++# CONFIG_INPUT_MOUSE is not set
++# CONFIG_INPUT_JOYSTICK is not set
++# CONFIG_INPUT_TABLET is not set
++# CONFIG_INPUT_TOUCHSCREEN is not set
++# CONFIG_INPUT_MISC is not set
++
++#
++# Hardware I/O ports
++#
++# CONFIG_SERIO is not set
++# CONFIG_GAMEPORT is not set
++
++#
++# Character devices
++#
++CONFIG_VT=y
++CONFIG_VT_CONSOLE=y
++CONFIG_HW_CONSOLE=y
++# CONFIG_VT_HW_CONSOLE_BINDING is not set
++# CONFIG_SERIAL_NONSTANDARD is not set
++
++#
++# Serial drivers
++#
++CONFIG_SERIAL_8250=y
++CONFIG_SERIAL_8250_CONSOLE=y
++CONFIG_SERIAL_8250_NR_UARTS=4
++CONFIG_SERIAL_8250_RUNTIME_UARTS=4
++# CONFIG_SERIAL_8250_EXTENDED is not set
++
++#
++# Non-8250 serial port support
++#
++# CONFIG_SERIAL_AMBA_PL010 is not set
++# CONFIG_SERIAL_AMBA_PL011 is not set
++CONFIG_SERIAL_CORE=y
++CONFIG_SERIAL_CORE_CONSOLE=y
++CONFIG_UNIX98_PTYS=y
++CONFIG_LEGACY_PTYS=y
++CONFIG_LEGACY_PTY_COUNT=256
++# CONFIG_IPMI_HANDLER is not set
++CONFIG_HW_RANDOM=m
++# CONFIG_NVRAM is not set
++# CONFIG_R3964 is not set
++# CONFIG_RAW_DRIVER is not set
++# CONFIG_TCG_TPM is not set
++CONFIG_I2C=m
++CONFIG_I2C_BOARDINFO=y
++# CONFIG_I2C_CHARDEV is not set
++
++#
++# I2C Algorithms
++#
++CONFIG_I2C_ALGOBIT=m
++# CONFIG_I2C_ALGOPCF is not set
++# CONFIG_I2C_ALGOPCA is not set
++# CONFIG_I2C_ALGOOXSEMI is not set
++
++#
++# I2C Hardware Bus support
++#
++CONFIG_I2C_HIPOX_BITBASH=m
++# CONFIG_I2C_OCORES is not set
++# CONFIG_I2C_PARPORT_LIGHT is not set
++# CONFIG_I2C_SIMTEC is not set
++# CONFIG_I2C_TAOS_EVM is not set
++# CONFIG_I2C_STUB is not set
++# CONFIG_I2C_TINY_USB is not set
++
++#
++# Miscellaneous I2C Chip support
++#
++# CONFIG_SENSORS_DS1337 is not set
++# CONFIG_SENSORS_DS1374 is not set
++# CONFIG_DS1682 is not set
++# CONFIG_SENSORS_EEPROM is not set
++# CONFIG_SENSORS_PCF8574 is not set
++# CONFIG_SENSORS_PCA9539 is not set
++# CONFIG_SENSORS_PCF8591 is not set
++# CONFIG_SENSORS_MAX6875 is not set
++# CONFIG_SENSORS_TSL2550 is not set
++# CONFIG_I2C_DEBUG_CORE is not set
++# CONFIG_I2C_DEBUG_ALGO is not set
++# CONFIG_I2C_DEBUG_BUS is not set
++# CONFIG_I2C_DEBUG_CHIP is not set
++
++#
++# SPI support
++#
++# CONFIG_SPI is not set
++# CONFIG_SPI_MASTER is not set
++# CONFIG_W1 is not set
++# CONFIG_POWER_SUPPLY is not set
++# CONFIG_HWMON is not set
++# CONFIG_WATCHDOG is not set
++
++#
++# Sonics Silicon Backplane
++#
++CONFIG_SSB_POSSIBLE=y
++# CONFIG_SSB is not set
++
++#
++# Multifunction device drivers
++#
++# CONFIG_MFD_SM501 is not set
++
++#
++# Multimedia devices
++#
++# CONFIG_VIDEO_DEV is not set
++# CONFIG_DVB_CORE is not set
++CONFIG_DAB=y
++# CONFIG_USB_DABUSB is not set
++
++#
++# Graphics support
++#
++# CONFIG_VGASTATE is not set
++CONFIG_VIDEO_OUTPUT_CONTROL=m
++# CONFIG_FB is not set
++# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
++
++#
++# Display device support
++#
++# CONFIG_DISPLAY_SUPPORT is not set
++
++#
++# Console display driver support
++#
++# CONFIG_VGA_CONSOLE is not set
++CONFIG_DUMMY_CONSOLE=y
++
++#
++# Sound
++#
++# CONFIG_SOUND is not set
++# CONFIG_HID_SUPPORT is not set
++CONFIG_USB_SUPPORT=y
++CONFIG_USB_ARCH_HAS_HCD=y
++CONFIG_USB_ARCH_HAS_OHCI=y
++CONFIG_USB_ARCH_HAS_EHCI=y
++CONFIG_USB=m
++# CONFIG_USB_DEBUG is not set
++
++#
++# Miscellaneous USB options
++#
++CONFIG_USB_DEVICEFS=y
++CONFIG_USB_DEVICE_CLASS=y
++# CONFIG_USB_DYNAMIC_MINORS is not set
++# CONFIG_USB_OTG is not set
++
++#
++# USB Host Controller Drivers
++#
++CONFIG_USB_EHCI_HCD=m
++# CONFIG_USB_EHCI_SPLIT_ISO is not set
++CONFIG_USB_EHCI_ROOT_HUB_TT=y
++# CONFIG_USB_EHCI_TT_NEWSCHED is not set
++# CONFIG_USB_ISP116X_HCD is not set
++# CONFIG_USB_OHCI_HCD is not set
++# CONFIG_USB_SL811_HCD is not set
++# CONFIG_USB_R8A66597_HCD is not set
++
++#
++# USB Device Class drivers
++#
++# CONFIG_USB_ACM is not set
++# CONFIG_USB_PRINTER is not set
++
++#
++# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support'
++#
++
++#
++# may also be needed; see USB_STORAGE Help for more information
++#
++CONFIG_USB_STORAGE=m
++# CONFIG_USB_STORAGE_DEBUG is not set
++# CONFIG_USB_STORAGE_DATAFAB is not set
++# CONFIG_USB_STORAGE_FREECOM is not set
++# CONFIG_USB_STORAGE_ISD200 is not set
++# CONFIG_USB_STORAGE_DPCM is not set
++# CONFIG_USB_STORAGE_USBAT is not set
++# CONFIG_USB_STORAGE_SDDR09 is not set
++# CONFIG_USB_STORAGE_SDDR55 is not set
++# CONFIG_USB_STORAGE_JUMPSHOT is not set
++# CONFIG_USB_STORAGE_ALAUDA is not set
++# CONFIG_USB_STORAGE_KARMA is not set
++# CONFIG_USB_LIBUSUAL is not set
++
++#
++# USB Imaging devices
++#
++# CONFIG_USB_MDC800 is not set
++# CONFIG_USB_MICROTEK is not set
++# CONFIG_USB_MON is not set
++
++#
++# USB port drivers
++#
++
++#
++# USB Serial Converter support
++#
++# CONFIG_USB_SERIAL is not set
++
++#
++# USB Miscellaneous drivers
++#
++# CONFIG_USB_EMI62 is not set
++# CONFIG_USB_EMI26 is not set
++# CONFIG_USB_ADUTUX is not set
++# CONFIG_USB_AUERSWALD is not set
++# CONFIG_USB_RIO500 is not set
++# CONFIG_USB_LEGOTOWER is not set
++# CONFIG_USB_LCD is not set
++# CONFIG_USB_BERRY_CHARGE is not set
++# CONFIG_USB_LED is not set
++# CONFIG_USB_CYPRESS_CY7C63 is not set
++# CONFIG_USB_CYTHERM is not set
++# CONFIG_USB_PHIDGET is not set
++# CONFIG_USB_IDMOUSE is not set
++# CONFIG_USB_FTDI_ELAN is not set
++# CONFIG_USB_APPLEDISPLAY is not set
++# CONFIG_USB_SISUSBVGA is not set
++# CONFIG_USB_LD is not set
++# CONFIG_USB_TRANCEVIBRATOR is not set
++# CONFIG_USB_IOWARRIOR is not set
++CONFIG_USB_TEST=m
++
++#
++# USB DSL modem support
++#
++
++#
++# USB Gadget Support
++#
++# CONFIG_USB_GADGET is not set
++# CONFIG_MMC is not set
++CONFIG_NEW_LEDS=y
++CONFIG_LEDS_CLASS=y
++
++#
++# LED drivers
++#
++# CONFIG_WDC_LEDS_HIPOX800 is not set
++CONFIG_HIPOX_WD810_LEDS=m
++
++#
++# LED Triggers
++#
++CONFIG_LEDS_TRIGGERS=y
++# CONFIG_LEDS_TRIGGER_TIMER is not set
++CONFIG_WDC_LEDS_TRIGGER_SATA_DISK=y
++# CONFIG_LEDS_TRIGGER_HEARTBEAT is not set
++CONFIG_RTC_LIB=y
++CONFIG_RTC_CLASS=m
++
++#
++# RTC interfaces
++#
++CONFIG_RTC_INTF_SYSFS=y
++CONFIG_RTC_INTF_PROC=y
++CONFIG_RTC_INTF_DEV=y
++# CONFIG_RTC_INTF_DEV_UIE_EMUL is not set
++# CONFIG_RTC_DRV_TEST is not set
++
++#
++# I2C RTC drivers
++#
++CONFIG_RTC_DRV_DS1307=m
++# CONFIG_RTC_DRV_DS1374 is not set
++# CONFIG_RTC_DRV_DS1672 is not set
++# CONFIG_RTC_DRV_MAX6900 is not set
++# CONFIG_RTC_DRV_RS5C372 is not set
++# CONFIG_RTC_DRV_ISL1208 is not set
++# CONFIG_RTC_DRV_X1205 is not set
++# CONFIG_RTC_DRV_PCF8563 is not set
++# CONFIG_RTC_DRV_PCF8583 is not set
++# CONFIG_RTC_DRV_M41T80 is not set
++
++#
++# SPI RTC drivers
++#
++
++#
++# Platform RTC drivers
++#
++# CONFIG_RTC_DRV_CMOS is not set
++# CONFIG_RTC_DRV_DS1553 is not set
++# CONFIG_RTC_DRV_STK17TA8 is not set
++# CONFIG_RTC_DRV_DS1742 is not set
++# CONFIG_RTC_DRV_M48T86 is not set
++# CONFIG_RTC_DRV_M48T59 is not set
++# CONFIG_RTC_DRV_V3020 is not set
++
++#
++# on-CPU RTC drivers
++#
++# CONFIG_RTC_DRV_PL031 is not set
++# CONFIG_DMADEVICES is not set
++
++#
++# File systems
++#
++CONFIG_EXT2_FS=y
++# CONFIG_EXT2_FS_XATTR is not set
++# CONFIG_EXT2_FS_XIP is not set
++CONFIG_EXT3_FS=y
++# CONFIG_EXT3_FS_XATTR is not set
++# CONFIG_EXT4DEV_FS is not set
++CONFIG_JBD=y
++# CONFIG_REISERFS_FS is not set
++# CONFIG_JFS_FS is not set
++CONFIG_FS_POSIX_ACL=y
++CONFIG_XFS_FS=y
++CONFIG_XFS_QUOTA=y
++# CONFIG_XFS_SECURITY is not set
++# CONFIG_XFS_POSIX_ACL is not set
++# CONFIG_XFS_RT is not set
++# CONFIG_GFS2_FS is not set
++# CONFIG_OCFS2_FS is not set
++# CONFIG_MINIX_FS is not set
++# CONFIG_ROMFS_FS is not set
++CONFIG_INOTIFY=y
++CONFIG_INOTIFY_USER=y
++# CONFIG_QUOTA is not set
++CONFIG_QUOTACTL=y
++CONFIG_DNOTIFY=y
++# CONFIG_AUTOFS_FS is not set
++# CONFIG_AUTOFS4_FS is not set
++CONFIG_FUSE_FS=y
++
++#
++# CD-ROM/DVD Filesystems
++#
++# CONFIG_ISO9660_FS is not set
++# CONFIG_UDF_FS is not set
++
++#
++# DOS/FAT/NT Filesystems
++#
++CONFIG_FAT_FS=y
++CONFIG_MSDOS_FS=y
++CONFIG_VFAT_FS=m
++CONFIG_FAT_DEFAULT_CODEPAGE=437
++CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1"
++CONFIG_NTFS_FS=m
++# CONFIG_NTFS_DEBUG is not set
++# CONFIG_NTFS_RW is not set
++
++#
++# Pseudo filesystems
++#
++CONFIG_PROC_FS=y
++CONFIG_PROC_SYSCTL=y
++CONFIG_SYSFS=y
++# CONFIG_TMPFS is not set
++# CONFIG_HUGETLB_PAGE is not set
++# CONFIG_CONFIGFS_FS is not set
++
++#
++# Miscellaneous filesystems
++#
++# CONFIG_ADFS_FS is not set
++# CONFIG_AFFS_FS is not set
++# CONFIG_HFS_FS is not set
++CONFIG_HFSPLUS_FS=m
++# CONFIG_BEFS_FS is not set
++# CONFIG_BFS_FS is not set
++# CONFIG_EFS_FS is not set
++# CONFIG_CRAMFS is not set
++# CONFIG_VXFS_FS is not set
++# CONFIG_HPFS_FS is not set
++# CONFIG_QNX4FS_FS is not set
++# CONFIG_SYSV_FS is not set
++# CONFIG_UFS_FS is not set
++CONFIG_NETWORK_FILESYSTEMS=y
++# CONFIG_NFS_FS is not set
++CONFIG_NFSD=m
++CONFIG_NFSD_V2_ACL=y
++CONFIG_NFSD_V3=y
++CONFIG_NFSD_V3_ACL=y
++# CONFIG_NFSD_V4 is not set
++CONFIG_NFSD_TCP=y
++CONFIG_LOCKD=m
++CONFIG_LOCKD_V4=y
++CONFIG_EXPORTFS=m
++CONFIG_NFS_ACL_SUPPORT=m
++CONFIG_NFS_COMMON=y
++CONFIG_SUNRPC=m
++# CONFIG_SUNRPC_BIND34 is not set
++# CONFIG_RPCSEC_GSS_KRB5 is not set
++# CONFIG_RPCSEC_GSS_SPKM3 is not set
++# CONFIG_SMB_FS is not set
++# CONFIG_CIFS is not set
++# CONFIG_NCP_FS is not set
++# CONFIG_CODA_FS is not set
++# CONFIG_AFS_FS is not set
++
++#
++# Partition Types
++#
++CONFIG_PARTITION_ADVANCED=y
++# CONFIG_ACORN_PARTITION is not set
++# CONFIG_OSF_PARTITION is not set
++# CONFIG_AMIGA_PARTITION is not set
++# CONFIG_ATARI_PARTITION is not set
++CONFIG_MAC_PARTITION=y
++CONFIG_MSDOS_PARTITION=y
++# CONFIG_BSD_DISKLABEL is not set
++# CONFIG_MINIX_SUBPARTITION is not set
++# CONFIG_SOLARIS_X86_PARTITION is not set
++# CONFIG_UNIXWARE_DISKLABEL is not set
++CONFIG_LDM_PARTITION=y
++# CONFIG_LDM_DEBUG is not set
++# CONFIG_SGI_PARTITION is not set
++# CONFIG_ULTRIX_PARTITION is not set
++# CONFIG_SUN_PARTITION is not set
++# CONFIG_KARMA_PARTITION is not set
++CONFIG_EFI_PARTITION=y
++# CONFIG_SYSV68_PARTITION is not set
++CONFIG_NLS=y
++CONFIG_NLS_DEFAULT="iso8859-1"
++CONFIG_NLS_CODEPAGE_437=m
++# CONFIG_NLS_CODEPAGE_737 is not set
++# CONFIG_NLS_CODEPAGE_775 is not set
++# CONFIG_NLS_CODEPAGE_850 is not set
++# CONFIG_NLS_CODEPAGE_852 is not set
++# CONFIG_NLS_CODEPAGE_855 is not set
++# CONFIG_NLS_CODEPAGE_857 is not set
++# CONFIG_NLS_CODEPAGE_860 is not set
++# CONFIG_NLS_CODEPAGE_861 is not set
++# CONFIG_NLS_CODEPAGE_862 is not set
++# CONFIG_NLS_CODEPAGE_863 is not set
++# CONFIG_NLS_CODEPAGE_864 is not set
++# CONFIG_NLS_CODEPAGE_865 is not set
++# CONFIG_NLS_CODEPAGE_866 is not set
++# CONFIG_NLS_CODEPAGE_869 is not set
++# CONFIG_NLS_CODEPAGE_936 is not set
++# CONFIG_NLS_CODEPAGE_950 is not set
++# CONFIG_NLS_CODEPAGE_932 is not set
++# CONFIG_NLS_CODEPAGE_949 is not set
++# CONFIG_NLS_CODEPAGE_874 is not set
++# CONFIG_NLS_ISO8859_8 is not set
++# CONFIG_NLS_CODEPAGE_1250 is not set
++# CONFIG_NLS_CODEPAGE_1251 is not set
++# CONFIG_NLS_ASCII is not set
++CONFIG_NLS_ISO8859_1=m
++# CONFIG_NLS_ISO8859_2 is not set
++# CONFIG_NLS_ISO8859_3 is not set
++# CONFIG_NLS_ISO8859_4 is not set
++# CONFIG_NLS_ISO8859_5 is not set
++# CONFIG_NLS_ISO8859_6 is not set
++# CONFIG_NLS_ISO8859_7 is not set
++# CONFIG_NLS_ISO8859_9 is not set
++# CONFIG_NLS_ISO8859_13 is not set
++# CONFIG_NLS_ISO8859_14 is not set
++# CONFIG_NLS_ISO8859_15 is not set
++# CONFIG_NLS_KOI8_R is not set
++# CONFIG_NLS_KOI8_U is not set
++CONFIG_NLS_UTF8=y
++# CONFIG_DLM is not set
++# CONFIG_INSTRUMENTATION is not set
++
++#
++# Kernel hacking
++#
++# CONFIG_PRINTK_TIME is not set
++CONFIG_ENABLE_WARN_DEPRECATED=y
++CONFIG_ENABLE_MUST_CHECK=y
++# CONFIG_MAGIC_SYSRQ is not set
++# CONFIG_UNUSED_SYMBOLS is not set
++# CONFIG_DEBUG_FS is not set
++# CONFIG_HEADERS_CHECK is not set
++# CONFIG_DEBUG_KERNEL is not set
++CONFIG_DEBUG_BUGVERBOSE=y
++CONFIG_FRAME_POINTER=y
++# CONFIG_SAMPLES is not set
++# CONFIG_DEBUG_USER is not set
++
++#
++# Security options
++#
++# CONFIG_KEYS is not set
++CONFIG_SECURITY=y
++# CONFIG_SECURITY_NETWORK is not set
++# CONFIG_SECURITY_CAPABILITIES is not set
++CONFIG_SECURITY_TRUSTEES=y
++# CONFIG_SECURITY_TRUSTEES_DEBUG is not set
++CONFIG_CRYPTO=y
++CONFIG_CRYPTO_ALGAPI=y
++CONFIG_CRYPTO_BLKCIPHER=y
++CONFIG_CRYPTO_MANAGER=y
++# CONFIG_CRYPTO_HMAC is not set
++# CONFIG_CRYPTO_XCBC is not set
++# CONFIG_CRYPTO_NULL is not set
++# CONFIG_CRYPTO_MD4 is not set
++# CONFIG_CRYPTO_MD5 is not set
++# CONFIG_CRYPTO_SHA1 is not set
++# CONFIG_CRYPTO_SHA256 is not set
++# CONFIG_CRYPTO_SHA512 is not set
++# CONFIG_CRYPTO_WP512 is not set
++# CONFIG_CRYPTO_TGR192 is not set
++# CONFIG_CRYPTO_GF128MUL is not set
++CONFIG_CRYPTO_ECB=m
++CONFIG_CRYPTO_CBC=y
++CONFIG_CRYPTO_PCBC=m
++# CONFIG_CRYPTO_LRW is not set
++# CONFIG_CRYPTO_XTS is not set
++# CONFIG_CRYPTO_CRYPTD is not set
++# CONFIG_CRYPTO_DES is not set
++# CONFIG_CRYPTO_FCRYPT is not set
++# CONFIG_CRYPTO_BLOWFISH is not set
++# CONFIG_CRYPTO_TWOFISH is not set
++# CONFIG_CRYPTO_SERPENT is not set
++CONFIG_CRYPTO_AES=m
++# CONFIG_CRYPTO_CAST5 is not set
++# CONFIG_CRYPTO_CAST6 is not set
++# CONFIG_CRYPTO_TEA is not set
++CONFIG_CRYPTO_ARC4=m
++# CONFIG_CRYPTO_KHAZAD is not set
++# CONFIG_CRYPTO_ANUBIS is not set
++# CONFIG_CRYPTO_SEED is not set
++# CONFIG_CRYPTO_DEFLATE is not set
++CONFIG_CRYPTO_MICHAEL_MIC=m
++# CONFIG_CRYPTO_CRC32C is not set
++# CONFIG_CRYPTO_CAMELLIA is not set
++# CONFIG_CRYPTO_TEST is not set
++# CONFIG_CRYPTO_AUTHENC is not set
++CONFIG_CRYPTO_HW=y
++
++#
++# Library routines
++#
++CONFIG_BITREVERSE=y
++CONFIG_CRC_CCITT=y
++# CONFIG_CRC16 is not set
++# CONFIG_CRC_ITU_T is not set
++CONFIG_CRC32=y
++# CONFIG_CRC7 is not set
++# CONFIG_LIBCRC32C is not set
++CONFIG_PLIST=y
++CONFIG_HAS_IOMEM=y
++CONFIG_HAS_IOPORT=y
++CONFIG_HAS_DMA=y
+diff -Nurd linux-2.6.24/arch/arm/kernel/armksyms.c linux-2.6.24-oxe810/arch/arm/kernel/armksyms.c
+--- linux-2.6.24/arch/arm/kernel/armksyms.c 2008-01-24 23:58:37.000000000 +0100
++++ linux-2.6.24-oxe810/arch/arm/kernel/armksyms.c 2008-06-11 17:47:43.000000000 +0200
+@@ -114,9 +114,15 @@
+ EXPORT_SYMBOL(__strncpy_from_user);
+
+ #ifdef CONFIG_MMU
++#ifdef CONFIG_HIPOX_INSTRUMENT_COPIES
++EXPORT_SYMBOL(__copy_from_user_alt);
++EXPORT_SYMBOL(__copy_to_user_alt);
++EXPORT_SYMBOL(__clear_user_alt);
++#else // CONFIG_HIPOX_INSTRUMENT_COPIES
+ EXPORT_SYMBOL(__copy_from_user);
+ EXPORT_SYMBOL(__copy_to_user);
+ EXPORT_SYMBOL(__clear_user);
++#endif // CONFIG_HIPOX_INSTRUMENT_COPIES
+
+ EXPORT_SYMBOL(__get_user_1);
+ EXPORT_SYMBOL(__get_user_2);
+diff -Nurd linux-2.6.24/arch/arm/kernel/bios32.c linux-2.6.24-oxe810/arch/arm/kernel/bios32.c
+--- linux-2.6.24/arch/arm/kernel/bios32.c 2008-01-24 23:58:37.000000000 +0100
++++ linux-2.6.24-oxe810/arch/arm/kernel/bios32.c 2008-06-11 17:47:43.000000000 +0200
+@@ -616,7 +616,7 @@
+ }
+ }
+
+-char * __init pcibios_setup(char *str)
++char * __devinit pcibios_setup(char *str)
+ {
+ if (!strcmp(str, "debug")) {
+ debug_pci = 1;
+diff -Nurd linux-2.6.24/arch/arm/kernel/calls.S linux-2.6.24-oxe810/arch/arm/kernel/calls.S
+--- linux-2.6.24/arch/arm/kernel/calls.S 2008-01-24 23:58:37.000000000 +0100
++++ linux-2.6.24-oxe810/arch/arm/kernel/calls.S 2008-06-11 17:47:43.000000000 +0200
+@@ -362,6 +362,7 @@
+ /* 350 */ CALL(sys_timerfd)
+ CALL(sys_eventfd)
+ CALL(sys_fallocate)
++ CALL(sys_samba_reserve)
+ #ifndef syscalls_counted
+ .equ syscalls_padding, ((NR_syscalls + 3) & ~3) - NR_syscalls
+ #define syscalls_counted
+diff -Nurd linux-2.6.24/arch/arm/kernel/head.S linux-2.6.24-oxe810/arch/arm/kernel/head.S
+--- linux-2.6.24/arch/arm/kernel/head.S 2008-01-24 23:58:37.000000000 +0100
++++ linux-2.6.24-oxe810/arch/arm/kernel/head.S 2008-06-11 17:47:43.000000000 +0200
+@@ -59,6 +59,34 @@
+ #define KERNEL_END _end
+ #endif
+
++#ifdef CONFIG_HIPOX_MAP_SRAM
++ .macro course_pgtbl, rd
++ ldr \rd, =(__virt_to_phys(KERNEL_RAM_ADDR - 0x4400))
++ .endm
++
++ .globl SMALL_AP
++ .equ SMALL_AP, 0xAA
++
++ .globl COURSE_DOMAIN
++ .equ COURSE_DOMAIN, 0x04
++
++ .globl SRAM_CODE_START
++ .globl CODE_COPY_LEN
++
++#ifdef CONFIG_SUPPORT_LEON
++ /*
++ * Allow 2 pages after GMAC/DMA descriptors for ARM/Leon TSO workspace
++ * May have to change if Leon code is built to use more Tx descriptors, but
++ * current 2 pages is easily enough for 54 descriptors
++ */
++ .equ SRAM_CODE_START, SRAM_PA+((CONFIG_DESCRIPTORS_PAGES+2)*4096)
++ .equ CODE_COPY_LEN, ((CONFIG_SRAM_NUM_PAGES-CONFIG_LEON_PAGES-(CONFIG_DESCRIPTORS_PAGES+2))*4096)
++#else // CONFIG_SUPPORT_LEON
++ .equ SRAM_CODE_START, SRAM_PA+(CONFIG_DESCRIPTORS_PAGES*4096)
++ .equ CODE_COPY_LEN, ((CONFIG_SRAM_NUM_PAGES-CONFIG_DESCRIPTORS_PAGES)*4096)
++#endif // CONFIG_SUPPORT_LEON
++#endif // CONFIG_HIPOX_MAP_SRAM
++
+ /*
+ * Kernel startup entry point.
+ * ---------------------------
+@@ -82,6 +110,27 @@
+ ENTRY(stext)
+ msr cpsr_c, #PSR_F_BIT | PSR_I_BIT | SVC_MODE @ ensure svc mode
+ @ and irqs disabled
++
++#ifdef CONFIG_HIPOX_CACHE_LOCKDOWN
++ /*
++ * Lock down ICache - do not care what ends up in locked down ways -
++ * eventually context switch etc will flush out anything that gets loaded
++ * next
++ */
++ mrc p15,0,r2,c9,c0,1
++ orr r2,r2,#CONFIG_HIPOX_CACHE_I_MASK
++ mcr p15,0,r2,c9,c0,1
++
++ /*
++ * Lock down DCache - do not care what ends up in locked down ways -
++ * eventually context switch etc will flush out anything that gets loaded
++ * next
++ */
++ mrc p15,0,r2,c9,c0,0
++ orr r2,r2,#CONFIG_HIPOX_CACHE_D_MASK
++ mcr p15,0,r2,c9,c0,0
++#endif // CONFIG_HIPOX_CACHE_LOCKDOWN
++
+ mrc p15, 0, r9, c0, c0 @ get processor id
+ bl __lookup_processor_type @ r5=procinfo r9=cpuid
+ movs r10, r5 @ invalid processor (r5=0)?
+@@ -231,7 +280,33 @@
+ teq r0, r6
+ bne 1b
+
+- ldr r7, [r10, #PROCINFO_MM_MMUFLAGS] @ mm_mmuflags
++ ldr r7, [r10, #PROCINFO_MM_MMUFLAGS] @ mmuflags
++
++#ifdef CONFIG_HIPOX_MAP_SRAM
++ /*
++ * Create the contents of the first descriptor in the course table which
++ * is to describe the first MB of the kernel with 256 4K small descriptors.
++ * The descriptors' are composed of the top 20 bits of the physical
++ * address plus the appropriate AP, cacheable and bufferable flags
++ */
++ mov r3, #PHYS_OFFSET
++ mov r3, r3, lsr #12
++ mov r3, r3, lsl #12
++ mov r6, #SMALL_AP @ TBC: AP values
++ orr r3, r3, r6, lsl #4
++ orr r3, r3, #0xe @ Cachable, bufferable and small desc
++
++ /*
++ * Fill all 256 entries in the course page table with descriptors for
++ * contiguous pages
++ */
++ course_pgtbl r0
++ add r6, r0, #0x0400
++1: str r3, [r0], #4
++ add r3, r3, #1 << 12
++ teq r0, r6
++ bne 1b
++#endif // CONFIG_HIPOX_MAP_SRAM
+
+ /*
+ * Create identity mapping for first MB of kernel to
+@@ -243,12 +318,26 @@
+ orr r3, r7, r6, lsl #20 @ flags + kernel base
+ str r3, [r4, r6, lsl #2] @ identity mapping
+
++#ifdef CONFIG_HIPOX_MAP_SRAM
++ /*
++ * Write a course descriptor pointing to the small page mapping table
++ * setup to map the first MB of kernel with 4K small pages
++ */
++ course_pgtbl r6
++ mov r0, #COURSE_DOMAIN @ TBC SBZ, Domain etc
++ orr r6, r6, r0, lsl #2
++ orr r6, r6, #1 @ Course descriptor identifier
++
++ add r0, r4, #(KERNEL_START & 0xff000000) >> 18
++ str r6, [r0, #(KERNEL_START & 0x00f00000) >> 18]!
++#else // CONFIG_HIPOX_MAP_SRAM
+ /*
+ * Now setup the pagetables for our kernel direct
+ * mapped region.
+ */
+ add r0, r4, #(KERNEL_START & 0xff000000) >> 18
+ str r3, [r0, #(KERNEL_START & 0x00f00000) >> 18]!
++#endif // CONFIG_HIPOX_MAP_SRAM
+ ldr r6, =(KERNEL_END - 1)
+ add r0, r0, #4
+ add r6, r4, r6, lsr #18
+@@ -276,6 +365,64 @@
+ bls 1b
+ #endif
+
++#ifdef CONFIG_HIPOX_COPY_CODE_TO_SRAM
++ /*
++ * Copy smallest/most-used kernel code into SRAM
++ */
++
++ /* Get start of kernel code to copy */
++ ldr r0, =(_text)
++ mvn r3, #0xff000000
++ and r0, r0, r3
++ mov r6, #PHYS_OFFSET
++ mov r3, #0xff000000
++ and r6, r6, r3
++ orr r0, r0, r6
++
++ /* Get start of SRAM region to copy into */
++ ldr r3, =(SRAM_CODE_START)
++
++ /* Get amount of code to copy */
++ ldr r6, =(CODE_COPY_LEN)
++
++ /* NB r7 is corrupted here, but opt. debug code below needs it */
++ add r6, r0, r6
++1: ldr r7, [r0], #4
++ str r7, [r3], #4
++ teq r0, r6
++ bne 1b
++
++ /*
++ * Map SRAM resident code into kernel virtual address space by altering
++ * course page table entries covering the smallest/most-used code
++ */
++
++ /* Get the address of the first page table entry to modify */
++ course_pgtbl r3
++ ldr r0, =(_text)
++ sub r0, r0, #PAGE_OFFSET
++ add r3, r3, r0, lsr #10
++
++ /* Get the address after the last entry in the page table to be altered */
++ ldr r6, =(CODE_COPY_LEN)
++ add r6, r3, r6, lsr #10
++
++ /* Form the first small descriptor contents */
++ ldr r0, =(SRAM_CODE_START)
++ mov r0, r0, lsr #12
++ mov r0, r0, lsl #12
++ mov r7, #SMALL_AP
++ orr r0, r0, r7, lsl #4
++ orr r0, r0, #0xe
++
++ /* Modify the page table entries for all SRAM pages filled with code */
++1: str r0, [r3], #4
++ add r0, r0, #1 << 12
++ teq r3, r6
++ bne 1b
++
++#else // CONFIG_HIPOX_COPY_CODE_TO_SRAM
++#ifndef CONFIG_ARCH_HIPOX
+ /*
+ * Then map first 1MB of ram in case it contains our boot params.
+ */
+@@ -285,6 +432,8 @@
+ orr r6, r6, #(PHYS_OFFSET & 0x00f00000)
+ .endif
+ str r6, [r0]
++#endif // !CONFIG_ARCH_HIPOX
++#endif // CONFIG_HIPOX_COPY_CODE_TO_SRAM
+
+ #ifdef CONFIG_DEBUG_LL
+ ldr r7, [r10, #PROCINFO_IO_MMUFLAGS] @ io_mmuflags
+diff -Nurd linux-2.6.24/arch/arm/kernel/process.c linux-2.6.24-oxe810/arch/arm/kernel/process.c
+--- linux-2.6.24/arch/arm/kernel/process.c 2008-01-24 23:58:37.000000000 +0100
++++ linux-2.6.24-oxe810/arch/arm/kernel/process.c 2008-06-11 17:47:43.000000000 +0200
+@@ -117,7 +117,7 @@
+ void (*pm_idle)(void);
+ EXPORT_SYMBOL(pm_idle);
+
+-void (*pm_power_off)(void);
++void (*pm_power_off)(void) = arch_poweroff;
+ EXPORT_SYMBOL(pm_power_off);
+
+ void (*arm_pm_restart)(char str) = arm_machine_restart;
+diff -Nurd linux-2.6.24/arch/arm/kernel/vmlinux.lds.S linux-2.6.24-oxe810/arch/arm/kernel/vmlinux.lds.S
+--- linux-2.6.24/arch/arm/kernel/vmlinux.lds.S 2008-01-24 23:58:37.000000000 +0100
++++ linux-2.6.24-oxe810/arch/arm/kernel/vmlinux.lds.S 2008-06-11 17:47:43.000000000 +0200
+@@ -86,8 +86,659 @@
+ #endif
+ }
+
+- .text : { /* Real text segment */
+- _text = .; /* Text and read-only data */
++ .text : { /* Real text segment */
++ _text = .; /* Text and read-only data */
++ *(.text.arm926_dma_clean_range)
++ *(.text.arm926_dma_inv_range)
++ *(.text.arm926_dma_flush_range)
++ *(.text.__irq_svc)
++ *(.text.__arch_copy_to_user)
++ *(.text.__arch_copy_from_user)
++ *(.text.__kmalloc)
++ *(.text.HIPOX_unmask_irq)
++ *(.text.local_bh_enable)
++ *(.text.do_level_IRQ)
++ *(.text.__memzero)
++ *(.text.irq_exit)
++ *(.text.__do_irq)
++ *(.text.pfifo_fast_dequeue)
++ *(.text.preempt_return)
++ *(.text.cpu_arm926_switch_mm)
++ *(.text.check_irq_lock)
++ *(.text.tcp_init_tso_segs)
++ *(.text.kfree_skbmem)
++ *(.text.consistent_sync)
++ *(.text.__alloc_skb)
++ *(.text.skb_release_data)
++ *(.text.HIPOX_mask_irq)
++ *(.text.Ldiv0)
++ *(.text.__do_softirq)
++ *(.text.kmem_cache_free)
++ *(.text.__kfree_skb)
++ *(.text.kmem_cache_alloc)
++ *(.text.radix_tree_lookup)
++ *(.text.kfree)
++ *(.text.asm_do_IRQ)
++ *(.text.skb_clone)
++ *(.text.qdisc_restart)
++ *(.text.sock_wfree)
++ *(.text.unlock_page)
++ *(.text.tcp_cwnd_validate)
++ *(.text.free_hot_cold_page)
++ *(.text.memcpy)
++ *(.text.velocity_free_tx_buf)
++ *(.text.wake_up_bit)
++ *(.text.cond_resched)
++ *(.text.pfifo_fast_enqueue)
++ *(.text.raise_softirq_irqoff)
++ *(.text.tcp_push_one)
++ *(.text.__modsi3)
++ *(.text.update_send_head)
++ *(.text.tcp_set_skb_tso_segs)
++ *(.text.tcp_snd_test)
++ *(.text.svc_preempt)
++ *(.text.__tcp_select_window)
++ *(.text.dev_queue_xmit)
++ *(.text.hipox_gettimeoffset)
++ *(.text.__wake_up_bit)
++ *(.text.mod_timer)
++ *(.text.do_simple_IRQ)
++ *(.text.velocity_xmit)
++ *(.text.ip_output)
++ *(.text.net_tx_action)
++ *(.text.ip_queue_xmit)
++ *(.text.tcp_cong_avoid)
++ *(.text.sk_reset_timer)
++ *(.text.velocity_intr)
++ *(.text.pci_dma_sync_single_for_device)
++ *(.text.process_backlog)
++ *(.text.tcp_v4_send_check)
++ *(.text.tcp_transmit_skb)
++ *(.text.file_send_actor)
++ *(.text.tcp_current_mss)
++ *(.text.__netif_rx_schedule)
++ *(.text.__muldi3)
++ *(.text.release_sock)
++ *(.text.do_softirq)
++ *(.text.pfifo_fast_reset)
++ *(.text.netif_rx)
++ *(.text.kernel_sendmsg)
++ *(.text.rt_hash_code)
++ *(.text.mod_page_state_offset)
++ *(.text.preempt_schedule)
++ *(.text.inet_sendmsg)
++ *(.text.page_waitqueue)
++ *(.text.bictcp_acked)
++ *(.text.__sk_dst_check)
++ *(.text.blk_rq_map_sg)
++ *(.text.tcp_mtu_to_mss)
++ *(.text.__delay)
++ *(.text.sock_sendmsg)
++ *(.text.sock_sendpage)
++ *(.text.ip_local_deliver)
++ *(.text.bio_add_page)
++ *(.text.tcp_sendmsg)
++ *(.text.sock_no_sendpage)
++ *(.text.__remove_from_page_cache)
++ *(.text.net_rx_action)
++ *(.text.eth_type_trans)
++ *(.text.find_get_page)
++ *(.text.netif_receive_skb)
++ *(.text.verify_chain)
++ *(.text.radix_tree_delete)
++ *(.text.mpage_readpages)
++ *(.text.velocity_rx_refill)
++ *(.text.mpage_end_io_read)
++ *(.text.radix_tree_insert)
++ *(.text.ip_rcv)
++ *(.text.register_gifconf)
++ *(.text.dma_mmap)
++ *(.text.tcp_rtt_estimator)
++ *(.text.ox800sata_get_bbp_base)
++ *(.text.mark_page_accessed)
++ *(.text.update_process_times)
++ *(.text.__pagevec_free)
++ *(.text.read_page_state_offset)
++ *(.text.__bio_add_page)
++ *(.text.__pagevec_lru_add)
++ *(.text.ox800sata_scr_read)
++ *(.text.bio_add_pc_page)
++ *(.text.__rcu_pending)
++ *(.text.free_sg_entry)
++ *(.text.put_page)
++ *(.text.lock_timer_base)
++ *(.text.radix_tree_tagged)
++ *(.text.__lshrdi3)
++ *(.text.lock_sock)
++ *(.text.__udivsi3)
++ *(.text.zone_watermark_ok)
++ *(.text.klist_children_put)
++ *(.text.sock_aio_dtor)
++ *(.text.ata_qc_prep)
++ *(.text.hipox_dma_free)
++ *(.text.rcu_pending)
++ *(.text.free_cold_page)
++ *(.text.get_page_from_freelist)
++ *(.text.alloc_sg_entry)
++ *(.text.ret_fast_syscall)
++ *(.text.add_to_page_cache)
++ *(.text.__mod_timer)
++ *(.text.velocity_free_td_ring)
++ *(.text.__do_div64)
++ *(.text.remove_mapping)
++ *(.text.fast_work_pending)
++ *(.text.cond_resched_softirq)
++ *(.text.tcp_v4_rcv)
++ *(.text.kernel_recvmsg)
++ *(.text.isolate_lru_pages)
++ *(.text.klist_children_get)
++ *(.text.sys_getpid)
++ *(.text.mempool_free_slab)
++ *(.text.kobject_get)
++ *(.text.__tcp_push_pending_frames)
++ *(.text.sk_stop_timer)
++ *(.text.bictcp_state)
++ *(.text.tcp_check_space)
++ *(.text.kmem_cache_zalloc)
++ *(.text.get_device)
++ *(.text.work_pending)
++ *(.text.tcp_ack)
++ *(.text.do_edge_IRQ)
++ *(.text.page_referenced)
++ *(.text.profile_tick)
++ *(.text.ox800sata_get_link_base)
++ *(.text.__pagevec_release_nonlru)
++ *(.text.blk_recount_segments)
++ *(.text.__mod_page_state_offset)
++ *(.text.linear_mergeable_bvec)
++ *(.text.recalc_task_prio)
++ *(.text.mempool_kmalloc)
++ *(.text.do_mpage_readpage)
++ *(.text.ksoftirqd)
++ *(.text.__generic_unplug_device)
++ *(.text.rt_cpu_seq_start)
++ *(.text.bio_alloc)
++ *(.text.tasklet_action)
++ *(.text.effective_prio)
++ *(.text.HIPOX_timer_interrupt)
++ *(.text.__wake_up_common)
++ *(.text.free_poll_entry)
++ *(.text.vector_swi)
++ *(.text.do_sock_read)
++ *(.text.alloc_sg_controller)
++ *(.text.tcp_rcv_established)
++ *(.text.hipox_dma_set_callback)
++ *(.text.run_local_timers)
++ *(.text.sock_rmalloc)
++ *(.text.__rmqueue)
++ *(.text.ox800sata_bmdma_start)
++ *(.text.fget_light)
++ *(.text.queue_work)
++ *(.text.mempool_alloc_slab)
++ *(.text.__wake_up)
++ *(.text.default_idle)
++ *(.text.fput)
++ *(.text.add_wait_queue)
++ *(.text.memcpy_toiovec)
++ *(.text.rw_verify_area)
++ *(.text.internal_add_timer)
++ *(.text.hrtimer_run_queues)
++ *(.text.tcp_v4_do_rcv)
++ *(.text.raise_softirq)
++ *(.text.del_timer)
++ *(.text.try_to_wake_up)
++ *(.text.__do_page_cache_readahead)
++ *(.text.__alloc_pages)
++ *(.text.sock_aio_read)
++ *(.text.timer_tick)
++ *(.text.ox800sata_check_status)
++ *(.text.do_generic_mapping_read)
++ *(.text.__ox800sata_scr_read)
++ *(.text.elv_queue_empty)
++ *(.text.do_select)
++ *(.text.free_pages_bulk)
++ *(.text.remove_wait_queue)
++ *(.text.dma_bh)
++ *(.text.__irq_usr)
++ *(.text.vfs_read)
++ *(.text.run_timer_softirq)
++ *(.text.radix_tree_preload)
++ *(.text.ptrace_getrn)
++ *(.text.tcp_dsack_set)
++ *(.text.__switch_to)
++ *(.text.bio_hw_segments)
++ *(.text.__const_udelay)
++ *(.text.nr_running)
++ *(.text.hipox_dma_device_set_prd)
++ *(.text.kref_put)
++ *(.text.enqueue_task)
++ *(.text.dequeue_task)
++ *(.text.elv_next_request)
++ *(.text.profile_hit)
++ *(.text.slab_destroy)
++ *(.text.schedule)
++ *(.text.end_that_request_first)
++ *(.text.cfq_find_next_crq)
++ *(.text.__freed_request)
++ *(.text.adjtime_adjustment)
++ *(.text.bictcp_cong_avoid)
++ *(.text.kthread_should_stop)
++ *(.text.__activate_task)
++ *(.text.account_system_time)
++ *(.text.bio_fs_destructor)
++ *(.text.mempool_alloc)
++ *(.text.elv_set_request)
++ *(.text.schedule_work)
++ *(.text.wake_up_state)
++ *(.text.encode_control_status)
++ *(.text.alloc_skb_from_cache)
++ *(.text.qdisc_lock_tree)
++ *(.text.kref_get)
++ *(.text.init_timer)
++ *(.text.hipox_dma_is_active)
++ *(.text.shrink_slab)
++ *(.text.poll_freewait)
++ *(.text.sys_fstat64)
++ *(.text.__pollwait)
++ *(.text.cfq_queue_empty)
++ *(.text.linear_issue_flush)
++ *(.text.__tasklet_schedule)
++ *(.text.ox800sata_get_io_base)
++ *(.text.deactivate_task)
++ *(.text.cleanup_rbuf)
++ *(.text.nr_free_zone_pages)
++ *(.text.ip_route_input)
++ *(.text.__lock_page)
++ *(.text.sock_poll)
++ *(.text.__pskb_trim_head)
++ *(.text.sys_read)
++ *(.text.__arch_copy_to_user)
++ *(.text.generic_make_request)
++ *(.text.scsi_end_request)
++ *(.text.bio_init)
++ *(.text.pipefs_delete_dentry)
++ *(.text.ox800sata_post_set_mode)
++ *(.text.sock_common_recvmsg)
++ *(.text.put_device)
++ *(.text.tcp_syn_build_options)
++ *(.text.scheduler_tick)
++ *(.text.__sys_trace)
++ *(.text.ox800sata_qc_new)
++ *(.text.elv_latter_request)
++ *(.text.do_sync_read)
++ *(.text.ox800sata_spot_the_end)
++ *(.text.get_dirty_limits)
++ *(.text.bio_phys_segments)
++ *(.text.vfs_fstat)
++ *(.text.scsi_finish_command)
++ *(.text.wake_up_process)
++ *(.text.wdc_ledtrig_sata_activity)
++ *(.text.__elv_add_request)
++ *(.text.sock_common_setsockopt)
++ *(.text.elv_may_queue)
++ *(.text.rb_first)
++ *(.text.dnotify_parent)
++ *(.text.get_writeback_state)
++ *(.text.__blk_put_request)
++ *(.text.sock_mmap)
++ *(.text.throttle_vm_writeout)
++ *(.text.drive_stat_acct)
++ *(.text.dlci_ioctl_set)
++ *(.text.sys_send)
++ *(.text.default_wake_function)
++ *(.text.cfq_resort_rr_list)
++ *(.text.bio_put)
++ *(.text.scsi_done)
++ *(.text.kobject_put)
++ *(.text.release_pages)
++ *(.text.ata_qc_issue)
++ *(.text.cfq_dispatch_insert)
++ *(.text.run_workqueue)
++ *(.text.delayed_work_timer_fn)
++ *(.text.scsi_init_cmd_errh)
++ *(.text.alloc_sock_iocb)
++ *(.text.blk_done_softirq)
++ *(.text.do_timer)
++ *(.text.scsi_10_lba_len)
++ *(.text.scsi_device_unbusy)
++ *(.text.bio_get_nr_vecs)
++ *(.text.cfq_find_cfq_hash)
++ *(.text.ata_dev_select)
++ *(.text.blk_remove_plug)
++ *(.text.end_that_request_last)
++ *(.text.shrink_dcache_memory)
++ *(.text.elv_put_request)
++ *(.text.sys_sendto)
++ *(.text.scsi_put_command)
++ *(.text._clear_bit_le)
++ *(.text.ata_rwcmd_protocol)
++ *(.text.kobject_cleanup)
++ *(.text.do_sendfile)
++ *(.text.worker_thread)
++ *(.text.elv_dispatch_sort)
++ *(.text.tcp_fast_parse_options)
++ *(.text.ox800sata_irq_on)
++ *(.text.scsi_request_fn)
++ *(.text.ox800sata_irq_handler)
++ *(.text.nr_context_switches)
++ *(.text.hipox_dma_request)
++ *(.text.sys_sendfile64)
++ *(.text.cfq_add_crq_rb)
++ *(.text.ata_scsi_queuecmd)
++ *(.text.sock_def_readable)
++ *(.text.inet_sendpage)
++ *(.text.cfq_set_request)
++ *(.text.init_request_from_bio)
++ *(.text.tcp_v4_conn_request)
++ *(.text.requeue_task)
++ *(.text.cache_alloc_refill)
++ *(.text.scsi_get_command)
++ *(.text.blk_complete_request)
++ *(.text.scsi_add_timer)
++ *(.text.sk_stream_rfree)
++ *(.text.__umodsi3)
++ *(.text.ox800sata_tf_load)
++ *(.text.tcp_recvmsg)
++ *(.text.cfq_insert_request)
++ *(.text.tcp_sendpage)
++ *(.text.bio_alloc_bioset)
++ *(.text.__tcp_ack_snd_check)
++ *(.text.kthread_bind)
++ *(.text.scsi_delete_timer)
++ *(.text.ox800sata_dev_config)
++ *(.text.add_wait_queue_exclusive)
++ *(.text.ox800sata_bmdma_setup)
++ *(.text.ox800sata_exec_command)
++ *(.text.clear_queue_congested)
++ *(.text.generic_file_sendfile)
++ *(.text.get_io_context)
++ *(.text.swap_buf_le16)
++ *(.text._set_bit_be)
++ *(.text.led_trigger_event)
++ *(.text.current_io_context)
++ *(.text.bio_free)
++ *(.text.pipe_poll)
++ *(.text.freed_request)
++ *(.text.cfq_choose_req)
++ *(.text.ox800sata_RAID_faults)
++ *(.text.rb_prev)
++ *(.text.blk_run_queue)
++ *(.text.mpage_alloc)
++ *(.text.__get_zone_counts)
++ *(.text.mpage_bio_submit)
++ *(.text.generic_fillattr)
++ *(.text.kswapd)
++ *(.text.preempt_schedule_irq)
++ *(.text.mempool_free)
++ *(.text.elv_dequeue_request)
++ *(.text.add_interrupt_randomness)
++ *(.text.poll_initwait)
++ *(.text.__put_user_bad)
++ *(.text.vfs_getattr)
++ *(.text.scsi_free_sgtable)
++ *(.text.laptop_sync_completion)
++ *(.text.submit_bio)
++ *(.text.sock_from_file)
++ *(.text.add_disk_randomness)
++ *(.text.scsi_kill_request)
++ *(.text.free_hot_page)
++ *(.text.bio_endio)
++ *(.text.scsi_dispatch_cmd)
++ *(.text.hipox_dma_start)
++ *(.text.cfq_remove_request)
++ *(.text.do_gettimeofday)
++ *(.text.skb_copy_datagram_iovec)
++ *(.text.ext3_get_blocks_handle)
++ *(.text.__down_read_trylock)
++ *(.text.cfq_activate_request)
++ *(.text.recalc_sigpending)
++ *(.text.ext3_readpage)
++ *(.text.ox800sata_dev_select)
++ *(.text.ret_to_user)
++ *(.text.elv_completed_request)
++ *(.text.read_cache_page)
++ *(.text.touch_atime)
++ *(.text.cfq_update_next_crq)
++ *(.text.no_work_pending)
++ *(.text.recalc_sigpending_tsk)
++ *(.text.end_that_request_chunk)
++ *(.text.cp_new_stat64)
++ *(.text.rb_next)
++ *(.text.__wake_up_sync)
++ *(.text.subsys_create_file)
++ *(.text.rcu_needs_cpu)
++ *(.text.sys_select)
++ *(.text.hipox_dma_device_set)
++ *(.text.ata_sg_init)
++ *(.text.__put_user_8)
++ *(.text.ox800sata_port_disable)
++ *(.text.scsi_next_command)
++ *(.text.__scsi_done)
++ *(.text.ata_scsi_qc_complete)
++ *(.text.__wake_up_locked)
++ *(.text.lru_add_drain)
++ *(.text.bio_check_pages_dirty)
++ *(.text.cascade)
++ *(.text.tcp_poll)
++ *(.text.hipox_dma_set_common)
++ *(.text.__pagevec_release)
++ *(.text.ata_scsi_translate)
++ *(.text.hipox_dma_interrupt)
++ *(.text.sys_newfstat)
++ *(.text.tcp_send_delayed_ack)
++ *(.text.scsi_decide_disposition)
++ *(.text.ox800sata_qc_free)
++ *(.text.scsi_softirq_done)
++ *(.text.netlink_group_mask)
++ *(.text.__brelse)
++ *(.text.do_sock_write)
++ *(.text.mempool_create_node)
++ *(.text.ox800sata_qc_issue)
++ *(.text.__scsi_release_request)
++ *(.text.blockable_page_cache_readahead)
++ *(.text.get_index)
++ *(.text.walk_page_buffers)
++ *(.text.__queue_work)
++ *(.text.ret_from_fork)
++ *(.text.mb_cache_shrink_fn)
++ *(.text.sys_socketcall)
++ *(.text.blk_congestion_wait)
++ *(.text.put_io_context)
++ *(.text.elevator_find)
++ *(.text._set_bit_le)
++ *(.text.generic_write_checks)
++ *(.text.datagram_poll)
++ *(.text.ext3_block_to_path)
++ *(.text.scsi_prep_fn)
++ *(.text.fget)
++ *(.text.blk_plug_device)
++ *(.text.disk_round_stats)
++ *(.text.get_request)
++ *(.text.page_cache_readahead)
++ *(.text.__bread)
++ *(.text.tcp_rcv_space_adjust)
++ *(.text.ox800sata_tf_read)
++ *(.text.add_timer_randomness)
++ *(.text.sockfd_lookup_light)
++ *(.text.__find_get_block)
++ *(.text.split_page)
++ *(.text.cfq_dispatch_requests)
++ *(.text.cfq_kick_queue)
++ *(.text.cfq_may_queue)
++ *(.text.cfq_put_request)
++ *(.text.get_request_wait)
++ *(.text.default_callback)
++ *(.text.cpu_arm926_set_pte)
++ *(.text.tcp_event_data_recv)
++ *(.text.ata_scsi_qc_new)
++ *(.text.SetRoundingMode)
++ *(.text.make_ahead_window)
++ *(.text.inotify_inode_queue_event)
++ *(.text.__make_request)
++ *(.text.finish_wait)
++ *(.text.cfq_completed_request)
++ *(.text.__cfq_slice_expired)
++ *(.text.sd_init_command)
++ *(.text.find_lock_page)
++ *(.text.pipefs_get_sb)
++ *(.text.ata_qc_new_init)
++ *(.text.task_timeslice)
++ *(.text.sk_dst_check)
++ *(.text.set_queue_congested)
++ *(.text.prepare_to_wait)
++ *(.text.sys_write)
++ *(.text.swap_io_context)
++ *(.text.sys_alarm)
++ *(.text.mempool_resize)
++ *(.text.__cond_resched)
++ *(.text.scsi_16_lba_len)
++ *(.text.autoremove_wake_function)
++ *(.text.inotify_dentry_parent_queue_event)
++ *(.text.cfq_init_prio_data)
++ *(.text.group_send_sig_info)
++ *(.text.ata_qc_issue_prot)
++ *(.text.cfq_put_queue)
++ *(.text.__set_irq_handler)
++ *(.text.__generic_file_aio_read)
++ *(.text.ox800sata_eng_timeout)
++ *(.text.rb_erase)
++ *(.text.generic_file_aio_read)
++ *(.text.default_llseek)
++ *(.text.blk_unplug_work)
++ *(.text.linear_make_request)
++ *(.text.elv_insert)
++ *(.text.velocity_init_registers)
++ *(.text.vfs_permission)
++ *(.text.alloc_inode)
++ *(.text.mii_ethtool_sset)
++ *(.text.blk_rq_map_kern)
++ *(.text.tcp_urg)
++ *(.text.__ata_qc_complete)
++ *(.text.io_schedule_timeout)
++ *(.text.run_posix_cpu_timers)
++ *(.text.ox800sata_irq_clear)
++ *(.text.put_tty_driver)
++ *(.text.free_sg_controller)
++ *(.text.__sk_stream_mem_reclaim)
++ *(.text.elv_merge)
++ *(.text.scsi_run_queue)
++ *(.text.elv_former_request)
++ *(.text.blk_requeue_request)
++ *(.text.__end_that_request_first)
++ *(.text.ext3_get_block)
++ *(.text.ox800sata_phy_reset)
++ *(.text.schedule_timeout)
++ *(.text.grab_cache_page_nowait)
++ *(.text.bio_map_kern_endio)
++ *(.text.__up_read)
++ *(.text.tcp_data_queue)
++ *(.text.set_bdev_super)
++ *(.text.ext3_readpages)
++ *(.text.scsi_exit_queue)
++ *(.text.ext3_get_branch)
++ *(.text.cfq_forced_dispatch_cfqqs)
++ *(.text.bioset_free)
++ *(.text.blk_execute_rq_nowait)
++ *(.text.scsi_eh_wakeup)
++ *(.text.tcp_delack_timer)
++ *(.text.shrink_icache_memory)
++ *(.text.mpage_end_io_write)
++ *(.text.scsi_io_completion)
++ *(.text.verify_iovec)
++ *(.text.credit_entropy_store)
++ *(.text.blk_unplug_timeout)
++ *(.text.work_resched)
++ *(.text.sys_sendfile)
++ *(.text.do_bad_IRQ)
++ *(.text.sd_rw_intr)
++ *(.text.set_task_comm)
++ *(.text.blk_do_ordered)
++ *(.text.rb_last)
++ *(.text.drop_buffers)
++ *(.text.ata_scsi_rw_xlat)
++ *(.text.hipox_dma_shutdown)
++ *(.text.__group_send_sig_info)
++ *(.text.led_trigger_set_default)
++ *(.text.blk_queue_bounce)
++ *(.text.cfq_var_store)
++ *(.text.rb_insert_color)
++ *(.text.__remove_hrtimer)
++ *(.text.sys_sysinfo)
++ *(.text.tcp_simple_retransmit)
++ *(.text.it_real_fn)
++ *(.text.sk_send_sigurg)
++ *(.text.sys_statfs64_wrapper)
++ *(.text.alloc_page_buffers)
++ *(.text.bio_pair_release)
++ *(.text.__dequeue_signal)
++ *(.text.kblockd_schedule_work)
++ *(.text.wakeup_kswapd)
++ *(.text.process_timeout)
++ *(.text.__getblk)
++ *(.text.blk_get_request)
++ *(.text.sync_buffer)
++ *(.text.sk_stream_mem_schedule)
++ *(.text.vfs_stat)
++ *(.text.rb_replace_node)
++ *(.text.signal_wake_up)
++ *(.text.ata_std_ports)
++ *(.text.tcp_send_ack)
++ *(.text.send_signal)
++ *(.text._atomic_dec_and_lock)
++ *(.text.set_bh_page)
++ *(.text.mutex_trylock)
++ *(.text.sys_sigaltstack_wrapper)
++ *(.text.sig_ignored)
++ *(.text.net_family_write_lock)
++ *(.text.radix_tree_node_alloc)
++ *(.text.may_open)
++ *(.text.account_user_time)
++ *(.text.udp_seq_start)
++ *(.text.ll_front_merge_fn)
++ *(.text.laptop_flush)
++ *(.text.__tasklet_hi_schedule)
++ *(.text.__und_usr)
++ *(.text.do_signal)
++ *(.text.wake_bit_function)
++ *(.text.mutex_lock_interruptible)
++ *(.text.cfq_merged_request)
++ *(.text.scsi_init_cmd_from_req)
++ *(.text.elv_requeue_request)
++ *(.text.force_sigsegv)
++ *(.text.elv_merge_requests)
++ *(.text.cp_new_stat)
++ *(.text.prepare_to_wait_exclusive)
++ *(.text.ioc_set_batching)
++ *(.text.check_kill_permission)
++ *(.text.scsi_queue_insert)
++ *(.text.__csum_ipv6_magic)
++ *(.text.wb_kupdate)
++ *(.text.__down_write_trylock)
++ *(.text.elv_register_queue)
++ *(.text.sys_getitimer)
++ *(.text.ox800sata_pio_task)
++ *(.text.hrtimer_try_to_cancel)
++ *(.text.find_pid)
++ *(.text.hipox_dma_raw_isactive)
++ *(.text.cmp_ex)
++ *(.text.__mpage_writepage)
++ *(.text.sk_stream_wait_memory)
++ *(.text.sys_sched_yield)
++ *(.text.background_writeout)
++ *(.text.rotate_reclaimable_page)
++ *(.text.do_sigaction)
++ *(.text.sock_def_write_space)
++ *(.text.sched_exit)
++ *(.text.inode_change_ok)
++ *(.text.wait_for_completion_interruptible)
++ *(.text.device_initialize)
++ *(.text.journal_set_revoke)
++ *(.text.try_to_free_pages)
++ *(.text.tcp_write_timer)
++ *(.text.dev_ioctl)
++ *(.text.skb_copy_expand)
++ *(.text.invalidate_complete_page)
++ *(.text.*)
+ __exception_text_start = .;
+ *(.exception.text)
+ __exception_text_end = .;
+diff -Nurd linux-2.6.24/arch/arm/lib/Makefile linux-2.6.24-oxe810/arch/arm/lib/Makefile
+--- linux-2.6.24/arch/arm/lib/Makefile 2008-01-24 23:58:37.000000000 +0100
++++ linux-2.6.24-oxe810/arch/arm/lib/Makefile 2008-06-11 17:47:47.000000000 +0200
+@@ -29,6 +29,10 @@
+ endif
+ endif
+
++ifeq ($(CONFIG_HIPOX_DMA_COPIES),y)
++ lib-y += hipox_copies.o
++endif
++
+ lib-$(CONFIG_MMU) += $(mmu-y)
+
+ ifeq ($(CONFIG_CPU_32v3),y)
+diff -Nurd linux-2.6.24/arch/arm/lib/clear_user.S linux-2.6.24-oxe810/arch/arm/lib/clear_user.S
+--- linux-2.6.24/arch/arm/lib/clear_user.S 2008-01-24 23:58:37.000000000 +0100
++++ linux-2.6.24-oxe810/arch/arm/lib/clear_user.S 2008-06-11 17:47:47.000000000 +0200
+@@ -18,7 +18,11 @@
+ * : sz - number of bytes to clear
+ * Returns : number of bytes NOT cleared
+ */
++#ifdef CONFIG_HIPOX_INSTRUMENT_COPIES
++ENTRY(__clear_user_alt)
++#else // CONFIG_HIPOX_INSTRUMENT_COPIES
+ ENTRY(__clear_user)
++#endif // CONFIG_HIPOX_INSTRUMENT_COPIES
+ stmfd sp!, {r1, lr}
+ mov r2, #0
+ cmp r1, #4
+diff -Nurd linux-2.6.24/arch/arm/lib/copy_from_user.S linux-2.6.24-oxe810/arch/arm/lib/copy_from_user.S
+--- linux-2.6.24/arch/arm/lib/copy_from_user.S 2008-01-24 23:58:37.000000000 +0100
++++ linux-2.6.24-oxe810/arch/arm/lib/copy_from_user.S 2008-06-11 17:47:47.000000000 +0200
+@@ -83,7 +83,12 @@
+
+ .text
+
++#ifdef CONFIG_HIPOX_INSTRUMENT_COPIES
++ENTRY(__copy_from_user_alt)
++#else // CONFIG_HIPOX_INSTRUMENT_COPIES
++.section ".text.__copy_from_user"
+ ENTRY(__copy_from_user)
++#endif // CONFIG_HIPOX_INSTRUMENT_COPIES
+
+ #include "copy_template.S"
+
+diff -Nurd linux-2.6.24/arch/arm/lib/copy_to_user.S linux-2.6.24-oxe810/arch/arm/lib/copy_to_user.S
+--- linux-2.6.24/arch/arm/lib/copy_to_user.S 2008-01-24 23:58:37.000000000 +0100
++++ linux-2.6.24-oxe810/arch/arm/lib/copy_to_user.S 2008-06-11 17:47:47.000000000 +0200
+@@ -86,7 +86,12 @@
+
+ .text
+
++#ifdef CONFIG_HIPOX_INSTRUMENT_COPIES
++ENTRY(__copy_to_user_alt)
++#else // CONFIG_HIPOX_INSTRUMENT_COPIES
++.section ".text.__copy_to_user"
+ ENTRY(__copy_to_user)
++#endif // CONFIG_HIPOX_INSTRUMENT_COPIES
+
+ #include "copy_template.S"
+
+diff -Nurd linux-2.6.24/arch/arm/lib/memcpy.S linux-2.6.24-oxe810/arch/arm/lib/memcpy.S
+--- linux-2.6.24/arch/arm/lib/memcpy.S 2008-01-24 23:58:37.000000000 +0100
++++ linux-2.6.24-oxe810/arch/arm/lib/memcpy.S 2008-06-11 17:47:47.000000000 +0200
+@@ -53,6 +53,7 @@
+
+ /* Prototype: void *memcpy(void *dest, const void *src, size_t n); */
+
++.section ".text.memcpy"
+ ENTRY(memcpy)
+
+ #include "copy_template.S"
+diff -Nurd linux-2.6.24/arch/arm/lib/memzero.S linux-2.6.24-oxe810/arch/arm/lib/memzero.S
+--- linux-2.6.24/arch/arm/lib/memzero.S 2008-01-24 23:58:37.000000000 +0100
++++ linux-2.6.24-oxe810/arch/arm/lib/memzero.S 2008-06-11 17:47:47.000000000 +0200
+@@ -30,6 +30,7 @@
+ * memzero again.
+ */
+
++.section ".text.__memzero"
+ ENTRY(__memzero)
+ mov r2, #0 @ 1
+ ands r3, r0, #3 @ 1 unaligned?
+diff -Nurd linux-2.6.24/arch/arm/lib/hipox_copies.c linux-2.6.24-oxe810/arch/arm/lib/hipox_copies.c
+--- linux-2.6.24/arch/arm/lib/hipox_copies.c 1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.24-oxe810/arch/arm/lib/hipox_copies.c 2008-06-11 17:47:47.000000000 +0200
+@@ -0,0 +1,261 @@
++/*
++ * linux/arch/arm/lib/nas_copies.c
++ *
++ * Copyright (C) 2006 Oxford Semiconductor Ltd
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License as published by
++ * the Free Software Foundation; either version 2 of the License, or
++ * (at your option) any later version.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
++ * GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program; if not, write to the Free Software
++ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
++ */
++#include <linux/compiler.h>
++#include <linux/dma-mapping.h>
++#include <linux/mm.h>
++#include <linux/pagemap.h>
++#include <asm/scatterlist.h>
++#include <asm/semaphore.h>
++#include <asm/arch/dma.h>
++
++static DECLARE_MUTEX(copy_mutex);
++static __DECLARE_SEMAPHORE_GENERIC(callback_semaphore, 0);
++
++static void dma_callback(
++ hipox_dma_channel_t *channel,
++ hipox_callback_arg_t arg,
++ hipox_dma_callback_status_t error_code,
++ u16 checksum,
++ int interrupt_count)
++{
++ up(&callback_semaphore);
++}
++
++unsigned long hipox_copy_from_user(void *to, const void __user *from, unsigned long count)
++{
++ int pages_mapped, i;
++ unsigned long transfered = 0;
++ struct page *pages[2];
++ hipox_dma_channel_t *channel;
++ unsigned long uaddr = (unsigned long)from;
++ unsigned long end_page = (uaddr + count + PAGE_SIZE - 1) >> PAGE_SHIFT;
++ unsigned long start_page = uaddr >> PAGE_SHIFT;
++ int nr_pages = end_page - start_page;
++//printk("F 0x%08lx 0x%08lx %lu -> %lu, %lu, %d\n", (unsigned long)to, (unsigned long)from, count, start_page, end_page, nr_pages);
++
++ might_sleep();
++
++ BUG_ON(nr_pages > 2);
++
++ // Only support a single concurrent copy operation, as only using a single
++ // DMA channel for now
++ while (down_interruptible(&copy_mutex));
++
++ // Get kernel mappings for the user pages
++ down_read(&current->mm->mmap_sem);
++ pages_mapped = get_user_pages(current, current->mm, uaddr, nr_pages, 0, 0, pages, NULL);
++ up_read(&current->mm->mmap_sem);
++
++ if (pages_mapped != nr_pages) {
++ // Didn't get mappings for all pages requested, so release any we did get
++ for (i=0; i < pages_mapped; ++i) {
++ page_cache_release(pages[i]);
++ }
++ pages_mapped = 0;
++ }
++
++ if (pages_mapped) {
++ int i;
++ struct scatterlist sl;
++ struct scatterlist gl[2];
++
++ // Fill gathering DMA descriptors
++ gl[0].page = pages[0];
++ gl[0].offset = uaddr & ~PAGE_MASK;
++ if (pages_mapped > 1) {
++ gl[0].length = PAGE_SIZE - gl[0].offset;
++ gl[1].offset = 0;
++ gl[1].page = pages[1];
++ gl[1].length = count - gl[0].length;
++ } else {
++ gl[0].length = count;
++ }
++
++ // Create DMA mappings for all the user pages
++ for (i=0; i < pages_mapped; ++i) {
++ gl[i].dma_address = dma_map_single(0, page_address(gl[i].page) + gl[i].offset, gl[i].length, DMA_TO_DEVICE);
++ }
++
++ // Create a DMA mapping for the kernel memory range
++ sl.dma_address = dma_map_single(0, to, count, DMA_FROM_DEVICE);
++ sl.length = count;
++
++ // Allocate a DMA channel
++ channel = hipox_dma_request(1);
++ BUG_ON(channel == HIPOX_DMA_CHANNEL_NUL);
++
++ // Do DMA from user to kernel memory
++ hipox_dma_set_sg(
++ channel,
++ gl,
++ pages_mapped,
++ &sl,
++ 1,
++ HIPOX_DMA_MODE_INC,
++ HIPOX_DMA_MODE_INC,
++ 0);
++
++ // Using notification callback
++ hipox_dma_set_callback(channel, dma_callback, HIPOX_DMA_CALLBACK_ARG_NUL);
++ hipox_dma_start(channel);
++
++ // Sleep until transfer complete
++ while (down_interruptible(&callback_semaphore));
++ hipox_dma_set_callback(channel, HIPOX_DMA_CALLBACK_NUL, HIPOX_DMA_CALLBACK_ARG_NUL);
++ transfered += count;
++
++ // Release the DMA channel
++ hipox_dma_free(channel);
++
++ // Release kernel DMA mapping
++ dma_unmap_single(0, sl.length, count, DMA_FROM_DEVICE);
++ // Release user DMA mappings
++ for (i=0; i < pages_mapped; ++i) {
++ dma_unmap_single(0, gl[i].dma_address, gl[i].length, DMA_TO_DEVICE);
++ }
++
++ // Release user pages
++ for (i=0; i < pages_mapped; ++i) {
++ page_cache_release(pages[i]);
++ }
++ }
++
++ up(&copy_mutex);
++
++ return count - transfered;
++}
++
++//unsigned long hipox_copy_to_user(void __user *to, const void *from, unsigned long count)
++//{
++// int pages_mapped, i;
++// unsigned long transfered = 0;
++// struct page *pages[2];
++// hipox_dma_channel_t *channel;
++// unsigned long uaddr = (unsigned long)to;
++// unsigned long end_page = (uaddr + count + PAGE_SIZE - 1) >> PAGE_SHIFT;
++// unsigned long start_page = uaddr >> PAGE_SHIFT;
++// int nr_pages = end_page - start_page;
++////printk("T 0x%08lx 0x%08lx %lu -> %lu, %lu, %d\n", (unsigned long)to, (unsigned long)from, count, start_page, end_page, nr_pages);
++//
++// might_sleep();
++//
++// BUG_ON(nr_pages > 2);
++//
++// // Only support a single concurrent copy operation, as only using a single
++// // DMA channel for now
++// while (down_interruptible(&copy_mutex));
++//
++// // Get kernel mappings for the user pages
++// down_read(&current->mm->mmap_sem);
++// pages_mapped = get_user_pages(current, current->mm, uaddr, nr_pages, 1, 0, pages, NULL);
++// up_read(&current->mm->mmap_sem);
++//
++// if (pages_mapped != nr_pages) {
++// // Didn't get mapping for all the pages we requested, so release any
++// // user page mappings we did get
++// for (i=0; i < pages_mapped; ++i) {
++// page_cache_release(pages[i]);
++// }
++// pages_mapped = 0;
++// }
++//
++// if (pages_mapped) {
++// int i;
++// struct scatterlist gl;
++// struct scatterlist sl[2];
++//
++// // Fill scattering DMA descriptors for writing to user space
++// sl[0].page = pages[0];
++// sl[0].offset = uaddr & ~PAGE_MASK;
++// if (pages_mapped > 1) {
++// sl[0].length = PAGE_SIZE - sl[0].offset;
++// sl[1].offset = 0;
++// sl[1].page = pages[1];
++// sl[1].length = count - sl[0].length;
++// } else {
++// sl[0].length = count;
++// }
++//
++// // Create DMA mappings for all the user pages
++// for (i=0; i < pages_mapped; ++i) {
++// sl[i].__address = page_address(sl[i].page) + sl[i].offset;
++// sl[i].dma_address = dma_map_single(0, sl[i].__address, sl[i].length, DMA_FROM_DEVICE);
++// }
++//
++// // Create a DMA mapping for the kernel memory range
++// gl.dma_address = dma_map_single(0, (void*)from, count, DMA_TO_DEVICE);
++// gl.length = count;
++//
++//// {
++//////flush_cache_all();
++//// // Do copy with CPU to test
++//// const char* src = from;
++//////printk("T Copying...\n");
++//// for (i=0; i < pages_mapped; ++i) {
++//// void* kadr = kmap(sl[i].page) + sl[i].offset;
++//// memcpy(kadr, src, sl[i].length);
++//// kunmap(sl[i].page);
++//// src += sl[i].length;
++//// transfered += sl[i].length;
++//// }
++//// }
++//
++//flush_cache_all();
++// // Allocate a DMA channel
++// channel = hipox_dma_request(1);
++// BUG_ON(channel == HIPOX_DMA_CHANNEL_NUL);
++//
++// // Do DMA from kernel to user memory
++// hipox_dma_set_sg(
++// channel,
++// &gl,
++// 1,
++// sl,
++// pages_mapped,
++// HIPOX_DMA_MODE_INC,
++// HIPOX_DMA_MODE_INC,
++// 0);
++// hipox_dma_start(channel);
++// while (hipox_dma_is_active(channel));
++// transfered += count;
++//
++// // Release the DMA channel
++// hipox_dma_free(channel);
++////flush_cache_all();
++//
++// // Release kernel DMA mapping
++// dma_unmap_single(0, gl.dma_address, count, DMA_TO_DEVICE);
++// // Release user DMA mappings
++// for (i=0; i < pages_mapped; ++i) {
++// dma_unmap_single(0, sl[i].dma_address, sl[i].length, DMA_FROM_DEVICE);
++// }
++//
++// // Release user pages
++// for (i=0; i < pages_mapped; ++i) {
++// SetPageDirty(pages[i]);
++// page_cache_release(pages[i]);
++// }
++// }
++//
++// up(&copy_mutex);
++//
++// return count - transfered;
++//}
++
+diff -Nurd linux-2.6.24/arch/arm/mach-hipox/Kconfig linux-2.6.24-oxe810/arch/arm/mach-hipox/Kconfig
+--- linux-2.6.24/arch/arm/mach-hipox/Kconfig 1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.24-oxe810/arch/arm/mach-hipox/Kconfig 2008-06-11 17:47:55.000000000 +0200
+@@ -0,0 +1,574 @@
++if ARCH_HIPOX
++
++menu "Oxford Semiconductor NAS Options"
++
++config ARCH_HIPOX_FPGA
++ bool "FPGA platform"
++ default n
++ help
++ This enables support for Oxsemi NAS SoC FPGA development platform
++
++config HIPOX_CORE_CLK
++ int "Integrator core module processor clock frequency in MHz"
++ depends on ARCH_HIPOX_FPGA
++ default 175
++ help
++ Maximum reliable frequency 175MHz
++
++config HIPOX_CORE_BUS_CLK_DIV
++ int "Integrator core module bus clock divider"
++ depends on ARCH_HIPOX_FPGA
++ default 4
++ help
++ Must be greater than 0
++
++config NOMINAL_PLL400_FREQ
++ int "The master clock frequency of the Soc"
++ default 400000000
++ help
++ The PLL400 clock is divided by 2 to drive the ARM clock and by
++ 4 to drive the AHB clock
++
++config NOMINAL_RPSCLK_FREQ
++ int "The input clock frequency to the RPS"
++ default 25000000
++ help
++ The RPS clock feeds into a prescaler and from there feeds the
++ RPS timers
++
++choice
++ prompt "HIPOX system type"
++ default HIPOX_VERSION_0X800
++
++config HIPOX_VERSION_0X800
++ bool "0X800"
++ select ARM_AMBA
++ help
++ Support for the 0X800 SoC
++
++config HIPOX_VERSION_0X810
++ bool "0X810"
++ select ARM_AMBA
++ help
++ Support for the 0X810 SoC
++
++config HIPOX_VERSION_0X850
++ bool "0X850"
++ help
++ Support for the 0X850 SoC
++endchoice
++
++config ARCH_HIPOX_UART1
++ bool "Support UART1"
++ default n
++ help
++ This enables UART1 to be accessible to Linux.
++ UARTs will be mapped to ttySn numbers from UART1 to UART4, only
++ including those UARTs selected to be present
++
++config ARCH_HIPOX_UART1_MODEM
++ bool "Support UART1 modem control lines"
++ depends on ARCH_HIPOX_UART1
++ default n
++ help
++ Multiplex the modem control lines from UART1 onto external pins
++
++config ARCH_HIPOX_UART2
++ bool "Support UART2"
++ default n
++ help
++ This enables UART2 to be accessible to Linux
++ UARTs will be mapped to ttySn numbers from UART1 to UART4, only
++ including those UARTs selected to be present
++
++config ARCH_HIPOX_UART2_MODEM
++ bool "Support UART2 modem control lines"
++ depends on ARCH_HIPOX_UART2
++ default n
++ help
++ Multiplex the modem control lines from UART2 onto external pins
++
++config ARCH_HIPOX_UART3
++ bool "Support UART3"
++ default n
++ help
++ This enables UAR3 to be accessible to Linux
++ UARTs will be mapped to ttySn numbers from UART1 to UART4, only
++ including those UARTs selected to be present
++
++config ARCH_HIPOX_UART3_MODEM
++ bool "Support UART3 modem control lines"
++ depends on ARCH_HIPOX_UART3
++ default n
++ help
++ Multiplex the modem control lines from UART3 onto external pins
++
++config ARCH_HIPOX_UART4
++ bool "Support UART4"
++ depends on !PCI
++ default n
++ help
++ This enables UART4 to be accessible to Linux
++ UARTs will be mapped to ttySn numbers from UART1 to UART4, only
++ including those UARTs selected to be present
++ UART4 always has its modem control lines available on external pins
++ when selected (overlaying PCI functions)
++
++config ARCH_HIPOX_PCI_REQGNT_0
++ bool "Enable req/gnt for PCI device 0"
++ depends on PCI
++ default n
++ help
++
++config ARCH_HIPOX_PCI_REQGNT_1
++ bool "Enable req/gnt for PCI device 1"
++ depends on PCI
++ default n
++ help
++
++config ARCH_HIPOX_PCI_REQGNT_2
++ bool "Enable req/gnt for PCI device 2"
++ depends on PCI
++ default n
++ help
++
++config ARCH_HIPOX_PCI_REQGNT_3
++ bool "Enable req/gnt for PCI device 3"
++ depends on PCI
++ default n
++ help
++
++config ARCH_HIPOX_PCI_CLKOUT_0
++ bool "Enable PCI clock output 0"
++ depends on PCI
++ default n
++ help
++
++config ARCH_HIPOX_PCI_CLKOUT_1
++ bool "Enable PCI clock output 1"
++ depends on PCI
++ default n
++ help
++
++config ARCH_HIPOX_PCI_CLKOUT_2
++ bool "Enable PCI clock output 2"
++ depends on PCI
++ default n
++ help
++
++config ARCH_HIPOX_PCI_CLKOUT_3
++ bool "Enable PCI clock output 3"
++ depends on PCI
++ default n
++ help
++
++config HIPOX_PCI_RESET
++ bool "Allow PCI reset to be toggled after power up"
++ depends on PCI
++ default n
++ help
++ The SoC requires that the PCI bus reset be toggled after the
++ rest of the SoC has emerged from reset
++
++config HIPOX_PCI_RESET_GPIO
++ int "GPIO line connected to PCI reset"
++ depends on HIPOX_PCI_RESET
++ default 12
++ help
++ The PCI bus requires a separate reset to be asserted after the
++ reset of the SoC has emerged from reset. This defines the GPIO
++ line which is connected to the PCI reset
++
++config HIPOX_SATA_POWER_1
++ bool "Allow control of SATA 1 disk power via GPIO"
++ default n
++ help
++ Allow SATA disk 1 power to be turned off via GPIO lines
++
++config HIPOX_SATA_POWER_GPIO_1
++ int "GPIO line connected to SATA power control for disk 1"
++ depends on HIPOX_SATA_POWER_1
++ default 15
++ help
++ The GPIO line that controls SATA disk 1 power
++
++config HIPOX_SATA_POWER_2
++ bool "Allow control of SATA disk 2 power via GPIO"
++ default n
++ help
++ Allow SATA disk 2 power to be turned off via GPIO lines
++
++config HIPOX_SATA_POWER_GPIO_2
++ int "GPIO line connected to SATA power control for disk 2"
++ depends on HIPOX_SATA_POWER_2
++ default 18
++ help
++ The GPIO line that controls SATA disk 2 power
++
++config FORCE_MAX_ZONEORDER
++ int "Max order of zoned buddy allocator"
++ default 11
++ help
++ The value to be assigned to MAX_ORDER
++
++config SRAM_NUM_PAGES
++ int "The number of SRAM memory pages present in the system"
++ default 8
++ help
++ Determines the number of pages of SRAM that are assumed to exist in the
++ system memory map
++
++config SUPPORT_LEON
++ bool "Include support for Leon"
++ default n
++
++config LEON_PAGES
++ int "The number of 4K pages of SRAM to reserve for the LEON program"
++ depends on SUPPORT_LEON
++ default 2
++ help
++ Determines the number of 4K pages of SRAM that are reserved for the
++ LEON program
++
++config LEON_COPRO
++ bool "Load LEON networking acceleration program"
++ depends on SUPPORT_LEON && HIPOX_VERSION_0X810
++ default n
++
++config LEON_OFFLOAD_TX
++ bool "Whether network Tx operations should be offloaded to the LEON"
++ depends on LEON_COPRO
++ default n
++
++config LEON_RESERVE_DMA_CHANNEL
++ bool "Whether to reserve the last DMA channel for the CoPro's use"
++ depends on LEON_OFFLOAD_TX
++ default n
++
++config LEON_OFFLOAD_TSO
++ bool "Whether network TSO operations should be offloaded to the LEON"
++ depends on LEON_OFFLOAD_TX
++ default n
++
++config LEON_START_EARLY
++ bool "Load LEON early startup program"
++ depends on SUPPORT_LEON
++ default n
++ help
++ For situations where the LEON is to run some code unrelated to
++ its normal network acceleration functions, this options causes
++ the LEON code to be loaded and the LEON started early in the
++ boot process
++
++config LEON_POWER_BUTTON_MONITOR
++ tristate "Load LEON power button monitoring program"
++ depends on SUPPORT_LEON
++ default n
++ help
++ Support powering down the system via a GPIO button and when the
++ system is powered down load a LEON program that will monitor the
++ button for attempts to power the system back on
++
++config HIPOX_POWER_BUTTON_GPIO
++ int "GPIO line connected to power button"
++ depends on LEON_POWER_BUTTON_MONITOR
++ default 33
++ help
++ Specifies the GPIO line to which the power button is connected
++
++config USER_RECOVERY_BUTTON_MONITOR
++ tristate "Load user recovery button monitoring program"
++ default n
++ help
++ Support User recovery of the system via a GPIO button. When the
++ system is power cycled after the use of this button, the admin
++ password and network settings are set to factory values.
++
++config HIPOX_USER_RECOVERY_BUTTON_GPIO
++ int "GPIO line connected to user recovery button"
++ depends on USER_RECOVERY_BUTTON_MONITOR
++ default 32
++ help
++ Specifies the GPIO line to which the user recovery button is
++ connected.
++
++config HIPOX_DDR_MON
++ bool "Poll the DDR core bus monitors from timer tick interrupt"
++ default n
++
++config HIPOX_AHB_MON
++ bool "Include support for AHB monitors"
++ default n
++
++config HIPOX_MONITOR_SUBSAMPLE
++ int "Jiffy subsample factor for AHB monitor sampling"
++ depends on HIPOX_AHB_MON || HIPOX_DDR_MON
++ default 10
++ help
++ The factor by which to subsample the jiffy count to produce AHB monitor
++ sampling events
++
++config HIPOX_CACHE_LOCKDOWN
++ bool "Allow locking down part of the caches"
++ default n
++
++config HIPOX_CACHE_I_MASK
++ int "Bit mask for I cache lockdown"
++ depends on HIPOX_CACHE_LOCKDOWN
++ default 0
++ help
++ Allowable values are:
++ 0 - No ways locked down
++ 1 - One way locked down
++ 3 - Two ways locked down
++ 7 - Three ways locked down
++
++config HIPOX_CACHE_D_MASK
++ int "Bit mask for D cache lockdown"
++ depends on HIPOX_CACHE_LOCKDOWN
++ default 0
++ help
++ Allowable values are:
++ 0 - No ways locked down
++ 1 - One way locked down
++ 3 - Two ways locked down
++ 7 - Three ways locked down
++
++config DO_MEM_TEST
++ bool "Perform memory copy throughput test during boot"
++ default 0
++
++config CRYPTO_OXAESLRW
++ tristate "LRW-AES hardware support"
++ help
++ Driver for controlling the Ox-Semi OX800 cipher core for LRW-AES
++ encryption
++
++config DESCRIPTORS_PAGES
++ int "The number of SRAM memory pages to reserve for DMA descriptors"
++ default 1
++ help
++ Determines the number of pages of SRAM that are reserved for DMA
++ descriptors
++
++config ARCH_HIPOX_NUM_GMAC_DESCRIPTORS
++ int "The number of GMAC descriptors to allocate"
++ default 112
++
++config ARCH_HIPOX_MAX_SATA_SG_ENTRIES
++ int "The max. number of SG DMA descriptors to use in the single transfer"
++ default 64
++
++config TACHO_THERM_AND_FAN
++ tristate "Include support for the temperature sensing, and automatic fan control"
++ default n
++
++config GPIO_TEST
++ tristate "Device driver for exercising GPIO block."
++ default n
++ help
++ Connect the I2C serial lines (SCLK, SCS, and SDT) together to run test
++
++config HIPOX_RTC
++ tristate "Probe for m41t00 RTC"
++ select I2C
++ select I2C_ALGOBIT
++ select I2C_HIPOX_BITBASH
++ select RTC_CLASS
++ select RTC_DRV_DS1307
++ default n
++ help
++ The M41T00 RTC provides basic time save and restore.
++ The device is probed for on the HIPOX bit-bash I2C bus.
++
++config I2S
++ tristate "I2S test interface"
++ default n
++ help
++ Say Y here to use i2s
++ This support is also available as a module. If so, the module will be
++ called i2s.
++
++config PCI_HIPOX_CARDBUS
++ bool "Switches from a PCI/Mini-PCI bus to a Cardbus bus."
++ depends on PCI && ARCH_HIPOX_FPGA
++ ---help---
++ This option limits scanning of the bus to omit the Via SATA interface.
++ This makes the bus compatible with cardbus cards that expect to be the
++ only PCI device on the bus.
++
++config DPE_TEST
++ tristate "Test the DPE core"
++ default n
++
++config HIPOX_EARLY_PRINTK
++ bool "Whether to output to printascii from printk"
++ depends on DEBUG_LL
++ help
++ If both CONFIG_DEBUG_LL and this option are selected, then each printk
++ call will duplicate the message in a call to printascii to get very
++ early console output
++
++config HIPOX_INSTRUMENT_COPIES
++ bool "Instrument copy_to_user and copy_from_user"
++ default n
++
++config HIPOX_INSTRUMENT_COPIES_THRESHOLD
++ int "The threshold above which copies will be instrumented"
++ depends on HIPOX_INSTRUMENT_COPIES
++ default 0
++
++config HIPOX_INSTRUMENT_COPIES_TIME
++ bool "Whether to print copy timing to console"
++ depends on HIPOX_INSTRUMENT_COPIES
++ default n
++
++config HIPOX_INSTRUMENT_COPIES_GPIO
++ bool "Whether to toggle a GPIO around copies"
++ depends on HIPOX_INSTRUMENT_COPIES
++ default n
++
++config HIPOX_DMA_COPIES
++ bool "Whether to use DMA for larger user-kernel copies"
++ default n
++
++config HIPOX_DMA_COPY_THRESHOLD
++ int "The threshold above which DMA will be used for copies"
++ depends on HIPOX_DMA_COPIES
++ default 1024
++
++config HIPOX_AHB_MONITOR_MODULE
++ tristate "Creates a loadable module to control the AHB monitors"
++ default n
++ help
++ This module publishes the current values of the AHB
++ monitors in the /proc filing system.
++ The monitors can be controlled by writing into this
++ filing system
++
++config HIPOX_USB_TEST_MODES
++ tristate "Create a loadable module to control the USB port test modes"
++ default n
++ help
++ This module reports the port status and allows setting
++ of the test mode in the port register via the /proc
++ filing system.
++
++config HIPOX_FRONT_LAMP_CONTROL
++ tristate "Front Panel LED control system"
++ depends on LEDS_CLASS
++ default n
++ help
++ This module reports drives a number of GPIOs as PWM signals to drive
++ front panel LEDs. The pattern displayed is dependent on system state.
++
++config LEDS_TRIGGER_SATA_DISK
++ tristate "Front Panel SATA disk activity lamp control system"
++ default n
++ help
++ This module reports drives the SATA disk activity lamp.
++
++config HIPOX_LED_TEST
++ bool "Exercise the WD LEDs"
++ default n
++
++config HIPOX_I2C_SDA
++ int "I2C bit-bash data line"
++ default 2
++
++config HIPOX_I2C_SCL
++ int "I2C bit-bash clock line"
++ default 3
++
++config HIPOX_USB_PORTA_POWER_CONTROL
++ bool "Support USB port A power control lines"
++ default n
++ help
++ Whether to support power switch out and monitor in via GPIOs
++ for USB port A
++
++config HIPOX_USB_PORTB_POWER_CONTROL
++ bool "Support USB port B power control lines"
++ default n
++ help
++ Whether to support power switch out and monitor in via GPIOs
++ for USB port B
++
++config HIPOX_USB_PORTC_POWER_CONTROL
++ bool "Support USB port C power control lines"
++ default n
++ help
++ Whether to support power switch out and monitor in via GPIOs
++ for USB port C
++
++config HIPOX_USB_OVERCURRENT_POLARITY_NEGATIVE
++ bool "Set USB power monitor input polarity to negative"
++ default n
++ help
++ n - Positive polarity
++ y - Negative polarity
++
++config HIPOX_USB_POWER_SWITCH_POLARITY_NEGATIVE
++ bool "Set USB power switch output polarity to negative"
++ default n
++ help
++ n - Positive polarity
++ y - Negative polarity
++
++config WDC_FAN_HIPOX800
++ tristate "WD NetCenter/2NC Fan control driver"
++ default n
++ help
++ This driver allows user-mode applications to control the cooling
++ fan on Western Digital's NetCenter/2NC platform.
++
++config HIPOX_MAP_SRAM
++ bool "Allow part of kernel to be mapped into SRAM"
++ default n
++
++config HIPOX_COPY_CODE_TO_SRAM
++ bool "Copy part of kernel to SRAM"
++ depends on HIPOX_MAP_SRAM
++ default n
++
++config HIPOX_SUID_INHERIT
++ bool "Make SUID be inherited by subdirectories"
++ default n
++
++config HIPOX_USB_HUB_SUPPORT
++ bool "Enable support for on-board USB hub"
++ default n
++
++config HIPOX_USB_CKOUT
++ bool "Enable output of 12MHz USB clock on GPIO 10"
++ depends on HIPOX_USB_HUB_SUPPORT
++ default n
++
++config HIPOX_USB_HUB_RESET_CONTROL
++ bool "Control the USB hub reset line"
++ depends on HIPOX_USB_HUB_SUPPORT
++ default n
++
++config HIPOX_USB_HUB_RESET_GPIO
++ int "The GPIO connected to the USB hub reset"
++ depends on HIPOX_USB_HUB_RESET_CONTROL
++ default 27
++
++config HIPOX_USB_HUB_RESET_ACTIVE_HIGH
++ int "Set to 1 for active high, 0 for active low reset"
++ depends on HIPOX_USB_HUB_RESET_CONTROL
++ default 1
++
++config HIPOX_USB_HUB_RESET_TOGGLE
++ bool "Select to toggle reset, do not select to just deassert reset"
++ depends on HIPOX_USB_HUB_RESET_CONTROL
++ default y
++
++config HIPOX_USB_HUB_RESET_PERIOD_MS
++ int "The period for which the USB hub reset should be asserted in milliseconds"
++ depends on HIPOX_USB_HUB_RESET_TOGGLE
++ default 100
++
++endmenu
++
++endif
+diff -Nurd linux-2.6.24/arch/arm/mach-hipox/Makefile linux-2.6.24-oxe810/arch/arm/mach-hipox/Makefile
+--- linux-2.6.24/arch/arm/mach-hipox/Makefile 1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.24-oxe810/arch/arm/mach-hipox/Makefile 2008-06-11 17:47:55.000000000 +0200
+@@ -0,0 +1,43 @@
++#
++# Makefile for the linux kernel.
++#
++
++# Object file lists.
++
++obj-y := hipox.o irq.o time.o dma.o pci.o ahb_mon.o leon.o samba_reserve.o
++
++obj-$(CONFIG_SYNOPSYS_GMAC) += gmac.o
++
++gmac-objs := gmac-napi.o gmac_ethtool.o gmac_phy.o gmac_desc.o gmac_offload.o
++
++obj-$(CONFIG_HIPOX_IBW) += ibw.o
++
++obj-$(CONFIG_TACHO_THERM_AND_FAN) += thermAndFan.o
++
++obj-$(CONFIG_I2S) += i2s.o
++
++obj-$(CONFIG_CRYPTO_OXAESLRW) += cipher.o
++
++obj-$(CONFIG_GPIO_TEST) += gpioTest.o
++
++obj-$(CONFIG_I2S) += i2s.o
++
++obj-$(CONFIG_DPE_TEST) += dpe_test.o
++
++obj-$(CONFIG_HIPOX_AHB_MONITOR_MODULE) += hipox-ahb-monitor.o
++
++obj-$(CONFIG_HIPOX_USB_TEST_MODES) += usb-test-mode.o
++
++obj-$(CONFIG_LEON_POWER_BUTTON_MONITOR) += power_button.o
++
++obj-$(CONFIG_USER_RECOVERY_BUTTON_MONITOR) += user_recovery_button.o
++
++obj-$(CONFIG_HIPOX_FRONT_LAMP_CONTROL) += leds.o
++
++obj-$(CONFIG_WDC_FAN_HIPOX800) += wdc-fan.o
++
++obj-$(CONFIG_WDC_LEDS_HIPOX800) += wdc-leds.o
++
++obj-$(CONFIG_HIPOX_WD810_LEDS) += hipox-wd810-leds.o
++
++obj-$(CONFIG_WDC_LEDS_TRIGGER_SATA_DISK) += wdc-ledtrig-sata.o
+diff -Nurd linux-2.6.24/arch/arm/mach-hipox/Makefile.boot linux-2.6.24-oxe810/arch/arm/mach-hipox/Makefile.boot
+--- linux-2.6.24/arch/arm/mach-hipox/Makefile.boot 1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.24-oxe810/arch/arm/mach-hipox/Makefile.boot 2008-06-11 17:47:55.000000000 +0200
+@@ -0,0 +1,3 @@
++initrd_phys-$(CONFIG_ARCH_HIPOX) := 0x48200000
++params_phys-$(CONFIG_ARCH_HIPOX) := 0x48000100
++zreladdr-$(CONFIG_ARCH_HIPOX) := 0x48008000
+diff -Nurd linux-2.6.24/arch/arm/mach-hipox/README linux-2.6.24-oxe810/arch/arm/mach-hipox/README
+--- linux-2.6.24/arch/arm/mach-hipox/README 1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.24-oxe810/arch/arm/mach-hipox/README 2008-06-11 17:47:55.000000000 +0200
+@@ -0,0 +1,85 @@
++
++usb-test-modes
++
++This is best built as a module which may be inserted into a running
++Linux system only when needed.
++The module can be built as part of the standard kernel module build
++if the correct options are chosen in the config.
++
++
++How to use:
++
++copy the usb-test-mode.ko file somewhere convenient on the NAS and
++insert the module into the system using
++'modprobe usb-test-mode.ko'
++
++It should report successfull loading or an error message. Assuming it is
++successful /proc will have an 'usb_test_mode' entry (verify with ls).
++
++Actions:
++read the current port status:
++cat /proc/usb_test_mode/read
++
++set port 1 into test mode 4:
++echo 4 > /proc/usb_test_mode/write1
++
++
++When testing is completed the module can be removed from the linux
++system using:
++rmmod usb_test_mode
++
++ahb_mon
++
++This should be built as a module.
++
++How to use:
++
++insert the module into a working system by typing
++'modprobe hipox-ahb-monitor'
++
++When successfully installed a directory entry will appear in /proc for
++hipox-ahb-monitor. In the directory will be a writeable file for each
++AHB monitor and a control file. There will also be a readable file for
++obtaining the counts stored in all the ahb monitors.
++
++
++Actions:
++set a monitor to a limited range, burst mode etc using
++low addres, high address, mode, burst mode, burst mask, hprot, hprot mask
++
++Use the echo command to set data into the /proc/hipox-ahb-monitor an example is
++the following script to observe the activities of the ARM processor on the GMAC
++core when pinging a remote machine:
++---------------------------
++#!/bin/sh -x
++#
++
++# start montoring of ARM data bus to MAC
++# format is "low high mode burst mask hprot mask"
++# mode - 1 write 2 read 3 read write.
++
++echo 2 > /proc/hipox-test/control
++
++echo 0 > /proc/hipox-test/control
++
++
++echo "0x40400000,0x405fffff,3,0,0,0,0" > /proc/hipox-test/ARM_Data
++echo "0x40400000,0x405fffff,3,0,0,0,0" > /proc/hipox-test/Arm_Inst
++echo "0,4,3,0,0,0,0" > /proc/hipox-test/CoPro
++echo "0,4,3,0,0,0,0" > /proc/hipox-test/DMA_A
++echo "0,4,3,0,0,0,0" > /proc/hipox-test/DMA_B
++echo "0,4,3,0,0,0,0" > /proc/hipox-test/GMAC
++echo "0,4,3,0,0,0,0" > /proc/hipox-test/PCI
++echo "0,4,3,0,0,0,0" > /proc/hipox-test/USBHS
++
++echo 1 > /proc/hipox-test/control
++
++ping -c 1 172.31.0.102
++
++echo 0 > /proc/hipox-test/control
++--------------------------------------
++
++When testing is commplete the module can be removed using
++rmmod hipox-ahb-monitor
++
++
+Files linux-2.6.24/arch/arm/mach-hipox/ThermCalc.xls and linux-2.6.24-oxe810/arch/arm/mach-hipox/ThermCalc.xls differ
+diff -Nurd linux-2.6.24/arch/arm/mach-hipox/ahb_mon.c linux-2.6.24-oxe810/arch/arm/mach-hipox/ahb_mon.c
+--- linux-2.6.24/arch/arm/mach-hipox/ahb_mon.c 1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.24-oxe810/arch/arm/mach-hipox/ahb_mon.c 2008-06-11 17:47:55.000000000 +0200
+@@ -0,0 +1,177 @@
++/*
++ * linux/arch/arm/mach-hipox/ahb_mon.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
++ */
++
++#include <linux/kernel.h>
++#include <asm/io.h>
++#include <asm/arch/hardware.h>
++
++#ifdef CONFIG_HIPOX_AHB_MON
++static void start_ahb_monitors(void)
++{
++ writel(AHB_MON_MODE_ACTIVE << AHB_MON_MODE_MODE_BIT, AHB_MON_ARM_D + AHB_MON_MODE_REG_OFFSET);
++ writel(AHB_MON_MODE_ACTIVE << AHB_MON_MODE_MODE_BIT, AHB_MON_ARM_I + AHB_MON_MODE_REG_OFFSET);
++ writel(AHB_MON_MODE_ACTIVE << AHB_MON_MODE_MODE_BIT, AHB_MON_DMA_A + AHB_MON_MODE_REG_OFFSET);
++ writel(AHB_MON_MODE_ACTIVE << AHB_MON_MODE_MODE_BIT, AHB_MON_DMA_B + AHB_MON_MODE_REG_OFFSET);
++ writel(AHB_MON_MODE_ACTIVE << AHB_MON_MODE_MODE_BIT, AHB_MON_LEON + AHB_MON_MODE_REG_OFFSET);
++ writel(AHB_MON_MODE_ACTIVE << AHB_MON_MODE_MODE_BIT, AHB_MON_USB + AHB_MON_MODE_REG_OFFSET);
++ writel(AHB_MON_MODE_ACTIVE << AHB_MON_MODE_MODE_BIT, AHB_MON_MAC + AHB_MON_MODE_REG_OFFSET);
++ writel(AHB_MON_MODE_ACTIVE << AHB_MON_MODE_MODE_BIT, AHB_MON_PCI + AHB_MON_MODE_REG_OFFSET);
++}
++
++void init_ahb_monitors(
++ AHB_MON_HWRITE_T ahb_mon_hwrite,
++ unsigned hburst_mask,
++ unsigned hburst_match,
++ unsigned hprot_mask,
++ unsigned hprot_match)
++{
++ u32 hburst_mask_value = (hburst_mask & ((1 << AHB_MON_HBURST_MASK_NUM_BITS) - 1));
++ u32 hburst_match_value = (hburst_match & ((1 << AHB_MON_HBURST_MATCH_NUM_BITS) - 1));
++ u32 hprot_mask_value = (hprot_mask & ((1 << AHB_MON_HPROT_MASK_NUM_BITS) - 1));
++ u32 hprot_match_value = (hprot_match & ((1 << AHB_MON_HPROT_MATCH_NUM_BITS) - 1));
++
++ u32 hburst_reg_value = (hburst_mask_value << AHB_MON_HBURST_MASK_BIT) | (hburst_match_value << AHB_MON_HBURST_MATCH_BIT);
++ u32 hprot_reg_value = (hprot_mask_value << AHB_MON_HPROT_MASK_BIT) | (hprot_match_value << AHB_MON_HPROT_MATCH_BIT);
++
++printk("$Ghburst reg value = 0x%08x\n", hburst_reg_value);
++printk("$Ghprot reg value = 0x%08x\n", hprot_reg_value);
++
++ // Reset all the counters and set their operating mode
++ writel(AHB_MON_MODE_RESET << AHB_MON_MODE_MODE_BIT, AHB_MON_ARM_D + AHB_MON_MODE_REG_OFFSET);
++ writel(ahb_mon_hwrite << AHB_MON_HWRITE_COUNT_BIT, AHB_MON_ARM_D + AHB_MON_HWRITE_REG_OFFSET);
++ writel(0UL, AHB_MON_ARM_D + AHB_MON_HADDR_LOW_REG_OFFSET);
++ writel(~0UL, AHB_MON_ARM_D + AHB_MON_HADDR_HIGH_REG_OFFSET);
++ writel(hburst_reg_value, AHB_MON_ARM_D + AHB_MON_HBURST_REG_OFFSET);
++ writel(hprot_reg_value, AHB_MON_ARM_D + AHB_MON_HPROT_REG_OFFSET);
++
++ writel(AHB_MON_MODE_RESET << AHB_MON_MODE_MODE_BIT, AHB_MON_ARM_I + AHB_MON_MODE_REG_OFFSET);
++ writel(ahb_mon_hwrite << AHB_MON_HWRITE_COUNT_BIT, AHB_MON_ARM_I + AHB_MON_HWRITE_REG_OFFSET);
++ writel(0UL, AHB_MON_ARM_I + AHB_MON_HADDR_LOW_REG_OFFSET);
++ writel(~0UL, AHB_MON_ARM_I + AHB_MON_HADDR_HIGH_REG_OFFSET);
++ writel(hburst_reg_value, AHB_MON_ARM_I + AHB_MON_HBURST_REG_OFFSET);
++ writel(hprot_reg_value, AHB_MON_ARM_I + AHB_MON_HPROT_REG_OFFSET);
++
++ writel(AHB_MON_MODE_RESET << AHB_MON_MODE_MODE_BIT, AHB_MON_DMA_A + AHB_MON_MODE_REG_OFFSET);
++ writel(ahb_mon_hwrite << AHB_MON_HWRITE_COUNT_BIT, AHB_MON_DMA_A + AHB_MON_HWRITE_REG_OFFSET);
++ writel(0UL, AHB_MON_DMA_A + AHB_MON_HADDR_LOW_REG_OFFSET);
++ writel(~0UL, AHB_MON_DMA_A + AHB_MON_HADDR_HIGH_REG_OFFSET);
++ writel(hburst_reg_value, AHB_MON_DMA_A + AHB_MON_HBURST_REG_OFFSET);
++ writel(hprot_reg_value, AHB_MON_DMA_A + AHB_MON_HPROT_REG_OFFSET);
++
++ writel(AHB_MON_MODE_RESET << AHB_MON_MODE_MODE_BIT, AHB_MON_DMA_B + AHB_MON_MODE_REG_OFFSET);
++ writel(ahb_mon_hwrite << AHB_MON_HWRITE_COUNT_BIT, AHB_MON_DMA_B + AHB_MON_HWRITE_REG_OFFSET);
++ writel(0UL, AHB_MON_DMA_B + AHB_MON_HADDR_LOW_REG_OFFSET);
++ writel(~0UL, AHB_MON_DMA_B + AHB_MON_HADDR_HIGH_REG_OFFSET);
++ writel(hburst_reg_value, AHB_MON_DMA_B + AHB_MON_HBURST_REG_OFFSET);
++ writel(hprot_reg_value, AHB_MON_DMA_B + AHB_MON_HPROT_REG_OFFSET);
++
++ writel(AHB_MON_MODE_RESET << AHB_MON_MODE_MODE_BIT, AHB_MON_LEON + AHB_MON_MODE_REG_OFFSET);
++ writel(ahb_mon_hwrite << AHB_MON_HWRITE_COUNT_BIT, AHB_MON_LEON + AHB_MON_HWRITE_REG_OFFSET);
++ writel(0UL, AHB_MON_LEON + AHB_MON_HADDR_LOW_REG_OFFSET);
++ writel(~0UL, AHB_MON_LEON + AHB_MON_HADDR_HIGH_REG_OFFSET);
++ writel(hburst_reg_value, AHB_MON_LEON + AHB_MON_HBURST_REG_OFFSET);
++ writel(hprot_reg_value, AHB_MON_LEON + AHB_MON_HPROT_REG_OFFSET);
++
++ writel(AHB_MON_MODE_RESET << AHB_MON_MODE_MODE_BIT, AHB_MON_USB + AHB_MON_MODE_REG_OFFSET);
++ writel(ahb_mon_hwrite << AHB_MON_HWRITE_COUNT_BIT, AHB_MON_USB + AHB_MON_HWRITE_REG_OFFSET);
++ writel(0UL, AHB_MON_USB + AHB_MON_HADDR_LOW_REG_OFFSET);
++ writel(~0UL, AHB_MON_USB + AHB_MON_HADDR_HIGH_REG_OFFSET);
++ writel(hburst_reg_value, AHB_MON_USB + AHB_MON_HBURST_REG_OFFSET);
++ writel(hprot_reg_value, AHB_MON_USB + AHB_MON_HPROT_REG_OFFSET);
++
++ writel(AHB_MON_MODE_RESET << AHB_MON_MODE_MODE_BIT, AHB_MON_MAC + AHB_MON_MODE_REG_OFFSET);
++ writel(ahb_mon_hwrite << AHB_MON_HWRITE_COUNT_BIT, AHB_MON_MAC + AHB_MON_HWRITE_REG_OFFSET);
++ writel(0UL, AHB_MON_MAC + AHB_MON_HADDR_LOW_REG_OFFSET);
++ writel(~0UL, AHB_MON_MAC + AHB_MON_HADDR_HIGH_REG_OFFSET);
++ writel(hburst_reg_value, AHB_MON_MAC + AHB_MON_HBURST_REG_OFFSET);
++ writel(hprot_reg_value, AHB_MON_MAC + AHB_MON_HPROT_REG_OFFSET);
++
++ writel(AHB_MON_MODE_RESET << AHB_MON_MODE_MODE_BIT, AHB_MON_PCI + AHB_MON_MODE_REG_OFFSET);
++ writel(ahb_mon_hwrite << AHB_MON_HWRITE_COUNT_BIT, AHB_MON_PCI + AHB_MON_HWRITE_REG_OFFSET);
++ writel(0UL, AHB_MON_PCI + AHB_MON_HADDR_LOW_REG_OFFSET);
++ writel(~0UL, AHB_MON_PCI + AHB_MON_HADDR_HIGH_REG_OFFSET);
++ writel(hburst_reg_value, AHB_MON_PCI + AHB_MON_HBURST_REG_OFFSET);
++ writel(hprot_reg_value, AHB_MON_PCI + AHB_MON_HPROT_REG_OFFSET);
++
++ // Start all the counters
++ start_ahb_monitors();
++}
++
++void restart_ahb_monitors(void)
++{
++ // Reset the counters
++ writel(AHB_MON_MODE_RESET << AHB_MON_MODE_MODE_BIT, AHB_MON_ARM_D + AHB_MON_MODE_REG_OFFSET);
++ writel(AHB_MON_MODE_RESET << AHB_MON_MODE_MODE_BIT, AHB_MON_ARM_I + AHB_MON_MODE_REG_OFFSET);
++ writel(AHB_MON_MODE_RESET << AHB_MON_MODE_MODE_BIT, AHB_MON_DMA_A + AHB_MON_MODE_REG_OFFSET);
++ writel(AHB_MON_MODE_RESET << AHB_MON_MODE_MODE_BIT, AHB_MON_DMA_B + AHB_MON_MODE_REG_OFFSET);
++ writel(AHB_MON_MODE_RESET << AHB_MON_MODE_MODE_BIT, AHB_MON_LEON + AHB_MON_MODE_REG_OFFSET);
++ writel(AHB_MON_MODE_RESET << AHB_MON_MODE_MODE_BIT, AHB_MON_USB + AHB_MON_MODE_REG_OFFSET);
++ writel(AHB_MON_MODE_RESET << AHB_MON_MODE_MODE_BIT, AHB_MON_MAC + AHB_MON_MODE_REG_OFFSET);
++ writel(AHB_MON_MODE_RESET << AHB_MON_MODE_MODE_BIT, AHB_MON_PCI + AHB_MON_MODE_REG_OFFSET);
++
++ // Start the counters
++ start_ahb_monitors();
++}
++
++void read_ahb_monitors(void)
++{
++ // Prepare the counters for reading
++ writel(AHB_MON_MODE_IDLE << AHB_MON_MODE_MODE_BIT, AHB_MON_ARM_D + AHB_MON_MODE_REG_OFFSET);
++ writel(AHB_MON_MODE_IDLE << AHB_MON_MODE_MODE_BIT, AHB_MON_ARM_I + AHB_MON_MODE_REG_OFFSET);
++ writel(AHB_MON_MODE_IDLE << AHB_MON_MODE_MODE_BIT, AHB_MON_DMA_A + AHB_MON_MODE_REG_OFFSET);
++ writel(AHB_MON_MODE_IDLE << AHB_MON_MODE_MODE_BIT, AHB_MON_DMA_B + AHB_MON_MODE_REG_OFFSET);
++ writel(AHB_MON_MODE_IDLE << AHB_MON_MODE_MODE_BIT, AHB_MON_LEON + AHB_MON_MODE_REG_OFFSET);
++ writel(AHB_MON_MODE_IDLE << AHB_MON_MODE_MODE_BIT, AHB_MON_USB + AHB_MON_MODE_REG_OFFSET);
++ writel(AHB_MON_MODE_IDLE << AHB_MON_MODE_MODE_BIT, AHB_MON_MAC + AHB_MON_MODE_REG_OFFSET);
++ writel(AHB_MON_MODE_IDLE << AHB_MON_MODE_MODE_BIT, AHB_MON_PCI + AHB_MON_MODE_REG_OFFSET);
++
++ // Read the counters
++ printk("ARM-D: B=%u, T=%u, W=%u\n", readl(AHB_MON_ARM_D + AHB_MON_CYCLES_REG_OFFSET),
++ readl(AHB_MON_ARM_D + AHB_MON_TRANSFERS_REG_OFFSET),
++ readl(AHB_MON_ARM_D + AHB_MON_WAITS_REG_OFFSET));
++
++ printk("ARM-I: B=%u, T=%u, W=%u\n", readl(AHB_MON_ARM_I + AHB_MON_CYCLES_REG_OFFSET),
++ readl(AHB_MON_ARM_I + AHB_MON_TRANSFERS_REG_OFFSET),
++ readl(AHB_MON_ARM_I + AHB_MON_WAITS_REG_OFFSET));
++
++ printk("DMA-A: B=%u, T=%u, W=%u\n", readl(AHB_MON_DMA_A + AHB_MON_CYCLES_REG_OFFSET),
++ readl(AHB_MON_DMA_A + AHB_MON_TRANSFERS_REG_OFFSET),
++ readl(AHB_MON_DMA_A + AHB_MON_WAITS_REG_OFFSET));
++
++ printk("DMA-B: B=%u, T=%u, W=%u\n", readl(AHB_MON_DMA_B + AHB_MON_CYCLES_REG_OFFSET),
++ readl(AHB_MON_DMA_B + AHB_MON_TRANSFERS_REG_OFFSET),
++ readl(AHB_MON_DMA_B + AHB_MON_WAITS_REG_OFFSET));
++
++ printk("LEON: B=%u, T=%u, W=%u\n", readl(AHB_MON_LEON + AHB_MON_CYCLES_REG_OFFSET),
++ readl(AHB_MON_LEON + AHB_MON_TRANSFERS_REG_OFFSET),
++ readl(AHB_MON_LEON + AHB_MON_WAITS_REG_OFFSET));
++
++ printk("USB: B=%u, T=%u, W=%u\n", readl(AHB_MON_USB + AHB_MON_CYCLES_REG_OFFSET),
++ readl(AHB_MON_USB + AHB_MON_TRANSFERS_REG_OFFSET),
++ readl(AHB_MON_USB + AHB_MON_WAITS_REG_OFFSET));
++
++ printk("MAC: B=%u, T=%u, W=%u\n", readl(AHB_MON_MAC + AHB_MON_CYCLES_REG_OFFSET),
++ readl(AHB_MON_MAC + AHB_MON_TRANSFERS_REG_OFFSET),
++ readl(AHB_MON_MAC + AHB_MON_WAITS_REG_OFFSET));
++
++ printk("PCI: B=%u, T=%u, W=%u\n", readl(AHB_MON_PCI + AHB_MON_CYCLES_REG_OFFSET),
++ readl(AHB_MON_PCI + AHB_MON_TRANSFERS_REG_OFFSET),
++ readl(AHB_MON_PCI + AHB_MON_WAITS_REG_OFFSET));
++}
++#endif // CONFIG_HIPOX_AHB_MON
++
+diff -Nurd linux-2.6.24/arch/arm/mach-hipox/cipher.c linux-2.6.24-oxe810/arch/arm/mach-hipox/cipher.c
+--- linux-2.6.24/arch/arm/mach-hipox/cipher.c 1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.24-oxe810/arch/arm/mach-hipox/cipher.c 2008-06-11 17:47:55.000000000 +0200
+@@ -0,0 +1,362 @@
++/* linux/arch/arm/mach-hipox/cipher.c
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License version 2 as
++ * published by the Free Software Foundation.
++ */
++
++#include <linux/types.h>
++#include <linux/sched.h>
++#include <linux/types.h>
++#include <linux/kernel.h>
++#include <linux/init.h>
++#include <linux/list.h>
++#include <linux/device.h>
++#include <linux/string.h>
++#include <linux/sysdev.h>
++#include <linux/highmem.h>
++#include <asm/semaphore.h>
++#include <asm/arch/cipher.h>
++#include <asm/io.h>
++#include <asm/arch/hardware.h>
++#include <linux/dma-mapping.h>
++#include <asm/arch/dma.h>
++#include <asm-arm/page.h>
++
++
++#if 0
++#define DPRINTK(fmt, args...) printk(KERN_ERR "%s: " fmt, __FUNCTION__, ## args)
++#define VPRINTK(fmt, args...) printk(KERN_ERR "%s: " fmt, __FUNCTION__, ## args)
++#else
++#define DPRINTK(fmt, args...)
++#define VPRINTK(fmt, args...)
++#endif
++
++//#define CIPHER_USE_SG_DMA
++
++/*****************************************************************************/
++
++typedef struct ox800_aeslrw_driver ox800_aeslrw_driver_t;
++
++struct ox800_aeslrw_driver {
++ struct device dev;
++ struct semaphore core;
++ int result;
++ u8 cipher_key[OX800DPE_KEYSIZE];
++ u8 tweak_key[OX800DPE_KEYSIZE];
++};
++
++static ox800_aeslrw_driver_t ox800_aeslrw_driver;
++
++
++/*****************************************************************************/
++
++/**
++ * Sets the keys only if they have changed.
++ * @param cipher_key 16 byte array that is the cipher key
++ * @param tweak_key 16 byte array that is the I-Value tweak key
++ */
++static void ox800_aeslrw_setkeys(u8* cipher_key, u8* tweak_key)
++{
++ VPRINTK(KERN_INFO"\n");
++
++ /*
++ * changing the keys can take a long time as the core will
++ * compute internal values based on the keys
++ */
++ if (memcmp(&(ox800_aeslrw_driver.cipher_key[0]), cipher_key, OX800DPE_KEYSIZE) ||
++ memcmp(&(ox800_aeslrw_driver.tweak_key[0]), tweak_key, OX800DPE_KEYSIZE) )
++ {
++ u32* key;
++ unsigned int i;
++
++ DPRINTK(KERN_INFO"cipher key =");
++ for (i = 0; i < OX800DPE_KEYSIZE; ++i)
++ DPRINTK("%02x", cipher_key[i]);
++ DPRINTK("\n");
++ DPRINTK(KERN_INFO"tweak key =");
++ for (i = 0; i < OX800DPE_KEYSIZE; ++i)
++ DPRINTK("%02x", tweak_key[i]);
++ DPRINTK("\n");
++
++ /* update stored values */
++ memcpy(&(ox800_aeslrw_driver.cipher_key[0]), cipher_key, OX800DPE_KEYSIZE);
++ memcpy(&(ox800_aeslrw_driver.tweak_key[0]), tweak_key, OX800DPE_KEYSIZE);
++
++ /* update hardware values */
++ key = (u32* )cipher_key;
++ writel(key[0], OX800DPE_KEY00 );
++ writel(key[1], OX800DPE_KEY01 );
++ writel(key[2], OX800DPE_KEY02 );
++ writel(key[3], OX800DPE_KEY03 );
++
++ key = (u32* )tweak_key;
++ writel(key[0], OX800DPE_KEY10 );
++ writel(key[1], OX800DPE_KEY11 );
++ writel(key[2], OX800DPE_KEY12 );
++ writel(key[3], OX800DPE_KEY13 );
++ }
++}
++
++/**
++ * Generic LRW-AES en/decryption
++ * @param encrypt non-zero to encrypt, zero to decrypt
++ * @param in Source of data
++ * @param out Location to place en/decrypted data
++ * @param nents Number of entries in scatter list, in and out must have the same
++ * number of entries
++ * @param iv 8 byte array containing the I-Value
++ * @return error code or 0 for success
++ */
++static int ox800_aeslrw_gencrypt( u8 encrypt,
++ struct scatterlist* in,
++ struct scatterlist* out,
++ unsigned int nents,
++ u8 iv[])
++{
++ hipox_dma_channel_t* dma_in;
++ hipox_dma_channel_t* dma_out;
++ struct scatterlist* out_;
++ char same_buffer;
++ int status = 0;
++
++ /* get dma resources (non blocking) */
++ dma_in = hipox_dma_request(0);
++ dma_out = hipox_dma_request(0);
++
++ VPRINTK("dma in %d out %d \n",
++ dma_in->channel_number_,
++ dma_out->channel_number_);
++
++ if ((dma_in) && (dma_out)) {
++ u32 reg;
++
++ // shouldn't be busy or full
++ reg = readl( OX800DPE_STATUS );
++ if (! (reg & OX800DPE_STAT_IDLE) )
++ printk("not idle after abort toggle");
++ if (reg & OX800DPE_STAT_TX_NOTEMPTY)
++ printk("tx fifo not empty after abort toggle");
++ if (! (reg & OX800DPE_STAT_RX_SPACE) )
++ printk("rx not empty after abort toggle");
++
++ /* check to see if the destination buffer is the same as the source */
++ same_buffer = (in->page == out->page);
++
++ /* map transfers */
++ if (same_buffer) {
++ dma_map_sg(NULL, in, nents, DMA_BIDIRECTIONAL);
++ out_ = in;
++ } else {
++ /* map transfers */
++ dma_map_sg(NULL, in, nents, DMA_TO_DEVICE);
++ dma_map_sg(NULL, out, nents, DMA_FROM_DEVICE);
++ out_ = out;
++ }
++#ifdef CIPHER_USE_SG_DMA
++ /* setup DMA transfers */
++ hipox_dma_device_set_sg(
++ dma_in,
++ HIPOX_DMA_TO_DEVICE,
++ in,
++ nents,
++ &hipox_dpe_rx_dma_settings,
++ HIPOX_DMA_MODE_INC);
++
++ hipox_dma_device_set_sg(
++ dma_out,
++ HIPOX_DMA_FROM_DEVICE,
++ out_,
++ nents,
++ &hipox_dpe_tx_dma_settings,
++ HIPOX_DMA_MODE_INC);
++
++#else
++ hipox_dma_device_set(
++ dma_in,
++ HIPOX_DMA_TO_DEVICE,
++ (unsigned char* )sg_dma_address(in),
++ sg_dma_len(in),
++ &hipox_dpe_rx_dma_settings,
++ HIPOX_DMA_MODE_INC,
++ 1 /*paused */ );
++
++ hipox_dma_device_set(
++ dma_out,
++ HIPOX_DMA_FROM_DEVICE,
++ (unsigned char* )sg_dma_address(out_),
++ sg_dma_len(out_),
++ &hipox_dpe_tx_dma_settings,
++ HIPOX_DMA_MODE_INC,
++ 1 /*paused */ );
++#endif
++
++ /* set dma callbacks */
++ hipox_dma_set_callback(
++ dma_in,
++ HIPOX_DMA_CALLBACK_ARG_NUL,
++ HIPOX_DMA_CALLBACK_ARG_NUL);
++
++ hipox_dma_set_callback(
++ dma_out,
++ HIPOX_DMA_CALLBACK_ARG_NUL,
++ HIPOX_DMA_CALLBACK_ARG_NUL);
++
++
++ /* set for AES LRW encryption or decryption */
++ writel( (encrypt ? OX800DPE_CTL_DIRECTION_ENC : 0 ) |
++ OX800DPE_CTL_MODE_LRW_AES,
++ OX800DPE_CONTROL);
++ wmb();
++
++ /* write in I-value */
++ writel(*((u32* )&(iv[0])), OX800DPE_DATA_LRW0 );
++ writel(*((u32* )&(iv[4])), OX800DPE_DATA_LRW1 );
++
++ wmb();
++
++ /* wait until done */
++ while( !(OX800DPE_STAT_IDLE & readl( OX800DPE_STATUS )) );
++
++ /* start dma */
++ hipox_dma_start(dma_out);
++ hipox_dma_start(dma_in);
++
++ /* wait (once for each channel) */
++ while ( hipox_dma_is_active( dma_out ) ||
++ hipox_dma_is_active( dma_in ) )
++ {
++ schedule();
++ }
++
++ /* free any allocated dma channels */
++ hipox_dma_free( dma_in );
++ hipox_dma_free( dma_out );
++
++ /* unmap transfers */
++ if (same_buffer) {
++ dma_unmap_sg(NULL, in, nents, DMA_BIDIRECTIONAL);
++ } else {
++ dma_unmap_sg(NULL, in, nents, DMA_TO_DEVICE);
++ dma_unmap_sg(NULL, out, nents, DMA_FROM_DEVICE);
++ }
++
++ status = ox800_aeslrw_driver.result;
++ } else {
++ /* free any allocated dma channels */
++ if (dma_in)
++ hipox_dma_free( dma_in );
++ if (dma_out)
++ hipox_dma_free( dma_out );
++ status = -EBUSY;
++ }
++ /* return an indication of success */
++ return status;
++}
++
++/**
++ * Performs LRW-AES encryption.
++ * @param in Source of data
++ * @param out Location to place encrypted data
++ * @param nents Number of entries in scatter list, in and out must have the same
++ * number of entries
++ * @param iv I-Value
++ * @param cipher_key 16 byte array that is the cipher key
++ * @param tweak_key 16 byte array that is the I-Value tweak key
++ * @return error code or 0 for success
++ */
++int ox800_aeslrw_encrypt( struct scatterlist* in,
++ struct scatterlist* out,
++ unsigned int nents,
++ u8* iv,
++ u8* cipher_key,
++ u8* tweak_key)
++{
++ int localresult;
++
++ VPRINTK(KERN_INFO"in %p, out %p, nents %d, iv %08x%08x, ckey %p, tkey %p\n",
++ in, out, nents, *((u32* )(&iv[4])), *((u32* )(&iv[0])), cipher_key, tweak_key );
++
++ /* get cipher core */
++ while( down_interruptible(&ox800_aeslrw_driver.core) ) ;
++
++ VPRINTK(KERN_INFO"got core\n");
++
++ ox800_aeslrw_setkeys(cipher_key, tweak_key);
++ localresult = ox800_aeslrw_gencrypt( 1, in, out, nents, iv);
++
++ up(&ox800_aeslrw_driver.core);
++ VPRINTK(KERN_INFO"released\n");
++
++ return localresult;
++}
++
++/**
++ * Performs LRW-AES decryption.
++ * @param in Source of data
++ * @param out Location to place decrypted data
++ * @param nents Number of entries in scatter list, in and out must have the same
++ * number of entries
++ * @param iv I-Value
++ * @param cipher_key 16 byte array that is the cipher key
++ * @param tweak_key 16 byte array that is the I-Value tweak key
++ * @return error code or 0 for success
++ */
++int ox800_aeslrw_decrypt( struct scatterlist* in,
++ struct scatterlist* out,
++ unsigned int nents,
++ u8* iv,
++ u8* cipher_key,
++ u8* tweak_key)
++{
++ int localresult;
++
++ VPRINTK(KERN_INFO"in %p, out %p, nents %d, iv %08x%08x, ckey %p, tkey%p\n",
++ in, out, nents, *((u32* )(&iv[4])), *((u32* )(&iv[0])), cipher_key, tweak_key );
++
++ /* get cipher core */
++ while( down_interruptible(&ox800_aeslrw_driver.core) ) ;
++
++ VPRINTK(KERN_INFO"got core\n");
++
++ ox800_aeslrw_setkeys(cipher_key, tweak_key);
++ localresult = ox800_aeslrw_gencrypt( 0, in, out, nents, iv);
++
++ up(&ox800_aeslrw_driver.core);
++ VPRINTK(KERN_INFO"released core \n");
++
++ return localresult;
++}
++
++/**
++ * module initialisation
++ * @return success is 0
++ */
++static int __init ox800_aeslrw_init( void )
++{
++ VPRINTK(KERN_INFO"\n");
++
++ /* Enable the clock to the DPE block */
++ writel(1UL << SYS_CTRL_CKEN_DPE_BIT, SYS_CTRL_CKEN_SET_CTRL);
++
++ /* Bring out of reset */
++ writel(1UL << SYS_CTRL_RSTEN_DPE_BIT, SYS_CTRL_RSTEN_CLR_CTRL);
++
++ /* initialise in unlocked state */
++ init_MUTEX(&ox800_aeslrw_driver.core);
++
++ return 0;
++}
++
++/**
++ * module cleanup
++ */
++static void __exit ox800_aeslrw_exit( void )
++{
++}
++
++/**
++ * macros to register intiialisation and exit functions with kernal
++ */
++module_init(ox800_aeslrw_init);
++module_exit(ox800_aeslrw_exit);
+diff -Nurd linux-2.6.24/arch/arm/mach-hipox/dma.c linux-2.6.24-oxe810/arch/arm/mach-hipox/dma.c
+--- linux-2.6.24/arch/arm/mach-hipox/dma.c 1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.24-oxe810/arch/arm/mach-hipox/dma.c 2008-06-11 17:47:55.000000000 +0200
+@@ -0,0 +1,2849 @@
++/*
++ * linux/arch/arm/mach-hipox/dma.c
++ *
++ * Copyright (C) 2005 Oxford Semiconductor Ltd
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License as published by
++ * the Free Software Foundation; either version 2 of the License, or
++ * (at your option) any later version.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
++ * GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program; if not, write to the Free Software
++ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
++ */
++#include <asm/dma.h>
++#include <asm/io.h>
++#include <asm/irq.h>
++#include <asm/arch/hardware.h>
++#include <linux/bitops.h>
++#include <linux/dma-mapping.h>
++#include <linux/dmapool.h>
++#include <linux/init.h>
++#include <linux/interrupt.h>
++#include <linux/delay.h>
++#include <asm/arch/desc_alloc.h>
++
++#ifdef CONFIG_HIPOX_VERSION_0X800
++#include <asm/checksum.h>
++#endif // CONFIG_HIPOX_VERSION_0X800
++
++//#define DMA_DEBUG
++
++#ifdef HIPOX_DMA_TEST
++#define DMA_DEBUG
++static void dma_test(unsigned long length);
++#endif // HIPOX_DMA_TEST
++
++#ifdef HIPOX_DMA_SG_TEST
++#define DMA_DEBUG
++static void dma_sg_test(void);
++#endif // HIPOX_DMA_SG_TEST
++
++#ifdef HIPOX_DMA_SG_TEST_2
++#define DMA_DEBUG
++static void dma_sg_test2(void);
++#endif // HIPOX_DMA_SG_TEST_2
++
++#ifdef DMA_DEBUG
++#define DBG(args...) printk(args)
++#else
++#define DBG(args...) do { } while(0)
++#endif
++
++// Normal (non-SG) registers
++#define DMA_REGS_PER_CHANNEL 8
++
++#define DMA_CTRL_STATUS 0x0
++#define DMA_BASE_SRC_ADR 0x4
++#define DMA_BASE_DST_ADR 0x8
++#define DMA_BYTE_CNT 0xC
++#define DMA_CURRENT_SRC_ADR 0x10
++#define DMA_CURRENT_DST_ADR 0x14
++#define DMA_CURRENT_BYTE_CNT 0x18
++#define DMA_INTR_ID 0x1C
++#define DMA_INTR_CLEAR_REG (DMA_CURRENT_SRC_ADR)
++
++// 8 quad-sized registers per channel arranged contiguously
++#define DMA_CALC_REG_ADR(channel, register) (DMA_BASE + ((channel) << 5) + (register))
++
++#define DMA_CTRL_STATUS_FAIR_SHARE_ARB (1 << 0)
++#define DMA_CTRL_STATUS_IN_PROGRESS (1 << 1)
++#define DMA_CTRL_STATUS_SRC_DREQ_MASK (0x0000003C)
++#define DMA_CTRL_STATUS_SRC_DREQ_SHIFT 2
++#define DMA_CTRL_STATUS_DEST_DREQ_MASK (0x000003C0)
++#define DMA_CTRL_STATUS_DEST_DREQ_SHIFT 6
++#define DMA_CTRL_STATUS_INTR (1 << 10)
++#define DMA_CTRL_STATUS_NXT_FREE (1 << 11)
++#define DMA_CTRL_STATUS_RESET (1 << 12)
++#define DMA_CTRL_STATUS_DIR_MASK (0x00006000)
++#define DMA_CTRL_STATUS_DIR_SHIFT 13
++#define DMA_CTRL_STATUS_SRC_ADR_MODE (1 << 15)
++#define DMA_CTRL_STATUS_DEST_ADR_MODE (1 << 16)
++#define DMA_CTRL_STATUS_TRANSFER_MODE_A (1 << 17)
++#define DMA_CTRL_STATUS_TRANSFER_MODE_B (1 << 18)
++#define DMA_CTRL_STATUS_SRC_WIDTH_MASK (0x00380000)
++#define DMA_CTRL_STATUS_SRC_WIDTH_SHIFT 19
++#define DMA_CTRL_STATUS_DEST_WIDTH_MASK (0x01C00000)
++#define DMA_CTRL_STATUS_DEST_WIDTH_SHIFT 22
++#define DMA_CTRL_STATUS_PAUSE (1 << 25)
++#define DMA_CTRL_STATUS_INTERRUPT_ENABLE (1 << 26)
++#define DMA_CTRL_STATUS_SOURCE_ADDRESS_FIXED (1 << 27)
++#define DMA_CTRL_STATUS_DESTINATION_ADDRESS_FIXED (1 << 28)
++#define DMA_CTRL_STATUS_STARVE_LOW_PRIORITY (1 << 29)
++#define DMA_CTRL_STATUS_INTR_CLEAR_ENABLE (1 << 30)
++
++#define DMA_BYTE_CNT_MASK ((1 << 21) - 1)
++#define DMA_BYTE_CNT_INC4_SET_MASK (1 << 28)
++#define DMA_BYTE_CNT_HPROT_MASK (1 << 29)
++#define DMA_BYTE_CNT_WR_EOT_MASK (1 << 30)
++#define DMA_BYTE_CNT_RD_EOT_MASK (1 << 31)
++
++#define DMA_INTR_ID_GET_NUM_CHANNELS(reg_contents) (((reg_contents) >> 16) & 0xFF)
++#define DMA_INTR_ID_GET_VERSION(reg_contents) (((reg_contents) >> 24) & 0xFF)
++#define DMA_INTR_ID_INT_BIT 0
++#define DMA_INTR_ID_INT_NUM_BITS (MAX_HIPOX_DMA_CHANNELS)
++#define DMA_INTR_ID_INT_MASK (((1 << DMA_INTR_ID_INT_NUM_BITS) - 1) << DMA_INTR_ID_INT_BIT)
++
++#define DMA_HAS_V4_INTR_CLEAR(version) ((version) > 3)
++
++// H/W scatter gather controller registers
++#define HIPOX_DMA_NUM_SG_REGS 4
++
++#define DMA_SG_CONTROL 0x0
++#define DMA_SG_STATUS 0x04
++#define DMA_SG_REQ_PTR 0x08
++#define DMA_SG_RESETS 0x0C
++
++#define DMA_SG_CALC_REG_ADR(channel, register) ((DMA_SG_BASE) + ((channel) << 4) + (register))
++
++// SG DMA controller control register field definitions
++#define DMA_SG_CONTROL_START_BIT 0
++#define DMA_SG_CONTROL_QUEUING_ENABLE_BIT 1
++#define DMA_SG_CONTROL_HBURST_ENABLE_BIT 2
++
++// SG DMA controller status register field definitions
++#define DMA_SG_STATUS_ERROR_CODE_BIT 0
++#define DMA_SG_STATUS_ERROR_CODE_NUM_BITS 6
++#define DMA_SG_STATUS_BUSY_BIT 7
++
++// SG DMA controller sub-block resets register field definitions
++#define DMA_SG_RESETS_CONTROL_BIT 0
++#define DMA_SG_RESETS_ARBITER_BIT 1
++#define DMA_SG_RESETS_AHB_BIT 2
++
++// hipox_dma_sg_info_t qualifier field definitions
++#define HIPOX_DMA_SG_QUALIFIER_BIT 0
++#define HIPOX_DMA_SG_QUALIFIER_NUM_BITS 16
++#define HIPOX_DMA_SG_DST_EOT_BIT 16
++#define HIPOX_DMA_SG_DST_EOT_NUM_BITS 2
++#define HIPOX_DMA_SG_SRC_EOT_BIT 20
++#define HIPOX_DMA_SG_SRC_EOT_NUM_BITS 2
++#define HIPOX_DMA_SG_CHANNEL_BIT 24
++#define HIPOX_DMA_SG_CHANNEL_NUM_BITS 8
++
++// Valid address bits mask
++#define HIPOX_DMA_ADR_MASK ((1UL << (MEM_MAP_ALIAS_SHIFT)) - 1)
++
++#ifdef CONFIG_HIPOX_VERSION_0X800
++#define HIPOX_DMA_CSUM_ADR_MASK ((HIPOX_DMA_ADR_MASK) | (1UL << (HIPOX_DMA_CSUM_ENABLE_ADR_BIT)))
++#else
++#define HIPOX_DMA_CSUM_ADR_MASK (HIPOX_DMA_ADR_MASK)
++#endif // CONFIG_HIPOX_VERSION_0X800
++
++/* The available buses to which the DMA controller is attached */
++typedef enum hipox_dma_transfer_bus
++{
++ HIPOX_DMA_SIDE_A,
++ HIPOX_DMA_SIDE_B
++} hipox_dma_transfer_bus_t;
++
++/* Direction of data flow between the DMA controller's pair of interfaces */
++typedef enum hipox_dma_transfer_direction
++{
++ HIPOX_DMA_A_TO_A,
++ HIPOX_DMA_B_TO_A,
++ HIPOX_DMA_A_TO_B,
++ HIPOX_DMA_B_TO_B
++} hipox_dma_transfer_direction_t;
++
++/* The available data widths */
++typedef enum hipox_dma_transfer_width
++{
++ HIPOX_DMA_TRANSFER_WIDTH_8BITS,
++ HIPOX_DMA_TRANSFER_WIDTH_16BITS,
++ HIPOX_DMA_TRANSFER_WIDTH_32BITS
++} hipox_dma_transfer_width_t;
++
++/* The mode of the DMA transfer */
++typedef enum hipox_dma_transfer_mode
++{
++ HIPOX_DMA_TRANSFER_MODE_SINGLE,
++ HIPOX_DMA_TRANSFER_MODE_BURST
++} hipox_dma_transfer_mode_t;
++
++/* The available transfer targets */
++typedef enum hipox_dma_dreq
++{
++ HIPOX_DMA_DREQ_PATA = 0,
++ HIPOX_DMA_DREQ_SATA = 0,
++ HIPOX_DMA_DREQ_DPE_RX = 1,
++ HIPOX_DMA_DREQ_DPE_TX = 2,
++ HIPOX_DMA_DREQ_AUDIO_TX = 5,
++ HIPOX_DMA_DREQ_AUDIO_RX = 6,
++ HIPOX_DMA_DREQ_MEMORY = 15
++} hipox_dma_dreq_t;
++
++/* Pre-defined settings for known DMA devices */
++hipox_dma_device_settings_t hipox_pata_dma_settings = {
++ .address_ = 0,
++ .fifo_size_ = 16,
++ .dreq_ = HIPOX_DMA_DREQ_PATA,
++ .read_eot_policy_ = HIPOX_DMA_EOT_FINAL,
++ .write_eot_policy_ = HIPOX_DMA_EOT_FINAL,
++ .bus_ = HIPOX_DMA_SIDE_A,
++ .width_ = HIPOX_DMA_TRANSFER_WIDTH_32BITS,
++ .transfer_mode_ = HIPOX_DMA_TRANSFER_MODE_BURST,
++ .address_mode_ = HIPOX_DMA_MODE_FIXED,
++ .address_really_fixed_ = 0
++};
++
++hipox_dma_device_settings_t hipox_sata_dma_settings = {
++ .address_ = SATA_DATA_BASE_PA,
++ .fifo_size_ = 16,
++ .dreq_ = HIPOX_DMA_DREQ_SATA,
++ .read_eot_policy_ = HIPOX_DMA_EOT_FINAL,
++ .write_eot_policy_ = HIPOX_DMA_EOT_FINAL,
++ .bus_ = HIPOX_DMA_SIDE_A,
++ .width_ = HIPOX_DMA_TRANSFER_WIDTH_32BITS,
++ .transfer_mode_ = HIPOX_DMA_TRANSFER_MODE_BURST,
++ .address_mode_ = HIPOX_DMA_MODE_FIXED,
++ .address_really_fixed_ = 0
++};
++
++hipox_dma_device_settings_t hipox_dpe_rx_dma_settings = {
++ .address_ = DPE_BASE_PA,
++ .fifo_size_ = 16,
++ .dreq_ = HIPOX_DMA_DREQ_DPE_RX,
++ .read_eot_policy_ = HIPOX_DMA_EOT_FINAL,
++ .write_eot_policy_ = HIPOX_DMA_EOT_FINAL,
++ .bus_ = HIPOX_DMA_SIDE_A,
++ .width_ = HIPOX_DMA_TRANSFER_WIDTH_32BITS,
++ .transfer_mode_ = HIPOX_DMA_TRANSFER_MODE_BURST,
++ .address_mode_ = HIPOX_DMA_MODE_FIXED,
++ .address_really_fixed_ = 0
++};
++
++hipox_dma_device_settings_t hipox_dpe_tx_dma_settings = {
++ .address_ = DPE_BASE_PA,
++ .fifo_size_ = 16,
++ .dreq_ = HIPOX_DMA_DREQ_DPE_TX,
++ .read_eot_policy_ = HIPOX_DMA_EOT_FINAL,
++ .write_eot_policy_ = HIPOX_DMA_EOT_FINAL,
++ .bus_ = HIPOX_DMA_SIDE_A,
++ .width_ = HIPOX_DMA_TRANSFER_WIDTH_32BITS,
++ .transfer_mode_ = HIPOX_DMA_TRANSFER_MODE_BURST,
++ .address_mode_ = HIPOX_DMA_MODE_FIXED,
++ .address_really_fixed_ = 0
++};
++
++/* For use with normal memory to memory transfers as the settings for the source
++ * of the transfer */
++hipox_dma_device_settings_t hipox_ram_only_src_dma_settings = {
++ .address_ = 0,
++ .fifo_size_ = 0,
++ .dreq_ = HIPOX_DMA_DREQ_MEMORY,
++ .read_eot_policy_ = HIPOX_DMA_EOT_FINAL, // Won't interfere with checksumming transfers, as csum only latched if high order address bit set
++ .write_eot_policy_ = HIPOX_DMA_EOT_NONE,
++ .bus_ = HIPOX_DMA_SIDE_A, // Maximise performance with src on side A while dst in on side B
++ .width_ = HIPOX_DMA_TRANSFER_WIDTH_32BITS,
++ .transfer_mode_ = HIPOX_DMA_TRANSFER_MODE_BURST,
++ .address_mode_ = HIPOX_DMA_MODE_FIXED,
++ .address_really_fixed_ = 1
++};
++
++#ifdef CONFIG_HIPOX_VERSION_0X800
++/* For use with checksumming transfers as the settings for the source of the
++ * transfer */
++hipox_dma_device_settings_t hipox_ram_csum_src_dma_settings = {
++ .address_ = 0,
++ .fifo_size_ = 0,
++ .dreq_ = HIPOX_DMA_DREQ_MEMORY,
++ .read_eot_policy_ = HIPOX_DMA_EOT_FINAL, // To enable checksum accumulation
++ .write_eot_policy_ = HIPOX_DMA_EOT_NONE,
++ .bus_ = HIPOX_DMA_SIDE_A, // Checksumming happens on read from side A only
++ .width_ = HIPOX_DMA_TRANSFER_WIDTH_32BITS,
++ .transfer_mode_ = HIPOX_DMA_TRANSFER_MODE_BURST,
++ .address_mode_ = HIPOX_DMA_MODE_FIXED,
++ .address_really_fixed_ = 1
++};
++#endif // CONFIG_HIPOX_VERSION_0X800
++
++/* For use in all occasions not covered by hipox_ram_only_src_dma_settings and
++ * hipox_ram_csum_src_dma_settings */
++hipox_dma_device_settings_t hipox_ram_generic_dma_settings = {
++ .address_ = 0,
++ .fifo_size_ = 0,
++ .dreq_ = HIPOX_DMA_DREQ_MEMORY,
++ .read_eot_policy_ = HIPOX_DMA_EOT_NONE, // Don't interfere with any checksumming transfers
++ .write_eot_policy_ = HIPOX_DMA_EOT_NONE,
++ .bus_ = HIPOX_DMA_SIDE_B,
++ .width_ = HIPOX_DMA_TRANSFER_WIDTH_32BITS,
++ .transfer_mode_ = HIPOX_DMA_TRANSFER_MODE_BURST,
++ .address_mode_ = HIPOX_DMA_MODE_FIXED,
++ .address_really_fixed_ = 1
++};
++
++static hipox_dma_controller_t dma_controller;
++
++/**
++ * Acquisition of a SG DMA descriptor list entry
++ * If called from non-atomic context the call could block.
++ */
++static hipox_dma_sg_entry_t* alloc_sg_entry(int in_atomic)
++{
++ hipox_dma_sg_entry_t* entry = 0;
++ if (in_atomic) {
++ if (down_trylock(&dma_controller.sg_entry_sem_)) {
++ return (hipox_dma_sg_entry_t*)0;
++ }
++ } else {
++ // Wait for an entry to be available
++ while (down_interruptible(&dma_controller.sg_entry_sem_));
++ }
++
++ // Serialise while manipulating free list
++ spin_lock_bh(&dma_controller.alloc_spinlock_);
++
++ // It's an error if there isn't a buffer available at this point
++ BUG_ON(!dma_controller.sg_entry_head_);
++
++ // Unlink the head entry on the free list and return it to caller
++ entry = dma_controller.sg_entry_head_;
++ dma_controller.sg_entry_head_ = dma_controller.sg_entry_head_->next_;
++ --dma_controller.sg_entry_available_;
++
++ // Finished manipulating free list
++ spin_unlock_bh(&dma_controller.alloc_spinlock_);
++
++ return entry;
++}
++
++static void free_sg_entry(hipox_dma_sg_entry_t* entry)
++{
++ // Serialise while manipulating free list
++ spin_lock(&dma_controller.alloc_spinlock_);
++
++ // Insert the freed buffer at the head of the free list
++ entry->next_ = dma_controller.sg_entry_head_;
++ dma_controller.sg_entry_head_ = entry;
++ ++dma_controller.sg_entry_available_;
++
++ // Finished manipulating free list
++ spin_unlock(&dma_controller.alloc_spinlock_);
++
++ // Make freed buffer available for allocation
++ up(&dma_controller.sg_entry_sem_);
++}
++
++void hipox_dma_free_sg_entries(hipox_dma_sg_entry_t* entries)
++{
++ while (entries) {
++ hipox_dma_sg_entry_t* next = entries->next_;
++ free_sg_entry(entries);
++ entries = next;
++ }
++}
++
++/**
++ * This implementation is not the most efficient, as it could result in alot
++ * of alloc's only to decide to free them all as not sufficient available, but
++ * in practice we would hope there will not be much contention for entries
++ */
++int hipox_dma_alloc_sg_entries(
++ hipox_dma_sg_entry_t **entries,
++ unsigned required,
++ int in_atomic)
++{
++ if (likely(required)) {
++ hipox_dma_sg_entry_t* prev;
++ hipox_dma_sg_entry_t* entry;
++ unsigned acquired = 0;
++
++ *entries = alloc_sg_entry(in_atomic);
++ if (!*entries) {
++ return 1;
++ }
++
++ (*entries)->next_ = 0;
++ prev = *entries;
++
++ while (++acquired < required) {
++ entry = alloc_sg_entry(in_atomic);
++ if (!entry) {
++ // Did not acquire the entry
++ hipox_dma_free_sg_entries(*entries);
++ return 1;
++ }
++ entry->next_ = 0;
++ prev->next_ = entry;
++ prev = entry;
++ }
++ }
++
++ return 0;
++}
++
++#ifdef CONFIG_HIPOX_VERSION_0X800
++/**
++ * Blocking acquisition of the checksum engine
++ */
++static inline int alloc_csum_engine(int in_atomic)
++{
++#ifdef CONFIG_LEON_RESERVE_DMA_CHANNEL
++ // Checksum engine is allocated exclusively to the CoPro
++ return 1;
++#else
++ if (in_atomic) {
++ return down_trylock(&dma_controller.csum_engine_sem_);
++ } else {
++ while (1) {
++ if (!down_interruptible(&dma_controller.csum_engine_sem_)) {
++ return 0;
++ }
++ }
++ }
++#endif // CONFIG_LEON_RESERVE_DMA_CHANNEL
++}
++
++static inline void free_csum_engine(void)
++{
++ up(&dma_controller.csum_engine_sem_);
++}
++#endif // CONFIG_HIPOX_VERSION_0X800
++
++/**
++ * Optionally blocking acquisition of a DMA channel
++ * May be invoked either at task or softirq level
++ */
++hipox_dma_channel_t* hipox_dma_request(int block)
++{
++ hipox_dma_channel_t* channel = HIPOX_DMA_CHANNEL_NUL;
++ while (channel == HIPOX_DMA_CHANNEL_NUL) {
++ if (block) {
++ // Wait for a channel to be available
++ if (down_interruptible(&dma_controller.channel_sem_)) {
++ // Awoken by signal
++ continue;
++ }
++ } else {
++ // Non-blocking test of whether a channel is available
++ if (down_trylock(&dma_controller.channel_sem_)) {
++ // No channel available so return to user immediately
++ break;
++ }
++ }
++
++ // Serialise while manipulating free list
++ spin_lock_bh(&dma_controller.channel_alloc_spinlock_);
++
++ // It's an error if there isn't a channel available at this point
++ BUG_ON(!dma_controller.channel_head_);
++
++ // Unlink the head entry on the free list and return it to caller
++ channel = dma_controller.channel_head_;
++ dma_controller.channel_head_ = dma_controller.channel_head_->next_;
++
++ // Finished manipulating free list
++ spin_unlock_bh(&dma_controller.channel_alloc_spinlock_);
++ }
++ return channel;
++}
++
++/**
++ * May be invoked either at task or softirq level
++ */
++void hipox_dma_free(hipox_dma_channel_t* channel)
++{
++ if (hipox_dma_is_active(channel)) {
++ printk(KERN_WARNING "hipox_dma_free() Freeing channel %u while active\n", channel->channel_number_);
++ }
++
++ // Serialise while manipulating free list
++ spin_lock_bh(&dma_controller.channel_alloc_spinlock_);
++
++ // Insert the freed buffer at the head of the free list
++ channel->next_ = dma_controller.channel_head_;
++ dma_controller.channel_head_ = channel;
++
++ // Finished manipulating free list
++ spin_unlock_bh(&dma_controller.channel_alloc_spinlock_);
++
++ // Make freed buffer available for allocation
++ up(&dma_controller.channel_sem_);
++}
++
++/** Shared between all DMA interrupts and run with interrupts enabled, thus any
++ * access to shared data structures must be sync'ed
++ */
++static irqreturn_t hipox_dma_interrupt(int irq, void *dev_id)
++{
++ hipox_dma_channel_t *channel = 0;
++ unsigned channel_number = 0;
++ int need_bh = 0;
++
++DBG("hipox_dma_interrupt() from interrupt line %u\n", irq);
++
++ // Only acknowledge interrupts from the channel directly responsible for the
++ // RPS interrupt line which caused the ISR to be entered, to get around the
++ // problem that the SG-DMA controller can only filter DMA interrupts exter-
++ // nally to the DMA controller, i.e. the DMA controller interrupt status
++ // register always shows all active interrupts for all channels, regardless
++ // of whether the SG-DMA controller is filtering them
++
++ // Find the DMA channel that can generate interrupts on the RPS interrupt
++ // line which caused the ISR to be invoked.
++ if (likely(irq == DMA_INTERRUPT_4)) {
++ channel = &dma_controller.channels_[4];
++ } else {
++ channel = &dma_controller.channels_[irq - DMA_INTERRUPT_0];
++ }
++ channel_number = channel->channel_number_;
++DBG("RPS interrupt %u from channel %u\n", irq, channel_number);
++
++ // Non-SG transfers have no completion status, so initialise
++ // channel's error code to no-error. If transfer turns out to
++ // have been SG, this status will be overwritten
++ channel->error_code_ = HIPOX_DMA_ERROR_CODE_NONE;
++
++ // Must finish in bottom half if checksumming or need to invoke callback
++#ifdef CONFIG_HIPOX_VERSION_0X800
++ need_bh = channel->checksumming_ ||
++#else // CONFIG_HIPOX_VERSION_0X800
++ need_bh =
++#endif // CONFIG_HIPOX_VERSION_0X800
++ (channel->notification_callback_ != HIPOX_DMA_CALLBACK_NUL);
++
++ // Cope with the DMA controller's ability to have a pair of chained
++ // transfers which have both completed, which causes the interrupt request
++ // to stay active until both have been acknowledged, which is causing the SG
++ // controller problems
++ while (readl(DMA_CALC_REG_ADR(0, DMA_INTR_ID)) & (1 << channel_number)) {
++DBG("Ack'ing interrupt for channel %u\n", channel_number);
++ // Write to the interrupt clear register to clear interrupt
++ writel(0, DMA_CALC_REG_ADR(channel_number, DMA_INTR_CLEAR_REG));
++
++ // Record how many interrupts are awaiting service
++ atomic_inc(&channel->interrupt_count_);
++ }
++DBG("Left int ack'ing loop\n");
++
++ // If was a SG transfer, record the completion status
++ if (channel->v_sg_info_->v_srcEntries_) {
++ // Record the SG transfer completion status
++ u32 error_code = readl(DMA_SG_CALC_REG_ADR(channel_number, DMA_SG_STATUS));
++ channel->error_code_ =
++ ((error_code >> DMA_SG_STATUS_ERROR_CODE_BIT) &
++ ((1UL << DMA_SG_STATUS_ERROR_CODE_NUM_BITS) - 1));
++
++ if (channel->auto_sg_entries_) {
++ // Must finish in bottom half if we are to manage the SG entries
++DBG("ISR channel %d is auto SG\n", channel->channel_number_);
++ need_bh = 1;
++ } else {
++DBG("ISR channel %d not auto SG\n", channel->channel_number_);
++ // Zeroise SG DMA descriptor info
++ channel->v_sg_info_->p_srcEntries_ = 0;
++ channel->v_sg_info_->v_srcEntries_ = 0;
++ channel->v_sg_info_->p_dstEntries_ = 0;
++ channel->v_sg_info_->v_dstEntries_ = 0;
++ }
++
++DBG("Return SG controller to idle, error_code = 0x%08x\n", error_code);
++ // Return the SG DMA controller to the IDLE state and clear any SG
++ // controller error interrupt
++ writel(1, DMA_SG_CALC_REG_ADR(channel_number, DMA_SG_STATUS));
++ }
++
++ // Can we finish w/o invoking bottom half?
++ if (likely(!need_bh)) {
++DBG("ISR channel %d do not call bh\n", channel->channel_number_);
++ atomic_set(&channel->interrupt_count_, 0);
++ atomic_set(&channel->active_count_, 0);
++ } else {
++DBG("Marking channel %d as requiring its bottom half to run\n", channel_number);
++ // Set a flag for the channel to cause its bottom half to be run
++ set_bit(channel_number, (void*)&dma_controller.run_bh_);
++
++DBG("Scheduling tasklet\n");
++ // Signal the bottom half to perform the notifications
++ tasklet_schedule(&dma_controller.tasklet_);
++ }
++
++DBG("Returning\n");
++ return IRQ_HANDLED;
++}
++
++static void fake_interrupt(int channel)
++{
++ // Set a flag to cause the bottom half handler to be run for the channel
++ set_bit(channel, (void*)&dma_controller.run_bh_);
++
++ // Signal the bottom half to perform the notifications
++ tasklet_schedule(&dma_controller.tasklet_);
++}
++
++static void dma_bh(unsigned long data)
++{
++ // Check for any bottom halves having become ready to run
++ u32 run_bh = atomic_read(&dma_controller.run_bh_);
++ while (run_bh) {
++ unsigned i;
++
++ // Free any checksumming or SG resources
++ u32 temp_run_bh = run_bh;
++ for (i = 0; i < dma_controller.numberOfChannels_; i++, temp_run_bh >>= 1) {
++ if (temp_run_bh & 1) {
++ hipox_dma_channel_t* channel = &dma_controller.channels_[i];
++DBG("Bottom halve for channel %u\n", channel->channel_number_);
++#ifdef CONFIG_HIPOX_VERSION_0X800
++ // If this channel computed a checksum
++ if (unlikely(channel->checksumming_)) {
++ // Read the result of the checksum calculation, clearing the
++ // result in the process
++ channel->checksum_ = readl(DMA_CHECKSUM_BASE);
++ channel->checksumming_ = 0;
++
++ // Relinquish ownership of the checksum engine
++ free_csum_engine();
++ }
++#endif // CONFIG_HIPOX_VERSION_0X800
++
++ if (channel->auto_sg_entries_) {
++ // Free SG DMA source descriptor resources
++ hipox_dma_sg_entry_t* sg_entry = channel->v_sg_info_->v_srcEntries_;
++DBG("Freeing SG resources for channel %d\n", channel->channel_number_);
++ while (sg_entry) {
++ hipox_dma_sg_entry_t* next = sg_entry->v_next_;
++ free_sg_entry(sg_entry);
++ sg_entry = next;
++ }
++
++ // Free SG DMA destination descriptor resources
++ sg_entry = channel->v_sg_info_->v_dstEntries_;
++ while (sg_entry) {
++ hipox_dma_sg_entry_t* next = sg_entry->v_next_;
++ free_sg_entry(sg_entry);
++ sg_entry = next;
++ }
++
++ // Zeroise SG DMA source descriptor info
++ channel->v_sg_info_->p_srcEntries_ = 0;
++ channel->v_sg_info_->v_srcEntries_ = 0;
++ channel->v_sg_info_->p_dstEntries_ = 0;
++ channel->v_sg_info_->v_dstEntries_ = 0;
++ }
++ }
++ }
++
++ // Mark that we have serviced the bottom halves. None of the channels
++ // we have just serviced can interrupt again until their active flags
++ // are cleared below
++ atomic_sub(run_bh, &dma_controller.run_bh_);
++
++ // Notify all listeners of transfer completion
++ for (i = 0; i < dma_controller.numberOfChannels_; i++, run_bh >>= 1) {
++ if (run_bh & 1) {
++ int interrupt_count;
++ hipox_dma_channel_t* channel = &dma_controller.channels_[i];
++
++ // Clear the count of received interrupts for the channel now
++ // that we have serviced them all
++ interrupt_count = atomic_read(&channel->interrupt_count_);
++ atomic_sub(interrupt_count, &channel->interrupt_count_);
++
++ // Decrement the count of active transfers, by the number of
++ // interrupts we've seen. This must occur before we inform any
++ // listeners who are awaiting completion notification. Should
++ // only decrement if greater than zero, in case we see spurious
++ // interrupt events - we can't be fully safe against this sort
++ // of broken h/w, but we can at least stop the count underflowing
++ // active_count_ is only shared with thread level code, so read
++ // and decrement don't need to be atomic
++ if (atomic_read(&channel->active_count_)) {
++ atomic_dec(&channel->active_count_);
++ }
++
++ // If there is a callback registered, notify the user that the
++ // transfer is complete
++ if (channel->notification_callback_ != HIPOX_DMA_CALLBACK_NUL) {
++DBG("Notifying channel %u, %d outstanding interrupts\n", channel->channel_number_, interrupt_count);
++ (*channel->notification_callback_)(
++ &dma_controller.channels_[i],
++ channel->notification_arg_,
++ channel->error_code_,
++#ifdef CONFIG_HIPOX_VERSION_0X800
++ channel->checksum_,
++#else // CONFIG_HIPOX_VERSION_0X800
++ 0,
++#endif // CONFIG_HIPOX_VERSION_0X800
++ interrupt_count);
++ }
++ }
++ }
++
++ // Check for any more bottom halves having become ready to run
++ run_bh = atomic_read(&dma_controller.run_bh_);
++ }
++}
++
++void __init hipox_dma_init()
++{
++ unsigned i;
++ unsigned long intId;
++ hipox_dma_sg_info_t *v_info;
++ dma_addr_t p_info;
++
++ // Ensure the DMA block is properly reset
++ writel(1UL << SYS_CTRL_RSTEN_DMA_BIT, SYS_CTRL_RSTEN_SET_CTRL);
++ writel(1UL << SYS_CTRL_RSTEN_DMA_BIT, SYS_CTRL_RSTEN_CLR_CTRL);
++
++ // Ensure the SG-DMA block is properly reset
++ writel(1UL << SYS_CTRL_RSTEN_SGDMA_BIT, SYS_CTRL_RSTEN_SET_CTRL);
++ writel(1UL << SYS_CTRL_RSTEN_SGDMA_BIT, SYS_CTRL_RSTEN_CLR_CTRL);
++
++ // Enable the clock to the DMA block
++ writel(1UL << SYS_CTRL_CKEN_DMA_BIT, SYS_CTRL_CKEN_SET_CTRL);
++
++ // Initialise the DMA controller
++ atomic_set(&dma_controller.run_bh_, 0);
++ spin_lock_init(&dma_controller.spinlock_);
++ spin_lock_init(&dma_controller.alloc_spinlock_);
++ spin_lock_init(&dma_controller.channel_alloc_spinlock_);
++ sema_init(&dma_controller.csum_engine_sem_, 1);
++
++ // Initialise channel allocation management
++ dma_controller.channel_head_ = 0;
++ sema_init(&dma_controller.channel_sem_, 0);
++ // Initialise SRAM buffer management
++ dma_controller.sg_entry_head_ = 0;
++ sema_init(&dma_controller.sg_entry_sem_, 0);
++ dma_controller.sg_entry_available_ = 0;
++
++ tasklet_init(&dma_controller.tasklet_, dma_bh, 0);
++
++ // Discover the number of channels available
++ intId = readl(DMA_CALC_REG_ADR(0, DMA_INTR_ID));
++ dma_controller.numberOfChannels_ = DMA_INTR_ID_GET_NUM_CHANNELS(intId);
++ if (dma_controller.numberOfChannels_ > MAX_HIPOX_DMA_CHANNELS) {
++ printk(KERN_WARNING "DMA: Too many DMA channels");
++ dma_controller.numberOfChannels_ = MAX_HIPOX_DMA_CHANNELS;
++ }
++
++ dma_controller.version_ = DMA_INTR_ID_GET_VERSION(intId);
++ printk(KERN_INFO "Number of DMA channels = %u, version = %u\n",
++ dma_controller.numberOfChannels_, dma_controller.version_);
++
++ if (!DMA_HAS_V4_INTR_CLEAR(dma_controller.version_)) {
++ panic("DMA: Trying to use v4+ interrupt clearing on DMAC version without support\n");
++ }
++
++#ifdef CONFIG_LEON_RESERVE_DMA_CHANNEL
++ // Reserve the last DMA channel for the CoPro's use
++ --dma_controller.numberOfChannels_;
++#endif // CONFIG_LEON_RESERVE_DMA_CHANNEL
++
++ // Allocate coherent memory for array sg_info structs
++ dma_controller.v_sg_infos_ = (hipox_dma_sg_info_t*)DMA_DESC_ALLOC_START;
++ dma_controller.p_sg_infos_ = DMA_DESC_ALLOC_START_PA;
++
++ if (!dma_controller.v_sg_infos_) {
++ panic("DMA: Coherent alloc of SG info struct array");
++ }
++
++ {
++ // Initialise list of DMA descriptors
++ unsigned long sg_info_alloc_size = (dma_controller.numberOfChannels_ * sizeof(hipox_dma_sg_info_t));
++ unsigned num_sg_entries = (DMA_DESC_ALLOC_SIZE - sg_info_alloc_size) / sizeof(hipox_dma_sg_entry_t);
++ hipox_dma_sg_entry_t* entry_v = (hipox_dma_sg_entry_t*)(DMA_DESC_ALLOC_START + sg_info_alloc_size);
++ hipox_dma_sg_entry_t* entry_p = (hipox_dma_sg_entry_t*)(DMA_DESC_ALLOC_START_PA + sg_info_alloc_size);
++printk("Allocating %u SRAM generic DMA descriptors\n", num_sg_entries);
++ for (i=0; i < num_sg_entries; ++i, ++entry_v, ++entry_p) {
++ entry_v->paddr_ = (dma_addr_t)entry_p;
++ free_sg_entry(entry_v);
++ }
++ }
++
++ // Initialise all available DMA channels
++ v_info = dma_controller.v_sg_infos_;
++ p_info = dma_controller.p_sg_infos_;
++ for (i=0; i < dma_controller.numberOfChannels_; i++) {
++ hipox_dma_channel_t *channel = &dma_controller.channels_[i];
++
++ channel->channel_number_ = i;
++ channel->notification_callback_ = HIPOX_DMA_CALLBACK_NUL;
++ channel->notification_arg_ = HIPOX_DMA_CALLBACK_ARG_NUL;
++
++ // Setup physical and virtual addresses of the SG info struct for this
++ // channel
++ channel->v_sg_info_ = v_info++;
++ channel->p_sg_info_ = p_info;
++ p_info += sizeof(hipox_dma_sg_info_t);
++
++ // Initialise heads of src and dst SG lists to null
++ channel->v_sg_info_->p_srcEntries_ = 0;
++ channel->v_sg_info_->p_dstEntries_ = 0;
++ channel->v_sg_info_->v_srcEntries_ = 0;
++ channel->v_sg_info_->v_dstEntries_ = 0;
++
++ channel->error_code_ = 0;
++#ifdef CONFIG_HIPOX_VERSION_0X800
++ channel->checksumming_ = 0;
++ channel->checksum_ = 0;
++#endif // CONFIG_HIPOX_VERSION_0X800
++
++ // Initialise the atomic variable that records the number of interrupts
++ // for the channel that are awaiting service
++ atomic_set(&channel->interrupt_count_, 0);
++
++ // Initialise the atomic variable maintaining the count of in-progress
++ // transfers for the channel. Currently can be a maximum of two, as
++ // the hardware can only queue details for a pair of transfers
++ atomic_set(&channel->active_count_, 0);
++
++ // The binary semaphore for the default callback used when abort
++ // requested without a user-registered callback being available
++ sema_init(&channel->default_semaphore_, 0);
++
++ // Add channel to free list
++ hipox_dma_free(channel);
++ }
++
++ // Connect the dma interrupt handler
++ dma_controller.channels_[0].rps_interrupt_ = DMA_INTERRUPT_0;
++ if (request_irq(DMA_INTERRUPT_0, &hipox_dma_interrupt, 0, "DMA 0", 0)) {
++ panic("DMA: Failed to allocate interrupt %u\n", DMA_INTERRUPT_0);
++ }
++ dma_controller.channels_[1].rps_interrupt_ = DMA_INTERRUPT_1;
++ if (request_irq(DMA_INTERRUPT_1, &hipox_dma_interrupt, 0, "DMA 1", 0)) {
++ panic("DMA: Failed to allocate interrupt %u\n", DMA_INTERRUPT_1);
++ }
++ dma_controller.channels_[2].rps_interrupt_ = DMA_INTERRUPT_2;
++ if (request_irq(DMA_INTERRUPT_2, &hipox_dma_interrupt, 0, "DMA 2", 0)) {
++ panic("DMA: Failed to allocate interrupt %u\n", DMA_INTERRUPT_2);
++ }
++ dma_controller.channels_[3].rps_interrupt_ = DMA_INTERRUPT_3;
++ if (request_irq(DMA_INTERRUPT_3, &hipox_dma_interrupt, 0, "DMA 3", 0)) {
++ panic("DMA: Failed to allocate interrupt %u\n", DMA_INTERRUPT_3);
++ }
++#ifndef CONFIG_LEON_RESERVE_DMA_CHANNEL
++ dma_controller.channels_[4].rps_interrupt_ = DMA_INTERRUPT_4;
++ if (request_irq(DMA_INTERRUPT_4, &hipox_dma_interrupt, 0, "DMA 4", 0)) {
++ panic("DMA: Failed to allocate interrupt %u\n", DMA_INTERRUPT_4);
++ }
++#endif // CONFIG_LEON_RESERVE_DMA_CHANNEL
++
++#ifdef HIPOX_DMA_OVERALL_TEST_LOOPS
++ {
++ int j;
++ for (j=0; j < HIPOX_DMA_OVERALL_TEST_LOOPS; ++j) {
++#ifdef HIPOX_DMA_TEST
++ {
++ int i;
++ for (i=0; i < HIPOX_DMA_TEST_ITERATIONS; ++i) {
++ dma_test(512);
++ }
++ }
++#endif // HIPOX_DMA_TEST
++#ifdef HIPOX_DMA_SG_TEST
++ {
++ int i;
++ for (i=0; i < HIPOX_DMA_SG_TEST_ITERATIONS; ++i) {
++ dma_sg_test();
++ }
++ }
++#endif // HIPOX_DMA_SG_TEST
++#ifdef HIPOX_DMA_SG_TEST_2
++ {
++ int i;
++ for (i=0; i < HIPOX_DMA_SG_TEST_ITERATIONS; ++i) {
++ dma_sg_test2();
++ }
++ }
++#endif // HIPOX_DMA_SG_TEST_2
++#ifdef HIPOX_DMA_TEST
++ {
++ int i;
++ for (i=0; i < HIPOX_DMA_TEST_AFTER_SG_ITERATIONS; ++i) {
++ dma_test(512);
++ }
++ }
++#endif // HIPOX_DMA_TEST
++ }
++ }
++#endif // HIPOX_DMA_OVERALL_TEST_LOOPS
++}
++
++void hipox_dma_shutdown()
++{
++ dma_controller.sg_entry_head_ = 0;
++}
++
++int hipox_dma_is_active(hipox_dma_channel_t* channel)
++{
++ return atomic_read(&channel->active_count_);
++}
++
++/**
++ * Get the transfer status directly from the hardware, so for instance the
++ * end of a transfer can be polled for within interrupt context.
++ *
++ * NB If this function indicates the channel is inactive, it does NOT imply that
++ * it can be reused. Reuse is only possible when hipox_dma_is_active() returns
++ * the inactive state
++ */
++int hipox_dma_raw_isactive(hipox_dma_channel_t* channel)
++{
++ unsigned long ctrl_status = readl(DMA_CALC_REG_ADR(channel->channel_number_, DMA_CTRL_STATUS));
++ return ctrl_status & DMA_CTRL_STATUS_IN_PROGRESS;
++}
++
++/**
++ * Get the SG transfer status directly from the hardware, so for instance the
++ * end of a SG transfer can be polled for within interrupt context.
++ *
++ * NB If this function indicates the channel is inactive, it does NOT imply that
++ * it can be reused. Reuse is only possible when hipox_dma_is_active() returns
++ * the inactive state
++ */
++int hipox_dma_raw_sg_isactive(hipox_dma_channel_t* channel)
++{
++ // Record the SG channel status
++ u32 status = readl(DMA_SG_CALC_REG_ADR(channel->channel_number_, DMA_SG_STATUS));
++ return status & (1UL << DMA_SG_STATUS_BUSY_BIT);
++}
++
++int hipox_dma_get_raw_direction(hipox_dma_channel_t* channel)
++{
++ unsigned long ctrl_status = readl(DMA_CALC_REG_ADR(channel->channel_number_, DMA_CTRL_STATUS));
++ return (ctrl_status & DMA_CTRL_STATUS_DIR_MASK) >> DMA_CTRL_STATUS_DIR_SHIFT;
++}
++
++static unsigned long encode_control_status(
++ hipox_dma_device_settings_t *src_settings,
++ hipox_dma_device_settings_t *dst_settings,
++ int paused)
++{
++ unsigned long ctrl_status;
++ hipox_dma_transfer_direction_t direction;
++
++ ctrl_status = paused ? DMA_CTRL_STATUS_PAUSE : 0; // Paused if requested
++ ctrl_status |= (DMA_CTRL_STATUS_INTERRUPT_ENABLE | // Interrupts enabled
++ DMA_CTRL_STATUS_FAIR_SHARE_ARB | // High priority
++ DMA_CTRL_STATUS_INTR_CLEAR_ENABLE); // Use new interrupt clearing register
++ ctrl_status |= (src_settings->dreq_ << DMA_CTRL_STATUS_SRC_DREQ_SHIFT); // Source dreq
++ ctrl_status |= (dst_settings->dreq_ << DMA_CTRL_STATUS_DEST_DREQ_SHIFT); // Destination dreq
++
++ // Setup the transfer direction and burst/single mode for the two DMA busses
++ if (src_settings->bus_ == HIPOX_DMA_SIDE_A) {
++ // Set the burst/single mode for bus A based on src device's settings
++ if (src_settings->transfer_mode_ == HIPOX_DMA_TRANSFER_MODE_BURST) {
++ ctrl_status |= DMA_CTRL_STATUS_TRANSFER_MODE_A;
++ } else {
++ ctrl_status &= ~DMA_CTRL_STATUS_TRANSFER_MODE_A;
++ }
++
++ if (dst_settings->bus_ == HIPOX_DMA_SIDE_A) {
++ direction = HIPOX_DMA_A_TO_A;
++ } else {
++ direction = HIPOX_DMA_A_TO_B;
++
++ // Set the burst/single mode for bus B based on dst device's settings
++ if (dst_settings->transfer_mode_ == HIPOX_DMA_TRANSFER_MODE_BURST) {
++ ctrl_status |= DMA_CTRL_STATUS_TRANSFER_MODE_B;
++ } else {
++ ctrl_status &= ~DMA_CTRL_STATUS_TRANSFER_MODE_B;
++ }
++ }
++ } else {
++ // Set the burst/single mode for bus B based on src device's settings
++ if (src_settings->transfer_mode_ == HIPOX_DMA_TRANSFER_MODE_BURST) {
++ ctrl_status |= DMA_CTRL_STATUS_TRANSFER_MODE_B;
++ } else {
++ ctrl_status &= ~DMA_CTRL_STATUS_TRANSFER_MODE_B;
++ }
++
++ if (dst_settings->bus_ == HIPOX_DMA_SIDE_A) {
++ direction = HIPOX_DMA_B_TO_A;
++
++ // Set the burst/single mode for bus A based on dst device's settings
++ if (dst_settings->transfer_mode_ == HIPOX_DMA_TRANSFER_MODE_BURST) {
++ ctrl_status |= DMA_CTRL_STATUS_TRANSFER_MODE_A;
++ } else {
++ ctrl_status &= ~DMA_CTRL_STATUS_TRANSFER_MODE_A;
++ }
++ } else {
++ direction = HIPOX_DMA_B_TO_B;
++ }
++ }
++ ctrl_status |= (direction << DMA_CTRL_STATUS_DIR_SHIFT);
++
++ // Setup source address mode fixed or increment
++ if (src_settings->address_mode_ == HIPOX_DMA_MODE_FIXED) {
++ // Fixed address
++ ctrl_status &= ~(DMA_CTRL_STATUS_SRC_ADR_MODE);
++
++ // Set up whether fixed address is _really_ fixed
++ if (src_settings->address_really_fixed_) {
++ ctrl_status |= DMA_CTRL_STATUS_SOURCE_ADDRESS_FIXED;
++ } else {
++ ctrl_status &= ~DMA_CTRL_STATUS_SOURCE_ADDRESS_FIXED;
++ }
++ } else {
++ // Incrementing address
++ ctrl_status |= DMA_CTRL_STATUS_SRC_ADR_MODE;
++ ctrl_status &= ~DMA_CTRL_STATUS_SOURCE_ADDRESS_FIXED;
++ }
++
++ // Setup destination address mode fixed or increment
++ if (dst_settings->address_mode_ == HIPOX_DMA_MODE_FIXED) {
++ // Fixed address
++ ctrl_status &= ~(DMA_CTRL_STATUS_DEST_ADR_MODE);
++
++ // Set up whether fixed address is _really_ fixed
++ if (dst_settings->address_really_fixed_) {
++ ctrl_status |= DMA_CTRL_STATUS_DESTINATION_ADDRESS_FIXED;
++ } else {
++ ctrl_status &= ~DMA_CTRL_STATUS_DESTINATION_ADDRESS_FIXED;
++ }
++ } else {
++ // Incrementing address
++ ctrl_status |= DMA_CTRL_STATUS_DEST_ADR_MODE;
++ ctrl_status &= ~DMA_CTRL_STATUS_DESTINATION_ADDRESS_FIXED;
++ }
++
++ // Set up the width of the transfers on the DMA buses
++ ctrl_status |= (src_settings->width_ << DMA_CTRL_STATUS_SRC_WIDTH_SHIFT);
++ ctrl_status |= (dst_settings->width_ << DMA_CTRL_STATUS_DEST_WIDTH_SHIFT);
++
++ // Setup the priority arbitration scheme
++ ctrl_status &= ~DMA_CTRL_STATUS_STARVE_LOW_PRIORITY; // !Starve low priority
++
++ return ctrl_status;
++}
++
++static unsigned long encode_eot(
++ hipox_dma_device_settings_t* src_settings,
++ hipox_dma_device_settings_t* dst_settings,
++ unsigned long length,
++ int isFinalTransfer)
++{
++ // Write the length, with EOT configuration and enable INC4 tranfers and
++ // HPROT. HPROT will delay data reaching memory for a few clock cycles, but
++ // most unlikely to cause a problem for the CPU.
++ unsigned long encoded = length |
++ DMA_BYTE_CNT_INC4_SET_MASK | // Always enable INC4 transfers
++ DMA_BYTE_CNT_HPROT_MASK; // Always enable HPROT assertion
++
++ // Encode the EOT setting for the src device based on its policy
++ encoded &= ~DMA_BYTE_CNT_RD_EOT_MASK;
++ switch (src_settings->read_eot_policy_) {
++ case HIPOX_DMA_EOT_FINAL:
++ if (!isFinalTransfer) {
++ break;
++ }
++ // Fall through in case of final transfer and EOT required for final
++ // transfer
++ case HIPOX_DMA_EOT_ALL:
++ encoded |= DMA_BYTE_CNT_RD_EOT_MASK;
++ break;
++ default:
++ break;
++ }
++
++ // Encode the EOT setting for the dst device based on its policy
++ encoded &= ~DMA_BYTE_CNT_WR_EOT_MASK;
++ switch (dst_settings->write_eot_policy_) {
++ case HIPOX_DMA_EOT_FINAL:
++ if (!isFinalTransfer) {
++ break;
++ }
++ // Fall through in case of final transfer and EOT required for final
++ // transfer
++ case HIPOX_DMA_EOT_ALL:
++ encoded |= DMA_BYTE_CNT_WR_EOT_MASK;
++ break;
++ default:
++ break;
++ }
++
++ return encoded;
++}
++
++static unsigned long encode_start(unsigned long ctrl_status)
++{
++ ctrl_status &= ~DMA_CTRL_STATUS_PAUSE;
++ return ctrl_status;
++}
++
++static void hipox_dma_set_common_lowlevel(
++ hipox_dma_channel_t *channel,
++ unsigned long ctrl_status,
++ dma_addr_t src_address,
++ dma_addr_t dst_address,
++ unsigned long lengthAndEOT)
++{
++ unsigned channel_number = channel->channel_number_;
++
++ spin_lock(&dma_controller.spinlock_);
++
++ // Write the control/status value to the DMAC
++ writel(ctrl_status, DMA_CALC_REG_ADR(channel_number, DMA_CTRL_STATUS));
++
++ // Ensure control/status word makes it to the DMAC before we write address/length info
++ wmb();
++
++ // Write the source addresses to the DMAC
++ writel(src_address, DMA_CALC_REG_ADR(channel_number, DMA_BASE_SRC_ADR));
++
++ // Write the destination addresses to the DMAC
++ writel(dst_address, DMA_CALC_REG_ADR(channel_number, DMA_BASE_DST_ADR));
++
++ // Write the length, with EOT configuration for the single transfer
++ writel(lengthAndEOT, DMA_CALC_REG_ADR(channel_number, DMA_BYTE_CNT));
++
++ // Ensure adr/len info makes it to DMAC before later modifications to
++ // control/status register due to starting the transfer, which happens in
++ // hipox_dma_start()
++ wmb();
++
++ spin_unlock(&dma_controller.spinlock_);
++
++ // Increase count of in-progress transfers on this channel
++ atomic_inc(&channel->active_count_);
++}
++
++static int hipox_dma_set_common(
++ hipox_dma_channel_t* channel,
++ unsigned long length,
++ hipox_dma_device_settings_t *src_settings,
++ hipox_dma_device_settings_t *dst_settings,
++ int isFinalTransfer,
++ int paused)
++{
++ int status = 0;
++
++ if (length > MAX_HIPOX_DMA_TRANSFER_LENGTH) {
++ printk(KERN_WARNING "hipox_dma_set_common() length exceeds hardware allowed maximum\n");
++ status = 1;
++ } else {
++ hipox_dma_set_common_lowlevel(
++ channel,
++ encode_control_status(src_settings, dst_settings, paused),
++ (dma_addr_t)src_settings->address_,
++ (dma_addr_t)dst_settings->address_,
++ encode_eot(src_settings, dst_settings, length, isFinalTransfer));
++ }
++ return status;
++}
++
++int hipox_dma_set(
++ hipox_dma_channel_t *channel,
++ unsigned char *src_adr, // Physical address
++ unsigned long length,
++ unsigned char *dst_adr, // Physical address
++ hipox_dma_mode_t src_mode,
++ hipox_dma_mode_t dst_mode,
++ int do_checksum,
++ int paused)
++{
++ if (hipox_dma_is_active(channel)) {
++ printk(KERN_WARNING "hipox_dma_set() Trying to use channel %u while active\n", channel->channel_number_);
++ }
++
++#ifdef CONFIG_HIPOX_VERSION_0X800
++ if (do_checksum) {
++ // Arbitrate for ownership of the checksum engine
++ if (alloc_csum_engine()) {
++ // Did not obtain the csum engine, so return will failure status
++ return 1;
++ }
++ }
++#else // CONFIG_HIPOX_VERSION_0X800
++ BUG_ON(do_checksum);
++#endif // CONFIG_HIPOX_VERSION_0X800
++
++ {
++ // Assemble complete memory settings, accounting for csum generation if
++ // required
++#ifdef CONFIG_HIPOX_VERSION_0X800
++ hipox_dma_device_settings_t src_settings =
++ do_checksum ? hipox_ram_csum_src_dma_settings :
++ hipox_ram_only_src_dma_settings;
++#else // CONFIG_HIPOX_VERSION_0X800
++ hipox_dma_device_settings_t src_settings = hipox_ram_only_src_dma_settings;
++#endif // CONFIG_HIPOX_VERSION_0X800
++
++ hipox_dma_device_settings_t dst_settings = hipox_ram_generic_dma_settings;
++
++ // Assemble the source address
++ src_settings.address_ = (unsigned long)src_adr;
++#ifdef CONFIG_HIPOX_VERSION_0X800
++ if (do_checksum) {
++ // Record that we are checksumming, so that the result is read on
++ // completion
++ channel->checksumming_ = 1;
++
++ // To checksum set the high order address bit to enable the engine
++ src_settings.address_ |= (1UL << HIPOX_DMA_CSUM_ENABLE_ADR_BIT);
++ }
++#endif // CONFIG_HIPOX_VERSION_0X800
++
++ // Ensure only use the valid src address bits are used
++ src_settings.address_ &= HIPOX_DMA_CSUM_ADR_MASK;
++ src_settings.address_mode_ = src_mode;
++
++ // Ensure only use the valid dst address bits are used
++ dst_settings.address_ = ((unsigned long)dst_adr) & HIPOX_DMA_ADR_MASK;
++ dst_settings.address_mode_ = dst_mode;
++
++ return hipox_dma_set_common(channel, length, &src_settings, &dst_settings, 1, paused);
++ }
++}
++
++int hipox_dma_device_set(
++ hipox_dma_channel_t *channel,
++ hipox_dma_direction_t direction,
++ unsigned char *mem_adr, // Physical address
++ unsigned long length,
++ hipox_dma_device_settings_t *device_settings,
++ hipox_dma_mode_t mem_mode,
++ int paused)
++{
++ hipox_dma_device_settings_t mem_settings;
++
++ if (hipox_dma_is_active(channel)) {
++ printk(KERN_WARNING "hipox_dma_device_set() Trying to use channel %u while active\n", channel->channel_number_);
++ }
++
++ // Assemble complete memory settings, ensuring addresses do not affect the
++ // checksum enabling high order adr bit
++ mem_settings = hipox_ram_generic_dma_settings;
++ mem_settings.address_ = ((unsigned long)mem_adr) & HIPOX_DMA_ADR_MASK;
++ mem_settings.address_mode_ = mem_mode;
++
++ device_settings->address_ &= HIPOX_DMA_ADR_MASK;
++
++ return hipox_dma_set_common(
++ channel,
++ length,
++ (direction == HIPOX_DMA_TO_DEVICE) ? &mem_settings : device_settings,
++ (direction == HIPOX_DMA_FROM_DEVICE) ? &mem_settings : device_settings,
++ 1,
++ paused);
++}
++
++int hipox_dma_device_pair_set(
++ hipox_dma_channel_t* channel,
++ unsigned long length,
++ hipox_dma_device_settings_t *src_device_settings,
++ hipox_dma_device_settings_t *dst_device_settings,
++ int paused)
++{
++ if (hipox_dma_is_active(channel)) {
++ printk(KERN_WARNING "hipox_dma_device_pair_set() Trying to use channel %u while active\n", channel->channel_number_);
++ }
++
++ // Ensure addresses do not affect the checksum enabling high order adr bit
++ src_device_settings->address_ &= HIPOX_DMA_ADR_MASK;
++ dst_device_settings->address_ &= HIPOX_DMA_ADR_MASK;
++ return hipox_dma_set_common(channel, length, src_device_settings, dst_device_settings, 1, paused);
++}
++
++static int hipox_dma_set_sg_common(
++ hipox_dma_channel_t* channel,
++ struct scatterlist* src_sg,
++ unsigned src_sg_count,
++ struct scatterlist* dst_sg,
++ unsigned dst_sg_count,
++ hipox_dma_device_settings_t* src_settings,
++ hipox_dma_device_settings_t* dst_settings,
++ int in_atomic)
++{
++ int i;
++ int failed = 0;
++ hipox_dma_sg_entry_t *sg_entry;
++ hipox_dma_sg_entry_t *previous_entry;
++
++ // Get reference to this channel's top level SG DMA descriptor structure
++ hipox_dma_sg_info_t *sg_info = channel->v_sg_info_;
++
++ // SG entries have not been provided
++ channel->auto_sg_entries_ = 1;
++
++ // Initialise list pointers to zero
++ sg_info->v_srcEntries_ = 0;
++ sg_info->p_srcEntries_ = 0;
++ sg_info->v_dstEntries_ = 0;
++ sg_info->p_dstEntries_ = 0;
++
++ sg_entry = 0;
++ previous_entry = 0;
++ for (i=0; i < src_sg_count; i++) {
++ // Is this entry contiguous with the previous one and would the combined
++ // lengths not exceed the maximum that the hardware is capable of
++#if 0
++ if (previous_entry &&
++ ((previous_entry->addr_ + previous_entry->length_) == (src_sg[i].dma_address & HIPOX_DMA_CSUM_ADR_MASK)) &&
++ ((previous_entry->length_ + src_sg[i].length) <= MAX_HIPOX_DMA_TRANSFER_LENGTH)) {
++ // Yes, so coalesce the pair
++ previous_entry->length_ += src_sg[i].length;
++ } else
++#endif
++ {
++ // Allocate space for SG list entry from coherent DMA pool
++ hipox_dma_sg_entry_t *new_sg_entry = alloc_sg_entry(in_atomic);
++ if (!new_sg_entry) {
++ failed = 1;
++ break;
++ }
++ sg_entry = new_sg_entry;
++
++ if (previous_entry) {
++ // Link the previous SG list entry forward to this one
++ previous_entry->v_next_ = sg_entry;
++ previous_entry->p_next_ = sg_entry->paddr_;
++ } else {
++ // Create a link from the SG info structure to the first SG list entry
++ sg_info->v_srcEntries_ = sg_entry;
++ sg_info->p_srcEntries_ = sg_entry->paddr_;
++ }
++ previous_entry = sg_entry;
++
++ // Fill in the SG list entry with start address, ensuring only valid
++ // address bits are used, preserving the checksum enabling flag
++ sg_entry->addr_ = src_sg[i].dma_address & HIPOX_DMA_CSUM_ADR_MASK;
++
++ // Fill in the length, checking that it does not exceed the hardware
++ // allowed maximum
++ sg_entry->length_ = (src_sg[i].length <= MAX_HIPOX_DMA_TRANSFER_LENGTH) ? src_sg[i].length : 0;
++ if (!sg_entry->length_) {
++ printk(KERN_WARNING "hipox_dma_set_sg_common() Source entry too long, zeroing\n");
++ }
++ }
++ }
++ if (sg_entry) {
++ // Mark the end of the source SG list with nulls
++ sg_entry->p_next_ = 0;
++ sg_entry->v_next_ = 0;
++ }
++
++ if (failed) {
++ // Failed to allocate all SG src entries, so free those we did get
++ hipox_dma_sg_entry_t* sg_entry = sg_info->v_srcEntries_;
++ while (sg_entry) {
++ hipox_dma_sg_entry_t* next = sg_entry->v_next_;
++ free_sg_entry(sg_entry);
++ sg_entry = next;
++ }
++ channel->v_sg_info_->p_srcEntries_ = 0;
++ channel->v_sg_info_->v_srcEntries_ = 0;
++ return 1;
++ }
++
++ // Assemble destination descriptors
++ sg_entry = 0;
++ previous_entry = 0;
++ for (i=0; i < dst_sg_count; i++) {
++ // Is this entry contiguous with the previous one?
++#if 0
++ if (previous_entry &&
++ ((previous_entry->addr_ + previous_entry->length_) == (dst_sg[i].dma_address & HIPOX_DMA_CSUM_ADR_MASK)) &&
++ ((previous_entry->length_ + dst_sg[i].length) <= MAX_HIPOX_DMA_TRANSFER_LENGTH)) {
++ // Yes, so coalesce the pair
++ previous_entry->length_ += dst_sg[i].length;
++ } else
++#endif
++ {
++ // Allocate space for SG list entry from coherent DMA pool
++ hipox_dma_sg_entry_t *new_sg_entry = alloc_sg_entry(in_atomic);
++ if (!new_sg_entry) {
++ failed = 1;
++ break;
++ }
++ sg_entry = new_sg_entry;
++
++ if (previous_entry) {
++ // Link the previous SG list entry forward to this one
++ previous_entry->v_next_ = sg_entry;
++ previous_entry->p_next_ = sg_entry->paddr_;
++ } else {
++ // Create a link from the SG info structure to the first SG list entry
++ sg_info->v_dstEntries_ = sg_entry;
++ sg_info->p_dstEntries_ = sg_entry->paddr_;
++ }
++ previous_entry = sg_entry;
++
++ // Fill in the SG list entry with start address, ensuring address
++ // does not affect the checksum enabling high order adr bit
++ sg_entry->addr_ = dst_sg[i].dma_address & HIPOX_DMA_ADR_MASK;
++
++ // Fill in the length, checking that it does not exceed the hardware
++ // allowed maximum
++ sg_entry->length_ = (dst_sg[i].length <= MAX_HIPOX_DMA_TRANSFER_LENGTH) ? dst_sg[i].length : 0;
++ if (!sg_entry->length_) {
++ printk(KERN_WARNING "hipox_dma_set_sg_common() Destination entry too long, zeroing\n");
++ }
++ }
++ }
++ if (sg_entry) {
++ // Mark the end of the destination SG list with nulls
++ sg_entry->p_next_ = 0;
++ sg_entry->v_next_ = 0;
++ }
++
++ if (failed) {
++ // Failed to allocate all SG dst entries, so free those we did obtain
++ hipox_dma_sg_entry_t* sg_entry = sg_info->v_dstEntries_;
++ while (sg_entry) {
++ hipox_dma_sg_entry_t* next = sg_entry->v_next_;
++ free_sg_entry(sg_entry);
++ sg_entry = next;
++ }
++ sg_info->p_dstEntries_ = 0;
++ sg_info->v_dstEntries_ = 0;
++
++ // Free all the SG src entries which we did sucessfully obtain
++ sg_entry = sg_info->v_srcEntries_;
++ while (sg_entry) {
++ hipox_dma_sg_entry_t* next = sg_entry->v_next_;
++ free_sg_entry(sg_entry);
++ sg_entry = next;
++ }
++ sg_info->p_srcEntries_ = 0;
++ sg_info->v_srcEntries_ = 0;
++ return 1;
++ }
++
++ sg_info->qualifer_ = ((channel->channel_number_ << HIPOX_DMA_SG_CHANNEL_BIT) |
++ (src_settings->read_eot_policy_ << HIPOX_DMA_SG_SRC_EOT_BIT) |
++ (dst_settings->write_eot_policy_ << HIPOX_DMA_SG_DST_EOT_BIT) |
++ (1 << HIPOX_DMA_SG_QUALIFIER_BIT));
++
++ // Flags are the same for source and destination for each SG transfer component
++ sg_info->control_ = encode_control_status(src_settings, dst_settings, 0);
++
++ // Increase count of in-progress transfers on this channel
++ atomic_inc(&channel->active_count_);
++
++ return 0;
++}
++
++int hipox_dma_set_sg(
++ hipox_dma_channel_t* channel,
++ struct scatterlist* src_sg,
++ unsigned src_sg_count,
++ struct scatterlist* dst_sg,
++ unsigned dst_sg_count,
++ hipox_dma_mode_t src_mode,
++ hipox_dma_mode_t dst_mode,
++ int do_checksum,
++ int in_atomic)
++{
++ if (hipox_dma_is_active(channel)) {
++ printk(KERN_WARNING "hipox_dma_set_sg() Trying to use channel %u while active\n", channel->channel_number_);
++ }
++
++#ifdef CONFIG_HIPOX_VERSION_0X800
++ if (do_checksum) {
++ // Arbitrate for ownership of the checksum engine
++ if (alloc_csum_engine()) {
++ // Failed to obtain csum engine, so return with failure status
++ return 1;
++ }
++ }
++#else // CONFIG_HIPOX_VERSION_0X800
++ BUG_ON(do_checksum);
++#endif // CONFIG_HIPOX_VERSION_0X800
++
++ {
++ // Assemble complete memory settings, accounting for csum generation if
++ // required
++#ifdef CONFIG_HIPOX_VERSION_0X800
++ hipox_dma_device_settings_t src_settings =
++ do_checksum ? hipox_ram_csum_src_dma_settings :
++ hipox_ram_only_src_dma_settings;
++#else // CONFIG_HIPOX_VERSION_0X800
++ hipox_dma_device_settings_t src_settings = hipox_ram_only_src_dma_settings;
++#endif // CONFIG_HIPOX_VERSION_0X800
++
++ hipox_dma_device_settings_t dst_settings = hipox_ram_generic_dma_settings;
++
++ // Normal adr bits not used for SG transfers
++ src_settings.address_ = 0;
++ src_settings.address_mode_ = src_mode;
++
++ // Normal adr bits not used for SG transfers
++ dst_settings.address_ = 0;
++ dst_settings.address_mode_ = dst_mode;
++
++#ifdef CONFIG_HIPOX_VERSION_0X800
++ if (do_checksum) {
++ // Record that we are checksumming, so that the result is read on
++ // completion
++ channel->checksumming_ = 1;
++
++ // The high order address bit enabling the checksum engine will be
++ // set by the caller in the passed scatterlist entries, for those
++ // entries which are required to contribute to the checksum
++ // calculation
++ }
++#endif // CONFIG_HIPOX_VERSION_0X800
++
++ return hipox_dma_set_sg_common(
++ channel,
++ src_sg,
++ src_sg_count,
++ dst_sg,
++ dst_sg_count,
++ &src_settings,
++ &dst_settings,
++ in_atomic);
++ }
++}
++
++int hipox_dma_device_set_sg(
++ hipox_dma_channel_t* channel,
++ hipox_dma_direction_t direction,
++ struct scatterlist* mem_sg,
++ unsigned mem_sg_count,
++ hipox_dma_device_settings_t* device_settings,
++ hipox_dma_mode_t mem_mode,
++ int in_atomic)
++{
++ int i;
++ struct scatterlist *sg;
++ struct scatterlist dev_sg;
++
++ hipox_dma_device_settings_t mem_settings;
++
++ if (hipox_dma_is_active(channel)) {
++ printk(KERN_WARNING "hipox_dma_device_set_sg() Trying to use channel %u while active\n", channel->channel_number_);
++ }
++
++ // Assemble complete memory settings
++ mem_settings = hipox_ram_generic_dma_settings;
++ mem_settings.address_ = 0; // Not used for SG transfers
++ mem_settings.address_mode_ = mem_mode;
++
++ // Need to total all memory transfer lengths and assign as device single transfer length
++ dev_sg.dma_address = device_settings->address_;
++ for (i=0, sg=mem_sg, dev_sg.length = 0; i < mem_sg_count; i++, sg++) {
++ dev_sg.length += sg->length;
++ }
++
++ return hipox_dma_set_sg_common(
++ channel,
++ (direction == HIPOX_DMA_TO_DEVICE) ? mem_sg : &dev_sg,
++ (direction == HIPOX_DMA_TO_DEVICE) ? mem_sg_count : 1,
++ (direction == HIPOX_DMA_FROM_DEVICE) ? mem_sg : &dev_sg,
++ (direction == HIPOX_DMA_FROM_DEVICE) ? mem_sg_count : 1,
++ (direction == HIPOX_DMA_TO_DEVICE) ? &mem_settings : device_settings,
++ (direction == HIPOX_DMA_FROM_DEVICE) ? &mem_settings : device_settings,
++ in_atomic);
++}
++
++static int hipox_dma_set_prd_common(
++ hipox_dma_channel_t *channel,
++ struct ata_prd *src_prd,
++ struct ata_prd *dst_prd,
++ hipox_dma_device_settings_t *src_settings,
++ hipox_dma_device_settings_t *dst_settings,
++ hipox_dma_sg_entry_t *sg_entries)
++{
++ int i;
++ int failed = 0;
++ hipox_dma_sg_entry_t *sg_entry, *previous_entry, *next_entry;
++ u32 eot;
++ u32 tot_src_len = 0, tot_dst_len = 0;
++
++ // Get reference to this channel's top level SG DMA descriptor structure
++ hipox_dma_sg_info_t *sg_info = channel->v_sg_info_;
++
++ // SG entries have been provided
++ channel->auto_sg_entries_ = 0;
++
++ // Initialise list pointers to zero
++ sg_info->v_srcEntries_ = 0;
++ sg_info->p_srcEntries_ = 0;
++ sg_info->v_dstEntries_ = 0;
++ sg_info->p_dstEntries_ = 0;
++
++ // Get pointer to first available SG entry
++ sg_entry = previous_entry = 0;
++ next_entry = sg_entries;
++ i=0;
++ do {
++ u32 addr;
++ u32 length;
++ u32 flags_len;
++
++ addr = src_prd[i].addr;
++ flags_len = le32_to_cpu(src_prd[i++].flags_len);
++ length = flags_len & ~ATA_PRD_EOT;
++ eot = flags_len & ATA_PRD_EOT;
++
++ // Zero length field means 64KB
++ if (!length) length = 0x10000;
++
++ // Accumulate the total length of all source elements
++ tot_src_len += length;
++
++ // Is this entry contiguous with the previous one and would the combined
++ // lengths not exceed the maximum that the hardware is capable of
++#if 0
++ if (previous_entry &&
++ ((previous_entry->addr_ + previous_entry->length_) == (addr & HIPOX_DMA_CSUM_ADR_MASK)) &&
++ ((previous_entry->length_ + length) <= MAX_HIPOX_DMA_TRANSFER_LENGTH)) {
++ // Yes, so coalesce the pair
++ previous_entry->length_ += length;
++ } else
++#endif
++ {
++ // Get the next available SG entry
++ if (!next_entry) {
++ failed = 1;
++ break;
++ }
++ sg_entry = next_entry;
++
++ if (previous_entry) {
++ // Link the previous SG list entry forward to this one
++ previous_entry->v_next_ = sg_entry;
++ previous_entry->p_next_ = sg_entry->paddr_;
++ } else {
++ // Create a link from the SG info structure to the first SG list entry
++ sg_info->v_srcEntries_ = sg_entry;
++ sg_info->p_srcEntries_ = sg_entry->paddr_;
++ }
++ previous_entry = sg_entry;
++
++ // Fill in the SG list entry with start address, ensuring only valid
++ // address bits are used, preserving the checksum enabling flag
++ sg_entry->addr_ = addr & HIPOX_DMA_CSUM_ADR_MASK;
++
++ // Fill in the length, checking that it does not exceed the hardware
++ // allowed maximum
++ if (length > MAX_HIPOX_DMA_TRANSFER_LENGTH) {
++ printk(KERN_WARNING "hipox_dma_set_prd_common() Source entry too long (0x%x), zeroing\n", length);
++ sg_entry->length_ = 0;
++ } else {
++ sg_entry->length_ = length;
++ }
++
++ // Get pointer to next available SG entry
++ next_entry = sg_entry->next_;
++ }
++ } while (!eot);
++ if (sg_entry) {
++ // Mark the end of the source SG list with nulls
++ sg_entry->p_next_ = 0;
++ sg_entry->v_next_ = 0;
++ }
++
++ if (failed) {
++ // Failed to allocate all SG src entries
++ channel->v_sg_info_->p_srcEntries_ = 0;
++ channel->v_sg_info_->v_srcEntries_ = 0;
++ printk(KERN_WARNING "Too few SG entries to satisfy source requirements\n");
++ return 1;
++ }
++
++ // Assemble destination descriptors
++ sg_entry = previous_entry = 0;
++ i=0;
++ do {
++ u32 addr;
++ u32 length;
++ u32 flags_len;
++
++ addr = dst_prd[i].addr;
++ flags_len = le32_to_cpu(dst_prd[i++].flags_len);
++ length = flags_len & ~ATA_PRD_EOT;
++ eot = flags_len & ATA_PRD_EOT;
++
++ // Zero length field means 64KB
++ if (!length) length = 0x10000;
++
++ // Accumulate the total length of all destination elements
++ tot_dst_len += length;
++
++ // Is this entry contiguous with the previous one?
++#if 0
++ if (previous_entry &&
++ ((previous_entry->addr_ + previous_entry->length_) == (addr & HIPOX_DMA_CSUM_ADR_MASK)) &&
++ ((previous_entry->length_ + length) <= MAX_HIPOX_DMA_TRANSFER_LENGTH)) {
++ // Yes, so coalesce the pair
++ previous_entry->length_ += length;
++ } else
++#endif
++ {
++ // Get the next available SG entry
++ if (!next_entry) {
++ failed = 1;
++ break;
++ }
++ sg_entry = next_entry;
++
++ if (previous_entry) {
++ // Link the previous SG list entry forward to this one
++ previous_entry->v_next_ = sg_entry;
++ previous_entry->p_next_ = sg_entry->paddr_;
++ } else {
++ // Create a link from the SG info structure to the first SG list entry
++ sg_info->v_dstEntries_ = sg_entry;
++ sg_info->p_dstEntries_ = sg_entry->paddr_;
++ }
++ previous_entry = sg_entry;
++
++ // Fill in the SG list entry with start address, ensuring address
++ // does not affect the checksum enabling high order adr bit
++ sg_entry->addr_ = addr & HIPOX_DMA_ADR_MASK;
++
++ // Fill in the length, checking that it does not exceed the hardware
++ // allowed maximum
++ if (length > MAX_HIPOX_DMA_TRANSFER_LENGTH) {
++ printk(KERN_WARNING "hipox_dma_set_prd_common() Destination entry too long (0x%x), zeroing\n", length);
++ sg_entry->length_ = 0;
++ } else {
++ sg_entry->length_ = length;
++ }
++
++ // Get pointer to next available SG entry
++ next_entry = sg_entry->next_;
++ }
++ } while (!eot);
++ if (sg_entry) {
++ // Mark the end of the destination SG list with nulls
++ sg_entry->p_next_ = 0;
++ sg_entry->v_next_ = 0;
++ }
++
++ if (failed) {
++ // Failed to allocate all SG dst entries
++ sg_info->p_dstEntries_ = 0;
++ sg_info->v_dstEntries_ = 0;
++ sg_info->p_srcEntries_ = 0;
++ sg_info->v_srcEntries_ = 0;
++ printk(KERN_WARNING "Too few SG entries to satisfy destination requirements\n");
++ return 1;
++ }
++
++ // Fill in length of single device SG entry from the total length of all the
++ // memory SG entries
++ if ((sg_entry = sg_info->v_srcEntries_) && !sg_entry->v_next_) {
++ sg_entry->length_ = tot_dst_len;
++ } else if ((sg_entry = sg_info->v_dstEntries_) && !sg_entry->v_next_) {
++ sg_entry->length_ = tot_src_len;
++ }
++
++ sg_info->qualifer_ = ((channel->channel_number_ << HIPOX_DMA_SG_CHANNEL_BIT) |
++ (src_settings->read_eot_policy_ << HIPOX_DMA_SG_SRC_EOT_BIT) |
++ (dst_settings->write_eot_policy_ << HIPOX_DMA_SG_DST_EOT_BIT) |
++ (1 << HIPOX_DMA_SG_QUALIFIER_BIT));
++
++ // Flags are the same for source and destination for each SG transfer component
++ sg_info->control_ = encode_control_status(src_settings, dst_settings, 0);
++
++ // Increase count of in-progress transfers on this channel
++ atomic_inc(&channel->active_count_);
++
++ return 0;
++}
++
++int hipox_dma_device_set_prd(
++ hipox_dma_channel_t *channel,
++ hipox_dma_direction_t direction,
++ struct ata_prd *mem_prd,
++ hipox_dma_device_settings_t *device_settings,
++ hipox_dma_mode_t mem_mode,
++ hipox_dma_sg_entry_t *sg_entries)
++{
++ struct ata_prd dev_prd;
++ hipox_dma_device_settings_t mem_settings;
++
++ if (unlikely(hipox_dma_is_active(channel))) {
++ printk(KERN_WARNING "hipox_dma_device_set_prd() Trying to use channel %u while active\n", channel->channel_number_);
++ }
++
++ // Assemble complete memory settings
++ mem_settings = hipox_ram_generic_dma_settings;
++ mem_settings.address_ = 0; // Not used for SG transfers
++ mem_settings.address_mode_ = mem_mode;
++
++ // Device has only a single SG entry whose length will be assigned once
++ // all the memory transfer lengths have been accumulated
++ dev_prd.addr = device_settings->address_;
++ dev_prd.flags_len = ATA_PRD_EOT;
++
++ return hipox_dma_set_prd_common(
++ channel,
++ (direction == HIPOX_DMA_TO_DEVICE) ? mem_prd : &dev_prd,
++ (direction == HIPOX_DMA_FROM_DEVICE) ? mem_prd : &dev_prd,
++ (direction == HIPOX_DMA_TO_DEVICE) ? &mem_settings : device_settings,
++ (direction == HIPOX_DMA_FROM_DEVICE) ? &mem_settings : device_settings,
++ sg_entries);
++}
++
++void hipox_dma_set_callback(hipox_dma_channel_t* channel, hipox_dma_callback_t callback, hipox_callback_arg_t arg)
++{
++#if defined(HIPOX_DMA_TEST) || defined(HIPOX_DMA_SG_TEST)
++printk("Registering callback 0x%08x for channel %u\n", (unsigned)callback, channel->channel_number_);
++#endif // defined(HIPOX_DMA_TEST) || defined(HIPOX_DMA_SG_TEST)
++ channel->notification_callback_ = callback;
++ channel->notification_arg_ = arg;
++}
++
++static void default_callback(
++ hipox_dma_channel_t* channel,
++ hipox_callback_arg_t arg,
++ hipox_dma_callback_status_t status,
++ u16 checksum,
++ int interrupt_count)
++{
++ up(&channel->default_semaphore_);
++}
++
++void hipox_dma_abort(
++ hipox_dma_channel_t *channel,
++ int in_atomic)
++{
++ u32 ctrl_status;
++ unsigned channel_number = channel->channel_number_;
++ int must_wait = 0;
++ int callback_registered = 0;
++
++ // Assert reset for the channel
++ spin_lock(&dma_controller.spinlock_);
++ ctrl_status = readl(DMA_CALC_REG_ADR(channel_number, DMA_CTRL_STATUS));
++ ctrl_status |= DMA_CTRL_STATUS_RESET;
++ writel(ctrl_status, DMA_CALC_REG_ADR(channel_number, DMA_CTRL_STATUS));
++ spin_unlock(&dma_controller.spinlock_);
++
++ // Wait for the channel to become idle - should be quick as should finish
++ // after the next AHB single or burst transfer
++ while (readl(DMA_CALC_REG_ADR(channel_number, DMA_CTRL_STATUS)) & DMA_CTRL_STATUS_IN_PROGRESS);
++
++ // Deassert reset for the channel
++ spin_lock(&dma_controller.spinlock_);
++ ctrl_status = readl(DMA_CALC_REG_ADR(channel_number, DMA_CTRL_STATUS));
++ ctrl_status &= ~DMA_CTRL_STATUS_RESET;
++ writel(ctrl_status, DMA_CALC_REG_ADR(channel_number, DMA_CTRL_STATUS));
++ spin_unlock(&dma_controller.spinlock_);
++
++ // If no user callback is registered, we need to wait here for the DMA
++ // channel to become inactive, i.e. for the ISR to be called and the
++ // channel software returned to the idle state
++ if (channel->notification_callback_ == HIPOX_DMA_CALLBACK_NUL) {
++ must_wait = 1;
++ if (!in_atomic) {
++ // If the callers is not calling us from atomic context we can
++ // register our own callback and sleep until it is invoked
++ hipox_dma_set_callback(channel, default_callback, HIPOX_DMA_CALLBACK_ARG_NUL);
++ callback_registered = 1;
++ }
++ }
++
++ // Fake an interrupt to cause the channel to be cleaned up by running the
++ // DMA bottom half tasklet
++ fake_interrupt(channel_number);
++
++ if (must_wait) {
++ if (callback_registered) {
++ // Sleep until the channel becomes inactive
++ down_interruptible(&channel->default_semaphore_);
++
++ // Deregister the callback
++ hipox_dma_set_callback(channel, HIPOX_DMA_CALLBACK_NUL, HIPOX_DMA_CALLBACK_ARG_NUL);
++ } else {
++ // If we reach here we are in an atomic context and thus must not do
++ // anything that might cause us to sleep
++ // NB. Possible problem here if we're atomic because someone has
++ // called spin_lock_bh(); I'm concerned that calling do_softirq()
++ // under these circumstances might cause issues, althought the net-
++ // working code calls do_softirq() and doesn't appear to worry
++ if (local_softirq_pending()) {
++ // If an interrupt has not arrived and caused the tasklet to
++ // have been run already, cause it to run now.
++ do_softirq();
++ }
++
++ // The tasklet should have run by this point and cleaned up the channel
++ BUG_ON(hipox_dma_is_active(channel));
++ }
++ }
++}
++
++void hipox_dma_start(hipox_dma_channel_t* channel)
++{
++ // Are there SG lists setup for this channel?
++ if (channel->v_sg_info_->v_srcEntries_) {
++#ifdef HIPOX_DMA_SG_TEST_DUMP_DESCRIPTORS
++ // Print the desciptor contents for debugging
++ hipox_dma_sg_entry_t* d = channel->v_sg_info_->v_srcEntries_;
++ printk("qualifer_ = 0x%08lx, control_ = 0x%lx\n", channel->v_sg_info_->qualifer_, channel->v_sg_info_->control_);
++ printk("Source Descriptors:\n");
++ while (d) {
++ printk("v_addr=0x%08x, p_addr=0x%08x, addr_=0x%08x, length_=0x%08lx, next=0x%08x\n", (u32)d, (u32)d->paddr_, d->addr_, d->length_, d->p_next_);
++ d = d->v_next_;
++ }
++ printk("Destination Descriptors:\n");
++ d = channel->v_sg_info_->v_dstEntries_;
++ while (d) {
++ printk("v_addr=0x%08x, p_addr=0x%08x, addr_=0x%08x, length_=0x%08lx, next=0x%08x\n", (u32)d, (u32)d->paddr_, d->addr_, d->length_, d->p_next_);
++ d = d->v_next_;
++ }
++#endif // HIPOX_DMA_SG_TEST_DUMP_DESCRIPTORS
++
++ // Write to the SG-DMA channel's reset register to reset the control
++ // in case the previous SG-DMA transfer failed in some way, thus
++ // leaving the SG-DMA controller hung up part way through processing
++ // its SG list. The reset bits are self-clearing
++ writel(1UL << DMA_SG_RESETS_CONTROL_BIT, DMA_SG_CALC_REG_ADR(channel->channel_number_, DMA_SG_RESETS));
++
++ // Write the pointer to the SG info struct into the Request Pointer reg.
++ writel(channel->p_sg_info_, DMA_SG_CALC_REG_ADR(channel->channel_number_, DMA_SG_REQ_PTR));
++
++#ifdef HIPOX_DMA_SG_TEST
++printk("p_sg_info_ = 0x%08x written to 0x%08x\n", (u32)channel->p_sg_info_, DMA_SG_CALC_REG_ADR(channel->channel_number_, DMA_SG_REQ_PTR));
++printk("*(DMA_SG_CONTROL) = 0x%08x\n", readl(DMA_SG_CALC_REG_ADR(channel->channel_number_, DMA_SG_CONTROL)));
++printk("*(DMA_SG_STATUS) = 0x%08x\n", readl(DMA_SG_CALC_REG_ADR(channel->channel_number_, DMA_SG_STATUS)));
++printk("*(DMA_SG_REQ_PTR) = 0x%08x\n", readl(DMA_SG_CALC_REG_ADR(channel->channel_number_, DMA_SG_REQ_PTR)));
++#endif // HIPOX_DMA_SG_TEST
++
++ // Start the transfer
++ writel((1UL << DMA_SG_CONTROL_START_BIT) |
++ (1UL << DMA_SG_CONTROL_QUEUING_ENABLE_BIT) |
++ (1UL << DMA_SG_CONTROL_HBURST_ENABLE_BIT),
++ DMA_SG_CALC_REG_ADR(channel->channel_number_, DMA_SG_CONTROL));
++ } else {
++ // Single transfer mode, so unpause the DMA controller channel
++ spin_lock(&dma_controller.spinlock_);
++ writel(encode_start(readl(DMA_CALC_REG_ADR(channel->channel_number_, DMA_CTRL_STATUS))),
++ DMA_CALC_REG_ADR(channel->channel_number_, DMA_CTRL_STATUS));
++ spin_unlock(&dma_controller.spinlock_);
++ }
++}
++
++void hipox_dma_dump_registers()
++{
++ unsigned long* adr = (unsigned long*)DMA_CALC_REG_ADR(0, 0);
++ unsigned long* end = (adr + DMA_REGS_PER_CHANNEL);
++ int i;
++
++ printk("hipox_dma_dump_registers(), adr= 0x%08lx, end=0x%08lx\n", (unsigned long)adr, (unsigned long)(adr + (DMA_REGS_PER_CHANNEL * dma_controller.numberOfChannels_)));
++
++ for (i=0; i < dma_controller.numberOfChannels_; i++) {
++ for (; adr < end; adr++) {
++ printk("0x%08lx\n", *adr);
++ }
++ printk("SG-Debug: 0x%08x\n", readl(DMA_SG_CALC_REG_ADR(i, DMA_SG_RESETS)));
++ printk("-----------------------\n");
++ end += DMA_REGS_PER_CHANNEL;
++ }
++ printk("hipox_dma_dump_registers() - end\n");
++}
++
++void hipox_dma_dump_registers_single(int channel_number)
++{
++ unsigned long* adr = (unsigned long*)DMA_CALC_REG_ADR(channel_number, 0);
++ unsigned long* end = (adr + DMA_REGS_PER_CHANNEL);
++
++ printk("DMA channel %d regs:\n", channel_number);
++ for (; adr < end; adr++) {
++ printk("0x%08lx\n", *adr);
++ }
++}
++
++#if defined(HIPOX_DMA_TEST) || defined(HIPOX_DMA_SG_TEST)
++static __DECLARE_SEMAPHORE_GENERIC(callback_semaphore, 0); // Binary semaphore for testing
++
++static void dma_callback(
++ hipox_dma_channel_t *channel,
++ hipox_callback_arg_t arg,
++ hipox_dma_callback_status_t error_code,
++ u16 checksum,
++ int interrupt_count)
++{
++ printk("dma_callback() for channel %u, arg = 0x%lx, status = 0x%04x, checksum = 0x%04hx, interrupt_count = %d\n", channel->channel_number_, (unsigned long)arg, error_code, checksum, interrupt_count);
++ up(&callback_semaphore);
++}
++
++#include <linux/dma-mapping.h>
++#include <linux/slab.h>
++
++#ifdef HIPOX_DMA_TEST
++static void dma_test(unsigned long length)
++{
++ void* memory1;
++ void* memory2;
++ unsigned long* ptr;
++ unsigned long quads;
++ int i;
++ unsigned long* end;
++ dma_addr_t dma_address1;
++ dma_addr_t dma_address2;
++ hipox_dma_channel_t* channels[MAX_HIPOX_DMA_CHANNELS];
++
++ printk("*************************************************************\n");
++ printk(" \n");
++ printk("Simple DMA Test, length = %lu, number of channel = %u\n", length, MAX_HIPOX_DMA_CHANNELS);
++ printk(" \n");
++ printk("*************************************************************\n");
++
++ for (i=0; i < MAX_HIPOX_DMA_CHANNELS; ++i) {
++ channels[i] = hipox_dma_request(0);
++ if (channels[i] == HIPOX_DMA_CHANNEL_NUL) {
++ printk("No DMA channels[%d] obtained\n", i);
++ } else {
++ printk("Obtained DMA channels[%d] %u, isActive=%d\n", i, channels[i]->channel_number_, hipox_dma_is_active(channels[i]));
++ }
++ }
++
++ // Allocate some DMA coherent memory
++ printk("Calling kmalloc()\n");
++ memory1 = kmalloc(length, GFP_KERNEL | GFP_DMA);
++ memory2 = kmalloc(length, GFP_KERNEL | GFP_DMA);
++
++ // Test each available DMA channel
++ for (i=0; i < MAX_HIPOX_DMA_CHANNELS; ++i) {
++ int j;
++
++ // Fill each memory area with a different pattern
++ ptr = (unsigned long*)memory1;
++ quads = length/sizeof(unsigned long);
++ for (j=0; j < quads; j++) {
++ *ptr++ = 0xdeadbeef;
++ }
++ ptr = (unsigned long*)memory2;
++ for (j=0; j < quads; j++) {
++ *ptr++ = 0xc001babe;
++ }
++
++ printk("Before:\n");
++ ptr = (unsigned long*)memory1;
++ end = (unsigned long*)(memory1 + length);
++ while (ptr < end) {
++ for (j=0; j < 8; j++) {
++ printk("0x%08lx ", *ptr++);
++ }
++ printk("\n");
++ }
++ printk("---------------------------------------------------------\n");
++ ptr = (unsigned long*)memory2;
++ end = (unsigned long*)(memory2 + length);
++ while (ptr < end) {
++ for (j=0; j < 8; j++) {
++ printk("0x%08lx ", *ptr++);
++ }
++ printk("\n");
++ }
++
++ // Get a consistent DMA mapping for the memory to be DMAed from - causing a
++ // flush from the CPU's cache to the memory
++ dma_address1 = dma_map_single(0, memory1, length, DMA_TO_DEVICE);
++ if (dma_mapping_error(dma_address1)) {
++ printk("Consistent DMA mapping 1 failed\n");
++ }
++
++ // Get a consistent DMA mapping for the memory to be DMAed to - causing a
++ // flush and invalidation of any entries in the CPU's cache covering the
++ // memory region
++ dma_address2 = dma_map_single(0, memory2, length, DMA_BIDIRECTIONAL);
++ if (dma_mapping_error(dma_address2)) {
++ printk("Consistent DMA mapping 2 failed\n");
++ }
++
++ // Setup up DMA from first half to second half on memory, using physical addresses
++ printk("Calling hipox_dma_set(), memory1 = 0x%08lx, memory2 = 0x%08lx\n", (unsigned long)memory1, (unsigned long)memory2);
++ hipox_dma_set(
++ channels[i],
++ (unsigned char*)dma_address1,
++ length,
++ (unsigned char*)dma_address2,
++ HIPOX_DMA_MODE_INC,
++ HIPOX_DMA_MODE_INC,
++#ifdef CONFIG_HIPOX_VERSION_0X800
++ 1, // Calculate checksum over source data
++#else // CONFIG_HIPOX_VERSION_0X800
++ 0,
++#endif // CONFIG_HIPOX_VERSION_0X800
++ 1); // Paused
++
++ // Using notification callback
++ hipox_dma_set_callback(channels[i], dma_callback, HIPOX_DMA_CALLBACK_ARG_NUL);
++
++//printk("Before starting status = 0x%08x, intId = 0x%08x\n", readl(DMA_CALC_REG_ADR(channels[i]->channel_number_, DMA_CTRL_STATUS)), readl(DMA_CALC_REG_ADR(0, DMA_INTR_ID)));
++ // Start the transfer
++ printk("hipox_dma_start() for channel %u\n", channels[i]->channel_number_);
++ hipox_dma_start(channels[i]);
++
++// Poll for transfer completion
++//while (hipox_dma_raw_isactive(channels[i])) {
++// printk(".");
++//}
++//printk("Found channel inactive, status = 0x%08x, intId = 0x%08x\n", readl(DMA_CALC_REG_ADR(channels[i]->channel_number_, DMA_CTRL_STATUS)), readl(DMA_CALC_REG_ADR(0, DMA_INTR_ID)));
++
++ printk("Waiting for channel to be inactive\n");
++
++ // Sleep until transfer completed
++ while (down_interruptible(&callback_semaphore));
++ hipox_dma_set_callback(channels[i], HIPOX_DMA_CALLBACK_NUL, HIPOX_DMA_CALLBACK_ARG_NUL);
++
++ // Release the consistent DMA mappings
++ dma_unmap_single(0, dma_address1, length, DMA_TO_DEVICE);
++ dma_unmap_single(0, dma_address2, length, DMA_BIDIRECTIONAL);
++
++ printk("After:\n");
++ ptr = (unsigned long*)memory1;
++ end = (unsigned long*)(memory1 + length);
++ while (ptr < end) {
++ for (j=0; j < 8; j++) {
++ printk("0x%08lx ", *ptr++);
++ }
++ printk("\n");
++ }
++ printk("---------------------------------------------------------\n");
++ ptr = (unsigned long*)memory2;
++ end = (unsigned long*)(memory2 + length);
++ while (ptr < end) {
++ for (j=0; j < 8; j++) {
++ printk("0x%08lx ", *ptr++);
++ }
++ printk("\n");
++ }
++ }
++
++ // Deallocate the memory
++ printk("Calling kfree()\n");
++ kfree(memory1);
++ kfree(memory2);
++ printk("Returned from kfree()\n");
++
++ for (i=0; i < MAX_HIPOX_DMA_CHANNELS; ++i) {
++ hipox_dma_free(channels[i]);
++ }
++
++ for (i=0; i < MAX_HIPOX_DMA_CHANNELS; ++i) {
++ channels[i] = hipox_dma_request(0);
++ if (channels[i] == HIPOX_DMA_CHANNEL_NUL) {
++ printk("No DMA channels[%d] obtained\n", i);
++ } else {
++ printk("Obtained DMA channels[%d] %u, isActive=%d\n", i, channels[i]->channel_number_, hipox_dma_is_active(channels[i]));
++ }
++ }
++
++ for (i=0; i < MAX_HIPOX_DMA_CHANNELS; ++i) {
++ hipox_dma_free(channels[i]);
++ }
++}
++#endif // HIPOX_DMA_TEST
++
++#ifdef HIPOX_DMA_SG_TEST
++static void dma_sg_test(void)
++{
++ int i;
++ struct scatterlist* src_scatterlist = 0;
++ struct scatterlist* dst_scatterlist = 0;
++ const int num_src_buffers = 8;
++ const int num_dst_buffers = 3;
++ unsigned long src_fill_value = 0;
++ unsigned long total_src_len = 0;
++ int channel_number;
++ hipox_dma_channel_t* channels[MAX_HIPOX_DMA_CHANNELS];
++
++ printk("*************************************************************\n");
++ printk(" \n");
++ printk("Scatter-Gather DMA Test\n");
++ printk(" \n");
++ printk("*************************************************************\n");
++
++ for (i=0; i < MAX_HIPOX_DMA_CHANNELS; ++i) {
++ channels[i] = hipox_dma_request(0);
++ if (channels[i] == HIPOX_DMA_CHANNEL_NUL) {
++ printk("No DMA channels[%d] obtained\n", i);
++ } else {
++ printk("Obtained DMA channels[%d] %u, isActive=%d\n", i, channels[i]->channel_number_, hipox_dma_is_active(channels[i]));
++ }
++ }
++
++ for (channel_number=0; channel_number < MAX_HIPOX_DMA_CHANNELS; ++channel_number) {
++ if (num_src_buffers) {
++ printk("Allocating source SG list and entry buffers\n");
++ // Allocate scatterlist and memory for source buffers - store virtual buffer
++ // addresses in scatterlist.offset for convenience. Include some contiguous
++ // entries to test coalescing
++ src_scatterlist = (struct scatterlist*)kmalloc(sizeof(struct scatterlist) * num_src_buffers, GFP_KERNEL);
++ src_scatterlist[0].offset = (unsigned int)kmalloc(8*1024, GFP_KERNEL | GFP_DMA);
++ src_scatterlist[0].__address = (char*)(8*1024); // Real allocation length
++ src_scatterlist[0].length = 8*1024;
++ src_scatterlist[0].page = (struct page*)0xdeadbeef; // Fill value
++ src_scatterlist[1].offset = (unsigned int)kmalloc(8, GFP_KERNEL | GFP_DMA);
++ src_scatterlist[1].__address = (char*)8; // Real allocation length
++ src_scatterlist[1].length = 8;
++ src_scatterlist[1].page = (struct page*)0xc001babe; // Fill value
++ src_scatterlist[2].offset = (unsigned int)kmalloc(48*1024, GFP_KERNEL | GFP_DMA);
++ src_scatterlist[2].__address = (char*)(48*1024); // Real allocation length
++ src_scatterlist[2].length = 16*1024;
++ src_scatterlist[2].page = (struct page*)0x22222222; // Fill value
++ src_scatterlist[3].offset = src_scatterlist[2].offset + src_scatterlist[2].length;
++ src_scatterlist[3].__address = (char*)0; // No allocation
++ src_scatterlist[3].length = 16*1024;
++ src_scatterlist[3].page = (struct page*)0x33333333; // Fill value
++ src_scatterlist[4].offset = src_scatterlist[3].offset + src_scatterlist[3].length;
++ src_scatterlist[4].__address = (char*)0; // No allocation
++ src_scatterlist[4].length = 16*1024;
++ src_scatterlist[4].page = (struct page*)0x44444444; // Fill value
++ src_scatterlist[5].offset = (unsigned int)kmalloc(64, GFP_KERNEL | GFP_DMA);
++ src_scatterlist[5].__address = (char*)64; // Real allocation length
++ src_scatterlist[5].length = 64;
++ src_scatterlist[5].page = (struct page*)0x55555555; // Fill value
++ src_scatterlist[6].offset = (unsigned int)kmalloc(256, GFP_KERNEL | GFP_DMA);
++ src_scatterlist[6].__address = (char*)256; // Real allocation length
++ src_scatterlist[6].length = 128;
++ src_scatterlist[6].page = (struct page*)0x66666666; // Fill value
++ src_scatterlist[7].offset = src_scatterlist[6].offset + src_scatterlist[6].length;
++ src_scatterlist[7].__address = (char*)0; // No allocation
++ src_scatterlist[7].length = 128;
++ src_scatterlist[7].page = (struct page*)0x77777777; // Fill value
++ }
++
++ // Fill source memory buffers with stuff
++ for (i=0; i < num_src_buffers; i++) {
++ unsigned long* ptr = (unsigned long*)src_scatterlist[i].offset;
++ int quads = src_scatterlist[i].length/sizeof(unsigned long);
++ int j=0;
++ printk("Filling source buffer %u\n", i);
++ src_fill_value = (unsigned long)(src_scatterlist[i].page);
++ for (; j < quads; j++) {
++ *ptr++ = src_fill_value;
++ }
++ }
++
++ #ifdef HIPOX_DMA_SG_TEST_DUMP_BUFFERS
++ // Print before contents of source buffers
++ printk("Source Before:\n");
++ for (i=0; i < num_src_buffers; i++) {
++ unsigned long* ptr = (unsigned long*)src_scatterlist[i].offset;
++ unsigned long* end = (unsigned long*)(src_scatterlist[i].offset + src_scatterlist[i].length);
++ printk("Buffer %d\n", i);
++ while (ptr < end) {
++ int j=0;
++ for (; j < 8; j++) {
++ printk("0x%08lx ", *ptr++);
++ }
++ printk("\n");
++ }
++ }
++ #endif // HIPOX_DMA_SG_TEST_DUMP_BUFFERS
++
++ // Get a consistent DMA mapping for the memory to be DMAed from - causing a
++ // flush from the CPU's cache to the memory
++ for (i=0; i < num_src_buffers; i++) {
++ printk("Creating DMA mappings for source entry buffer %u\n", i);
++ src_scatterlist[i].dma_address = dma_map_single(0, (void*)src_scatterlist[i].offset, src_scatterlist[i].length, DMA_TO_DEVICE);
++ if (dma_mapping_error(src_scatterlist[i].dma_address)) {
++ printk("Consistent source DMA mapping %d failed\n", i);
++ }
++
++ // Set the checksum enabling high order address bit
++ src_scatterlist[i].dma_address |= (1UL << HIPOX_DMA_CSUM_ENABLE_ADR_BIT);
++ }
++
++ // Allocate scatterlist and memory for destination buffers - store virtual
++ // buffer addresses in scatterlist.offset for convenience
++ if (num_dst_buffers) {
++ unsigned long dst_length;
++ unsigned long offset;
++
++ printk("Allocating destination SG list and entry buffers\n");
++ total_src_len = 0;
++ for (i=0; i < num_src_buffers; i++) {
++ total_src_len += src_scatterlist[i].length;
++ }
++
++ // Following will only work if no remainder due to divide
++ dst_length = total_src_len / num_dst_buffers;
++ dst_scatterlist = (struct scatterlist*)kmalloc(sizeof(struct scatterlist) * num_dst_buffers, GFP_KERNEL);
++
++ // First destination segment owns the buffer
++ dst_scatterlist[0].offset = (unsigned int)kmalloc(total_src_len, GFP_KERNEL | GFP_DMA);
++ dst_scatterlist[0].__address = (char*)total_src_len; // Real allocation length
++ dst_scatterlist[0].length = dst_length;
++
++ offset = dst_length;
++ for (i=1; i < num_dst_buffers; i++) {
++ dst_scatterlist[i].offset = dst_scatterlist[0].offset + offset;
++ dst_scatterlist[i].__address = 0; // No allocation
++ dst_scatterlist[i].length = dst_length;
++
++ offset += dst_length;
++ }
++ }
++
++ // Fill destination memory buffers with zero
++ for (i=0; i < num_dst_buffers; i++) {
++ unsigned long* ptr = (unsigned long*)dst_scatterlist[i].offset;
++ int quads = dst_scatterlist[i].length/sizeof(unsigned long);
++ int j=0;
++ printk("Filling destination buffer %u\n", i);
++ for (; j < quads; j++) {
++ *ptr++ = 0x000000;
++ }
++ }
++
++ //#ifdef HIPOX_DMA_SG_TEST_DUMP_BUFFERS
++ // // Print before contents of destination buffers
++ // printk("Destination Before:\n");
++ // for (i=0; i < num_dst_buffers; i++) {
++ // unsigned long* ptr = (unsigned long*)dst_scatterlist[i].offset;
++ // unsigned long* end = (unsigned long*)(dst_scatterlist[i].offset + dst_scatterlist[i].length);
++ // printk("Buffer %d\n", i);
++ // while (ptr < end) {
++ // int j=0;
++ // for (; j < 8; j++) {
++ // printk("0x%08lx ", *ptr++);
++ // }
++ // printk("\n");
++ // }
++ // }
++ //#endif // HIPOX_DMA_SG_TEST_DUMP_BUFFERS
++
++ // Get a consistent DMA mapping for the memory to be DMAed to - causing an
++ // invalidate to the CPU's cache
++ for (i=0; i < num_dst_buffers; i++) {
++ printk("Creating DMA mappings for destination entry buffer %u\n", i);
++ dst_scatterlist[i].dma_address = dma_map_single(0, (void*)dst_scatterlist[i].offset, dst_scatterlist[i].length, DMA_BIDIRECTIONAL);
++ if (dma_mapping_error(dst_scatterlist[i].dma_address)) {
++ printk("Consistent destination DMA mapping %d failed\n", i);
++ }
++ }
++
++ // Setup up SG DMA transfer
++ printk("Setting up transfer\n");
++ hipox_dma_set_sg(
++ channels[channel_number],
++ src_scatterlist,
++ num_src_buffers,
++ dst_scatterlist,
++ num_dst_buffers,
++ HIPOX_DMA_MODE_INC,
++ HIPOX_DMA_MODE_INC,
++#ifdef CONFIG_HIPOX_VERSION_0X800
++ 1); // Compute checksum
++#else // CONFIG_HIPOX_VERSION_0X800
++ 0);
++#endif // CONFIG_HIPOX_VERSION_0X800
++
++ // Using second DMA channel requested
++ hipox_dma_set_callback(channels[channel_number], dma_callback, HIPOX_DMA_CALLBACK_ARG_NUL);
++
++ // Start the transfer
++ printk("Starting the transfer\n");
++ hipox_dma_start(channels[channel_number]);
++
++ // Sleep until transfer completed
++ printk("Waiting for transfer to complete...\n");
++
++ while (down_interruptible(&callback_semaphore));
++ hipox_dma_set_callback(channels[channel_number], HIPOX_DMA_CALLBACK_NUL, HIPOX_DMA_CALLBACK_ARG_NUL);
++
++ // Release the consistent DMA mappings for the source buffers
++ for (i=0; i < num_src_buffers; i++) {
++ printk("Releasing DMA mappings for source entry buffer %u\n", i);
++ // Ensure the checksum enabling high order address bit is not set, as
++ // this would confuse the DMA mapping release function
++ src_scatterlist[i].dma_address &= ~(1UL << HIPOX_DMA_CSUM_ENABLE_ADR_BIT);
++ dma_unmap_single(0, src_scatterlist[i].dma_address, src_scatterlist[i].length, DMA_TO_DEVICE);
++ }
++
++ // Release the consistent DMA mappings for the destination buffers
++ for (i=0; i < num_dst_buffers; i++) {
++ printk("Releasing DMA mappings for destination entry buffer %u\n", i);
++ dma_unmap_single(0, dst_scatterlist[i].dma_address, dst_scatterlist[i].length, DMA_BIDIRECTIONAL);
++ }
++
++ {
++ u32 sw_csum = 0;
++ for (i=0; i < num_src_buffers; i++) {
++ sw_csum = csum_partial((u8*)src_scatterlist[i].offset, src_scatterlist[i].length, sw_csum);
++ }
++ printk("S/W generated src csum = 0x%04hx\n", csum_fold(sw_csum));
++
++ sw_csum = 0;
++ for (i=0; i < num_dst_buffers; i++) {
++ sw_csum = csum_partial((u8*)dst_scatterlist[i].offset, dst_scatterlist[i].length, sw_csum);
++ }
++ printk("S/W generated dst csum = 0x%04hx\n", csum_fold(sw_csum));
++ }
++
++ #ifdef HIPOX_DMA_SG_TEST_DUMP_BUFFERS
++ // // Print after contents of source buffers
++ // printk("Source After:\n");
++ // for (i=0; i < num_src_buffers; i++) {
++ // unsigned long* ptr = (unsigned long*)src_scatterlist[i].offset;
++ // unsigned long* end = (unsigned long*)(src_scatterlist[i].offset + src_scatterlist[i].length);
++ // printk("Buffer %d\n", i);
++ // while (ptr < end) {
++ // int j=0;
++ // for (; j < 8; j++) {
++ // printk("0x%08lx ", *ptr++);
++ // }
++ // printk("\n");
++ // }
++ // }
++
++ // Print after contents of destination buffers
++ printk("Destination After:\n");
++ for (i=0; i < num_dst_buffers; i++) {
++ unsigned long* ptr = (unsigned long*)dst_scatterlist[i].offset;
++ unsigned long* end = (unsigned long*)(dst_scatterlist[i].offset + dst_scatterlist[i].length);
++ printk("Buffer %d\n", i);
++ while (ptr < end) {
++ int j=0;
++ for (; j < 8; j++) {
++ printk("0x%08lx ", *ptr++);
++ }
++ printk("\n");
++ }
++ }
++ #endif // HIPOX_DMA_SG_TEST_DUMP_BUFFERS
++
++ // Free the memory for the source buffers
++ for (i=0; i < num_src_buffers; i++) {
++ // Check that unique allocation made for this entry
++ if (src_scatterlist[i].__address) {
++ printk("Freeing source SG entry buffer, adr = 0x%08x, len = 0x%08x\n", src_scatterlist[i].offset, (u32)src_scatterlist[i].__address);
++ kfree((void*)src_scatterlist[i].offset);
++ }
++ }
++
++ // Free the memory for the source scatterlist
++ if (src_scatterlist) {
++ printk("Freeing source SG scatter list structure\n");
++ kfree(src_scatterlist);
++ }
++
++ // Free the memory for the destination buffers
++ for (i=0; i < num_dst_buffers; i++) {
++ if (dst_scatterlist[i].__address) {
++ printk("Freeing destination SG entry, adr = 0x%08x, len = 0x%08x\n", dst_scatterlist[i].offset, (u32)dst_scatterlist[i].__address);
++ kfree((void*)dst_scatterlist[i].offset);
++ }
++ }
++
++ // Free the memory for the destination scatterlist
++ if (dst_scatterlist) {
++ printk("Freeing source SG scatter list structure\n");
++ kfree(dst_scatterlist);
++ }
++ }
++
++ for (i=0; i < MAX_HIPOX_DMA_CHANNELS; ++i) {
++ hipox_dma_free(channels[i]);
++ }
++}
++#endif // HIPOX_DMA_SG_TEST
++
++#ifdef HIPOX_DMA_SG_TEST_2
++static void dma_sg_test2()
++{
++ /** Include initial 2 bytes of pad that real network buffers would contain
++ in order to ensure that IP header and TCP/UDP header are quad aligned */
++ static const unsigned char bad_src_data0[] = {
++ 0xff, 0xff, 0x00, 0xa0, 0xd2, 0x05, 0x06, 0xec, 0x00, 0xcf, 0x52, 0x49, 0xc3, 0x03, 0x08, 0x00,
++ 0x45, 0x00, 0x05, 0xb4, 0x99, 0x45, 0x40, 0x00, 0x40, 0x06, 0x42, 0xf5, 0xac, 0x1f, 0x00, 0x65,
++ 0xac, 0x1f, 0x00, 0x66
++ };
++
++ static const unsigned char bad_src_data1[] = {
++ 0x04, 0x00, 0x13, 0x89, 0x02, 0x8a, 0x5c, 0x83, 0x52, 0xde, 0xc7, 0x0c, 0x80, 0x19, 0x0b, 0x68,
++ 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x08, 0x0a, 0xff, 0xff, 0xb3, 0x9d, 0x3f, 0x82, 0xf0, 0xff,
++ 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39,
++ 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35,
++ 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31,
++ 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
++ 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33,
++ 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39,
++ 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35,
++ 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31,
++ 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
++ 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33,
++ 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39,
++ 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35,
++ 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31,
++ 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
++ 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33,
++ 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39,
++ 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35,
++ 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31,
++ 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
++ 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33,
++ 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39,
++ 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35,
++ 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31,
++ 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
++ 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33,
++ 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39,
++ 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35,
++ 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31,
++ 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
++ 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33,
++ 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39,
++ 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35,
++ 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31,
++ 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
++ 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33,
++ 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39,
++ 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35,
++ 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31,
++ 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
++ 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33,
++ 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39,
++ 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35,
++ 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31,
++ 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
++ 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33,
++ 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39,
++ 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35,
++ 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31,
++ 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
++ 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33,
++ 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39,
++ 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35,
++ 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31,
++ 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
++ 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33,
++ 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39,
++ 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35,
++ 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31,
++ 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
++ 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33,
++ 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39,
++ 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35,
++ 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31,
++ 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
++ 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33,
++ 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39,
++ 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35,
++ 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31,
++ 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
++ 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33,
++ 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39,
++ 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35,
++ 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31,
++ 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
++ 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33,
++ 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39,
++ 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35,
++ 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31,
++ 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
++ 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33,
++ 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39,
++ 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35,
++ 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31,
++ 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
++ 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33,
++ 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39,
++ 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35,
++ 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31
++ };
++
++ /** Include initial 2 bytes of pad that real network buffers would contain
++ in order to ensure that IP header and TCP/UDP header are quad aligned */
++ static const unsigned char good_src_data0[] = {
++ 0xff, 0xff, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5,
++ 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5,
++ 0xa5, 0xa5, 0xa5, 0xa5
++ };
++
++ static const unsigned char good_src_data1[] = {
++ 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5,
++ 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5,
++ 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5,
++ 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5,
++ 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5,
++ 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5,
++ 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5,
++ 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5,
++ 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5,
++ 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5,
++ 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5,
++ 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5,
++ 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5,
++ 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5,
++ 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5,
++ 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5,
++ 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5,
++ 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5,
++ 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5,
++ 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5,
++ 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5,
++ 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5,
++ 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5,
++ 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5,
++ 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5,
++ 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5,
++ 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5,
++ 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5,
++ 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5,
++ 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5,
++ 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5,
++ 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5,
++ 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5,
++ 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5,
++ 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5,
++ 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5,
++ 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5,
++ 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5,
++ 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5,
++ 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5,
++ 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5,
++ 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5,
++ 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5,
++ 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5,
++ 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5,
++ 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5,
++ 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5,
++ 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5,
++ 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5,
++ 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5,
++ 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5,
++ 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5,
++ 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5,
++ 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5,
++ 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5,
++ 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5,
++ 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5,
++ 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5,
++ 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5,
++ 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5,
++ 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5,
++ 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5,
++ 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5,
++ 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5,
++ 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5,
++ 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5,
++ 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5,
++ 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5,
++ 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5,
++ 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5,
++ 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5,
++ 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5,
++ 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5,
++ 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5,
++ 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5,
++ 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5,
++ 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5,
++ 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5,
++ 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5,
++ 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5,
++ 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5,
++ 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5,
++ 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5,
++ 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5,
++ 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5,
++ 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5,
++ 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5,
++ 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5,
++ 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5,
++ 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5
++ };
++
++ static const int src_offset = 2; // To jump IP quad align padding
++ static const int dst_buffer_size = 512;
++
++ const unsigned char *src_data0 = bad_src_data0;
++ const unsigned char *src_data1 = bad_src_data1;
++ unsigned long src_data0_len = sizeof(bad_src_data0);
++ unsigned long src_data1_len = sizeof(bad_src_data1);
++ int channel_number;
++ hipox_dma_channel_t* channels[MAX_HIPOX_DMA_CHANNELS];
++ int i;
++
++// const unsigned char *src_data0 = good_src_data0;
++// const unsigned char *src_data1 = good_src_data1;
++// unsigned long src_data0_len = sizeof(good_src_data0);
++// unsigned long src_data1_len = sizeof(good_src_data1);
++
++ printk("*************************************************************\n");
++ printk(" \n");
++ printk("Scatter-Gather DMA Test 2\n");
++ printk(" \n");
++ printk("*************************************************************\n");
++
++ printk("seg0 0x%08x, %lu\n", (u32)src_data0, src_data0_len);
++ printk("seg1 0x%08x, %lu\n", (u32)src_data1, src_data1_len);
++
++ for (i=0; i < MAX_HIPOX_DMA_CHANNELS; ++i) {
++ channels[i] = hipox_dma_request(0);
++ if (channels[i] == HIPOX_DMA_CHANNEL_NUL) {
++ printk("No DMA channels[%d] obtained\n", i);
++ } else {
++ printk("Obtained DMA channels[%d] %u, isActive=%d\n", i, channels[i]->channel_number_, hipox_dma_is_active(channels[i]));
++ }
++ }
++
++ // Test each available DMA channel
++ for (channel_number=0; channel_number < MAX_HIPOX_DMA_CHANNELS; ++channel_number) {
++
++ struct scatterlist* src_scatterlist = (struct scatterlist*)kmalloc(sizeof(struct scatterlist) * 2, GFP_KERNEL);
++
++ unsigned long total_src_length = src_data0_len + src_data1_len;
++ src_scatterlist[0].offset = (unsigned int)kmalloc(total_src_length, GFP_KERNEL | GFP_DMA) + src_offset;
++ src_scatterlist[0].length = src_data0_len - src_offset;
++ memcpy((u8*)src_scatterlist[0].offset, src_data0, src_scatterlist[0].length);
++
++ src_scatterlist[1].offset = src_scatterlist[0].offset + src_scatterlist[0].length;
++ src_scatterlist[1].length = src_data1_len;
++ memcpy((u8*)src_scatterlist[1].offset, src_data1, src_scatterlist[1].length);
++
++ unsigned long total_dst_length = total_src_length - src_offset; // Excludes initial IP quad alignment pad
++ unsigned num_dst_buffers = total_dst_length / dst_buffer_size;
++ if ((num_dst_buffers * dst_buffer_size) < total_dst_length) {
++ ++num_dst_buffers;
++ }
++ printk("total_src_length = %lu, src_offset = %u, total_dst_length = %lu, dst_buffer_size = %u, num_dst_buffers = %u\n", total_src_length, src_offset, total_dst_length, dst_buffer_size, num_dst_buffers);
++ struct scatterlist* dst_scatterlist = (struct scatterlist*)kmalloc(sizeof(struct scatterlist) * num_dst_buffers, GFP_KERNEL);
++
++ int i;
++ unsigned long remainder = total_dst_length;
++ for (i=0; i < num_dst_buffers; ++i) {
++ dst_scatterlist[i].offset = (unsigned int)kmalloc(dst_buffer_size, GFP_KERNEL | GFP_DMA);
++ dst_scatterlist[i].length = (remainder < dst_buffer_size) ? remainder : dst_buffer_size;
++ remainder -= dst_scatterlist[i].length;
++ }
++
++ int j;
++ for (j=0; j < HIPOX_DMA_SG_TEST2_ITERATIONS; ++j) {
++ src_scatterlist[0].dma_address = dma_map_single(0, (void*)src_scatterlist[0].offset, src_scatterlist[0].length, DMA_TO_DEVICE);
++ if (dma_mapping_error(src_scatterlist[0].dma_address)) {
++ printk("Consistent source DMA mapping 0 failed\n");
++ }
++ // Set the checksum enabling high order address bit
++ //src_scatterlist[0].dma_address |= (1UL << HIPOX_DMA_CSUM_ENABLE_ADR_BIT);
++
++ src_scatterlist[1].dma_address = dma_map_single(0, (void*)src_scatterlist[1].offset, src_scatterlist[1].length, DMA_TO_DEVICE);
++ if (dma_mapping_error(src_scatterlist[1].dma_address)) {
++ printk("Consistent source DMA mapping 1 failed\n");
++ }
++ // Set the checksum enabling high order address bit
++ src_scatterlist[1].dma_address |= (1UL << HIPOX_DMA_CSUM_ENABLE_ADR_BIT);
++
++ printk("num_dst_buffers = %u\n", num_dst_buffers);
++ for (i=0; i < num_dst_buffers; i++) {
++ memset((void*)dst_scatterlist[i].offset, 0, dst_scatterlist[i].length);
++
++ dst_scatterlist[i].dma_address = dma_map_single(0, (void*)dst_scatterlist[i].offset, dst_scatterlist[i].length, DMA_BIDIRECTIONAL);
++ if (dma_mapping_error(dst_scatterlist[i].dma_address)) {
++ printk("Consistent destination DMA mapping %d failed\n", i);
++ }
++ }
++
++ // Setup up SG DMA transfer
++ printk("Setting up transfer\n");
++ hipox_dma_set_sg(
++ channels[channel_number],
++ src_scatterlist,
++ 2,
++ dst_scatterlist,
++ num_dst_buffers,
++ HIPOX_DMA_MODE_INC,
++ HIPOX_DMA_MODE_INC,
++#ifdef CONFIG_HIPOX_VERSION_0X800
++ 1); // Compute checksum
++#else // CONFIG_HIPOX_VERSION_0X800
++ 0);
++#endif // CONFIG_HIPOX_VERSION_0X800
++
++ // Using second DMA channel requested
++ hipox_dma_set_callback(channels[channel_number], dma_callback, HIPOX_DMA_CALLBACK_ARG_NUL);
++
++ // Start the transfer
++ printk("Starting the transfer\n");
++ hipox_dma_start(channels[channel_number]);
++
++ // Sleep until transfer completed
++ printk("Waiting for transfer to complete...\n");
++ while (down_interruptible(&callback_semaphore));
++ hipox_dma_set_callback(channels[channel_number], HIPOX_DMA_CALLBACK_NUL, HIPOX_DMA_CALLBACK_ARG_NUL);
++
++ printk("Error code = %u\n", channels[channel_number]->error_code_);
++
++ // Release the consistent DMA mappings for the source buffers
++ for (i=0; i < 2; i++) {
++ // Ensure the checksum enabling high order address bit is not set, as
++ // this would confuse the DMA mapping release function
++ src_scatterlist[i].dma_address &= ~(1UL << HIPOX_DMA_CSUM_ENABLE_ADR_BIT);
++ dma_unmap_single(0, src_scatterlist[i].dma_address, src_scatterlist[i].length, DMA_TO_DEVICE);
++ }
++
++ // Release the consistent DMA mappings for the destination buffers
++ for (i=0; i < num_dst_buffers; i++) {
++ printk("Releasing DMA mappings for destination entry buffer %u\n", i);
++ dma_unmap_single(0, dst_scatterlist[i].dma_address, dst_scatterlist[i].length, DMA_BIDIRECTIONAL);
++ }
++
++ u32 sw_csum = 0;
++ //sw_csum = csum_partial((u8*)src_scatterlist[0].offset, src_scatterlist[0].length, 0);
++ sw_csum = csum_partial((u8*)src_scatterlist[1].offset, src_scatterlist[1].length, sw_csum);
++ printk("S/W generated src csum = 0x%04hx\n", csum_fold(sw_csum));
++
++ sw_csum = 0;
++ unsigned offset = src_scatterlist[0].length;
++ //unsigned offset = 0;
++ for (i=0; i < num_dst_buffers; i++) {
++ sw_csum = csum_partial((u8*)dst_scatterlist[i].offset + offset, dst_scatterlist[i].length - offset, sw_csum);
++ offset = 0;
++ }
++ printk("S/W generated dst csum = 0x%04hx\n", csum_fold(sw_csum));
++ }
++
++ for (i=0; i < num_dst_buffers; ++i) {
++ kfree((void*)dst_scatterlist[i].offset);
++ }
++ kfree(dst_scatterlist);
++
++ kfree((void*)(src_scatterlist[0].offset - src_offset));
++ kfree(src_scatterlist);
++ }
++
++ for (i=0; i < MAX_HIPOX_DMA_CHANNELS; ++i) {
++ hipox_dma_free(channels[i]);
++ }
++}
++#endif // HIPOX_DMA_SG_TEST_2
++#endif // defined(HIPOX_DMA_TEST) || defined(HIPOX_DMA_SG_TEST)
++
++EXPORT_SYMBOL(hipox_dma_request);
++EXPORT_SYMBOL(hipox_dma_free);
++EXPORT_SYMBOL(hipox_dma_set_callback);
++EXPORT_SYMBOL(hipox_dma_set_common);
++EXPORT_SYMBOL(hipox_dma_is_active);
++EXPORT_SYMBOL(hipox_dma_raw_isactive);
++EXPORT_SYMBOL(hipox_dma_set);
++EXPORT_SYMBOL(hipox_dma_device_set);
++EXPORT_SYMBOL(hipox_dma_abort);
++EXPORT_SYMBOL(hipox_dma_dump_registers);
++EXPORT_SYMBOL(hipox_dma_dump_registers_single);
++EXPORT_SYMBOL(hipox_dma_start);
++
++EXPORT_SYMBOL(hipox_pata_dma_settings);
++EXPORT_SYMBOL(hipox_sata_dma_settings);
++EXPORT_SYMBOL(hipox_dpe_rx_dma_settings);
++EXPORT_SYMBOL(hipox_dpe_tx_dma_settings);
+diff -Nurd linux-2.6.24/arch/arm/mach-hipox/dpe_test.c linux-2.6.24-oxe810/arch/arm/mach-hipox/dpe_test.c
+--- linux-2.6.24/arch/arm/mach-hipox/dpe_test.c 1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.24-oxe810/arch/arm/mach-hipox/dpe_test.c 2008-06-11 17:47:55.000000000 +0200
+@@ -0,0 +1,3051 @@
++/*
++ * /arch/=arm/mach-hipox/dpe-test.c
++ *
++ * Copyright (C) 2005 Oxford Semiconductor Ltd
++ *
++ * 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
++ */
++
++/**
++ * Test driver for the cipher core
++ *
++ */
++
++#include <linux/types.h>
++#include <linux/sched.h>
++#include <linux/interrupt.h>
++#include <linux/types.h>
++#include <linux/kernel.h>
++#include <linux/init.h>
++#include <linux/list.h>
++#include <linux/device.h>
++#include <linux/string.h>
++#include <linux/sysdev.h>
++#include <linux/fs.h>
++#include <asm/arch/cipher.h>
++#include <asm/io.h>
++#include <asm/arch/hardware.h>
++#include <linux/dma-mapping.h>
++#include <asm/arch/dma.h>
++
++/***************************************************************************
++* CONSTANTS
++***************************************************************************/
++#define DRIVER_AUTHOR "Oxford Semiconductor Inc."
++#define DRIVER_DESC "Cipher block testing"
++MODULE_LICENSE("GPL");
++MODULE_AUTHOR(DRIVER_AUTHOR);
++MODULE_DESCRIPTION(DRIVER_DESC);
++
++// uses /dev/dv940led
++#define DEVICE_NAME "ox800dpetst"
++MODULE_SUPPORTED_DEVICE(DEVICE_NAME);
++
++#define FAILED(reason) {printk(KERN_ERR"%s failed %s\n",__FUNCTION__,reason);++failed;}
++/**************************************************************************
++* PROTOTYPES
++**************************************************************************/
++#if 0
++static u32 READL(int a) {u32 v = readl(a);printk("0x%08x <- [0x%08x]\n",v,a);return v;}
++static void WRITEL(int v,int a){printk("0x%08x -> [0x%08x]\n",v,a);writel(v,a);}
++#else
++static u32 READL(int a) {u32 v = readl(a);return v;}
++static void WRITEL(int v,int a){writel(v,a);}
++#endif
++/**************************************************************************
++* STRUCTURES
++**************************************************************************/
++typedef int (ox800dpe_test_t)(void) ;
++
++/**************************************************************************
++* FUCTIONS
++* prefix all with "ox800dpe"
++**************************************************************************/
++
++/*************************************************************************/
++static int test1(void) {
++ int failed = 0;
++ u32 reg;
++
++ // authenticate
++ WRITEL(OX800IBW_STAT_AUTHENTICATED ,OX800IBW_STATUS);
++
++ // toggle cleardown bit to start
++ WRITEL(OX800DPE_CTL_ABORT ,OX800DPE_CONTROL);
++ WRITEL(0 ,OX800DPE_CONTROL);
++
++
++ // shouldn't be busy or full
++ reg = READL( OX800DPE_STATUS );
++ if (! (reg & OX800DPE_STAT_IDLE) )
++ FAILED("not idle after abort toggle");
++ if (reg & OX800DPE_STAT_TX_NOTEMPTY)
++ FAILED("tx fifo not empty after abort toggle");
++ if (! (reg & OX800DPE_STAT_RX_SPACE) )
++ FAILED("rx not empty after abort toggle");
++
++ // setup for encryption
++ reg = OX800DPE_CTL_DIRECTION_ENC | OX800DPE_CTL_MODE_ECB_AES;
++ WRITEL(reg ,OX800DPE_CONTROL);
++
++ reg = READL( OX800DPE_STATUS );
++ // shouldn't be busy
++ if (! (reg & OX800DPE_STAT_IDLE) )
++ FAILED("not idle even with incomplete data");
++ if (reg & OX800DPE_STAT_TX_NOTEMPTY)
++ FAILED("tx not empty before data input ");
++ if (! (reg & OX800DPE_STAT_RX_SPACE) )
++ FAILED("rx fifo filling without data");
++
++
++ // key no 1
++ WRITEL(be32_to_cpu( 0x00010203), OX800DPE_KEY00 );
++ WRITEL(be32_to_cpu( 0x04050607), OX800DPE_KEY01 );
++ WRITEL(be32_to_cpu( 0x08090a0b), OX800DPE_KEY02 );
++ WRITEL(be32_to_cpu( 0x0c0d0e0f), OX800DPE_KEY03 );
++
++ /* wait until done */
++ while( !(OX800DPE_STAT_IDLE & READL( OX800DPE_STATUS )) );
++
++ // 1st data set
++ WRITEL(be32_to_cpu( 0x00112233), OX800DPE_DATA_IN0 );
++
++ /* in fifo no longer empty */
++ reg = READL( OX800DPE_STATUS );
++ if ( (reg & OX800DPE_STAT_RX_SPACE) )
++ FAILED("rx fifo still empty after data input")
++
++ WRITEL(be32_to_cpu( 0x44556677), OX800DPE_DATA_IN1 );
++ WRITEL(be32_to_cpu( 0x8899aabb), OX800DPE_DATA_IN2 );
++
++ // shouldn't be busy as not enough data
++ reg = READL( OX800DPE_STATUS );
++ if (! (reg & OX800DPE_STAT_IDLE) )
++ FAILED("core lept into action before putting in all the data");
++
++ WRITEL(be32_to_cpu( 0xccddeeff), OX800DPE_DATA_IN3 );
++
++ /* wait until done */
++ while( !(OX800DPE_STAT_IDLE & READL( OX800DPE_STATUS )) );
++
++ reg = READL( OX800DPE_STATUS );
++
++ /* output should be full */
++ if ( !(reg & OX800DPE_STAT_TX_NOTEMPTY) )
++ FAILED("tx still empty after encrypting data ");
++
++ /* in empty */
++ if (! (reg & OX800DPE_STAT_RX_SPACE) )
++ FAILED("rx still full after encrypting data ");
++
++ /* check output */
++ {
++ u32 data[4];
++
++ data[0] = READL( OX800DPE_DATA_OUT0 );
++ data[1] = READL( OX800DPE_DATA_OUT1 );
++ data[2] = READL( OX800DPE_DATA_OUT2 );
++ data[3] = READL( OX800DPE_DATA_OUT3 );
++
++ if ((data[0] != cpu_to_be32(0x69c4e0d8)) ||
++ (data[1] != cpu_to_be32(0x6a7b0430)) ||
++ (data[2] != cpu_to_be32(0xd8cdb780)) ||
++ (data[3] != cpu_to_be32(0x70b4c55a)))
++ {
++ FAILED("encryption output incorrect");
++ printk("%08x%08x%08x%08x\n",data[0],data[1],data[2],data[3]);
++ }
++ }
++
++ /* output should be empty again */
++ reg = READL( OX800DPE_STATUS );
++ if ( (reg & OX800DPE_STAT_TX_NOTEMPTY) )
++ FAILED("tx still full after data read");
++
++ return failed;
++
++}
++
++/*************************************************************************/
++static int test2(void) {
++ int failed = 0;
++ u32 reg;
++ hipox_dma_channel_t* dma_in;
++ hipox_dma_channel_t* dma_out;
++ dma_addr_t in_address;
++ dma_addr_t out_address;
++
++ u32* data_in;
++ u32* data_out;
++
++ // setup dmas
++ dma_in = hipox_dma_request(1);
++ dma_out = hipox_dma_request(1);
++
++ // get some dma accessable memory
++ data_in = (u32*)kmalloc( 4 * sizeof(u32), GFP_KERNEL|GFP_DMA);
++ data_out = (u32*)kmalloc( 4 * sizeof(u32), GFP_KERNEL|GFP_DMA);
++
++ // fill with input and non expected output
++ data_in[0] = be32_to_cpu( 0x00112233);
++ data_in[1] = be32_to_cpu( 0x44556677);
++ data_in[2] = be32_to_cpu( 0x8899aabb);
++ data_in[3] = be32_to_cpu( 0xccddeeff);
++ data_out[0] = ~0;
++ data_out[1] = ~0;
++ data_out[2] = ~0;
++ data_out[3] = ~0;
++
++ // map the dma regons
++ in_address = dma_map_single(
++ 0,
++ data_in,
++ 4 * sizeof(u32),
++ DMA_TO_DEVICE);
++
++ // map the dma regons
++ out_address = dma_map_single(
++ 0,
++ data_out,
++ 4 * sizeof(u32),
++ DMA_FROM_DEVICE);
++
++ // setup the transfers
++ hipox_dma_device_set(
++ dma_in,
++ HIPOX_DMA_TO_DEVICE,
++ (char*)in_address,
++ 4 * sizeof(u32),
++ &hipox_dpe_rx_dma_settings,
++ HIPOX_DMA_MODE_INC, 1);
++
++ hipox_dma_device_set(
++ dma_out,
++ HIPOX_DMA_FROM_DEVICE,
++ (char*)out_address,
++ 4 * sizeof(u32),
++ &hipox_dpe_tx_dma_settings,
++ HIPOX_DMA_MODE_INC, 1);
++
++ // don't authenticate
++ WRITEL(0 ,OX800IBW_STATUS);
++
++ // toggle cleardown bit to start
++ WRITEL(OX800DPE_CTL_ABORT ,OX800DPE_CONTROL);
++ WRITEL(0 ,OX800DPE_CONTROL);
++
++
++ // shouldn't be busy or full
++ reg = READL( OX800DPE_STATUS );
++ if (! (reg & OX800DPE_STAT_IDLE) )
++ FAILED("not idle after abort toggle");
++ if (reg & OX800DPE_STAT_TX_NOTEMPTY)
++ FAILED("tx fifo not empty after abort toggle");
++ if (! (reg & OX800DPE_STAT_RX_SPACE) )
++ FAILED("rx not empty after abort toggle");
++
++ // setup for encryption
++ reg = OX800DPE_CTL_DIRECTION_ENC | OX800DPE_CTL_MODE_ECB_AES;
++ WRITEL(reg ,OX800DPE_CONTROL);
++
++ reg = READL( OX800DPE_STATUS );
++ // shouldn't be busy
++ if (! (reg & OX800DPE_STAT_IDLE) )
++ FAILED("not idle even with incomplete data");
++ if (reg & OX800DPE_STAT_TX_NOTEMPTY)
++ FAILED("tx not empty before data input ");
++ if (! (reg & OX800DPE_STAT_RX_SPACE) )
++ FAILED("rx fifo filling without data");
++
++
++ // key no 1
++ WRITEL(be32_to_cpu( 0x00010203), OX800DPE_KEY00 );
++ WRITEL(be32_to_cpu( 0x04050607), OX800DPE_KEY01 );
++ WRITEL(be32_to_cpu( 0x08090a0b), OX800DPE_KEY02 );
++ WRITEL(be32_to_cpu( 0x0c0d0e0f), OX800DPE_KEY03 );
++
++ /* wait until done */
++ while( !(OX800DPE_STAT_IDLE & READL( OX800DPE_STATUS )) );
++
++ // start dma transfers
++ hipox_dma_start(dma_out);
++ hipox_dma_start(dma_in);
++
++ /* wait until done */
++ while( hipox_dma_is_active( dma_out ) );
++
++ reg = READL( OX800DPE_STATUS );
++
++ /* output should be empty */
++ if ( (reg & OX800DPE_STAT_TX_NOTEMPTY) )
++ FAILED("tx still full after fetching ");
++
++ /* in empty */
++ if (! (reg & OX800DPE_STAT_RX_SPACE) )
++ FAILED("rx still full after encrypting data ");
++
++ dma_unmap_single(0, in_address, 4 * sizeof(u32), DMA_TO_DEVICE);
++ dma_unmap_single(0, out_address, 4 * sizeof(u32), DMA_FROM_DEVICE);
++
++ /* check output */
++ if ((data_out[0] != cpu_to_be32(0x69c4e0d8)) ||
++ (data_out[1] != cpu_to_be32(0x6a7b0430)) ||
++ (data_out[2] != cpu_to_be32(0xd8cdb780)) ||
++ (data_out[3] != cpu_to_be32(0x70b4c55a)))
++ {
++ FAILED("encryption output incorrect");
++ printk("%08x%08x%08x%08x\n",data_out[0],data_out[1],data_out[2],data_out[3]);
++ }
++
++ // free dmas
++ hipox_dma_free( dma_in );
++ hipox_dma_free( dma_out );
++
++ kfree(data_in);
++ kfree(data_out);
++
++ return failed;
++
++}
++
++
++/*************************************************************************/
++static int test3(void) {
++ int failed = 0;
++ u32 reg;
++ hipox_dma_channel_t* dma_in;
++ hipox_dma_channel_t* dma_out;
++ dma_addr_t in_address;
++ dma_addr_t out_address;
++
++ u32* data_in;
++ u32* data_out;
++
++ // setup dmas
++ dma_in = hipox_dma_request(1);
++ dma_out = hipox_dma_request(1);
++
++ // get some dma accessable memory
++ data_in = (u32*)kmalloc( 4 * sizeof(u32), GFP_KERNEL|GFP_DMA);
++ data_out = (u32*)kmalloc( 4 * sizeof(u32), GFP_KERNEL|GFP_DMA);
++
++ // fill with input and non expected output
++ data_in[0] = be32_to_cpu( 0x69c4e0d8);
++ data_in[1] = be32_to_cpu( 0x6a7b0430);
++ data_in[2] = be32_to_cpu( 0xd8cdb780);
++ data_in[3] = be32_to_cpu( 0x70b4c55a);
++ data_out[0] = ~0;
++ data_out[1] = ~0;
++ data_out[2] = ~0;
++ data_out[3] = ~0;
++
++ // map the dma regons
++ in_address = dma_map_single(
++ 0,
++ data_in,
++ 4 * sizeof(u32),
++ DMA_TO_DEVICE);
++
++ // map the dma regons
++ out_address = dma_map_single(
++ 0,
++ data_out,
++ 4 * sizeof(u32),
++ DMA_FROM_DEVICE);
++
++ // setup the transfers
++ hipox_dma_device_set(
++ dma_in,
++ HIPOX_DMA_TO_DEVICE,
++ (char*)in_address,
++ 4 * sizeof(u32),
++ &hipox_dpe_rx_dma_settings,
++ HIPOX_DMA_MODE_INC, 1);
++
++ hipox_dma_device_set(
++ dma_out,
++ HIPOX_DMA_FROM_DEVICE,
++ (char*)out_address,
++ 4 * sizeof(u32),
++ &hipox_dpe_tx_dma_settings,
++ HIPOX_DMA_MODE_INC, 1);
++
++ // authenticate
++ WRITEL(OX800IBW_STAT_AUTHENTICATED ,OX800IBW_STATUS);
++
++ // toggle cleardown bit to start
++ WRITEL(OX800DPE_CTL_ABORT ,OX800DPE_CONTROL);
++ WRITEL(0 ,OX800DPE_CONTROL);
++
++
++ // shouldn't be busy or full
++ reg = READL( OX800DPE_STATUS );
++ if (! (reg & OX800DPE_STAT_IDLE) )
++ FAILED("not idle after abort toggle");
++ if (reg & OX800DPE_STAT_TX_NOTEMPTY)
++ FAILED("tx fifo not empty after abort toggle");
++ if (! (reg & OX800DPE_STAT_RX_SPACE) )
++ FAILED("rx not empty after abort toggle");
++
++ // setup for decryption
++ reg = OX800DPE_CTL_MODE_ECB_AES;
++ WRITEL(reg ,OX800DPE_CONTROL);
++
++ reg = READL( OX800DPE_STATUS );
++ // shouldn't be busy
++ if (! (reg & OX800DPE_STAT_IDLE) )
++ FAILED("not idle even with incomplete data");
++ if (reg & OX800DPE_STAT_TX_NOTEMPTY)
++ FAILED("tx not empty before data input ");
++ if (! (reg & OX800DPE_STAT_RX_SPACE) )
++ FAILED("rx fifo filling without data");
++
++
++ // key no 1
++ WRITEL(be32_to_cpu( 0x00010203), OX800DPE_KEY00 );
++ WRITEL(be32_to_cpu( 0x04050607), OX800DPE_KEY01 );
++ WRITEL(be32_to_cpu( 0x08090a0b), OX800DPE_KEY02 );
++ WRITEL(be32_to_cpu( 0x0c0d0e0f), OX800DPE_KEY03 );
++
++ /* wait until done */
++ while( !(OX800DPE_STAT_IDLE & READL( OX800DPE_STATUS )) );
++
++ // start dma transfers
++ hipox_dma_start(dma_out);
++ hipox_dma_start(dma_in);
++
++ /* wait until dma done */
++ while( hipox_dma_is_active( dma_out ) );
++
++ reg = READL( OX800DPE_STATUS );
++
++ /* output should be empty */
++ if ( (reg & OX800DPE_STAT_TX_NOTEMPTY) )
++ FAILED("tx still full after fetching ");
++
++ /* in empty */
++ if (! (reg & OX800DPE_STAT_RX_SPACE) )
++ FAILED("rx still full after encrypting data ");
++
++ dma_unmap_single(0, in_address, 4 * sizeof(u32), DMA_TO_DEVICE);
++ dma_unmap_single(0, out_address, 4 * sizeof(u32), DMA_FROM_DEVICE);
++
++ /* check output */
++ if ((data_out[0] != cpu_to_be32(0x00112233)) ||
++ (data_out[1] != cpu_to_be32(0x44556677)) ||
++ (data_out[2] != cpu_to_be32(0x8899aabb)) ||
++ (data_out[3] != cpu_to_be32(0xccddeeff)))
++ {
++ FAILED("encryption output incorrect");
++ printk("%08x%08x%08x%08x\n",data_out[0],data_out[1],data_out[2],data_out[3]);
++ }
++
++ // free dmas
++ hipox_dma_free( dma_in );
++ hipox_dma_free( dma_out );
++
++ kfree(data_in);
++ kfree(data_out);
++
++ return failed;
++
++}
++
++/*************************************************************************/
++static int test4(void) {
++ int failed = 0;
++ u32 reg;
++ hipox_dma_channel_t* dma_out;
++ dma_addr_t out_address;
++
++ u32* data_out;
++
++ // setup dmas
++ dma_out = hipox_dma_request(1);
++
++ // get some dma accessable memory
++ data_out = (u32*)kmalloc( 4 * sizeof(u32), GFP_KERNEL|GFP_DMA);
++
++ // fill with non expected output
++ data_out[0] = ~0;
++ data_out[1] = ~0;
++ data_out[2] = ~0;
++ data_out[3] = ~0;
++
++ // map the dma regons
++ out_address = dma_map_single(
++ 0,
++ data_out,
++ 4 * sizeof(u32),
++ DMA_FROM_DEVICE);
++
++ hipox_dma_device_set(
++ dma_out,
++ HIPOX_DMA_FROM_DEVICE,
++ (char*)out_address,
++ 4 * sizeof(u32),
++ &hipox_dpe_tx_dma_settings,
++ HIPOX_DMA_MODE_INC, 1);
++
++ // toggle cleardown bit to start
++ WRITEL(OX800DPE_CTL_ABORT ,OX800DPE_CONTROL);
++ WRITEL(0 ,OX800DPE_CONTROL);
++
++ // don't authenticate
++ WRITEL(0 ,OX800IBW_STATUS);
++
++
++ // shouldn't be busy or full
++ reg = READL( OX800DPE_STATUS );
++ if (! (reg & OX800DPE_STAT_IDLE) )
++ FAILED("not idle after abort toggle");
++ if (reg & OX800DPE_STAT_TX_NOTEMPTY)
++ FAILED("tx fifo not empty after abort toggle");
++ if (! (reg & OX800DPE_STAT_RX_SPACE) )
++ FAILED("rx not empty after abort toggle");
++
++ // setup for decryption
++ reg = OX800DPE_CTL_PRIMARY_IS_KEY3 | OX800DPE_CTL_MODE_ECB_AES;
++ WRITEL(reg ,OX800DPE_CONTROL);
++
++ reg = READL( OX800DPE_STATUS );
++ // shouldn't be busy
++ if (! (reg & OX800DPE_STAT_IDLE) )
++ FAILED("not idle even with incomplete data");
++ if (reg & OX800DPE_STAT_TX_NOTEMPTY)
++ FAILED("tx not empty before data input ");
++ if (! (reg & OX800DPE_STAT_RX_SPACE) )
++ FAILED("rx fifo filling without data");
++
++
++ // key no 1
++ WRITEL(be32_to_cpu( 0x00010203), OX800DPE_KEY20 );
++ WRITEL(be32_to_cpu( 0x04050607), OX800DPE_KEY21 );
++ WRITEL(be32_to_cpu( 0x08090a0b), OX800DPE_KEY22 );
++ WRITEL(be32_to_cpu( 0x0c0d0e0f), OX800DPE_KEY23 );
++
++ /* wait until done */
++ while( !(OX800DPE_STAT_IDLE & READL( OX800DPE_STATUS )) );
++
++ // start dma transfers
++ hipox_dma_start(dma_out);
++
++ // 1st data set
++ WRITEL(be32_to_cpu( 0x69c4e0d8), OX800DPE_DATA_IN0 );
++ WRITEL(be32_to_cpu( 0x6a7b0430), OX800DPE_DATA_IN1 );
++ WRITEL(be32_to_cpu( 0xd8cdb780), OX800DPE_DATA_IN2 );
++ WRITEL(be32_to_cpu( 0x70b4c55a), OX800DPE_DATA_IN3 );
++
++ /* wait until done */
++ while( hipox_dma_is_active( dma_out ) );
++
++ reg = READL( OX800DPE_STATUS );
++
++ /* output should be empty */
++ if ( (reg & OX800DPE_STAT_TX_NOTEMPTY) )
++ FAILED("tx still full after fetching ");
++
++ /* in empty */
++ if (! (reg & OX800DPE_STAT_RX_SPACE) )
++ FAILED("rx still full after encrypting data ");
++
++
++ dma_unmap_single(0, out_address, 4 * sizeof(u32), DMA_FROM_DEVICE);
++
++ /* check output */
++ if ((data_out[0] != cpu_to_be32(0x00112233)) ||
++ (data_out[1] != cpu_to_be32(0x44556677)) ||
++ (data_out[2] != cpu_to_be32(0x8899aabb)) ||
++ (data_out[3] != cpu_to_be32(0xccddeeff)))
++ {
++ FAILED("encryption output incorrect");
++ printk("%08x%08x%08x%08x\n",data_out[0],data_out[1],data_out[2],data_out[3]);
++ }
++
++ // free dmas
++ hipox_dma_free( dma_out );
++ kfree(data_out);
++
++ return failed;
++
++}
++
++/*************************************************************************/
++static int test5(void) {
++ int failed = 0;
++ u32 reg;
++ hipox_dma_channel_t* dma_in;
++ dma_addr_t in_address;
++
++ u32* data_in;
++
++ // setup dmas
++ dma_in = hipox_dma_request(1);
++
++ // get some dma accessable memory
++ data_in = (u32*)kmalloc( 4 * sizeof(u32), GFP_KERNEL|GFP_DMA);
++
++ // fill with input and non expected output
++ data_in[0] = be32_to_cpu( 0x00112233);
++ data_in[1] = be32_to_cpu( 0x44556677);
++ data_in[2] = be32_to_cpu( 0x8899aabb);
++ data_in[3] = be32_to_cpu( 0xccddeeff);
++
++ // map the dma regons
++ in_address = dma_map_single(
++ 0,
++ data_in,
++ 4 * sizeof(u32),
++ DMA_TO_DEVICE);
++
++ // setup the transfers
++ hipox_dma_device_set(
++ dma_in,
++ HIPOX_DMA_TO_DEVICE,
++ (char*)in_address,
++ 4 * sizeof(u32),
++ &hipox_dpe_rx_dma_settings,
++ HIPOX_DMA_MODE_INC, 1);
++
++ // toggle cleardown bit to start
++ WRITEL(OX800DPE_CTL_ABORT ,OX800DPE_CONTROL);
++ WRITEL(0 ,OX800DPE_CONTROL);
++
++ // don't authenticate
++ WRITEL(0 ,OX800IBW_STATUS);
++
++
++ // shouldn't be busy or full
++ reg = READL( OX800DPE_STATUS );
++ if (! (reg & OX800DPE_STAT_IDLE) )
++ FAILED("not idle after abort toggle");
++ if (reg & OX800DPE_STAT_TX_NOTEMPTY)
++ FAILED("tx fifo not empty after abort toggle");
++ if (! (reg & OX800DPE_STAT_RX_SPACE) )
++ FAILED("rx not empty after abort toggle");
++
++ // setup for encryption
++ reg = OX800DPE_CTL_DIRECTION_ENC |
++ OX800DPE_CTL_MODE_ECB_AES |
++ OX800DPE_CTL_PRIMARY_IS_KEY3 ;
++ WRITEL(reg ,OX800DPE_CONTROL);
++
++ reg = READL( OX800DPE_STATUS );
++ // shouldn't be busy
++ if (! (reg & OX800DPE_STAT_IDLE) )
++ FAILED("not idle even with incomplete data");
++ if (reg & OX800DPE_STAT_TX_NOTEMPTY)
++ FAILED("tx not empty before data input ");
++ if (! (reg & OX800DPE_STAT_RX_SPACE) )
++ FAILED("rx fifo filling without data");
++
++
++ // key no 1
++ WRITEL(be32_to_cpu( 0x00010203), OX800DPE_KEY20 );
++ WRITEL(be32_to_cpu( 0x04050607), OX800DPE_KEY21 );
++ WRITEL(be32_to_cpu( 0x08090a0b), OX800DPE_KEY22 );
++ WRITEL(be32_to_cpu( 0x0c0d0e0f), OX800DPE_KEY23 );
++
++ /* wait until done */
++ while( !(OX800DPE_STAT_IDLE & READL( OX800DPE_STATUS )) );
++
++ // start dma transfers
++ hipox_dma_start(dma_in);
++
++ /* wait until done */
++ while( hipox_dma_is_active( dma_in ) );
++ while( !(OX800DPE_STAT_IDLE & READL( OX800DPE_STATUS )) );
++
++ reg = READL( OX800DPE_STATUS );
++
++ /* output should be full */
++ if ( !(reg & OX800DPE_STAT_TX_NOTEMPTY) )
++ FAILED("tx still empty after encrypting data ");
++
++ /* in empty */
++ if (! (reg & OX800DPE_STAT_RX_SPACE) )
++ FAILED("rx still full after encrypting data ");
++
++ dma_unmap_single(0, in_address, 4 * sizeof(u32), DMA_TO_DEVICE);
++
++ /* check output */
++ {
++ u32 data[4];
++
++ data[0] = READL( OX800DPE_DATA_OUT0 );
++ data[1] = READL( OX800DPE_DATA_OUT1 );
++ data[2] = READL( OX800DPE_DATA_OUT2 );
++ data[3] = READL( OX800DPE_DATA_OUT3 );
++
++ if ((data[0] != cpu_to_be32(0x69c4e0d8)) ||
++ (data[1] != cpu_to_be32(0x6a7b0430)) ||
++ (data[2] != cpu_to_be32(0xd8cdb780)) ||
++ (data[3] != cpu_to_be32(0x70b4c55a)))
++ {
++ FAILED("encryption output incorrect");
++ printk("%08x%08x%08x%08x\n",data[0],data[1],data[2],data[3]);
++ }
++ }
++
++ /* output should be empty again */
++ reg = READL( OX800DPE_STATUS );
++ if ( (reg & OX800DPE_STAT_TX_NOTEMPTY) )
++ FAILED("tx still full after data read");
++
++ // free dmas
++ kfree(data_in);
++
++ hipox_dma_free( dma_in );
++
++ return failed;
++
++}
++
++/*************************************************************************/
++static int test6(void) {
++ int failed = 0;
++ u32 reg;
++
++ // toggle cleardown bit to start
++ WRITEL(OX800DPE_CTL_ABORT ,OX800DPE_CONTROL);
++ WRITEL(0 ,OX800DPE_CONTROL);
++
++ // don't authenticate
++ WRITEL(0 ,OX800IBW_STATUS);
++
++ // shouldn't be busy or full
++ reg = READL( OX800DPE_STATUS );
++ if (! (reg & OX800DPE_STAT_IDLE) )
++ FAILED("not idle after abort toggle");
++ if (reg & OX800DPE_STAT_TX_NOTEMPTY)
++ FAILED("tx fifo not empty after abort toggle");
++ if (! (reg & OX800DPE_STAT_RX_SPACE) )
++ FAILED("rx not empty after abort toggle");
++
++ // setup for key encryption
++ reg = OX800DPE_CTL_DIRECTION_ENC |
++ OX800DPE_CTL_ENCRYPT_KEY |
++ OX800DPE_CTL_MODE_ECB_AES;
++ WRITEL(reg ,OX800DPE_CONTROL);
++
++ reg = READL( OX800DPE_STATUS );
++
++ // shouldn't be busy
++ if (! (reg & OX800DPE_STAT_IDLE) )
++ FAILED("not idle even with incomplete data");
++ if (reg & OX800DPE_STAT_TX_NOTEMPTY)
++ FAILED("tx not empty before data input ");
++ if (! (reg & OX800DPE_STAT_RX_SPACE) )
++ FAILED("rx fifo filling without data");
++
++ // data to be encrypted to form a key
++ WRITEL(be32_to_cpu( 0x00010203), OX800DPE_DATA_IN0 );
++ WRITEL(be32_to_cpu( 0x04050607), OX800DPE_DATA_IN1 );
++ WRITEL(be32_to_cpu( 0x08090a0b), OX800DPE_DATA_IN2 );
++ WRITEL(be32_to_cpu( 0x0c0d0e0f), OX800DPE_DATA_IN3 );
++
++ /* wait until done */
++ while( !(OX800DPE_STAT_IDLE & READL( OX800DPE_STATUS )) );
++
++ /* output should be empty */
++ reg = READL( OX800DPE_STATUS );
++ if ( (reg & OX800DPE_STAT_TX_NOTEMPTY) )
++ FAILED("tx still full after fetching ");
++
++ /* in empty */
++ if (! (reg & OX800DPE_STAT_RX_SPACE) )
++ FAILED("rx still full after encrypting data ");
++
++ {
++ u32 data[4];
++
++ data[0] = READL( OX800DPE_KEY00 );
++ data[1] = READL( OX800DPE_KEY01 );
++ data[2] = READL( OX800DPE_KEY02 );
++ data[3] = READL( OX800DPE_KEY03 );
++
++ if ((data[0] != cpu_to_be32(0x4791b833)) ||
++ (data[1] != cpu_to_be32(0x7e2d8a69)) ||
++ (data[2] != cpu_to_be32(0x290233f1)) ||
++ (data[3] != cpu_to_be32(0xf3dff5a9)))
++ {
++ FAILED("encrypted key incorrect");
++ printk("%08x%08x%08x%08x\n",data[0],data[1],data[2],data[3]);
++ }
++ }
++
++ return failed;
++
++}
++
++
++/*************************************************************************/
++static int test7(void) {
++ int failed = 0;
++ u32 reg;
++
++ // toggle cleardown bit to start
++ WRITEL(OX800DPE_CTL_ABORT ,OX800DPE_CONTROL);
++ WRITEL(0 ,OX800DPE_CONTROL);
++
++ // shouldn't be busy or full
++ reg = READL( OX800DPE_STATUS );
++ if (! (reg & OX800DPE_STAT_IDLE) )
++ FAILED("not idle after abort toggle");
++ if (reg & OX800DPE_STAT_TX_NOTEMPTY)
++ FAILED("tx fifo not empty after abort toggle");
++ if (! (reg & OX800DPE_STAT_RX_SPACE) )
++ FAILED("rx not empty after abort toggle");
++
++ // authenticate
++ WRITEL(OX800IBW_STAT_AUTHENTICATED ,OX800IBW_STATUS);
++
++ // setup for key encryption
++ reg = OX800DPE_CTL_DIRECTION_ENC |
++ OX800DPE_CTL_ENCRYPT_KEY |
++ OX800DPE_CTL_MODE_ECB_AES;
++ WRITEL(reg ,OX800DPE_CONTROL);
++
++ reg = READL( OX800DPE_STATUS );
++
++ // shouldn't be busy
++ if (! (reg & OX800DPE_STAT_IDLE) )
++ FAILED("not idle even with incomplete data");
++ if (reg & OX800DPE_STAT_TX_NOTEMPTY)
++ FAILED("tx not empty before data input ");
++ if (! (reg & OX800DPE_STAT_RX_SPACE) )
++ FAILED("rx fifo filling without data");
++
++ // data to be encrypted to form a key
++ WRITEL(be32_to_cpu( 0x00010203), OX800DPE_DATA_IN0 );
++ WRITEL(be32_to_cpu( 0x04050607), OX800DPE_DATA_IN1 );
++ WRITEL(be32_to_cpu( 0x08090a0b), OX800DPE_DATA_IN2 );
++ WRITEL(be32_to_cpu( 0x0c0d0e0f), OX800DPE_DATA_IN3 );
++
++ /* wait until done */
++ while( !(OX800DPE_STAT_IDLE & READL( OX800DPE_STATUS )) );
++
++ /* output should be empty */
++ reg = READL( OX800DPE_STATUS );
++ if ( (reg & OX800DPE_STAT_TX_NOTEMPTY) )
++ FAILED("tx still full after fetching ");
++
++ /* in empty */
++ if (! (reg & OX800DPE_STAT_RX_SPACE) )
++ FAILED("rx still full after encrypting data ");
++
++ {
++ u32 data[4];
++
++ data[0] = READL( OX800DPE_KEY00 );
++ data[1] = READL( OX800DPE_KEY01 );
++ data[2] = READL( OX800DPE_KEY02 );
++ data[3] = READL( OX800DPE_KEY03 );
++
++ if ((data[0] != cpu_to_be32(0x4791b833)) ||
++ (data[1] != cpu_to_be32(0x7e2d8a69)) ||
++ (data[2] != cpu_to_be32(0x290233f1)) ||
++ (data[3] != cpu_to_be32(0xf3dff5a9)))
++ {
++ FAILED("encrypted key incorrect");
++ printk("%08x%08x%08x%08x\n",data[0],data[1],data[2],data[3]);
++ }
++ }
++
++ return failed;
++
++}
++
++
++
++/**********************************************************************/
++/* CBC tests */
++/**********************************************************************/
++
++static int test8(void) {
++ int failed = 0;
++ u32 reg;
++ hipox_dma_channel_t* dma_in;
++ hipox_dma_channel_t* dma_out;
++ dma_addr_t in_address;
++ dma_addr_t out_address;
++
++ u32* data_in;
++ u32* data_out;
++
++ // setup dmas
++ dma_in = hipox_dma_request(1);
++ dma_out = hipox_dma_request(1);
++
++ // get some dma accessable memory
++ data_in = (u32*)kmalloc( 8 * sizeof(u32), GFP_KERNEL|GFP_DMA);
++ data_out = (u32*)kmalloc( 8 * sizeof(u32), GFP_KERNEL|GFP_DMA);
++
++ // fill with input and non expected output
++ data_in[0] = be32_to_cpu( 0x00112233);
++ data_in[1] = be32_to_cpu( 0x44556677);
++ data_in[2] = be32_to_cpu( 0x8899aabb);
++ data_in[3] = be32_to_cpu( 0xccddeeff);
++ data_in[4] = be32_to_cpu( 0x00112233);
++ data_in[5] = be32_to_cpu( 0x44556677);
++ data_in[6] = be32_to_cpu( 0x8899aabb);
++ data_in[7] = be32_to_cpu( 0xccddeeff);
++ data_out[0] = ~0;
++ data_out[1] = ~0;
++ data_out[2] = ~0;
++ data_out[3] = ~0;
++ data_out[4] = ~0;
++ data_out[5] = ~0;
++ data_out[6] = ~0;
++ data_out[7] = ~0;
++
++ // map the dma regons
++ in_address = dma_map_single(
++ 0,
++ data_in,
++ 8 * sizeof(u32),
++ DMA_TO_DEVICE);
++
++ // map the dma regons
++ out_address = dma_map_single(
++ 0,
++ data_out,
++ 8 * sizeof(u32),
++ DMA_FROM_DEVICE);
++
++ // setup the transfers
++ hipox_dma_device_set(
++ dma_in,
++ HIPOX_DMA_TO_DEVICE,
++ (char*)in_address,
++ 8 * sizeof(u32),
++ &hipox_dpe_rx_dma_settings,
++ HIPOX_DMA_MODE_INC, 1);
++
++ hipox_dma_device_set(
++ dma_out,
++ HIPOX_DMA_FROM_DEVICE,
++ (char*)out_address,
++ 8 * sizeof(u32),
++ &hipox_dpe_tx_dma_settings,
++ HIPOX_DMA_MODE_INC, 1);
++
++ // toggle cleardown bit to start
++ WRITEL(OX800DPE_CTL_ABORT ,OX800DPE_CONTROL);
++ WRITEL(0 ,OX800DPE_CONTROL);
++
++ // don't authenticate
++ WRITEL(0 ,OX800IBW_STATUS);
++
++
++ // shouldn't be busy or full
++ reg = READL( OX800DPE_STATUS );
++ if (! (reg & OX800DPE_STAT_IDLE) )
++ FAILED("not idle after abort toggle");
++ if (reg & OX800DPE_STAT_TX_NOTEMPTY)
++ FAILED("tx fifo not empty after abort toggle");
++ if (! (reg & OX800DPE_STAT_RX_SPACE) )
++ FAILED("rx not empty after abort toggle");
++
++ // setup for encryption
++ reg = OX800DPE_CTL_DIRECTION_ENC |
++ OX800DPE_CTL_MODE_CBC_AES;
++ WRITEL(reg ,OX800DPE_CONTROL);
++
++ reg = READL( OX800DPE_STATUS );
++ // shouldn't be busy
++ if (! (reg & OX800DPE_STAT_IDLE) )
++ FAILED("not idle even with incomplete data");
++ if (reg & OX800DPE_STAT_TX_NOTEMPTY)
++ FAILED("tx not empty before data input ");
++ if (! (reg & OX800DPE_STAT_RX_SPACE) )
++ FAILED("rx fifo filling without data");
++
++
++ // key no 1
++ WRITEL(be32_to_cpu( 0x00010203), OX800DPE_KEY00 );
++ WRITEL(be32_to_cpu( 0x04050607), OX800DPE_KEY01 );
++ WRITEL(be32_to_cpu( 0x08090a0b), OX800DPE_KEY02 );
++ WRITEL(be32_to_cpu( 0x0c0d0e0f), OX800DPE_KEY03 );
++
++ /* wait until done */
++ while( !(OX800DPE_STAT_IDLE & READL( OX800DPE_STATUS )) );
++
++ // setup initialisation vector
++ WRITEL(be32_to_cpu(0), OX800DPE_DATA_CBC0 );
++ WRITEL(be32_to_cpu(0), OX800DPE_DATA_CBC1 );
++
++ // start dma transfers
++ hipox_dma_start(dma_out);
++ hipox_dma_start(dma_in);
++
++ /* wait until dma done */
++ while( hipox_dma_is_active( dma_out ) );
++
++ reg = READL( OX800DPE_STATUS );
++
++ /* output should be empty */
++ if ( (reg & OX800DPE_STAT_TX_NOTEMPTY) )
++ FAILED("tx still full after fetching ");
++ /* in empty */
++ if (! (reg & OX800DPE_STAT_RX_SPACE) )
++ FAILED("rx still full after encrypting data ");
++
++ dma_unmap_single(0, in_address, 8 * sizeof(u32), DMA_TO_DEVICE);
++ dma_unmap_single(0, out_address, 8 * sizeof(u32), DMA_FROM_DEVICE);
++
++ /* check output */
++ if ((data_out[0] != cpu_to_be32(0x69c4e0d8)) ||
++ (data_out[1] != cpu_to_be32(0x6a7b0430)) ||
++ (data_out[2] != cpu_to_be32(0xd8cdb780)) ||
++ (data_out[3] != cpu_to_be32(0x70b4c55a)) ||
++
++ (data_out[4] != cpu_to_be32(0x7d7786be)) ||
++ (data_out[5] != cpu_to_be32(0x32d059a6)) ||
++ (data_out[6] != cpu_to_be32(0x0ca8021a)) ||
++ (data_out[7] != cpu_to_be32(0x65dd9f09)))
++ {
++ FAILED("encryption output incorrect");
++ printk("%08x%08x%08x%08x\n",data_out[0],data_out[1],data_out[2],data_out[3]);
++ printk("%08x%08x%08x%08x\n",data_out[4],data_out[5],data_out[6],data_out[7]);
++ }
++
++ // free dmas
++ hipox_dma_free( dma_in );
++ hipox_dma_free( dma_out );
++
++ kfree(data_in);
++ kfree(data_out);
++
++ return failed;
++
++}
++
++
++/*************************************************************************/
++static int test9(void) {
++ int failed = 0;
++ u32 reg;
++ hipox_dma_channel_t* dma_in;
++ hipox_dma_channel_t* dma_out;
++ dma_addr_t in_address;
++ dma_addr_t out_address;
++
++ u32* data_in;
++ u32* data_out;
++
++ // setup dmas
++ dma_in = hipox_dma_request(1);
++ dma_out = hipox_dma_request(1);
++
++ // get some dma accessable memory
++ data_in = (u32*)kmalloc( 8 * sizeof(u32), GFP_KERNEL|GFP_DMA);
++ data_out = (u32*)kmalloc( 8 * sizeof(u32), GFP_KERNEL|GFP_DMA);
++
++ // fill with input and non expected output
++ data_in[0] = be32_to_cpu( 0x69c4e0d8);
++ data_in[1] = be32_to_cpu( 0x6a7b0430);
++ data_in[2] = be32_to_cpu( 0xd8cdb780);
++ data_in[3] = be32_to_cpu( 0x70b4c55a);
++ data_in[4] = be32_to_cpu( 0x7d7786be);
++ data_in[5] = be32_to_cpu( 0x32d059a6);
++ data_in[6] = be32_to_cpu( 0x0ca8021a);
++ data_in[7] = be32_to_cpu( 0x65dd9f09);
++ data_out[0] = ~0;
++ data_out[1] = ~0;
++ data_out[2] = ~0;
++ data_out[3] = ~0;
++ data_out[4] = ~0;
++ data_out[5] = ~0;
++ data_out[6] = ~0;
++ data_out[7] = ~0;
++
++ // map the dma regons
++ in_address = dma_map_single(
++ 0,
++ data_in,
++ 8 * sizeof(u32),
++ DMA_TO_DEVICE);
++
++ // map the dma regons
++ out_address = dma_map_single(
++ 0,
++ data_out,
++ 8 * sizeof(u32),
++ DMA_FROM_DEVICE);
++
++ // setup the transfers
++ hipox_dma_device_set(
++ dma_in,
++ HIPOX_DMA_TO_DEVICE,
++ (char*)in_address,
++ 8 * sizeof(u32),
++ &hipox_dpe_rx_dma_settings,
++ HIPOX_DMA_MODE_INC, 1);
++
++ hipox_dma_device_set(
++ dma_out,
++ HIPOX_DMA_FROM_DEVICE,
++ (char*)out_address,
++ 8 * sizeof(u32),
++ &hipox_dpe_tx_dma_settings,
++ HIPOX_DMA_MODE_INC, 1);
++
++ // authenticate
++ WRITEL(OX800IBW_STAT_AUTHENTICATED ,OX800IBW_STATUS);
++
++ // toggle cleardown bit to start
++ WRITEL(OX800DPE_CTL_ABORT ,OX800DPE_CONTROL);
++ WRITEL(0 ,OX800DPE_CONTROL);
++
++
++ // shouldn't be busy or full
++ reg = READL( OX800DPE_STATUS );
++ if (! (reg & OX800DPE_STAT_IDLE) )
++ FAILED("not idle after abort toggle");
++ if (reg & OX800DPE_STAT_TX_NOTEMPTY)
++ FAILED("tx fifo not empty after abort toggle");
++ if (! (reg & OX800DPE_STAT_RX_SPACE) )
++ FAILED("rx not empty after abort toggle");
++
++ // setup for decryption
++ reg = OX800DPE_CTL_MODE_CBC_AES;
++ WRITEL(reg ,OX800DPE_CONTROL);
++
++ reg = READL( OX800DPE_STATUS );
++ // shouldn't be busy
++ if (! (reg & OX800DPE_STAT_IDLE) )
++ FAILED("not idle even with incomplete data");
++ if (reg & OX800DPE_STAT_TX_NOTEMPTY)
++ FAILED("tx not empty before data input ");
++ if (! (reg & OX800DPE_STAT_RX_SPACE) )
++ FAILED("rx fifo filling without data");
++
++
++ // key no 1
++ WRITEL(be32_to_cpu( 0x00010203), OX800DPE_KEY00 );
++ WRITEL(be32_to_cpu( 0x04050607), OX800DPE_KEY01 );
++ WRITEL(be32_to_cpu( 0x08090a0b), OX800DPE_KEY02 );
++ WRITEL(be32_to_cpu( 0x0c0d0e0f), OX800DPE_KEY03 );
++
++ /* wait until done */
++ while( !(OX800DPE_STAT_IDLE & READL( OX800DPE_STATUS )) );
++
++ // setup initialisation vector
++ WRITEL(be32_to_cpu(0), OX800DPE_DATA_CBC0 );
++ WRITEL(be32_to_cpu(0), OX800DPE_DATA_CBC1 );
++
++ // start dma transfers
++ hipox_dma_start(dma_out);
++ hipox_dma_start(dma_in);
++
++ /* wait until done */
++ while( hipox_dma_is_active( dma_out ) );
++
++ reg = READL( OX800DPE_STATUS );
++
++ /* output should be empty */
++ if ( (reg & OX800DPE_STAT_TX_NOTEMPTY) )
++ FAILED("tx still full after fetching ");
++
++ /* in empty */
++ if (! (reg & OX800DPE_STAT_RX_SPACE) )
++ FAILED("rx still full after encrypting data ");
++
++ dma_unmap_single(0, in_address, 8 * sizeof(u32), DMA_TO_DEVICE);
++ dma_unmap_single(0, out_address, 8 * sizeof(u32), DMA_FROM_DEVICE);
++
++ /* check output */
++ if ((data_out[0] != cpu_to_be32(0x00112233)) ||
++ (data_out[1] != cpu_to_be32(0x44556677)) ||
++ (data_out[2] != cpu_to_be32(0x8899aabb)) ||
++ (data_out[3] != cpu_to_be32(0xccddeeff)) ||
++ (data_out[4] != cpu_to_be32(0x00112233)) ||
++ (data_out[5] != cpu_to_be32(0x44556677)) ||
++ (data_out[6] != cpu_to_be32(0x8899aabb)) ||
++ (data_out[7] != cpu_to_be32(0xccddeeff)))
++ {
++ FAILED("encryption output incorrect");
++ printk("%08x%08x%08x%08x\n",data_out[0],data_out[1],data_out[2],data_out[3]);
++ printk("%08x%08x%08x%08x\n",data_out[4],data_out[5],data_out[6],data_out[7]);
++ }
++
++ // free dmas
++ hipox_dma_free( dma_in );
++ hipox_dma_free( dma_out );
++
++ kfree(data_in);
++ kfree(data_out);
++
++ return failed;
++
++}
++
++/*************************************************************************/
++static int test10(void) {
++ int failed = 0;
++ u32 reg;
++ hipox_dma_channel_t* dma_in;
++ hipox_dma_channel_t* dma_out;
++ dma_addr_t in_address;
++ dma_addr_t out_address;
++
++ u32* data_in;
++ u32* data_out;
++
++ // setup dmas
++ dma_in = hipox_dma_request(1);
++ dma_out = hipox_dma_request(1);
++
++ // get some dma accessable memory
++ data_in = (u32*)kmalloc( 4 * sizeof(u32), GFP_KERNEL|GFP_DMA);
++ data_out = (u32*)kmalloc( 4 * sizeof(u32), GFP_KERNEL|GFP_DMA);
++
++ // fill with input and non expected output
++ data_in[0] = be32_to_cpu( 0x00112233);
++ data_in[1] = be32_to_cpu( 0x44556677);
++ data_in[2] = be32_to_cpu( 0x8899aabb);
++ data_in[3] = be32_to_cpu( 0xccddeeff);
++ data_out[0] = ~0;
++ data_out[1] = ~0;
++ data_out[2] = ~0;
++ data_out[3] = ~0;
++
++ // map the dma regons
++ in_address = dma_map_single(
++ 0,
++ data_in,
++ 4 * sizeof(u32),
++ DMA_TO_DEVICE);
++
++ // map the dma regons
++ out_address = dma_map_single(
++ 0,
++ data_out,
++ 4 * sizeof(u32),
++ DMA_FROM_DEVICE);
++
++ // setup the transfers
++ hipox_dma_device_set(
++ dma_in,
++ HIPOX_DMA_TO_DEVICE,
++ (char*)in_address,
++ 4 * sizeof(u32),
++ &hipox_dpe_rx_dma_settings,
++ HIPOX_DMA_MODE_INC, 1);
++
++ hipox_dma_device_set(
++ dma_out,
++ HIPOX_DMA_FROM_DEVICE,
++ (char*)out_address,
++ 4 * sizeof(u32),
++ &hipox_dpe_tx_dma_settings,
++ HIPOX_DMA_MODE_INC, 1);
++
++ // don't authenticate
++ WRITEL(0 ,OX800IBW_STATUS);
++
++ // toggle cleardown bit to start
++ WRITEL(OX800DPE_CTL_ABORT ,OX800DPE_CONTROL);
++ WRITEL(0 ,OX800DPE_CONTROL);
++
++
++ // shouldn't be busy or full
++ reg = READL( OX800DPE_STATUS );
++ if (! (reg & OX800DPE_STAT_IDLE) )
++ FAILED("not idle after abort toggle");
++ if (reg & OX800DPE_STAT_TX_NOTEMPTY)
++ FAILED("tx fifo not empty after abort toggle");
++ if (! (reg & OX800DPE_STAT_RX_SPACE) )
++ FAILED("rx not empty after abort toggle");
++
++ // setup for encryption
++ reg = OX800DPE_CTL_DIRECTION_ENC |
++ OX800DPE_CTL_MODE_CBC_AES;
++ WRITEL(reg ,OX800DPE_CONTROL);
++
++ reg = READL( OX800DPE_STATUS );
++ // shouldn't be busy
++ if (! (reg & OX800DPE_STAT_IDLE) )
++ FAILED("not idle even with incomplete data");
++ if (reg & OX800DPE_STAT_TX_NOTEMPTY)
++ FAILED("tx not empty before data input ");
++ if (! (reg & OX800DPE_STAT_RX_SPACE) )
++ FAILED("rx fifo filling without data");
++
++
++ // key no 1
++ WRITEL(be32_to_cpu( 0x00010203), OX800DPE_KEY00 );
++ WRITEL(be32_to_cpu( 0x04050607), OX800DPE_KEY01 );
++ WRITEL(be32_to_cpu( 0x08090a0b), OX800DPE_KEY02 );
++ WRITEL(be32_to_cpu( 0x0c0d0e0f), OX800DPE_KEY03 );
++
++ /* wait until done */
++ while( !(OX800DPE_STAT_IDLE & READL( OX800DPE_STATUS )) );
++
++ // setup initialisation vector
++ WRITEL(be32_to_cpu(~0), OX800DPE_DATA_CBC0 );
++ WRITEL(be32_to_cpu(~0), OX800DPE_DATA_CBC1 );
++
++ // start dma transfers
++ hipox_dma_start(dma_out);
++ hipox_dma_start(dma_in);
++
++ /* wait until done */
++ while( hipox_dma_is_active( dma_out ) );
++
++ reg = READL( OX800DPE_STATUS );
++
++ /* output should be empty */
++ if ( (reg & OX800DPE_STAT_TX_NOTEMPTY) )
++ FAILED("tx still full after fetching ");
++
++ /* in empty */
++ if (! (reg & OX800DPE_STAT_RX_SPACE) )
++ FAILED("rx still full after encrypting data ");
++
++ dma_unmap_single(0, in_address, 4 * sizeof(u32), DMA_TO_DEVICE);
++ dma_unmap_single(0, out_address, 4 * sizeof(u32), DMA_FROM_DEVICE);
++
++ /* check output */
++ if ((data_out[0] != cpu_to_be32(0x0bde5b88)) ||
++ (data_out[1] != cpu_to_be32(0x114ac430)) ||
++ (data_out[2] != cpu_to_be32(0x134e99ee)) ||
++ (data_out[3] != cpu_to_be32(0xd3557046)))
++ {
++ FAILED("encryption output incorrect");
++ printk("%08x%08x%08x%08x\n",data_out[0],data_out[1],data_out[2],data_out[3]);
++ }
++
++ // free dmas
++ hipox_dma_free( dma_in );
++ hipox_dma_free( dma_out );
++
++ kfree(data_in);
++ kfree(data_out);
++
++ return failed;
++
++}
++
++
++/*************************************************************************/
++static int test11(void) {
++ int failed = 0;
++ u32 reg;
++ hipox_dma_channel_t* dma_in;
++ hipox_dma_channel_t* dma_out;
++ dma_addr_t in_address;
++ dma_addr_t out_address;
++
++ u32* data_in;
++ u32* data_out;
++
++ // setup dmas
++ dma_in = hipox_dma_request(1);
++ dma_out = hipox_dma_request(1);
++
++ // get some dma accessable memory
++ data_in = (u32*)kmalloc( 4 * sizeof(u32), GFP_KERNEL|GFP_DMA);
++ data_out = (u32*)kmalloc( 4 * sizeof(u32), GFP_KERNEL|GFP_DMA);
++
++ // fill with input and non expected output
++ data_in[0] = be32_to_cpu( 0x69c4e0d8);
++ data_in[1] = be32_to_cpu( 0x6a7b0430);
++ data_in[2] = be32_to_cpu( 0xd8cdb780);
++ data_in[3] = be32_to_cpu( 0x70b4c55a);
++ data_out[0] = ~0;
++ data_out[1] = ~0;
++ data_out[2] = ~0;
++ data_out[3] = ~0;
++
++ // map the dma regons
++ in_address = dma_map_single(
++ 0,
++ data_in,
++ 4 * sizeof(u32),
++ DMA_TO_DEVICE);
++
++ // map the dma regons
++ out_address = dma_map_single(
++ 0,
++ data_out,
++ 4 * sizeof(u32),
++ DMA_FROM_DEVICE);
++
++ // setup the transfers
++ hipox_dma_device_set(
++ dma_in,
++ HIPOX_DMA_TO_DEVICE,
++ (char*)in_address,
++ 4 * sizeof(u32),
++ &hipox_dpe_rx_dma_settings,
++ HIPOX_DMA_MODE_INC, 1);
++
++ hipox_dma_device_set(
++ dma_out,
++ HIPOX_DMA_FROM_DEVICE,
++ (char*)out_address,
++ 4 * sizeof(u32),
++ &hipox_dpe_tx_dma_settings,
++ HIPOX_DMA_MODE_INC, 1);
++
++ // authenticate
++ WRITEL(OX800IBW_STAT_AUTHENTICATED ,OX800IBW_STATUS);
++
++ // toggle cleardown bit to start
++ WRITEL(OX800DPE_CTL_ABORT ,OX800DPE_CONTROL);
++ WRITEL(0 ,OX800DPE_CONTROL);
++
++
++ // shouldn't be busy or full
++ reg = READL( OX800DPE_STATUS );
++ if (! (reg & OX800DPE_STAT_IDLE) )
++ FAILED("not idle after abort toggle");
++ if (reg & OX800DPE_STAT_TX_NOTEMPTY)
++ FAILED("tx fifo not empty after abort toggle");
++ if (! (reg & OX800DPE_STAT_RX_SPACE) )
++ FAILED("rx not empty after abort toggle");
++
++ // setup for decryption
++ reg = OX800DPE_CTL_MODE_CBC_AES;
++ WRITEL(reg ,OX800DPE_CONTROL);
++
++ reg = READL( OX800DPE_STATUS );
++ // shouldn't be busy
++ if (! (reg & OX800DPE_STAT_IDLE) )
++ FAILED("not idle even with incomplete data");
++ if (reg & OX800DPE_STAT_TX_NOTEMPTY)
++ FAILED("tx not empty before data input ");
++ if (! (reg & OX800DPE_STAT_RX_SPACE) )
++ FAILED("rx fifo filling without data");
++
++
++ // key no 1
++ WRITEL(be32_to_cpu( 0x00010203), OX800DPE_KEY00 );
++ WRITEL(be32_to_cpu( 0x04050607), OX800DPE_KEY01 );
++ WRITEL(be32_to_cpu( 0x08090a0b), OX800DPE_KEY02 );
++ WRITEL(be32_to_cpu( 0x0c0d0e0f), OX800DPE_KEY03 );
++
++ /* wait until done */
++ while( !(OX800DPE_STAT_IDLE & READL( OX800DPE_STATUS )) );
++
++ // setup initialisation vector
++ WRITEL(be32_to_cpu(~0), OX800DPE_DATA_CBC0 );
++ WRITEL(be32_to_cpu(~0), OX800DPE_DATA_CBC1 );
++
++ // start dma transfers
++ hipox_dma_start(dma_out);
++ hipox_dma_start(dma_in);
++
++ /* wait until done */
++ while( hipox_dma_is_active( dma_out ) );
++
++ reg = READL( OX800DPE_STATUS );
++
++ /* output should be empty */
++ if ( (reg & OX800DPE_STAT_TX_NOTEMPTY) )
++ FAILED("tx still full after fetching ");
++
++ /* in empty */
++ if (! (reg & OX800DPE_STAT_RX_SPACE) )
++ FAILED("rx still full after encrypting data ");
++
++ dma_unmap_single(0, in_address, 4 * sizeof(u32), DMA_TO_DEVICE);
++ dma_unmap_single(0, out_address, 4 * sizeof(u32), DMA_FROM_DEVICE);
++
++ /* check output */
++ if ((data_out[0] != cpu_to_be32(0x00112233)) ||
++ (data_out[1] != cpu_to_be32(0x44556677)) ||
++ (data_out[2] != cpu_to_be32(0x8899aab4)) ||
++ (data_out[3] != cpu_to_be32(0x33221100)))
++ {
++ FAILED("encryption output incorrect");
++ printk("%08x%08x%08x%08x\n",data_out[0],data_out[1],data_out[2],data_out[3]);
++ }
++
++ // free dmas
++ hipox_dma_free( dma_in );
++ hipox_dma_free( dma_out );
++
++ kfree(data_in);
++ kfree(data_out);
++
++ return failed;
++
++}
++
++/*************************************************************************/
++static int test12(void) {
++ int failed = 0;
++ u32 reg;
++ hipox_dma_channel_t* dma_in;
++ hipox_dma_channel_t* dma_out;
++ dma_addr_t in_address;
++ dma_addr_t out_address;
++
++ u32* data_in;
++ u32* data_out;
++
++ // setup dmas
++ dma_in = hipox_dma_request(1);
++ dma_out = hipox_dma_request(1);
++
++ // get some dma accessable memory
++ data_in = (u32*)kmalloc( 4 * sizeof(u32), GFP_KERNEL|GFP_DMA);
++ data_out = (u32*)kmalloc( 4 * sizeof(u32), GFP_KERNEL|GFP_DMA);
++
++ // fill with input and non expected output
++ data_in[0] = be32_to_cpu( 0x00112233);
++ data_in[1] = be32_to_cpu( 0x44556677);
++ data_in[2] = be32_to_cpu( 0x8899aabb);
++ data_in[3] = be32_to_cpu( 0xccddeeff);
++ data_out[0] = ~0;
++ data_out[1] = ~0;
++ data_out[2] = ~0;
++ data_out[3] = ~0;
++
++ // map the dma regons
++ in_address = dma_map_single(
++ 0,
++ data_in,
++ 4 * sizeof(u32),
++ DMA_TO_DEVICE);
++
++ // map the dma regons
++ out_address = dma_map_single(
++ 0,
++ data_out,
++ 4 * sizeof(u32),
++ DMA_FROM_DEVICE);
++
++ // setup the transfers
++ hipox_dma_device_set(
++ dma_in,
++ HIPOX_DMA_TO_DEVICE,
++ (char*)in_address,
++ 4 * sizeof(u32),
++ &hipox_dpe_rx_dma_settings,
++ HIPOX_DMA_MODE_INC, 1);
++
++ hipox_dma_device_set(
++ dma_out,
++ HIPOX_DMA_FROM_DEVICE,
++ (char*)out_address,
++ 4 * sizeof(u32),
++ &hipox_dpe_tx_dma_settings,
++ HIPOX_DMA_MODE_INC, 1);
++
++ // don't authenticate
++ WRITEL(0 ,OX800IBW_STATUS);
++
++ // toggle cleardown bit to start
++ WRITEL(OX800DPE_CTL_ABORT ,OX800DPE_CONTROL);
++ WRITEL(0 ,OX800DPE_CONTROL);
++
++
++ // shouldn't be busy or full
++ reg = READL( OX800DPE_STATUS );
++ if (! (reg & OX800DPE_STAT_IDLE) )
++ FAILED("not idle after abort toggle");
++ if (reg & OX800DPE_STAT_TX_NOTEMPTY)
++ FAILED("tx fifo not empty after abort toggle");
++ if (! (reg & OX800DPE_STAT_RX_SPACE) )
++ FAILED("rx not empty after abort toggle");
++
++ // setup for encryption
++ reg = OX800DPE_CTL_DIRECTION_ENC |
++ OX800DPE_CTL_MODE_CBC_AES;
++ WRITEL(reg ,OX800DPE_CONTROL);
++
++ reg = READL( OX800DPE_STATUS );
++ // shouldn't be busy
++ if (! (reg & OX800DPE_STAT_IDLE) )
++ FAILED("not idle even with incomplete data");
++ if (reg & OX800DPE_STAT_TX_NOTEMPTY)
++ FAILED("tx not empty before data input ");
++ if (! (reg & OX800DPE_STAT_RX_SPACE) )
++ FAILED("rx fifo filling without data");
++
++
++ // key no 1
++ WRITEL(be32_to_cpu( 0x00010203), OX800DPE_KEY00 );
++ WRITEL(be32_to_cpu( 0x04050607), OX800DPE_KEY01 );
++ WRITEL(be32_to_cpu( 0x08090a0b), OX800DPE_KEY02 );
++ WRITEL(be32_to_cpu( 0x0c0d0e0f), OX800DPE_KEY03 );
++
++ /* wait until done */
++ while( !(OX800DPE_STAT_IDLE & READL( OX800DPE_STATUS )) );
++
++ // setup initialisation vector
++ WRITEL(be32_to_cpu(1), OX800DPE_DATA_CBC0 );
++ WRITEL(be32_to_cpu(0), OX800DPE_DATA_CBC1 );
++
++ // start dma transfers
++ hipox_dma_start(dma_out);
++ hipox_dma_start(dma_in);
++
++ /* wait until done */
++ while( hipox_dma_is_active( dma_out ) );
++
++ reg = READL( OX800DPE_STATUS );
++
++ /* output should be empty */
++ if ( (reg & OX800DPE_STAT_TX_NOTEMPTY) )
++ FAILED("tx still full after fetching ");
++
++ /* in empty */
++ if (! (reg & OX800DPE_STAT_RX_SPACE) )
++ FAILED("rx still full after encrypting data ");
++
++ dma_unmap_single(0, in_address, 4 * sizeof(u32), DMA_TO_DEVICE);
++ dma_unmap_single(0, out_address, 4 * sizeof(u32), DMA_FROM_DEVICE);
++
++
++
++
++
++ /* check output */
++ if ((data_out[0] != 0x850d2506) ||
++ (data_out[1] != 0xd71056c7) ||
++ (data_out[2] != 0xe62c220f) ||
++ (data_out[3] != 0xc3dedaf9))
++ {
++ FAILED("encryption output incorrect");
++ printk("%08x%08x%08x%08x\n",data_out[0],data_out[1],data_out[2],data_out[3]);
++ }
++
++ // free dmas
++ hipox_dma_free( dma_in );
++ hipox_dma_free( dma_out );
++
++ kfree(data_in);
++ kfree(data_out);
++
++ return failed;
++
++}
++
++
++/*************************************************************************/
++static int test13(void) {
++ int failed = 0;
++ u32 reg;
++ hipox_dma_channel_t* dma_in;
++ hipox_dma_channel_t* dma_out;
++ dma_addr_t in_address;
++ dma_addr_t out_address;
++
++ u32* data_in;
++ u32* data_out;
++
++ // setup dmas
++ dma_in = hipox_dma_request(1);
++ dma_out = hipox_dma_request(1);
++
++ // get some dma accessable memory
++ data_in = (u32*)kmalloc( 4 * sizeof(u32), GFP_KERNEL|GFP_DMA);
++ data_out = (u32*)kmalloc( 4 * sizeof(u32), GFP_KERNEL|GFP_DMA);
++
++ // fill with input and non expected output
++ data_in[0] = 0x850d2506;
++ data_in[1] = 0xd71056c7;
++ data_in[2] = 0xe62c220f;
++ data_in[3] = 0xc3dedaf9;
++ data_out[0] = ~0;
++ data_out[1] = ~0;
++ data_out[2] = ~0;
++ data_out[3] = ~0;
++
++ // map the dma regons
++ in_address = dma_map_single(
++ 0,
++ data_in,
++ 4 * sizeof(u32),
++ DMA_TO_DEVICE);
++
++ // map the dma regons
++ out_address = dma_map_single(
++ 0,
++ data_out,
++ 4 * sizeof(u32),
++ DMA_FROM_DEVICE);
++
++ // setup the transfers
++ hipox_dma_device_set(
++ dma_in,
++ HIPOX_DMA_TO_DEVICE,
++ (char*)in_address,
++ 4 * sizeof(u32),
++ &hipox_dpe_rx_dma_settings,
++ HIPOX_DMA_MODE_INC, 1);
++
++ hipox_dma_device_set(
++ dma_out,
++ HIPOX_DMA_FROM_DEVICE,
++ (char*)out_address,
++ 4 * sizeof(u32),
++ &hipox_dpe_tx_dma_settings,
++ HIPOX_DMA_MODE_INC, 1);
++
++ // authenticate
++ WRITEL(OX800IBW_STAT_AUTHENTICATED ,OX800IBW_STATUS);
++
++ // toggle cleardown bit to start
++ WRITEL(OX800DPE_CTL_ABORT ,OX800DPE_CONTROL);
++ WRITEL(0 ,OX800DPE_CONTROL);
++
++
++ // shouldn't be busy or full
++ reg = READL( OX800DPE_STATUS );
++ if (! (reg & OX800DPE_STAT_IDLE) )
++ FAILED("not idle after abort toggle");
++ if (reg & OX800DPE_STAT_TX_NOTEMPTY)
++ FAILED("tx fifo not empty after abort toggle");
++ if (! (reg & OX800DPE_STAT_RX_SPACE) )
++ FAILED("rx not empty after abort toggle");
++
++ // setup for decryption
++ reg = OX800DPE_CTL_MODE_CBC_AES;
++ WRITEL(reg ,OX800DPE_CONTROL);
++
++ reg = READL( OX800DPE_STATUS );
++ // shouldn't be busy
++ if (! (reg & OX800DPE_STAT_IDLE) )
++ FAILED("not idle even with incomplete data");
++ if (reg & OX800DPE_STAT_TX_NOTEMPTY)
++ FAILED("tx not empty before data input ");
++ if (! (reg & OX800DPE_STAT_RX_SPACE) )
++ FAILED("rx fifo filling without data");
++
++
++ // key no 1
++ WRITEL(be32_to_cpu( 0x00010203), OX800DPE_KEY00 );
++ WRITEL(be32_to_cpu( 0x04050607), OX800DPE_KEY01 );
++ WRITEL(be32_to_cpu( 0x08090a0b), OX800DPE_KEY02 );
++ WRITEL(be32_to_cpu( 0x0c0d0e0f), OX800DPE_KEY03 );
++
++ /* wait until done */
++ while( !(OX800DPE_STAT_IDLE & READL( OX800DPE_STATUS )) );
++
++ // setup initialisation vector
++ WRITEL(be32_to_cpu(1), OX800DPE_DATA_CBC0 );
++ WRITEL(be32_to_cpu(0), OX800DPE_DATA_CBC1 );
++
++ // start dma transfers
++ hipox_dma_start(dma_out);
++ hipox_dma_start(dma_in);
++
++ /* wait until done */
++ while( hipox_dma_is_active( dma_out ) );
++
++ reg = READL( OX800DPE_STATUS );
++
++ /* output should be empty */
++ if ( (reg & OX800DPE_STAT_TX_NOTEMPTY) )
++ FAILED("tx still full after fetching ");
++
++ /* in empty */
++ if (! (reg & OX800DPE_STAT_RX_SPACE) )
++ FAILED("rx still full after encrypting data ");
++
++ dma_unmap_single(0, in_address, 4 * sizeof(u32), DMA_TO_DEVICE);
++ dma_unmap_single(0, out_address, 4 * sizeof(u32), DMA_FROM_DEVICE);
++
++ /* check output */
++ if ((data_out[0] != cpu_to_be32(0x00112233)) ||
++ (data_out[1] != cpu_to_be32(0x44556677)) ||
++ (data_out[2] != cpu_to_be32(0x8899aabb)) ||
++ (data_out[3] != cpu_to_be32(0xccddeeff)))
++ {
++ FAILED("encryption output incorrect");
++ printk("%08x%08x%08x%08x\n",data_out[0],data_out[1],data_out[2],data_out[3]);
++ }
++
++ // free dmas
++ hipox_dma_free( dma_in );
++ hipox_dma_free( dma_out );
++
++ kfree(data_in);
++ kfree(data_out);
++
++ return failed;
++
++}
++
++
++/**********************************************************************/
++/* LRW tests */
++/**********************************************************************/
++
++static int test14(void) {
++ int failed = 0;
++ u32 reg;
++ hipox_dma_channel_t* dma_in;
++ hipox_dma_channel_t* dma_out;
++ dma_addr_t in_address;
++ dma_addr_t out_address;
++
++ u32* data_in;
++ u32* data_out;
++
++ // setup dmas
++ dma_in = hipox_dma_request(1);
++ dma_out = hipox_dma_request(1);
++
++ // get some dma accessable memory
++ data_in = (u32*)kmalloc( 8 * sizeof(u32), GFP_KERNEL|GFP_DMA);
++ data_out = (u32*)kmalloc( 8 * sizeof(u32), GFP_KERNEL|GFP_DMA);
++
++ // fill with input and non expected output
++ data_in[0] = be32_to_cpu( 0x30313233);
++ data_in[1] = be32_to_cpu( 0x34353637);
++ data_in[2] = be32_to_cpu( 0x38394142);
++ data_in[3] = be32_to_cpu( 0x43444546);
++ data_in[4] = be32_to_cpu( 0x30313233);
++ data_in[5] = be32_to_cpu( 0x34353637);
++ data_in[6] = be32_to_cpu( 0x38394142);
++ data_in[7] = be32_to_cpu( 0x43444546);
++ data_out[0] = ~0;
++ data_out[1] = ~0;
++ data_out[2] = ~0;
++ data_out[3] = ~0;
++ data_out[4] = ~0;
++ data_out[5] = ~0;
++ data_out[6] = ~0;
++ data_out[7] = ~0;
++
++ // map the dma regons
++ in_address = dma_map_single(
++ 0,
++ data_in,
++ 8 * sizeof(u32),
++ DMA_TO_DEVICE);
++
++ // map the dma regons
++ out_address = dma_map_single(
++ 0,
++ data_out,
++ 8 * sizeof(u32),
++ DMA_FROM_DEVICE);
++
++ // setup the transfers
++ hipox_dma_device_set(
++ dma_in,
++ HIPOX_DMA_TO_DEVICE,
++ (char*)in_address,
++ 8 * sizeof(u32),
++ &hipox_dpe_rx_dma_settings,
++ HIPOX_DMA_MODE_INC, 1);
++
++ hipox_dma_device_set(
++ dma_out,
++ HIPOX_DMA_FROM_DEVICE,
++ (char*)out_address,
++ 8 * sizeof(u32),
++ &hipox_dpe_tx_dma_settings,
++ HIPOX_DMA_MODE_INC, 1);
++
++ // don't authenticate
++ WRITEL(0 ,OX800IBW_STATUS);
++
++ // toggle cleardown bit to start
++ WRITEL(OX800DPE_CTL_ABORT ,OX800DPE_CONTROL);
++ WRITEL(0 ,OX800DPE_CONTROL);
++
++
++ // shouldn't be busy or full
++ reg = READL( OX800DPE_STATUS );
++ if (! (reg & OX800DPE_STAT_IDLE) )
++ FAILED("not idle after abort toggle");
++ if (reg & OX800DPE_STAT_TX_NOTEMPTY)
++ FAILED("tx fifo not empty after abort toggle");
++ if (! (reg & OX800DPE_STAT_RX_SPACE) )
++ FAILED("rx not empty after abort toggle");
++
++ // setup for encryption
++ reg = OX800DPE_CTL_DIRECTION_ENC |
++ OX800DPE_CTL_MODE_LRW_AES;
++ WRITEL(reg ,OX800DPE_CONTROL);
++
++ // key no 1
++ WRITEL(be32_to_cpu( 0x4562ac25), OX800DPE_KEY00 );
++ WRITEL(be32_to_cpu( 0xf828176d), OX800DPE_KEY01 );
++ WRITEL(be32_to_cpu( 0x4c268414), OX800DPE_KEY02 );
++ WRITEL(be32_to_cpu( 0xb5680185), OX800DPE_KEY03 );
++
++ // key no 2
++ WRITEL(be32_to_cpu( 0x258e2a05), OX800DPE_KEY10 );
++ WRITEL(be32_to_cpu( 0xe73e9d03), OX800DPE_KEY11 );
++ WRITEL(be32_to_cpu( 0xee5a830c), OX800DPE_KEY12 );
++ WRITEL(be32_to_cpu( 0xcc094c87), OX800DPE_KEY13 );
++
++ // setup index
++ WRITEL(0, OX800DPE_DATA_LRW0 );
++ WRITEL(0, OX800DPE_DATA_LRW1 );
++
++ /* wait until done */
++ while( !(OX800DPE_STAT_IDLE & READL( OX800DPE_STATUS )) );
++
++ // start dma transfers
++ hipox_dma_start(dma_out);
++ hipox_dma_start(dma_in);
++
++ /* wait until dma done */
++ while( hipox_dma_is_active( dma_out ) );
++
++ reg = READL( OX800DPE_STATUS );
++
++ /* output should be empty */
++ if ( (reg & OX800DPE_STAT_TX_NOTEMPTY) )
++ FAILED("tx still full after fetching ");
++
++ /* in empty */
++ if (! (reg & OX800DPE_STAT_RX_SPACE) )
++ FAILED("rx still full after encrypting data ");
++
++ dma_unmap_single(0, in_address, 8 * sizeof(u32), DMA_TO_DEVICE);
++ dma_unmap_single(0, out_address, 8 * sizeof(u32), DMA_FROM_DEVICE);
++
++ /*
++ check output.
++ note: first 4 quads contain unwanted data used to set
++ tweek location to 1, they are not checked.
++ */
++ if ((data_out[4] != cpu_to_be32(0xf1b273cd)) ||
++ (data_out[5] != cpu_to_be32(0x65a3df5f)) ||
++ (data_out[6] != cpu_to_be32(0xe95d4892)) ||
++ (data_out[7] != cpu_to_be32(0x54634eb8)))
++ {
++ FAILED("encryption output incorrect");
++ printk("%08x%08x%08x%08x\n",data_out[0],data_out[1],data_out[2],data_out[3]);
++ printk("%08x%08x%08x%08x\n",data_out[4],data_out[5],data_out[6],data_out[7]);
++ }
++
++ // free dmas
++ hipox_dma_free( dma_in );
++ hipox_dma_free( dma_out );
++
++ kfree(data_in);
++ kfree(data_out);
++
++ return failed;
++
++}
++
++
++/*************************************************************************/
++static int test15(void) {
++ int failed = 0;
++ u32 reg;
++ hipox_dma_channel_t* dma_in;
++ hipox_dma_channel_t* dma_out;
++ dma_addr_t in_address;
++ dma_addr_t out_address;
++
++ u32* data_in;
++ u32* data_out;
++
++ // setup dmas
++ dma_in = hipox_dma_request(1);
++ dma_out = hipox_dma_request(1);
++
++ // get some dma accessable memory
++ data_in = (u32*)kmalloc( 8 * sizeof(u32), GFP_KERNEL|GFP_DMA);
++ data_out = (u32*)kmalloc( 8 * sizeof(u32), GFP_KERNEL|GFP_DMA);
++
++ // fill with input and non expected output
++ data_in[0] = be32_to_cpu( 0xf1b273cd);
++ data_in[1] = be32_to_cpu( 0x65a3df5f);
++ data_in[2] = be32_to_cpu( 0xe95d4892);
++ data_in[3] = be32_to_cpu( 0x54634eb8);
++ data_in[4] = be32_to_cpu( 0xf1b273cd);
++ data_in[5] = be32_to_cpu( 0x65a3df5f);
++ data_in[6] = be32_to_cpu( 0xe95d4892);
++ data_in[7] = be32_to_cpu( 0x54634eb8);
++ data_out[0] = ~0;
++ data_out[1] = ~0;
++ data_out[2] = ~0;
++ data_out[3] = ~0;
++ data_out[4] = ~0;
++ data_out[5] = ~0;
++ data_out[6] = ~0;
++ data_out[7] = ~0;
++
++ // map the dma regons
++ in_address = dma_map_single(
++ 0,
++ data_in,
++ 8 * sizeof(u32),
++ DMA_TO_DEVICE);
++
++ // map the dma regons
++ out_address = dma_map_single(
++ 0,
++ data_out,
++ 8 * sizeof(u32),
++ DMA_FROM_DEVICE);
++
++ // setup the transfers
++ hipox_dma_device_set(
++ dma_in,
++ HIPOX_DMA_TO_DEVICE,
++ (char*)in_address,
++ 8 * sizeof(u32),
++ &hipox_dpe_rx_dma_settings,
++ HIPOX_DMA_MODE_INC, 1);
++
++ hipox_dma_device_set(
++ dma_out,
++ HIPOX_DMA_FROM_DEVICE,
++ (char*)out_address,
++ 8 * sizeof(u32),
++ &hipox_dpe_tx_dma_settings,
++ HIPOX_DMA_MODE_INC, 1);
++
++ // authenticate
++ WRITEL(OX800IBW_STAT_AUTHENTICATED ,OX800IBW_STATUS);
++
++ // toggle cleardown bit to start
++ WRITEL(OX800DPE_CTL_ABORT ,OX800DPE_CONTROL);
++ WRITEL(0 ,OX800DPE_CONTROL);
++
++ // shouldn't be busy or full
++ reg = READL( OX800DPE_STATUS );
++ if (! (reg & OX800DPE_STAT_IDLE) )
++ FAILED("not idle after abort toggle");
++ if (reg & OX800DPE_STAT_TX_NOTEMPTY)
++ FAILED("tx fifo not empty after abort toggle");
++ if (! (reg & OX800DPE_STAT_RX_SPACE) )
++ FAILED("rx not empty after abort toggle");
++
++ // setup for decryption
++ reg = OX800DPE_CTL_MODE_LRW_AES |
++ OX800DPE_CTL_PRIMARY_IS_KEY3;
++ WRITEL(reg ,OX800DPE_CONTROL);
++
++ // key no 1
++ WRITEL(be32_to_cpu( 0x4562ac25), OX800DPE_KEY20 );
++ WRITEL(be32_to_cpu( 0xf828176d), OX800DPE_KEY21 );
++ WRITEL(be32_to_cpu( 0x4c268414), OX800DPE_KEY22 );
++ WRITEL(be32_to_cpu( 0xb5680185), OX800DPE_KEY23 );
++
++ // key no 2
++ WRITEL(be32_to_cpu( 0x258e2a05), OX800DPE_KEY10 );
++ WRITEL(be32_to_cpu( 0xe73e9d03), OX800DPE_KEY11 );
++ WRITEL(be32_to_cpu( 0xee5a830c), OX800DPE_KEY12 );
++ WRITEL(be32_to_cpu( 0xcc094c87), OX800DPE_KEY13 );
++
++ // setup index
++ WRITEL(0, OX800DPE_DATA_LRW0 );
++ WRITEL(0, OX800DPE_DATA_LRW1 );
++
++ /* wait until done */
++ while( !(OX800DPE_STAT_IDLE & READL( OX800DPE_STATUS )) );
++
++ // start dma transfers
++ hipox_dma_start(dma_out);
++ hipox_dma_start(dma_in);
++
++ /* wait until done */
++ while( hipox_dma_is_active( dma_out ) );
++
++ reg = READL( OX800DPE_STATUS );
++
++ /* output should be empty */
++ if ( (reg & OX800DPE_STAT_TX_NOTEMPTY) )
++ FAILED("tx still full after fetching ");
++
++ /* in empty */
++ if (! (reg & OX800DPE_STAT_RX_SPACE) )
++ FAILED("rx still full after encrypting data ");
++
++ dma_unmap_single(0, in_address, 8 * sizeof(u32), DMA_TO_DEVICE);
++ dma_unmap_single(0, out_address, 8 * sizeof(u32), DMA_FROM_DEVICE);
++
++ /* check output */
++ if ((data_out[4] != cpu_to_be32(0x30313233)) ||
++ (data_out[5] != cpu_to_be32(0x34353637)) ||
++ (data_out[6] != cpu_to_be32(0x38394142)) ||
++ (data_out[7] != cpu_to_be32(0x43444546)))
++ {
++ FAILED("encryption output incorrect");
++ printk("%08x%08x%08x%08x\n",data_out[0],data_out[1],data_out[2],data_out[3]);
++ printk("%08x%08x%08x%08x\n",data_out[4],data_out[5],data_out[6],data_out[7]);
++ }
++
++ // free dmas
++ hipox_dma_free( dma_in );
++ hipox_dma_free( dma_out );
++
++ kfree(data_in);
++ kfree(data_out);
++
++ return failed;
++
++}
++
++/*************************************************************************/
++static int test16(void) {
++ int failed = 0;
++ u32 reg;
++ hipox_dma_channel_t* dma_in;
++ hipox_dma_channel_t* dma_out;
++ dma_addr_t in_address;
++ dma_addr_t out_address;
++
++ u32* data_in;
++ u32* data_out;
++
++ // setup dmas
++ dma_in = hipox_dma_request(1);
++ dma_out = hipox_dma_request(1);
++
++ // get some dma accessable memory
++ data_in = (u32*)kmalloc( 12 * sizeof(u32), GFP_KERNEL|GFP_DMA);
++ data_out = (u32*)kmalloc( 12 * sizeof(u32), GFP_KERNEL|GFP_DMA);
++
++ // fill with input and non expected output
++ data_in[8 ] = be32_to_cpu( 0x30313233);
++ data_in[9 ] = be32_to_cpu( 0x34353637);
++ data_in[10] = be32_to_cpu( 0x38394142);
++ data_in[11] = be32_to_cpu( 0x43444546);
++ data_out[0] = ~0;
++ data_out[1] = ~0;
++ data_out[2] = ~0;
++ data_out[3] = ~0;
++ data_out[4] = ~0;
++ data_out[5] = ~0;
++ data_out[6] = ~0;
++ data_out[7] = ~0;
++ data_out[8] = ~0;
++ data_out[9] = ~0;
++ data_out[10] = ~0;
++ data_out[11] = ~0;
++
++ // map the dma regons
++ in_address = dma_map_single(
++ 0,
++ data_in,
++ 12 * sizeof(u32),
++ DMA_TO_DEVICE);
++
++ // map the dma regons
++ out_address = dma_map_single(
++ 0,
++ data_out,
++ 12 * sizeof(u32),
++ DMA_FROM_DEVICE);
++
++ // setup the transfers
++ hipox_dma_device_set(
++ dma_in,
++ HIPOX_DMA_TO_DEVICE,
++ (char*)in_address,
++ 12 * sizeof(u32),
++ &hipox_dpe_rx_dma_settings,
++ HIPOX_DMA_MODE_INC, 1);
++
++ hipox_dma_device_set(
++ dma_out,
++ HIPOX_DMA_FROM_DEVICE,
++ (char*)out_address,
++ 12 * sizeof(u32),
++ &hipox_dpe_tx_dma_settings,
++ HIPOX_DMA_MODE_INC, 1);
++
++ // don't authenticate
++ WRITEL(0 ,OX800IBW_STATUS);
++
++ // toggle cleardown bit to start
++ WRITEL(OX800DPE_CTL_ABORT ,OX800DPE_CONTROL);
++ WRITEL(0 ,OX800DPE_CONTROL);
++
++
++ // shouldn't be busy or full
++ reg = READL( OX800DPE_STATUS );
++ if (! (reg & OX800DPE_STAT_IDLE) )
++ FAILED("not idle after abort toggle");
++ if (reg & OX800DPE_STAT_TX_NOTEMPTY)
++ FAILED("tx fifo not empty after abort toggle");
++ if (! (reg & OX800DPE_STAT_RX_SPACE) )
++ FAILED("rx not empty after abort toggle");
++
++ // setup for encryption
++ reg = OX800DPE_CTL_DIRECTION_ENC |
++ OX800DPE_CTL_PRIMARY_IS_KEY3 |
++ OX800DPE_CTL_MODE_LRW_AES;
++ WRITEL(reg ,OX800DPE_CONTROL);
++
++ // key no 1
++ WRITEL(be32_to_cpu( 0x59704714), OX800DPE_KEY20 );
++ WRITEL(be32_to_cpu( 0xf557478c), OX800DPE_KEY21 );
++ WRITEL(be32_to_cpu( 0xd779e80f), OX800DPE_KEY22 );
++ WRITEL(be32_to_cpu( 0x54887944), OX800DPE_KEY23 );
++
++ // key no 2
++ WRITEL(be32_to_cpu( 0x0d48f0b7), OX800DPE_KEY10 );
++ WRITEL(be32_to_cpu( 0xb15a53ea), OX800DPE_KEY11 );
++ WRITEL(be32_to_cpu( 0x1caa6b29), OX800DPE_KEY12 );
++ WRITEL(be32_to_cpu( 0xc2cafbaf), OX800DPE_KEY13 );
++
++ // setup index
++ WRITEL(0, OX800DPE_DATA_LRW0 );
++ WRITEL(0, OX800DPE_DATA_LRW1 );
++
++ /* wait until done */
++ while( !(OX800DPE_STAT_IDLE & READL( OX800DPE_STATUS )) );
++
++ // start dma transfers
++ hipox_dma_start(dma_out);
++ hipox_dma_start(dma_in);
++
++ /* wait until dma done */
++ while( hipox_dma_is_active( dma_out ) );
++
++ reg = READL( OX800DPE_STATUS );
++
++ /* output should be empty */
++ if ( (reg & OX800DPE_STAT_TX_NOTEMPTY) )
++ FAILED("tx still full after fetching ");
++
++ /* in empty */
++ if (! (reg & OX800DPE_STAT_RX_SPACE) )
++ FAILED("rx still full after encrypting data ");
++
++ dma_unmap_single(0, in_address, 12 * sizeof(u32), DMA_TO_DEVICE);
++ dma_unmap_single(0, out_address, 12 * sizeof(u32), DMA_FROM_DEVICE);
++
++ /*
++ check output.
++ note: first 4 quads contain unwanted data used to set
++ tweek location to 1, they are not checked.
++ */
++ if ((data_out[ 8] != cpu_to_be32(0x00c82bae)) ||
++ (data_out[ 9] != cpu_to_be32(0x95bbcde5)) ||
++ (data_out[10] != cpu_to_be32(0x274f0769)) ||
++ (data_out[11] != cpu_to_be32(0xb260e136)))
++ {
++ FAILED("encryption output incorrect");
++ printk("%08x%08x%08x%08x\n",data_out[8],data_out[9],data_out[10],data_out[11]);
++ }
++
++ // free dmas
++ hipox_dma_free( dma_in );
++ hipox_dma_free( dma_out );
++
++ kfree(data_in);
++ kfree(data_out);
++
++ return failed;
++
++}
++
++
++/*************************************************************************/
++static int test17(void) {
++ int failed = 0;
++ u32 reg;
++ hipox_dma_channel_t* dma_in;
++ hipox_dma_channel_t* dma_out;
++ dma_addr_t in_address;
++ dma_addr_t out_address;
++
++ u32* data_in;
++ u32* data_out;
++
++ // setup dmas
++ dma_in = hipox_dma_request(1);
++ dma_out = hipox_dma_request(1);
++
++ // get some dma accessable memory
++ data_in = (u32*)kmalloc( 12 * sizeof(u32), GFP_KERNEL|GFP_DMA);
++ data_out = (u32*)kmalloc( 12 * sizeof(u32), GFP_KERNEL|GFP_DMA);
++
++ // fill with input and non expected output
++ data_in[ 8] = be32_to_cpu( 0x00c82bae);
++ data_in[ 9] = be32_to_cpu( 0x95bbcde5);
++ data_in[10] = be32_to_cpu( 0x274f0769);
++ data_in[11] = be32_to_cpu( 0xb260e136);
++ data_out[ 0] = ~0;
++ data_out[ 1] = ~0;
++ data_out[ 2] = ~0;
++ data_out[ 3] = ~0;
++ data_out[ 4] = ~0;
++ data_out[ 5] = ~0;
++ data_out[ 6] = ~0;
++ data_out[ 7] = ~0;
++ data_out[ 8] = ~0;
++ data_out[ 9] = ~0;
++ data_out[10] = ~0;
++ data_out[11] = ~0;
++
++ // map the dma regons
++ in_address = dma_map_single(
++ 0,
++ data_in,
++ 12 * sizeof(u32),
++ DMA_TO_DEVICE);
++
++ // map the dma regons
++ out_address = dma_map_single(
++ 0,
++ data_out,
++ 12 * sizeof(u32),
++ DMA_FROM_DEVICE);
++
++ // setup the transfers
++ hipox_dma_device_set(
++ dma_in,
++ HIPOX_DMA_TO_DEVICE,
++ (char*)in_address,
++ 12 * sizeof(u32),
++ &hipox_dpe_rx_dma_settings,
++ HIPOX_DMA_MODE_INC, 1);
++
++ hipox_dma_device_set(
++ dma_out,
++ HIPOX_DMA_FROM_DEVICE,
++ (char*)out_address,
++ 12 * sizeof(u32),
++ &hipox_dpe_tx_dma_settings,
++ HIPOX_DMA_MODE_INC, 1);
++
++ // authenticate
++ WRITEL(OX800IBW_STAT_AUTHENTICATED ,OX800IBW_STATUS);
++
++ // toggle cleardown bit to start
++ WRITEL(OX800DPE_CTL_ABORT ,OX800DPE_CONTROL);
++ WRITEL(0 ,OX800DPE_CONTROL);
++
++ // shouldn't be busy or full
++ reg = READL( OX800DPE_STATUS );
++ if (! (reg & OX800DPE_STAT_IDLE) )
++ FAILED("not idle after abort toggle");
++ if (reg & OX800DPE_STAT_TX_NOTEMPTY)
++ FAILED("tx fifo not empty after abort toggle");
++ if (! (reg & OX800DPE_STAT_RX_SPACE) )
++ FAILED("rx not empty after abort toggle");
++
++ // setup for decryption
++ reg = OX800DPE_CTL_MODE_LRW_AES ;
++ WRITEL(reg ,OX800DPE_CONTROL);
++
++ // key no 1
++ WRITEL(be32_to_cpu( 0x59704714), OX800DPE_KEY00 );
++ WRITEL(be32_to_cpu( 0xf557478c), OX800DPE_KEY01 );
++ WRITEL(be32_to_cpu( 0xd779e80f), OX800DPE_KEY02 );
++ WRITEL(be32_to_cpu( 0x54887944), OX800DPE_KEY03 );
++
++ // key no 2
++ WRITEL(be32_to_cpu( 0x0d48f0b7), OX800DPE_KEY10 );
++ WRITEL(be32_to_cpu( 0xb15a53ea), OX800DPE_KEY11 );
++ WRITEL(be32_to_cpu( 0x1caa6b29), OX800DPE_KEY12 );
++ WRITEL(be32_to_cpu( 0xc2cafbaf), OX800DPE_KEY13 );
++
++ // setup index
++ WRITEL(0, OX800DPE_DATA_LRW0 );
++ WRITEL(0, OX800DPE_DATA_LRW1 );
++
++ /* wait until done */
++ while( !(OX800DPE_STAT_IDLE & READL( OX800DPE_STATUS )) );
++
++ // start dma transfers
++ hipox_dma_start(dma_out);
++ hipox_dma_start(dma_in);
++
++ /* wait until done */
++ while( hipox_dma_is_active( dma_out ) );
++
++ reg = READL( OX800DPE_STATUS );
++
++ /* output should be empty */
++ if ( (reg & OX800DPE_STAT_TX_NOTEMPTY) )
++ FAILED("tx still full after fetching ");
++
++ /* in empty */
++ if (! (reg & OX800DPE_STAT_RX_SPACE) )
++ FAILED("rx still full after encrypting data ");
++
++ dma_unmap_single(0, in_address, 12 * sizeof(u32), DMA_TO_DEVICE);
++ dma_unmap_single(0, out_address, 12 * sizeof(u32), DMA_FROM_DEVICE);
++
++ /* check output */
++ if ((data_out[ 8] != cpu_to_be32(0x30313233)) ||
++ (data_out[ 9] != cpu_to_be32(0x34353637)) ||
++ (data_out[10] != cpu_to_be32(0x38394142)) ||
++ (data_out[11] != cpu_to_be32(0x43444546)))
++ {
++ FAILED("encryption output incorrect");
++ printk("%08x%08x%08x%08x\n",data_out[8],data_out[9],data_out[10],data_out[11]);
++ }
++
++ // free dmas
++ hipox_dma_free( dma_in );
++ hipox_dma_free( dma_out );
++
++ kfree(data_in);
++ kfree(data_out);
++
++ return failed;
++
++}
++
++/*************************************************************************/
++static int test18(void) {
++ int failed = 0;
++ u32 reg;
++ hipox_dma_channel_t* dma_in;
++ hipox_dma_channel_t* dma_out;
++ dma_addr_t in_address;
++ dma_addr_t out_address;
++
++ u32* data_in;
++ u32* data_out;
++
++ // setup dmas
++ dma_in = hipox_dma_request(1);
++ dma_out = hipox_dma_request(1);
++
++ // get some dma accessable memory
++ data_in = (u32*)kmalloc( 4 * sizeof(u32), GFP_KERNEL|GFP_DMA);
++ data_out = (u32*)kmalloc( 4 * sizeof(u32), GFP_KERNEL|GFP_DMA);
++
++ // fill with input and non expected output
++ data_in[0] = be32_to_cpu( 0x30313233);
++ data_in[1] = be32_to_cpu( 0x34353637);
++ data_in[2] = be32_to_cpu( 0x38394142);
++ data_in[3] = be32_to_cpu( 0x43444546);
++ data_out[0] = ~0;
++ data_out[1] = ~0;
++ data_out[2] = ~0;
++ data_out[3] = ~0;
++
++ // map the dma regons
++ in_address = dma_map_single(
++ 0,
++ data_in,
++ 4 * sizeof(u32),
++ DMA_TO_DEVICE);
++
++ // map the dma regons
++ out_address = dma_map_single(
++ 0,
++ data_out,
++ 4 * sizeof(u32),
++ DMA_FROM_DEVICE);
++
++ // setup the transfers
++ hipox_dma_device_set(
++ dma_in,
++ HIPOX_DMA_TO_DEVICE,
++ (char*)in_address,
++ 4 * sizeof(u32),
++ &hipox_dpe_rx_dma_settings,
++ HIPOX_DMA_MODE_INC, 1);
++
++ hipox_dma_device_set(
++ dma_out,
++ HIPOX_DMA_FROM_DEVICE,
++ (char*)out_address,
++ 4 * sizeof(u32),
++ &hipox_dpe_tx_dma_settings,
++ HIPOX_DMA_MODE_INC, 1);
++
++ // don't authenticate
++ WRITEL(0 ,OX800IBW_STATUS);
++
++ // toggle cleardown bit to start
++ WRITEL(OX800DPE_CTL_ABORT ,OX800DPE_CONTROL);
++ WRITEL(0 ,OX800DPE_CONTROL);
++
++
++ // shouldn't be busy or full
++ reg = READL( OX800DPE_STATUS );
++ if (! (reg & OX800DPE_STAT_IDLE) )
++ FAILED("not idle after abort toggle");
++ if (reg & OX800DPE_STAT_TX_NOTEMPTY)
++ FAILED("tx fifo not empty after abort toggle");
++ if (! (reg & OX800DPE_STAT_RX_SPACE) )
++ FAILED("rx not empty after abort toggle");
++
++ // setup for encryption
++ reg = OX800DPE_CTL_DIRECTION_ENC |
++ OX800DPE_CTL_MODE_LRW_AES;
++ WRITEL(reg ,OX800DPE_CONTROL);
++
++ // key no 1
++ WRITEL(be32_to_cpu( 0xd82a9134), OX800DPE_KEY00 );
++ WRITEL(be32_to_cpu( 0xb26a5650), OX800DPE_KEY01 );
++ WRITEL(be32_to_cpu( 0x30fe69e2), OX800DPE_KEY02 );
++ WRITEL(be32_to_cpu( 0x377f9847), OX800DPE_KEY03 );
++
++ // key no 2
++ WRITEL(be32_to_cpu( 0xcdf90b16), OX800DPE_KEY10 );
++ WRITEL(be32_to_cpu( 0x0c648fb6), OX800DPE_KEY11 );
++ WRITEL(be32_to_cpu( 0xb00d0d1b), OX800DPE_KEY12 );
++ WRITEL(be32_to_cpu( 0xae85871f), OX800DPE_KEY13 );
++
++ // setup index
++ WRITEL(0x10000000, OX800DPE_DATA_LRW0 );
++ WRITEL(0, OX800DPE_DATA_LRW1 );
++
++ /* wait until done */
++ while( !(OX800DPE_STAT_IDLE & READL( OX800DPE_STATUS )) );
++
++ // start dma transfers
++ hipox_dma_start(dma_out);
++ hipox_dma_start(dma_in);
++
++ /* wait until dma done */
++ while( hipox_dma_is_active( dma_out ) );
++
++ reg = READL( OX800DPE_STATUS );
++
++ /* output should be empty */
++ if ( (reg & OX800DPE_STAT_TX_NOTEMPTY) )
++ FAILED("tx still full after fetching ");
++
++ /* in empty */
++ if (! (reg & OX800DPE_STAT_RX_SPACE) )
++ FAILED("rx still full after encrypting data ");
++
++ dma_unmap_single(0, in_address, 4 * sizeof(u32), DMA_TO_DEVICE);
++ dma_unmap_single(0, out_address, 4 * sizeof(u32), DMA_FROM_DEVICE);
++
++ /*
++ check output.
++ */
++ if ((data_out[0] != cpu_to_be32(0x76322183)) ||
++ (data_out[1] != cpu_to_be32(0xed8ff182)) ||
++ (data_out[2] != cpu_to_be32(0xf9596203)) ||
++ (data_out[3] != cpu_to_be32(0x690e5e01)))
++ {
++ FAILED("encryption output incorrect");
++ printk("%08x%08x%08x%08x\n",data_out[0],data_out[1],data_out[2],data_out[3]);
++ }
++
++ // free dmas
++ hipox_dma_free( dma_in );
++ hipox_dma_free( dma_out );
++
++ kfree(data_in);
++ kfree(data_out);
++
++ return failed;
++
++}
++
++
++/*************************************************************************/
++static int test19(void) {
++ int failed = 0;
++ u32 reg;
++ hipox_dma_channel_t* dma_in;
++ hipox_dma_channel_t* dma_out;
++ dma_addr_t in_address;
++ dma_addr_t out_address;
++
++ u32* data_in;
++ u32* data_out;
++
++ // setup dmas
++ dma_in = hipox_dma_request(1);
++ dma_out = hipox_dma_request(1);
++
++ // get some dma accessable memory
++ data_in = (u32*)kmalloc( 8 * sizeof(u32), GFP_KERNEL|GFP_DMA);
++ data_out = (u32*)kmalloc( 8 * sizeof(u32), GFP_KERNEL|GFP_DMA);
++
++ // fill with input and non expected output
++ data_in[0] = be32_to_cpu( 0x76322183);
++ data_in[1] = be32_to_cpu( 0xed8ff182);
++ data_in[2] = be32_to_cpu( 0xf9596203);
++ data_in[3] = be32_to_cpu( 0x690e5e01);
++ data_out[0] = ~0;
++ data_out[1] = ~0;
++ data_out[2] = ~0;
++ data_out[3] = ~0;
++
++ // map the dma regons
++ in_address = dma_map_single(
++ 0,
++ data_in,
++ 4 * sizeof(u32),
++ DMA_TO_DEVICE);
++
++ // map the dma regons
++ out_address = dma_map_single(
++ 0,
++ data_out,
++ 4 * sizeof(u32),
++ DMA_FROM_DEVICE);
++
++ // setup the transfers
++ hipox_dma_device_set(
++ dma_in,
++ HIPOX_DMA_TO_DEVICE,
++ (char*)in_address,
++ 4 * sizeof(u32),
++ &hipox_dpe_rx_dma_settings,
++ HIPOX_DMA_MODE_INC, 1);
++
++ hipox_dma_device_set(
++ dma_out,
++ HIPOX_DMA_FROM_DEVICE,
++ (char*)out_address,
++ 4 * sizeof(u32),
++ &hipox_dpe_tx_dma_settings,
++ HIPOX_DMA_MODE_INC, 1);
++
++ // authenticate
++ WRITEL(OX800IBW_STAT_AUTHENTICATED ,OX800IBW_STATUS);
++
++ // toggle cleardown bit to start
++ WRITEL(OX800DPE_CTL_ABORT ,OX800DPE_CONTROL);
++ WRITEL(0 ,OX800DPE_CONTROL);
++
++ // shouldn't be busy or full
++ reg = READL( OX800DPE_STATUS );
++ if (! (reg & OX800DPE_STAT_IDLE) )
++ FAILED("not idle after abort toggle");
++ if (reg & OX800DPE_STAT_TX_NOTEMPTY)
++ FAILED("tx fifo not empty after abort toggle");
++ if (! (reg & OX800DPE_STAT_RX_SPACE) )
++ FAILED("rx not empty after abort toggle");
++
++ // setup for decryption
++ reg = OX800DPE_CTL_MODE_LRW_AES |
++ OX800DPE_CTL_PRIMARY_IS_KEY3;
++ WRITEL(reg ,OX800DPE_CONTROL);
++
++ // key no 1
++ WRITEL(be32_to_cpu( 0xd82a9134), OX800DPE_KEY20 );
++ WRITEL(be32_to_cpu( 0xb26a5650), OX800DPE_KEY21 );
++ WRITEL(be32_to_cpu( 0x30fe69e2), OX800DPE_KEY22 );
++ WRITEL(be32_to_cpu( 0x377f9847), OX800DPE_KEY23 );
++
++ // key no 2
++ WRITEL(be32_to_cpu( 0xcdf90b16), OX800DPE_KEY10 );
++ WRITEL(be32_to_cpu( 0x0c648fb6), OX800DPE_KEY11 );
++ WRITEL(be32_to_cpu( 0xb00d0d1b), OX800DPE_KEY12 );
++ WRITEL(be32_to_cpu( 0xae85871f), OX800DPE_KEY13 );
++
++ // setup index
++ WRITEL(0x10000000, OX800DPE_DATA_LRW0 );
++ WRITEL(0, OX800DPE_DATA_LRW1 );
++
++ /* wait until done */
++ while( !(OX800DPE_STAT_IDLE & READL( OX800DPE_STATUS )) );
++
++ // start dma transfers
++ hipox_dma_start(dma_out);
++ hipox_dma_start(dma_in);
++
++ /* wait until done */
++ while( hipox_dma_is_active( dma_out ) );
++
++ reg = READL( OX800DPE_STATUS );
++
++ /* output should be empty */
++ if ( (reg & OX800DPE_STAT_TX_NOTEMPTY) )
++ FAILED("tx still full after fetching ");
++
++ /* in empty */
++ if (! (reg & OX800DPE_STAT_RX_SPACE) )
++ FAILED("rx still full after encrypting data ");
++
++ dma_unmap_single(0, in_address, 4 * sizeof(u32), DMA_TO_DEVICE);
++ dma_unmap_single(0, out_address, 4 * sizeof(u32), DMA_FROM_DEVICE);
++
++ /* check output */
++ if ((data_out[0] != cpu_to_be32(0x30313233)) ||
++ (data_out[1] != cpu_to_be32(0x34353637)) ||
++ (data_out[2] != cpu_to_be32(0x38394142)) ||
++ (data_out[3] != cpu_to_be32(0x43444546)))
++ {
++ FAILED("encryption output incorrect");
++ printk("%08x%08x%08x%08x\n",data_out[0],data_out[1],data_out[2],data_out[3]);
++ }
++
++ // free dmas
++ hipox_dma_free( dma_in );
++ hipox_dma_free( dma_out );
++
++ kfree(data_in);
++ kfree(data_out);
++
++ return failed;
++
++}
++
++/*************************************************************************/
++static int test20(void) {
++ int failed = 0;
++ u32 reg;
++ hipox_dma_channel_t* dma_in;
++ hipox_dma_channel_t* dma_out;
++ dma_addr_t in_address;
++ dma_addr_t out_address;
++
++ u32* data_in;
++ u32* data_out;
++
++ // setup dmas
++ dma_in = hipox_dma_request(1);
++ dma_out = hipox_dma_request(1);
++
++ // get some dma accessable memory
++ data_in = (u32*)kmalloc( 4 * sizeof(u32), GFP_KERNEL|GFP_DMA);
++ data_out = (u32*)kmalloc( 4 * sizeof(u32), GFP_KERNEL|GFP_DMA);
++
++ // fill with input and non expected output
++ data_in[0] = be32_to_cpu( 0x30313233);
++ data_in[1] = be32_to_cpu( 0x34353637);
++ data_in[2] = be32_to_cpu( 0x38394142);
++ data_in[3] = be32_to_cpu( 0x43444546);
++ data_out[0] = ~0;
++ data_out[1] = ~0;
++ data_out[2] = ~0;
++ data_out[3] = ~0;
++
++ // map the dma regons
++ in_address = dma_map_single(
++ 0,
++ data_in,
++ 4 * sizeof(u32),
++ DMA_TO_DEVICE);
++
++ // map the dma regons
++ out_address = dma_map_single(
++ 0,
++ data_out,
++ 4 * sizeof(u32),
++ DMA_FROM_DEVICE);
++
++ // setup the transfers
++ hipox_dma_device_set(
++ dma_in,
++ HIPOX_DMA_TO_DEVICE,
++ (char*)in_address,
++ 4 * sizeof(u32),
++ &hipox_dpe_rx_dma_settings,
++ HIPOX_DMA_MODE_INC, 1);
++
++ hipox_dma_device_set(
++ dma_out,
++ HIPOX_DMA_FROM_DEVICE,
++ (char*)out_address,
++ 4 * sizeof(u32),
++ &hipox_dpe_tx_dma_settings,
++ HIPOX_DMA_MODE_INC, 1);
++
++ // don't authenticate
++ WRITEL(0 ,OX800IBW_STATUS);
++
++ // toggle cleardown bit to start
++ WRITEL(OX800DPE_CTL_ABORT ,OX800DPE_CONTROL);
++ WRITEL(0 ,OX800DPE_CONTROL);
++
++
++ // shouldn't be busy or full
++ reg = READL( OX800DPE_STATUS );
++ if (! (reg & OX800DPE_STAT_IDLE) )
++ FAILED("not idle after abort toggle");
++ if (reg & OX800DPE_STAT_TX_NOTEMPTY)
++ FAILED("tx fifo not empty after abort toggle");
++ if (! (reg & OX800DPE_STAT_RX_SPACE) )
++ FAILED("rx not empty after abort toggle");
++
++ // setup for encryption
++ reg = OX800DPE_CTL_DIRECTION_ENC |
++ OX800DPE_CTL_MODE_LRW_AES;
++ WRITEL(reg ,OX800DPE_CONTROL);
++
++ // key no 1
++ WRITEL(be32_to_cpu( 0x4562ac25), OX800DPE_KEY00 );
++ WRITEL(be32_to_cpu( 0xf828176d), OX800DPE_KEY01 );
++ WRITEL(be32_to_cpu( 0x4c268414), OX800DPE_KEY02 );
++ WRITEL(be32_to_cpu( 0xb5680185), OX800DPE_KEY03 );
++
++ // key no 2
++ WRITEL(be32_to_cpu( 0x258e2a05), OX800DPE_KEY10 );
++ WRITEL(be32_to_cpu( 0xe73e9d03), OX800DPE_KEY11 );
++ WRITEL(be32_to_cpu( 0xee5a830c), OX800DPE_KEY12 );
++ WRITEL(be32_to_cpu( 0xcc094c87), OX800DPE_KEY13 );
++
++ // setup index
++ WRITEL(0x00000000, OX800DPE_DATA_LRW0 );
++ WRITEL(0x00000008, OX800DPE_DATA_LRW1 );
++
++ /* wait until done */
++ while( !(OX800DPE_STAT_IDLE & READL( OX800DPE_STATUS )) );
++
++ // start dma transfers
++ hipox_dma_start(dma_out);
++ hipox_dma_start(dma_in);
++
++ /* wait until dma done */
++ while( hipox_dma_is_active( dma_out ) );
++
++ reg = READL( OX800DPE_STATUS );
++
++ /* output should be empty */
++ if ( (reg & OX800DPE_STAT_TX_NOTEMPTY) )
++ FAILED("tx still full after fetching ");
++
++ /* in empty */
++ if (! (reg & OX800DPE_STAT_RX_SPACE) )
++ FAILED("rx still full after encrypting data ");
++
++ dma_unmap_single(0, in_address, 4 * sizeof(u32), DMA_TO_DEVICE);
++ dma_unmap_single(0, out_address, 4 * sizeof(u32), DMA_FROM_DEVICE);
++
++ /*
++ check output.
++ */
++ if ((data_out[0] == 0xc0a37fda) )
++ {
++ FAILED("encryption output indicates most significant bit is ignored.");
++ printk("%08x%08x%08x%08x\n",data_out[0],data_out[1],data_out[2],data_out[3]);
++ }
++
++ // free dmas
++ hipox_dma_free( dma_in );
++ hipox_dma_free( dma_out );
++
++ kfree(data_in);
++ kfree(data_out);
++
++ return failed;
++
++}
++
++
++/*************************************************************************/
++static int test21(void) {
++ int failed = 0;
++ u32 reg;
++ hipox_dma_channel_t* dma_in;
++ hipox_dma_channel_t* dma_out;
++ dma_addr_t in_address;
++ dma_addr_t out_address;
++
++ u32* data_in;
++ u32* data_out;
++
++ // setup dmas
++ dma_in = hipox_dma_request(1);
++ dma_out = hipox_dma_request(1);
++
++ // get some dma accessable memory (512B + 16B
++ data_in = (u32*)kmalloc( 132 * sizeof(u32), GFP_KERNEL|GFP_DMA);
++ data_out = (u32*)kmalloc( 132 * sizeof(u32), GFP_KERNEL|GFP_DMA);
++
++ // fill with input and non expected output
++ data_in[128] = be32_to_cpu( 0x30313233);
++ data_in[129] = be32_to_cpu( 0x34353637);
++ data_in[130] = be32_to_cpu( 0x38394142);
++ data_in[131] = be32_to_cpu( 0x43444546);
++ data_out[128] = ~0;
++ data_out[129] = ~0;
++ data_out[130] = ~0;
++ data_out[131] = ~0;
++
++ // map the dma regons
++ in_address = dma_map_single(
++ 0,
++ data_in,
++ 132 * sizeof(u32),
++ DMA_TO_DEVICE);
++
++ // map the dma regons
++ out_address = dma_map_single(
++ 0,
++ data_out,
++ 132 * sizeof(u32),
++ DMA_FROM_DEVICE);
++
++ // setup the transfers
++ hipox_dma_device_set(
++ dma_in,
++ HIPOX_DMA_TO_DEVICE,
++ (char*)in_address,
++ 132 * sizeof(u32),
++ &hipox_dpe_rx_dma_settings,
++ HIPOX_DMA_MODE_INC, 1);
++
++ hipox_dma_device_set(
++ dma_out,
++ HIPOX_DMA_FROM_DEVICE,
++ (char*)out_address,
++ 132 * sizeof(u32),
++ &hipox_dpe_tx_dma_settings,
++ HIPOX_DMA_MODE_INC, 1);
++
++ // authenticate
++ WRITEL(OX800IBW_STAT_AUTHENTICATED ,OX800IBW_STATUS);
++
++ // toggle cleardown bit to start
++ WRITEL(OX800DPE_CTL_ABORT ,OX800DPE_CONTROL);
++ WRITEL(0 ,OX800DPE_CONTROL);
++
++ // shouldn't be busy or full
++ reg = READL( OX800DPE_STATUS );
++ if (! (reg & OX800DPE_STAT_IDLE) )
++ FAILED("not idle after abort toggle");
++ if (reg & OX800DPE_STAT_TX_NOTEMPTY)
++ FAILED("tx fifo not empty after abort toggle");
++ if (! (reg & OX800DPE_STAT_RX_SPACE) )
++ FAILED("rx not empty after abort toggle");
++
++ // setup for decryption
++ reg = OX800DPE_CTL_DIRECTION_ENC |
++ OX800DPE_CTL_MODE_LRW_AES ;
++ WRITEL(reg ,OX800DPE_CONTROL);
++
++ // key no 1
++ WRITEL(be32_to_cpu( 0xd82a9134), OX800DPE_KEY00 );
++ WRITEL(be32_to_cpu( 0xb26a5650), OX800DPE_KEY01 );
++ WRITEL(be32_to_cpu( 0x30fe69e2), OX800DPE_KEY02 );
++ WRITEL(be32_to_cpu( 0x377f9847), OX800DPE_KEY03 );
++
++ // key no 2
++ WRITEL(be32_to_cpu( 0xcdf90b16), OX800DPE_KEY10 );
++ WRITEL(be32_to_cpu( 0x0c648fb6), OX800DPE_KEY11 );
++ WRITEL(be32_to_cpu( 0xb00d0d1b), OX800DPE_KEY12 );
++ WRITEL(be32_to_cpu( 0xae85871f), OX800DPE_KEY13 );
++
++ // setup index
++ WRITEL(0x0fffffff, OX800DPE_DATA_LRW0 );
++ WRITEL(0x00000000, OX800DPE_DATA_LRW1 );
++
++ /* wait until done */
++ while( !(OX800DPE_STAT_IDLE & READL( OX800DPE_STATUS )) );
++
++ // start dma transfers
++ hipox_dma_start(dma_out);
++ hipox_dma_start(dma_in);
++
++ /* wait until done */
++ while( hipox_dma_is_active( dma_out ) );
++
++ reg = READL( OX800DPE_STATUS );
++
++ /* output should be empty */
++ if ( (reg & OX800DPE_STAT_TX_NOTEMPTY) )
++ FAILED("tx still full after fetching ");
++
++ /* in empty */
++ if (! (reg & OX800DPE_STAT_RX_SPACE) )
++ FAILED("rx still full after encrypting data ");
++
++ dma_unmap_single(0, in_address, 132 * sizeof(u32), DMA_TO_DEVICE);
++ dma_unmap_single(0, out_address, 132 * sizeof(u32), DMA_FROM_DEVICE);
++
++ /* check output */
++ if ((data_out[128] != cpu_to_be32(0x76322183)) ||
++ (data_out[129] != cpu_to_be32(0xed8ff182)) ||
++ (data_out[130] != cpu_to_be32(0xf9596203)) ||
++ (data_out[131] != cpu_to_be32(0x690e5e01)))
++ {
++ FAILED("encryption output incorrect");
++ printk("%08x%08x%08x%08x\n",data_out[128],data_out[129],data_out[130],data_out[131]);
++ }
++
++ // free dmas
++ hipox_dma_free( dma_in );
++ hipox_dma_free( dma_out );
++
++ kfree(data_in);
++ kfree(data_out);
++
++ return failed;
++
++}
++
++
++/*****************************************************************************/
++#define NOCIPHERTESTS 21
++static ox800dpe_test_t* tests[NOCIPHERTESTS] = {
++ /* ordinary AES tests */
++ test1,
++ test2,
++ test3,
++ test4,
++ test5,
++ test6,
++ test7,
++
++ /* CBC AES tests */
++ test8,
++ test9,
++ test10,
++ test11,
++ test12,
++ test13,
++
++ /* LRW AES tests */
++ test14,
++ test15,
++ test16,
++ test17,
++ test18,
++ test19,
++ test20,
++ test21
++
++} ;
++
++
++static int __init ox800dpe_init(void)
++{
++ int i;
++ int result;
++ printk("*******************************************************************\n");
++ printk("* CIPHER CORE TESTING START *\n");
++ printk("*******************************************************************\n");
++
++ /* Enable the clock to the DPE block */
++ writel(1UL << SYS_CTRL_CKEN_DPE_BIT, SYS_CTRL_CKEN_SET_CTRL);
++
++ /* Bring out of reset */
++ writel(1UL << SYS_CTRL_RSTEN_DPE_BIT, SYS_CTRL_RSTEN_CLR_CTRL);
++
++
++
++
++ for (i = 0; i < NOCIPHERTESTS; ++i)
++ {
++ printk("\nTest %d start\n",i+1);
++ result = (tests[i])();
++ if (result)
++ printk("Test %d failed with %d faults.\n",i+1,result);
++ else
++ printk("Test %d passed\n",i+1);
++
++ }
++
++ printk("*******************************************************************\n");
++ printk("* CIPHER CORE TESTING END *\n");
++ printk("*******************************************************************\n");
++
++ return 0;
++}
++
++
++
++/***************************************************************************/
++module_init(ox800dpe_init);
+diff -Nurd linux-2.6.24/arch/arm/mach-hipox/gmac-napi.c linux-2.6.24-oxe810/arch/arm/mach-hipox/gmac-napi.c
+--- linux-2.6.24/arch/arm/mach-hipox/gmac-napi.c 1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.24-oxe810/arch/arm/mach-hipox/gmac-napi.c 2008-06-11 17:47:55.000000000 +0200
+@@ -0,0 +1,3637 @@
++/*
++ * linux/arch/arm/mach-hipox/gmac.c
++ *
++ * Copyright (C) 2005 Oxford Semiconductor Ltd
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License as published by
++ * the Free Software Foundation; either version 2 of the License, or
++ * (at your option) any later version.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
++ * GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program; if not, write to the Free Software
++ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
++ */
++
++#include <linux/crc32.h>
++#include <linux/version.h>
++#include <linux/init.h>
++#include <linux/errno.h>
++#include <linux/netdevice.h>
++#include <linux/etherdevice.h>
++#include <linux/dma-mapping.h>
++#include <linux/delay.h>
++#include <linux/in.h>
++#include <net/ip.h>
++#include <linux/tcp.h>
++#include <linux/udp.h>
++#include <asm/io.h>
++#include <asm/arch/hardware.h>
++#include <asm/arch/irqs.h>
++
++#ifdef CONFIG_LEON_COPRO
++#include <asm/arch/leon-program.h>
++#endif // CONFIG_LEON_COPRO
++
++//#define GMAC_DEBUG
++#undef GMAC_DEBUG
++
++#include "gmac.h"
++#include "gmac_ethtool.h"
++#include "gmac_phy.h"
++#include "gmac_desc.h"
++#include "gmac_reg.h"
++
++//#define DUMP_REGS_ON_GMAC_UP
++
++#define MAX_GMAC_UNITS 1
++
++#define ALLOW_AUTONEG
++
++//#define ALLOW_OX800_1000M
++
++//#define SUPPORT_IPV6
++
++#ifdef CONFIG_LEON_COPRO
++//#define TEST_COPRO
++#define COPRO_RX_MITIGATION 0 /* No Rx mitigation in CoPro */
++#define COPRO_RX_MITIGATION_FRAMES 5
++#define COPRO_RX_MITIGATION_USECS 500
++
++#define COPRO_TX_QUEUE_NUM_ENTRIES 4
++#define COPRO_CMD_QUEUE_NUM_ENTRIES 6
++#define COPRO_MAX_QUEUED_TX_SKBS 16
++#endif // CONFIG_LEON_COPRO
++
++#ifdef CONFIG_LEON_OFFLOAD_TX
++#define NUM_RX_DMA_DESCRIPTORS NUM_GMAC_DMA_DESCRIPTORS
++#define NUM_TX_DMA_DESCRIPTORS 0
++#else
++#define NUM_RX_DMA_DESCRIPTORS (NUM_GMAC_DMA_DESCRIPTORS / 2)
++#define NUM_TX_DMA_DESCRIPTORS (NUM_GMAC_DMA_DESCRIPTORS - NUM_RX_DMA_DESCRIPTORS)
++#endif // CONFIG_LEON_OFFLOAD_TX
++
++#if (((NUM_RX_DMA_DESCRIPTORS) + (NUM_TX_DMA_DESCRIPTORS)) > (NUM_GMAC_DMA_DESCRIPTORS))
++#error "GMAC TX+RX descriptors exceed allocation"
++#endif
++
++#define DESC_SINCE_REFILL_LIMIT ((NUM_RX_DMA_DESCRIPTORS) / 4)
++
++static const u32 MAC_BASE_OFFSET = 0x0000;
++static const u32 DMA_BASE_OFFSET = 0x1000;
++
++static const int MIN_PACKET_SIZE = 68;
++static const int NORMAL_PACKET_SIZE = 1500;
++static const int MAX_JUMBO = 9000;
++
++#define RX_BUFFER_SIZE 796 // Must be multiple of 4, If not defined will size buffer to hold a single MTU-sized packet
++
++#ifdef CONFIG_HIPOX_VERSION_0X800
++static const int EXTRA_RX_SKB_SPACE = 24; // Has extra 2 bytes of Rx payload csum
++#else // CONFIG_HIPOX_VERSION_0X800
++static const int EXTRA_RX_SKB_SPACE = 22; // Ethernet header 14, VLAN 4, CRC 4
++#endif // CONFIG_HIPOX_VERSION_0X800
++
++// The amount of header to copy from a receive packet into the skb buffer
++static const int GMAC_HLEN = 66;
++
++#define GMAC_ALLOC_ORDER 0
++static const int GMAC_ALLOC_SIZE = ((1 << GMAC_ALLOC_ORDER) * PAGE_SIZE);
++
++static const u32 AUTO_NEGOTIATION_WAIT_TIMEOUT_MS = 5000;
++
++static const u32 NAPI_POLL_WEIGHT = 64;
++static const u32 NAPI_OOM_POLL_INTERVAL_MS = 50;
++
++static const int WATCHDOG_TIMER_INTERVAL = 500*HZ/1000;
++
++#define AUTO_NEG_MS_WAIT 500
++static const int AUTO_NEG_INTERVAL = (AUTO_NEG_MS_WAIT)*HZ/1000;
++static const int START_RESET_INTERVAL = 50*HZ/1000;
++static const int RESET_INTERVAL = 10*HZ/1000;
++
++static const int GMAC_RESET_TIMEOUT_MS = 10000;
++
++static int debug = 0;
++
++MODULE_AUTHOR("Brian Clarke (Oxford Semiconductor Ltd)");
++MODULE_DESCRIPTION("GMAC Network Driver");
++MODULE_LICENSE("GPL");
++MODULE_VERSION("v2.0");
++
++/* Ethernet MAC adr to assign to interface */
++static int mac_adr[] = { 0x00, 0x30, 0xe0, 0x00, 0x00, 0x00 };
++module_param_array(mac_adr, int, NULL, S_IRUGO);
++
++/* PHY type kernel cmdline options */
++static int phy_is_rgmii = 0;
++module_param(phy_is_rgmii, int, S_IRUGO);
++
++/* Parse netdev kernel cmdline options */
++static int __init do_setup(char *str)
++{
++ int i;
++ int ints[5]; // Hold arg count and four args
++ u32 mac_hi = 0;
++ u32 mac_lo = 0;
++
++ /* Get the netdev bootargs parameters */
++ get_options(str, sizeof(ints)/sizeof(int), ints);
++ for (i=1; i<=ints[0]; i++) {
++ switch (i) {
++ case 3:
++ mac_hi = ints[i];
++ break;
++ case 4:
++ mac_lo = ints[i];
++ break;
++ }
++ }
++
++ /* Break down the mac adr into its components */
++ for (i=0; i < sizeof(mac_adr)/sizeof(int); i++) {
++ if (i < sizeof(u32)) {
++ mac_adr[i] = ((mac_hi >> (((sizeof(u32)-1)-i)*8)) & 0xff);
++ } else {
++ mac_adr[i] = ((mac_lo >> (((sizeof(u32)+1)-i)*8)) & 0xff);
++ }
++ }
++
++ return 0;
++}
++__setup("netdev=",do_setup);
++
++#ifdef DUMP_REGS_ON_GMAC_UP
++static void dump_mac_regs(u32 macBase, u32 dmaBase)
++{
++ int n = 0;
++
++ for (n=0; n<0x60; n+=4) {
++ printk(KERN_INFO "MAC Register %08x (%08x) = %08x\n", n, macBase+n, readl(macBase+n));
++ }
++
++ for (n=0; n<0x60; n+=4) {
++ printk(KERN_INFO "DMA Register %08x (%08x) = %08x\n", n, dmaBase+n, readl(dmaBase+n));
++ }
++}
++#endif // DUMP_REGS_ON_GMAC_UP
++
++#ifdef CONFIG_LEON_COPRO
++static struct semaphore copro_update_semaphore;
++
++static void copro_update_callback(volatile gmac_cmd_que_ent_t* entry)
++{
++ up(&copro_update_semaphore);
++}
++
++static struct semaphore copro_start_semaphore;
++
++static void copro_start_callback(volatile gmac_cmd_que_ent_t* entry)
++{
++ up(&copro_start_semaphore);
++}
++
++static struct semaphore copro_rx_enable_semaphore;
++
++static void copro_rx_enable_callback(volatile gmac_cmd_que_ent_t* entry)
++{
++ up(&copro_rx_enable_semaphore);
++}
++#endif // CONFIG_LEON_COPRO
++
++static void gmac_int_en_set(
++ gmac_priv_t *priv,
++ u32 mask)
++{
++ unsigned long irq_flags = 0;
++
++#ifdef CONFIG_LEON_COPRO
++ int cmd_queue_result = -1;
++ while (cmd_queue_result) {
++ if (in_irq())
++ spin_lock(&priv->cmd_que_lock_);
++ else
++ spin_lock_irqsave(&priv->cmd_que_lock_, irq_flags);
++
++ cmd_queue_result = cmd_que_queue_cmd(&priv->cmd_queue_, GMAC_CMD_INT_EN_SET, mask, 0);
++
++ if (in_irq())
++ spin_unlock(&priv->cmd_que_lock_);
++ else
++ spin_unlock_irqrestore(&priv->cmd_que_lock_, irq_flags);
++ }
++
++ // Interrupt the CoPro so it sees the new command
++ writel(1UL << COPRO_SEM_INT_CMD, SYS_CTRL_SEMA_SET_CTRL);
++#else
++ if (in_irq())
++ spin_lock(&priv->cmd_que_lock_);
++ else
++ spin_lock_irqsave(&priv->cmd_que_lock_, irq_flags);
++
++ dma_reg_set_mask(priv, DMA_INT_ENABLE_REG, mask);
++
++ if (in_irq())
++ spin_unlock(&priv->cmd_que_lock_);
++ else
++ spin_unlock_irqrestore(&priv->cmd_que_lock_, irq_flags);
++#endif // CONFIG_LEON_COPRO
++}
++
++#ifdef CONFIG_LEON_COPRO
++static struct semaphore copro_int_clr_semaphore;
++static unsigned long copro_int_clr_return;
++
++static void copro_int_clr_callback(volatile gmac_cmd_que_ent_t* entry)
++{
++ copro_int_clr_return = entry->operand_;
++ up(&copro_int_clr_semaphore);
++}
++#endif // CONFIG_LEON_COPRO
++
++static void gmac_int_en_clr(
++ gmac_priv_t *priv,
++ u32 mask,
++ u32 *new_value,
++ int in_atomic)
++{
++#ifdef CONFIG_LEON_COPRO
++ unsigned long irq_flags = 0;
++
++ int cmd_queue_result = -1;
++ while (cmd_queue_result) {
++ if (in_irq())
++ spin_lock(&priv->cmd_que_lock_);
++ else
++ spin_lock_irqsave(&priv->cmd_que_lock_, irq_flags);
++
++ cmd_queue_result = cmd_que_queue_cmd(&priv->cmd_queue_, GMAC_CMD_INT_EN_CLR, mask, copro_int_clr_callback);
++
++ if (in_irq())
++ spin_unlock(&priv->cmd_que_lock_);
++ else
++ spin_unlock_irqrestore(&priv->cmd_que_lock_, irq_flags);
++ }
++
++ // Interrupt the CoPro so it sees the new command
++ writel(1UL << COPRO_SEM_INT_CMD, SYS_CTRL_SEMA_SET_CTRL);
++
++ if (new_value) {
++ // Wait until the CoPro acknowledges that it has stopped
++ if (in_atomic) {
++ while (down_trylock(&copro_int_clr_semaphore)) {
++ udelay(100);
++ }
++ } else {
++ down_interruptible(&copro_int_clr_semaphore);
++ }
++ *new_value = copro_int_clr_return;
++ }
++#else
++ unsigned long temp;
++ unsigned long irq_flags = 0;
++
++ if (in_irq())
++ spin_lock(&priv->cmd_que_lock_);
++ else
++ spin_lock_irqsave(&priv->cmd_que_lock_, irq_flags);
++
++ temp = dma_reg_clear_mask(priv, DMA_INT_ENABLE_REG, mask);
++
++ if (in_irq())
++ spin_unlock(&priv->cmd_que_lock_);
++ else
++ spin_unlock_irqrestore(&priv->cmd_que_lock_, irq_flags);
++
++ if (new_value) {
++ *new_value = temp;
++ }
++#endif
++}
++
++/**
++ * May be invoked from either ISR or process context, so locking must be
++ * invoked appropriate to the return from in_irq()
++ */
++static void change_rx_enable(
++ gmac_priv_t *priv,
++ u32 start,
++ int waitForAck,
++ int in_atomic)
++{
++#ifdef CONFIG_LEON_COPRO
++ unsigned long irq_flags = 0;
++ int cmd_queue_result = -1;
++
++ while (cmd_queue_result) {
++ if (in_irq())
++ spin_lock(&priv->cmd_que_lock_);
++ else
++ spin_lock_irqsave(&priv->cmd_que_lock_, irq_flags);
++
++ // Request the CoPro to start/stop GMAC receiver
++ cmd_queue_result =
++ cmd_que_queue_cmd(&priv->cmd_queue_,
++ GMAC_CMD_CHANGE_RX_ENABLE,
++ start,
++ waitForAck ? copro_rx_enable_callback : 0);
++
++ if (in_irq())
++ spin_unlock(&priv->cmd_que_lock_);
++ else
++ spin_unlock_irqrestore(&priv->cmd_que_lock_, irq_flags);
++ }
++
++ // Interrupt the CoPro so it sees the new command
++ writel(1UL << COPRO_SEM_INT_CMD, SYS_CTRL_SEMA_SET_CTRL);
++
++ if (waitForAck) {
++ // Wait until the CoPro acknowledges that the receiver has been stopped
++ if (in_atomic) {
++ while (down_trylock(&copro_rx_enable_semaphore)) {
++ udelay(100);
++ }
++ } else {
++ down_interruptible(&copro_rx_enable_semaphore);
++ }
++ }
++#else // CONFIG_LEON_COPRO
++ start ? dma_reg_set_mask(priv, DMA_OP_MODE_REG, 1UL << DMA_OP_MODE_SR_BIT) :
++ dma_reg_clear_mask(priv, DMA_OP_MODE_REG, 1UL << DMA_OP_MODE_SR_BIT);
++#endif // CONFIG_LEON_COPRO
++}
++
++/**
++ * Invoked from the watchdog timer action routine which runs as softirq, so
++ * must disable interrupts when obtaining locks
++ */
++static void change_gig_mode(gmac_priv_t *priv)
++{
++ unsigned int is_gig = priv->mii.using_1000;
++
++#ifdef CONFIG_LEON_COPRO
++ unsigned long irq_flags = 0;
++ int cmd_queue_result = -1;
++
++ while (cmd_queue_result) {
++ spin_lock_irqsave(&priv->cmd_que_lock_, irq_flags);
++ // Request the CoPro to change gigabit mode
++ cmd_queue_result = cmd_que_queue_cmd(&priv->cmd_queue_, GMAC_CMD_CHANGE_GIG_MODE, is_gig, 0);
++ spin_unlock_irqrestore(&priv->cmd_que_lock_, irq_flags);
++ }
++
++ // Interrupt the CoPro so it sees the new command
++ writel(1UL << COPRO_SEM_INT_CMD, SYS_CTRL_SEMA_SET_CTRL);
++#else // CONFIG_LEON_COPRO
++ static const int MAX_TRIES = 1000;
++ int tries = 0;
++
++ // Mask to extract the transmit status field from the status register
++ u32 ts_mask = ((1UL << DMA_STATUS_TS_NUM_BITS) - 1) << DMA_STATUS_TS_BIT;
++
++ // Must stop transmission in order to change store&forward mode
++ dma_reg_clear_mask(priv, DMA_OP_MODE_REG, (1UL << DMA_OP_MODE_ST_BIT));
++
++ // Transmission only stops after current Tx frame has completed trans-
++ // mission, so wait for the Tx state machine to enter the stopped state
++ while ((dma_reg_read(priv, DMA_STATUS_REG) & ts_mask) != (DMA_STATUS_TS_STOPPED << DMA_STATUS_TS_BIT)) {
++ mdelay(1);
++ if (unlikely(++tries == MAX_TRIES)) {
++ break;
++ }
++ }
++
++ if (unlikely(tries == MAX_TRIES)) {
++ printk(KERN_WARNING "Timed out of wait for Tx to stop\n");
++ }
++
++ if (is_gig) {
++ mac_reg_clear_mask(priv, MAC_CONFIG_REG, (1UL << MAC_CONFIG_PS_BIT));
++#ifdef CONFIG_HIPOX_VERSION_0X800
++ // In gigabit mode the OX800 cannot support the required data rate to
++ // the GMAC, so must use store&forward and OX800 doesn't support Tx
++ // checksumming in the GMAC
++ dma_reg_set_mask(priv, DMA_OP_MODE_REG, (1UL << DMA_OP_MODE_SF_BIT));
++#endif // CONFIG_HIPOX_VERSION_0X800
++ } else {
++ mac_reg_set_mask(priv, MAC_CONFIG_REG, (1UL << MAC_CONFIG_PS_BIT));
++#ifdef CONFIG_HIPOX_VERSION_0X800
++ dma_reg_clear_mask(priv, DMA_OP_MODE_REG, (1UL << DMA_OP_MODE_SF_BIT));
++#endif // CONFIG_HIPOX_VERSION_0X800
++ }
++
++ // Re-start transmission after store&forward change applied
++ dma_reg_set_mask(priv, DMA_OP_MODE_REG, (1UL << DMA_OP_MODE_ST_BIT));
++#endif // CONFIG_LEON_COPRO
++}
++
++/**
++ * Invoked from the watchdog timer action routine which runs as softirq, so
++ * must disable interrupts when obtaining locks
++ */
++static void change_pause_mode(gmac_priv_t *priv)
++{
++#ifdef CONFIG_LEON_COPRO
++ unsigned int enable_pause = priv->mii.using_pause;
++ unsigned long irq_flags = 0;
++ int cmd_queue_result = -1;
++
++ while (cmd_queue_result) {
++ spin_lock_irqsave(&priv->cmd_que_lock_, irq_flags);
++ // Request the CoPro to change pause mode
++ cmd_queue_result = cmd_que_queue_cmd(&priv->cmd_queue_, GMAC_CMD_CHANGE_PAUSE_MODE, enable_pause, 0);
++ spin_unlock_irqrestore(&priv->cmd_que_lock_, irq_flags);
++ }
++
++ // Interrupt the CoPro so it sees the new command
++ writel(1UL << COPRO_SEM_INT_CMD, SYS_CTRL_SEMA_SET_CTRL);
++#else // CONFIG_LEON_COPRO
++#ifndef CONFIG_HIPOX_VERSION_0X800
++ unsigned int enable_pause = priv->mii.using_pause;
++
++ if (enable_pause) {
++ mac_reg_set_mask(priv, MAC_FLOW_CNTL_REG, (1UL << MAC_FLOW_CNTL_TFE_BIT));
++ } else {
++ mac_reg_clear_mask(priv, MAC_FLOW_CNTL_REG, (1UL << MAC_FLOW_CNTL_TFE_BIT));
++ }
++#endif // !CONFIG_HIPOX_VERSION_0X800
++#endif // CONFIG_LEON_COPRO
++}
++
++static void refill_rx_ring(struct net_device *dev)
++{
++ gmac_priv_t *priv = (gmac_priv_t*)netdev_priv(dev);
++ int filled = 0;
++
++ if (unlikely(priv->rx_buffers_per_page)) {
++ // Receive into pages
++ struct page *page = 0;
++ int offset = 0;
++ dma_addr_t phys_adr = 0;
++
++ // While there are empty RX descriptor ring slots
++ while (1) {
++ int available;
++ int desc;
++ rx_frag_info_t frag_info;
++
++ // Have we run out of space in the current page?
++ if (offset + NET_IP_ALIGN + priv->rx_buffer_size_ > GMAC_ALLOC_SIZE) {
++ page = 0;
++ offset = 0;
++ }
++
++ if (!page) {
++ // Start a new page
++ available = available_for_write(&priv->rx_gmac_desc_list_info);
++ if (available < priv->rx_buffers_per_page) {
++ break;
++ }
++
++ // Allocate a page to hold a received packet
++ page = alloc_pages(GFP_ATOMIC, GMAC_ALLOC_ORDER);
++ if (unlikely(page == NULL)) {
++ printk(KERN_WARNING "refill_rx_ring() Could not alloc page\n");
++ break;
++ }
++
++ // Get a consistent DMA mapping for the entire page that will be
++ // DMAed to - causing an invalidation of any entries in the CPU's
++ // cache covering the memory region
++ phys_adr = dma_map_page(0, page, 0, GMAC_ALLOC_SIZE, DMA_FROM_DEVICE);
++ BUG_ON(dma_mapping_error(phys_adr));
++ } else {
++ // Using the current page again
++ get_page(page);
++ }
++
++ // Ensure IP header is quad aligned
++ offset += NET_IP_ALIGN;
++ frag_info.page = page;
++ frag_info.length = priv->rx_buffer_size_;
++ frag_info.phys_adr = phys_adr + offset;
++
++ // Try to associate a descriptor with the fragment info
++ desc = set_rx_descriptor(priv, &frag_info);
++ if (desc >= 0) {
++ filled = 1;
++ } else {
++ // Failed to associate the descriptor, so release the DMA mapping
++ // for the socket buffer
++ dma_unmap_page(0, frag_info.phys_adr, frag_info.length, DMA_FROM_DEVICE);
++
++ // No more RX descriptor ring entries to refill
++ break;
++ }
++
++ // Account for the space used in the current page
++ offset += frag_info.length;
++
++ // Start next packet on a cacheline boundary
++ offset = SKB_DATA_ALIGN(offset);
++ }
++ } else {
++ // Preallocate MTU-sized SKBs
++ while (1) {
++ struct sk_buff *skb;
++ rx_frag_info_t frag_info;
++ int desc;
++
++ if (!available_for_write(&priv->rx_gmac_desc_list_info)) {
++ break;
++ }
++
++ // Allocate a new skb for the descriptor ring which is large enough
++ // for any packet received from the link
++ skb = dev_alloc_skb(priv->rx_buffer_size_ + NET_IP_ALIGN);
++ if (!skb) {
++ // Can't refill any more RX descriptor ring entries
++ break;
++ } else {
++ // Despite what the comments in the original code from Synopsys
++ // claimed, the GMAC DMA can cope with non-quad aligned buffers
++ // - it will always perform quad transfers but zero/ignore the
++ // unwanted bytes.
++ skb_reserve(skb, NET_IP_ALIGN);
++ }
++
++ // Get a consistent DMA mapping for the memory to be DMAed to
++ // causing invalidation of any entries in the CPU's cache covering
++ // the memory region
++ frag_info.page = (struct page*)skb;
++ frag_info.length = skb_tailroom(skb);
++ frag_info.phys_adr = dma_map_single(0, skb->tail, frag_info.length, DMA_FROM_DEVICE);
++ BUG_ON(dma_mapping_error(frag_info.phys_adr));
++
++ // Associate the skb with the descriptor
++ desc = set_rx_descriptor(priv, &frag_info);
++ if (desc >= 0) {
++ filled = 1;
++ } else {
++ // No, so release the DMA mapping for the socket buffer
++ dma_unmap_single(0, frag_info.phys_adr, frag_info.length, DMA_FROM_DEVICE);
++
++ // Free the socket buffer
++ dev_kfree_skb(skb);
++
++ // No more RX descriptor ring entries to refill
++ break;
++ }
++ }
++ }
++
++#ifndef CONFIG_HIPOX_VERSION_0X800
++ if (likely(filled)) {
++ // Issue a RX poll demand to restart RX descriptor processing and DFF
++ // mode does not automatically restart descriptor processing after a
++ // descriptor unavailable event
++ dma_reg_write(priv, DMA_RX_POLL_REG, 0);
++ }
++#endif // !CONFIG_HIPOX_VERSION_0X800
++}
++
++static inline void set_phy_type_rgmii(void)
++{
++#ifndef CONFIG_HIPOX_VERSION_0X800
++ // Use sysctrl to switch MAC link lines into either (G)MII or RGMII mode
++ u32 reg_contents = readl(SYS_CTRL_GMAC_CTRL);
++ reg_contents |= (1UL << SYS_CTRL_GMAC_RGMII);
++ writel(reg_contents, SYS_CTRL_RSTEN_SET_CTRL);
++#endif // !CONFIG_HIPOX_VERSION_0X800
++}
++
++static void initialise_phy(gmac_priv_t* priv)
++{
++ switch (priv->phy_type) {
++ case PHY_TYPE_VITESSE_VSC8201XVZ:
++ {
++ // Allow s/w to override mode/duplex pin settings
++ u32 acsr = priv->mii.mdio_read(priv->netdev, priv->mii.phy_id, VSC8201_MII_ACSR);
++
++ printk(KERN_INFO "%s: PHY is Vitesse VSC8201XVZ\n", priv->netdev->name);
++ acsr |= (1UL << VSC8201_MII_ACSR_MDPPS_BIT);
++ priv->mii.mdio_write(priv->netdev, priv->mii.phy_id, VSC8201_MII_ACSR, acsr);
++ }
++ break;
++ case PHY_TYPE_REALTEK_RTL8211BGR:
++ printk(KERN_INFO "%s: PHY is Realtek RTL8211BGR\n", priv->netdev->name);
++ set_phy_type_rgmii();
++ break;
++ case PHY_TYPE_LSI_ET1011C:
++ case PHY_TYPE_LSI_ET1011C2:
++ {
++ u32 phy_reg;
++
++ printk(KERN_INFO "%s: PHY is LSI ET1011C\n", priv->netdev->name);
++
++ // Configure clocks
++ phy_reg = priv->mii.mdio_read(priv->netdev, priv->mii.phy_id, ET1011C_MII_CONFIG);
++ phy_reg &= ~(((1UL << ET1011C_MII_CONFIG_IFMODESEL_NUM_BITS) - 1) << ET1011C_MII_CONFIG_IFMODESEL);
++ phy_reg |= (ET1011C_MII_CONFIG_IFMODESEL_GMII_MII << ET1011C_MII_CONFIG_IFMODESEL);
++ phy_reg |= ((1UL << ET1011C_MII_CONFIG_SYSCLKEN) |
++ (1UL << ET1011C_MII_CONFIG_TXCLKEN) |
++ (1UL << ET1011C_MII_CONFIG_TBI_RATESEL) |
++ (1UL << ET1011C_MII_CONFIG_CRS_TX_EN));
++ priv->mii.mdio_write(priv->netdev, priv->mii.phy_id, ET1011C_MII_CONFIG, phy_reg);
++
++ // Enable Tx/Rx LED
++ phy_reg = priv->mii.mdio_read(priv->netdev, priv->mii.phy_id, ET1011C_MII_LED2);
++ phy_reg &= ~(((1UL << ET1011C_MII_LED2_LED_NUM_BITS) - 1) << ET1011C_MII_LED2_LED_TXRX);
++ phy_reg |= (ET1011C_MII_LED2_LED_TXRX_ACTIVITY << ET1011C_MII_LED2_LED_TXRX);
++ priv->mii.mdio_write(priv->netdev, priv->mii.phy_id, ET1011C_MII_LED2, phy_reg);
++ }
++ break;
++ case PHY_TYPE_ICPLUS_IP1001:
++ printk(KERN_INFO "%s: PHY is ICPlus 1001\n", priv->netdev->name);
++ break;
++ }
++}
++
++static struct kobj_type ktype_gmac_link_state = {
++ .release = 0,
++ .sysfs_ops = 0,
++ .default_attrs = 0,
++};
++
++static int gmac_link_state_hotplug_filter(struct kset* kset, struct kobject* kobj) {
++ return get_ktype(kobj) == &ktype_gmac_link_state;
++}
++
++static const char* gmac_link_state_hotplug_name(struct kset* kset, struct kobject* kobj) {
++ return "gmac_link_state";
++}
++
++static struct kset_uevent_ops gmac_link_state_uevent_ops = {
++ .filter = gmac_link_state_hotplug_filter,
++ .name = gmac_link_state_hotplug_name,
++ .uevent = NULL,
++};
++
++static int gmac_link_state_init_sysfs(gmac_priv_t* priv)
++{
++ int err = 0;
++
++ /* Prepare the sysfs interface for use */
++ kobject_set_name(&priv->link_state_kset.kobj, "gmac_link_state");
++ priv->link_state_kset.ktype = &ktype_gmac_link_state;
++
++ err = subsystem_register(&priv->link_state_kset);
++ if (err)
++ return err;
++
++ /* Setup hotplugging */
++ priv->link_state_kset.uevent_ops = &gmac_link_state_uevent_ops;
++
++ /* Setup the heirarchy, the name will be set on detection */
++ kobject_init(&priv->link_state_kobject);
++ priv->link_state_kobject.kset = kset_get(&priv->link_state_kset);
++ priv->link_state_kobject.parent = &priv->link_state_kset.kobj;
++
++ /* Build the sysfs entry */
++ kobject_set_name(&priv->link_state_kobject, "gmac_link_state-1");
++ return kobject_add(&priv->link_state_kobject);
++}
++
++static void work_handler(struct work_struct *ws) {
++ gmac_priv_t *priv = container_of(ws, gmac_priv_t, link_state_change_work);
++
++ kobject_uevent(&priv->link_state_kobject, priv->link_state ? KOBJ_ONLINE : KOBJ_OFFLINE);
++}
++
++static void link_state_change_callback(
++ int link_state,
++ void *arg)
++{
++ gmac_priv_t* priv = (gmac_priv_t*)arg;
++
++ priv->link_state = link_state;
++ schedule_work(&priv->link_state_change_work);
++}
++
++static void start_watchdog_timer(gmac_priv_t* priv)
++{
++ priv->watchdog_timer.expires = jiffies + WATCHDOG_TIMER_INTERVAL;
++ priv->watchdog_timer_shutdown = 0;
++ mod_timer(&priv->watchdog_timer, priv->watchdog_timer.expires);
++}
++
++static void delete_watchdog_timer(gmac_priv_t* priv)
++{
++ // Ensure link/PHY state watchdog timer won't be invoked again
++ priv->watchdog_timer_shutdown = 1;
++ del_timer_sync(&priv->watchdog_timer);
++}
++
++static inline int is_auto_negotiation_in_progress(gmac_priv_t* priv)
++{
++ return !(phy_read(priv->netdev, priv->phy_addr, MII_BMSR) & BMSR_ANEGCOMPLETE);
++}
++
++static void watchdog_timer_action(unsigned long arg)
++{
++ typedef enum watchdog_state {
++ WDS_IDLE,
++ WDS_RESETTING,
++ WDS_NEGOTIATING
++ } watchdog_state_t;
++
++ static int state = WDS_IDLE;
++
++ gmac_priv_t* priv = (gmac_priv_t*)arg;
++ unsigned long new_timeout = jiffies + WATCHDOG_TIMER_INTERVAL;
++#ifndef ARMULATING
++ int ready;
++ int duplex_changed;
++ int gigabit_changed;
++ int pause_changed;
++
++ // Interpret the PHY/link state.
++ if (priv->phy_force_negotiation || (state == WDS_RESETTING)) {
++ mii_check_link(&priv->mii);
++ ready = 0;
++ } else {
++ duplex_changed = mii_check_media_ex(&priv->mii, 1, priv->mii_init_media, &gigabit_changed, &pause_changed, link_state_change_callback, priv);
++ priv->mii_init_media = 0;
++ ready = netif_carrier_ok(priv->netdev);
++ }
++
++ if (!ready) {
++ if (priv->phy_force_negotiation) {
++ if (netif_carrier_ok(priv->netdev)) {
++ state = WDS_RESETTING;
++ } else {
++ state = WDS_IDLE;
++ }
++
++ priv->phy_force_negotiation = 0;
++ }
++
++ // May be a good idea to restart everything here, in an attempt to clear
++ // out any fault conditions
++ if ((state == WDS_NEGOTIATING) && is_auto_negotiation_in_progress(priv)) {
++ new_timeout = jiffies + AUTO_NEG_INTERVAL;
++ } else {
++ switch (state) {
++ case WDS_IDLE:
++ // Reset the PHY to get it into a known state
++ start_phy_reset(priv);
++ new_timeout = jiffies + START_RESET_INTERVAL;
++ state = WDS_RESETTING;
++ break;
++ case WDS_RESETTING:
++ if (!is_phy_reset_complete(priv)) {
++ new_timeout = jiffies + RESET_INTERVAL;
++ } else {
++ // Force or auto-negotiate PHY mode
++ set_phy_negotiate_mode(priv->netdev);
++
++ // Set PHY specfic features
++ initialise_phy(priv);
++
++ state = WDS_NEGOTIATING;
++ new_timeout = jiffies + AUTO_NEG_INTERVAL;
++ }
++ break;
++ default:
++ DBG(1, KERN_ERR "watchdog_timer_action() %s: Unexpected state\n", priv->netdev->name);
++ state = WDS_IDLE;
++ break;
++ }
++ }
++ } else {
++ state = WDS_IDLE;
++ if (duplex_changed) {
++ priv->mii.full_duplex ? mac_reg_set_mask(priv, MAC_CONFIG_REG, (1UL << MAC_CONFIG_DM_BIT)) :
++ mac_reg_clear_mask(priv, MAC_CONFIG_REG, (1UL << MAC_CONFIG_DM_BIT));
++ }
++
++ if (gigabit_changed) {
++ change_gig_mode(priv);
++ }
++
++ if (pause_changed) {
++ change_pause_mode(priv);
++ }
++ }
++#endif // !ARMULATING
++
++ // Re-trigger the timer, unless some other thread has requested it be stopped
++ if (!priv->watchdog_timer_shutdown) {
++ // Restart the timer
++ mod_timer(&priv->watchdog_timer, new_timeout);
++ }
++}
++
++static int inline is_ip_packet(unsigned short eth_protocol)
++{
++ return (eth_protocol == ETH_P_IP)
++#ifdef SUPPORT_IPV6
++ || (eth_protocol == ETH_P_IPV6)
++#endif // SUPPORT_IPV6
++ ;
++}
++
++static int inline is_ipv4_packet(unsigned short eth_protocol)
++{
++ return eth_protocol == ETH_P_IP;
++}
++
++#ifdef SUPPORT_IPV6
++static int inline is_ipv6_packet(unsigned short eth_protocol)
++{
++ return eth_protocol == ETH_P_IPV6;
++}
++#endif // SUPPORT_IPV6
++
++static int inline is_hw_checksummable(unsigned short protocol)
++{
++ return (protocol == IPPROTO_TCP) || (protocol == IPPROTO_UDP)
++#ifndef CONFIG_HIPOX_VERSION_0X800
++ || (protocol == IPPROTO_ICMP)
++#endif // !CONFIG_HIPOX_VERSION_0X800
++ ;
++}
++
++static u32 unmap_rx_page(
++ gmac_priv_t *priv,
++ dma_addr_t phys_adr)
++{
++ u32 offset = phys_adr & ~PAGE_MASK;
++ u32 next_offset = offset + priv->rx_buffer_size_;
++ next_offset = SKB_DATA_ALIGN(next_offset);
++ next_offset += NET_IP_ALIGN;
++
++ // If this is the last packet in a page
++ if (next_offset > GMAC_ALLOC_SIZE) {
++ // Release the DMA mapping for the page
++ dma_unmap_page(0, phys_adr & PAGE_MASK, GMAC_ALLOC_SIZE, DMA_FROM_DEVICE);
++ }
++
++ return offset;
++}
++
++#define FCS_LEN 4 // Ethernet CRC length
++#ifdef CONFIG_HIPOX_VERSION_0X800
++#define HW_CSUM_LEN 2 // The OX800 H/W appending partial csum length
++#endif // CONFIG_HIPOX_VERSION_0X800
++
++static inline int get_desc_len(
++ u32 desc_status,
++ int last)
++{
++ int length = get_rx_length(desc_status);
++
++ if (last) {
++ length -= FCS_LEN;
++#if defined(CONFIG_HIPOX_VERSION_0X800) && defined(USE_RX_CSUM)
++ length -= HW_CSUM_LEN;
++#endif // CONFIG_HIPOX_VERSION_0X800 && USE_RX_CSUM
++ }
++
++ return length;
++}
++
++static int process_rx_packet_skb(gmac_priv_t *priv)
++{
++ int desc;
++ int last;
++ u32 desc_status = 0;
++ rx_frag_info_t frag_info;
++ int packet_len;
++ struct sk_buff *skb;
++ int valid;
++ int ip_summed;
++
++ desc = get_rx_descriptor(priv, &last, &desc_status, &frag_info);
++ if (desc < 0) {
++ return 0;
++ }
++
++ // Release the DMA mapping for the received data
++ dma_unmap_single(0, frag_info.phys_adr, frag_info.length, DMA_FROM_DEVICE);
++
++ // Get the packet data length
++ packet_len = get_desc_len(desc_status, last);
++
++ // Get pointer to the SKB
++ skb = (struct sk_buff*)frag_info.page;
++
++ // Is the packet entirely contained within the descriptors and without errors?
++ valid = !(desc_status & (1UL << RDES0_ES_BIT));
++
++ if (unlikely(!valid)) {
++ goto not_valid_skb;
++ }
++
++ ip_summed = CHECKSUM_NONE;
++
++#ifdef USE_RX_CSUM
++ // Has the h/w flagged an IP header checksum failure?
++ valid = !(desc_status & (1UL << RDES0_IPC_BIT));
++
++ if (likely(valid)) {
++ // Determine whether Ethernet frame contains an IP packet -
++ // only bother with Ethernet II frames, but do cope with
++ // 802.1Q VLAN tag presence
++ int vlan_offset = 0;
++ unsigned short eth_protocol = ntohs(((struct ethhdr*)skb->data)->h_proto);
++ int is_ip = is_ip_packet(eth_protocol);
++
++ if (!is_ip) {
++ // Check for VLAN tag
++ if (eth_protocol == ETH_P_8021Q) {
++ // Extract the contained protocol type from after
++ // the VLAN tag
++ eth_protocol = ntohs(*(unsigned short*)(skb->data + ETH_HLEN));
++ is_ip = is_ip_packet(eth_protocol);
++
++ // Adjustment required to skip the VLAN stuff and
++ // get to the IP header
++ vlan_offset = 4;
++ }
++ }
++
++ // Only offload checksum calculation for IP packets
++ if (is_ip) {
++#ifdef CONFIG_HIPOX_VERSION_0X800
++ u16 payload_length = 0;
++#endif // CONFIG_HIPOX_VERSION_0X800
++ struct iphdr* ipv4_header = 0;
++
++#ifndef CONFIG_HIPOX_VERSION_0X800
++ if (unlikely(desc_status & (1UL << RDES0_PCE_BIT))) {
++ valid = 0;
++ } else
++#endif // !CONFIG_HIPOX_VERSION_0X800
++ if (is_ipv4_packet(eth_protocol)) {
++ ipv4_header = (struct iphdr*)(skb->data + ETH_HLEN + vlan_offset);
++
++ // H/W can only checksum non-fragmented IP packets
++ if (!(ipv4_header->frag_off & htons(IP_MF | IP_OFFSET))) {
++#ifdef CONFIG_HIPOX_VERSION_0X800
++ switch (ipv4_header->protocol) {
++ case IPPROTO_TCP:
++ // Compute TCP pseudo-header checksum
++ payload_length = ntohs(ipv4_header->tot_len) - (ipv4_header->ihl*4);
++ break;
++ case IPPROTO_UDP:
++ {
++ struct udphdr* udp_header = (struct udphdr*)((u8*)ipv4_header + (ipv4_header->ihl*4));
++ payload_length = ntohs(udp_header->len);
++ }
++ break;
++ default:
++ // Not supporting any other than TCP/UDP
++ break;
++ }
++#else // CONFIG_HIPOX_VERSION_0X800
++ if (is_hw_checksummable(ipv4_header->protocol)) {
++ ip_summed = CHECKSUM_UNNECESSARY;
++ }
++#endif // CONFIG_HIPOX_VERSION_0X800
++ }
++ }
++#ifndef CONFIG_HIPOX_VERSION_0X800
++ else {
++#ifdef SUPPORT_IPV6
++ struct ipv6hdr* ipv6_header = (struct ipv6hdr*)(skb->data + ETH_HLEN + vlan_offset);
++
++ if (is_hw_checksummable(ipv6_header->nexthdr)) {
++ ip_summed = CHECKSUM_UNNECESSARY;
++ }
++#endif // SUPPORT_IPV6
++ }
++#endif // !CONFIG_HIPOX_VERSION_0X800
++
++#ifdef CONFIG_HIPOX_VERSION_0X800
++ if (payload_length) {
++ // Get the hardware generated payload checksum from
++ // the end of the received packet, reverse the 1's
++ // complement operation that the h/w applies and add
++ // to the pseudo-header checksum, in network order
++ u16 hw_csum = ~(*(u16*)(skb->data + packet_len + FCS_LEN));
++
++ // Calculate checksum of pseudo header and payload
++ if (csum_tcpudp_magic(
++ ipv4_header->saddr,
++ ipv4_header->daddr,
++ payload_length,
++ ipv4_header->protocol,
++ hw_csum)) {
++ // Bad checksum, so indicate in descriptor status
++ desc_status |= (1UL << RDES0_IPC_BIT);
++ valid = 0;
++ } else {
++ ip_summed = CHECKSUM_UNNECESSARY;
++ }
++ }
++#endif // CONFIG_HIPOX_VERSION_0X800
++ }
++ }
++
++ if (unlikely(!valid)) {
++ goto not_valid_skb;
++ }
++#endif // USE_RX_CSUM
++
++ // Increase the skb's data pointer to account for the RX packet that has
++ // been DMAed into it
++ skb_put(skb, packet_len);
++
++ // Set the device for the skb
++ skb->dev = priv->netdev;
++
++ // Set packet protocol
++ skb->protocol = eth_type_trans(skb, priv->netdev);
++
++ // Record whether h/w checksumed the packet
++ skb->ip_summed = ip_summed;
++
++ // Send the packet up the network stack
++ netif_receive_skb(skb);
++
++ // Update receive statistics
++ priv->netdev->last_rx = jiffies;
++ ++priv->stats.rx_packets;
++ priv->stats.rx_bytes += packet_len;
++
++ return 1;
++
++not_valid_skb:
++ dev_kfree_skb(skb);
++
++ DBG(2, KERN_WARNING "process_rx_packet() %s: Received packet has bad desc_status = 0x%08x\n", priv->netdev->name, desc_status);
++
++ // Update receive statistics from the descriptor status
++ if (is_rx_collision_error(desc_status)) {
++ DBG(20, KERN_INFO "process_rx_packet() %s: Collision (0x%08x:%u bytes)\n", priv->netdev->name, desc_status, desc_len);
++ ++priv->stats.collisions;
++ }
++ if (is_rx_crc_error(desc_status)) {
++ DBG(20, KERN_INFO "process_rx_packet() %s: CRC error (0x%08x:%u bytes)\n", priv->netdev->name, desc_status, desc_len);
++ ++priv->stats.rx_crc_errors;
++ ++priv->stats.rx_errors;
++ }
++ if (is_rx_frame_error(desc_status)) {
++ DBG(20, KERN_INFO "process_rx_packet() %s: frame error (0x%08x:%u bytes)\n", priv->netdev->name, desc_status, desc_len);
++ ++priv->stats.rx_frame_errors;
++ ++priv->stats.rx_errors;
++ }
++ if (is_rx_length_error(desc_status)) {
++ DBG(20, KERN_INFO "process_rx_packet() %s: Length error (0x%08x:%u bytes)\n", priv->netdev->name, desc_status, desc_len);
++ ++priv->stats.rx_length_errors;
++ ++priv->stats.rx_errors;
++ }
++ if (is_rx_csum_error(desc_status)) {
++ DBG(20, KERN_INFO "process_rx_packet() %s: Checksum error (0x%08x:%u bytes)\n", priv->netdev->name, desc_status, desc_len);
++ ++priv->stats.rx_frame_errors;
++ ++priv->stats.rx_errors;
++ }
++
++ return 0;
++}
++
++static int process_rx_packet(gmac_priv_t *priv)
++{
++ struct sk_buff *skb = NULL;
++ int last;
++ u32 desc_status;
++ rx_frag_info_t frag_info;
++ int desc;
++ u32 offset;
++ int desc_len;
++ unsigned char *packet;
++ int valid;
++ int desc_used = 0;
++ int hlen = 0;
++ int partial_len = 0;
++ int first = 1;
++
++ // Check that there is at least one Rx descriptor available. Cache the
++ // descriptor information so we don't have to touch the uncached/unbuffered
++ // descriptor memory more than necessary when we come to use that descriptor
++ if (!rx_available_for_read(&priv->rx_gmac_desc_list_info, &desc_status)) {
++ return 0;
++ }
++
++ // Attempt to allocate an skb before we change anything on the Rx descriptor ring
++ skb = dev_alloc_skb(GMAC_HLEN + NET_IP_ALIGN);
++ if (unlikely(skb == NULL)) {
++ return 0;
++ }
++
++ // Align IP header start in header storage
++ skb_reserve(skb, NET_IP_ALIGN);
++
++ // Process all descriptors associated with the packet
++ while (1) {
++ int prev_len;
++
++ // First call to get_rx_descriptor() will use the status read from the
++ // first descriptor by the call to rx_available_for_read() above
++ while ((desc = get_rx_descriptor(priv, &last, &desc_status, &frag_info)) < 0) {
++ // We are part way through processing a multi-descriptor packet
++ // and the GMAC hasn't finished with the next descriptor for the
++ // packet yet, so have to poll until it becomes available
++ desc_status = 0;
++ udelay(1);
++ }
++
++ // We've consumed a descriptor
++ ++desc_used;
++
++ if (!frag_info.page) {
++ panic("process_rx_packet() %s: Found RX descriptor without attached page\n", priv->netdev->name);
++ }
++
++ // If this is the last packet in the page, release the DMA mapping
++ offset = unmap_rx_page(priv, frag_info.phys_adr);
++ if (!first) {
++ // The buffer adr of descriptors associate with middle or last
++ // parts of a packet have ls 2 bits of buffer adr ignored by GMAC DMA
++ offset &= ~0x3;
++ }
++
++ // Get the length of the packet excluding CRC, h/w csum etc.
++ prev_len = partial_len;
++ partial_len = get_desc_len(desc_status, last);
++ desc_len = partial_len - prev_len;
++
++ // Get a pointer to the start of the packet data received into page
++ packet = page_address(frag_info.page) + offset;
++
++ // Is the packet entirely contained within the desciptors and without errors?
++ valid = !(desc_status & (1UL << RDES0_ES_BIT));
++
++ if (unlikely(!valid)) {
++ goto not_valid;
++ }
++
++ if (first) {
++ // Store headers in skb buffer
++ hlen = min(GMAC_HLEN, desc_len);
++
++ // Copy header into skb buffer
++ memcpy(skb->data, packet, hlen);
++ skb->tail += hlen;
++
++ if (desc_len > hlen) {
++ // Point skb frags array at remaining packet data in pages
++ skb_shinfo(skb)->nr_frags = 1;
++ skb_shinfo(skb)->frags[0].page = frag_info.page;
++ skb_shinfo(skb)->frags[0].page_offset = offset + hlen;
++ skb_shinfo(skb)->frags[0].size = desc_len - hlen;
++ } else {
++ // Entire packet now in skb buffer so don't require page anymore
++ put_page(frag_info.page);
++ }
++
++ first = 0;
++ } else {
++ // Store intermediate descriptor data into packet
++ int frag_index = skb_shinfo(skb)->nr_frags;
++ skb_shinfo(skb)->frags[frag_index].page = frag_info.page;
++ skb_shinfo(skb)->frags[frag_index].page_offset = offset;
++ skb_shinfo(skb)->frags[frag_index].size = desc_len;
++ ++skb_shinfo(skb)->nr_frags;
++ }
++
++ if (last) {
++ int ip_summed = CHECKSUM_NONE;
++
++ // Update total packet length skb metadata
++ skb->len = partial_len;
++ skb->data_len = skb->len - hlen;
++ skb->truesize = skb->len + sizeof(struct sk_buff);
++
++#ifdef USE_RX_CSUM
++ // Has the h/w flagged an IP header checksum failure?
++ valid = !(desc_status & (1UL << RDES0_IPC_BIT));
++
++ // Are we offloading RX checksuming?
++ if (likely(valid)) {
++ // Determine whether Ethernet frame contains an IP packet -
++ // only bother with Ethernet II frames, but do cope with
++ // 802.1Q VLAN tag presence
++ int vlan_offset = 0;
++ unsigned short eth_protocol = ntohs(((struct ethhdr*)skb->data)->h_proto);
++ int is_ip = is_ip_packet(eth_protocol);
++
++ if (!is_ip) {
++ // Check for VLAN tag
++ if (eth_protocol == ETH_P_8021Q) {
++ // Extract the contained protocol type from after
++ // the VLAN tag
++ eth_protocol = ntohs(*(unsigned short*)(skb->data + ETH_HLEN));
++ is_ip = is_ip_packet(eth_protocol);
++
++ // Adjustment required to skip the VLAN stuff and
++ // get to the IP header
++ vlan_offset = 4;
++ }
++ }
++
++ // Only offload checksum calculation for IP packets
++ if (is_ip) {
++#ifdef CONFIG_HIPOX_VERSION_0X800
++ u16 payload_length = 0;
++#endif // CONFIG_HIPOX_VERSION_0X800
++ struct iphdr* ipv4_header = 0;
++
++#ifndef CONFIG_HIPOX_VERSION_0X800
++ if (unlikely(desc_status & (1UL << RDES0_PCE_BIT))) {
++ valid = 0;
++ } else
++#endif // !CONFIG_HIPOX_VERSION_0X800
++ if (is_ipv4_packet(eth_protocol)) {
++ ipv4_header = (struct iphdr*)(skb->data + ETH_HLEN + vlan_offset);
++
++ // H/W can only checksum non-fragmented IP packets
++ if (!(ipv4_header->frag_off & htons(IP_MF | IP_OFFSET))) {
++#ifdef CONFIG_HIPOX_VERSION_0X800
++ switch (ipv4_header->protocol) {
++ case IPPROTO_TCP:
++ // Compute TCP pseudo-header checksum
++ payload_length = ntohs(ipv4_header->tot_len) - (ipv4_header->ihl*4);
++ break;
++ case IPPROTO_UDP:
++ {
++ struct udphdr* udp_header = (struct udphdr*)((u8*)ipv4_header + (ipv4_header->ihl*4));
++ payload_length = ntohs(udp_header->len);
++ }
++ break;
++ default:
++ // Not supporting any other than TCP/UDP
++ break;
++ }
++#else // CONFIG_HIPOX_VERSION_0X800
++ if (is_hw_checksummable(ipv4_header->protocol)) {
++ ip_summed = CHECKSUM_UNNECESSARY;
++ }
++#endif // CONFIG_HIPOX_VERSION_0X800
++ }
++ }
++#ifndef CONFIG_HIPOX_VERSION_0X800
++ else {
++#ifdef SUPPORT_IPV6
++ struct ipv6hdr* ipv6_header = (struct ipv6hdr*)(skb->data + ETH_HLEN + vlan_offset);
++
++ if (is_hw_checksummable(ipv6_header->nexthdr)) {
++ ip_summed = CHECKSUM_UNNECESSARY;
++ }
++#endif // SUPPORT_IPV6
++ }
++#endif // !CONFIG_HIPOX_VERSION_0X800
++
++#ifdef CONFIG_HIPOX_VERSION_0X800
++ if (payload_length) {
++ // Get the hardware generated payload checksum from
++ // the end of the received packet, reverse the 1's
++ // complement operation that the h/w applies and add
++ // to the pseudo-header checksum, in network order
++ u16 hw_csum = ~(*(u16*)(packet + desc_len + FCS_LEN));
++
++ // Calculate checksum of pseudo header and payload
++ if (csum_tcpudp_magic(
++ ipv4_header->saddr,
++ ipv4_header->daddr,
++ payload_length,
++ ipv4_header->protocol,
++ hw_csum)) {
++ // Bad checksum, so indicate in descriptor status
++ desc_status |= (1UL << RDES0_IPC_BIT);
++ valid = 0;
++ } else {
++ ip_summed = CHECKSUM_UNNECESSARY;
++ }
++ }
++#endif // CONFIG_HIPOX_VERSION_0X800
++ }
++ }
++
++ if (unlikely(!valid)) {
++ goto not_valid;
++ }
++#endif // USE_RX_CSUM
++
++ // Initialise other required skb header fields
++ skb->dev = priv->netdev;
++ skb->protocol = eth_type_trans(skb, priv->netdev);
++
++ // Record whether h/w checksumed the packet
++ skb->ip_summed = ip_summed;
++
++ // Send the skb up the network stack
++ netif_receive_skb(skb);
++
++ // Update receive statistics
++ priv->netdev->last_rx = jiffies;
++ ++priv->stats.rx_packets;
++ priv->stats.rx_bytes += partial_len;
++
++ break;
++ }
++
++ // Want next call to get_rx_descriptor() to read status from descriptor
++ desc_status = 0;
++ }
++ return desc_used;
++
++not_valid:
++ if (!skb_shinfo(skb)->nr_frags) {
++ // Free the page as it wasn't attached to the skb
++ put_page(frag_info.page);
++ }
++
++ dev_kfree_skb(skb);
++
++ DBG(2, KERN_WARNING "process_rx_packet() %s: Received packet has bad desc_status = 0x%08x\n", priv->netdev->name, desc_status);
++
++ // Update receive statistics from the descriptor status
++ if (is_rx_collision_error(desc_status)) {
++ DBG(20, KERN_INFO "process_rx_packet() %s: Collision (0x%08x:%u bytes)\n", priv->netdev->name, desc_status, desc_len);
++ ++priv->stats.collisions;
++ }
++ if (is_rx_crc_error(desc_status)) {
++ DBG(20, KERN_INFO "process_rx_packet() %s: CRC error (0x%08x:%u bytes)\n", priv->netdev->name, desc_status, desc_len);
++ ++priv->stats.rx_crc_errors;
++ ++priv->stats.rx_errors;
++ }
++ if (is_rx_frame_error(desc_status)) {
++ DBG(20, KERN_INFO "process_rx_packet() %s: frame error (0x%08x:%u bytes)\n", priv->netdev->name, desc_status, desc_len);
++ ++priv->stats.rx_frame_errors;
++ ++priv->stats.rx_errors;
++ }
++ if (is_rx_length_error(desc_status)) {
++ DBG(20, KERN_INFO "process_rx_packet() %s: Length error (0x%08x:%u bytes)\n", priv->netdev->name, desc_status, desc_len);
++ ++priv->stats.rx_length_errors;
++ ++priv->stats.rx_errors;
++ }
++ if (is_rx_csum_error(desc_status)) {
++ DBG(20, KERN_INFO "process_rx_packet() %s: Checksum error (0x%08x:%u bytes)\n", priv->netdev->name, desc_status, desc_len);
++ ++priv->stats.rx_frame_errors;
++ ++priv->stats.rx_errors;
++ }
++
++ return desc_used;
++}
++
++/*
++ * NAPI receive polling method
++ */
++static int poll(
++ struct napi_struct *napi,
++ int budget)
++{
++ gmac_priv_t *priv = container_of(napi, gmac_priv_t, napi_struct);
++ struct net_device *dev = priv->netdev;
++ int rx_work_limit = budget;
++ int work_done = 0;
++ int continue_polling;
++ int finished;
++ int available;
++ int desc_since_refill = 0;
++
++ finished = 0;
++ do {
++ u32 status;
++
++ // While there are receive polling jobs to be done
++ while (rx_work_limit) {
++ int desc_used;
++
++ if (unlikely(priv->rx_buffers_per_page)) {
++ desc_used = process_rx_packet(priv);
++ } else {
++ desc_used = process_rx_packet_skb(priv);
++ }
++
++ if (!desc_used) {
++ break;
++ }
++
++ // Increment count of processed packets
++ ++work_done;
++
++ // Decrement our remaining budget
++ if (rx_work_limit > 0) {
++ --rx_work_limit;
++ }
++
++ // Rx overflows seem to upset the GMAC, so try to ensure we never see them
++ desc_since_refill += desc_used;
++ if (desc_since_refill >= DESC_SINCE_REFILL_LIMIT) {
++ desc_since_refill = 0;
++ refill_rx_ring(dev);
++ }
++ }
++
++ if (rx_work_limit) {
++ // We have unused budget remaining, but apparently no Rx packets to
++ // process
++ available = 0;
++
++ // Clear any RI status so we don't immediately get reinterrupted
++ // when we leave polling, due to either a new RI event, or a left
++ // over interrupt from one of the RX descriptors we've already
++ // processed
++ status = dma_reg_read(priv, DMA_STATUS_REG);
++ if (status & (1UL << DMA_STATUS_RI_BIT)) {
++ // Ack the RI, including the normal summary sticky bit
++ dma_reg_write(priv, DMA_STATUS_REG, ((1UL << DMA_STATUS_RI_BIT) |
++ (1UL << DMA_STATUS_NIS_BIT)));
++
++ // Must check again for available RX descriptors, in case the RI
++ // status came from a new RX descriptor
++ available = rx_available_for_read(&priv->rx_gmac_desc_list_info, 0);
++ }
++
++ if (!available) {
++ // We have budget left but no Rx packets to process so stop
++ // polling
++ continue_polling = 0;
++ finished = 1;
++ }
++ } else {
++ // If we have consumed all our budget, don't cancel the
++ // poll, the NAPI instructure assumes we won't
++ continue_polling = 1;
++
++ // Must leave poll() routine as no budget left
++ finished = 1;
++ }
++ } while (!finished);
++
++ // Attempt to fill any empty slots in the RX ring
++ refill_rx_ring(dev);
++
++ // Decrement the budget even if we didn't process any packets
++ if (!work_done) {
++ work_done = 1;
++ }
++
++ if (!continue_polling) {
++ // No more received packets to process so return to interrupt mode
++ netif_rx_complete(dev, napi);
++
++ // Enable interrupts caused by received packets that may have been
++ // disabled in the ISR before entering polled mode
++ gmac_int_en_set(priv, (1UL << DMA_INT_ENABLE_RI_BIT) |
++ (1UL << DMA_INT_ENABLE_RU_BIT) |
++ (1UL << DMA_INT_ENABLE_OV_BIT));
++ }
++
++ return work_done;
++}
++
++#if defined(CONFIG_LEON_COPRO) && defined(CONFIG_LEON_OFFLOAD_TX)
++static void copro_fill_tx_job(
++ volatile gmac_tx_que_ent_t *job,
++ struct sk_buff *skb)
++{
++ int i;
++ int nr_frags = skb_shinfo(skb)->nr_frags;
++ unsigned short flags = 0;
++ dma_addr_t hdr_dma_address;
++
++ // if too many fragments call sbk_linearize()
++ // and take the CPU memory copies hit
++ if (nr_frags > COPRO_NUM_TX_FRAGS_DIRECT) {
++ int err;
++ printk(KERN_WARNING "Fill: linearizing socket buffer as required %d frags and have only %d\n", nr_frags, COPRO_NUM_TX_FRAGS_DIRECT);
++ err = skb_linearize(skb);
++ if (err) {
++ panic("Fill: No free memory");
++ }
++
++ // update nr_frags
++ nr_frags = skb_shinfo(skb)->nr_frags;
++ }
++
++ // Get a DMA mapping of the packet's data
++ hdr_dma_address = dma_map_single(0, skb->data, skb_headlen(skb), DMA_TO_DEVICE);
++ BUG_ON(dma_mapping_error(hdr_dma_address));
++
++ // Allocate storage for remainder of fragments and create DMA mappings
++ // Get a DMA mapping for as many fragments as will fit into the first level
++ // fragment info. storage within the job structure
++ for (i=0; i < nr_frags; ++i) {
++ struct skb_frag_struct *frag = &skb_shinfo(skb)->frags[i];
++ job->frag_ptr_[i] = dma_map_page(0, frag->page, frag->page_offset, frag->size, DMA_TO_DEVICE);
++ job->frag_len_[i] = frag->size;
++ }
++
++ // Is h/w checksumming and possibly TSO required
++ if (likely((skb->ip_summed == CHECKSUM_PARTIAL) &&
++ (ntohs(skb->protocol) == ETH_P_IP))) {
++ flags |= (1UL << TX_JOB_FLAGS_ACCELERATE_BIT);
++ }
++
++ // Fill the job description with information about the packet
++ job->skb_ = (u32)skb;
++ job->len_ = skb->len;
++ job->data_len_ = skb->data_len;
++ job->ethhdr_ = hdr_dma_address;
++ job->iphdr_ = hdr_dma_address + (skb_network_header(skb) - skb->data);
++ job->iphdr_csum_ = ((struct iphdr*)skb_network_header(skb))->check;
++ job->tso_segs_ = skb_shinfo(skb)->gso_segs;
++ job->tso_size_ = skb_shinfo(skb)->gso_size;
++ job->flags_ = flags;
++ job->statistics_ = 0;
++}
++
++static void copro_free_tx_resources(volatile gmac_tx_que_ent_t* job)
++{
++ int i;
++ struct sk_buff* skb = (struct sk_buff*)job->skb_;
++ int nr_frags = skb_shinfo(skb)->nr_frags;
++
++ // This should never happen, since we check space when we filled
++ // the job in copro_fill_tx_job
++ if (nr_frags > COPRO_NUM_TX_FRAGS_DIRECT) {
++ panic("Free: Insufficient fragment storage, required %d, have only %d", nr_frags, COPRO_NUM_TX_FRAGS_DIRECT);
++ }
++
++ // Release the DMA mapping for the data directly referenced by the SKB
++ dma_unmap_single(0, job->ethhdr_, skb_headlen(skb), DMA_TO_DEVICE);
++
++ // Release the DMA mapping for any fragments in the first level fragment
++ // info. storage within the job structure
++ for (i=0; (i < nr_frags) && (i < COPRO_NUM_TX_FRAGS_DIRECT); ++i) {
++ dma_unmap_page(0, job->frag_ptr_[i], job->frag_len_[i], DMA_TO_DEVICE);
++ }
++
++ // Inform the network stack that we've finished with the packet
++ dev_kfree_skb_irq(skb);
++}
++
++static void copro_process_pending_tx_skbs(
++ struct net_device *dev,
++ volatile gmac_tx_que_ent_t *job)
++{
++ gmac_priv_t *priv = (gmac_priv_t*)netdev_priv(dev);
++
++ // Process pending SKBs, oldest first
++ do {
++ // Get the oldest pending SKB
++ struct sk_buff *skb;
++ struct list_head *entry = priv->copro_tx_skb_list_.next;
++ BUG_ON(!entry);
++ list_del(entry);
++
++ skb = list_entry(entry, struct sk_buff, cb);
++ BUG_ON(!skb);
++
++ // Keep track of how many entries are in the pending SKB list
++ --priv->copro_tx_skb_list_count_;
++
++ // Fill the Tx offload job with the network packet's details
++ copro_fill_tx_job(job, skb);
++
++ // Enqueue the new Tx offload job with the CoPro
++ tx_que_new_job(dev, job);
++
++ if (list_empty(&priv->copro_tx_skb_list_)) {
++ // No more pending SKBs
++ break;
++ }
++ } while ((job = tx_que_get_idle_job(dev)));
++}
++
++static void finish_xmit(struct net_device *dev)
++{
++ gmac_priv_t *priv = (gmac_priv_t*)netdev_priv(dev);
++ volatile gmac_tx_que_ent_t *job;
++
++ // Process all available completed jobs
++ while ((job = tx_que_get_finished_job(dev))) {
++ int aborted;
++ int carrier;
++ int collisions;
++ u32 statistics = job->statistics_;
++
++ copro_free_tx_resources(job);
++
++ // Accumulate TX statistics returned by CoPro in the job structure
++ priv->stats.tx_bytes += (statistics & TX_JOB_STATS_BYTES_MASK) >> TX_JOB_STATS_BYTES_BIT;
++ priv->stats.tx_packets += (statistics & TX_JOB_STATS_PACKETS_MASK) >> TX_JOB_STATS_PACKETS_BIT;
++ aborted = (statistics & TX_JOB_STATS_ABORT_MASK) >> TX_JOB_STATS_ABORT_BIT;
++ carrier = (statistics & TX_JOB_STATS_CARRIER_MASK) >> TX_JOB_STATS_CARRIER_BIT;
++ collisions = (statistics & TX_JOB_STATS_COLLISION_MASK) >> TX_JOB_STATS_COLLISION_BIT;
++ priv->stats.tx_aborted_errors += aborted;
++ priv->stats.tx_carrier_errors += carrier;
++ priv->stats.collisions += collisions;
++ priv->stats.tx_errors += (aborted + carrier);
++ }
++
++ // Process any queued pending SKBs for which resources are available
++ if (priv->copro_tx_skb_list_count_ && (job = tx_que_get_idle_job(dev))) {
++ copro_process_pending_tx_skbs(dev, job);
++
++ // Record start of transmission, so timeouts will work once they're
++ // implemented
++ dev->trans_start = jiffies;
++
++ // Interrupt the CoPro to cause it to examine the Tx offload queue
++ wmb();
++ writel(1UL << COPRO_SEM_INT_TX, SYS_CTRL_SEMA_SET_CTRL);
++ }
++
++ // If the network stack's Tx queue was stopped and we now have resources
++ // to process more Tx offload jobs
++ if (netif_queue_stopped(dev) &&
++ !tx_que_is_full(&priv->tx_queue_) &&
++ !priv->copro_tx_skb_list_count_) {
++ // Restart the network stack's TX queue
++ netif_wake_queue(dev);
++ }
++}
++#else
++static void finish_xmit(struct net_device *dev)
++{
++ gmac_priv_t *priv = (gmac_priv_t*)netdev_priv(dev);
++ unsigned descriptors_freed = 0;
++ u32 desc_status = 0;
++
++ // Handle transmit descriptors for the completed packet transmission
++ while (1) {
++ struct sk_buff *skb;
++ tx_frag_info_t fragment;
++ int buffer_owned;
++ int desc_index;
++
++ // Get tx descriptor content, accumulating status for all buffers
++ // contributing to each packet
++ desc_index = get_tx_descriptor(priv, &skb, &desc_status, &fragment, &buffer_owned);
++
++ if (desc_index < 0) {
++ // No more completed Tx packets
++ break;
++ }
++
++ // Only unmap DMA buffer if descriptor owned the buffer
++ if (buffer_owned) {
++ // Release the DMA mapping for the buffer
++ dma_unmap_single(0, fragment.phys_adr, fragment.length, DMA_TO_DEVICE);
++ }
++
++ // When all buffers contributing to a packet have been processed
++ if (skb) {
++ // Check the status of the transmission
++ if (likely(is_tx_valid(desc_status))) {
++ priv->stats.tx_bytes += skb->len;
++ priv->stats.tx_packets++;
++ } else {
++ priv->stats.tx_errors++;
++ if (is_tx_aborted(desc_status)) {
++ ++priv->stats.tx_aborted_errors;
++ }
++ if (is_tx_carrier_error(desc_status)) {
++ ++priv->stats.tx_carrier_errors;
++ }
++ }
++
++ if (unlikely(is_tx_collision_error(desc_status))) {
++ ++priv->stats.collisions;
++ }
++
++ // Inform the network stack that packet transmission has finished
++ dev_kfree_skb_irq(skb);
++
++ // Start accumulating status for the next packet
++ desc_status = 0;
++ }
++
++ // Track how many descriptors we make available, so we know
++ // if we need to re-start of network stack's TX queue processing
++ ++descriptors_freed;
++ }
++
++ // If the TX queue is stopped, there may be a pending TX packet waiting to
++ // be transmitted
++ if (unlikely(netif_queue_stopped(dev))) {
++ // No locking with hard_start_xmit() required, as queue is already
++ // stopped so hard_start_xmit() won't touch the h/w
++
++ // If any TX descriptors have been freed and there is an outstanding TX
++ // packet waiting to be queued due to there not having been a TX
++ // descriptor available when hard_start_xmit() was presented with an skb
++ // by the network stack
++ if (priv->tx_pending_skb) {
++ // Construct the GMAC specific DMA descriptor
++ if (set_tx_descriptor(priv,
++ priv->tx_pending_skb,
++ priv->tx_pending_fragments,
++ priv->tx_pending_fragment_count,
++ priv->tx_pending_skb->ip_summed == CHECKSUM_PARTIAL) >= 0) {
++ // No TX packets now outstanding
++ priv->tx_pending_skb = 0;
++ priv->tx_pending_fragment_count = 0;
++
++ // We have used one of the TX descriptors freed by transmission
++ // completion processing having occured above
++ --descriptors_freed;
++
++ // Issue a TX poll demand to restart TX descriptor processing, as we
++ // have just added one, in case it had found there were no more
++ // pending transmission
++ dma_reg_write(priv, DMA_TX_POLL_REG, 0);
++ }
++ }
++
++ // If there are TX descriptors available we should restart the TX queue
++ if (descriptors_freed) {
++ // The TX queue had been stopped by hard_start_xmit() due to lack of
++ // TX descriptors, so restart it now that we've freed at least one
++ netif_wake_queue(dev);
++ }
++ }
++}
++#endif // CONFIG_LEON_COPRO && CONFIG_LEON_OFFLOAD_TX
++
++#ifndef CONFIG_LEON_COPRO
++static void process_non_dma_ints(u32 raw_status)
++{
++ printk(KERN_ERR "Found GPI/GMI/GLI interrupt\n");
++}
++#endif // !CONFIG_LEON_COPRO
++
++#ifdef CONFIG_LEON_COPRO
++static void copro_fwd_intrs_handler(
++ void *dev_id,
++ u32 status)
++{
++ struct net_device *dev = (struct net_device *)dev_id;
++ gmac_priv_t *priv = (gmac_priv_t*)netdev_priv(dev);
++ int restart_watchdog = 0;
++ int restart_tx = 0;
++ int poll_tx = 0;
++
++ // Test for normal receive interrupt
++ if (status & (1UL << DMA_STATUS_RI_BIT)) {
++ if (netif_rx_schedule_prep(dev, &priv->napi_struct)) {
++ // Tell system we have work to be done
++ __netif_rx_schedule(dev, &priv->napi_struct);
++ } else {
++ printk(KERN_ERR "copro_fwd_intrs_handler() %s: RX interrupt while in poll\n", dev->name);
++ }
++ }
++
++ // Test for unavailable RX buffers - CoPro should have disabled
++ if (unlikely(status & (1UL << DMA_STATUS_RU_BIT))) {
++ DBG(30, KERN_INFO "int_handler() %s: RX buffer unavailable\n", dev->name);
++ // Accumulate receive statistics
++ ++priv->stats.rx_over_errors;
++ ++priv->stats.rx_errors;
++ }
++
++ // Test for Rx overflow - CoPro should have disabled
++ if (unlikely(status & (1UL << DMA_STATUS_OVF_BIT))) {
++ DBG(30, KERN_INFO "int_handler() %s: Rx overflow\n", dev->name);
++ // Accumulate receive statistics
++ ++priv->stats.rx_fifo_errors;
++ ++priv->stats.rx_errors;
++ }
++
++ // Test for normal TX interrupt
++ if (status & ((1UL << DMA_STATUS_TI_BIT) |
++ (1UL << DMA_STATUS_ETI_BIT))) {
++#ifndef CONFIG_LEON_OFFLOAD_TX
++ // Finish packet transmision started by start_xmit
++ finish_xmit(dev);
++#endif // !CONFIG_LEON_OFFLOAD_TX
++ }
++
++ // Test for abnormal transmitter interrupt where there may be completed
++ // packets waiting to be processed
++ if (unlikely(status & ((1UL << DMA_STATUS_TJT_BIT) |
++ (1UL << DMA_STATUS_UNF_BIT)))) {
++#ifndef CONFIG_LEON_OFFLOAD_TX
++ // Complete processing of any TX packets closed by the DMA
++ finish_xmit(dev);
++#endif // !CONFIG_LEON_OFFLOAD_TX
++
++ if (status & (1UL << DMA_STATUS_TJT_BIT)) {
++ // A transmit jabber timeout causes the transmitter to enter the
++ // stopped state
++ DBG(50, KERN_INFO "int_handler() %s: TX jabber timeout\n", dev->name);
++ restart_tx = 1;
++ } else {
++ DBG(51, KERN_INFO "int_handler() %s: TX underflow\n", dev->name);
++ }
++
++ // Issue a TX poll demand in an attempt to restart TX descriptor
++ // processing
++ poll_tx = 1;
++ }
++
++ // Test for any of the error states which we deal with directly within
++ // this interrupt service routine.
++ if (unlikely(status & ((1UL << DMA_STATUS_ERI_BIT) |
++ (1UL << DMA_STATUS_RWT_BIT) |
++ (1UL << DMA_STATUS_RPS_BIT) |
++ (1UL << DMA_STATUS_TPS_BIT) |
++ (1UL << DMA_STATUS_FBE_BIT)))) {
++ // Test for early RX interrupt
++ if (status & (1UL << DMA_STATUS_ERI_BIT)) {
++ // Don't expect to see this, as never enable it
++ DBG(30, KERN_WARNING "int_handler() %s: Early RX \n", dev->name);
++ }
++
++ if (status & (1UL << DMA_STATUS_RWT_BIT)) {
++ DBG(30, KERN_INFO "int_handler() %s: RX watchdog timeout\n", dev->name);
++ // Accumulate receive statistics
++ ++priv->stats.rx_frame_errors;
++ ++priv->stats.rx_errors;
++ restart_watchdog = 1;
++ }
++
++ if (status & (1UL << DMA_STATUS_RPS_BIT)) {
++ // Mask to extract the receive status field from the status register
++// u32 rs_mask = ((1UL << DMA_STATUS_RS_NUM_BITS) - 1) << DMA_STATUS_RS_BIT;
++// u32 rs = (status & rs_mask) >> DMA_STATUS_RS_BIT;
++// printk("int_handler() %s: RX process stopped 0x%x\n", dev->name, rs);
++ ++priv->stats.rx_errors;
++ restart_watchdog = 1;
++
++ // Restart the receiver
++ DBG(35, KERN_INFO "int_handler() %s: Restarting receiver\n", dev->name);
++ change_rx_enable(priv, 1, 0, 1);
++ }
++
++ if (status & (1UL << DMA_STATUS_TPS_BIT)) {
++ // Mask to extract the transmit status field from the status register
++// u32 ts_mask = ((1UL << DMA_STATUS_TS_NUM_BITS) - 1) << DMA_STATUS_TS_BIT;
++// u32 ts = (status & ts_mask) >> DMA_STATUS_TS_BIT;
++// printk("int_handler() %s: TX process stopped 0x%x\n", dev->name, ts);
++ ++priv->stats.tx_errors;
++ restart_watchdog = 1;
++ restart_tx = 1;
++ }
++
++ // Test for pure error interrupts
++ if (status & (1UL << DMA_STATUS_FBE_BIT)) {
++ // Mask to extract the bus error status field from the status register
++// u32 eb_mask = ((1UL << DMA_STATUS_EB_NUM_BITS) - 1) << DMA_STATUS_EB_BIT;
++// u32 eb = (status & eb_mask) >> DMA_STATUS_EB_BIT;
++// printk("int_handler() %s: Bus error 0x%x\n", dev->name, eb);
++ restart_watchdog = 1;
++ }
++
++ if (restart_watchdog) {
++ // Restart the link/PHY state watchdog immediately, which will
++ // attempt to restart the system
++ mod_timer(&priv->watchdog_timer, jiffies);
++ restart_watchdog = 0;
++ }
++ }
++
++ if (unlikely(restart_tx)) {
++ // Restart the transmitter, causes am implicit Tx descriptor list poll
++ DBG(35, KERN_INFO "int_handler() %s: Restarting transmitter\n", dev->name);
++#ifndef CONFIG_LEON_OFFLOAD_TX
++ dma_reg_set_mask(priv, DMA_OP_MODE_REG, (1UL << DMA_OP_MODE_ST_BIT));
++#endif // !CONFIG_LEON_OFFLOAD_TX
++ poll_tx = 0;
++ }
++
++ if (unlikely(poll_tx)) {
++ // Issue a TX poll demand in an attempt to restart TX descriptor
++ // processing
++ DBG(33, KERN_INFO "int_handler() %s: Issuing Tx poll demand\n", dev->name);
++#ifndef CONFIG_LEON_OFFLOAD_TX
++ dma_reg_write(priv, DMA_TX_POLL_REG, 0);
++#endif // !CONFIG_LEON_OFFLOAD_TX
++ }
++}
++#else // CONFIG_LEON_COPRO
++static irqreturn_t int_handler(int int_num, void* dev_id)
++{
++ struct net_device *dev = (struct net_device *)dev_id;
++ gmac_priv_t* priv = (gmac_priv_t*)netdev_priv(dev);
++ u32 int_enable;
++ int rx_polling;
++ u32 raw_status;
++ u32 status;
++
++ /** Read the interrupt enable register to determine if we're in rx poll mode
++ * Id like to get rid of this read, if a more efficient way of determining
++ * whether we are polling is available */
++ spin_lock(&priv->cmd_que_lock_);
++ int_enable = dma_reg_read(priv, DMA_INT_ENABLE_REG);
++ spin_unlock(&priv->cmd_que_lock_);
++
++ rx_polling = !(int_enable & (1UL << DMA_INT_ENABLE_RI_BIT));
++
++ // Get interrupt status
++ raw_status = dma_reg_read(priv, DMA_STATUS_REG);
++
++ // MMC, PMT and GLI interrupts are not masked by the interrupt enable
++ // register, so must deal with them on the raw status
++ if (unlikely(raw_status & ((1UL << DMA_STATUS_GPI_BIT) |
++ (1UL << DMA_STATUS_GMI_BIT) |
++ (1UL << DMA_STATUS_GLI_BIT)))) {
++ process_non_dma_ints(raw_status);
++ }
++
++ // Get status of enabled interrupt sources
++ status = raw_status & int_enable;
++
++ while (status) {
++ // Whether the link/PHY watchdog timer should be restarted
++ int restart_watchdog = 0;
++ int restart_tx = 0;
++ int poll_tx = 0;
++ u32 int_disable_mask = 0;
++
++ // Test for RX interrupt resulting from sucessful reception of a packet-
++ // must do this before ack'ing, else otherwise can get into trouble with
++ // the sticky summary bits when we try to disable further RI interrupts
++ if (status & (1UL << DMA_STATUS_RI_BIT)) {
++//printk("RI ");
++ // Disable interrupts caused by received packets as henceforth
++ // we shall poll for packet reception
++ int_disable_mask |= (1UL << DMA_INT_ENABLE_RI_BIT);
++
++ // Do NAPI compatible receive processing for RI interrupts
++ if (likely(netif_rx_schedule_prep(dev, &priv->napi_struct))) {
++ // Remember that we are polling, so we ignore RX events for the
++ // remainder of the ISR
++ rx_polling = 1;
++
++ // Tell system we have work to be done
++ __netif_rx_schedule(dev, &priv->napi_struct);
++ } else {
++ printk(KERN_ERR "int_handler() %s: RX interrupt while in poll\n", dev->name);
++ }
++ }
++
++ // Test for unavailable RX buffers - must do this before ack'ing, else
++ // otherwise can get into trouble with the sticky summary bits
++ if (unlikely(status & (1UL << DMA_STATUS_RU_BIT))) {
++ printk(/*DBG(30, KERN_INFO */"int_handler() %s: RX buffer unavailable\n", dev->name);
++ // Accumulate receive statistics
++ ++priv->stats.rx_over_errors;
++ ++priv->stats.rx_errors;
++
++ // Disable RX buffer unavailable reporting, so we don't get swamped
++ int_disable_mask |= (1UL << DMA_INT_ENABLE_RU_BIT);
++ }
++
++ if (unlikely(status & (1UL << DMA_STATUS_OVF_BIT))) {
++ printk(/*DBG(30, KERN_INFO */"int_handler() %s: RX overflow\n", dev->name);
++ // Accumulate receive statistics
++ ++priv->stats.rx_fifo_errors;
++ ++priv->stats.rx_errors;
++
++ // Disable RX overflow reporting, so we don't get swamped
++ int_disable_mask |= (1UL << DMA_INT_ENABLE_OV_BIT);
++ }
++
++ // Do any interrupt disabling with a single register write
++ if (int_disable_mask) {
++ gmac_int_en_clr(priv, int_disable_mask, 0);
++
++ // Update our record of the current interrupt enable status
++ int_enable &= ~int_disable_mask;
++ }
++
++ // The broken GMAC interrupt mechanism with its sticky summary bits
++ // means that we have to ack all asserted interrupts here; we can't not
++ // ack the RI interrupt source as we might like to (in order that the
++ // poll() routine could examine the status) because if it was asserted
++ // prior to being masked above, then the summary bit(s) would remain
++ // asserted and cause an immediate re-interrupt.
++ dma_reg_write(priv, DMA_STATUS_REG, status | ((1UL << DMA_STATUS_NIS_BIT) |
++ (1UL << DMA_STATUS_AIS_BIT)));
++
++ // Test for normal TX interrupt
++ if (status & ((1UL << DMA_STATUS_TI_BIT) |
++ (1UL << DMA_STATUS_ETI_BIT))) {
++ // Finish packet transmision started by start_xmit
++ finish_xmit(dev);
++ }
++
++ // Test for abnormal transmitter interrupt where there may be completed
++ // packets waiting to be processed
++ if (unlikely(status & ((1UL << DMA_STATUS_TJT_BIT) |
++ (1UL << DMA_STATUS_UNF_BIT)))) {
++ // Complete processing of any TX packets closed by the DMA
++ finish_xmit(dev);
++
++ if (status & (1UL << DMA_STATUS_TJT_BIT)) {
++ // A transmit jabber timeout causes the transmitter to enter the
++ // stopped state
++ DBG(50, KERN_INFO "int_handler() %s: TX jabber timeout\n", dev->name);
++ restart_tx = 1;
++ } else {
++ DBG(51, KERN_INFO "int_handler() %s: TX underflow\n", dev->name);
++ }
++
++ // Issue a TX poll demand in an attempt to restart TX descriptor
++ // processing
++ poll_tx = 1;
++ }
++
++ // Test for any of the error states which we deal with directly within
++ // this interrupt service routine.
++ if (unlikely(status & ((1UL << DMA_STATUS_ERI_BIT) |
++ (1UL << DMA_STATUS_RWT_BIT) |
++ (1UL << DMA_STATUS_RPS_BIT) |
++ (1UL << DMA_STATUS_TPS_BIT) |
++ (1UL << DMA_STATUS_FBE_BIT)))) {
++ // Test for early RX interrupt
++ if (status & (1UL << DMA_STATUS_ERI_BIT)) {
++ // Don't expect to see this, as never enable it
++ DBG(30, KERN_WARNING "int_handler() %s: Early RX \n", dev->name);
++ }
++
++ if (status & (1UL << DMA_STATUS_RWT_BIT)) {
++ DBG(30, KERN_INFO "int_handler() %s: RX watchdog timeout\n", dev->name);
++ // Accumulate receive statistics
++ ++priv->stats.rx_frame_errors;
++ ++priv->stats.rx_errors;
++ restart_watchdog = 1;
++ }
++
++ if (status & (1UL << DMA_STATUS_RPS_BIT)) {
++ // Mask to extract the receive status field from the status register
++ u32 rs_mask = ((1UL << DMA_STATUS_RS_NUM_BITS) - 1) << DMA_STATUS_RS_BIT;
++ u32 rs = (status & rs_mask) >> DMA_STATUS_RS_BIT;
++ printk(/*DBG(30, KERN_INFO */"int_handler() %s: RX process stopped 0x%x\n", dev->name, rs);
++ ++priv->stats.rx_errors;
++ restart_watchdog = 1;
++
++ // Restart the receiver
++ printk(/*DBG(35, KERN_INFO */"int_handler() %s: Restarting receiver\n", dev->name);
++ dma_reg_set_mask(priv, DMA_OP_MODE_REG, (1UL << DMA_OP_MODE_SR_BIT));
++ }
++
++ if (status & (1UL << DMA_STATUS_TPS_BIT)) {
++ // Mask to extract the transmit status field from the status register
++// u32 ts_mask = ((1UL << DMA_STATUS_TS_NUM_BITS) - 1) << DMA_STATUS_TS_BIT;
++// u32 ts = (status & ts_mask) >> DMA_STATUS_TS_BIT;
++// DBG(30, KERN_INFO "int_handler() %s: TX process stopped 0x%x\n", dev->name, ts);
++ ++priv->stats.tx_errors;
++ restart_watchdog = 1;
++ restart_tx = 1;
++ }
++
++ // Test for pure error interrupts
++ if (status & (1UL << DMA_STATUS_FBE_BIT)) {
++ // Mask to extract the bus error status field from the status register
++// u32 eb_mask = ((1UL << DMA_STATUS_EB_NUM_BITS) - 1) << DMA_STATUS_EB_BIT;
++// u32 eb = (status & eb_mask) >> DMA_STATUS_EB_BIT;
++// DBG(30, KERN_INFO "int_handler() %s: Bus error 0x%x\n", dev->name, eb);
++ restart_watchdog = 1;
++ }
++
++ if (restart_watchdog) {
++ // Restart the link/PHY state watchdog immediately, which will
++ // attempt to restart the system
++ mod_timer(&priv->watchdog_timer, jiffies);
++ restart_watchdog = 0;
++ }
++ }
++
++ if (unlikely(restart_tx)) {
++ // Restart the transmitter
++ DBG(35, KERN_INFO "int_handler() %s: Restarting transmitter\n", dev->name);
++ dma_reg_set_mask(priv, DMA_OP_MODE_REG, (1UL << DMA_OP_MODE_ST_BIT));
++ }
++
++ if (unlikely(poll_tx)) {
++ // Issue a TX poll demand in an attempt to restart TX descriptor
++ // processing
++ DBG(33, KERN_INFO "int_handler() %s: Issuing Tx poll demand\n", dev->name);
++ dma_reg_write(priv, DMA_TX_POLL_REG, 0);
++ }
++
++ // Read the record of current interrupt requests again, in case some
++ // more arrived while we were processing
++ raw_status = dma_reg_read(priv, DMA_STATUS_REG);
++
++ // MMC, PMT and GLI interrupts are not masked by the interrupt enable
++ // register, so must deal with them on the raw status
++ if (unlikely(raw_status & ((1UL << DMA_STATUS_GPI_BIT) |
++ (1UL << DMA_STATUS_GMI_BIT) |
++ (1UL << DMA_STATUS_GLI_BIT)))) {
++ process_non_dma_ints(raw_status);
++ }
++
++ // Get status of enabled interrupt sources.
++ status = raw_status & int_enable;
++ }
++
++ return IRQ_HANDLED;
++}
++#endif // CONFIG_LEON_COPRO
++
++#ifdef CONFIG_LEON_COPRO
++static struct semaphore copro_stop_semaphore;
++
++static void copro_stop_callback(volatile gmac_cmd_que_ent_t* entry)
++{
++ up(&copro_stop_semaphore);
++}
++#endif // CONFIG_LEON_COPRO
++
++static void gmac_down(struct net_device *dev)
++{
++ gmac_priv_t* priv = (gmac_priv_t*)netdev_priv(dev);
++ int desc;
++ u32 int_enable;
++#ifdef CONFIG_LEON_COPRO
++ tx_que_t *tx_queue = &priv->tx_queue_;
++ int cmd_queue_result;
++#endif // CONFIG_LEON_COPRO
++
++ // Stop NAPI
++ napi_disable(&priv->napi_struct);
++
++ // Stop further TX packets being delivered to hard_start_xmit();
++ netif_stop_queue(dev);
++ netif_carrier_off(dev);
++
++ // Disable all GMAC interrupts and wait for change to be acknowledged
++ gmac_int_en_clr(priv, ~0UL, &int_enable, 0);
++
++#ifdef CONFIG_LEON_COPRO
++ // Tell the CoPro to stop network offload operations
++ cmd_queue_result = -1;
++ while (cmd_queue_result) {
++ spin_lock(&priv->cmd_que_lock_);
++ cmd_queue_result = cmd_que_queue_cmd(&priv->cmd_queue_, GMAC_CMD_STOP, 0, copro_stop_callback);
++ spin_unlock(&priv->cmd_que_lock_);
++ }
++
++ // Interrupt the CoPro so it sees the new command
++ writel(1UL << COPRO_SEM_INT_CMD, SYS_CTRL_SEMA_SET_CTRL);
++
++ // Wait until the CoPro acknowledges the STOP command
++ down_interruptible(&copro_stop_semaphore);
++
++ // Wait until the CoPro acknowledges that it has completed stopping
++ down_interruptible(&priv->copro_stop_complete_semaphore_);
++
++ // Clear out the Tx offload job queue, deallocating associated resources
++ while (tx_que_not_empty(tx_queue)) {
++ // Free any dynamic fragment ptr/len storage
++ /** @todo */
++ tx_que_inc_r_ptr(tx_queue);
++ }
++
++ // Reinitialise the Tx offload queue metadata
++ tx_que_init(
++ &priv->tx_queue_,
++ (gmac_tx_que_ent_t*)descriptors_phys_to_virt(priv->copro_params_.tx_que_head_),
++ priv->copro_tx_que_num_entries_);
++
++ // Empty the pending SKB queue
++ while (!list_empty(&priv->copro_tx_skb_list_)) {
++ struct sk_buff *skb;
++
++ // Remove the first entry on the list
++ struct list_head *entry = priv->copro_tx_skb_list_.next;
++ BUG_ON(!entry);
++ list_del(entry);
++
++ // Get pointer to SKB from it's list_head member
++ skb = list_entry(entry, struct sk_buff, cb);
++ BUG_ON(!skb);
++
++ // Inform the network stack that we've finished with the packet
++ dev_kfree_skb(skb);
++ }
++ priv->copro_tx_skb_list_count_ = 0;
++#endif // CONFIG_LEON_COPRO
++
++#ifndef CONFIG_LEON_OFFLOAD_TX
++ // Stop transmitter, take ownership of all tx descriptors
++ dma_reg_clear_mask(priv, DMA_OP_MODE_REG, 1UL << DMA_OP_MODE_ST_BIT);
++ if (priv->desc_vaddr) {
++ tx_take_ownership(&priv->tx_gmac_desc_list_info);
++ }
++#endif // !CONFIG_LEON_OFFLOAD_TX
++
++ // Stop receiver, waiting until it's really stopped and then take ownership
++ // of all rx descriptors
++ change_rx_enable(priv, 0, 1, 0);
++
++ if (priv->desc_vaddr) {
++ rx_take_ownership(&priv->rx_gmac_desc_list_info);
++ }
++
++ // Stop all timers
++ delete_watchdog_timer(priv);
++
++ if (priv->desc_vaddr) {
++ // Free receive descriptors
++ do {
++ int first_last = 0;
++ rx_frag_info_t frag_info;
++
++ desc = get_rx_descriptor(priv, &first_last, 0, &frag_info);
++ if (desc >= 0) {
++ if (unlikely(priv->rx_buffers_per_page)) {
++ // If this is the last packet in the page, release the DMA mapping
++ unmap_rx_page(priv, frag_info.phys_adr);
++ put_page(frag_info.page);
++ } else {
++ // Release the DMA mapping for the packet buffer
++ dma_unmap_single(0, frag_info.phys_adr, frag_info.length, DMA_FROM_DEVICE);
++
++ // Free the skb
++ dev_kfree_skb((struct sk_buff *)frag_info.page);
++ }
++ }
++ } while (desc >= 0);
++
++ // Free transmit descriptors
++ do {
++ struct sk_buff *skb;
++ tx_frag_info_t frag_info;
++ int buffer_owned;
++
++ desc = get_tx_descriptor(priv, &skb, 0, &frag_info, &buffer_owned);
++ if (desc >= 0) {
++ if (buffer_owned) {
++ // Release the DMA mapping for the packet buffer
++ dma_unmap_single(0, frag_info.phys_adr, frag_info.length, DMA_FROM_DEVICE);
++ }
++
++ if (skb) {
++ // Free the skb
++ dev_kfree_skb(skb);
++ }
++ }
++ } while (desc >= 0);
++
++ // Free any resources associated with the buffers of a pending packet
++ if (priv->tx_pending_fragment_count) {
++ tx_frag_info_t *frag_info = priv->tx_pending_fragments;
++
++ while (priv->tx_pending_fragment_count--) {
++ dma_unmap_single(0, frag_info->phys_adr, frag_info->length, DMA_FROM_DEVICE);
++ ++frag_info;
++ }
++ }
++
++ // Free the socket buffer of a pending packet
++ if (priv->tx_pending_skb) {
++ dev_kfree_skb(priv->tx_pending_skb);
++ priv->tx_pending_skb = 0;
++ }
++ }
++
++ // Power down the PHY
++ phy_powerdown(dev);
++}
++
++static int stop(struct net_device *dev)
++{
++ gmac_priv_t* priv = (gmac_priv_t*)netdev_priv(dev);
++
++ gmac_down(dev);
++
++#ifdef CONFIG_LEON_COPRO
++ shutdown_copro();
++
++ if (priv->shared_copro_params_) {
++ // Free the DMA coherent parameter space
++ dma_free_coherent(0, sizeof(copro_params_t), priv->shared_copro_params_, priv->shared_copro_params_pa_);
++ priv->shared_copro_params_ = 0;
++ }
++
++ // Disable semaphore register from causing ARM interrupts
++ *((volatile unsigned long*)SYS_CTRL_SEMA_MASKA_CTRL) = 0;
++ *((volatile unsigned long*)SYS_CTRL_SEMA_MASKB_CTRL) = 0;
++
++ // Release interrupts lines used by semaphore register interrupts
++ if (priv->copro_a_irq_alloced_) {
++ free_irq(priv->copro_a_irq_, dev);
++ priv->copro_a_irq_alloced_ = 0;
++ }
++ if (priv->copro_b_irq_alloced_) {
++ free_irq(priv->copro_b_irq_, dev);
++ priv->copro_b_irq_alloced_ = 0;
++ }
++#endif // CONFIG_LEON_COPRO
++
++ // Free the shadow descriptor memory
++ kfree(priv->tx_desc_shadow_);
++ priv->tx_desc_shadow_ = 0;
++
++ kfree(priv->rx_desc_shadow_);
++ priv->rx_desc_shadow_ = 0;
++
++ // Release the IRQ
++ if (priv->have_irq) {
++ free_irq(dev->irq, dev);
++ priv->have_irq = 0;
++ }
++
++ // Disable the clock to the MAC block
++ writel(1UL << SYS_CTRL_CKEN_MAC_BIT, SYS_CTRL_CKEN_CLR_CTRL);
++
++ // Free the sysfs resources
++ kobject_del(&priv->link_state_kobject);
++ subsystem_unregister(&priv->link_state_kset);
++
++ return 0;
++}
++
++static void hw_set_mac_address(struct net_device *dev, unsigned char* addr)
++{
++ u32 mac_lo;
++ u32 mac_hi;
++
++ mac_lo = (u32)addr[0];
++ mac_lo |= ((u32)addr[1] << 8);
++ mac_lo |= ((u32)addr[2] << 16);
++ mac_lo |= ((u32)addr[3] << 24);
++
++ mac_hi = (u32)addr[4];
++ mac_hi |= ((u32)addr[5] << 8);
++
++ mac_reg_write(netdev_priv(dev), MAC_ADR0_LOW_REG, mac_lo);
++ mac_reg_write(netdev_priv(dev), MAC_ADR0_HIGH_REG, mac_hi);
++}
++
++static int set_mac_address(struct net_device *dev, void *p)
++{
++ struct sockaddr *addr = p;
++
++ if (!is_valid_ether_addr(addr->sa_data)) {
++ return -EADDRNOTAVAIL;
++ }
++
++ memcpy(dev->dev_addr, addr->sa_data, dev->addr_len);
++ hw_set_mac_address(dev, addr->sa_data);
++
++ return 0;
++}
++
++static void multicast_hash(struct dev_mc_list *dmi, u32 *hash_lo, u32 *hash_hi)
++{
++ u32 crc = ether_crc_le(dmi->dmi_addrlen, dmi->dmi_addr);
++ u32 mask = 1 << ((crc >> 26) & 0x1F);
++
++ if (crc >> 31) {
++ *hash_hi |= mask;
++ } else {
++ *hash_lo |= mask;
++ }
++}
++
++static void set_multicast_list(struct net_device *dev)
++{
++ gmac_priv_t* priv = netdev_priv(dev);
++ u32 hash_lo=0;
++ u32 hash_hi=0;
++ u32 mode = 0;
++ int i;
++
++ // Disable promiscuous mode and uni/multi-cast matching
++ mac_reg_write(priv, MAC_FRAME_FILTER_REG, mode);
++
++ // Disable all perfect match registers
++ for (i=0; i < NUM_PERFECT_MATCH_REGISTERS; ++i) {
++ mac_adrhi_reg_write(priv, i, 0);
++ }
++
++ // Promiscuous mode overrides all-multi which overrides other filtering
++ if (dev->flags & IFF_PROMISC) {
++ mode |= (1 << MAC_FRAME_FILTER_PR_BIT);
++ } else if (dev->flags & IFF_ALLMULTI) {
++ mode |= (1 << MAC_FRAME_FILTER_PM_BIT);
++ } else {
++ struct dev_mc_list *dmi;
++
++ if (dev->mc_count <= NUM_PERFECT_MATCH_REGISTERS) {
++ // Use perfect matching registers
++ for (i=0, dmi = dev->mc_list; dmi; dmi = dmi->next, ++i) {
++ u32 addr;
++
++ addr = dmi->dmi_addr[0];
++ addr |= (u32)dmi->dmi_addr[1] << 8;
++ addr |= (u32)dmi->dmi_addr[2] << 16;
++ addr |= (u32)dmi->dmi_addr[3] << 24;
++ mac_adrlo_reg_write(priv, i, addr);
++
++ addr = dmi->dmi_addr[4];
++ addr |= (u32)dmi->dmi_addr[5] << 8;
++ addr |= (1 << MAC_ADR1_HIGH_AE_BIT);
++ mac_adrhi_reg_write(priv, i, addr);
++ }
++ } else {
++ // Use hashing
++ mode |= (1 << MAC_FRAME_FILTER_HUC_BIT);
++ mode |= (1 << MAC_FRAME_FILTER_HMC_BIT);
++
++ for (dmi = dev->mc_list; dmi; dmi = dmi->next) {
++ multicast_hash(dmi, &hash_lo, &hash_hi);
++ }
++ }
++ }
++
++ // Update the filtering rules
++ mac_reg_write(priv, MAC_FRAME_FILTER_REG, mode);
++
++ // Update the filtering hash table
++ mac_reg_write(priv, MAC_HASH_LOW_REG, hash_lo);
++ mac_reg_write(priv, MAC_HASH_HIGH_REG, hash_hi);
++}
++
++static int gmac_up(struct net_device *dev)
++{
++ int status = 0;
++ gmac_priv_t *priv = (gmac_priv_t*)netdev_priv(dev);
++ u32 reg_contents;
++#ifdef CONFIG_LEON_COPRO
++ int cmd_queue_result;
++#endif // CONFIG_LEON_COPRO
++
++ // Reset the entire GMAC
++ dma_reg_write(priv, DMA_BUS_MODE_REG, 1UL << DMA_BUS_MODE_SWR_BIT);
++
++ // Ensure reset is performed before testing for completion
++ wmb();
++
++ // Wait for the reset operation to complete
++ status = -EIO;
++ printk(KERN_INFO "Resetting GMAC\n");
++ for (;;) {
++ if (!(dma_reg_read(priv, DMA_BUS_MODE_REG) & (1UL << DMA_BUS_MODE_SWR_BIT))) {
++ status = 0;
++ break;
++ }
++ }
++
++ // Did the GMAC reset operation fail?
++ if (status) {
++ printk(KERN_ERR "open() %s: GMAC reset failed\n", dev->name);
++ goto gmac_up_err_out;
++ }
++ printk(KERN_INFO "GMAC reset complete\n");
++
++ /* Initialise MAC config register contents
++ */
++ reg_contents = 0;
++ if (!priv->mii.using_1000) {
++ DBG(1, KERN_INFO "open() %s: PHY in 10/100Mb mode\n", dev->name);
++ reg_contents |= (1UL << MAC_CONFIG_PS_BIT);
++ } else {
++ DBG(1, KERN_INFO "open() %s: PHY in 1000Mb mode\n", dev->name);
++ }
++ if (priv->mii.full_duplex) {
++ reg_contents |= (1UL << MAC_CONFIG_DM_BIT);
++ }
++
++#ifdef USE_RX_CSUM
++ reg_contents |= (1UL << MAC_CONFIG_IPC_BIT);
++#endif // USE_RX_CSUM
++
++ if (priv->jumbo_) {
++ // Allow passage of jumbo frames through both transmitter and receiver
++ reg_contents |= ((1UL << MAC_CONFIG_JE_BIT) |
++ (1UL << MAC_CONFIG_JD_BIT) |
++ (1UL << MAC_CONFIG_WD_BIT));
++ }
++
++ // Enable transmitter and receiver
++ reg_contents |= ((1UL << MAC_CONFIG_TE_BIT) |
++ (1UL << MAC_CONFIG_RE_BIT));
++
++ // Select the minimum IFG - I found that 80 bit times caused very poor
++ // IOZone performance, so stcik with the 96 bit times default
++ reg_contents |= (0UL << MAC_CONFIG_IFG_BIT);
++
++ // Write MAC config setup to the GMAC
++ mac_reg_write(priv, MAC_CONFIG_REG, reg_contents);
++
++ /* Initialise MAC VLAN register contents
++ */
++ reg_contents = 0;
++ mac_reg_write(priv, MAC_VLAN_TAG_REG, reg_contents);
++
++ // Initialise the hardware's record of our primary MAC address
++ hw_set_mac_address(dev, dev->dev_addr);
++
++ // Initialise multicast and promiscuous modes
++ set_multicast_list(dev);
++
++ // Disable all MMC interrupt sources
++ mac_reg_write(priv, MMC_RX_MASK_REG, ~0UL);
++ mac_reg_write(priv, MMC_TX_MASK_REG, ~0UL);
++
++ // Remember how large the unified descriptor array is to be
++ priv->total_num_descriptors = NUM_TX_DMA_DESCRIPTORS + NUM_RX_DMA_DESCRIPTORS;
++
++ // Initialise the structures managing the TX descriptor list
++ init_tx_desc_list(&priv->tx_gmac_desc_list_info,
++ priv->desc_vaddr,
++ priv->tx_desc_shadow_,
++ NUM_TX_DMA_DESCRIPTORS);
++
++ // Initialise the structures managing the RX descriptor list
++ init_rx_desc_list(&priv->rx_gmac_desc_list_info,
++ priv->desc_vaddr + NUM_TX_DMA_DESCRIPTORS,
++ priv->rx_desc_shadow_,
++ NUM_RX_DMA_DESCRIPTORS,
++ priv->rx_buffer_size_);
++
++ // Reset record of pending Tx packet
++ priv->tx_pending_skb = 0;
++ priv->tx_pending_fragment_count = 0;
++
++#ifndef CONFIG_LEON_OFFLOAD_TX
++ // Write the physical DMA consistent address of the start of the tx descriptor array
++ dma_reg_write(priv, DMA_TX_DESC_ADR_REG, priv->desc_dma_addr);
++#endif // !CONFIG_LEON_OFFLOAD_TX
++
++ // Write the physical DMA consistent address of the start of the rx descriptor array
++ dma_reg_write(priv, DMA_RX_DESC_ADR_REG, priv->desc_dma_addr +
++ (priv->tx_gmac_desc_list_info.num_descriptors * sizeof(gmac_dma_desc_t)));
++
++ // Initialise the GMAC DMA bus mode register
++ dma_reg_write(priv, DMA_BUS_MODE_REG, ((1UL << DMA_BUS_MODE_FB_BIT) | // Force bursts
++ (8UL << DMA_BUS_MODE_PBL_BIT) | // AHB burst size
++ (1UL << DMA_BUS_MODE_DA_BIT))); // Round robin Rx/Tx
++
++ // Prepare receive descriptors
++ refill_rx_ring(dev);
++
++ // Clear any pending interrupt requests
++ dma_reg_write(priv, DMA_STATUS_REG, dma_reg_read(priv, DMA_STATUS_REG));
++
++ /* Initialise flow control register contents
++ */
++ // Enable Rx flow control
++ reg_contents = (1UL << MAC_FLOW_CNTL_RFE_BIT);
++
++#ifndef CONFIG_HIPOX_VERSION_0X800
++ if (priv->mii.using_pause) {
++ // Enable Tx flow control
++ reg_contents |= (1UL << MAC_FLOW_CNTL_TFE_BIT);
++ }
++
++ // Set the duration of the pause frames generated by the transmitter when
++ // the Rx fifo fill threshold is exceeded
++ reg_contents |= ((0x100UL << MAC_FLOW_CNTL_PT_BIT) | // Pause for 256 slots
++ (0x1UL << MAC_FLOW_CNTL_PLT_BIT));
++#endif // !CONFIG_HIPOX_VERSION_0X800
++
++ // Write flow control setup to the GMAC
++ mac_reg_write(priv, MAC_FLOW_CNTL_REG, reg_contents);
++
++ /* Initialise operation mode register contents
++ */
++ // Initialise the GMAC DMA operation mode register. Set Tx/Rx FIFO thresholds
++ // to make best use of our limited SDRAM bandwidth when operating in gigabit
++ reg_contents = ((DMA_OP_MODE_TTC_256 << DMA_OP_MODE_TTC_BIT) | // Tx threshold
++ (1UL << DMA_OP_MODE_FUF_BIT) | // Forward Undersized good Frames
++ (DMA_OP_MODE_RTC_128 << DMA_OP_MODE_RTC_BIT) | // Rx threshold 128 bytes
++ (1UL << DMA_OP_MODE_OSF_BIT)); // Operate on 2nd frame
++
++#ifndef CONFIG_HIPOX_VERSION_0X800
++ // Enable hardware flow control
++ reg_contents |= (1UL << DMA_OP_MODE_EFC_BIT);
++
++ // Set threshold for enabling hardware flow control at (full-4KB) to give
++ // space for upto two in-flight std MTU packets to arrive after pause frame
++ // has been sent.
++ reg_contents |= ((0UL << DMA_OP_MODE_RFA2_BIT) |
++ (3UL << DMA_OP_MODE_RFA_BIT));
++
++ // Set threshold for disabling hardware flow control (-7KB)
++ reg_contents |= ((1UL << DMA_OP_MODE_RFD2_BIT) |
++ (2UL << DMA_OP_MODE_RFD_BIT));
++
++ // Don't flush Rx frames from FIFO just because there's no descriptor available
++ reg_contents |= (1UL << DMA_OP_MODE_DFF_BIT);
++#endif // !CONFIG_HIPOX_VERSION_0X800
++
++ // Write settings to operation mode register
++ dma_reg_write(priv, DMA_OP_MODE_REG, reg_contents);
++
++#ifdef CONFIG_HIPOX_VERSION_0X800
++ // Use store&forward when operating in gigabit mode, as OX800 does not have
++ // sufficient SDRAM bandwidth to support gigabit Tx without it and OX800
++ // does not support Tx checksumming in the GMAC
++ if (priv->mii.using_1000) {
++ dma_reg_set_mask(priv, DMA_OP_MODE_REG, (1UL << DMA_OP_MODE_SF_BIT));
++ } else {
++ dma_reg_clear_mask(priv, DMA_OP_MODE_REG, (1UL << DMA_OP_MODE_SF_BIT));
++ }
++#else // CONFIG_HIPOX_VERSION_0X800
++ // GMAC requires store&forward in order to compute Tx checksums
++ dma_reg_set_mask(priv, DMA_OP_MODE_REG, (1UL << DMA_OP_MODE_SF_BIT));
++#endif // CONFIG_HIPOX_VERSION_0X800
++
++ // Ensure setup is complete, before enabling TX and RX
++ wmb();
++
++#ifdef CONFIG_LEON_COPRO
++ // Update the CoPro's parameters with the current MTU
++ priv->copro_params_.mtu_ = dev->mtu;
++
++ // Only attempt to write to uncached/unbuffered shared parameter storage if
++ // CoPro is started and thus storage has been allocated
++ if (priv->shared_copro_params_) {
++ // Fill the CoPro parameter block
++ memcpy(priv->shared_copro_params_, &priv->copro_params_, sizeof(copro_params_t));
++ }
++
++ // Make sure the CoPro parameter block updates have made it to memory (which
++ // is uncached/unbuffered, so just compiler issues to overcome)
++ wmb();
++
++ // Tell the CoPro to re-read parameters
++ cmd_queue_result = -1;
++ while (cmd_queue_result) {
++ spin_lock(&priv->cmd_que_lock_);
++ cmd_queue_result = cmd_que_queue_cmd(&priv->cmd_queue_, GMAC_CMD_UPDATE_PARAMS, 0, copro_update_callback);
++ spin_unlock(&priv->cmd_que_lock_);
++ }
++
++ // Interrupt the CoPro so it sees the new command
++ writel(1UL << COPRO_SEM_INT_CMD, SYS_CTRL_SEMA_SET_CTRL);
++
++ // Wait until the CoPro acknowledges that the update of parameters is complete
++ down_interruptible(&copro_update_semaphore);
++
++ // Tell the CoPro to begin network offload operations
++ cmd_queue_result = -1;
++ while (cmd_queue_result) {
++ spin_lock(&priv->cmd_que_lock_);
++ cmd_queue_result = cmd_que_queue_cmd(&priv->cmd_queue_, GMAC_CMD_START, 0, copro_start_callback);
++ spin_unlock(&priv->cmd_que_lock_);
++ }
++
++ // Interrupt the CoPro so it sees the new command
++ writel(1UL << COPRO_SEM_INT_CMD, SYS_CTRL_SEMA_SET_CTRL);
++
++ // Wait until the CoPro acknowledges that it has started
++ down_interruptible(&copro_start_semaphore);
++#endif // CONFIG_LEON_COPRO
++
++ // Start NAPI
++ napi_enable(&priv->napi_struct);
++
++ // Start the transmitter and receiver
++#ifndef CONFIG_LEON_OFFLOAD_TX
++ dma_reg_set_mask(priv, DMA_OP_MODE_REG, (1UL << DMA_OP_MODE_ST_BIT));
++#endif // !LEON_OFFLOAD_TX
++ change_rx_enable(priv, 1, 0, 0);
++
++ // Enable interesting GMAC interrupts
++ gmac_int_en_set(priv, ((1UL << DMA_INT_ENABLE_NI_BIT) |
++ (1UL << DMA_INT_ENABLE_AI_BIT) |
++ (1UL << DMA_INT_ENABLE_FBE_BIT) |
++ (1UL << DMA_INT_ENABLE_RI_BIT) |
++ (1UL << DMA_INT_ENABLE_RU_BIT) |
++ (1UL << DMA_INT_ENABLE_OV_BIT) |
++ (1UL << DMA_INT_ENABLE_RW_BIT) |
++ (1UL << DMA_INT_ENABLE_RS_BIT) |
++ (1UL << DMA_INT_ENABLE_TI_BIT) |
++ (1UL << DMA_INT_ENABLE_UN_BIT) |
++ (1UL << DMA_INT_ENABLE_TJ_BIT) |
++ (1UL << DMA_INT_ENABLE_TS_BIT)));
++
++ // (Re)start the link/PHY state monitoring timer
++ start_watchdog_timer(priv);
++
++ // Allow the network stack to call hard_start_xmit()
++ netif_start_queue(dev);
++
++#ifdef DUMP_REGS_ON_GMAC_UP
++ dump_mac_regs(priv->macBase, priv->dmaBase);
++#endif // DUMP_REGS_ON_GMAC_UP
++
++ return status;
++
++gmac_up_err_out:
++ stop(dev);
++
++ return status;
++}
++
++static void set_rx_packet_info(struct net_device *dev)
++{
++ gmac_priv_t *priv = (gmac_priv_t*)netdev_priv(dev);
++ int max_packet_buffer_size = dev->mtu + EXTRA_RX_SKB_SPACE;
++
++ if (max_packet_buffer_size > max_descriptor_length()) {
++#ifndef RX_BUFFER_SIZE
++ priv->rx_buffer_size_ = max_packet_buffer_size;
++#else // !RX_BUFFER_SIZE
++ priv->rx_buffer_size_ = RX_BUFFER_SIZE;
++#endif // ! RX_BUFFER_SIZE
++ priv->rx_buffers_per_page = GMAC_ALLOC_SIZE / (priv->rx_buffer_size_ + NET_IP_ALIGN);
++ } else {
++ priv->rx_buffer_size_ = max_packet_buffer_size;
++ priv->rx_buffers_per_page = 0;
++ }
++}
++
++static int change_mtu(struct net_device *dev, int new_mtu)
++{
++ int status = 0;
++ gmac_priv_t *priv = (gmac_priv_t*)netdev_priv(dev);
++ int original_mtu = dev->mtu;
++
++ // Check that new MTU is within supported range
++ if ((new_mtu < MIN_PACKET_SIZE) || (new_mtu > MAX_JUMBO)) {
++ DBG(1, KERN_WARNING "change_mtu() %s: Invalid MTU %d\n", dev->name, new_mtu);
++ status = -EINVAL;
++ } else {
++ // Put MAC/PHY into quiesent state, causing all current buffers to be
++ // deallocated and the PHY to powerdown
++ gmac_down(dev);
++
++ // Record the new MTU, so bringing the MAC back up will allocate
++ // resources to suit the new MTU
++ dev->mtu = new_mtu;
++
++ // Set length etc. of rx packets
++ set_rx_packet_info(dev);
++
++ // Reset the PHY to get it into a known state and ensure we have TX/RX
++ // clocks to allow the GMAC reset to complete
++ if (phy_reset(priv->netdev)) {
++ DBG(1, KERN_ERR "change_mtu() %s: Failed to reset PHY\n", dev->name);
++ status = -EIO;
++ } else {
++ // Set PHY specfic features
++ initialise_phy(priv);
++
++ // Record whether jumbo frames should be enabled
++ priv->jumbo_ = (dev->mtu > NORMAL_PACKET_SIZE);
++
++ // Force or auto-negotiate PHY mode
++ priv->phy_force_negotiation = 1;
++
++ // Reallocate buffers with new MTU
++ gmac_up(dev);
++ }
++ }
++
++ // If there was a failure
++ if (status) {
++ // Return the MTU to its original value
++ DBG(1, KERN_INFO "change_mtu() Failed, returning MTU to original value\n");
++ dev->mtu = original_mtu;
++ }
++
++ return status;
++}
++
++#ifdef TEST_COPRO
++DECLARE_MUTEX_LOCKED(start_sem);
++DECLARE_MUTEX_LOCKED(heartbeat_sem);
++
++void start_callback(volatile gmac_cmd_que_ent_t* entry)
++{
++ printk("START callback, operand = 0x%08x\n", entry->operand_);
++ up(&start_sem);
++}
++
++void heartbeat_callback(volatile gmac_cmd_que_ent_t* entry)
++{
++ printk("Heartbeat callback, operand = 0x%08x\n", entry->operand_);
++ up(&heartbeat_sem);
++}
++
++static void test_copro(gmac_priv_t* priv)
++{
++ unsigned long irq_flags;
++
++ spin_lock(&priv->cmd_que_lock_);
++ cmd_que_queue_cmd(&priv->cmd_queue_, GMAC_CMD_STOP, 0, 0);
++ spin_unlock(&priv->cmd_que_lock_);
++ writel(1UL << COPRO_SEM_INT_CMD, SYS_CTRL_SEMA_SET_CTRL);
++ mdelay(500);
++
++ spin_lock(&priv->cmd_que_lock_);
++ cmd_que_queue_cmd(&priv->cmd_queue_, GMAC_CMD_START, 0, start_callback);
++ spin_unlock(&priv->cmd_que_lock_);
++ writel(1UL << COPRO_SEM_INT_CMD, SYS_CTRL_SEMA_SET_CTRL);
++ mdelay(500);
++
++ spin_lock(&priv->cmd_que_lock_);
++ cmd_que_queue_cmd(&priv->cmd_queue_, GMAC_CMD_HEARTBEAT, 0, heartbeat_callback);
++ spin_unlock(&priv->cmd_que_lock_);
++ writel(1UL << COPRO_SEM_INT_CMD, SYS_CTRL_SEMA_SET_CTRL);
++ mdelay(500);
++
++ printk("Waiting for start ack...\n");
++ down_interruptible(&start_sem);
++ printk("Start ack received\n");
++
++ printk("Waiting for heartbeat ack...\n");
++ down_interruptible(&heartbeat_sem);
++ printk("Heartbeat ack received\n");
++}
++#endif // TEST_COPRO
++
++#ifdef CONFIG_LEON_COPRO
++#define SEM_INT_FWD 8
++#define SEM_INT_ACK 16
++#define SEM_INT_TX 17
++#define SEM_INT_STOP_ACK 18
++
++#define SEM_INTA_MASK (1UL << SEM_INT_FWD)
++#define SEM_INTB_MASK ((1UL << SEM_INT_ACK) | (1UL << SEM_INT_TX) | (1UL << SEM_INT_STOP_ACK))
++
++static irqreturn_t copro_sema_intr(int irq, void *dev_id)
++{
++ struct net_device *dev = (struct net_device *)dev_id;
++ gmac_priv_t *priv = (gmac_priv_t*)netdev_priv(dev);
++ u32 asserted;
++ u32 fwd_intrs_status = 0;
++ int is_fwd_intr;
++
++ // Read the contents of semaphore A register
++ asserted = (*((volatile unsigned long*)SYS_CTRL_SEMA_STAT) & SEM_INTA_MASK);
++
++ while (asserted) {
++ // Extract any forwarded interrupts info
++ is_fwd_intr = asserted & (1UL << SEM_INT_FWD);
++ if (is_fwd_intr) {
++ fwd_intrs_status = ((volatile gmac_fwd_intrs_t*)descriptors_phys_to_virt(priv->copro_params_.fwd_intrs_mailbox_))->status_;
++ }
++
++ // Clear any interrupts directed at the ARM
++ *((volatile unsigned long*)SYS_CTRL_SEMA_CLR_CTRL) = asserted;
++
++ if (is_fwd_intr) {
++ // Process any forwarded GMAC interrupts
++ copro_fwd_intrs_handler(dev_id, fwd_intrs_status);
++ }
++
++ // Stay in interrupt routine if interrupt has been re-asserted
++ asserted = (*((volatile unsigned long*)SYS_CTRL_SEMA_STAT) & SEM_INTA_MASK);
++ }
++
++ return IRQ_HANDLED;
++}
++
++static irqreturn_t copro_semb_intr(int irq, void *dev_id)
++{
++ struct net_device *dev = (struct net_device *)dev_id;
++ gmac_priv_t *priv = (gmac_priv_t*)netdev_priv(dev);
++ u32 asserted;
++
++ // Read the contents of semaphore B register
++ asserted = (*((volatile unsigned long*)SYS_CTRL_SEMA_STAT) & SEM_INTB_MASK);
++
++ while (asserted) {
++ // Clear any interrupts directed at the ARM
++ *((volatile unsigned long*)SYS_CTRL_SEMA_CLR_CTRL) = asserted;
++
++ // Process any outstanding command acknowledgements
++ if (asserted & (1UL << SEM_INT_ACK)) {
++ while (!cmd_que_dequeue_ack(&priv->cmd_queue_));
++ }
++
++ // Process STOP completion signal
++ if (asserted & (1UL << SEM_INT_STOP_ACK)) {
++ up(&priv->copro_stop_complete_semaphore_);
++ }
++
++#ifdef CONFIG_LEON_OFFLOAD_TX
++ // Process any completed TX offload jobs
++ if (asserted & (1UL << SEM_INT_TX)) {
++ finish_xmit(dev);
++ }
++#endif // CONFIG_LEON_OFFLOAD_TX
++
++ // Stay in interrupt routine if interrupt has been re-asserted
++ asserted = (*((volatile unsigned long*)SYS_CTRL_SEMA_STAT) & SEM_INTB_MASK);
++ }
++
++ return IRQ_HANDLED;
++}
++#endif // CONFIG_LEON_COPRO
++
++static int open(struct net_device *dev)
++{
++ gmac_priv_t* priv = (gmac_priv_t*)netdev_priv(dev);
++ int status;
++
++ // Ensure the MAC block is properly reset
++ writel(1UL << SYS_CTRL_RSTEN_MAC_BIT, SYS_CTRL_RSTEN_SET_CTRL);
++ writel(1UL << SYS_CTRL_RSTEN_MAC_BIT, SYS_CTRL_RSTEN_CLR_CTRL);
++
++ // Enable the clock to the MAC block
++ writel(1UL << SYS_CTRL_CKEN_MAC_BIT, SYS_CTRL_CKEN_SET_CTRL);
++
++ // Ensure reset and clock operations are complete
++ wmb();
++
++ // Reset the PHY to get it into a known state and ensure we have TX/RX clocks
++ // to allow the GMAC reset to complete
++ if (phy_reset(priv->netdev)) {
++ DBG(1, KERN_ERR "open() %s: Failed to reset PHY\n", dev->name);
++ status = -EIO;
++ goto open_err_out;
++ }
++
++ // Set PHY specfic features
++ initialise_phy(priv);
++
++ // Check that the MAC address is valid. If it's not, refuse to bring the
++ // device up
++ if (!is_valid_ether_addr(dev->dev_addr)) {
++ DBG(1, KERN_ERR "open() %s: MAC address invalid\n", dev->name);
++ status = -EINVAL;
++ goto open_err_out;
++ }
++
++#ifdef CONFIG_LEON_COPRO
++ // Register ISRs for the semaphore register interrupt sources, which will
++ // originate from the CoPro
++ if (request_irq(priv->copro_a_irq_, &copro_sema_intr, 0, "SEMA", dev)) {
++ panic("open: Failed to allocate semaphore A %u\n", priv->copro_a_irq_);
++ status = -ENODEV;
++ goto open_err_out;
++ }
++ priv->copro_a_irq_alloced_ = 1;
++
++ if (request_irq(priv->copro_b_irq_, &copro_semb_intr, 0, "SEMB", dev)) {
++ panic("open: Failed to allocate semaphore B %u\n", priv->copro_b_irq_);
++ status = -ENODEV;
++ goto open_err_out;
++ }
++ priv->copro_b_irq_alloced_ = 1;
++#else // CONFIG_LEON_COPRO
++ // Allocate the IRQ
++ if (request_irq(dev->irq, &int_handler, 0, dev->name, dev)) {
++ DBG(1, KERN_ERR "open() %s: Failed to allocate irq %d\n", dev->name, dev->irq);
++ status = -ENODEV;
++ goto open_err_out;
++ }
++ priv->have_irq = 1;
++#endif // CONFIG_LEON_COPRO
++
++ // Need a consistent DMA mapping covering all the memory occupied by DMA
++ // unified descriptor array, as both CPU and DMA engine will be reading and
++ // writing descriptor fields.
++ priv->desc_vaddr = (gmac_dma_desc_t*)GMAC_DESC_ALLOC_START;
++ priv->desc_dma_addr = GMAC_DESC_ALLOC_START_PA;
++
++ if (!priv->desc_vaddr) {
++ DBG(1, KERN_ERR "open() %s: Failed to allocate consistent memory for DMA descriptors\n", dev->name);
++ status = -ENOMEM;
++ goto open_err_out;
++ }
++
++ // Allocate memory to hold shadow of GMAC descriptors
++ if (!(priv->tx_desc_shadow_ = kmalloc(NUM_TX_DMA_DESCRIPTORS * sizeof(gmac_dma_desc_t), GFP_KERNEL))) {
++ DBG(1, KERN_ERR "open() %s: Failed to allocate memory for Tx descriptor shadows\n", dev->name);
++ status = -ENOMEM;
++ goto open_err_out;
++ }
++ if (!(priv->rx_desc_shadow_ = kmalloc(NUM_RX_DMA_DESCRIPTORS * sizeof(gmac_dma_desc_t), GFP_KERNEL))) {
++ DBG(1, KERN_ERR "open() %s: Failed to allocate memory for Rx descriptor shadows\n", dev->name);
++ status = -ENOMEM;
++ goto open_err_out;
++ }
++
++ // Record whether jumbo frames should be enabled
++ priv->jumbo_ = (dev->mtu > NORMAL_PACKET_SIZE);
++
++ set_rx_packet_info(dev);
++
++#ifdef CONFIG_LEON_COPRO
++ // Allocate SRAM for the command queue entries
++ priv->copro_params_.cmd_que_head_ = DESCRIPTORS_BASE_PA + DESCRIPTORS_SIZE;
++
++ priv->copro_params_.cmd_que_tail_ =
++ (u32)((gmac_cmd_que_ent_t*)(priv->copro_params_.cmd_que_head_) + priv->copro_cmd_que_num_entries_);
++ priv->copro_params_.fwd_intrs_mailbox_ = priv->copro_params_.cmd_que_tail_;
++ priv->copro_params_.tx_que_head_ = priv->copro_params_.fwd_intrs_mailbox_ + sizeof(gmac_fwd_intrs_t);
++ priv->copro_params_.tx_que_tail_ =
++ (u32)((gmac_tx_que_ent_t*)(priv->copro_params_.tx_que_head_) + priv->copro_tx_que_num_entries_);
++ priv->copro_params_.free_start_ = priv->copro_params_.tx_que_tail_;
++
++ // Set RX interrupt mitigation behaviour
++ priv->copro_params_.rx_mitigation_ = COPRO_RX_MITIGATION;
++ priv->copro_params_.rx_mitigation_frames_ = COPRO_RX_MITIGATION_FRAMES;
++ priv->copro_params_.rx_mitigation_usec_ = COPRO_RX_MITIGATION_USECS;
++
++ // Initialise command queue metadata
++ cmd_que_init(
++ &priv->cmd_queue_,
++ (gmac_cmd_que_ent_t*)descriptors_phys_to_virt(priv->copro_params_.cmd_que_head_),
++ priv->copro_cmd_que_num_entries_);
++
++ // Initialise tx offload queue metadata
++ tx_que_init(
++ &priv->tx_queue_,
++ (gmac_tx_que_ent_t*)descriptors_phys_to_virt(priv->copro_params_.tx_que_head_),
++ priv->copro_tx_que_num_entries_);
++
++ // Allocate DMA coherent space for the parameter block shared with the CoPro
++ priv->shared_copro_params_ = dma_alloc_coherent(0, sizeof(copro_params_t), &priv->shared_copro_params_pa_, GFP_KERNEL);
++ if (!priv->shared_copro_params_) {
++ DBG(1, KERN_ERR "open() %s: Failed to allocate DMA coherent space for parameters\n");
++ status = -ENOMEM;
++ goto open_err_out;
++ }
++
++ // Update the CoPro's parameters with the current MTU
++ priv->copro_params_.mtu_ = dev->mtu;
++
++ // Fill the shared CoPro parameter block from the ARM's local copy
++ memcpy(priv->shared_copro_params_, &priv->copro_params_, sizeof(copro_params_t));
++
++ // Load CoPro program and start it running
++ init_copro(leon_srec, priv->shared_copro_params_pa_);
++
++ // Enable selected semaphore register bits to cause ARM interrupts
++ *((volatile unsigned long*)SYS_CTRL_SEMA_MASKA_CTRL) = SEM_INTA_MASK;
++ *((volatile unsigned long*)SYS_CTRL_SEMA_MASKB_CTRL) = SEM_INTB_MASK;
++
++#ifdef TEST_COPRO
++ // Send test commands to the CoPro
++ test_copro(priv);
++#endif // TEST_COPRO
++#endif // CONFIG_LEON_COPRO
++
++ // Do startup operations that are in common with gmac_down()/_up() processing
++ priv->mii_init_media = 1;
++ priv->phy_force_negotiation = 1;
++ status = gmac_up(dev);
++ if (status) {
++ goto open_err_out;
++ }
++
++ return 0;
++
++open_err_out:
++ stop(dev);
++
++ return status;
++}
++
++#if defined(CONFIG_LEON_COPRO) && defined(CONFIG_LEON_OFFLOAD_TX)
++static int hard_start_xmit(
++ struct sk_buff *skb,
++ struct net_device *dev)
++{
++ gmac_priv_t *priv = (gmac_priv_t*)netdev_priv(dev);
++ volatile gmac_tx_que_ent_t *job;
++ unsigned long irq_flags;
++
++ if (skb_shinfo(skb)->frag_list) {
++ panic("Frag list - can't handle this!\n");
++ }
++
++ // Protection against concurrent operations in ISR and hard_start_xmit()
++ if (!spin_trylock_irqsave(&priv->tx_spinlock_, irq_flags)) {
++ return NETDEV_TX_LOCKED;
++ }
++
++ // NETIF_F_LLTX apparently introduces a potential for hard_start_xmit() to
++ // be called when the queue has been stopped (although I think only in SMP)
++ // so do a check here to make sure we should proceed
++ if (netif_queue_stopped(dev)) {
++ spin_unlock_irqrestore(&priv->tx_spinlock_, irq_flags);
++ return NETDEV_TX_BUSY;
++ }
++
++ job = tx_que_get_idle_job(dev);
++ if (!job) {
++ // Tx offload queue is full, so add skb to pending skb list
++ list_add_tail((struct list_head*)&skb->cb, &priv->copro_tx_skb_list_);
++
++ // Keep track of how many entries are in the pending SKB list
++ ++priv->copro_tx_skb_list_count_;
++
++ // Have we queued the max allowed number of SKBs?
++ if (priv->copro_tx_skb_list_count_ >= COPRO_MAX_QUEUED_TX_SKBS) {
++ // Stop further calls to hard_start_xmit() until some descriptors
++ // are freed up by already queued TX packets being completed
++ netif_stop_queue(dev);
++ }
++ } else {
++ if (priv->copro_tx_skb_list_count_) {
++ // Have queued pending SKBs, so add new SKB to tail of pending list
++ list_add_tail((struct list_head*)&skb->cb, &priv->copro_tx_skb_list_);
++
++ // Keep track of how many entries are in the pending SKB list
++ ++priv->copro_tx_skb_list_count_;
++
++ // Process pending SKBs, oldest first
++ copro_process_pending_tx_skbs(dev, job);
++ } else {
++ // Fill the Tx offload job with the network packet's details
++ copro_fill_tx_job(job, skb);
++
++ // Enqueue the new Tx offload job with the CoPro
++ tx_que_new_job(dev, job);
++ }
++
++ // Record start of transmission, so timeouts will work once they're
++ // implemented
++ dev->trans_start = jiffies;
++
++ // Interrupt the CoPro to cause it to examine the Tx offload queue
++ wmb();
++ writel(1UL << COPRO_SEM_INT_TX, SYS_CTRL_SEMA_SET_CTRL);
++
++ // If the network stack's Tx queue was stopped and we now have resources
++ // to process more Tx offload jobs
++ if (netif_queue_stopped(dev) &&
++ !tx_que_is_full(&priv->tx_queue_) &&
++ !priv->copro_tx_skb_list_count_) {
++ // Restart the network stack's TX queue
++ netif_wake_queue(dev);
++ }
++ }
++
++ spin_unlock_irqrestore(&priv->tx_spinlock_, irq_flags);
++
++ return NETDEV_TX_OK;
++}
++#else
++static inline void unmap_fragments(
++ tx_frag_info_t *frags,
++ int count)
++{
++ while (count--) {
++ dma_unmap_single(0, frags->phys_adr, frags->length, DMA_TO_DEVICE);
++ ++frags;
++ }
++}
++
++static int hard_start_xmit(
++ struct sk_buff *skb,
++ struct net_device *dev)
++{
++ gmac_priv_t *priv = (gmac_priv_t*)netdev_priv(dev);
++ unsigned long irq_flags;
++ struct skb_shared_info *shinfo = skb_shinfo(skb);
++ int fragment_count = shinfo->nr_frags + 1;
++ tx_frag_info_t fragments[fragment_count];
++ int frag_index;
++
++ // Get consistent DMA mappings for the SDRAM to be DMAed from by the GMAC,
++ // causing a flush from the CPU's cache to the memory.
++
++ // Do the DMA mappings before acquiring the tx lock, even though it complicates
++ // the later code, as this can be a long operation involving cache flushing
++
++ // Map the main buffer
++ fragments[0].length = skb_headlen(skb);
++ fragments[0].phys_adr = dma_map_single(0, skb->data, skb_headlen(skb), DMA_TO_DEVICE);
++ BUG_ON(dma_mapping_error(fragments[0].phys_adr));
++
++ // Map any SG fragments
++ for (frag_index = 0; frag_index < shinfo->nr_frags; ++frag_index) {
++ skb_frag_t *frag = &shinfo->frags[frag_index];
++
++ fragments[frag_index + 1].length = frag->size;
++ fragments[frag_index + 1].phys_adr = dma_map_page(0, frag->page, frag->page_offset, frag->size, DMA_TO_DEVICE);
++ BUG_ON(dma_mapping_error(fragments[frag_index + 1].phys_adr));
++ }
++
++ // Protection against concurrent operations in ISR and hard_start_xmit()
++ if (unlikely(!spin_trylock_irqsave(&priv->tx_spinlock_, irq_flags))) {
++ unmap_fragments(fragments, fragment_count);
++ return NETDEV_TX_LOCKED;
++ }
++
++ // NETIF_F_LLTX apparently introduces a potential for hard_start_xmit() to
++ // be called when the queue has been stopped (although I think only in SMP)
++ // so do a check here to make sure we should proceed
++ if (unlikely(netif_queue_stopped(dev))) {
++ unmap_fragments(fragments, fragment_count);
++ spin_unlock_irqrestore(&priv->tx_spinlock_, irq_flags);
++ return NETDEV_TX_BUSY;
++ }
++
++ // Construct the GMAC DMA descriptor
++ if (unlikely(set_tx_descriptor(priv,
++ skb,
++ fragments,
++ fragment_count,
++ skb->ip_summed == CHECKSUM_PARTIAL) < 0)) {
++ // Shouldn't see a full ring without the queue having already been
++ // stopped, and the queue should already have been stopped if we have
++ // already queued a single pending packet
++ if (priv->tx_pending_skb) {
++ printk(KERN_WARNING "hard_start_xmit() Ring full and pending packet already queued\n");
++ unmap_fragments(fragments, fragment_count);
++ spin_unlock_irqrestore(&priv->tx_spinlock_, irq_flags);
++ return NETDEV_TX_BUSY;
++ }
++
++ // Should keep a record of the skb that we haven't been able to queue
++ // for transmission and queue it as soon as a descriptor becomes free
++ priv->tx_pending_skb = skb;
++ priv->tx_pending_fragment_count = fragment_count;
++
++ // Copy the fragment info to the allocated storage
++ memcpy(priv->tx_pending_fragments, fragments, sizeof(tx_frag_info_t) * fragment_count);
++
++ // Stop further calls to hard_start_xmit() until some descriptors are
++ // freed up by already queued TX packets being completed
++ netif_stop_queue(dev);
++ } else {
++ // Record start of transmission, so timeouts will work once they're
++ // implemented
++ dev->trans_start = jiffies;
++
++ // Poke the transmitter to look for available TX descriptors, as we have
++ // just added one, in case it had previously found there were no more
++ // pending transmission
++ dma_reg_write(priv, DMA_TX_POLL_REG, 0);
++ }
++
++ spin_unlock_irqrestore(&priv->tx_spinlock_, irq_flags);
++
++ return NETDEV_TX_OK;
++}
++#endif // CONFIG_LEON_COPRO && CONFIG_LEON_OFFLOAD_TX
++
++static struct net_device_stats *get_stats(struct net_device *dev)
++{
++ gmac_priv_t* priv = (gmac_priv_t*)netdev_priv(dev);
++ return &priv->stats;
++}
++
++#ifdef CONFIG_NET_POLL_CONTROLLER
++/**
++ * Polling 'interrupt' - used by things like netconsole to send skbs without
++ * having to re-enable interrupts. It's not called while the interrupt routine
++ * is executing.
++ */
++static void netpoll(struct net_device *netdev)
++{
++ disable_irq(netdev->irq);
++ int_handler(netdev->irq, netdev, NULL);
++ enable_irq(netdev->irq);
++}
++#endif // CONFIG_NET_POLL_CONTROLLER
++
++static int probe(
++ struct net_device *netdev,
++ u32 vaddr,
++ u32 irq,
++ int copro_a_irq,
++ int copro_b_irq)
++{
++ int err = 0;
++ u32 version;
++ int i;
++ unsigned synopsis_version;
++ unsigned vendor_version;
++ gmac_priv_t* priv = netdev_priv(netdev);
++ u32 reg_contents;
++
++ // Ensure the MAC block is properly reset
++ writel(1UL << SYS_CTRL_RSTEN_MAC_BIT, SYS_CTRL_RSTEN_SET_CTRL);
++ writel(1UL << SYS_CTRL_RSTEN_MAC_BIT, SYS_CTRL_RSTEN_CLR_CTRL);
++
++ // Enable the clock to the MAC block
++ writel(1UL << SYS_CTRL_CKEN_MAC_BIT, SYS_CTRL_CKEN_SET_CTRL);
++
++ // Ensure reset and clock operations are complete
++ wmb();
++
++ // Ensure all of the device private data are zero, so we can clean up in
++ // the event of a later failure to initialise all fields
++ priv = (gmac_priv_t*)netdev_priv(netdev);
++ memset(priv, 0, sizeof(gmac_priv_t));
++
++ // No debug messages allowed
++ priv->msg_level = 0UL;
++
++ // Initialise the ISR/hard_start_xmit() lock
++ spin_lock_init(&priv->tx_spinlock_);
++
++ // Initialise the PHY access lock
++ spin_lock_init(&priv->phy_lock);
++
++ // Set hardware device base addresses
++ priv->macBase = vaddr + MAC_BASE_OFFSET;
++ priv->dmaBase = vaddr + DMA_BASE_OFFSET;
++
++ // Initialise IRQ ownership to not owned
++ priv->have_irq = 0;
++
++ // Lock protecting access to CoPro command queue functions or direct access
++ // to the GMAC interrupt enable register if CoPro is not in use
++ spin_lock_init(&priv->cmd_que_lock_);
++
++#ifdef CONFIG_LEON_COPRO
++ sema_init(&copro_stop_semaphore, 0);
++ sema_init(&copro_start_semaphore, 0);
++ sema_init(&copro_int_clr_semaphore, 0);
++ sema_init(&copro_update_semaphore, 0);
++ sema_init(&copro_rx_enable_semaphore, 0);
++ priv->copro_a_irq_alloced_ = 0;
++ priv->copro_b_irq_alloced_ = 0;
++ sema_init(&priv->copro_stop_complete_semaphore_, 0);
++ INIT_LIST_HEAD(&priv->copro_tx_skb_list_);
++ priv->copro_tx_skb_list_count_ = 0;
++#endif // CONFIG_LEON_COPRO
++
++ init_timer(&priv->watchdog_timer);
++ priv->watchdog_timer.function = &watchdog_timer_action;
++ priv->watchdog_timer.data = (unsigned long)priv;
++
++ // Set pointer to device in private data
++ priv->netdev = netdev;
++
++ /** Do something here to detect the present or otherwise of the MAC
++ * Read the version register as a first test */
++ version = mac_reg_read(priv, MAC_VERSION_REG);
++ synopsis_version = version & 0xff;
++ vendor_version = (version >> 8) & 0xff;
++
++ /** Assume device is at the adr and irq specified until have probing working */
++ netdev->base_addr = vaddr;
++ netdev->irq = irq;
++#ifdef CONFIG_LEON_COPRO
++ priv->copro_a_irq_ = copro_a_irq;
++ priv->copro_b_irq_ = copro_b_irq;
++#endif // CONFIG_LEON_COPRO
++
++#ifdef CONFIG_LEON_COPRO
++ // Allocate the CoPro A IRQ
++ err = request_irq(priv->copro_a_irq_, &copro_sema_intr, 0, "SEMA", netdev);
++ if (err) {
++ DBG(1, KERN_ERR "probe() %s: Failed to allocate CoPro irq A (%d)\n", netdev->name, priv->copro_a_irq_);
++ goto probe_err_out;
++ }
++ // Release the CoPro A IRQ again, as open()/stop() should manage IRQ ownership
++ free_irq(priv->copro_a_irq_, netdev);
++
++ // Allocate the CoPro B IRQ
++ err = request_irq(priv->copro_b_irq_, &copro_semb_intr, 0, "SEMB", netdev);
++ if (err) {
++ DBG(1, KERN_ERR "probe() %s: Failed to allocate CoPro irq B (%d)\n", netdev->name, priv->copro_b_irq_);
++ goto probe_err_out;
++ }
++ // Release the CoPro B IRQ again, as open()/stop() should manage IRQ ownership
++ free_irq(priv->copro_b_irq_, netdev);
++#else // CONFIG_LEON_COPRO
++ // Allocate the IRQ
++ err = request_irq(netdev->irq, &int_handler, 0, netdev->name, netdev);
++ if (err) {
++ DBG(1, KERN_ERR "probe() %s: Failed to allocate irq %d\n", netdev->name, netdev->irq);
++ goto probe_err_out;
++ }
++
++ // Release the IRQ again, as open()/stop() should manage IRQ ownership
++ free_irq(netdev->irq, netdev);
++#endif // CONFIG_LEON_COPRO
++
++ // Initialise the ethernet device with std. contents
++ ether_setup(netdev);
++
++ // Tell the kernel of our MAC address
++ for (i = 0; i < netdev->addr_len; i++) {
++ netdev->dev_addr[i] = (unsigned char)mac_adr[i];
++ }
++
++ // Setup operations pointers
++ netdev->open = &open;
++ netdev->hard_start_xmit = &hard_start_xmit;
++ netdev->stop = &stop;
++ netdev->get_stats = &get_stats;
++ netdev->change_mtu = &change_mtu;
++#ifdef CONFIG_NET_POLL_CONTROLLER
++ netdev->poll_controller = &netpoll;
++#endif // CONFIG_NET_POLL_CONTROLLER
++ netdev->set_mac_address = &set_mac_address;
++ netdev->set_multicast_list = &set_multicast_list;
++
++ // Initialise NAPI support
++ netif_napi_add(netdev, &priv->napi_struct, &poll, NAPI_POLL_WEIGHT);
++
++ set_ethtool_ops(netdev);
++
++ if (debug) {
++ netdev->flags |= IFF_DEBUG;
++ }
++
++#if defined(CONFIG_LEON_COPRO) && defined(CONFIG_LEON_OFFLOAD_TSO)
++ // Do TX H/W checksum and SG list processing
++ netdev->features |= NETIF_F_HW_CSUM;
++ netdev->features |= NETIF_F_SG;
++
++ // Do hardware TCP/IP Segmentation Offload
++ netdev->features |= NETIF_F_TSO;
++#elif !defined(CONFIG_LEON_COPRO) && !defined(CONFIG_HIPOX_VERSION_0X800)
++ // Do TX H/W checksum and SG list processing
++ netdev->features |= NETIF_F_HW_CSUM;
++ netdev->features |= NETIF_F_SG;
++#endif // USE_TX_CSUM
++
++ // We take care of our own TX locking
++ netdev->features |= NETIF_F_LLTX;
++
++ // Initialise PHY support
++ priv->mii.phy_id_mask = 0x1f;
++ priv->mii.reg_num_mask = 0x1f;
++ priv->mii.force_media = 0;
++ priv->mii.full_duplex = 1;
++ priv->mii.using_100 = 0;
++ priv->mii.using_1000 = 1;
++ priv->mii.using_pause = 1;
++ priv->mii.dev = netdev;
++ priv->mii.mdio_read = phy_read;
++ priv->mii.mdio_write = phy_write;
++
++ priv->gmii_csr_clk_range = 5; // Slowest for now
++
++ // Use simple mux for 25/125 Mhz clock switching and
++ // enable GMII_GTXCLK to follow GMII_REFCLK - required for gigabit PHY
++ reg_contents = readl(SYS_CTRL_GMAC_CTRL);
++ reg_contents |= ((1UL << SYS_CTRL_GMAC_SIMPLE_MAX) |
++ (1UL << SYS_CTRL_GMAC_CKEN_GTX));
++ writel(reg_contents, SYS_CTRL_GMAC_CTRL);
++
++ // Remember whether auto-negotiation is allowed
++#ifdef ALLOW_AUTONEG
++ priv->ethtool_cmd.autoneg = 1;
++ priv->ethtool_pauseparam.autoneg = 1;
++#else // ALLOW_AUTONEG
++ priv->ethtool_cmd.autoneg = 0;
++ priv->ethtool_pauseparam.autoneg = 0;
++#endif // ALLOW_AUTONEG
++
++ // Set up PHY mode for when auto-negotiation is not allowed
++ priv->ethtool_cmd.speed = SPEED_1000;
++ priv->ethtool_cmd.duplex = DUPLEX_FULL;
++ priv->ethtool_cmd.port = PORT_MII;
++ priv->ethtool_cmd.transceiver = XCVR_INTERNAL;
++
++#ifndef CONFIG_HIPOX_VERSION_0X800
++ // We can support both reception and generation of pause frames
++ priv->ethtool_pauseparam.rx_pause = 1;
++ priv->ethtool_pauseparam.tx_pause = 1;
++#endif // !CONFIG_HIPOX_VERSION_0X800
++
++ // Initialise the set of features we would like to advertise as being
++ // available for negotiation
++ priv->ethtool_cmd.advertising = (ADVERTISED_10baseT_Half |
++ ADVERTISED_10baseT_Full |
++ ADVERTISED_100baseT_Half |
++ ADVERTISED_100baseT_Full |
++#if !defined(CONFIG_HIPOX_VERSION_0X800) || defined(ALLOW_OX800_1000M)
++ ADVERTISED_1000baseT_Half |
++ ADVERTISED_1000baseT_Full |
++ ADVERTISED_Pause |
++ ADVERTISED_Asym_Pause |
++#endif
++ ADVERTISED_Autoneg |
++ ADVERTISED_MII);
++
++ // Attempt to locate the PHY
++ phy_detect(netdev);
++ priv->ethtool_cmd.phy_address = priv->mii.phy_id;
++
++ // Did we find a PHY?
++ if (priv->phy_type == PHY_TYPE_NONE) {
++ printk(KERN_WARNING "%s: No PHY found\n", netdev->name);
++ err = ENXIO;
++ goto probe_err_out;
++ }
++
++ // Setup the PHY
++ initialise_phy(priv);
++
++ // Find out what modes the PHY supports
++ priv->ethtool_cmd.supported = get_phy_capabilies(priv);
++#if defined(CONFIG_HIPOX_VERSION_0X800) && !defined(ALLOW_OX800_1000M)
++ // OX800 has broken 1000M support in the MAC
++ priv->ethtool_cmd.supported &= ~(SUPPORTED_1000baseT_Full | SUPPORTED_1000baseT_Half);
++#endif
++
++ // Register the device with the network intrastructure
++ err = register_netdev(netdev);
++ if (err) {
++ DBG(1, KERN_ERR "probe() %s: Failed to register device\n", netdev->name);
++ goto probe_err_out;
++ }
++
++ // Record details about the hardware we found
++ printk(KERN_NOTICE "%s: GMAC ver = %u, vendor ver = %u at 0x%lx, IRQ %d\n", netdev->name, synopsis_version, vendor_version, netdev->base_addr, netdev->irq);
++#ifndef ARMULATING
++ printk(KERN_NOTICE "%s: Found PHY at address %u, type 0x%08x -> %s\n", priv->netdev->name, priv->phy_addr, priv->phy_type, (priv->ethtool_cmd.supported & SUPPORTED_1000baseT_Full) ? "10/100/1000" : "10/100");
++#endif // !ARMULATING
++ printk(KERN_NOTICE "%s: Ethernet addr: ", priv->netdev->name);
++ for (i = 0; i < 5; i++) {
++ printk("%02x:", netdev->dev_addr[i]);
++ }
++ printk("%02x\n", netdev->dev_addr[5]);
++
++#ifdef CONFIG_LEON_COPRO
++ // Define sizes of queues for communicating with the CoPro
++ priv->copro_cmd_que_num_entries_ = COPRO_CMD_QUEUE_NUM_ENTRIES;
++ priv->copro_tx_que_num_entries_ = COPRO_TX_QUEUE_NUM_ENTRIES;
++#endif // CONFIG_LEON_COPRO
++
++ // Initialise sysfs for link state reporting
++ err = gmac_link_state_init_sysfs(priv);
++ if (err) {
++ DBG(1, KERN_ERR "probe() %s: Failed to initialise sysfs support\n", netdev->name);
++ goto probe_err_out;
++ }
++
++ // Initialise the work queue entry to be used to issue hotplug events to userspace
++ INIT_WORK(&priv->link_state_change_work, work_handler);
++
++ return 0;
++
++probe_err_out:
++#ifdef CONFIG_LEON_COPRO
++ shutdown_copro();
++
++ if (priv->shared_copro_params_) {
++ // Free the DMA coherent parameter space
++ dma_free_coherent(0, sizeof(copro_params_t), priv->shared_copro_params_, priv->shared_copro_params_pa_);
++ priv->shared_copro_params_ = 0;
++ }
++#endif // CONFIG_LEON_COPRO
++
++ // Disable the clock to the MAC block
++ writel(1UL << SYS_CTRL_CKEN_MAC_BIT, SYS_CTRL_CKEN_CLR_CTRL);
++
++ return err;
++}
++
++static int gmac_found_count = 0;
++static struct net_device* gmac_netdev[MAX_GMAC_UNITS];
++
++/**
++ * External entry point to the driver, called from Space.c to detect a card
++ */
++struct net_device* __init synopsys_gmac_probe(int unit)
++{
++ int err = 0;
++ struct net_device *netdev = alloc_etherdev(sizeof(gmac_priv_t));
++
++ printk(KERN_NOTICE "Probing for Synopsis GMAC, unit %d\n", unit);
++
++ // Will allocate private data later, as may want descriptors etc in special memory
++ if (!netdev) {
++ printk(KERN_WARNING "synopsys_gmac_probe() failed to alloc device\n");
++ err = -ENODEV;
++ } else {
++ if (unit >= 0) {
++ sprintf(netdev->name, "eth%d", unit);
++
++ netdev_boot_setup_check(netdev);
++
++ if (gmac_found_count >= MAX_GMAC_UNITS) {
++ err = -ENODEV;
++ } else {
++ err = probe(netdev, MAC_BASE, MAC_INTERRUPT, SEM_A_INTERRUPT, SEM_B_INTERRUPT);
++ if (err) {
++ printk(KERN_WARNING "synopsys_gmac_probe() Probing failed for %s\n", netdev->name);
++ } else {
++ ++gmac_found_count;
++ }
++ }
++ }
++
++ if (err) {
++ netdev->reg_state = NETREG_UNREGISTERED;
++ free_netdev(netdev);
++ } else {
++ gmac_netdev[unit] = netdev;
++ }
++ }
++
++ return ERR_PTR(err);
++}
++
++static int __init gmac_module_init(void)
++{
++ return (int)synopsys_gmac_probe(0);
++}
++module_init(gmac_module_init);
++
++static void __exit gmac_module_cleanup(void)
++{
++ int i;
++ for (i=0; i < gmac_found_count; i++) {
++ stop(gmac_netdev[i]);
++ gmac_netdev[i]->reg_state = NETREG_UNREGISTERED;
++ free_netdev(gmac_netdev[i]);
++ }
++}
++module_exit(gmac_module_cleanup);
++
+diff -Nurd linux-2.6.24/arch/arm/mach-hipox/gmac.h linux-2.6.24-oxe810/arch/arm/mach-hipox/gmac.h
+--- linux-2.6.24/arch/arm/mach-hipox/gmac.h 1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.24-oxe810/arch/arm/mach-hipox/gmac.h 2008-06-11 17:47:55.000000000 +0200
+@@ -0,0 +1,194 @@
++/*
++ * linux/arch/arm/mach-hipox/gmac.h
++ *
++ * Copyright (C) 2005 Oxford Semiconductor Ltd
++ *
++ * 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
++ */
++#if !defined(__GMAC_H__)
++#define __GMAC_H__
++
++#include <asm/semaphore.h>
++#include <asm/types.h>
++#include <linux/mii.h>
++#include <linux/netdevice.h>
++#include <linux/spinlock.h>
++#include <linux/workqueue.h>
++#include <linux/list.h>
++#include <linux/ethtool.h>
++#include <linux/kobject.h>
++#include <asm/arch/desc_alloc.h>
++#include <asm/arch/dma.h>
++#ifdef CONFIG_LEON_COPRO
++#include <asm/arch/leon.h>
++#include "gmac_offload.h"
++#endif // CONFIG_LEON_COPRO
++
++#ifdef GMAC_DEBUG
++#define DBG(n, args...)\
++ do {\
++ if ((n) <= priv->msg_level)\
++ printk(args);\
++ } while (0)
++#else
++#define DBG(n, args...) do { } while(0)
++#endif
++
++#define MS_TO_JIFFIES(x) (((x)