diff -Nur linux-2.6.30.5.orig/arch/mips/configs/fulong_defconfig linux-2.6.30.5/arch/mips/configs/fulong_defconfig --- linux-2.6.30.5.orig/arch/mips/configs/fulong_defconfig 2009-08-16 23:19:38.000000000 +0200 +++ linux-2.6.30.5/arch/mips/configs/fulong_defconfig 1970-01-01 01:00:00.000000000 +0100 @@ -1,1912 +0,0 @@ -# -# Automatically generated make config: don't edit -# Linux kernel version: 2.6.28-rc6 -# Fri Nov 28 17:53:48 2008 -# -CONFIG_MIPS=y - -# -# Machine selection -# -# CONFIG_MACH_ALCHEMY is not set -# CONFIG_BASLER_EXCITE is not set -# CONFIG_BCM47XX is not set -# CONFIG_MIPS_COBALT is not set -# CONFIG_MACH_DECSTATION is not set -# CONFIG_MACH_JAZZ is not set -# CONFIG_LASAT is not set -CONFIG_LEMOTE_FULONG=y -# CONFIG_MIPS_MALTA is not set -# CONFIG_MIPS_SIM is not set -# CONFIG_MACH_EMMA is not set -# CONFIG_MACH_VR41XX is not set -# CONFIG_NXP_STB220 is not set -# CONFIG_NXP_STB225 is not set -# CONFIG_PNX8550_JBS is not set -# CONFIG_PNX8550_STB810 is not set -# CONFIG_PMC_MSP is not set -# CONFIG_PMC_YOSEMITE is not set -# CONFIG_SGI_IP22 is not set -# CONFIG_SGI_IP27 is not set -# CONFIG_SGI_IP28 is not set -# CONFIG_SGI_IP32 is not set -# CONFIG_SIBYTE_CRHINE is not set -# CONFIG_SIBYTE_CARMEL is not set -# CONFIG_SIBYTE_CRHONE is not set -# CONFIG_SIBYTE_RHONE is not set -# CONFIG_SIBYTE_SWARM is not set -# CONFIG_SIBYTE_LITTLESUR is not set -# CONFIG_SIBYTE_SENTOSA is not set -# CONFIG_SIBYTE_BIGSUR is not set -# CONFIG_SNI_RM is not set -# CONFIG_MACH_TX39XX is not set -# CONFIG_MACH_TX49XX is not set -# CONFIG_MIKROTIK_RB532 is not set -# CONFIG_WR_PPMC is not set -CONFIG_RWSEM_GENERIC_SPINLOCK=y -# CONFIG_ARCH_HAS_ILOG2_U32 is not set -# CONFIG_ARCH_HAS_ILOG2_U64 is not set -CONFIG_ARCH_SUPPORTS_OPROFILE=y -CONFIG_GENERIC_FIND_NEXT_BIT=y -CONFIG_GENERIC_HWEIGHT=y -CONFIG_GENERIC_CALIBRATE_DELAY=y -CONFIG_GENERIC_CLOCKEVENTS=y -CONFIG_GENERIC_TIME=y -CONFIG_GENERIC_CMOS_UPDATE=y -CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER=y -CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y -CONFIG_CEVT_R4K=y -CONFIG_CSRC_R4K=y -CONFIG_DMA_NONCOHERENT=y -CONFIG_DMA_NEED_PCI_MAP_STATE=y -CONFIG_EARLY_PRINTK=y -CONFIG_SYS_HAS_EARLY_PRINTK=y -# CONFIG_HOTPLUG_CPU is not set -CONFIG_I8259=y -# CONFIG_NO_IOPORT is not set -CONFIG_GENERIC_ISA_DMA=y -CONFIG_GENERIC_ISA_DMA_SUPPORT_BROKEN=y -# CONFIG_CPU_BIG_ENDIAN is not set -CONFIG_CPU_LITTLE_ENDIAN=y -CONFIG_SYS_SUPPORTS_LITTLE_ENDIAN=y -CONFIG_IRQ_CPU=y -CONFIG_BOOT_ELF32=y -CONFIG_MIPS_L1_CACHE_SHIFT=5 -CONFIG_HAVE_STD_PC_SERIAL_PORT=y - -# -# CPU selection -# -CONFIG_CPU_LOONGSON2=y -# CONFIG_CPU_MIPS32_R1 is not set -# CONFIG_CPU_MIPS32_R2 is not set -# CONFIG_CPU_MIPS64_R1 is not set -# CONFIG_CPU_MIPS64_R2 is not set -# CONFIG_CPU_R3000 is not set -# CONFIG_CPU_TX39XX is not set -# CONFIG_CPU_VR41XX is not set -# CONFIG_CPU_R4300 is not set -# CONFIG_CPU_R4X00 is not set -# CONFIG_CPU_TX49XX is not set -# CONFIG_CPU_R5000 is not set -# CONFIG_CPU_R5432 is not set -# CONFIG_CPU_R5500 is not set -# CONFIG_CPU_R6000 is not set -# CONFIG_CPU_NEVADA is not set -# CONFIG_CPU_R8000 is not set -# CONFIG_CPU_R10000 is not set -# CONFIG_CPU_RM7000 is not set -# CONFIG_CPU_RM9000 is not set -# CONFIG_CPU_SB1 is not set -CONFIG_SYS_HAS_CPU_LOONGSON2=y -CONFIG_SYS_SUPPORTS_32BIT_KERNEL=y -CONFIG_SYS_SUPPORTS_64BIT_KERNEL=y -CONFIG_CPU_SUPPORTS_32BIT_KERNEL=y -CONFIG_CPU_SUPPORTS_64BIT_KERNEL=y - -# -# Kernel type -# -# CONFIG_32BIT is not set -CONFIG_64BIT=y -# CONFIG_PAGE_SIZE_4KB is not set -# CONFIG_PAGE_SIZE_8KB is not set -CONFIG_PAGE_SIZE_16KB=y -# CONFIG_PAGE_SIZE_64KB is not set -CONFIG_BOARD_SCACHE=y -CONFIG_MIPS_MT_DISABLED=y -# CONFIG_MIPS_MT_SMP is not set -# CONFIG_MIPS_MT_SMTC is not set -CONFIG_CPU_HAS_WB=y -CONFIG_CPU_HAS_SYNC=y -CONFIG_GENERIC_HARDIRQS=y -CONFIG_GENERIC_IRQ_PROBE=y -CONFIG_CPU_SUPPORTS_HIGHMEM=y -CONFIG_SYS_SUPPORTS_HIGHMEM=y -CONFIG_ARCH_FLATMEM_ENABLE=y -CONFIG_ARCH_POPULATES_NODE_MAP=y -CONFIG_ARCH_SPARSEMEM_ENABLE=y -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=y -CONFIG_PAGEFLAGS_EXTENDED=y -CONFIG_SPLIT_PTLOCK_CPUS=4 -CONFIG_RESOURCES_64BIT=y -CONFIG_PHYS_ADDR_T_64BIT=y -CONFIG_ZONE_DMA_FLAG=0 -CONFIG_VIRT_TO_BUS=y -CONFIG_UNEVICTABLE_LRU=y -CONFIG_TICK_ONESHOT=y -CONFIG_NO_HZ=y -CONFIG_HIGH_RES_TIMERS=y -CONFIG_GENERIC_CLOCKEVENTS_BUILD=y -# CONFIG_HZ_48 is not set -# CONFIG_HZ_100 is not set -# CONFIG_HZ_128 is not set -CONFIG_HZ_250=y -# CONFIG_HZ_256 is not set -# CONFIG_HZ_1000 is not set -# CONFIG_HZ_1024 is not set -CONFIG_SYS_SUPPORTS_ARBIT_HZ=y -CONFIG_HZ=250 -# CONFIG_PREEMPT_NONE is not set -CONFIG_PREEMPT_VOLUNTARY=y -# CONFIG_PREEMPT is not set -# CONFIG_KEXEC is not set -CONFIG_SECCOMP=y -CONFIG_LOCKDEP_SUPPORT=y -CONFIG_STACKTRACE_SUPPORT=y -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="lm32" -# CONFIG_LOCALVERSION_AUTO is not set -CONFIG_SWAP=y -CONFIG_SYSVIPC=y -CONFIG_SYSVIPC_SYSCTL=y -CONFIG_POSIX_MQUEUE=y -CONFIG_BSD_PROCESS_ACCT=y -# CONFIG_BSD_PROCESS_ACCT_V3 is not set -# CONFIG_TASKSTATS is not set -# CONFIG_AUDIT is not set -CONFIG_IKCONFIG=y -CONFIG_IKCONFIG_PROC=y -CONFIG_LOG_BUF_SHIFT=14 -# CONFIG_CGROUPS is not set -# CONFIG_GROUP_SCHED is not set -CONFIG_SYSFS_DEPRECATED=y -CONFIG_SYSFS_DEPRECATED_V2=y -# CONFIG_RELAY is not set -CONFIG_NAMESPACES=y -# CONFIG_UTS_NS is not set -# CONFIG_IPC_NS is not set -CONFIG_USER_NS=y -CONFIG_PID_NS=y -# CONFIG_BLK_DEV_INITRD is not set -# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set -CONFIG_SYSCTL=y -CONFIG_EMBEDDED=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_PCSPKR_PLATFORM is not set -# CONFIG_COMPAT_BRK is not set -CONFIG_BASE_FULL=y -CONFIG_FUTEX=y -CONFIG_ANON_INODES=y -CONFIG_EPOLL=y -CONFIG_SIGNALFD=y -CONFIG_TIMERFD=y -CONFIG_EVENTFD=y -CONFIG_SHMEM=y -CONFIG_AIO=y -CONFIG_VM_EVENT_COUNTERS=y -CONFIG_PCI_QUIRKS=y -CONFIG_SLAB=y -# CONFIG_SLUB is not set -# CONFIG_SLOB is not set -CONFIG_PROFILING=y -# CONFIG_MARKERS is not set -CONFIG_OPROFILE=m -CONFIG_HAVE_OPROFILE=y -# CONFIG_HAVE_GENERIC_DMA_COHERENT 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_FORCE_LOAD is not set -CONFIG_MODULE_UNLOAD=y -CONFIG_MODULE_FORCE_UNLOAD=y -# CONFIG_MODVERSIONS is not set -# CONFIG_MODULE_SRCVERSION_ALL is not set -CONFIG_KMOD=y -CONFIG_BLOCK=y -# CONFIG_BLK_DEV_IO_TRACE is not set -CONFIG_BLK_DEV_BSG=y -# CONFIG_BLK_DEV_INTEGRITY is not set -CONFIG_BLOCK_COMPAT=y - -# -# IO Schedulers -# -CONFIG_IOSCHED_NOOP=y -CONFIG_IOSCHED_AS=y -CONFIG_IOSCHED_DEADLINE=y -CONFIG_IOSCHED_CFQ=y -# CONFIG_DEFAULT_AS is not set -# CONFIG_DEFAULT_DEADLINE is not set -CONFIG_DEFAULT_CFQ=y -# CONFIG_DEFAULT_NOOP is not set -CONFIG_DEFAULT_IOSCHED="cfq" -CONFIG_CLASSIC_RCU=y -CONFIG_FREEZER=y - -# -# Bus options (PCI, PCMCIA, EISA, ISA, TC) -# -CONFIG_HW_HAS_PCI=y -CONFIG_PCI=y -CONFIG_PCI_DOMAINS=y -# CONFIG_ARCH_SUPPORTS_MSI is not set -CONFIG_PCI_LEGACY=y -CONFIG_ISA=y -CONFIG_MMU=y -# CONFIG_PCCARD is not set -# CONFIG_HOTPLUG_PCI is not set - -# -# Executable file formats -# -CONFIG_BINFMT_ELF=y -# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set -# CONFIG_HAVE_AOUT is not set -CONFIG_BINFMT_MISC=y -CONFIG_MIPS32_COMPAT=y -CONFIG_COMPAT=y -CONFIG_SYSVIPC_COMPAT=y -CONFIG_MIPS32_O32=y -CONFIG_MIPS32_N32=y -CONFIG_BINFMT_ELF32=y - -# -# Power management options -# -CONFIG_ARCH_SUSPEND_POSSIBLE=y -CONFIG_PM=y -# CONFIG_PM_DEBUG is not set -CONFIG_PM_SLEEP=y -CONFIG_SUSPEND=y -CONFIG_SUSPEND_FREEZER=y -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_XFRM_STATISTICS 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=y -# CONFIG_IP_PNP_DHCP is not set -CONFIG_IP_PNP_BOOTP=y -# CONFIG_IP_PNP_RARP is not set -CONFIG_NET_IPIP=m -CONFIG_NET_IPGRE=m -CONFIG_NET_IPGRE_BROADCAST=y -# 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=m -# CONFIG_INET_XFRM_MODE_TRANSPORT is not set -# CONFIG_INET_XFRM_MODE_TUNNEL is not set -CONFIG_INET_XFRM_MODE_BEET=y -# CONFIG_INET_LRO is not set -# CONFIG_INET_DIAG is not set -# CONFIG_TCP_CONG_ADVANCED is not set -CONFIG_TCP_CONG_CUBIC=y -CONFIG_DEFAULT_TCP_CONG="cubic" -# CONFIG_TCP_MD5SIG is not set -# CONFIG_IPV6 is not set -# CONFIG_NETWORK_SECMARK is not set -CONFIG_NETFILTER=y -# CONFIG_NETFILTER_DEBUG is not set -CONFIG_NETFILTER_ADVANCED=y - -# -# Core Netfilter Configuration -# -CONFIG_NETFILTER_NETLINK=m -CONFIG_NETFILTER_NETLINK_QUEUE=m -CONFIG_NETFILTER_NETLINK_LOG=m -# CONFIG_NF_CONNTRACK is not set -CONFIG_NETFILTER_XTABLES=m -CONFIG_NETFILTER_XT_TARGET_CLASSIFY=m -# CONFIG_NETFILTER_XT_TARGET_DSCP is not set -CONFIG_NETFILTER_XT_TARGET_MARK=m -# CONFIG_NETFILTER_XT_TARGET_NFLOG is not set -CONFIG_NETFILTER_XT_TARGET_NFQUEUE=m -CONFIG_NETFILTER_XT_TARGET_RATEEST=m -CONFIG_NETFILTER_XT_TARGET_TRACE=m -# CONFIG_NETFILTER_XT_TARGET_TCPMSS is not set -CONFIG_NETFILTER_XT_TARGET_TCPOPTSTRIP=m -CONFIG_NETFILTER_XT_MATCH_COMMENT=m -CONFIG_NETFILTER_XT_MATCH_DCCP=m -# CONFIG_NETFILTER_XT_MATCH_DSCP is not set -CONFIG_NETFILTER_XT_MATCH_ESP=m -# CONFIG_NETFILTER_XT_MATCH_HASHLIMIT is not set -CONFIG_NETFILTER_XT_MATCH_IPRANGE=m -CONFIG_NETFILTER_XT_MATCH_LENGTH=m -CONFIG_NETFILTER_XT_MATCH_LIMIT=m -CONFIG_NETFILTER_XT_MATCH_MAC=m -CONFIG_NETFILTER_XT_MATCH_MARK=m -CONFIG_NETFILTER_XT_MATCH_MULTIPORT=m -CONFIG_NETFILTER_XT_MATCH_OWNER=m -# CONFIG_NETFILTER_XT_MATCH_POLICY is not set -CONFIG_NETFILTER_XT_MATCH_PKTTYPE=m -CONFIG_NETFILTER_XT_MATCH_QUOTA=m -CONFIG_NETFILTER_XT_MATCH_RATEEST=m -CONFIG_NETFILTER_XT_MATCH_REALM=m -CONFIG_NETFILTER_XT_MATCH_RECENT=m -# CONFIG_NETFILTER_XT_MATCH_RECENT_PROC_COMPAT is not set -CONFIG_NETFILTER_XT_MATCH_SCTP=m -CONFIG_NETFILTER_XT_MATCH_STATISTIC=m -CONFIG_NETFILTER_XT_MATCH_STRING=m -CONFIG_NETFILTER_XT_MATCH_TCPMSS=m -CONFIG_NETFILTER_XT_MATCH_TIME=m -CONFIG_NETFILTER_XT_MATCH_U32=m -# CONFIG_IP_VS is not set - -# -# IP: Netfilter Configuration -# -# CONFIG_NF_DEFRAG_IPV4 is not set -CONFIG_IP_NF_QUEUE=m -CONFIG_IP_NF_IPTABLES=m -CONFIG_IP_NF_MATCH_ADDRTYPE=m -CONFIG_IP_NF_MATCH_AH=m -CONFIG_IP_NF_MATCH_ECN=m -CONFIG_IP_NF_MATCH_TTL=m -CONFIG_IP_NF_FILTER=m -CONFIG_IP_NF_TARGET_REJECT=m -CONFIG_IP_NF_TARGET_LOG=m -CONFIG_IP_NF_TARGET_ULOG=m -CONFIG_IP_NF_MANGLE=m -CONFIG_IP_NF_TARGET_ECN=m -CONFIG_IP_NF_TARGET_TTL=m -CONFIG_IP_NF_RAW=m -CONFIG_IP_NF_ARPTABLES=m -CONFIG_IP_NF_ARPFILTER=m -CONFIG_IP_NF_ARP_MANGLE=m -# 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_NET_DSA 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 -CONFIG_NET_CLS_ROUTE=y - -# -# Network testing -# -# CONFIG_NET_PKTGEN is not set -# CONFIG_HAMRADIO is not set -# CONFIG_CAN is not set -# CONFIG_IRDA is not set -# CONFIG_BT is not set -# CONFIG_AF_RXRPC is not set -CONFIG_PHONET=m -CONFIG_WIRELESS=y -# CONFIG_CFG80211 is not set -CONFIG_WIRELESS_OLD_REGULATORY=y -CONFIG_WIRELESS_EXT=y -CONFIG_WIRELESS_EXT_SYSFS=y -# CONFIG_MAC80211 is not set -CONFIG_IEEE80211=m -# CONFIG_IEEE80211_DEBUG is not set -CONFIG_IEEE80211_CRYPT_WEP=m -# CONFIG_IEEE80211_CRYPT_CCMP is not set -# CONFIG_IEEE80211_CRYPT_TKIP is not set -# CONFIG_RFKILL is not set -CONFIG_NET_9P=m -# CONFIG_NET_9P_DEBUG 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=m -CONFIG_FIRMWARE_IN_KERNEL=y -CONFIG_EXTRA_FIRMWARE="" -# CONFIG_SYS_HYPERVISOR is not set -# CONFIG_CONNECTOR is not set -CONFIG_MTD=m -# CONFIG_MTD_DEBUG is not set -# CONFIG_MTD_CONCAT is not set -# CONFIG_MTD_PARTITIONS is not set - -# -# User Modules And Translation Layers -# -CONFIG_MTD_CHAR=m -CONFIG_MTD_BLKDEVS=m -CONFIG_MTD_BLOCK=m -# CONFIG_MTD_BLOCK_RO is not set -# CONFIG_FTL is not set -# CONFIG_NFTL is not set -# CONFIG_INFTL is not set -# CONFIG_RFD_FTL is not set -# CONFIG_SSFDC is not set -# CONFIG_MTD_OOPS is not set - -# -# RAM/ROM/Flash chip drivers -# -CONFIG_MTD_CFI=m -CONFIG_MTD_JEDECPROBE=m -CONFIG_MTD_GEN_PROBE=m -CONFIG_MTD_CFI_ADV_OPTIONS=y -CONFIG_MTD_CFI_NOSWAP=y -# CONFIG_MTD_CFI_BE_BYTE_SWAP is not set -# CONFIG_MTD_CFI_LE_BYTE_SWAP is not set -# CONFIG_MTD_CFI_GEOMETRY is not set -CONFIG_MTD_MAP_BANK_WIDTH_1=y -CONFIG_MTD_MAP_BANK_WIDTH_2=y -CONFIG_MTD_MAP_BANK_WIDTH_4=y -# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set -# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set -# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set -CONFIG_MTD_CFI_I1=y -CONFIG_MTD_CFI_I2=y -# CONFIG_MTD_CFI_I4 is not set -# CONFIG_MTD_CFI_I8 is not set -# CONFIG_MTD_OTP is not set -# CONFIG_MTD_CFI_INTELEXT is not set -CONFIG_MTD_CFI_AMDSTD=m -CONFIG_MTD_CFI_STAA=m -CONFIG_MTD_CFI_UTIL=m -# CONFIG_MTD_RAM is not set -# CONFIG_MTD_ROM is not set -# CONFIG_MTD_ABSENT is not set - -# -# Mapping drivers for chip access -# -# CONFIG_MTD_COMPLEX_MAPPINGS is not set -CONFIG_MTD_PHYSMAP=m -CONFIG_MTD_PHYSMAP_START=0x1fc00000 -CONFIG_MTD_PHYSMAP_LEN=0x80000 -CONFIG_MTD_PHYSMAP_BANKWIDTH=1 -# CONFIG_MTD_INTEL_VR_NOR is not set -# CONFIG_MTD_PLATRAM is not set - -# -# Self-contained MTD device drivers -# -# CONFIG_MTD_PMC551 is not set -# CONFIG_MTD_SLRAM is not set -# CONFIG_MTD_PHRAM is not set -# CONFIG_MTD_MTDRAM is not set -# CONFIG_MTD_BLOCK2MTD is not set - -# -# Disk-On-Chip Device Drivers -# -# CONFIG_MTD_DOC2000 is not set -# CONFIG_MTD_DOC2001 is not set -# CONFIG_MTD_DOC2001PLUS is not set -# CONFIG_MTD_NAND is not set -# CONFIG_MTD_ONENAND is not set - -# -# UBI - Unsorted block images -# -# CONFIG_MTD_UBI is not set -# CONFIG_PARPORT is not set -# CONFIG_PNP 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=m -# 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=m -CONFIG_BLK_DEV_RAM_COUNT=16 -CONFIG_BLK_DEV_RAM_SIZE=4096 -# CONFIG_BLK_DEV_XIP is not set -CONFIG_CDROM_PKTCDVD=m -CONFIG_CDROM_PKTCDVD_BUFFERS=8 -# CONFIG_CDROM_PKTCDVD_WCACHE is not set -CONFIG_ATA_OVER_ETH=m -# CONFIG_BLK_DEV_HD is not set -# CONFIG_MISC_DEVICES is not set -CONFIG_HAVE_IDE=y -CONFIG_IDE=y - -# -# Please see Documentation/ide/ide.txt for help/info on IDE drives -# -CONFIG_IDE_TIMINGS=y -CONFIG_IDE_ATAPI=y -# CONFIG_BLK_DEV_IDE_SATA is not set -CONFIG_IDE_GD=y -CONFIG_IDE_GD_ATA=y -# CONFIG_IDE_GD_ATAPI is not set -CONFIG_BLK_DEV_IDECD=y -CONFIG_BLK_DEV_IDECD_VERBOSE_ERRORS=y -# CONFIG_BLK_DEV_IDETAPE is not set -CONFIG_BLK_DEV_IDESCSI=y -CONFIG_IDE_TASK_IOCTL=y -CONFIG_IDE_PROC_FS=y - -# -# IDE chipset support/bugfixes -# -CONFIG_IDE_GENERIC=y -# CONFIG_BLK_DEV_PLATFORM is not set -CONFIG_BLK_DEV_IDEDMA_SFF=y - -# -# PCI IDE chipsets support -# -CONFIG_BLK_DEV_IDEPCI=y -CONFIG_IDEPCI_PCIBUS_ORDER=y -# CONFIG_BLK_DEV_OFFBOARD is not set -CONFIG_BLK_DEV_GENERIC=y -# CONFIG_BLK_DEV_OPTI621 is not set -CONFIG_BLK_DEV_IDEDMA_PCI=y -# CONFIG_BLK_DEV_AEC62XX is not set -# CONFIG_BLK_DEV_ALI15X3 is not set -# CONFIG_BLK_DEV_AMD74XX is not set -# CONFIG_BLK_DEV_CMD64X is not set -# CONFIG_BLK_DEV_TRIFLEX is not set -# CONFIG_BLK_DEV_CS5520 is not set -# CONFIG_BLK_DEV_CS5530 is not set -# CONFIG_BLK_DEV_HPT366 is not set -# CONFIG_BLK_DEV_JMICRON is not set -# CONFIG_BLK_DEV_SC1200 is not set -# CONFIG_BLK_DEV_PIIX is not set -# CONFIG_BLK_DEV_IT8213 is not set -# CONFIG_BLK_DEV_IT821X is not set -# CONFIG_BLK_DEV_NS87415 is not set -# CONFIG_BLK_DEV_PDC202XX_OLD is not set -# CONFIG_BLK_DEV_PDC202XX_NEW is not set -# CONFIG_BLK_DEV_SVWKS is not set -# CONFIG_BLK_DEV_SIIMAGE is not set -# CONFIG_BLK_DEV_SLC90E66 is not set -# CONFIG_BLK_DEV_TRM290 is not set -CONFIG_BLK_DEV_VIA82CXXX=y -# CONFIG_BLK_DEV_TC86C001 is not set - -# -# Other IDE chipsets support -# - -# -# Note: most of these also require special kernel boot parameters -# -# CONFIG_BLK_DEV_4DRIVES is not set -# CONFIG_BLK_DEV_ALI14XX is not set -# CONFIG_BLK_DEV_DTC2278 is not set -# CONFIG_BLK_DEV_HT6560B is not set -# CONFIG_BLK_DEV_QD65XX is not set -# CONFIG_BLK_DEV_UMC8672 is not set -CONFIG_BLK_DEV_IDEDMA=y - -# -# 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=y -CONFIG_BLK_DEV_SR_VENDOR=y -CONFIG_CHR_DEV_SG=y -# CONFIG_CHR_DEV_SCH is not set - -# -# Some SCSI devices (e.g. CD jukebox) support multiple LUNs -# -# CONFIG_SCSI_MULTI_LUN is not set -CONFIG_SCSI_CONSTANTS=y -# 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_ATTRS is not set -# CONFIG_SCSI_SAS_LIBSAS is not set -# CONFIG_SCSI_SRP_ATTRS is not set -# CONFIG_SCSI_LOWLEVEL is not set -# CONFIG_SCSI_DH is not set -# CONFIG_ATA is not set -# CONFIG_MD is not set -# CONFIG_FUSION is not set - -# -# IEEE 1394 (FireWire) support -# - -# -# Enable only one of the two stacks, unless you know what you are doing -# -# CONFIG_FIREWIRE is not set -# CONFIG_IEEE1394 is not set -# CONFIG_I2O is not set -CONFIG_NETDEVICES=y -# CONFIG_DUMMY is not set -# CONFIG_BONDING is not set -CONFIG_MACVLAN=m -# CONFIG_EQUALIZER is not set -# CONFIG_TUN is not set -CONFIG_VETH=m -# CONFIG_ARCNET is not set -CONFIG_PHYLIB=m - -# -# MII PHY device drivers -# -CONFIG_MARVELL_PHY=m -CONFIG_DAVICOM_PHY=m -CONFIG_QSEMI_PHY=m -CONFIG_LXT_PHY=m -CONFIG_CICADA_PHY=m -# CONFIG_VITESSE_PHY is not set -# CONFIG_SMSC_PHY is not set -# CONFIG_BROADCOM_PHY is not set -# CONFIG_ICPLUS_PHY is not set -# CONFIG_REALTEK_PHY is not set -# CONFIG_MDIO_BITBANG is not set -CONFIG_NET_ETHERNET=y -CONFIG_MII=y -# CONFIG_AX88796 is not set -# CONFIG_HAPPYMEAL is not set -# CONFIG_SUNGEM is not set -# CONFIG_CASSINI is not set -# CONFIG_NET_VENDOR_3COM is not set -# CONFIG_NET_VENDOR_SMC is not set -# CONFIG_SMC91X is not set -# CONFIG_DM9000 is not set -# CONFIG_NET_VENDOR_RACAL is not set -# CONFIG_NET_TULIP is not set -# CONFIG_AT1700 is not set -# CONFIG_DEPCA is not set -# CONFIG_HP100 is not set -# CONFIG_NET_ISA is not set -# CONFIG_IBM_NEW_EMAC_ZMII is not set -# CONFIG_IBM_NEW_EMAC_RGMII is not set -# CONFIG_IBM_NEW_EMAC_TAH is not set -# CONFIG_IBM_NEW_EMAC_EMAC4 is not set -# CONFIG_IBM_NEW_EMAC_NO_FLOW_CTRL is not set -# CONFIG_IBM_NEW_EMAC_MAL_CLR_ICINTSTAT is not set -# CONFIG_IBM_NEW_EMAC_MAL_COMMON_ERR is not set -CONFIG_NET_PCI=y -# CONFIG_PCNET32 is not set -# CONFIG_AMD8111_ETH is not set -# CONFIG_ADAPTEC_STARFIRE is not set -# CONFIG_AC3200 is not set -# CONFIG_APRICOT is not set -# CONFIG_B44 is not set -# CONFIG_FORCEDETH is not set -# CONFIG_CS89x0 is not set -# CONFIG_TC35815 is not set -# CONFIG_EEPRO100 is not set -# CONFIG_E100 is not set -# CONFIG_FEALNX is not set -# CONFIG_NATSEMI is not set -# CONFIG_NE2K_PCI is not set -# CONFIG_8139CP is not set -CONFIG_8139TOO=y -# CONFIG_8139TOO_PIO is not set -# CONFIG_8139TOO_TUNE_TWISTER is not set -# CONFIG_8139TOO_8129 is not set -# CONFIG_8139_OLD_RX_RESET is not set -# CONFIG_R6040 is not set -# CONFIG_SIS900 is not set -# CONFIG_EPIC100 is not set -# CONFIG_SUNDANCE is not set -# CONFIG_TLAN is not set -# CONFIG_VIA_RHINE is not set -# CONFIG_SC92031 is not set -# CONFIG_ATL2 is not set -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_IGB 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_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_ATL1E is not set -# CONFIG_JME is not set -CONFIG_NETDEV_10000=y -# CONFIG_CHELSIO_T1 is not set -# CONFIG_CHELSIO_T3 is not set -# CONFIG_ENIC is not set -# CONFIG_IXGBE is not set -# CONFIG_IXGB is not set -# CONFIG_S2IO is not set -# CONFIG_MYRI10GE is not set -# CONFIG_NETXEN_NIC is not set -# CONFIG_NIU is not set -# CONFIG_MLX4_EN is not set -# CONFIG_MLX4_CORE is not set -# CONFIG_TEHUTI is not set -# CONFIG_BNX2X is not set -# CONFIG_QLGE is not set -# CONFIG_SFC is not set -# CONFIG_TR is not set - -# -# Wireless LAN -# -# CONFIG_WLAN_PRE80211 is not set -# CONFIG_WLAN_80211 is not set -# CONFIG_IWLWIFI_LEDS 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=m -CONFIG_PPP_MULTILINK=y -CONFIG_PPP_FILTER=y -CONFIG_PPP_ASYNC=m -CONFIG_PPP_SYNC_TTY=m -CONFIG_PPP_DEFLATE=m -CONFIG_PPP_BSDCOMP=m -CONFIG_PPP_MPPE=m -CONFIG_PPPOE=m -CONFIG_PPPOL2TP=m -CONFIG_SLIP=m -CONFIG_SLIP_COMPRESSED=y -CONFIG_SLHC=m -CONFIG_SLIP_SMART=y -CONFIG_SLIP_MODE_SLIP6=y -CONFIG_NET_FC=y -# CONFIG_NETCONSOLE is not set -# CONFIG_NETPOLL is not set -# CONFIG_NET_POLL_CONTROLLER is not set -# CONFIG_ISDN is not set -# CONFIG_PHONE is not set - -# -# Input device support -# -CONFIG_INPUT=y -CONFIG_INPUT_FF_MEMLESS=y -# CONFIG_INPUT_POLLDEV is not set - -# -# Userland interfaces -# -CONFIG_INPUT_MOUSEDEV=y -CONFIG_INPUT_MOUSEDEV_PSAUX=y -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=y -CONFIG_KEYBOARD_ATKBD=m -# CONFIG_KEYBOARD_SUNKBD is not set -# CONFIG_KEYBOARD_LKKBD is not set -# CONFIG_KEYBOARD_XTKBD is not set -# CONFIG_KEYBOARD_NEWTON is not set -# CONFIG_KEYBOARD_STOWAWAY is not set -CONFIG_INPUT_MOUSE=y -CONFIG_MOUSE_PS2=y -CONFIG_MOUSE_PS2_ALPS=y -CONFIG_MOUSE_PS2_LOGIPS2PP=y -CONFIG_MOUSE_PS2_SYNAPTICS=y -CONFIG_MOUSE_PS2_LIFEBOOK=y -CONFIG_MOUSE_PS2_TRACKPOINT=y -# CONFIG_MOUSE_PS2_ELANTECH is not set -# CONFIG_MOUSE_PS2_TOUCHKIT is not set -CONFIG_MOUSE_SERIAL=y -# CONFIG_MOUSE_APPLETOUCH is not set -# CONFIG_MOUSE_BCM5974 is not set -# CONFIG_MOUSE_INPORT is not set -# CONFIG_MOUSE_LOGIBM is not set -# CONFIG_MOUSE_PC110PAD is not set -# CONFIG_MOUSE_VSXXXAA 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=y -CONFIG_SERIO_I8042=y -CONFIG_SERIO_SERPORT=y -# CONFIG_SERIO_PCIPS2 is not set -CONFIG_SERIO_LIBPS2=y -# CONFIG_SERIO_RAW is not set -# CONFIG_GAMEPORT is not set - -# -# Character devices -# -CONFIG_VT=y -CONFIG_CONSOLE_TRANSLATIONS=y -CONFIG_VT_CONSOLE=y -CONFIG_HW_CONSOLE=y -# CONFIG_VT_HW_CONSOLE_BINDING is not set -CONFIG_DEVKMEM=y -# CONFIG_SERIAL_NONSTANDARD is not set -# CONFIG_NOZOMI is not set - -# -# Serial drivers -# -CONFIG_SERIAL_8250=y -CONFIG_SERIAL_8250_CONSOLE=y -CONFIG_SERIAL_8250_PCI=y -CONFIG_SERIAL_8250_NR_UARTS=2 -CONFIG_SERIAL_8250_RUNTIME_UARTS=2 -# CONFIG_SERIAL_8250_EXTENDED is not set - -# -# Non-8250 serial port support -# -CONFIG_SERIAL_CORE=y -CONFIG_SERIAL_CORE_CONSOLE=y -# CONFIG_SERIAL_JSM is not set -CONFIG_UNIX98_PTYS=y -CONFIG_LEGACY_PTYS=y -CONFIG_LEGACY_PTY_COUNT=256 -# CONFIG_IPMI_HANDLER is not set -CONFIG_HW_RANDOM=y -# CONFIG_DTLK 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=m -CONFIG_I2C_HELPER_AUTO=y - -# -# I2C Hardware Bus support -# - -# -# PC SMBus host controller drivers -# -# 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_ISCH is not set -# CONFIG_I2C_PIIX4 is not set -# CONFIG_I2C_NFORCE2 is not set -# CONFIG_I2C_SIS5595 is not set -# CONFIG_I2C_SIS630 is not set -# CONFIG_I2C_SIS96X is not set -# CONFIG_I2C_VIA is not set -CONFIG_I2C_VIAPRO=m - -# -# I2C system bus drivers (mostly embedded / system-on-chip) -# -# CONFIG_I2C_OCORES is not set -# CONFIG_I2C_SIMTEC is not set - -# -# External I2C/SMBus adapter drivers -# -# CONFIG_I2C_PARPORT_LIGHT is not set -# CONFIG_I2C_TAOS_EVM is not set -# CONFIG_I2C_TINY_USB is not set - -# -# Graphics adapter I2C/DDC channel drivers -# -# CONFIG_I2C_VOODOO3 is not set - -# -# Other I2C/SMBus bus drivers -# -# CONFIG_I2C_ELEKTOR is not set -# CONFIG_I2C_PCA_ISA is not set -# CONFIG_I2C_PCA_PLATFORM is not set -# CONFIG_I2C_STUB is not set - -# -# Miscellaneous I2C Chip support -# -# CONFIG_DS1682 is not set -# CONFIG_EEPROM_AT24 is not set -# CONFIG_EEPROM_LEGACY is not set -# CONFIG_SENSORS_PCF8574 is not set -# CONFIG_PCF8575 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 -# CONFIG_SPI is not set -# CONFIG_W1 is not set -# CONFIG_POWER_SUPPLY is not set -# CONFIG_HWMON is not set -# CONFIG_THERMAL is not set -# CONFIG_THERMAL_HWMON is not set -# CONFIG_WATCHDOG is not set -CONFIG_SSB_POSSIBLE=y - -# -# Sonics Silicon Backplane -# -# CONFIG_SSB is not set - -# -# Multifunction device drivers -# -# CONFIG_MFD_CORE is not set -# CONFIG_MFD_SM501 is not set -# CONFIG_HTC_PASIC3 is not set -# CONFIG_MFD_TMIO is not set -# CONFIG_MFD_WM8400 is not set -# CONFIG_MFD_WM8350_I2C is not set -# CONFIG_REGULATOR is not set - -# -# Multimedia devices -# - -# -# Multimedia core support -# -CONFIG_VIDEO_DEV=m -CONFIG_VIDEO_V4L2_COMMON=m -CONFIG_VIDEO_ALLOW_V4L1=y -CONFIG_VIDEO_V4L1_COMPAT=y -# CONFIG_DVB_CORE is not set -CONFIG_VIDEO_MEDIA=m - -# -# Multimedia drivers -# -CONFIG_MEDIA_ATTACH=y -CONFIG_MEDIA_TUNER=m -CONFIG_MEDIA_TUNER_CUSTOMIZE=y -CONFIG_MEDIA_TUNER_SIMPLE=m -CONFIG_MEDIA_TUNER_TDA8290=m -CONFIG_MEDIA_TUNER_TDA827X=m -CONFIG_MEDIA_TUNER_TDA18271=m -CONFIG_MEDIA_TUNER_TDA9887=m -CONFIG_MEDIA_TUNER_TEA5761=m -CONFIG_MEDIA_TUNER_TEA5767=m -CONFIG_MEDIA_TUNER_MT20XX=m -CONFIG_MEDIA_TUNER_MT2060=m -CONFIG_MEDIA_TUNER_MT2266=m -CONFIG_MEDIA_TUNER_MT2131=m -CONFIG_MEDIA_TUNER_QT1010=m -CONFIG_MEDIA_TUNER_XC2028=m -CONFIG_MEDIA_TUNER_XC5000=m -CONFIG_MEDIA_TUNER_MXL5005S=m -CONFIG_MEDIA_TUNER_MXL5007T=m -CONFIG_VIDEO_V4L2=m -CONFIG_VIDEO_V4L1=m -CONFIG_VIDEOBUF_GEN=m -CONFIG_VIDEOBUF_VMALLOC=m -CONFIG_VIDEOBUF_DMA_CONTIG=m -CONFIG_VIDEO_CAPTURE_DRIVERS=y -# CONFIG_VIDEO_ADV_DEBUG is not set -# CONFIG_VIDEO_FIXED_MINOR_RANGES is not set -CONFIG_VIDEO_HELPER_CHIPS_AUTO=y -# CONFIG_VIDEO_VIVI is not set -# CONFIG_VIDEO_BT848 is not set -# CONFIG_VIDEO_PMS is not set -# CONFIG_VIDEO_CPIA is not set -# CONFIG_VIDEO_CPIA2 is not set -# CONFIG_VIDEO_SAA5246A is not set -# CONFIG_VIDEO_SAA5249 is not set -# CONFIG_VIDEO_STRADIS is not set -# CONFIG_VIDEO_SAA7134 is not set -# CONFIG_VIDEO_MXB is not set -# CONFIG_VIDEO_HEXIUM_ORION is not set -# CONFIG_VIDEO_HEXIUM_GEMINI is not set -# CONFIG_VIDEO_CX88 is not set -# CONFIG_VIDEO_IVTV is not set -# CONFIG_VIDEO_CAFE_CCIC is not set -CONFIG_SOC_CAMERA=m -CONFIG_SOC_CAMERA_MT9M001=m -CONFIG_SOC_CAMERA_MT9M111=m -CONFIG_SOC_CAMERA_MT9V022=m -CONFIG_SOC_CAMERA_PLATFORM=m -CONFIG_VIDEO_SH_MOBILE_CEU=m -CONFIG_V4L_USB_DRIVERS=y -CONFIG_USB_VIDEO_CLASS=m -CONFIG_USB_VIDEO_CLASS_INPUT_EVDEV=y -CONFIG_USB_GSPCA=m -CONFIG_USB_M5602=m -CONFIG_USB_GSPCA_CONEX=m -CONFIG_USB_GSPCA_ETOMS=m -CONFIG_USB_GSPCA_FINEPIX=m -CONFIG_USB_GSPCA_MARS=m -CONFIG_USB_GSPCA_OV519=m -CONFIG_USB_GSPCA_PAC207=m -CONFIG_USB_GSPCA_PAC7311=m -CONFIG_USB_GSPCA_SONIXB=m -CONFIG_USB_GSPCA_SONIXJ=m -CONFIG_USB_GSPCA_SPCA500=m -CONFIG_USB_GSPCA_SPCA501=m -CONFIG_USB_GSPCA_SPCA505=m -CONFIG_USB_GSPCA_SPCA506=m -CONFIG_USB_GSPCA_SPCA508=m -CONFIG_USB_GSPCA_SPCA561=m -CONFIG_USB_GSPCA_STK014=m -CONFIG_USB_GSPCA_SUNPLUS=m -CONFIG_USB_GSPCA_T613=m -CONFIG_USB_GSPCA_TV8532=m -CONFIG_USB_GSPCA_VC032X=m -CONFIG_USB_GSPCA_ZC3XX=m -# CONFIG_VIDEO_PVRUSB2 is not set -# CONFIG_VIDEO_EM28XX is not set -# CONFIG_VIDEO_USBVISION is not set -CONFIG_VIDEO_USBVIDEO=m -CONFIG_USB_VICAM=m -CONFIG_USB_IBMCAM=m -CONFIG_USB_KONICAWC=m -CONFIG_USB_QUICKCAM_MESSENGER=m -CONFIG_USB_ET61X251=m -# CONFIG_VIDEO_OVCAMCHIP is not set -CONFIG_USB_OV511=m -CONFIG_USB_SE401=m -CONFIG_USB_SN9C102=m -CONFIG_USB_STV680=m -CONFIG_USB_ZC0301=m -CONFIG_USB_PWC=m -# CONFIG_USB_PWC_DEBUG is not set -# CONFIG_USB_ZR364XX is not set -CONFIG_USB_STKWEBCAM=m -CONFIG_USB_S2255=m -CONFIG_RADIO_ADAPTERS=y -# CONFIG_RADIO_CADET is not set -# CONFIG_RADIO_RTRACK is not set -# CONFIG_RADIO_RTRACK2 is not set -# CONFIG_RADIO_AZTECH is not set -# CONFIG_RADIO_GEMTEK is not set -# CONFIG_RADIO_GEMTEK_PCI is not set -# CONFIG_RADIO_MAXIRADIO is not set -# CONFIG_RADIO_MAESTRO is not set -# CONFIG_RADIO_SF16FMI is not set -# CONFIG_RADIO_SF16FMR2 is not set -# CONFIG_RADIO_TERRATEC is not set -# CONFIG_RADIO_TRUST is not set -# CONFIG_RADIO_TYPHOON is not set -# CONFIG_RADIO_ZOLTRIX is not set -# CONFIG_USB_DSBR is not set -CONFIG_USB_SI470X=m -CONFIG_USB_MR800=m -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=y -# CONFIG_FIRMWARE_EDID is not set -# CONFIG_FB_DDC is not set -# CONFIG_FB_BOOT_VESA_SUPPORT is not set -CONFIG_FB_CFB_FILLRECT=y -CONFIG_FB_CFB_COPYAREA=y -CONFIG_FB_CFB_IMAGEBLIT=y -# CONFIG_FB_CFB_REV_PIXELS_IN_BYTE is not set -# CONFIG_FB_SYS_FILLRECT is not set -# CONFIG_FB_SYS_COPYAREA is not set -# CONFIG_FB_SYS_IMAGEBLIT is not set -# CONFIG_FB_FOREIGN_ENDIAN is not set -# CONFIG_FB_SYS_FOPS is not set -# CONFIG_FB_SVGALIB is not set -# CONFIG_FB_MACMODES is not set -CONFIG_FB_BACKLIGHT=y -CONFIG_FB_MODE_HELPERS=y -# CONFIG_FB_TILEBLITTING is not set - -# -# Frame buffer hardware drivers -# -# CONFIG_FB_CIRRUS is not set -# CONFIG_FB_PM2 is not set -# CONFIG_FB_CYBER2000 is not set -# CONFIG_FB_ASILIANT is not set -# CONFIG_FB_IMSTT is not set -# CONFIG_FB_S1D13XXX is not set -# CONFIG_FB_NVIDIA is not set -# CONFIG_FB_RIVA is not set -# CONFIG_FB_MATROX is not set -CONFIG_FB_RADEON=y -# CONFIG_FB_RADEON_I2C is not set -CONFIG_FB_RADEON_BACKLIGHT=y -# CONFIG_FB_RADEON_DEBUG is not set -# CONFIG_FB_ATY128 is not set -# CONFIG_FB_ATY is not set -# CONFIG_FB_S3 is not set -# CONFIG_FB_SAVAGE is not set -# CONFIG_FB_SIS is not set -# CONFIG_FB_VIA is not set -# CONFIG_FB_NEOMAGIC is not set -# CONFIG_FB_KYRO is not set -# CONFIG_FB_3DFX is not set -# CONFIG_FB_VOODOO1 is not set -# CONFIG_FB_VT8623 is not set -# CONFIG_FB_TRIDENT is not set -# CONFIG_FB_ARK is not set -# CONFIG_FB_PM3 is not set -# CONFIG_FB_CARMINE is not set -# CONFIG_FB_VIRTUAL is not set -# CONFIG_FB_METRONOME is not set -# CONFIG_FB_MB862XX is not set -CONFIG_BACKLIGHT_LCD_SUPPORT=y -CONFIG_LCD_CLASS_DEVICE=m -# CONFIG_LCD_ILI9320 is not set -# CONFIG_LCD_PLATFORM is not set -CONFIG_BACKLIGHT_CLASS_DEVICE=y -# CONFIG_BACKLIGHT_CORGI is not set - -# -# Display device support -# -# CONFIG_DISPLAY_SUPPORT is not set - -# -# Console display driver support -# -# CONFIG_VGA_CONSOLE is not set -# CONFIG_MDA_CONSOLE is not set -CONFIG_DUMMY_CONSOLE=y -CONFIG_FRAMEBUFFER_CONSOLE=y -# CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY is not set -# CONFIG_FRAMEBUFFER_CONSOLE_ROTATION is not set -# CONFIG_FONTS is not set -CONFIG_FONT_8x8=y -CONFIG_FONT_8x16=y -# CONFIG_LOGO is not set -CONFIG_SOUND=y -CONFIG_SOUND_OSS_CORE=y -CONFIG_SND=m -CONFIG_SND_TIMER=m -CONFIG_SND_PCM=m -CONFIG_SND_RAWMIDI=m -CONFIG_SND_SEQUENCER=m -CONFIG_SND_SEQ_DUMMY=m -CONFIG_SND_OSSEMUL=y -CONFIG_SND_MIXER_OSS=m -CONFIG_SND_PCM_OSS=m -CONFIG_SND_PCM_OSS_PLUGINS=y -CONFIG_SND_SEQUENCER_OSS=y -# CONFIG_SND_DYNAMIC_MINORS is not set -CONFIG_SND_SUPPORT_OLD_API=y -CONFIG_SND_VERBOSE_PROCFS=y -# CONFIG_SND_VERBOSE_PRINTK is not set -# CONFIG_SND_DEBUG is not set -CONFIG_SND_VMASTER=y -CONFIG_SND_MPU401_UART=m -CONFIG_SND_AC97_CODEC=m -CONFIG_SND_DRIVERS=y -# CONFIG_SND_DUMMY is not set -# CONFIG_SND_VIRMIDI is not set -# CONFIG_SND_MTPAV is not set -# CONFIG_SND_SERIAL_U16550 is not set -# CONFIG_SND_MPU401 is not set -# CONFIG_SND_AC97_POWER_SAVE is not set -CONFIG_SND_PCI=y -# CONFIG_SND_AD1889 is not set -# CONFIG_SND_ALS300 is not set -# CONFIG_SND_ALI5451 is not set -# CONFIG_SND_ATIIXP is not set -# CONFIG_SND_ATIIXP_MODEM is not set -# CONFIG_SND_AU8810 is not set -# CONFIG_SND_AU8820 is not set -# CONFIG_SND_AU8830 is not set -# CONFIG_SND_AW2 is not set -# CONFIG_SND_AZT3328 is not set -# CONFIG_SND_BT87X is not set -# CONFIG_SND_CA0106 is not set -# CONFIG_SND_CMIPCI is not set -# CONFIG_SND_OXYGEN is not set -# CONFIG_SND_CS4281 is not set -# CONFIG_SND_CS46XX is not set -# CONFIG_SND_DARLA20 is not set -# CONFIG_SND_GINA20 is not set -# CONFIG_SND_LAYLA20 is not set -# CONFIG_SND_DARLA24 is not set -# CONFIG_SND_GINA24 is not set -# CONFIG_SND_LAYLA24 is not set -# CONFIG_SND_MONA is not set -# CONFIG_SND_MIA is not set -# CONFIG_SND_ECHO3G is not set -# CONFIG_SND_INDIGO is not set -# CONFIG_SND_INDIGOIO is not set -# CONFIG_SND_INDIGODJ is not set -# CONFIG_SND_EMU10K1 is not set -# CONFIG_SND_EMU10K1X is not set -# CONFIG_SND_ENS1370 is not set -# CONFIG_SND_ENS1371 is not set -# CONFIG_SND_ES1938 is not set -# CONFIG_SND_ES1968 is not set -# CONFIG_SND_FM801 is not set -# CONFIG_SND_HDA_INTEL is not set -# CONFIG_SND_HDSP is not set -# CONFIG_SND_HDSPM is not set -# CONFIG_SND_HIFIER is not set -# CONFIG_SND_ICE1712 is not set -# CONFIG_SND_ICE1724 is not set -# CONFIG_SND_INTEL8X0 is not set -# CONFIG_SND_INTEL8X0M is not set -# CONFIG_SND_KORG1212 is not set -# CONFIG_SND_MAESTRO3 is not set -# CONFIG_SND_MIXART is not set -# CONFIG_SND_NM256 is not set -# CONFIG_SND_PCXHR is not set -# CONFIG_SND_RIPTIDE is not set -# CONFIG_SND_RME32 is not set -# CONFIG_SND_RME96 is not set -# CONFIG_SND_RME9652 is not set -# CONFIG_SND_SONICVIBES is not set -# CONFIG_SND_TRIDENT is not set -CONFIG_SND_VIA82XX=m -# CONFIG_SND_VIA82XX_MODEM is not set -# CONFIG_SND_VIRTUOSO is not set -# CONFIG_SND_VX222 is not set -# CONFIG_SND_YMFPCI is not set -CONFIG_SND_MIPS=y -CONFIG_SND_USB=y -# CONFIG_SND_USB_AUDIO is not set -# CONFIG_SND_USB_CAIAQ is not set -# CONFIG_SND_SOC is not set -# CONFIG_SOUND_PRIME is not set -CONFIG_AC97_BUS=m -CONFIG_HID_SUPPORT=y -CONFIG_HID=y -# CONFIG_HID_DEBUG is not set -CONFIG_HIDRAW=y - -# -# USB Input Devices -# -CONFIG_USB_HID=m -CONFIG_HID_PID=y -CONFIG_USB_HIDDEV=y - -# -# USB HID Boot Protocol drivers -# -# CONFIG_USB_KBD is not set -# CONFIG_USB_MOUSE is not set - -# -# Special HID drivers -# -CONFIG_HID_COMPAT=y -CONFIG_HID_A4TECH=m -CONFIG_HID_APPLE=m -CONFIG_HID_BELKIN=m -CONFIG_HID_BRIGHT=m -CONFIG_HID_CHERRY=m -CONFIG_HID_CHICONY=m -CONFIG_HID_CYPRESS=m -CONFIG_HID_DELL=m -CONFIG_HID_EZKEY=m -CONFIG_HID_GYRATION=m -CONFIG_HID_LOGITECH=m -CONFIG_LOGITECH_FF=y -CONFIG_LOGIRUMBLEPAD2_FF=y -CONFIG_HID_MICROSOFT=m -CONFIG_HID_MONTEREY=m -CONFIG_HID_PANTHERLORD=m -# CONFIG_PANTHERLORD_FF is not set -CONFIG_HID_PETALYNX=m -CONFIG_HID_SAMSUNG=m -CONFIG_HID_SONY=m -CONFIG_HID_SUNPLUS=m -# CONFIG_THRUSTMASTER_FF is not set -CONFIG_ZEROPLUS_FF=m -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 -CONFIG_USB_ANNOUNCE_NEW_DEVICES=y - -# -# Miscellaneous USB options -# -CONFIG_USB_DEVICEFS=y -# CONFIG_USB_DEVICE_CLASS is not set -# CONFIG_USB_DYNAMIC_MINORS is not set -# CONFIG_USB_SUSPEND is not set -# CONFIG_USB_OTG is not set -CONFIG_USB_OTG_WHITELIST=y -# CONFIG_USB_OTG_BLACKLIST_HUB is not set -# CONFIG_USB_MON is not set -# CONFIG_USB_WUSB is not set -CONFIG_USB_WUSB_CBAF=m -# CONFIG_USB_WUSB_CBAF_DEBUG is not set - -# -# USB Host Controller Drivers -# -CONFIG_USB_C67X00_HCD=m -CONFIG_USB_EHCI_HCD=y -CONFIG_USB_EHCI_ROOT_HUB_TT=y -CONFIG_USB_EHCI_TT_NEWSCHED=y -# CONFIG_USB_ISP116X_HCD is not set -CONFIG_USB_ISP1760_HCD=m -CONFIG_USB_OHCI_HCD=y -# CONFIG_USB_OHCI_BIG_ENDIAN_DESC is not set -# CONFIG_USB_OHCI_BIG_ENDIAN_MMIO is not set -CONFIG_USB_OHCI_LITTLE_ENDIAN=y -CONFIG_USB_UHCI_HCD=m -# CONFIG_USB_SL811_HCD is not set -CONFIG_USB_R8A66597_HCD=m -# CONFIG_USB_WHCI_HCD is not set -# CONFIG_USB_HWA_HCD is not set - -# -# USB Device Class drivers -# -CONFIG_USB_ACM=y -CONFIG_USB_PRINTER=y -CONFIG_USB_WDM=m -CONFIG_USB_TMC=m - -# -# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may also be needed; -# - -# -# see USB_STORAGE Help for more information -# -CONFIG_USB_STORAGE=y -# 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_ONETOUCH=y -# CONFIG_USB_STORAGE_KARMA is not set -CONFIG_USB_STORAGE_CYPRESS_ATACB=y -CONFIG_USB_LIBUSUAL=y - -# -# USB Imaging devices -# -# CONFIG_USB_MDC800 is not set -# CONFIG_USB_MICROTEK is not set - -# -# USB port drivers -# -# 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_SEVSEG=m -# 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 is not set -CONFIG_USB_ISIGHTFW=m -CONFIG_USB_VST=m -# CONFIG_USB_GADGET is not set -# CONFIG_UWB is not set -# CONFIG_MMC is not set -# CONFIG_MEMSTICK is not set -# CONFIG_NEW_LEDS is not set -# CONFIG_ACCESSIBILITY is not set -# CONFIG_INFINIBAND 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=y -# CONFIG_RTC_DRV_TEST is not set - -# -# I2C RTC drivers -# -# CONFIG_RTC_DRV_DS1307 is not set -# 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 -# CONFIG_RTC_DRV_S35390A is not set -# CONFIG_RTC_DRV_FM3130 is not set -# CONFIG_RTC_DRV_RX8581 is not set - -# -# SPI RTC drivers -# - -# -# Platform RTC drivers -# -CONFIG_RTC_DRV_CMOS=m -# CONFIG_RTC_DRV_DS1286 is not set -# CONFIG_RTC_DRV_DS1511 is not set -# CONFIG_RTC_DRV_DS1553 is not set -# CONFIG_RTC_DRV_DS1742 is not set -# CONFIG_RTC_DRV_STK17TA8 is not set -# CONFIG_RTC_DRV_M48T86 is not set -# CONFIG_RTC_DRV_M48T35 is not set -# CONFIG_RTC_DRV_M48T59 is not set -# CONFIG_RTC_DRV_BQ4802 is not set -# CONFIG_RTC_DRV_V3020 is not set - -# -# on-CPU RTC drivers -# -# CONFIG_DMADEVICES is not set -CONFIG_UIO=m -CONFIG_UIO_CIF=m -# CONFIG_UIO_PDRV is not set -# CONFIG_UIO_PDRV_GENIRQ is not set -# CONFIG_UIO_SMX is not set -# CONFIG_UIO_SERCOS3 is not set -# CONFIG_STAGING is not set -CONFIG_STAGING_EXCLUDE_BUILD=y - -# -# File systems -# -CONFIG_EXT2_FS=y -# CONFIG_EXT2_FS_XATTR is not set -CONFIG_EXT2_FS_XIP=y -CONFIG_EXT3_FS=y -# CONFIG_EXT3_FS_XATTR is not set -CONFIG_EXT4_FS=m -CONFIG_EXT4DEV_COMPAT=y -CONFIG_EXT4_FS_XATTR=y -CONFIG_EXT4_FS_POSIX_ACL=y -CONFIG_EXT4_FS_SECURITY=y -CONFIG_FS_XIP=y -CONFIG_JBD=y -CONFIG_JBD2=m -CONFIG_FS_MBCACHE=m -CONFIG_REISERFS_FS=m -# CONFIG_REISERFS_CHECK is not set -# CONFIG_REISERFS_PROC_INFO is not set -# CONFIG_REISERFS_FS_XATTR is not set -# CONFIG_JFS_FS is not set -CONFIG_FS_POSIX_ACL=y -CONFIG_FILE_LOCKING=y -# CONFIG_XFS_FS is not set -# CONFIG_GFS2_FS is not set -# CONFIG_OCFS2_FS is not set -CONFIG_DNOTIFY=y -CONFIG_INOTIFY=y -CONFIG_INOTIFY_USER=y -# CONFIG_QUOTA is not set -CONFIG_AUTOFS_FS=y -CONFIG_AUTOFS4_FS=y -CONFIG_FUSE_FS=y - -# -# CD-ROM/DVD Filesystems -# -CONFIG_ISO9660_FS=m -CONFIG_JOLIET=y -CONFIG_ZISOFS=y -CONFIG_UDF_FS=m -CONFIG_UDF_NLS=y - -# -# DOS/FAT/NT Filesystems -# -CONFIG_FAT_FS=m -CONFIG_MSDOS_FS=m -CONFIG_VFAT_FS=m -CONFIG_FAT_DEFAULT_CODEPAGE=936 -CONFIG_FAT_DEFAULT_IOCHARSET="utf8" -CONFIG_NTFS_FS=m -# CONFIG_NTFS_DEBUG is not set -CONFIG_NTFS_RW=y - -# -# Pseudo filesystems -# -CONFIG_PROC_FS=y -CONFIG_PROC_KCORE=y -CONFIG_PROC_SYSCTL=y -CONFIG_PROC_PAGE_MONITOR=y -CONFIG_SYSFS=y -CONFIG_TMPFS=y -# CONFIG_TMPFS_POSIX_ACL 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_JFFS2_FS is not set -# CONFIG_CRAMFS is not set -# CONFIG_VXFS_FS is not set -# CONFIG_MINIX_FS is not set -CONFIG_OMFS_FS=m -# CONFIG_HPFS_FS is not set -# CONFIG_QNX4FS_FS is not set -# CONFIG_ROMFS_FS is not set -# CONFIG_SYSV_FS is not set -# CONFIG_UFS_FS is not set -CONFIG_NETWORK_FILESYSTEMS=y -CONFIG_NFS_FS=m -CONFIG_NFS_V3=y -CONFIG_NFS_V3_ACL=y -CONFIG_NFS_V4=y -CONFIG_NFSD=m -CONFIG_NFSD_V2_ACL=y -CONFIG_NFSD_V3=y -CONFIG_NFSD_V3_ACL=y -CONFIG_NFSD_V4=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_GSS=m -# CONFIG_SUNRPC_REGISTER_V4 is not set -CONFIG_RPCSEC_GSS_KRB5=m -# CONFIG_RPCSEC_GSS_SPKM3 is not set -CONFIG_SMB_FS=m -CONFIG_SMB_NLS_DEFAULT=y -CONFIG_SMB_NLS_REMOTE="cp936" -CONFIG_CIFS=m -CONFIG_CIFS_STATS=y -CONFIG_CIFS_STATS2=y -CONFIG_CIFS_WEAK_PW_HASH=y -CONFIG_CIFS_XATTR=y -CONFIG_CIFS_POSIX=y -CONFIG_CIFS_DEBUG2=y -CONFIG_CIFS_EXPERIMENTAL=y -# CONFIG_NCP_FS is not set -# CONFIG_CODA_FS is not set -# CONFIG_AFS_FS is not set -# CONFIG_9P_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 is not set -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 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 is not set -# CONFIG_SYSV68_PARTITION is not set -CONFIG_NLS=y -CONFIG_NLS_DEFAULT="utf8" -# CONFIG_NLS_CODEPAGE_437 is not set -# 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=y -# 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_DLM is not set - -# -# Kernel hacking -# -CONFIG_TRACE_IRQFLAGS_SUPPORT=y -# CONFIG_PRINTK_TIME is not set -CONFIG_ENABLE_WARN_DEPRECATED=y -# CONFIG_ENABLE_MUST_CHECK is not set -CONFIG_FRAME_WARN=2048 -# 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_MEMORY_INIT is not set -# CONFIG_RCU_CPU_STALL_DETECTOR is not set -CONFIG_SYSCTL_SYSCALL_CHECK=y - -# -# Tracers -# -CONFIG_DYNAMIC_PRINTK_DEBUG=y -# CONFIG_SAMPLES is not set -CONFIG_HAVE_ARCH_KGDB=y -CONFIG_CMDLINE="" - -# -# Security options -# -# CONFIG_KEYS is not set -# CONFIG_SECURITY is not set -# CONFIG_SECURITYFS is not set -CONFIG_SECURITY_FILE_CAPABILITIES=y -CONFIG_CRYPTO=y - -# -# Crypto core or helper -# -CONFIG_CRYPTO_FIPS=y -CONFIG_CRYPTO_ALGAPI=y -CONFIG_CRYPTO_AEAD=y -CONFIG_CRYPTO_BLKCIPHER=y -CONFIG_CRYPTO_HASH=y -CONFIG_CRYPTO_RNG=y -CONFIG_CRYPTO_MANAGER=y -CONFIG_CRYPTO_GF128MUL=m -# CONFIG_CRYPTO_NULL is not set -# CONFIG_CRYPTO_CRYPTD is not set -CONFIG_CRYPTO_AUTHENC=m -# CONFIG_CRYPTO_TEST is not set - -# -# Authenticated Encryption with Associated Data -# -CONFIG_CRYPTO_CCM=m -CONFIG_CRYPTO_GCM=m -CONFIG_CRYPTO_SEQIV=m - -# -# Block modes -# -CONFIG_CRYPTO_CBC=m -CONFIG_CRYPTO_CTR=m -CONFIG_CRYPTO_CTS=m -CONFIG_CRYPTO_ECB=m -# CONFIG_CRYPTO_LRW is not set -CONFIG_CRYPTO_PCBC=m -CONFIG_CRYPTO_XTS=m - -# -# Hash modes -# -CONFIG_CRYPTO_HMAC=y -# CONFIG_CRYPTO_XCBC is not set - -# -# Digest -# -# CONFIG_CRYPTO_CRC32C is not set -# CONFIG_CRYPTO_MD4 is not set -CONFIG_CRYPTO_MD5=m -# CONFIG_CRYPTO_MICHAEL_MIC is not set -CONFIG_CRYPTO_RMD128=m -CONFIG_CRYPTO_RMD160=m -CONFIG_CRYPTO_RMD256=m -CONFIG_CRYPTO_RMD320=m -CONFIG_CRYPTO_SHA1=m -# CONFIG_CRYPTO_SHA256 is not set -# CONFIG_CRYPTO_SHA512 is not set -# CONFIG_CRYPTO_TGR192 is not set -# CONFIG_CRYPTO_WP512 is not set - -# -# Ciphers -# -CONFIG_CRYPTO_AES=m -# CONFIG_CRYPTO_ANUBIS is not set -CONFIG_CRYPTO_ARC4=m -# CONFIG_CRYPTO_BLOWFISH is not set -# CONFIG_CRYPTO_CAMELLIA is not set -# CONFIG_CRYPTO_CAST5 is not set -# CONFIG_CRYPTO_CAST6 is not set -CONFIG_CRYPTO_DES=m -# CONFIG_CRYPTO_FCRYPT is not set -# CONFIG_CRYPTO_KHAZAD is not set -CONFIG_CRYPTO_SALSA20=m -CONFIG_CRYPTO_SEED=m -# CONFIG_CRYPTO_SERPENT is not set -# CONFIG_CRYPTO_TEA is not set -# CONFIG_CRYPTO_TWOFISH is not set - -# -# Compression -# -CONFIG_CRYPTO_DEFLATE=m -CONFIG_CRYPTO_LZO=m - -# -# Random Number Generation -# -CONFIG_CRYPTO_ANSI_CPRNG=m -# CONFIG_CRYPTO_HW is not set - -# -# Library routines -# -CONFIG_BITREVERSE=y -CONFIG_CRC_CCITT=y -CONFIG_CRC16=m -# CONFIG_CRC_T10DIF is not set -CONFIG_CRC_ITU_T=m -CONFIG_CRC32=y -CONFIG_CRC7=m -# CONFIG_LIBCRC32C is not set -CONFIG_ZLIB_INFLATE=m -CONFIG_ZLIB_DEFLATE=m -CONFIG_LZO_COMPRESS=m -CONFIG_LZO_DECOMPRESS=m -CONFIG_TEXTSEARCH=y -CONFIG_TEXTSEARCH_KMP=m -CONFIG_TEXTSEARCH_BM=m -CONFIG_TEXTSEARCH_FSM=m -CONFIG_PLIST=y -CONFIG_HAS_IOMEM=y -CONFIG_HAS_IOPORT=y -CONFIG_HAS_DMA=y diff -Nur linux-2.6.30.5.orig/arch/mips/configs/fuloong2e_defconfig linux-2.6.30.5/arch/mips/configs/fuloong2e_defconfig --- linux-2.6.30.5.orig/arch/mips/configs/fuloong2e_defconfig 1970-01-01 01:00:00.000000000 +0100 +++ linux-2.6.30.5/arch/mips/configs/fuloong2e_defconfig 2009-08-23 19:01:04.000000000 +0200 @@ -0,0 +1,1919 @@ +# +# Automatically generated make config: don't edit +# Linux kernel version: 2.6.31-rc1 +# Tue Jun 30 15:37:31 2009 +# +CONFIG_MIPS=y + +# +# Machine selection +# +# CONFIG_MACH_ALCHEMY is not set +# CONFIG_AR7 is not set +# CONFIG_BASLER_EXCITE is not set +# CONFIG_BCM47XX is not set +# CONFIG_MIPS_COBALT is not set +# CONFIG_MACH_DECSTATION is not set +# CONFIG_MACH_JAZZ is not set +# CONFIG_LASAT is not set +CONFIG_MACH_LOONGSON=y +# CONFIG_MIPS_MALTA is not set +# CONFIG_MIPS_SIM is not set +# CONFIG_NEC_MARKEINS is not set +# CONFIG_MACH_VR41XX is not set +# CONFIG_NXP_STB220 is not set +# CONFIG_NXP_STB225 is not set +# CONFIG_PNX8550_JBS is not set +# CONFIG_PNX8550_STB810 is not set +# CONFIG_PMC_MSP is not set +# CONFIG_PMC_YOSEMITE is not set +# CONFIG_SGI_IP22 is not set +# CONFIG_SGI_IP27 is not set +# CONFIG_SGI_IP28 is not set +# CONFIG_SGI_IP32 is not set +# CONFIG_SIBYTE_CRHINE is not set +# CONFIG_SIBYTE_CARMEL is not set +# CONFIG_SIBYTE_CRHONE is not set +# CONFIG_SIBYTE_RHONE is not set +# CONFIG_SIBYTE_SWARM is not set +# CONFIG_SIBYTE_LITTLESUR is not set +# CONFIG_SIBYTE_SENTOSA is not set +# CONFIG_SIBYTE_BIGSUR is not set +# CONFIG_SNI_RM is not set +# CONFIG_MACH_TX39XX is not set +# CONFIG_MACH_TX49XX is not set +# CONFIG_MIKROTIK_RB532 is not set +# CONFIG_WR_PPMC is not set +# CONFIG_CAVIUM_OCTEON_SIMULATOR is not set +# CONFIG_CAVIUM_OCTEON_REFERENCE_BOARD is not set +# CONFIG_ALCHEMY_GPIO_INDIRECT is not set +CONFIG_ARCH_SPARSEMEM_ENABLE=y +CONFIG_LEMOTE_FULOONG2E=y +# CONFIG_LEMOTE_FULOONG2F is not set +# CONFIG_LEMOTE_YEELOONG2F is not set +CONFIG_RWSEM_GENERIC_SPINLOCK=y +# CONFIG_ARCH_HAS_ILOG2_U32 is not set +# CONFIG_ARCH_HAS_ILOG2_U64 is not set +CONFIG_ARCH_SUPPORTS_OPROFILE=y +CONFIG_GENERIC_FIND_NEXT_BIT=y +CONFIG_GENERIC_HWEIGHT=y +CONFIG_GENERIC_CALIBRATE_DELAY=y +CONFIG_GENERIC_CLOCKEVENTS=y +CONFIG_GENERIC_TIME=y +CONFIG_GENERIC_CMOS_UPDATE=y +CONFIG_SCHED_OMIT_FRAME_POINTER=y +CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y +CONFIG_CEVT_R4K_LIB=y +CONFIG_CEVT_R4K=y +CONFIG_CSRC_R4K_LIB=y +CONFIG_CSRC_R4K=y +CONFIG_DMA_NONCOHERENT=y +CONFIG_DMA_NEED_PCI_MAP_STATE=y +CONFIG_EARLY_PRINTK=y +CONFIG_SYS_HAS_EARLY_PRINTK=y +CONFIG_SYS_SUPPORTS_HOTPLUG_CPU=y +CONFIG_I8259=y +# CONFIG_NO_IOPORT is not set +CONFIG_GENERIC_ISA_DMA=y +CONFIG_GENERIC_ISA_DMA_SUPPORT_BROKEN=y +# CONFIG_CPU_BIG_ENDIAN is not set +CONFIG_CPU_LITTLE_ENDIAN=y +CONFIG_SYS_SUPPORTS_LITTLE_ENDIAN=y +CONFIG_IRQ_CPU=y +CONFIG_BOOT_ELF32=y +CONFIG_MIPS_L1_CACHE_SHIFT=5 + +# +# CPU selection +# +CONFIG_CPU_LOONGSON2E=y +# CONFIG_CPU_LOONGSON2F is not set +# CONFIG_CPU_MIPS32_R1 is not set +# CONFIG_CPU_MIPS32_R2 is not set +# CONFIG_CPU_MIPS64_R1 is not set +# CONFIG_CPU_MIPS64_R2 is not set +# CONFIG_CPU_R3000 is not set +# CONFIG_CPU_TX39XX is not set +# CONFIG_CPU_VR41XX is not set +# CONFIG_CPU_R4300 is not set +# CONFIG_CPU_R4X00 is not set +# CONFIG_CPU_TX49XX is not set +# CONFIG_CPU_R5000 is not set +# CONFIG_CPU_R5432 is not set +# CONFIG_CPU_R5500 is not set +# CONFIG_CPU_R6000 is not set +# CONFIG_CPU_NEVADA is not set +# CONFIG_CPU_R8000 is not set +# CONFIG_CPU_R10000 is not set +# CONFIG_CPU_RM7000 is not set +# CONFIG_CPU_RM9000 is not set +# CONFIG_CPU_SB1 is not set +# CONFIG_CPU_CAVIUM_OCTEON is not set +CONFIG_CPU_LOONGSON2=y +CONFIG_SYS_HAS_CPU_LOONGSON2E=y +CONFIG_SYS_SUPPORTS_32BIT_KERNEL=y +CONFIG_SYS_SUPPORTS_64BIT_KERNEL=y +CONFIG_CPU_SUPPORTS_32BIT_KERNEL=y +CONFIG_CPU_SUPPORTS_64BIT_KERNEL=y + +# +# Kernel type +# +# CONFIG_32BIT is not set +CONFIG_64BIT=y +# CONFIG_PAGE_SIZE_4KB is not set +# CONFIG_PAGE_SIZE_8KB is not set +CONFIG_PAGE_SIZE_16KB=y +# CONFIG_PAGE_SIZE_32KB is not set +# CONFIG_PAGE_SIZE_64KB is not set +CONFIG_BOARD_SCACHE=y +CONFIG_MIPS_MT_DISABLED=y +# CONFIG_MIPS_MT_SMP is not set +# CONFIG_MIPS_MT_SMTC is not set +CONFIG_CPU_HAS_WB=y +CONFIG_CPU_HAS_SYNC=y +CONFIG_GENERIC_HARDIRQS=y +CONFIG_GENERIC_IRQ_PROBE=y +CONFIG_CPU_SUPPORTS_HIGHMEM=y +CONFIG_SYS_SUPPORTS_HIGHMEM=y +CONFIG_ARCH_FLATMEM_ENABLE=y +CONFIG_ARCH_POPULATES_NODE_MAP=y +CONFIG_SELECT_MEMORY_MODEL=y +# CONFIG_FLATMEM_MANUAL is not set +# CONFIG_DISCONTIGMEM_MANUAL is not set +CONFIG_SPARSEMEM_MANUAL=y +CONFIG_SPARSEMEM=y +CONFIG_HAVE_MEMORY_PRESENT=y +CONFIG_SPARSEMEM_STATIC=y + +# +# Memory hotplug is currently incompatible with Software Suspend +# +CONFIG_PAGEFLAGS_EXTENDED=y +CONFIG_SPLIT_PTLOCK_CPUS=4 +CONFIG_PHYS_ADDR_T_64BIT=y +CONFIG_ZONE_DMA_FLAG=0 +CONFIG_VIRT_TO_BUS=y +CONFIG_HAVE_MLOCK=y +CONFIG_HAVE_MLOCKED_PAGE_BIT=y +CONFIG_DEFAULT_MMAP_MIN_ADDR=4096 +CONFIG_TICK_ONESHOT=y +CONFIG_NO_HZ=y +CONFIG_HIGH_RES_TIMERS=y +CONFIG_GENERIC_CLOCKEVENTS_BUILD=y +# CONFIG_HZ_48 is not set +# CONFIG_HZ_100 is not set +# CONFIG_HZ_128 is not set +CONFIG_HZ_250=y +# CONFIG_HZ_256 is not set +# CONFIG_HZ_1000 is not set +# CONFIG_HZ_1024 is not set +CONFIG_SYS_SUPPORTS_ARBIT_HZ=y +CONFIG_HZ=250 +# CONFIG_PREEMPT_NONE is not set +CONFIG_PREEMPT_VOLUNTARY=y +# CONFIG_PREEMPT is not set +# CONFIG_KEXEC is not set +CONFIG_SECCOMP=y +CONFIG_LOCKDEP_SUPPORT=y +CONFIG_STACKTRACE_SUPPORT=y +CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" +CONFIG_CONSTRUCTORS=y + +# +# General setup +# +CONFIG_EXPERIMENTAL=y +CONFIG_BROKEN_ON_SMP=y +CONFIG_INIT_ENV_ARG_LIMIT=32 +CONFIG_LOCALVERSION="-loongson2e" +# CONFIG_LOCALVERSION_AUTO is not set +CONFIG_SWAP=y +CONFIG_SYSVIPC=y +CONFIG_SYSVIPC_SYSCTL=y +CONFIG_POSIX_MQUEUE=y +CONFIG_POSIX_MQUEUE_SYSCTL=y +CONFIG_BSD_PROCESS_ACCT=y +# CONFIG_BSD_PROCESS_ACCT_V3 is not set +# CONFIG_TASKSTATS is not set +# CONFIG_AUDIT is not set + +# +# RCU Subsystem +# +CONFIG_CLASSIC_RCU=y +# CONFIG_TREE_RCU is not set +# CONFIG_PREEMPT_RCU is not set +# CONFIG_TREE_RCU_TRACE is not set +# CONFIG_PREEMPT_RCU_TRACE is not set +CONFIG_IKCONFIG=y +CONFIG_IKCONFIG_PROC=y +CONFIG_LOG_BUF_SHIFT=14 +# CONFIG_GROUP_SCHED is not set +# CONFIG_CGROUPS is not set +CONFIG_SYSFS_DEPRECATED=y +CONFIG_SYSFS_DEPRECATED_V2=y +# CONFIG_RELAY is not set +CONFIG_NAMESPACES=y +# CONFIG_UTS_NS is not set +# CONFIG_IPC_NS is not set +CONFIG_USER_NS=y +CONFIG_PID_NS=y +# CONFIG_NET_NS is not set +# CONFIG_BLK_DEV_INITRD is not set +# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set +CONFIG_SYSCTL=y +CONFIG_ANON_INODES=y +CONFIG_EMBEDDED=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_PCSPKR_PLATFORM is not set +CONFIG_BASE_FULL=y +CONFIG_FUTEX=y +CONFIG_EPOLL=y +CONFIG_SIGNALFD=y +CONFIG_TIMERFD=y +CONFIG_EVENTFD=y +CONFIG_SHMEM=y +CONFIG_AIO=y + +# +# Performance Counters +# +CONFIG_VM_EVENT_COUNTERS=y +CONFIG_PCI_QUIRKS=y +# CONFIG_STRIP_ASM_SYMS is not set +# CONFIG_COMPAT_BRK is not set +CONFIG_SLAB=y +# CONFIG_SLUB is not set +# CONFIG_SLOB is not set +CONFIG_PROFILING=y +CONFIG_TRACEPOINTS=y +CONFIG_MARKERS=y +CONFIG_OPROFILE=m +CONFIG_HAVE_OPROFILE=y +CONFIG_HAVE_SYSCALL_WRAPPERS=y + +# +# GCOV-based kernel profiling +# +# CONFIG_GCOV_KERNEL is not set +# CONFIG_SLOW_WORK is not set +# CONFIG_HAVE_GENERIC_DMA_COHERENT is not set +CONFIG_SLABINFO=y +CONFIG_RT_MUTEXES=y +CONFIG_BASE_SMALL=0 +CONFIG_MODULES=y +# CONFIG_MODULE_FORCE_LOAD is not set +CONFIG_MODULE_UNLOAD=y +CONFIG_MODULE_FORCE_UNLOAD=y +# CONFIG_MODVERSIONS is not set +# CONFIG_MODULE_SRCVERSION_ALL is not set +CONFIG_BLOCK=y +CONFIG_BLK_DEV_BSG=y +# CONFIG_BLK_DEV_INTEGRITY is not set +CONFIG_BLOCK_COMPAT=y + +# +# IO Schedulers +# +CONFIG_IOSCHED_NOOP=y +CONFIG_IOSCHED_AS=y +CONFIG_IOSCHED_DEADLINE=y +CONFIG_IOSCHED_CFQ=y +# CONFIG_DEFAULT_AS is not set +# CONFIG_DEFAULT_DEADLINE is not set +CONFIG_DEFAULT_CFQ=y +# CONFIG_DEFAULT_NOOP is not set +CONFIG_DEFAULT_IOSCHED="cfq" +CONFIG_FREEZER=y + +# +# Bus options (PCI, PCMCIA, EISA, ISA, TC) +# +CONFIG_HW_HAS_PCI=y +CONFIG_PCI=y +CONFIG_PCI_DOMAINS=y +# CONFIG_ARCH_SUPPORTS_MSI is not set +CONFIG_PCI_LEGACY=y +# CONFIG_PCI_STUB is not set +# CONFIG_PCI_IOV is not set +CONFIG_ISA=y +CONFIG_MMU=y +# CONFIG_PCCARD is not set +# CONFIG_HOTPLUG_PCI is not set + +# +# Executable file formats +# +CONFIG_BINFMT_ELF=y +# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set +# CONFIG_HAVE_AOUT is not set +CONFIG_BINFMT_MISC=y +CONFIG_MIPS32_COMPAT=y +CONFIG_COMPAT=y +CONFIG_SYSVIPC_COMPAT=y +CONFIG_MIPS32_O32=y +CONFIG_MIPS32_N32=y +CONFIG_BINFMT_ELF32=y + +# +# Power management options +# +CONFIG_ARCH_HIBERNATION_POSSIBLE=y +CONFIG_ARCH_SUSPEND_POSSIBLE=y +CONFIG_PM=y +# CONFIG_PM_DEBUG is not set +CONFIG_PM_SLEEP=y +CONFIG_SUSPEND=y +CONFIG_SUSPEND_FREEZER=y +CONFIG_HIBERNATION_NVS=y +CONFIG_HIBERNATION=y +CONFIG_PM_STD_PARTITION="/dev/hda3" + +# +# CPU Frequency scaling +# +# CONFIG_CPU_FREQ is not set +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_XFRM_STATISTICS 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=y +# CONFIG_IP_PNP_DHCP is not set +CONFIG_IP_PNP_BOOTP=y +# CONFIG_IP_PNP_RARP is not set +CONFIG_NET_IPIP=m +CONFIG_NET_IPGRE=m +CONFIG_NET_IPGRE_BROADCAST=y +# 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=m +# CONFIG_INET_XFRM_MODE_TRANSPORT is not set +# CONFIG_INET_XFRM_MODE_TUNNEL is not set +CONFIG_INET_XFRM_MODE_BEET=y +# CONFIG_INET_LRO is not set +# CONFIG_INET_DIAG is not set +# CONFIG_TCP_CONG_ADVANCED is not set +CONFIG_TCP_CONG_CUBIC=y +CONFIG_DEFAULT_TCP_CONG="cubic" +# CONFIG_TCP_MD5SIG is not set +# CONFIG_IPV6 is not set +# CONFIG_NETWORK_SECMARK is not set +CONFIG_NETFILTER=y +# CONFIG_NETFILTER_DEBUG is not set +CONFIG_NETFILTER_ADVANCED=y + +# +# Core Netfilter Configuration +# +CONFIG_NETFILTER_NETLINK=m +CONFIG_NETFILTER_NETLINK_QUEUE=m +CONFIG_NETFILTER_NETLINK_LOG=m +# CONFIG_NF_CONNTRACK is not set +# CONFIG_NETFILTER_TPROXY is not set +CONFIG_NETFILTER_XTABLES=m +CONFIG_NETFILTER_XT_TARGET_CLASSIFY=m +# CONFIG_NETFILTER_XT_TARGET_DSCP is not set +CONFIG_NETFILTER_XT_TARGET_HL=m +CONFIG_NETFILTER_XT_TARGET_MARK=m +# CONFIG_NETFILTER_XT_TARGET_NFLOG is not set +CONFIG_NETFILTER_XT_TARGET_NFQUEUE=m +CONFIG_NETFILTER_XT_TARGET_RATEEST=m +CONFIG_NETFILTER_XT_TARGET_TRACE=m +# CONFIG_NETFILTER_XT_TARGET_TCPMSS is not set +CONFIG_NETFILTER_XT_TARGET_TCPOPTSTRIP=m +CONFIG_NETFILTER_XT_MATCH_COMMENT=m +CONFIG_NETFILTER_XT_MATCH_DCCP=m +# CONFIG_NETFILTER_XT_MATCH_DSCP is not set +CONFIG_NETFILTER_XT_MATCH_ESP=m +# CONFIG_NETFILTER_XT_MATCH_HASHLIMIT is not set +CONFIG_NETFILTER_XT_MATCH_HL=m +CONFIG_NETFILTER_XT_MATCH_IPRANGE=m +CONFIG_NETFILTER_XT_MATCH_LENGTH=m +CONFIG_NETFILTER_XT_MATCH_LIMIT=m +CONFIG_NETFILTER_XT_MATCH_MAC=m +CONFIG_NETFILTER_XT_MATCH_MARK=m +CONFIG_NETFILTER_XT_MATCH_MULTIPORT=m +CONFIG_NETFILTER_XT_MATCH_OWNER=m +# CONFIG_NETFILTER_XT_MATCH_POLICY is not set +CONFIG_NETFILTER_XT_MATCH_PKTTYPE=m +CONFIG_NETFILTER_XT_MATCH_QUOTA=m +CONFIG_NETFILTER_XT_MATCH_RATEEST=m +CONFIG_NETFILTER_XT_MATCH_REALM=m +CONFIG_NETFILTER_XT_MATCH_RECENT=m +# CONFIG_NETFILTER_XT_MATCH_RECENT_PROC_COMPAT is not set +CONFIG_NETFILTER_XT_MATCH_SCTP=m +CONFIG_NETFILTER_XT_MATCH_STATISTIC=m +CONFIG_NETFILTER_XT_MATCH_STRING=m +CONFIG_NETFILTER_XT_MATCH_TCPMSS=m +CONFIG_NETFILTER_XT_MATCH_TIME=m +CONFIG_NETFILTER_XT_MATCH_U32=m +# CONFIG_NETFILTER_XT_MATCH_OSF is not set +# CONFIG_IP_VS is not set + +# +# IP: Netfilter Configuration +# +# CONFIG_NF_DEFRAG_IPV4 is not set +CONFIG_IP_NF_QUEUE=m +CONFIG_IP_NF_IPTABLES=m +CONFIG_IP_NF_MATCH_ADDRTYPE=m +CONFIG_IP_NF_MATCH_AH=m +CONFIG_IP_NF_MATCH_ECN=m +CONFIG_IP_NF_MATCH_TTL=m +CONFIG_IP_NF_FILTER=m +CONFIG_IP_NF_TARGET_REJECT=m +CONFIG_IP_NF_TARGET_LOG=m +CONFIG_IP_NF_TARGET_ULOG=m +CONFIG_IP_NF_MANGLE=m +CONFIG_IP_NF_TARGET_ECN=m +CONFIG_IP_NF_TARGET_TTL=m +CONFIG_IP_NF_RAW=m +CONFIG_IP_NF_ARPTABLES=m +CONFIG_IP_NF_ARPFILTER=m +CONFIG_IP_NF_ARP_MANGLE=m +# 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_NET_DSA 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_PHONET=m +# CONFIG_IEEE802154 is not set +# CONFIG_NET_SCHED is not set +CONFIG_NET_CLS_ROUTE=y +# CONFIG_DCB is not set + +# +# Network testing +# +# CONFIG_NET_PKTGEN is not set +# CONFIG_NET_DROP_MONITOR is not set +# CONFIG_HAMRADIO is not set +# CONFIG_CAN is not set +# CONFIG_IRDA is not set +# CONFIG_BT is not set +# CONFIG_AF_RXRPC is not set +CONFIG_WIRELESS=y +# CONFIG_CFG80211 is not set +CONFIG_WIRELESS_OLD_REGULATORY=y +CONFIG_WIRELESS_EXT=y +CONFIG_WIRELESS_EXT_SYSFS=y +# CONFIG_LIB80211 is not set + +# +# CFG80211 needs to be enabled for MAC80211 +# +CONFIG_MAC80211_DEFAULT_PS_VALUE=0 +# CONFIG_WIMAX is not set +# CONFIG_RFKILL is not set +CONFIG_NET_9P=m +# CONFIG_NET_9P_DEBUG 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=m +CONFIG_FIRMWARE_IN_KERNEL=y +CONFIG_EXTRA_FIRMWARE="" +# CONFIG_SYS_HYPERVISOR is not set +# CONFIG_CONNECTOR is not set +CONFIG_MTD=m +# CONFIG_MTD_DEBUG is not set +# CONFIG_MTD_CONCAT is not set +# CONFIG_MTD_PARTITIONS is not set +# CONFIG_MTD_TESTS is not set + +# +# User Modules And Translation Layers +# +CONFIG_MTD_CHAR=m +CONFIG_MTD_BLKDEVS=m +CONFIG_MTD_BLOCK=m +# CONFIG_MTD_BLOCK_RO is not set +# CONFIG_FTL is not set +# CONFIG_NFTL is not set +# CONFIG_INFTL is not set +# CONFIG_RFD_FTL is not set +# CONFIG_SSFDC is not set +# CONFIG_MTD_OOPS is not set + +# +# RAM/ROM/Flash chip drivers +# +CONFIG_MTD_CFI=m +CONFIG_MTD_JEDECPROBE=m +CONFIG_MTD_GEN_PROBE=m +CONFIG_MTD_CFI_ADV_OPTIONS=y +CONFIG_MTD_CFI_NOSWAP=y +# CONFIG_MTD_CFI_BE_BYTE_SWAP is not set +# CONFIG_MTD_CFI_LE_BYTE_SWAP is not set +# CONFIG_MTD_CFI_GEOMETRY is not set +CONFIG_MTD_MAP_BANK_WIDTH_1=y +CONFIG_MTD_MAP_BANK_WIDTH_2=y +CONFIG_MTD_MAP_BANK_WIDTH_4=y +# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set +# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set +# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set +CONFIG_MTD_CFI_I1=y +CONFIG_MTD_CFI_I2=y +# CONFIG_MTD_CFI_I4 is not set +# CONFIG_MTD_CFI_I8 is not set +# CONFIG_MTD_OTP is not set +# CONFIG_MTD_CFI_INTELEXT is not set +CONFIG_MTD_CFI_AMDSTD=m +CONFIG_MTD_CFI_STAA=m +CONFIG_MTD_CFI_UTIL=m +# CONFIG_MTD_RAM is not set +# CONFIG_MTD_ROM is not set +# CONFIG_MTD_ABSENT is not set + +# +# Mapping drivers for chip access +# +# CONFIG_MTD_COMPLEX_MAPPINGS is not set +CONFIG_MTD_PHYSMAP=m +# CONFIG_MTD_PHYSMAP_COMPAT is not set +# CONFIG_MTD_INTEL_VR_NOR is not set +# CONFIG_MTD_PLATRAM is not set + +# +# Self-contained MTD device drivers +# +# CONFIG_MTD_PMC551 is not set +# CONFIG_MTD_SLRAM is not set +# CONFIG_MTD_PHRAM is not set +# CONFIG_MTD_MTDRAM is not set +# CONFIG_MTD_BLOCK2MTD is not set + +# +# Disk-On-Chip Device Drivers +# +# CONFIG_MTD_DOC2000 is not set +# CONFIG_MTD_DOC2001 is not set +# CONFIG_MTD_DOC2001PLUS is not set +# CONFIG_MTD_NAND is not set +# CONFIG_MTD_ONENAND is not set + +# +# LPDDR flash memory drivers +# +# CONFIG_MTD_LPDDR is not set + +# +# UBI - Unsorted block images +# +# CONFIG_MTD_UBI is not set +# CONFIG_PARPORT is not set +# CONFIG_PNP 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=m +# 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=m +CONFIG_BLK_DEV_RAM_COUNT=16 +CONFIG_BLK_DEV_RAM_SIZE=4096 +# CONFIG_BLK_DEV_XIP is not set +CONFIG_CDROM_PKTCDVD=m +CONFIG_CDROM_PKTCDVD_BUFFERS=8 +# CONFIG_CDROM_PKTCDVD_WCACHE is not set +CONFIG_ATA_OVER_ETH=m +# CONFIG_BLK_DEV_HD is not set +# CONFIG_MISC_DEVICES is not set +CONFIG_HAVE_IDE=y +CONFIG_IDE=y + +# +# Please see Documentation/ide/ide.txt for help/info on IDE drives +# +CONFIG_IDE_XFER_MODE=y +CONFIG_IDE_TIMINGS=y +CONFIG_IDE_ATAPI=y +# CONFIG_BLK_DEV_IDE_SATA is not set +CONFIG_IDE_GD=y +CONFIG_IDE_GD_ATA=y +# CONFIG_IDE_GD_ATAPI is not set +CONFIG_BLK_DEV_IDECD=y +CONFIG_BLK_DEV_IDECD_VERBOSE_ERRORS=y +# CONFIG_BLK_DEV_IDETAPE is not set +CONFIG_IDE_TASK_IOCTL=y +CONFIG_IDE_PROC_FS=y + +# +# IDE chipset support/bugfixes +# +CONFIG_IDE_GENERIC=y +# CONFIG_BLK_DEV_PLATFORM is not set +CONFIG_BLK_DEV_IDEDMA_SFF=y + +# +# PCI IDE chipsets support +# +CONFIG_BLK_DEV_IDEPCI=y +CONFIG_IDEPCI_PCIBUS_ORDER=y +# CONFIG_BLK_DEV_OFFBOARD is not set +CONFIG_BLK_DEV_GENERIC=y +# CONFIG_BLK_DEV_OPTI621 is not set +CONFIG_BLK_DEV_IDEDMA_PCI=y +# CONFIG_BLK_DEV_AEC62XX is not set +# CONFIG_BLK_DEV_ALI15X3 is not set +# CONFIG_BLK_DEV_AMD74XX is not set +# CONFIG_BLK_DEV_CMD64X is not set +# CONFIG_BLK_DEV_TRIFLEX is not set +# CONFIG_BLK_DEV_CS5520 is not set +# CONFIG_BLK_DEV_CS5530 is not set +# CONFIG_BLK_DEV_HPT366 is not set +# CONFIG_BLK_DEV_JMICRON is not set +# CONFIG_BLK_DEV_SC1200 is not set +# CONFIG_BLK_DEV_PIIX is not set +# CONFIG_BLK_DEV_IT8172 is not set +# CONFIG_BLK_DEV_IT8213 is not set +# CONFIG_BLK_DEV_IT821X is not set +# CONFIG_BLK_DEV_NS87415 is not set +# CONFIG_BLK_DEV_PDC202XX_OLD is not set +# CONFIG_BLK_DEV_PDC202XX_NEW is not set +# CONFIG_BLK_DEV_SVWKS is not set +# CONFIG_BLK_DEV_SIIMAGE is not set +# CONFIG_BLK_DEV_SLC90E66 is not set +# CONFIG_BLK_DEV_TRM290 is not set +CONFIG_BLK_DEV_VIA82CXXX=y +# CONFIG_BLK_DEV_TC86C001 is not set + +# +# Other IDE chipsets support +# + +# +# Note: most of these also require special kernel boot parameters +# +# CONFIG_BLK_DEV_4DRIVES is not set +# CONFIG_BLK_DEV_ALI14XX is not set +# CONFIG_BLK_DEV_DTC2278 is not set +# CONFIG_BLK_DEV_HT6560B is not set +# CONFIG_BLK_DEV_QD65XX is not set +# CONFIG_BLK_DEV_UMC8672 is not set +CONFIG_BLK_DEV_IDEDMA=y + +# +# 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=y +CONFIG_BLK_DEV_SR_VENDOR=y +CONFIG_CHR_DEV_SG=y +# CONFIG_CHR_DEV_SCH is not set +# CONFIG_SCSI_MULTI_LUN is not set +CONFIG_SCSI_CONSTANTS=y +# 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_ATTRS is not set +# CONFIG_SCSI_SAS_LIBSAS is not set +# CONFIG_SCSI_SRP_ATTRS is not set +# CONFIG_SCSI_LOWLEVEL is not set +# CONFIG_SCSI_DH is not set +# CONFIG_SCSI_OSD_INITIATOR is not set +# CONFIG_ATA is not set +# CONFIG_MD is not set +# CONFIG_FUSION is not set + +# +# IEEE 1394 (FireWire) support +# + +# +# You can enable one or both FireWire driver stacks. +# + +# +# See the help texts for more information. +# +# CONFIG_FIREWIRE is not set +# CONFIG_IEEE1394 is not set +# CONFIG_I2O is not set +CONFIG_NETDEVICES=y +# CONFIG_DUMMY is not set +# CONFIG_BONDING is not set +CONFIG_MACVLAN=m +# CONFIG_EQUALIZER is not set +# CONFIG_TUN is not set +CONFIG_VETH=m +# CONFIG_ARCNET is not set +CONFIG_PHYLIB=m + +# +# MII PHY device drivers +# +CONFIG_MARVELL_PHY=m +CONFIG_DAVICOM_PHY=m +CONFIG_QSEMI_PHY=m +CONFIG_LXT_PHY=m +CONFIG_CICADA_PHY=m +# CONFIG_VITESSE_PHY is not set +# CONFIG_SMSC_PHY is not set +# CONFIG_BROADCOM_PHY is not set +# CONFIG_ICPLUS_PHY is not set +# CONFIG_REALTEK_PHY is not set +# CONFIG_NATIONAL_PHY is not set +# CONFIG_STE10XP is not set +# CONFIG_LSI_ET1011C_PHY is not set +# CONFIG_MDIO_BITBANG is not set +CONFIG_NET_ETHERNET=y +CONFIG_MII=y +# CONFIG_AX88796 is not set +# CONFIG_HAPPYMEAL is not set +# CONFIG_SUNGEM is not set +# CONFIG_CASSINI is not set +# CONFIG_NET_VENDOR_3COM is not set +# CONFIG_NET_VENDOR_SMC is not set +# CONFIG_SMC91X is not set +# CONFIG_DM9000 is not set +# CONFIG_ETHOC is not set +# CONFIG_NET_VENDOR_RACAL is not set +# CONFIG_DNET is not set +# CONFIG_NET_TULIP is not set +# CONFIG_AT1700 is not set +# CONFIG_DEPCA is not set +# CONFIG_HP100 is not set +# CONFIG_NET_ISA is not set +# CONFIG_IBM_NEW_EMAC_ZMII is not set +# CONFIG_IBM_NEW_EMAC_RGMII is not set +# CONFIG_IBM_NEW_EMAC_TAH is not set +# CONFIG_IBM_NEW_EMAC_EMAC4 is not set +# CONFIG_IBM_NEW_EMAC_NO_FLOW_CTRL is not set +# CONFIG_IBM_NEW_EMAC_MAL_CLR_ICINTSTAT is not set +# CONFIG_IBM_NEW_EMAC_MAL_COMMON_ERR is not set +CONFIG_NET_PCI=y +# CONFIG_PCNET32 is not set +# CONFIG_AMD8111_ETH is not set +# CONFIG_ADAPTEC_STARFIRE is not set +# CONFIG_AC3200 is not set +# CONFIG_APRICOT is not set +# CONFIG_B44 is not set +# CONFIG_FORCEDETH is not set +# CONFIG_CS89x0 is not set +# CONFIG_TC35815 is not set +# CONFIG_E100 is not set +# CONFIG_FEALNX is not set +# CONFIG_NATSEMI is not set +# CONFIG_NE2K_PCI is not set +# CONFIG_8139CP is not set +CONFIG_8139TOO=y +# CONFIG_8139TOO_PIO is not set +# CONFIG_8139TOO_TUNE_TWISTER is not set +# CONFIG_8139TOO_8129 is not set +# CONFIG_8139_OLD_RX_RESET is not set +# CONFIG_R6040 is not set +# CONFIG_SIS900 is not set +# CONFIG_EPIC100 is not set +# CONFIG_SMSC9420 is not set +# CONFIG_SUNDANCE is not set +# CONFIG_TLAN is not set +# CONFIG_KS8842 is not set +# CONFIG_VIA_RHINE is not set +# CONFIG_SC92031 is not set +# CONFIG_ATL2 is not set +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_IGB is not set +# CONFIG_IGBVF 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_VIA_VELOCITY is not set +# CONFIG_TIGON3 is not set +# CONFIG_BNX2 is not set +# CONFIG_CNIC is not set +# CONFIG_QLA3XXX is not set +# CONFIG_ATL1 is not set +# CONFIG_ATL1E is not set +# CONFIG_ATL1C is not set +# CONFIG_JME is not set +CONFIG_NETDEV_10000=y +# CONFIG_CHELSIO_T1 is not set +CONFIG_CHELSIO_T3_DEPENDS=y +# CONFIG_CHELSIO_T3 is not set +# CONFIG_ENIC is not set +# CONFIG_IXGBE is not set +# CONFIG_IXGB is not set +# CONFIG_S2IO is not set +# CONFIG_VXGE is not set +# CONFIG_MYRI10GE is not set +# CONFIG_NETXEN_NIC is not set +# CONFIG_NIU is not set +# CONFIG_MLX4_EN is not set +# CONFIG_MLX4_CORE is not set +# CONFIG_TEHUTI is not set +# CONFIG_BNX2X is not set +# CONFIG_QLGE is not set +# CONFIG_SFC is not set +# CONFIG_BE2NET is not set +# CONFIG_TR is not set + +# +# Wireless LAN +# +# CONFIG_WLAN_PRE80211 is not set +# CONFIG_WLAN_80211 is not set + +# +# Enable WiMAX (Networking options) to see the WiMAX drivers +# + +# +# 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=m +CONFIG_PPP_MULTILINK=y +CONFIG_PPP_FILTER=y +CONFIG_PPP_ASYNC=m +CONFIG_PPP_SYNC_TTY=m +CONFIG_PPP_DEFLATE=m +CONFIG_PPP_BSDCOMP=m +CONFIG_PPP_MPPE=m +CONFIG_PPPOE=m +CONFIG_PPPOL2TP=m +CONFIG_SLIP=m +CONFIG_SLIP_COMPRESSED=y +CONFIG_SLHC=m +CONFIG_SLIP_SMART=y +CONFIG_SLIP_MODE_SLIP6=y +CONFIG_NET_FC=y +# CONFIG_NETCONSOLE is not set +# CONFIG_NETPOLL is not set +# CONFIG_NET_POLL_CONTROLLER is not set +# CONFIG_ISDN is not set +# CONFIG_PHONE is not set + +# +# Input device support +# +CONFIG_INPUT=y +CONFIG_INPUT_FF_MEMLESS=y +# CONFIG_INPUT_POLLDEV is not set + +# +# Userland interfaces +# +CONFIG_INPUT_MOUSEDEV=y +CONFIG_INPUT_MOUSEDEV_PSAUX=y +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=y +CONFIG_KEYBOARD_ATKBD=m +# CONFIG_KEYBOARD_SUNKBD is not set +# CONFIG_KEYBOARD_LKKBD is not set +# CONFIG_KEYBOARD_XTKBD is not set +# CONFIG_KEYBOARD_NEWTON is not set +# CONFIG_KEYBOARD_STOWAWAY is not set +CONFIG_INPUT_MOUSE=y +CONFIG_MOUSE_PS2=y +CONFIG_MOUSE_PS2_ALPS=y +CONFIG_MOUSE_PS2_LOGIPS2PP=y +CONFIG_MOUSE_PS2_SYNAPTICS=y +CONFIG_MOUSE_PS2_TRACKPOINT=y +# CONFIG_MOUSE_PS2_ELANTECH is not set +# CONFIG_MOUSE_PS2_TOUCHKIT is not set +CONFIG_MOUSE_SERIAL=y +# CONFIG_MOUSE_APPLETOUCH is not set +# CONFIG_MOUSE_BCM5974 is not set +# CONFIG_MOUSE_INPORT is not set +# CONFIG_MOUSE_LOGIBM is not set +# CONFIG_MOUSE_PC110PAD is not set +# CONFIG_MOUSE_VSXXXAA is not set +# CONFIG_MOUSE_SYNAPTICS_I2C 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=y +CONFIG_SERIO_I8042=y +CONFIG_SERIO_SERPORT=y +# CONFIG_SERIO_PCIPS2 is not set +CONFIG_SERIO_LIBPS2=y +# CONFIG_SERIO_RAW is not set +# CONFIG_GAMEPORT is not set + +# +# Character devices +# +CONFIG_VT=y +CONFIG_CONSOLE_TRANSLATIONS=y +CONFIG_VT_CONSOLE=y +CONFIG_HW_CONSOLE=y +# CONFIG_VT_HW_CONSOLE_BINDING is not set +CONFIG_DEVKMEM=y +# CONFIG_SERIAL_NONSTANDARD is not set +# CONFIG_NOZOMI is not set + +# +# Serial drivers +# +CONFIG_SERIAL_8250=y +CONFIG_SERIAL_8250_CONSOLE=y +CONFIG_SERIAL_8250_PCI=y +CONFIG_SERIAL_8250_NR_UARTS=2 +CONFIG_SERIAL_8250_RUNTIME_UARTS=2 +# CONFIG_SERIAL_8250_EXTENDED is not set + +# +# Non-8250 serial port support +# +CONFIG_SERIAL_CORE=y +CONFIG_SERIAL_CORE_CONSOLE=y +# CONFIG_SERIAL_JSM is not set +CONFIG_UNIX98_PTYS=y +# CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set +CONFIG_LEGACY_PTYS=y +CONFIG_LEGACY_PTY_COUNT=256 +# CONFIG_IPMI_HANDLER is not set +CONFIG_HW_RANDOM=y +# CONFIG_HW_RANDOM_TIMERIOMEM is not set +# CONFIG_DTLK 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=m +CONFIG_I2C_HELPER_AUTO=y + +# +# I2C Hardware Bus support +# + +# +# PC SMBus host controller drivers +# +# 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_ISCH is not set +# CONFIG_I2C_PIIX4 is not set +# CONFIG_I2C_NFORCE2 is not set +# CONFIG_I2C_SIS5595 is not set +# CONFIG_I2C_SIS630 is not set +# CONFIG_I2C_SIS96X is not set +# CONFIG_I2C_VIA is not set +CONFIG_I2C_VIAPRO=m + +# +# I2C system bus drivers (mostly embedded / system-on-chip) +# +# CONFIG_I2C_OCORES is not set +# CONFIG_I2C_SIMTEC is not set + +# +# External I2C/SMBus adapter drivers +# +# CONFIG_I2C_PARPORT_LIGHT is not set +# CONFIG_I2C_TAOS_EVM is not set +# CONFIG_I2C_TINY_USB is not set + +# +# Graphics adapter I2C/DDC channel drivers +# +# CONFIG_I2C_VOODOO3 is not set + +# +# Other I2C/SMBus bus drivers +# +# CONFIG_I2C_ELEKTOR is not set +# CONFIG_I2C_PCA_ISA is not set +# CONFIG_I2C_PCA_PLATFORM is not set +# CONFIG_I2C_STUB is not set + +# +# Miscellaneous I2C Chip support +# +# CONFIG_DS1682 is not set +# CONFIG_SENSORS_PCF8574 is not set +# CONFIG_PCF8575 is not set +# CONFIG_SENSORS_PCA9539 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 +# CONFIG_SPI is not set + +# +# PPS support +# +# CONFIG_PPS is not set +# CONFIG_W1 is not set +# CONFIG_POWER_SUPPLY is not set +# CONFIG_HWMON is not set +# CONFIG_THERMAL is not set +# CONFIG_THERMAL_HWMON is not set +# CONFIG_WATCHDOG is not set +CONFIG_SSB_POSSIBLE=y + +# +# Sonics Silicon Backplane +# +# CONFIG_SSB is not set + +# +# Multifunction device drivers +# +# CONFIG_MFD_CORE is not set +# CONFIG_MFD_SM501 is not set +# CONFIG_HTC_PASIC3 is not set +# CONFIG_MFD_TMIO is not set +# CONFIG_MFD_WM8400 is not set +# CONFIG_MFD_WM8350_I2C is not set +# CONFIG_MFD_PCF50633 is not set +# CONFIG_AB3100_CORE is not set +# CONFIG_REGULATOR is not set +# CONFIG_MEDIA_SUPPORT is not set + +# +# Graphics support +# +# CONFIG_DRM is not set +# CONFIG_VGASTATE is not set +CONFIG_VIDEO_OUTPUT_CONTROL=m +CONFIG_FB=y +# CONFIG_FIRMWARE_EDID is not set +# CONFIG_FB_DDC is not set +# CONFIG_FB_BOOT_VESA_SUPPORT is not set +CONFIG_FB_CFB_FILLRECT=y +CONFIG_FB_CFB_COPYAREA=y +CONFIG_FB_CFB_IMAGEBLIT=y +# CONFIG_FB_CFB_REV_PIXELS_IN_BYTE is not set +# CONFIG_FB_SYS_FILLRECT is not set +# CONFIG_FB_SYS_COPYAREA is not set +# CONFIG_FB_SYS_IMAGEBLIT is not set +# CONFIG_FB_FOREIGN_ENDIAN is not set +# CONFIG_FB_SYS_FOPS is not set +# CONFIG_FB_SVGALIB is not set +# CONFIG_FB_MACMODES is not set +CONFIG_FB_BACKLIGHT=y +CONFIG_FB_MODE_HELPERS=y +# CONFIG_FB_TILEBLITTING is not set + +# +# Frame buffer hardware drivers +# +# CONFIG_FB_CIRRUS is not set +# CONFIG_FB_PM2 is not set +# CONFIG_FB_CYBER2000 is not set +# CONFIG_FB_ASILIANT is not set +# CONFIG_FB_IMSTT is not set +# CONFIG_FB_S1D13XXX is not set +# CONFIG_FB_NVIDIA is not set +# CONFIG_FB_RIVA is not set +# CONFIG_FB_MATROX is not set +CONFIG_FB_RADEON=y +# CONFIG_FB_RADEON_I2C is not set +CONFIG_FB_RADEON_BACKLIGHT=y +# CONFIG_FB_RADEON_DEBUG is not set +# CONFIG_FB_ATY128 is not set +# CONFIG_FB_ATY is not set +# CONFIG_FB_S3 is not set +# CONFIG_FB_SAVAGE is not set +# CONFIG_FB_SIS is not set +# CONFIG_FB_VIA is not set +# CONFIG_FB_NEOMAGIC is not set +# CONFIG_FB_KYRO is not set +# CONFIG_FB_3DFX is not set +# CONFIG_FB_VOODOO1 is not set +# CONFIG_FB_VT8623 is not set +# CONFIG_FB_TRIDENT is not set +# CONFIG_FB_ARK is not set +# CONFIG_FB_PM3 is not set +# CONFIG_FB_CARMINE is not set +# CONFIG_FB_SM7XX is not set +# CONFIG_FB_VIRTUAL is not set +# CONFIG_FB_METRONOME is not set +# CONFIG_FB_MB862XX is not set +# CONFIG_FB_BROADSHEET is not set +CONFIG_BACKLIGHT_LCD_SUPPORT=y +CONFIG_LCD_CLASS_DEVICE=m +# CONFIG_LCD_ILI9320 is not set +# CONFIG_LCD_PLATFORM is not set +CONFIG_BACKLIGHT_CLASS_DEVICE=y +CONFIG_BACKLIGHT_GENERIC=y + +# +# Display device support +# +# CONFIG_DISPLAY_SUPPORT is not set + +# +# Console display driver support +# +# CONFIG_VGA_CONSOLE is not set +# CONFIG_MDA_CONSOLE is not set +CONFIG_DUMMY_CONSOLE=y +CONFIG_FRAMEBUFFER_CONSOLE=y +# CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY is not set +# CONFIG_FRAMEBUFFER_CONSOLE_ROTATION is not set +# CONFIG_FONTS is not set +CONFIG_FONT_8x8=y +CONFIG_FONT_8x16=y +# CONFIG_LOGO is not set +CONFIG_SOUND=y +CONFIG_SOUND_OSS_CORE=y +CONFIG_SND=m +CONFIG_SND_TIMER=m +CONFIG_SND_PCM=m +CONFIG_SND_RAWMIDI=m +CONFIG_SND_SEQUENCER=m +CONFIG_SND_SEQ_DUMMY=m +CONFIG_SND_OSSEMUL=y +CONFIG_SND_MIXER_OSS=m +CONFIG_SND_PCM_OSS=m +CONFIG_SND_PCM_OSS_PLUGINS=y +CONFIG_SND_SEQUENCER_OSS=y +# CONFIG_SND_HRTIMER is not set +# CONFIG_SND_DYNAMIC_MINORS is not set +CONFIG_SND_SUPPORT_OLD_API=y +CONFIG_SND_VERBOSE_PROCFS=y +# CONFIG_SND_VERBOSE_PRINTK is not set +# CONFIG_SND_DEBUG is not set +CONFIG_SND_VMASTER=y +CONFIG_SND_RAWMIDI_SEQ=m +# CONFIG_SND_OPL3_LIB_SEQ is not set +# CONFIG_SND_OPL4_LIB_SEQ is not set +# CONFIG_SND_SBAWE_SEQ is not set +# CONFIG_SND_EMU10K1_SEQ is not set +CONFIG_SND_MPU401_UART=m +CONFIG_SND_AC97_CODEC=m +CONFIG_SND_DRIVERS=y +# CONFIG_SND_DUMMY is not set +# CONFIG_SND_VIRMIDI is not set +# CONFIG_SND_MTPAV is not set +# CONFIG_SND_SERIAL_U16550 is not set +# CONFIG_SND_MPU401 is not set +# CONFIG_SND_AC97_POWER_SAVE is not set +CONFIG_SND_PCI=y +# CONFIG_SND_AD1889 is not set +# CONFIG_SND_ALS300 is not set +# CONFIG_SND_ALI5451 is not set +# CONFIG_SND_ATIIXP is not set +# CONFIG_SND_ATIIXP_MODEM is not set +# CONFIG_SND_AU8810 is not set +# CONFIG_SND_AU8820 is not set +# CONFIG_SND_AU8830 is not set +# CONFIG_SND_AW2 is not set +# CONFIG_SND_AZT3328 is not set +# CONFIG_SND_BT87X is not set +# CONFIG_SND_CA0106 is not set +# CONFIG_SND_CMIPCI is not set +# CONFIG_SND_OXYGEN is not set +# CONFIG_SND_CS4281 is not set +# CONFIG_SND_CS46XX is not set +# CONFIG_SND_CS5535AUDIO is not set +# CONFIG_SND_CTXFI is not set +# CONFIG_SND_DARLA20 is not set +# CONFIG_SND_GINA20 is not set +# CONFIG_SND_LAYLA20 is not set +# CONFIG_SND_DARLA24 is not set +# CONFIG_SND_GINA24 is not set +# CONFIG_SND_LAYLA24 is not set +# CONFIG_SND_MONA is not set +# CONFIG_SND_MIA is not set +# CONFIG_SND_ECHO3G is not set +# CONFIG_SND_INDIGO is not set +# CONFIG_SND_INDIGOIO is not set +# CONFIG_SND_INDIGODJ is not set +# CONFIG_SND_INDIGOIOX is not set +# CONFIG_SND_INDIGODJX is not set +# CONFIG_SND_EMU10K1 is not set +# CONFIG_SND_EMU10K1X is not set +# CONFIG_SND_ENS1370 is not set +# CONFIG_SND_ENS1371 is not set +# CONFIG_SND_ES1938 is not set +# CONFIG_SND_ES1968 is not set +# CONFIG_SND_FM801 is not set +# CONFIG_SND_HDA_INTEL is not set +# CONFIG_SND_HDSP is not set +# CONFIG_SND_HDSPM is not set +# CONFIG_SND_HIFIER is not set +# CONFIG_SND_ICE1712 is not set +# CONFIG_SND_ICE1724 is not set +# CONFIG_SND_INTEL8X0 is not set +# CONFIG_SND_INTEL8X0M is not set +# CONFIG_SND_KORG1212 is not set +# CONFIG_SND_LX6464ES is not set +# CONFIG_SND_MAESTRO3 is not set +# CONFIG_SND_MIXART is not set +# CONFIG_SND_NM256 is not set +# CONFIG_SND_PCXHR is not set +# CONFIG_SND_RIPTIDE is not set +# CONFIG_SND_RME32 is not set +# CONFIG_SND_RME96 is not set +# CONFIG_SND_RME9652 is not set +# CONFIG_SND_SONICVIBES is not set +# CONFIG_SND_TRIDENT is not set +CONFIG_SND_VIA82XX=m +# CONFIG_SND_VIA82XX_MODEM is not set +# CONFIG_SND_VIRTUOSO is not set +# CONFIG_SND_VX222 is not set +# CONFIG_SND_YMFPCI is not set +CONFIG_SND_MIPS=y +CONFIG_SND_USB=y +# CONFIG_SND_USB_AUDIO is not set +# CONFIG_SND_USB_CAIAQ is not set +# CONFIG_SND_SOC is not set +# CONFIG_SOUND_PRIME is not set +CONFIG_AC97_BUS=m +CONFIG_HID_SUPPORT=y +CONFIG_HID=y +# CONFIG_HID_DEBUG is not set +CONFIG_HIDRAW=y + +# +# USB Input Devices +# +CONFIG_USB_HID=m +CONFIG_HID_PID=y +CONFIG_USB_HIDDEV=y + +# +# USB HID Boot Protocol drivers +# +# CONFIG_USB_KBD is not set +# CONFIG_USB_MOUSE is not set + +# +# Special HID drivers +# +CONFIG_HID_A4TECH=m +CONFIG_HID_APPLE=m +CONFIG_HID_BELKIN=m +CONFIG_HID_CHERRY=m +CONFIG_HID_CHICONY=m +CONFIG_HID_CYPRESS=m +# CONFIG_HID_DRAGONRISE is not set +CONFIG_HID_EZKEY=m +# CONFIG_HID_KYE is not set +CONFIG_HID_GYRATION=m +# CONFIG_HID_KENSINGTON is not set +CONFIG_HID_LOGITECH=m +CONFIG_LOGITECH_FF=y +CONFIG_LOGIRUMBLEPAD2_FF=y +CONFIG_HID_MICROSOFT=m +CONFIG_HID_MONTEREY=m +# CONFIG_HID_NTRIG is not set +CONFIG_HID_PANTHERLORD=m +# CONFIG_PANTHERLORD_FF is not set +CONFIG_HID_PETALYNX=m +CONFIG_HID_SAMSUNG=m +CONFIG_HID_SONY=m +CONFIG_HID_SUNPLUS=m +# CONFIG_HID_GREENASIA is not set +# CONFIG_HID_SMARTJOYPLUS is not set +# CONFIG_HID_TOPSEED is not set +# CONFIG_HID_THRUSTMASTER is not set +# CONFIG_HID_ZEROPLUS 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 +CONFIG_USB_ANNOUNCE_NEW_DEVICES=y + +# +# Miscellaneous USB options +# +CONFIG_USB_DEVICEFS=y +# CONFIG_USB_DEVICE_CLASS is not set +# CONFIG_USB_DYNAMIC_MINORS is not set +# CONFIG_USB_SUSPEND is not set +# CONFIG_USB_OTG is not set +CONFIG_USB_OTG_WHITELIST=y +# CONFIG_USB_OTG_BLACKLIST_HUB is not set +# CONFIG_USB_MON is not set +# CONFIG_USB_WUSB is not set +CONFIG_USB_WUSB_CBAF=m +# CONFIG_USB_WUSB_CBAF_DEBUG is not set + +# +# USB Host Controller Drivers +# +CONFIG_USB_C67X00_HCD=m +# CONFIG_USB_XHCI_HCD is not set +CONFIG_USB_EHCI_HCD=y +CONFIG_USB_EHCI_ROOT_HUB_TT=y +CONFIG_USB_EHCI_TT_NEWSCHED=y +# CONFIG_USB_OXU210HP_HCD is not set +# CONFIG_USB_ISP116X_HCD is not set +CONFIG_USB_ISP1760_HCD=m +CONFIG_USB_OHCI_HCD=y +# CONFIG_USB_OHCI_BIG_ENDIAN_DESC is not set +# CONFIG_USB_OHCI_BIG_ENDIAN_MMIO is not set +CONFIG_USB_OHCI_LITTLE_ENDIAN=y +CONFIG_USB_UHCI_HCD=m +# CONFIG_USB_SL811_HCD is not set +CONFIG_USB_R8A66597_HCD=m +# CONFIG_USB_WHCI_HCD is not set +# CONFIG_USB_HWA_HCD is not set + +# +# USB Device Class drivers +# +CONFIG_USB_ACM=y +CONFIG_USB_PRINTER=y +CONFIG_USB_WDM=m +CONFIG_USB_TMC=m + +# +# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may +# + +# +# also be needed; see USB_STORAGE Help for more info +# +CONFIG_USB_STORAGE=y +# 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_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_ONETOUCH=y +# CONFIG_USB_STORAGE_KARMA is not set +CONFIG_USB_STORAGE_CYPRESS_ATACB=y +CONFIG_USB_LIBUSUAL=y + +# +# USB Imaging devices +# +# CONFIG_USB_MDC800 is not set +# CONFIG_USB_MICROTEK is not set + +# +# USB port drivers +# +# 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_SEVSEG=m +# 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_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 is not set +CONFIG_USB_ISIGHTFW=m +CONFIG_USB_VST=m +# CONFIG_USB_GADGET is not set + +# +# OTG and related infrastructure +# +# CONFIG_NOP_USB_XCEIV is not set +# CONFIG_UWB is not set +# CONFIG_MMC is not set +# CONFIG_MEMSTICK is not set +# CONFIG_NEW_LEDS is not set +# CONFIG_ACCESSIBILITY is not set +# CONFIG_INFINIBAND 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 is not set +# 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 +# CONFIG_RTC_DRV_S35390A is not set +# CONFIG_RTC_DRV_FM3130 is not set +# CONFIG_RTC_DRV_RX8581 is not set +# CONFIG_RTC_DRV_RX8025 is not set + +# +# SPI RTC drivers +# + +# +# Platform RTC drivers +# +CONFIG_RTC_DRV_CMOS=y +# CONFIG_RTC_DRV_DS1286 is not set +# CONFIG_RTC_DRV_DS1511 is not set +# CONFIG_RTC_DRV_DS1553 is not set +# CONFIG_RTC_DRV_DS1742 is not set +# CONFIG_RTC_DRV_STK17TA8 is not set +# CONFIG_RTC_DRV_M48T86 is not set +# CONFIG_RTC_DRV_M48T35 is not set +# CONFIG_RTC_DRV_M48T59 is not set +# CONFIG_RTC_DRV_BQ4802 is not set +# CONFIG_RTC_DRV_V3020 is not set + +# +# on-CPU RTC drivers +# +# CONFIG_DMADEVICES is not set +# CONFIG_AUXDISPLAY is not set +CONFIG_UIO=m +CONFIG_UIO_CIF=m +# CONFIG_UIO_PDRV is not set +# CONFIG_UIO_PDRV_GENIRQ is not set +# CONFIG_UIO_SMX is not set +# CONFIG_UIO_AEC is not set +# CONFIG_UIO_SERCOS3 is not set + +# +# TI VLYNQ +# +# CONFIG_STAGING is not set + +# +# File systems +# +CONFIG_EXT2_FS=y +# CONFIG_EXT2_FS_XATTR is not set +CONFIG_EXT2_FS_XIP=y +CONFIG_EXT3_FS=y +# CONFIG_EXT3_DEFAULTS_TO_ORDERED is not set +# CONFIG_EXT3_FS_XATTR is not set +CONFIG_EXT4_FS=m +CONFIG_EXT4DEV_COMPAT=y +CONFIG_EXT4_FS_XATTR=y +CONFIG_EXT4_FS_POSIX_ACL=y +CONFIG_EXT4_FS_SECURITY=y +CONFIG_FS_XIP=y +CONFIG_JBD=y +# CONFIG_JBD_DEBUG is not set +CONFIG_JBD2=m +# CONFIG_JBD2_DEBUG is not set +CONFIG_FS_MBCACHE=m +CONFIG_REISERFS_FS=m +# CONFIG_REISERFS_CHECK is not set +# CONFIG_REISERFS_PROC_INFO is not set +# CONFIG_REISERFS_FS_XATTR is not set +# CONFIG_JFS_FS is not set +CONFIG_FS_POSIX_ACL=y +# CONFIG_XFS_FS is not set +# CONFIG_GFS2_FS is not set +# CONFIG_OCFS2_FS is not set +# CONFIG_BTRFS_FS is not set +CONFIG_FILE_LOCKING=y +CONFIG_FSNOTIFY=y +CONFIG_DNOTIFY=y +CONFIG_INOTIFY=y +CONFIG_INOTIFY_USER=y +# CONFIG_QUOTA is not set +CONFIG_AUTOFS_FS=y +CONFIG_AUTOFS4_FS=y +CONFIG_FUSE_FS=y +# CONFIG_CUSE is not set + +# +# Caches +# +# CONFIG_FSCACHE is not set + +# +# CD-ROM/DVD Filesystems +# +CONFIG_ISO9660_FS=m +CONFIG_JOLIET=y +CONFIG_ZISOFS=y +CONFIG_UDF_FS=m +CONFIG_UDF_NLS=y + +# +# DOS/FAT/NT Filesystems +# +CONFIG_FAT_FS=m +CONFIG_MSDOS_FS=m +CONFIG_VFAT_FS=m +CONFIG_FAT_DEFAULT_CODEPAGE=936 +CONFIG_FAT_DEFAULT_IOCHARSET="utf8" +CONFIG_NTFS_FS=m +# CONFIG_NTFS_DEBUG is not set +CONFIG_NTFS_RW=y + +# +# Pseudo filesystems +# +CONFIG_PROC_FS=y +CONFIG_PROC_KCORE=y +CONFIG_PROC_SYSCTL=y +CONFIG_PROC_PAGE_MONITOR=y +CONFIG_SYSFS=y +CONFIG_TMPFS=y +# CONFIG_TMPFS_POSIX_ACL is not set +# CONFIG_HUGETLB_PAGE is not set +# CONFIG_CONFIGFS_FS is not set +CONFIG_MISC_FILESYSTEMS=y +# 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_JFFS2_FS is not set +# CONFIG_CRAMFS is not set +# CONFIG_SQUASHFS is not set +# CONFIG_VXFS_FS is not set +# CONFIG_MINIX_FS is not set +CONFIG_OMFS_FS=m +# CONFIG_HPFS_FS is not set +# CONFIG_QNX4FS_FS is not set +# CONFIG_ROMFS_FS is not set +# CONFIG_SYSV_FS is not set +# CONFIG_UFS_FS is not set +# CONFIG_NILFS2_FS is not set +CONFIG_NETWORK_FILESYSTEMS=y +CONFIG_NFS_FS=m +CONFIG_NFS_V3=y +CONFIG_NFS_V3_ACL=y +CONFIG_NFS_V4=y +# CONFIG_NFS_V4_1 is not set +CONFIG_NFSD=m +CONFIG_NFSD_V2_ACL=y +CONFIG_NFSD_V3=y +CONFIG_NFSD_V3_ACL=y +CONFIG_NFSD_V4=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_GSS=m +CONFIG_RPCSEC_GSS_KRB5=m +# CONFIG_RPCSEC_GSS_SPKM3 is not set +CONFIG_SMB_FS=m +CONFIG_SMB_NLS_DEFAULT=y +CONFIG_SMB_NLS_REMOTE="cp936" +CONFIG_CIFS=m +CONFIG_CIFS_STATS=y +CONFIG_CIFS_STATS2=y +CONFIG_CIFS_WEAK_PW_HASH=y +CONFIG_CIFS_XATTR=y +CONFIG_CIFS_POSIX=y +CONFIG_CIFS_DEBUG2=y +CONFIG_CIFS_EXPERIMENTAL=y +# CONFIG_NCP_FS is not set +# CONFIG_CODA_FS is not set +# CONFIG_AFS_FS is not set +# CONFIG_9P_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 is not set +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 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 is not set +# CONFIG_SYSV68_PARTITION is not set +CONFIG_NLS=y +CONFIG_NLS_DEFAULT="utf8" +# CONFIG_NLS_CODEPAGE_437 is not set +# 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=y +# 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_DLM is not set + +# +# Kernel hacking +# +CONFIG_TRACE_IRQFLAGS_SUPPORT=y +# CONFIG_PRINTK_TIME is not set +CONFIG_ENABLE_WARN_DEPRECATED=y +# CONFIG_ENABLE_MUST_CHECK is not set +CONFIG_FRAME_WARN=2048 +# CONFIG_MAGIC_SYSRQ is not set +# CONFIG_UNUSED_SYMBOLS is not set +CONFIG_DEBUG_FS=y +# CONFIG_HEADERS_CHECK is not set +# CONFIG_DEBUG_KERNEL is not set +CONFIG_STACKTRACE=y +# CONFIG_DEBUG_MEMORY_INIT is not set +# CONFIG_RCU_CPU_STALL_DETECTOR is not set +CONFIG_SYSCTL_SYSCALL_CHECK=y +CONFIG_NOP_TRACER=y +CONFIG_RING_BUFFER=y +CONFIG_EVENT_TRACING=y +CONFIG_CONTEXT_SWITCH_TRACER=y +CONFIG_TRACING=y +CONFIG_TRACING_SUPPORT=y +# CONFIG_FTRACE is not set +# CONFIG_DYNAMIC_DEBUG is not set +# CONFIG_SAMPLES is not set +CONFIG_HAVE_ARCH_KGDB=y +CONFIG_CMDLINE="" + +# +# Security options +# +# CONFIG_KEYS is not set +# CONFIG_SECURITY is not set +# CONFIG_SECURITYFS is not set +CONFIG_SECURITY_FILE_CAPABILITIES=y +CONFIG_CRYPTO=y + +# +# Crypto core or helper +# +CONFIG_CRYPTO_FIPS=y +CONFIG_CRYPTO_ALGAPI=y +CONFIG_CRYPTO_ALGAPI2=y +CONFIG_CRYPTO_AEAD=m +CONFIG_CRYPTO_AEAD2=y +CONFIG_CRYPTO_BLKCIPHER=m +CONFIG_CRYPTO_BLKCIPHER2=y +CONFIG_CRYPTO_HASH=y +CONFIG_CRYPTO_HASH2=y +CONFIG_CRYPTO_RNG=m +CONFIG_CRYPTO_RNG2=y +CONFIG_CRYPTO_PCOMP=y +CONFIG_CRYPTO_MANAGER=y +CONFIG_CRYPTO_MANAGER2=y +CONFIG_CRYPTO_GF128MUL=m +# CONFIG_CRYPTO_NULL is not set +CONFIG_CRYPTO_WORKQUEUE=y +# CONFIG_CRYPTO_CRYPTD is not set +CONFIG_CRYPTO_AUTHENC=m +# CONFIG_CRYPTO_TEST is not set + +# +# Authenticated Encryption with Associated Data +# +CONFIG_CRYPTO_CCM=m +CONFIG_CRYPTO_GCM=m +CONFIG_CRYPTO_SEQIV=m + +# +# Block modes +# +CONFIG_CRYPTO_CBC=m +CONFIG_CRYPTO_CTR=m +CONFIG_CRYPTO_CTS=m +CONFIG_CRYPTO_ECB=m +# CONFIG_CRYPTO_LRW is not set +CONFIG_CRYPTO_PCBC=m +CONFIG_CRYPTO_XTS=m + +# +# Hash modes +# +CONFIG_CRYPTO_HMAC=y +# CONFIG_CRYPTO_XCBC is not set + +# +# Digest +# +# CONFIG_CRYPTO_CRC32C is not set +# CONFIG_CRYPTO_MD4 is not set +CONFIG_CRYPTO_MD5=m +# CONFIG_CRYPTO_MICHAEL_MIC is not set +CONFIG_CRYPTO_RMD128=m +CONFIG_CRYPTO_RMD160=m +CONFIG_CRYPTO_RMD256=m +CONFIG_CRYPTO_RMD320=m +CONFIG_CRYPTO_SHA1=m +# CONFIG_CRYPTO_SHA256 is not set +# CONFIG_CRYPTO_SHA512 is not set +# CONFIG_CRYPTO_TGR192 is not set +# CONFIG_CRYPTO_WP512 is not set + +# +# Ciphers +# +CONFIG_CRYPTO_AES=m +# CONFIG_CRYPTO_ANUBIS is not set +CONFIG_CRYPTO_ARC4=m +# CONFIG_CRYPTO_BLOWFISH is not set +# CONFIG_CRYPTO_CAMELLIA is not set +# CONFIG_CRYPTO_CAST5 is not set +# CONFIG_CRYPTO_CAST6 is not set +CONFIG_CRYPTO_DES=m +# CONFIG_CRYPTO_FCRYPT is not set +# CONFIG_CRYPTO_KHAZAD is not set +CONFIG_CRYPTO_SALSA20=m +CONFIG_CRYPTO_SEED=m +# CONFIG_CRYPTO_SERPENT is not set +# CONFIG_CRYPTO_TEA is not set +# CONFIG_CRYPTO_TWOFISH is not set + +# +# Compression +# +CONFIG_CRYPTO_DEFLATE=m +# CONFIG_CRYPTO_ZLIB is not set +CONFIG_CRYPTO_LZO=m + +# +# Random Number Generation +# +CONFIG_CRYPTO_ANSI_CPRNG=m +# CONFIG_CRYPTO_HW is not set +CONFIG_BINARY_PRINTF=y + +# +# Library routines +# +CONFIG_BITREVERSE=y +CONFIG_GENERIC_FIND_LAST_BIT=y +CONFIG_CRC_CCITT=y +CONFIG_CRC16=m +# CONFIG_CRC_T10DIF is not set +CONFIG_CRC_ITU_T=m +CONFIG_CRC32=y +CONFIG_CRC7=m +# CONFIG_LIBCRC32C is not set +CONFIG_ZLIB_INFLATE=m +CONFIG_ZLIB_DEFLATE=m +CONFIG_LZO_COMPRESS=m +CONFIG_LZO_DECOMPRESS=m +CONFIG_TEXTSEARCH=y +CONFIG_TEXTSEARCH_KMP=m +CONFIG_TEXTSEARCH_BM=m +CONFIG_TEXTSEARCH_FSM=m +CONFIG_HAS_IOMEM=y +CONFIG_HAS_IOPORT=y +CONFIG_HAS_DMA=y +CONFIG_NLATTR=y diff -Nur linux-2.6.30.5.orig/arch/mips/configs/fuloong2f_defconfig linux-2.6.30.5/arch/mips/configs/fuloong2f_defconfig --- linux-2.6.30.5.orig/arch/mips/configs/fuloong2f_defconfig 1970-01-01 01:00:00.000000000 +0100 +++ linux-2.6.30.5/arch/mips/configs/fuloong2f_defconfig 2009-08-23 19:01:04.000000000 +0200 @@ -0,0 +1,2637 @@ +# +# Automatically generated make config: don't edit +# Linux kernel version: 2.6.30-rc8 +# Wed Jun 10 22:20:53 2009 +# +CONFIG_MIPS=y + +# +# Machine selection +# +# CONFIG_MACH_ALCHEMY is not set +# CONFIG_BASLER_EXCITE is not set +# CONFIG_BCM47XX is not set +# CONFIG_MIPS_COBALT is not set +# CONFIG_MACH_DECSTATION is not set +# CONFIG_MACH_JAZZ is not set +# CONFIG_LASAT is not set +CONFIG_MACH_LOONGSON=y +# CONFIG_MIPS_MALTA is not set +# CONFIG_MIPS_SIM is not set +# CONFIG_NEC_MARKEINS is not set +# CONFIG_MACH_VR41XX is not set +# CONFIG_NXP_STB220 is not set +# CONFIG_NXP_STB225 is not set +# CONFIG_PNX8550_JBS is not set +# CONFIG_PNX8550_STB810 is not set +# CONFIG_PMC_MSP is not set +# CONFIG_PMC_YOSEMITE is not set +# CONFIG_SGI_IP22 is not set +# CONFIG_SGI_IP27 is not set +# CONFIG_SGI_IP28 is not set +# CONFIG_SGI_IP32 is not set +# CONFIG_SIBYTE_CRHINE is not set +# CONFIG_SIBYTE_CARMEL is not set +# CONFIG_SIBYTE_CRHONE is not set +# CONFIG_SIBYTE_RHONE is not set +# CONFIG_SIBYTE_SWARM is not set +# CONFIG_SIBYTE_LITTLESUR is not set +# CONFIG_SIBYTE_SENTOSA is not set +# CONFIG_SIBYTE_BIGSUR is not set +# CONFIG_SNI_RM is not set +# CONFIG_MACH_TX39XX is not set +# CONFIG_MACH_TX49XX is not set +# CONFIG_MIKROTIK_RB532 is not set +# CONFIG_WR_PPMC is not set +# CONFIG_CAVIUM_OCTEON_SIMULATOR is not set +# CONFIG_CAVIUM_OCTEON_REFERENCE_BOARD is not set +CONFIG_ARCH_SPARSEMEM_ENABLE=y +# CONFIG_LEMOTE_FULOONG2E is not set +CONFIG_LEMOTE_FULOONG2F=y +# CONFIG_LEMOTE_YEELOONG2F is not set +CONFIG_CS5536=y +CONFIG_CS5536_MFGPT=y +CONFIG_UCA_SIZE=0x2000000 +CONFIG_RWSEM_GENERIC_SPINLOCK=y +# CONFIG_ARCH_HAS_ILOG2_U32 is not set +# CONFIG_ARCH_HAS_ILOG2_U64 is not set +CONFIG_ARCH_SUPPORTS_OPROFILE=y +CONFIG_GENERIC_FIND_NEXT_BIT=y +CONFIG_GENERIC_HWEIGHT=y +CONFIG_GENERIC_CALIBRATE_DELAY=y +CONFIG_GENERIC_CLOCKEVENTS=y +CONFIG_GENERIC_TIME=y +CONFIG_GENERIC_CMOS_UPDATE=y +CONFIG_SCHED_OMIT_FRAME_POINTER=y +CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y +CONFIG_DMA_NONCOHERENT=y +CONFIG_DMA_NEED_PCI_MAP_STATE=y +CONFIG_EARLY_PRINTK=y +CONFIG_SYS_HAS_EARLY_PRINTK=y +# CONFIG_HOTPLUG_CPU is not set +CONFIG_I8259=y +# CONFIG_NO_IOPORT is not set +CONFIG_GENERIC_ISA_DMA=y +CONFIG_GENERIC_ISA_DMA_SUPPORT_BROKEN=y +# CONFIG_CPU_BIG_ENDIAN is not set +CONFIG_CPU_LITTLE_ENDIAN=y +CONFIG_SYS_SUPPORTS_LITTLE_ENDIAN=y +CONFIG_IRQ_CPU=y +CONFIG_BOOT_ELF32=y +CONFIG_MIPS_L1_CACHE_SHIFT=5 + +# +# CPU selection +# +# CONFIG_CPU_LOONGSON2E is not set +CONFIG_CPU_LOONGSON2F=y +# CONFIG_CPU_MIPS32_R1 is not set +# CONFIG_CPU_MIPS32_R2 is not set +# CONFIG_CPU_MIPS64_R1 is not set +# CONFIG_CPU_MIPS64_R2 is not set +# CONFIG_CPU_R3000 is not set +# CONFIG_CPU_TX39XX is not set +# CONFIG_CPU_VR41XX is not set +# CONFIG_CPU_R4300 is not set +# CONFIG_CPU_R4X00 is not set +# CONFIG_CPU_TX49XX is not set +# CONFIG_CPU_R5000 is not set +# CONFIG_CPU_R5432 is not set +# CONFIG_CPU_R5500 is not set +# CONFIG_CPU_R6000 is not set +# CONFIG_CPU_NEVADA is not set +# CONFIG_CPU_R8000 is not set +# CONFIG_CPU_R10000 is not set +# CONFIG_CPU_RM7000 is not set +# CONFIG_CPU_RM9000 is not set +# CONFIG_CPU_SB1 is not set +# CONFIG_CPU_CAVIUM_OCTEON is not set +CONFIG_CPU_LOONGSON2=y +CONFIG_SYS_HAS_CPU_LOONGSON2F=y +CONFIG_SYS_SUPPORTS_32BIT_KERNEL=y +CONFIG_SYS_SUPPORTS_64BIT_KERNEL=y +CONFIG_CPU_SUPPORTS_32BIT_KERNEL=y +CONFIG_CPU_SUPPORTS_64BIT_KERNEL=y + +# +# Kernel type +# +# CONFIG_32BIT is not set +CONFIG_64BIT=y +# CONFIG_PAGE_SIZE_4KB is not set +# CONFIG_PAGE_SIZE_8KB is not set +CONFIG_PAGE_SIZE_16KB=y +# CONFIG_PAGE_SIZE_32KB is not set +# CONFIG_PAGE_SIZE_64KB is not set +CONFIG_BOARD_SCACHE=y +CONFIG_MIPS_MT_DISABLED=y +# CONFIG_MIPS_MT_SMP is not set +# CONFIG_MIPS_MT_SMTC is not set +CONFIG_CPU_HAS_WB=y +CONFIG_CPU_HAS_SYNC=y +CONFIG_GENERIC_HARDIRQS=y +CONFIG_GENERIC_IRQ_PROBE=y +CONFIG_CPU_SUPPORTS_HIGHMEM=y +CONFIG_SYS_SUPPORTS_HIGHMEM=y +CONFIG_ARCH_FLATMEM_ENABLE=y +CONFIG_ARCH_POPULATES_NODE_MAP=y +CONFIG_SELECT_MEMORY_MODEL=y +# CONFIG_FLATMEM_MANUAL is not set +# CONFIG_DISCONTIGMEM_MANUAL is not set +CONFIG_SPARSEMEM_MANUAL=y +CONFIG_SPARSEMEM=y +CONFIG_HAVE_MEMORY_PRESENT=y +CONFIG_SPARSEMEM_STATIC=y + +# +# Memory hotplug is currently incompatible with Software Suspend +# +CONFIG_PAGEFLAGS_EXTENDED=y +CONFIG_SPLIT_PTLOCK_CPUS=4 +CONFIG_PHYS_ADDR_T_64BIT=y +CONFIG_ZONE_DMA_FLAG=0 +CONFIG_VIRT_TO_BUS=y +CONFIG_UNEVICTABLE_LRU=y +CONFIG_HAVE_MLOCK=y +CONFIG_HAVE_MLOCKED_PAGE_BIT=y +CONFIG_TICK_ONESHOT=y +CONFIG_NO_HZ=y +CONFIG_HIGH_RES_TIMERS=y +CONFIG_GENERIC_CLOCKEVENTS_BUILD=y +# CONFIG_HZ_48 is not set +# CONFIG_HZ_100 is not set +# CONFIG_HZ_128 is not set +CONFIG_HZ_250=y +# CONFIG_HZ_256 is not set +# CONFIG_HZ_1000 is not set +# CONFIG_HZ_1024 is not set +CONFIG_SYS_SUPPORTS_ARBIT_HZ=y +CONFIG_HZ=250 +# CONFIG_PREEMPT_NONE is not set +CONFIG_PREEMPT_VOLUNTARY=y +# CONFIG_PREEMPT is not set +CONFIG_KEXEC=y +# CONFIG_SECCOMP is not set +CONFIG_LOCKDEP_SUPPORT=y +CONFIG_STACKTRACE_SUPPORT=y +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 is not set +CONFIG_SWAP=y +CONFIG_SYSVIPC=y +CONFIG_SYSVIPC_SYSCTL=y +CONFIG_POSIX_MQUEUE=y +CONFIG_POSIX_MQUEUE_SYSCTL=y +CONFIG_BSD_PROCESS_ACCT=y +CONFIG_BSD_PROCESS_ACCT_V3=y +# CONFIG_TASKSTATS is not set +CONFIG_AUDIT=y + +# +# RCU Subsystem +# +CONFIG_CLASSIC_RCU=y +# CONFIG_TREE_RCU is not set +# CONFIG_PREEMPT_RCU is not set +# CONFIG_TREE_RCU_TRACE is not set +# CONFIG_PREEMPT_RCU_TRACE is not set +CONFIG_IKCONFIG=y +CONFIG_IKCONFIG_PROC=y +CONFIG_LOG_BUF_SHIFT=15 +# CONFIG_GROUP_SCHED is not set +# CONFIG_CGROUPS is not set +CONFIG_SYSFS_DEPRECATED=y +CONFIG_SYSFS_DEPRECATED_V2=y +# CONFIG_RELAY is not set +# CONFIG_NAMESPACES is not set +CONFIG_BLK_DEV_INITRD=y +CONFIG_INITRAMFS_SOURCE="" +CONFIG_RD_GZIP=y +# CONFIG_RD_BZIP2 is not set +# CONFIG_RD_LZMA is not set +CONFIG_CC_OPTIMIZE_FOR_SIZE=y +CONFIG_SYSCTL=y +CONFIG_ANON_INODES=y +CONFIG_EMBEDDED=y +CONFIG_SYSCTL_SYSCALL=y +CONFIG_KALLSYMS=y +# CONFIG_KALLSYMS_EXTRA_PASS is not set +# CONFIG_STRIP_ASM_SYMS is not set +CONFIG_HOTPLUG=y +CONFIG_PRINTK=y +CONFIG_BUG=y +CONFIG_ELF_CORE=y +CONFIG_PCSPKR_PLATFORM=y +CONFIG_BASE_FULL=y +CONFIG_FUTEX=y +CONFIG_EPOLL=y +CONFIG_SIGNALFD=y +CONFIG_TIMERFD=y +CONFIG_EVENTFD=y +CONFIG_SHMEM=y +CONFIG_AIO=y +CONFIG_VM_EVENT_COUNTERS=y +CONFIG_PCI_QUIRKS=y +CONFIG_COMPAT_BRK=y +CONFIG_SLAB=y +# CONFIG_SLUB is not set +# CONFIG_SLOB is not set +CONFIG_PROFILING=y +# CONFIG_MARKERS is not set +# CONFIG_OPROFILE is not set +CONFIG_HAVE_OPROFILE=y +CONFIG_HAVE_SYSCALL_WRAPPERS=y +# CONFIG_SLOW_WORK is not set +# CONFIG_HAVE_GENERIC_DMA_COHERENT is not set +CONFIG_SLABINFO=y +CONFIG_RT_MUTEXES=y +CONFIG_BASE_SMALL=0 +CONFIG_MODULES=y +# CONFIG_MODULE_FORCE_LOAD is not set +CONFIG_MODULE_UNLOAD=y +CONFIG_MODULE_FORCE_UNLOAD=y +CONFIG_MODVERSIONS=y +# CONFIG_MODULE_SRCVERSION_ALL is not set +CONFIG_BLOCK=y +# CONFIG_BLK_DEV_BSG is not set +# CONFIG_BLK_DEV_INTEGRITY is not set +CONFIG_BLOCK_COMPAT=y + +# +# IO Schedulers +# +CONFIG_IOSCHED_NOOP=y +CONFIG_IOSCHED_AS=y +CONFIG_IOSCHED_DEADLINE=y +CONFIG_IOSCHED_CFQ=y +# CONFIG_DEFAULT_AS is not set +# CONFIG_DEFAULT_DEADLINE is not set +CONFIG_DEFAULT_CFQ=y +# CONFIG_DEFAULT_NOOP is not set +CONFIG_DEFAULT_IOSCHED="cfq" +# CONFIG_PROBE_INITRD_HEADER is not set +CONFIG_FREEZER=y + +# +# Bus options (PCI, PCMCIA, EISA, ISA, TC) +# +CONFIG_HW_HAS_PCI=y +CONFIG_PCI=y +CONFIG_PCI_DOMAINS=y +# CONFIG_ARCH_SUPPORTS_MSI is not set +CONFIG_PCI_LEGACY=y +# CONFIG_PCI_STUB is not set +# CONFIG_PCI_IOV is not set +CONFIG_ISA=y +CONFIG_MMU=y +CONFIG_PCCARD=m +# CONFIG_PCMCIA_DEBUG is not set +CONFIG_PCMCIA=m +CONFIG_PCMCIA_LOAD_CIS=y +CONFIG_PCMCIA_IOCTL=y +CONFIG_CARDBUS=y + +# +# PC-card bridges +# +CONFIG_YENTA=m +CONFIG_YENTA_O2=y +CONFIG_YENTA_RICOH=y +CONFIG_YENTA_TI=y +CONFIG_YENTA_ENE_TUNE=y +CONFIG_YENTA_TOSHIBA=y +CONFIG_PD6729=m +CONFIG_I82092=m +CONFIG_I82365=m +CONFIG_TCIC=m +CONFIG_PCMCIA_PROBE=y +CONFIG_PCCARD_NONSTATIC=m +CONFIG_HOTPLUG_PCI=m +CONFIG_HOTPLUG_PCI_FAKE=m +CONFIG_HOTPLUG_PCI_CPCI=y +CONFIG_HOTPLUG_PCI_SHPC=m + +# +# Executable file formats +# +CONFIG_BINFMT_ELF=y +# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set +# CONFIG_HAVE_AOUT is not set +CONFIG_BINFMT_MISC=m +CONFIG_MIPS32_COMPAT=y +CONFIG_COMPAT=y +CONFIG_SYSVIPC_COMPAT=y +CONFIG_MIPS32_O32=y +CONFIG_MIPS32_N32=y +CONFIG_BINFMT_ELF32=y + +# +# Power management options +# +CONFIG_ARCH_HIBERNATION_POSSIBLE=y +CONFIG_ARCH_SUSPEND_POSSIBLE=y +CONFIG_PM=y +# CONFIG_PM_DEBUG is not set +CONFIG_PM_SLEEP=y +CONFIG_SUSPEND=y +CONFIG_SUSPEND_FREEZER=y +CONFIG_HIBERNATION=y +CONFIG_PM_STD_PARTITION="/dev/hda3" + +# +# CPU Frequency scaling +# +CONFIG_CPU_FREQ=y +CONFIG_CPU_FREQ_TABLE=y +# CONFIG_CPU_FREQ_DEBUG is not set +CONFIG_CPU_FREQ_STAT=y +# CONFIG_CPU_FREQ_STAT_DETAILS is not set +# CONFIG_CPU_FREQ_DEFAULT_GOV_PERFORMANCE is not set +# CONFIG_CPU_FREQ_DEFAULT_GOV_POWERSAVE is not set +# CONFIG_CPU_FREQ_DEFAULT_GOV_USERSPACE is not set +# CONFIG_CPU_FREQ_DEFAULT_GOV_ONDEMAND is not set +CONFIG_CPU_FREQ_DEFAULT_GOV_CONSERVATIVE=y +CONFIG_CPU_FREQ_GOV_PERFORMANCE=y +CONFIG_CPU_FREQ_GOV_POWERSAVE=y +CONFIG_CPU_FREQ_GOV_USERSPACE=y +CONFIG_CPU_FREQ_GOV_ONDEMAND=y +CONFIG_CPU_FREQ_GOV_CONSERVATIVE=y +CONFIG_LOONGSON2F_CPU_FREQ=y +CONFIG_NET=y + +# +# Networking options +# +CONFIG_PACKET=y +CONFIG_PACKET_MMAP=y +CONFIG_UNIX=y +CONFIG_XFRM=y +CONFIG_XFRM_USER=m +# CONFIG_XFRM_SUB_POLICY is not set +# CONFIG_XFRM_MIGRATE is not set +# CONFIG_XFRM_STATISTICS is not set +CONFIG_XFRM_IPCOMP=m +CONFIG_NET_KEY=m +# CONFIG_NET_KEY_MIGRATE is not set +CONFIG_INET=y +CONFIG_IP_MULTICAST=y +CONFIG_IP_ADVANCED_ROUTER=y +CONFIG_ASK_IP_FIB_HASH=y +# CONFIG_IP_FIB_TRIE is not set +CONFIG_IP_FIB_HASH=y +CONFIG_IP_MULTIPLE_TABLES=y +CONFIG_IP_ROUTE_MULTIPATH=y +CONFIG_IP_ROUTE_VERBOSE=y +# CONFIG_IP_PNP is not set +CONFIG_NET_IPIP=m +CONFIG_NET_IPGRE=m +CONFIG_NET_IPGRE_BROADCAST=y +CONFIG_IP_MROUTE=y +CONFIG_IP_PIMSM_V1=y +CONFIG_IP_PIMSM_V2=y +# CONFIG_ARPD is not set +CONFIG_SYN_COOKIES=y +CONFIG_INET_AH=m +CONFIG_INET_ESP=m +CONFIG_INET_IPCOMP=m +CONFIG_INET_XFRM_TUNNEL=m +CONFIG_INET_TUNNEL=m +CONFIG_INET_XFRM_MODE_TRANSPORT=m +CONFIG_INET_XFRM_MODE_TUNNEL=m +CONFIG_INET_XFRM_MODE_BEET=y +CONFIG_INET_LRO=y +CONFIG_INET_DIAG=m +CONFIG_INET_TCP_DIAG=m +CONFIG_TCP_CONG_ADVANCED=y +CONFIG_TCP_CONG_BIC=y +CONFIG_TCP_CONG_CUBIC=m +CONFIG_TCP_CONG_WESTWOOD=m +CONFIG_TCP_CONG_HTCP=m +CONFIG_TCP_CONG_HSTCP=m +CONFIG_TCP_CONG_HYBLA=m +CONFIG_TCP_CONG_VEGAS=m +CONFIG_TCP_CONG_SCALABLE=m +CONFIG_TCP_CONG_LP=m +CONFIG_TCP_CONG_VENO=m +# CONFIG_TCP_CONG_YEAH is not set +# CONFIG_TCP_CONG_ILLINOIS is not set +CONFIG_DEFAULT_BIC=y +# CONFIG_DEFAULT_CUBIC is not set +# CONFIG_DEFAULT_HTCP is not set +# CONFIG_DEFAULT_VEGAS is not set +# CONFIG_DEFAULT_WESTWOOD is not set +# CONFIG_DEFAULT_RENO is not set +CONFIG_DEFAULT_TCP_CONG="bic" +# CONFIG_TCP_MD5SIG is not set +CONFIG_IPV6=m +CONFIG_IPV6_PRIVACY=y +# CONFIG_IPV6_ROUTER_PREF is not set +# CONFIG_IPV6_OPTIMISTIC_DAD is not set +CONFIG_INET6_AH=m +CONFIG_INET6_ESP=m +CONFIG_INET6_IPCOMP=m +# CONFIG_IPV6_MIP6 is not set +CONFIG_INET6_XFRM_TUNNEL=m +CONFIG_INET6_TUNNEL=m +CONFIG_INET6_XFRM_MODE_TRANSPORT=m +CONFIG_INET6_XFRM_MODE_TUNNEL=m +CONFIG_INET6_XFRM_MODE_BEET=m +# CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION is not set +CONFIG_IPV6_SIT=m +CONFIG_IPV6_NDISC_NODETYPE=y +CONFIG_IPV6_TUNNEL=m +# CONFIG_IPV6_MULTIPLE_TABLES is not set +# CONFIG_IPV6_MROUTE is not set +# CONFIG_NETLABEL is not set +CONFIG_NETWORK_SECMARK=y +CONFIG_NETFILTER=y +# CONFIG_NETFILTER_DEBUG is not set +CONFIG_NETFILTER_ADVANCED=y +CONFIG_BRIDGE_NETFILTER=y + +# +# Core Netfilter Configuration +# +CONFIG_NETFILTER_NETLINK=m +CONFIG_NETFILTER_NETLINK_QUEUE=m +CONFIG_NETFILTER_NETLINK_LOG=m +# CONFIG_NF_CONNTRACK is not set +# CONFIG_NETFILTER_TPROXY is not set +CONFIG_NETFILTER_XTABLES=m +CONFIG_NETFILTER_XT_TARGET_CLASSIFY=m +# CONFIG_NETFILTER_XT_TARGET_DSCP is not set +CONFIG_NETFILTER_XT_TARGET_HL=m +CONFIG_NETFILTER_XT_TARGET_MARK=m +# CONFIG_NETFILTER_XT_TARGET_NFLOG is not set +CONFIG_NETFILTER_XT_TARGET_NFQUEUE=m +# CONFIG_NETFILTER_XT_TARGET_RATEEST is not set +# CONFIG_NETFILTER_XT_TARGET_TRACE is not set +CONFIG_NETFILTER_XT_TARGET_SECMARK=m +# CONFIG_NETFILTER_XT_TARGET_TCPMSS is not set +# CONFIG_NETFILTER_XT_TARGET_TCPOPTSTRIP is not set +CONFIG_NETFILTER_XT_MATCH_COMMENT=m +CONFIG_NETFILTER_XT_MATCH_DCCP=m +# CONFIG_NETFILTER_XT_MATCH_DSCP is not set +CONFIG_NETFILTER_XT_MATCH_ESP=m +# CONFIG_NETFILTER_XT_MATCH_HASHLIMIT is not set +CONFIG_NETFILTER_XT_MATCH_HL=m +# CONFIG_NETFILTER_XT_MATCH_IPRANGE is not set +CONFIG_NETFILTER_XT_MATCH_LENGTH=m +CONFIG_NETFILTER_XT_MATCH_LIMIT=m +CONFIG_NETFILTER_XT_MATCH_MAC=m +CONFIG_NETFILTER_XT_MATCH_MARK=m +CONFIG_NETFILTER_XT_MATCH_MULTIPORT=m +# CONFIG_NETFILTER_XT_MATCH_OWNER is not set +CONFIG_NETFILTER_XT_MATCH_POLICY=m +CONFIG_NETFILTER_XT_MATCH_PHYSDEV=m +CONFIG_NETFILTER_XT_MATCH_PKTTYPE=m +CONFIG_NETFILTER_XT_MATCH_QUOTA=m +# CONFIG_NETFILTER_XT_MATCH_RATEEST is not set +CONFIG_NETFILTER_XT_MATCH_REALM=m +# CONFIG_NETFILTER_XT_MATCH_RECENT is not set +CONFIG_NETFILTER_XT_MATCH_SCTP=m +CONFIG_NETFILTER_XT_MATCH_STATISTIC=m +CONFIG_NETFILTER_XT_MATCH_STRING=m +CONFIG_NETFILTER_XT_MATCH_TCPMSS=m +# CONFIG_NETFILTER_XT_MATCH_TIME is not set +# CONFIG_NETFILTER_XT_MATCH_U32 is not set +CONFIG_IP_VS=m +# CONFIG_IP_VS_IPV6 is not set +# CONFIG_IP_VS_DEBUG is not set +CONFIG_IP_VS_TAB_BITS=12 + +# +# IPVS transport protocol load balancing support +# +CONFIG_IP_VS_PROTO_TCP=y +CONFIG_IP_VS_PROTO_UDP=y +CONFIG_IP_VS_PROTO_AH_ESP=y +CONFIG_IP_VS_PROTO_ESP=y +CONFIG_IP_VS_PROTO_AH=y + +# +# IPVS scheduler +# +CONFIG_IP_VS_RR=m +CONFIG_IP_VS_WRR=m +CONFIG_IP_VS_LC=m +CONFIG_IP_VS_WLC=m +CONFIG_IP_VS_LBLC=m +CONFIG_IP_VS_LBLCR=m +CONFIG_IP_VS_DH=m +CONFIG_IP_VS_SH=m +CONFIG_IP_VS_SED=m +CONFIG_IP_VS_NQ=m + +# +# IPVS application helper +# +CONFIG_IP_VS_FTP=m + +# +# IP: Netfilter Configuration +# +# CONFIG_NF_DEFRAG_IPV4 is not set +CONFIG_IP_NF_QUEUE=m +CONFIG_IP_NF_IPTABLES=m +CONFIG_IP_NF_MATCH_ADDRTYPE=m +CONFIG_IP_NF_MATCH_AH=m +CONFIG_IP_NF_MATCH_ECN=m +CONFIG_IP_NF_MATCH_TTL=m +CONFIG_IP_NF_FILTER=m +CONFIG_IP_NF_TARGET_REJECT=m +CONFIG_IP_NF_TARGET_LOG=m +CONFIG_IP_NF_TARGET_ULOG=m +CONFIG_IP_NF_MANGLE=m +CONFIG_IP_NF_TARGET_ECN=m +CONFIG_IP_NF_TARGET_TTL=m +CONFIG_IP_NF_RAW=m +# CONFIG_IP_NF_SECURITY is not set +CONFIG_IP_NF_ARPTABLES=m +CONFIG_IP_NF_ARPFILTER=m +CONFIG_IP_NF_ARP_MANGLE=m + +# +# IPv6: Netfilter Configuration +# +CONFIG_IP6_NF_QUEUE=m +CONFIG_IP6_NF_IPTABLES=m +CONFIG_IP6_NF_MATCH_AH=m +CONFIG_IP6_NF_MATCH_EUI64=m +CONFIG_IP6_NF_MATCH_FRAG=m +CONFIG_IP6_NF_MATCH_OPTS=m +CONFIG_IP6_NF_MATCH_HL=m +CONFIG_IP6_NF_MATCH_IPV6HEADER=m +# CONFIG_IP6_NF_MATCH_MH is not set +CONFIG_IP6_NF_MATCH_RT=m +CONFIG_IP6_NF_TARGET_HL=m +CONFIG_IP6_NF_TARGET_LOG=m +CONFIG_IP6_NF_FILTER=m +CONFIG_IP6_NF_TARGET_REJECT=m +CONFIG_IP6_NF_MANGLE=m +CONFIG_IP6_NF_RAW=m +# CONFIG_IP6_NF_SECURITY is not set + +# +# DECnet: Netfilter Configuration +# +CONFIG_DECNET_NF_GRABULATOR=m +CONFIG_BRIDGE_NF_EBTABLES=m +CONFIG_BRIDGE_EBT_BROUTE=m +CONFIG_BRIDGE_EBT_T_FILTER=m +CONFIG_BRIDGE_EBT_T_NAT=m +CONFIG_BRIDGE_EBT_802_3=m +CONFIG_BRIDGE_EBT_AMONG=m +CONFIG_BRIDGE_EBT_ARP=m +CONFIG_BRIDGE_EBT_IP=m +# CONFIG_BRIDGE_EBT_IP6 is not set +CONFIG_BRIDGE_EBT_LIMIT=m +CONFIG_BRIDGE_EBT_MARK=m +CONFIG_BRIDGE_EBT_PKTTYPE=m +CONFIG_BRIDGE_EBT_STP=m +CONFIG_BRIDGE_EBT_VLAN=m +CONFIG_BRIDGE_EBT_ARPREPLY=m +CONFIG_BRIDGE_EBT_DNAT=m +CONFIG_BRIDGE_EBT_MARK_T=m +CONFIG_BRIDGE_EBT_REDIRECT=m +CONFIG_BRIDGE_EBT_SNAT=m +CONFIG_BRIDGE_EBT_LOG=m +CONFIG_BRIDGE_EBT_ULOG=m +# CONFIG_BRIDGE_EBT_NFLOG is not set +CONFIG_IP_DCCP=m +CONFIG_INET_DCCP_DIAG=m + +# +# DCCP CCIDs Configuration (EXPERIMENTAL) +# +# CONFIG_IP_DCCP_CCID2_DEBUG is not set +CONFIG_IP_DCCP_CCID3=y +# CONFIG_IP_DCCP_CCID3_DEBUG is not set +CONFIG_IP_DCCP_CCID3_RTO=100 +CONFIG_IP_DCCP_TFRC_LIB=y +CONFIG_IP_SCTP=m +# CONFIG_SCTP_DBG_MSG is not set +# CONFIG_SCTP_DBG_OBJCNT is not set +# CONFIG_SCTP_HMAC_NONE is not set +# CONFIG_SCTP_HMAC_SHA1 is not set +CONFIG_SCTP_HMAC_MD5=y +CONFIG_TIPC=m +CONFIG_TIPC_ADVANCED=y +CONFIG_TIPC_ZONES=3 +CONFIG_TIPC_CLUSTERS=1 +CONFIG_TIPC_NODES=255 +CONFIG_TIPC_SLAVE_NODES=0 +CONFIG_TIPC_PORTS=8191 +CONFIG_TIPC_LOG=0 +# CONFIG_TIPC_DEBUG is not set +CONFIG_ATM=y +CONFIG_ATM_CLIP=y +# CONFIG_ATM_CLIP_NO_ICMP is not set +CONFIG_ATM_LANE=m +CONFIG_ATM_MPOA=m +CONFIG_ATM_BR2684=m +# CONFIG_ATM_BR2684_IPFILTER is not set +CONFIG_STP=m +CONFIG_BRIDGE=m +# CONFIG_NET_DSA is not set +CONFIG_VLAN_8021Q=m +# CONFIG_VLAN_8021Q_GVRP is not set +CONFIG_DECNET=m +# CONFIG_DECNET_ROUTER is not set +CONFIG_LLC=m +CONFIG_LLC2=m +CONFIG_IPX=m +# CONFIG_IPX_INTERN is not set +CONFIG_ATALK=m +CONFIG_DEV_APPLETALK=m +# CONFIG_COPS is not set +CONFIG_IPDDP=m +CONFIG_IPDDP_ENCAP=y +CONFIG_IPDDP_DECAP=y +CONFIG_X25=m +CONFIG_LAPB=m +CONFIG_ECONET=m +CONFIG_ECONET_AUNUDP=y +CONFIG_ECONET_NATIVE=y +CONFIG_WAN_ROUTER=m +# CONFIG_PHONET is not set +CONFIG_NET_SCHED=y + +# +# Queueing/Scheduling +# +CONFIG_NET_SCH_CBQ=m +CONFIG_NET_SCH_HTB=m +CONFIG_NET_SCH_HFSC=m +CONFIG_NET_SCH_ATM=m +CONFIG_NET_SCH_PRIO=m +# CONFIG_NET_SCH_MULTIQ is not set +CONFIG_NET_SCH_RED=m +CONFIG_NET_SCH_SFQ=m +CONFIG_NET_SCH_TEQL=m +CONFIG_NET_SCH_TBF=m +CONFIG_NET_SCH_GRED=m +CONFIG_NET_SCH_DSMARK=m +CONFIG_NET_SCH_NETEM=m +# CONFIG_NET_SCH_DRR is not set +CONFIG_NET_SCH_INGRESS=m + +# +# Classification +# +CONFIG_NET_CLS=y +CONFIG_NET_CLS_BASIC=m +CONFIG_NET_CLS_TCINDEX=m +CONFIG_NET_CLS_ROUTE4=m +CONFIG_NET_CLS_ROUTE=y +CONFIG_NET_CLS_FW=m +CONFIG_NET_CLS_U32=m +CONFIG_CLS_U32_PERF=y +CONFIG_CLS_U32_MARK=y +CONFIG_NET_CLS_RSVP=m +CONFIG_NET_CLS_RSVP6=m +# CONFIG_NET_CLS_FLOW is not set +CONFIG_NET_EMATCH=y +CONFIG_NET_EMATCH_STACK=32 +CONFIG_NET_EMATCH_CMP=m +CONFIG_NET_EMATCH_NBYTE=m +CONFIG_NET_EMATCH_U32=m +CONFIG_NET_EMATCH_META=m +CONFIG_NET_EMATCH_TEXT=m +CONFIG_NET_CLS_ACT=y +CONFIG_NET_ACT_POLICE=m +CONFIG_NET_ACT_GACT=m +CONFIG_GACT_PROB=y +CONFIG_NET_ACT_MIRRED=m +CONFIG_NET_ACT_IPT=m +# CONFIG_NET_ACT_NAT is not set +CONFIG_NET_ACT_PEDIT=m +CONFIG_NET_ACT_SIMP=m +# CONFIG_NET_ACT_SKBEDIT is not set +CONFIG_NET_CLS_IND=y +CONFIG_NET_SCH_FIFO=y +# CONFIG_DCB is not set + +# +# Network testing +# +CONFIG_NET_PKTGEN=m +CONFIG_HAMRADIO=y + +# +# Packet Radio protocols +# +CONFIG_AX25=m +# CONFIG_AX25_DAMA_SLAVE is not set +CONFIG_NETROM=m +CONFIG_ROSE=m + +# +# AX.25 network device drivers +# +CONFIG_MKISS=m +CONFIG_6PACK=m +CONFIG_BPQETHER=m +CONFIG_BAYCOM_SER_FDX=m +CONFIG_BAYCOM_SER_HDX=m +CONFIG_YAM=m +# CONFIG_CAN is not set +# CONFIG_IRDA is not set +# CONFIG_BT is not set +CONFIG_AF_RXRPC=y +# CONFIG_AF_RXRPC_DEBUG is not set +# CONFIG_RXKAD is not set +CONFIG_FIB_RULES=y +# CONFIG_WIRELESS is not set +# CONFIG_WIMAX 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=m +CONFIG_FIRMWARE_IN_KERNEL=y +CONFIG_EXTRA_FIRMWARE="" +# CONFIG_SYS_HYPERVISOR is not set +CONFIG_CONNECTOR=m +# CONFIG_MTD is not set +# CONFIG_PARPORT is not set +CONFIG_PNP=y +CONFIG_PNP_DEBUG_MESSAGES=y + +# +# Protocols +# +CONFIG_ISAPNP=y +# CONFIG_PNPACPI 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=y +CONFIG_BLK_DEV_NBD=m +# 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=8192 +# CONFIG_BLK_DEV_XIP is not set +CONFIG_CDROM_PKTCDVD=m +CONFIG_CDROM_PKTCDVD_BUFFERS=8 +# CONFIG_CDROM_PKTCDVD_WCACHE is not set +CONFIG_ATA_OVER_ETH=m +# CONFIG_BLK_DEV_HD is not set +CONFIG_MISC_DEVICES=y +# CONFIG_PHANTOM is not set +# CONFIG_SGI_IOC4 is not set +# CONFIG_TIFM_CORE is not set +# CONFIG_ICS932S401 is not set +# CONFIG_ENCLOSURE_SERVICES is not set +# CONFIG_HP_ILO is not set +# CONFIG_ISL29003 is not set +# CONFIG_C2PORT is not set + +# +# EEPROM support +# +# CONFIG_EEPROM_AT24 is not set +# CONFIG_EEPROM_LEGACY is not set +# CONFIG_EEPROM_93CX6 is not set +CONFIG_HAVE_IDE=y +CONFIG_IDE=y + +# +# Please see Documentation/ide/ide.txt for help/info on IDE drives +# +CONFIG_IDE_XFER_MODE=y +CONFIG_IDE_TIMINGS=y +CONFIG_IDE_ATAPI=y +# CONFIG_BLK_DEV_IDE_SATA is not set +CONFIG_IDE_GD=y +CONFIG_IDE_GD_ATA=y +# CONFIG_IDE_GD_ATAPI is not set +# CONFIG_BLK_DEV_IDECS is not set +# CONFIG_BLK_DEV_DELKIN is not set +CONFIG_BLK_DEV_IDECD=m +CONFIG_BLK_DEV_IDECD_VERBOSE_ERRORS=y +# CONFIG_BLK_DEV_IDETAPE is not set +CONFIG_IDE_TASK_IOCTL=y +CONFIG_IDE_PROC_FS=y + +# +# IDE chipset support/bugfixes +# +# CONFIG_IDE_GENERIC is not set +# CONFIG_BLK_DEV_PLATFORM is not set +# CONFIG_BLK_DEV_IDEPNP is not set +CONFIG_BLK_DEV_IDEDMA_SFF=y + +# +# PCI IDE chipsets support +# +CONFIG_BLK_DEV_IDEPCI=y +# CONFIG_IDEPCI_PCIBUS_ORDER is not set +# CONFIG_BLK_DEV_OFFBOARD is not set +CONFIG_BLK_DEV_GENERIC=y +# CONFIG_BLK_DEV_OPTI621 is not set +CONFIG_BLK_DEV_IDEDMA_PCI=y +# CONFIG_BLK_DEV_AEC62XX is not set +# CONFIG_BLK_DEV_ALI15X3 is not set +CONFIG_BLK_DEV_AMD74XX=y +# CONFIG_BLK_DEV_CMD64X is not set +# CONFIG_BLK_DEV_TRIFLEX is not set +# CONFIG_BLK_DEV_CS5520 is not set +# CONFIG_BLK_DEV_CS5530 is not set +# CONFIG_BLK_DEV_HPT366 is not set +# CONFIG_BLK_DEV_JMICRON is not set +# CONFIG_BLK_DEV_SC1200 is not set +# CONFIG_BLK_DEV_PIIX is not set +# CONFIG_BLK_DEV_IT8172 is not set +# CONFIG_BLK_DEV_IT8213 is not set +# CONFIG_BLK_DEV_IT821X is not set +# CONFIG_BLK_DEV_NS87415 is not set +# CONFIG_BLK_DEV_PDC202XX_OLD is not set +# CONFIG_BLK_DEV_PDC202XX_NEW is not set +# CONFIG_BLK_DEV_SVWKS is not set +# CONFIG_BLK_DEV_SIIMAGE is not set +# CONFIG_BLK_DEV_SLC90E66 is not set +# CONFIG_BLK_DEV_TRM290 is not set +# CONFIG_BLK_DEV_VIA82CXXX is not set +# CONFIG_BLK_DEV_TC86C001 is not set + +# +# Other IDE chipsets support +# + +# +# Note: most of these also require special kernel boot parameters +# +# CONFIG_BLK_DEV_4DRIVES is not set +# CONFIG_BLK_DEV_ALI14XX is not set +# CONFIG_BLK_DEV_DTC2278 is not set +# CONFIG_BLK_DEV_HT6560B is not set +# CONFIG_BLK_DEV_QD65XX is not set +# CONFIG_BLK_DEV_UMC8672 is not set +CONFIG_BLK_DEV_IDEDMA=y + +# +# 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=y +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=m +CONFIG_BLK_DEV_SR_VENDOR=y +CONFIG_CHR_DEV_SG=m +CONFIG_CHR_DEV_SCH=m + +# +# Some SCSI devices (e.g. CD jukebox) support multiple LUNs +# +CONFIG_SCSI_MULTI_LUN=y +CONFIG_SCSI_CONSTANTS=y +CONFIG_SCSI_LOGGING=y +# CONFIG_SCSI_SCAN_ASYNC is not set +CONFIG_SCSI_WAIT_SCAN=m + +# +# SCSI Transports +# +CONFIG_SCSI_SPI_ATTRS=m +CONFIG_SCSI_FC_ATTRS=m +CONFIG_SCSI_ISCSI_ATTRS=m +CONFIG_SCSI_SAS_ATTRS=m +# CONFIG_SCSI_SAS_LIBSAS is not set +CONFIG_SCSI_SRP_ATTRS=m +CONFIG_SCSI_LOWLEVEL=y +CONFIG_ISCSI_TCP=m +# 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_IN2000 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_MPT2SAS is not set +# CONFIG_SCSI_HPTIOP is not set +# CONFIG_LIBFC is not set +# CONFIG_LIBFCOE is not set +# CONFIG_FCOE is not set +# CONFIG_SCSI_DMX3191D is not set +# CONFIG_SCSI_DTC3280 is not set +# CONFIG_SCSI_FUTURE_DOMAIN is not set +# CONFIG_SCSI_GENERIC_NCR5380 is not set +# CONFIG_SCSI_GENERIC_NCR5380_MMIO is not set +# CONFIG_SCSI_IPS is not set +# CONFIG_SCSI_INITIO is not set +# CONFIG_SCSI_INIA100 is not set +# CONFIG_SCSI_MVSAS is not set +# CONFIG_SCSI_NCR53C406A is not set +# CONFIG_SCSI_STEX is not set +# CONFIG_SCSI_SYM53C8XX_2 is not set +# CONFIG_SCSI_PAS16 is not set +# CONFIG_SCSI_QLOGIC_FAS 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_SYM53C416 is not set +# CONFIG_SCSI_DC395x is not set +# CONFIG_SCSI_DC390T is not set +# CONFIG_SCSI_T128 is not set +# CONFIG_SCSI_DEBUG is not set +# CONFIG_SCSI_SRP is not set +# CONFIG_SCSI_LOWLEVEL_PCMCIA is not set +# CONFIG_SCSI_DH is not set +# CONFIG_SCSI_OSD_INITIATOR is not set +# CONFIG_ATA is not set +CONFIG_MD=y +CONFIG_BLK_DEV_MD=m +CONFIG_MD_LINEAR=m +CONFIG_MD_RAID0=m +CONFIG_MD_RAID1=m +CONFIG_MD_RAID10=m +CONFIG_MD_RAID456=m +CONFIG_MD_RAID6_PQ=m +CONFIG_MD_MULTIPATH=m +CONFIG_MD_FAULTY=m +CONFIG_BLK_DEV_DM=m +# CONFIG_DM_DEBUG is not set +CONFIG_DM_CRYPT=m +CONFIG_DM_SNAPSHOT=m +CONFIG_DM_MIRROR=m +CONFIG_DM_ZERO=m +CONFIG_DM_MULTIPATH=m +# CONFIG_DM_DELAY is not set +# CONFIG_DM_UEVENT is not set +CONFIG_FUSION=y +CONFIG_FUSION_SPI=m +CONFIG_FUSION_FC=m +CONFIG_FUSION_SAS=m +CONFIG_FUSION_MAX_SGE=40 +CONFIG_FUSION_CTL=m +# CONFIG_FUSION_LOGGING is not set + +# +# IEEE 1394 (FireWire) support +# + +# +# Enable only one of the two stacks, unless you know what you are doing +# +# CONFIG_FIREWIRE is not set +# CONFIG_IEEE1394 is not set +# CONFIG_I2O is not set +CONFIG_NETDEVICES=y +CONFIG_COMPAT_NET_DEV_OPS=y +# CONFIG_IFB 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=m +CONFIG_VETH=m +CONFIG_NET_SB1000=m +# CONFIG_ARCNET is not set +CONFIG_PHYLIB=y + +# +# MII PHY device drivers +# +CONFIG_MARVELL_PHY=m +CONFIG_DAVICOM_PHY=m +CONFIG_QSEMI_PHY=m +CONFIG_LXT_PHY=m +CONFIG_CICADA_PHY=m +CONFIG_VITESSE_PHY=m +CONFIG_SMSC_PHY=m +# CONFIG_BROADCOM_PHY is not set +# CONFIG_ICPLUS_PHY is not set +CONFIG_REALTEK_PHY=m +# CONFIG_NATIONAL_PHY is not set +# CONFIG_STE10XP is not set +# CONFIG_LSI_ET1011C_PHY is not set +# CONFIG_FIXED_PHY is not set +# CONFIG_MDIO_BITBANG is not set +CONFIG_NET_ETHERNET=y +CONFIG_MII=y +# CONFIG_AX88796 is not set +# CONFIG_HAPPYMEAL is not set +# CONFIG_SUNGEM is not set +# CONFIG_CASSINI is not set +# CONFIG_NET_VENDOR_3COM is not set +# CONFIG_NET_VENDOR_SMC is not set +# CONFIG_SMC91X is not set +# CONFIG_DM9000 is not set +# CONFIG_ETHOC is not set +# CONFIG_NET_VENDOR_RACAL is not set +# CONFIG_DNET is not set +# CONFIG_NET_TULIP is not set +# CONFIG_AT1700 is not set +# CONFIG_DEPCA is not set +# CONFIG_HP100 is not set +# CONFIG_NET_ISA is not set +# CONFIG_IBM_NEW_EMAC_ZMII is not set +# CONFIG_IBM_NEW_EMAC_RGMII is not set +# CONFIG_IBM_NEW_EMAC_TAH is not set +# CONFIG_IBM_NEW_EMAC_EMAC4 is not set +# CONFIG_IBM_NEW_EMAC_NO_FLOW_CTRL is not set +# CONFIG_IBM_NEW_EMAC_MAL_CLR_ICINTSTAT is not set +# CONFIG_IBM_NEW_EMAC_MAL_COMMON_ERR is not set +# CONFIG_NET_PCI is not set +# CONFIG_B44 is not set +# CONFIG_CS89x0 is not set +# CONFIG_ATL2 is not set +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_IGB is not set +# CONFIG_IGBVF is not set +# CONFIG_NS83820 is not set +# CONFIG_HAMACHI is not set +# CONFIG_YELLOWFIN is not set +CONFIG_R8169=y +CONFIG_R8169_VLAN=y +# CONFIG_SIS190 is not set +# CONFIG_SKGE is not set +# CONFIG_SKY2 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_ATL1E is not set +# CONFIG_ATL1C is not set +# CONFIG_JME is not set +# 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 + +# +# Enable WiMAX (Networking options) to see the WiMAX drivers +# + +# +# 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_NET_PCMCIA is not set +# CONFIG_WAN is not set +# CONFIG_ATM_DRIVERS is not set +# CONFIG_FDDI is not set +# CONFIG_HIPPI is not set +CONFIG_PPP=m +CONFIG_PPP_MULTILINK=y +CONFIG_PPP_FILTER=y +CONFIG_PPP_ASYNC=m +CONFIG_PPP_SYNC_TTY=m +CONFIG_PPP_DEFLATE=m +CONFIG_PPP_BSDCOMP=m +CONFIG_PPP_MPPE=m +CONFIG_PPPOE=m +CONFIG_PPPOATM=m +# CONFIG_PPPOL2TP is not set +# CONFIG_SLIP is not set +CONFIG_SLHC=m +# CONFIG_NET_FC 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 +# CONFIG_PHONE 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=y +CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024 +CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768 +CONFIG_INPUT_JOYDEV=m +CONFIG_INPUT_EVDEV=m +# CONFIG_INPUT_EVBUG is not set + +# +# Input Device Drivers +# +CONFIG_INPUT_KEYBOARD=y +CONFIG_KEYBOARD_ATKBD=y +CONFIG_KEYBOARD_SUNKBD=m +CONFIG_KEYBOARD_LKKBD=m +CONFIG_KEYBOARD_XTKBD=m +CONFIG_KEYBOARD_NEWTON=m +# CONFIG_KEYBOARD_STOWAWAY is not set +CONFIG_INPUT_MOUSE=y +CONFIG_MOUSE_PS2=y +CONFIG_MOUSE_PS2_ALPS=y +CONFIG_MOUSE_PS2_LOGIPS2PP=y +CONFIG_MOUSE_PS2_SYNAPTICS=y +CONFIG_MOUSE_PS2_TRACKPOINT=y +# CONFIG_MOUSE_PS2_ELANTECH is not set +# CONFIG_MOUSE_PS2_TOUCHKIT is not set +CONFIG_MOUSE_SERIAL=m +# CONFIG_MOUSE_APPLETOUCH is not set +# CONFIG_MOUSE_BCM5974 is not set +CONFIG_MOUSE_INPORT=m +# CONFIG_MOUSE_ATIXL is not set +CONFIG_MOUSE_LOGIBM=m +CONFIG_MOUSE_PC110PAD=m +CONFIG_MOUSE_VSXXXAA=m +CONFIG_INPUT_JOYSTICK=y +CONFIG_JOYSTICK_ANALOG=m +CONFIG_JOYSTICK_A3D=m +CONFIG_JOYSTICK_ADI=m +CONFIG_JOYSTICK_COBRA=m +CONFIG_JOYSTICK_GF2K=m +CONFIG_JOYSTICK_GRIP=m +CONFIG_JOYSTICK_GRIP_MP=m +CONFIG_JOYSTICK_GUILLEMOT=m +CONFIG_JOYSTICK_INTERACT=m +CONFIG_JOYSTICK_SIDEWINDER=m +CONFIG_JOYSTICK_TMDC=m +CONFIG_JOYSTICK_IFORCE=m +CONFIG_JOYSTICK_IFORCE_USB=y +CONFIG_JOYSTICK_IFORCE_232=y +CONFIG_JOYSTICK_WARRIOR=m +CONFIG_JOYSTICK_MAGELLAN=m +CONFIG_JOYSTICK_SPACEORB=m +CONFIG_JOYSTICK_SPACEBALL=m +CONFIG_JOYSTICK_STINGER=m +CONFIG_JOYSTICK_TWIDJOY=m +# CONFIG_JOYSTICK_ZHENHUA is not set +CONFIG_JOYSTICK_JOYDUMP=m +# CONFIG_JOYSTICK_XPAD is not set +# CONFIG_INPUT_TABLET is not set +CONFIG_INPUT_TOUCHSCREEN=y +# CONFIG_TOUCHSCREEN_AD7879_I2C is not set +# CONFIG_TOUCHSCREEN_AD7879 is not set +# CONFIG_TOUCHSCREEN_FUJITSU is not set +CONFIG_TOUCHSCREEN_GUNZE=m +CONFIG_TOUCHSCREEN_ELO=m +# CONFIG_TOUCHSCREEN_WACOM_W8001 is not set +CONFIG_TOUCHSCREEN_MTOUCH=m +# CONFIG_TOUCHSCREEN_INEXIO is not set +CONFIG_TOUCHSCREEN_MK712=m +# CONFIG_TOUCHSCREEN_HTCPEN is not set +# CONFIG_TOUCHSCREEN_PENMOUNT is not set +# CONFIG_TOUCHSCREEN_TOUCHRIGHT is not set +# CONFIG_TOUCHSCREEN_TOUCHWIN is not set +# CONFIG_TOUCHSCREEN_WM97XX is not set +# CONFIG_TOUCHSCREEN_USB_COMPOSITE is not set +# CONFIG_TOUCHSCREEN_TOUCHIT213 is not set +# CONFIG_TOUCHSCREEN_TSC2007 is not set +CONFIG_INPUT_MISC=y +CONFIG_INPUT_PCSPKR=m +# CONFIG_INPUT_ATI_REMOTE is not set +# CONFIG_INPUT_ATI_REMOTE2 is not set +# CONFIG_INPUT_KEYSPAN_REMOTE is not set +# CONFIG_INPUT_POWERMATE is not set +# CONFIG_INPUT_YEALINK is not set +# CONFIG_INPUT_CM109 is not set +CONFIG_INPUT_UINPUT=m + +# +# Hardware I/O ports +# +CONFIG_SERIO=y +# CONFIG_SERIO_I8042 is not set +CONFIG_SERIO_SERPORT=m +CONFIG_SERIO_PCIPS2=m +CONFIG_SERIO_LIBPS2=y +CONFIG_SERIO_RAW=m +CONFIG_GAMEPORT=m +CONFIG_GAMEPORT_NS558=m +CONFIG_GAMEPORT_L4=m +CONFIG_GAMEPORT_EMU10K1=m +CONFIG_GAMEPORT_FM801=m + +# +# Character devices +# +CONFIG_VT=y +CONFIG_CONSOLE_TRANSLATIONS=y +CONFIG_VT_CONSOLE=y +CONFIG_HW_CONSOLE=y +# CONFIG_VT_HW_CONSOLE_BINDING is not set +CONFIG_DEVKMEM=y +CONFIG_SERIAL_NONSTANDARD=y +# CONFIG_COMPUTONE is not set +# CONFIG_ROCKETPORT is not set +# CONFIG_CYCLADES is not set +# CONFIG_DIGIEPCA is not set +# CONFIG_MOXA_INTELLIO is not set +# CONFIG_MOXA_SMARTIO is not set +# CONFIG_ISI is not set +# CONFIG_SYNCLINKMP is not set +# CONFIG_SYNCLINK_GT is not set +# CONFIG_N_HDLC is not set +# CONFIG_RISCOM8 is not set +# CONFIG_SPECIALIX is not set +# CONFIG_SX is not set +# CONFIG_RIO is not set +# CONFIG_STALDRV is not set +# CONFIG_NOZOMI is not set + +# +# Serial drivers +# +CONFIG_SERIAL_8250=y +CONFIG_SERIAL_8250_CONSOLE=y +# CONFIG_SERIAL_8250_PCI is not set +# CONFIG_SERIAL_8250_PNP is not set +CONFIG_SERIAL_8250_CS=m +CONFIG_SERIAL_8250_NR_UARTS=16 +CONFIG_SERIAL_8250_RUNTIME_UARTS=4 +CONFIG_SERIAL_8250_EXTENDED=y +CONFIG_SERIAL_8250_MANY_PORTS=y +CONFIG_SERIAL_8250_FOURPORT=y +# CONFIG_SERIAL_8250_ACCENT is not set +# CONFIG_SERIAL_8250_BOCA is not set +# CONFIG_SERIAL_8250_EXAR_ST16C554 is not set +CONFIG_SERIAL_8250_HUB6=m +CONFIG_SERIAL_8250_SHARE_IRQ=y +# CONFIG_SERIAL_8250_DETECT_IRQ is not set +CONFIG_SERIAL_8250_RSA=y + +# +# Non-8250 serial port support +# +CONFIG_SERIAL_CORE=y +CONFIG_SERIAL_CORE_CONSOLE=y +# CONFIG_SERIAL_JSM is not set +CONFIG_UNIX98_PTYS=y +CONFIG_DEVPTS_MULTIPLE_INSTANCES=y +CONFIG_LEGACY_PTYS=y +CONFIG_LEGACY_PTY_COUNT=16 +# CONFIG_IPMI_HANDLER is not set +CONFIG_HW_RANDOM=y +# CONFIG_HW_RANDOM_TIMERIOMEM is not set +# CONFIG_DTLK is not set +# CONFIG_R3964 is not set +# CONFIG_APPLICOM is not set + +# +# PCMCIA character devices +# +# CONFIG_SYNCLINK_CS is not set +# CONFIG_CARDMAN_4000 is not set +# CONFIG_CARDMAN_4040 is not set +# CONFIG_IPWIRELESS 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=m +CONFIG_I2C_HELPER_AUTO=y +CONFIG_I2C_ALGOBIT=m +CONFIG_I2C_ALGOPCA=m + +# +# I2C Hardware Bus support +# + +# +# PC SMBus host controller drivers +# +CONFIG_I2C_ALI1535=m +CONFIG_I2C_ALI1563=m +CONFIG_I2C_ALI15X3=m +CONFIG_I2C_AMD756=m +CONFIG_I2C_AMD8111=m +CONFIG_I2C_I801=m +# CONFIG_I2C_ISCH is not set +CONFIG_I2C_PIIX4=m +CONFIG_I2C_NFORCE2=m +CONFIG_I2C_SIS5595=m +CONFIG_I2C_SIS630=m +CONFIG_I2C_SIS96X=m +CONFIG_I2C_VIA=m +CONFIG_I2C_VIAPRO=m + +# +# I2C system bus drivers (mostly embedded / system-on-chip) +# +CONFIG_I2C_OCORES=m +# CONFIG_I2C_SIMTEC is not set + +# +# External I2C/SMBus adapter drivers +# +CONFIG_I2C_PARPORT_LIGHT=m +# CONFIG_I2C_TAOS_EVM is not set +# CONFIG_I2C_TINY_USB is not set + +# +# Graphics adapter I2C/DDC channel drivers +# +CONFIG_I2C_VOODOO3=m + +# +# Other I2C/SMBus bus drivers +# +# CONFIG_I2C_ELEKTOR is not set +CONFIG_I2C_PCA_ISA=m +# CONFIG_I2C_PCA_PLATFORM is not set +CONFIG_I2C_STUB=m + +# +# Miscellaneous I2C Chip support +# +# CONFIG_DS1682 is not set +CONFIG_SENSORS_PCF8574=m +# CONFIG_PCF8575 is not set +# CONFIG_SENSORS_PCA9539 is not set +CONFIG_SENSORS_MAX6875=m +# 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 +# CONFIG_SPI is not set +# CONFIG_W1 is not set +# CONFIG_POWER_SUPPLY is not set +# CONFIG_HWMON is not set +# CONFIG_THERMAL is not set +# CONFIG_THERMAL_HWMON is not set +CONFIG_WATCHDOG=y +# CONFIG_WATCHDOG_NOWAYOUT is not set + +# +# Watchdog Device Drivers +# +CONFIG_SOFT_WATCHDOG=m +# CONFIG_ALIM7101_WDT is not set + +# +# ISA-based Watchdog Cards +# +CONFIG_PCWATCHDOG=m +CONFIG_MIXCOMWD=m +CONFIG_WDT=m + +# +# PCI-based Watchdog Cards +# +CONFIG_PCIPCWATCHDOG=m +CONFIG_WDTPCI=m +CONFIG_WDT_501_PCI=y + +# +# USB-based Watchdog Cards +# +CONFIG_USBPCWATCHDOG=m +CONFIG_SSB_POSSIBLE=y + +# +# Sonics Silicon Backplane +# +CONFIG_SSB=m +CONFIG_SSB_SPROM=y +CONFIG_SSB_PCIHOST_POSSIBLE=y +CONFIG_SSB_PCIHOST=y +# CONFIG_SSB_B43_PCI_BRIDGE is not set +CONFIG_SSB_PCMCIAHOST_POSSIBLE=y +# CONFIG_SSB_PCMCIAHOST is not set +# CONFIG_SSB_SILENT is not set +# CONFIG_SSB_DEBUG is not set +CONFIG_SSB_DRIVER_PCICORE_POSSIBLE=y +CONFIG_SSB_DRIVER_PCICORE=y +# CONFIG_SSB_DRIVER_MIPS is not set + +# +# Multifunction device drivers +# +# CONFIG_MFD_CORE is not set +# CONFIG_MFD_SM501 is not set +# CONFIG_HTC_PASIC3 is not set +# CONFIG_MFD_TMIO is not set +# CONFIG_MFD_WM8400 is not set +# CONFIG_MFD_WM8350_I2C is not set +# CONFIG_MFD_PCF50633 is not set +# CONFIG_REGULATOR is not set + +# +# Multimedia devices +# + +# +# Multimedia core support +# +CONFIG_VIDEO_DEV=m +CONFIG_VIDEO_V4L2_COMMON=m +CONFIG_VIDEO_ALLOW_V4L1=y +CONFIG_VIDEO_V4L1_COMPAT=y +CONFIG_DVB_CORE=m +CONFIG_VIDEO_MEDIA=m + +# +# Multimedia drivers +# +CONFIG_VIDEO_SAA7146=m +CONFIG_VIDEO_SAA7146_VV=m +# CONFIG_MEDIA_ATTACH is not set +CONFIG_MEDIA_TUNER=m +# CONFIG_MEDIA_TUNER_CUSTOMISE is not set +CONFIG_MEDIA_TUNER_SIMPLE=m +CONFIG_MEDIA_TUNER_TDA8290=m +CONFIG_MEDIA_TUNER_TDA827X=m +CONFIG_MEDIA_TUNER_TDA18271=m +CONFIG_MEDIA_TUNER_TDA9887=m +CONFIG_MEDIA_TUNER_TEA5761=m +CONFIG_MEDIA_TUNER_TEA5767=m +CONFIG_MEDIA_TUNER_MT20XX=m +CONFIG_MEDIA_TUNER_MT2060=m +CONFIG_MEDIA_TUNER_XC2028=m +CONFIG_MEDIA_TUNER_XC5000=m +CONFIG_MEDIA_TUNER_MXL5005S=m +CONFIG_MEDIA_TUNER_MC44S803=m +CONFIG_VIDEO_V4L2=m +CONFIG_VIDEO_V4L1=m +CONFIG_VIDEOBUF_GEN=m +CONFIG_VIDEOBUF_DMA_SG=m +CONFIG_VIDEOBUF_VMALLOC=m +CONFIG_VIDEOBUF_DVB=m +CONFIG_VIDEO_BTCX=m +CONFIG_VIDEO_IR=m +CONFIG_VIDEO_TVEEPROM=m +CONFIG_VIDEO_TUNER=m +CONFIG_VIDEO_CAPTURE_DRIVERS=y +# CONFIG_VIDEO_ADV_DEBUG is not set +# CONFIG_VIDEO_FIXED_MINOR_RANGES is not set +CONFIG_VIDEO_HELPER_CHIPS_AUTO=y +CONFIG_VIDEO_IR_I2C=m +CONFIG_VIDEO_TVAUDIO=m +CONFIG_VIDEO_TDA7432=m +CONFIG_VIDEO_TDA9840=m +CONFIG_VIDEO_TEA6415C=m +CONFIG_VIDEO_TEA6420=m +CONFIG_VIDEO_MSP3400=m +CONFIG_VIDEO_CS53L32A=m +CONFIG_VIDEO_WM8775=m +CONFIG_VIDEO_SAA6588=m +CONFIG_VIDEO_BT819=m +CONFIG_VIDEO_BT856=m +CONFIG_VIDEO_BT866=m +CONFIG_VIDEO_KS0127=m +CONFIG_VIDEO_SAA7110=m +CONFIG_VIDEO_SAA711X=m +CONFIG_VIDEO_TVP5150=m +CONFIG_VIDEO_VPX3220=m +CONFIG_VIDEO_CX25840=m +CONFIG_VIDEO_CX2341X=m +CONFIG_VIDEO_SAA7185=m +CONFIG_VIDEO_ADV7170=m +CONFIG_VIDEO_ADV7175=m +CONFIG_VIDEO_VIVI=m +CONFIG_VIDEO_BT848=m +CONFIG_VIDEO_BT848_DVB=y +CONFIG_VIDEO_PMS=m +CONFIG_VIDEO_CPIA=m +CONFIG_VIDEO_CPIA_USB=m +CONFIG_VIDEO_CPIA2=m +CONFIG_VIDEO_SAA5246A=m +CONFIG_VIDEO_SAA5249=m +CONFIG_VIDEO_STRADIS=m +CONFIG_VIDEO_ZORAN=m +CONFIG_VIDEO_ZORAN_DC30=m +CONFIG_VIDEO_ZORAN_ZR36060=m +CONFIG_VIDEO_ZORAN_BUZ=m +CONFIG_VIDEO_ZORAN_DC10=m +CONFIG_VIDEO_ZORAN_LML33=m +CONFIG_VIDEO_ZORAN_LML33R10=m +CONFIG_VIDEO_ZORAN_AVS6EYES=m +CONFIG_VIDEO_SAA7134=m +CONFIG_VIDEO_SAA7134_ALSA=m +CONFIG_VIDEO_SAA7134_DVB=m +CONFIG_VIDEO_MXB=m +CONFIG_VIDEO_HEXIUM_ORION=m +CONFIG_VIDEO_HEXIUM_GEMINI=m +CONFIG_VIDEO_CX88=m +CONFIG_VIDEO_CX88_ALSA=m +CONFIG_VIDEO_CX88_BLACKBIRD=m +CONFIG_VIDEO_CX88_DVB=m +CONFIG_VIDEO_CX88_MPEG=m +CONFIG_VIDEO_CX88_VP3054=m +# CONFIG_VIDEO_CX23885 is not set +# CONFIG_VIDEO_AU0828 is not set +# CONFIG_VIDEO_IVTV is not set +# CONFIG_VIDEO_CX18 is not set +# CONFIG_VIDEO_CAFE_CCIC is not set +# CONFIG_SOC_CAMERA is not set +CONFIG_V4L_USB_DRIVERS=y +# CONFIG_USB_VIDEO_CLASS is not set +CONFIG_USB_VIDEO_CLASS_INPUT_EVDEV=y +# CONFIG_USB_GSPCA is not set +CONFIG_VIDEO_PVRUSB2=m +CONFIG_VIDEO_PVRUSB2_SYSFS=y +CONFIG_VIDEO_PVRUSB2_DVB=y +# CONFIG_VIDEO_PVRUSB2_DEBUGIFC is not set +# CONFIG_VIDEO_HDPVR is not set +CONFIG_VIDEO_EM28XX=m +# CONFIG_VIDEO_EM28XX_ALSA is not set +# CONFIG_VIDEO_EM28XX_DVB is not set +# CONFIG_VIDEO_CX231XX is not set +# CONFIG_VIDEO_USBVISION is not set +CONFIG_VIDEO_USBVIDEO=m +CONFIG_USB_VICAM=m +CONFIG_USB_IBMCAM=m +CONFIG_USB_KONICAWC=m +CONFIG_USB_QUICKCAM_MESSENGER=m +CONFIG_USB_ET61X251=m +CONFIG_VIDEO_OVCAMCHIP=m +# CONFIG_USB_W9968CF is not set +CONFIG_USB_OV511=m +CONFIG_USB_SE401=m +CONFIG_USB_SN9C102=m +CONFIG_USB_STV680=m +CONFIG_USB_ZC0301=m +CONFIG_USB_PWC=m +# CONFIG_USB_PWC_DEBUG is not set +CONFIG_USB_PWC_INPUT_EVDEV=y +# CONFIG_USB_ZR364XX is not set +# CONFIG_USB_STKWEBCAM is not set +# CONFIG_USB_S2255 is not set +CONFIG_RADIO_ADAPTERS=y +CONFIG_RADIO_CADET=m +CONFIG_RADIO_RTRACK=m +CONFIG_RADIO_RTRACK2=m +CONFIG_RADIO_AZTECH=m +CONFIG_RADIO_GEMTEK=m +CONFIG_RADIO_GEMTEK_PCI=m +CONFIG_RADIO_MAXIRADIO=m +CONFIG_RADIO_MAESTRO=m +CONFIG_RADIO_SF16FMI=m +CONFIG_RADIO_SF16FMR2=m +CONFIG_RADIO_TERRATEC=m +CONFIG_RADIO_TRUST=m +CONFIG_RADIO_TYPHOON=m +CONFIG_RADIO_TYPHOON_PROC_FS=y +CONFIG_RADIO_ZOLTRIX=m +CONFIG_USB_DSBR=m +# CONFIG_USB_SI470X is not set +# CONFIG_USB_MR800 is not set +# CONFIG_RADIO_TEA5764 is not set +# CONFIG_DVB_DYNAMIC_MINORS is not set +CONFIG_DVB_CAPTURE_DRIVERS=y + +# +# Supported SAA7146 based PCI Adapters +# +CONFIG_TTPCI_EEPROM=m +CONFIG_DVB_AV7110=m +CONFIG_DVB_AV7110_OSD=y +# CONFIG_DVB_BUDGET_CORE is not set + +# +# Supported USB Adapters +# +CONFIG_DVB_USB=m +# CONFIG_DVB_USB_DEBUG is not set +CONFIG_DVB_USB_A800=m +CONFIG_DVB_USB_DIBUSB_MB=m +CONFIG_DVB_USB_DIBUSB_MB_FAULTY=y +CONFIG_DVB_USB_DIBUSB_MC=m +# CONFIG_DVB_USB_DIB0700 is not set +CONFIG_DVB_USB_UMT_010=m +CONFIG_DVB_USB_CXUSB=m +# CONFIG_DVB_USB_M920X is not set +# CONFIG_DVB_USB_GL861 is not set +# CONFIG_DVB_USB_AU6610 is not set +CONFIG_DVB_USB_DIGITV=m +CONFIG_DVB_USB_VP7045=m +CONFIG_DVB_USB_VP702X=m +CONFIG_DVB_USB_GP8PSK=m +CONFIG_DVB_USB_NOVA_T_USB2=m +# CONFIG_DVB_USB_TTUSB2 is not set +CONFIG_DVB_USB_DTT200U=m +# CONFIG_DVB_USB_OPERA1 is not set +# CONFIG_DVB_USB_AF9005 is not set +# CONFIG_DVB_USB_DW2102 is not set +# CONFIG_DVB_USB_CINERGY_T2 is not set +# CONFIG_DVB_USB_ANYSEE is not set +# CONFIG_DVB_USB_DTV5100 is not set +# CONFIG_DVB_USB_AF9015 is not set +# CONFIG_DVB_USB_CE6230 is not set +CONFIG_DVB_TTUSB_BUDGET=m +CONFIG_DVB_TTUSB_DEC=m +# CONFIG_DVB_SIANO_SMS1XXX is not set + +# +# Supported FlexCopII (B2C2) Adapters +# +CONFIG_DVB_B2C2_FLEXCOP=m +CONFIG_DVB_B2C2_FLEXCOP_PCI=m +CONFIG_DVB_B2C2_FLEXCOP_USB=m +# CONFIG_DVB_B2C2_FLEXCOP_DEBUG is not set + +# +# Supported BT878 Adapters +# +CONFIG_DVB_BT8XX=m + +# +# Supported Pluto2 Adapters +# +CONFIG_DVB_PLUTO2=m + +# +# Supported SDMC DM1105 Adapters +# +# CONFIG_DVB_DM1105 is not set + +# +# Supported DVB Frontends +# +# CONFIG_DVB_FE_CUSTOMISE is not set +CONFIG_DVB_CX24110=m +CONFIG_DVB_CX24123=m +CONFIG_DVB_MT312=m +CONFIG_DVB_ZL10036=m +CONFIG_DVB_S5H1420=m +CONFIG_DVB_STV0288=m +CONFIG_DVB_STB6000=m +CONFIG_DVB_STV0299=m +CONFIG_DVB_TDA8083=m +CONFIG_DVB_TDA10086=m +CONFIG_DVB_VES1X93=m +CONFIG_DVB_TUNER_ITD1000=m +CONFIG_DVB_TUNER_CX24113=m +CONFIG_DVB_TDA826X=m +CONFIG_DVB_CX24116=m +CONFIG_DVB_SP8870=m +CONFIG_DVB_SP887X=m +CONFIG_DVB_CX22700=m +CONFIG_DVB_CX22702=m +CONFIG_DVB_L64781=m +CONFIG_DVB_TDA1004X=m +CONFIG_DVB_NXT6000=m +CONFIG_DVB_MT352=m +CONFIG_DVB_ZL10353=m +CONFIG_DVB_DIB3000MB=m +CONFIG_DVB_DIB3000MC=m +CONFIG_DVB_DIB7000P=m +CONFIG_DVB_TDA10048=m +CONFIG_DVB_VES1820=m +CONFIG_DVB_STV0297=m +CONFIG_DVB_NXT200X=m +CONFIG_DVB_OR51211=m +CONFIG_DVB_OR51132=m +CONFIG_DVB_BCM3510=m +CONFIG_DVB_LGDT330X=m +CONFIG_DVB_LGDT3305=m +CONFIG_DVB_S5H1409=m +CONFIG_DVB_S5H1411=m +CONFIG_DVB_PLL=m +CONFIG_DVB_TUNER_DIB0070=m +CONFIG_DVB_LNBP21=m +CONFIG_DVB_ISL6405=m +CONFIG_DVB_ISL6421=m +CONFIG_DVB_LGS8GL5=m +# CONFIG_DAB is not set + +# +# Graphics support +# +CONFIG_DRM=m +CONFIG_DRM_TDFX=m +CONFIG_DRM_R128=m +CONFIG_DRM_RADEON=m +CONFIG_DRM_MGA=m +CONFIG_DRM_VIA=m +CONFIG_DRM_SAVAGE=m +CONFIG_VGASTATE=m +# CONFIG_VIDEO_OUTPUT_CONTROL is not set +CONFIG_FB=y +CONFIG_FIRMWARE_EDID=y +CONFIG_FB_DDC=m +CONFIG_FB_BOOT_VESA_SUPPORT=y +CONFIG_FB_CFB_FILLRECT=y +CONFIG_FB_CFB_COPYAREA=y +CONFIG_FB_CFB_IMAGEBLIT=y +# CONFIG_FB_CFB_REV_PIXELS_IN_BYTE is not set +CONFIG_FB_SYS_FILLRECT=m +CONFIG_FB_SYS_COPYAREA=m +CONFIG_FB_SYS_IMAGEBLIT=m +# CONFIG_FB_FOREIGN_ENDIAN is not set +CONFIG_FB_SYS_FOPS=m +# CONFIG_FB_SVGALIB is not set +# CONFIG_FB_MACMODES is not set +CONFIG_FB_BACKLIGHT=y +CONFIG_FB_MODE_HELPERS=y +CONFIG_FB_TILEBLITTING=y + +# +# Frame buffer hardware drivers +# +CONFIG_FB_CIRRUS=m +CONFIG_FB_PM2=m +CONFIG_FB_PM2_FIFO_DISCONNECT=y +CONFIG_FB_CYBER2000=m +# CONFIG_FB_ASILIANT is not set +# CONFIG_FB_IMSTT is not set +# CONFIG_FB_UVESA is not set +CONFIG_FB_S1D13XXX=m +CONFIG_FB_NVIDIA=m +CONFIG_FB_NVIDIA_I2C=y +# CONFIG_FB_NVIDIA_DEBUG is not set +CONFIG_FB_NVIDIA_BACKLIGHT=y +# CONFIG_FB_RIVA is not set +CONFIG_FB_MATROX=m +CONFIG_FB_MATROX_MILLENIUM=y +CONFIG_FB_MATROX_MYSTIQUE=y +CONFIG_FB_MATROX_G=y +CONFIG_FB_MATROX_I2C=m +CONFIG_FB_MATROX_MAVEN=m +CONFIG_FB_MATROX_MULTIHEAD=y +CONFIG_FB_RADEON=m +CONFIG_FB_RADEON_I2C=y +CONFIG_FB_RADEON_BACKLIGHT=y +# CONFIG_FB_RADEON_DEBUG is not set +CONFIG_FB_ATY128=m +CONFIG_FB_ATY128_BACKLIGHT=y +CONFIG_FB_ATY=m +CONFIG_FB_ATY_CT=y +CONFIG_FB_ATY_GENERIC_LCD=y +CONFIG_FB_ATY_GX=y +CONFIG_FB_ATY_BACKLIGHT=y +# CONFIG_FB_S3 is not set +CONFIG_FB_SAVAGE=m +CONFIG_FB_SAVAGE_I2C=y +# CONFIG_FB_SAVAGE_ACCEL is not set +CONFIG_FB_SIS=y +CONFIG_FB_SIS_300=y +CONFIG_FB_SIS_315=y +# CONFIG_FB_VIA is not set +CONFIG_FB_NEOMAGIC=m +CONFIG_FB_KYRO=m +CONFIG_FB_3DFX=m +# CONFIG_FB_3DFX_ACCEL is not set +CONFIG_FB_3DFX_I2C=y +CONFIG_FB_VOODOO1=m +# CONFIG_FB_VT8623 is not set +CONFIG_FB_TRIDENT=m +# CONFIG_FB_ARK is not set +# CONFIG_FB_PM3 is not set +# CONFIG_FB_CARMINE is not set +# CONFIG_FB_SM7XX is not set +CONFIG_FB_VIRTUAL=m +# CONFIG_FB_METRONOME is not set +# CONFIG_FB_MB862XX is not set +# CONFIG_FB_BROADSHEET is not set +CONFIG_BACKLIGHT_LCD_SUPPORT=y +# CONFIG_LCD_CLASS_DEVICE is not set +CONFIG_BACKLIGHT_CLASS_DEVICE=y +CONFIG_BACKLIGHT_GENERIC=y + +# +# Display device support +# +# CONFIG_DISPLAY_SUPPORT is not set + +# +# Console display driver support +# +# CONFIG_VGA_CONSOLE is not set +# CONFIG_MDA_CONSOLE is not set +CONFIG_DUMMY_CONSOLE=y +CONFIG_FRAMEBUFFER_CONSOLE=y +# CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY is not set +CONFIG_FRAMEBUFFER_CONSOLE_ROTATION=y +# CONFIG_FONTS is not set +CONFIG_FONT_8x8=y +CONFIG_FONT_8x16=y +# CONFIG_LOGO is not set +CONFIG_SOUND=m +CONFIG_SOUND_OSS_CORE=y +CONFIG_SND=m +CONFIG_SND_TIMER=m +CONFIG_SND_PCM=m +CONFIG_SND_SEQUENCER=m +CONFIG_SND_SEQ_DUMMY=m +CONFIG_SND_OSSEMUL=y +CONFIG_SND_MIXER_OSS=m +CONFIG_SND_PCM_OSS=m +CONFIG_SND_PCM_OSS_PLUGINS=y +CONFIG_SND_SEQUENCER_OSS=y +# CONFIG_SND_HRTIMER is not set +# CONFIG_SND_DYNAMIC_MINORS is not set +CONFIG_SND_SUPPORT_OLD_API=y +CONFIG_SND_VERBOSE_PROCFS=y +# CONFIG_SND_VERBOSE_PRINTK is not set +# CONFIG_SND_DEBUG is not set +CONFIG_SND_VMASTER=y +CONFIG_SND_AC97_CODEC=m +# CONFIG_SND_DRIVERS is not set +CONFIG_SND_PCI=y +# CONFIG_SND_AD1889 is not set +# CONFIG_SND_ALS300 is not set +# CONFIG_SND_ALI5451 is not set +# CONFIG_SND_ATIIXP is not set +# CONFIG_SND_ATIIXP_MODEM is not set +# CONFIG_SND_AU8810 is not set +# CONFIG_SND_AU8820 is not set +# CONFIG_SND_AU8830 is not set +# CONFIG_SND_AW2 is not set +# CONFIG_SND_AZT3328 is not set +# CONFIG_SND_BT87X is not set +# CONFIG_SND_CA0106 is not set +# CONFIG_SND_CMIPCI is not set +# CONFIG_SND_OXYGEN is not set +# CONFIG_SND_CS4281 is not set +# CONFIG_SND_CS46XX is not set +CONFIG_SND_CS5535AUDIO=m +# CONFIG_SND_DARLA20 is not set +# CONFIG_SND_GINA20 is not set +# CONFIG_SND_LAYLA20 is not set +# CONFIG_SND_DARLA24 is not set +# CONFIG_SND_GINA24 is not set +# CONFIG_SND_LAYLA24 is not set +# CONFIG_SND_MONA is not set +# CONFIG_SND_MIA is not set +# CONFIG_SND_ECHO3G is not set +# CONFIG_SND_INDIGO is not set +# CONFIG_SND_INDIGOIO is not set +# CONFIG_SND_INDIGODJ is not set +# CONFIG_SND_INDIGOIOX is not set +# CONFIG_SND_INDIGODJX is not set +# CONFIG_SND_EMU10K1 is not set +# CONFIG_SND_EMU10K1X is not set +# CONFIG_SND_ENS1370 is not set +# CONFIG_SND_ENS1371 is not set +# CONFIG_SND_ES1938 is not set +# CONFIG_SND_ES1968 is not set +# CONFIG_SND_FM801 is not set +# CONFIG_SND_HDA_INTEL is not set +# CONFIG_SND_HDSP is not set +# CONFIG_SND_HDSPM is not set +# CONFIG_SND_HIFIER is not set +# CONFIG_SND_ICE1712 is not set +# CONFIG_SND_ICE1724 is not set +# CONFIG_SND_INTEL8X0 is not set +# CONFIG_SND_INTEL8X0M is not set +# CONFIG_SND_KORG1212 is not set +# CONFIG_SND_MAESTRO3 is not set +# CONFIG_SND_MIXART is not set +# CONFIG_SND_NM256 is not set +# CONFIG_SND_PCXHR is not set +# CONFIG_SND_RIPTIDE is not set +# CONFIG_SND_RME32 is not set +# CONFIG_SND_RME96 is not set +# CONFIG_SND_RME9652 is not set +# CONFIG_SND_SONICVIBES is not set +# CONFIG_SND_TRIDENT is not set +# CONFIG_SND_VIA82XX is not set +# CONFIG_SND_VIA82XX_MODEM is not set +# CONFIG_SND_VIRTUOSO is not set +# CONFIG_SND_VX222 is not set +# CONFIG_SND_YMFPCI is not set +# CONFIG_SND_MIPS is not set +# CONFIG_SND_USB is not set +# CONFIG_SND_PCMCIA is not set +# CONFIG_SND_SOC is not set +# CONFIG_SOUND_PRIME is not set +CONFIG_AC97_BUS=m +CONFIG_HID_SUPPORT=y +CONFIG_HID=y +# CONFIG_HID_DEBUG is not set +# CONFIG_HIDRAW is not set + +# +# USB Input Devices +# +CONFIG_USB_HID=y +# CONFIG_HID_PID is not set +CONFIG_USB_HIDDEV=y + +# +# Special HID drivers +# +# CONFIG_HID_A4TECH is not set +# CONFIG_HID_APPLE is not set +# CONFIG_HID_BELKIN is not set +# CONFIG_HID_CHERRY is not set +# CONFIG_HID_CHICONY is not set +# CONFIG_HID_CYPRESS is not set +# CONFIG_DRAGONRISE_FF is not set +# CONFIG_HID_EZKEY is not set +# CONFIG_HID_KYE is not set +# CONFIG_HID_GYRATION is not set +# CONFIG_HID_KENSINGTON is not set +# CONFIG_HID_LOGITECH is not set +# CONFIG_HID_MICROSOFT is not set +# CONFIG_HID_MONTEREY is not set +# CONFIG_HID_NTRIG is not set +# CONFIG_HID_PANTHERLORD is not set +# CONFIG_HID_PETALYNX is not set +# CONFIG_HID_SAMSUNG is not set +# CONFIG_HID_SONY is not set +# CONFIG_HID_SUNPLUS is not set +# CONFIG_GREENASIA_FF is not set +# CONFIG_HID_TOPSEED is not set +# CONFIG_THRUSTMASTER_FF is not set +# CONFIG_ZEROPLUS_FF 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 +# CONFIG_USB_ANNOUNCE_NEW_DEVICES is not set + +# +# Miscellaneous USB options +# +CONFIG_USB_DEVICEFS=y +# CONFIG_USB_DEVICE_CLASS is not set +# CONFIG_USB_DYNAMIC_MINORS is not set +# CONFIG_USB_SUSPEND is not set +# CONFIG_USB_OTG is not set +# CONFIG_USB_OTG_WHITELIST is not set +# CONFIG_USB_OTG_BLACKLIST_HUB is not set +CONFIG_USB_MON=y +# CONFIG_USB_WUSB is not set +# CONFIG_USB_WUSB_CBAF is not set + +# +# USB Host Controller Drivers +# +# CONFIG_USB_C67X00_HCD is not set +CONFIG_USB_EHCI_HCD=y +CONFIG_USB_EHCI_ROOT_HUB_TT=y +# CONFIG_USB_EHCI_TT_NEWSCHED is not set +# CONFIG_USB_OXU210HP_HCD is not set +# CONFIG_USB_ISP116X_HCD is not set +# CONFIG_USB_ISP1760_HCD is not set +CONFIG_USB_OHCI_HCD=y +# CONFIG_USB_OHCI_BIG_ENDIAN_DESC is not set +# CONFIG_USB_OHCI_BIG_ENDIAN_MMIO is not set +CONFIG_USB_OHCI_LITTLE_ENDIAN=y +CONFIG_USB_UHCI_HCD=m +# CONFIG_USB_SL811_HCD is not set +# CONFIG_USB_R8A66597_HCD is not set +# CONFIG_USB_WHCI_HCD is not set +# CONFIG_USB_HWA_HCD is not set + +# +# USB Device Class drivers +# +CONFIG_USB_ACM=m +CONFIG_USB_PRINTER=m +# CONFIG_USB_WDM is not set +# CONFIG_USB_TMC is not set + +# +# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may +# + +# +# also be needed; see USB_STORAGE Help for more info +# +CONFIG_USB_STORAGE=y +# CONFIG_USB_STORAGE_DEBUG is not set +CONFIG_USB_STORAGE_DATAFAB=y +CONFIG_USB_STORAGE_FREECOM=y +CONFIG_USB_STORAGE_ISD200=y +CONFIG_USB_STORAGE_USBAT=y +CONFIG_USB_STORAGE_SDDR09=y +CONFIG_USB_STORAGE_SDDR55=y +CONFIG_USB_STORAGE_JUMPSHOT=y +CONFIG_USB_STORAGE_ALAUDA=y +# CONFIG_USB_STORAGE_ONETOUCH is not set +# CONFIG_USB_STORAGE_KARMA is not set +# CONFIG_USB_STORAGE_CYPRESS_ATACB is not set +# CONFIG_USB_LIBUSUAL is not set + +# +# USB Imaging devices +# +CONFIG_USB_MDC800=m +# CONFIG_USB_MICROTEK is not set + +# +# USB port drivers +# +CONFIG_USB_SERIAL=m +CONFIG_USB_EZUSB=y +CONFIG_USB_SERIAL_GENERIC=y +# CONFIG_USB_SERIAL_AIRCABLE is not set +CONFIG_USB_SERIAL_ARK3116=m +CONFIG_USB_SERIAL_BELKIN=m +# CONFIG_USB_SERIAL_CH341 is not set +# CONFIG_USB_SERIAL_WHITEHEAT is not set +CONFIG_USB_SERIAL_DIGI_ACCELEPORT=m +# CONFIG_USB_SERIAL_CP210X is not set +CONFIG_USB_SERIAL_CYPRESS_M8=m +CONFIG_USB_SERIAL_EMPEG=m +CONFIG_USB_SERIAL_FTDI_SIO=m +CONFIG_USB_SERIAL_FUNSOFT=m +CONFIG_USB_SERIAL_VISOR=m +CONFIG_USB_SERIAL_IPAQ=m +CONFIG_USB_SERIAL_IR=m +CONFIG_USB_SERIAL_EDGEPORT=m +CONFIG_USB_SERIAL_EDGEPORT_TI=m +CONFIG_USB_SERIAL_GARMIN=m +CONFIG_USB_SERIAL_IPW=m +# CONFIG_USB_SERIAL_IUU is not set +CONFIG_USB_SERIAL_KEYSPAN_PDA=m +# CONFIG_USB_SERIAL_KEYSPAN is not set +CONFIG_USB_SERIAL_KLSI=m +CONFIG_USB_SERIAL_KOBIL_SCT=m +CONFIG_USB_SERIAL_MCT_U232=m +# CONFIG_USB_SERIAL_MOS7720 is not set +# CONFIG_USB_SERIAL_MOS7840 is not set +# CONFIG_USB_SERIAL_MOTOROLA is not set +CONFIG_USB_SERIAL_NAVMAN=m +CONFIG_USB_SERIAL_PL2303=m +# CONFIG_USB_SERIAL_OTI6858 is not set +# CONFIG_USB_SERIAL_QUALCOMM is not set +# CONFIG_USB_SERIAL_SPCP8X5 is not set +CONFIG_USB_SERIAL_HP4X=m +CONFIG_USB_SERIAL_SAFE=m +# CONFIG_USB_SERIAL_SAFE_PADDED is not set +# CONFIG_USB_SERIAL_SIEMENS_MPI is not set +CONFIG_USB_SERIAL_SIERRAWIRELESS=m +# CONFIG_USB_SERIAL_SYMBOL is not set +CONFIG_USB_SERIAL_TI=m +CONFIG_USB_SERIAL_CYBERJACK=m +CONFIG_USB_SERIAL_XIRCOM=m +CONFIG_USB_SERIAL_OPTION=m +CONFIG_USB_SERIAL_OMNINET=m +# CONFIG_USB_SERIAL_OPTICON is not set +# CONFIG_USB_SERIAL_DEBUG 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_SEVSEG 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_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 is not set +# CONFIG_USB_ISIGHTFW is not set +# CONFIG_USB_VST is not set +# CONFIG_USB_ATM is not set +# CONFIG_USB_GADGET is not set + +# +# OTG and related infrastructure +# +# CONFIG_NOP_USB_XCEIV is not set +# CONFIG_UWB is not set +# CONFIG_MMC is not set +# CONFIG_MEMSTICK is not set +# CONFIG_NEW_LEDS is not set +# CONFIG_ACCESSIBILITY is not set +# CONFIG_INFINIBAND is not set +CONFIG_RTC_LIB=y +CONFIG_RTC_CLASS=y +CONFIG_RTC_HCTOSYS=y +CONFIG_RTC_HCTOSYS_DEVICE="rtc" +# 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 is not set +# 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 +# CONFIG_RTC_DRV_S35390A is not set +# CONFIG_RTC_DRV_FM3130 is not set +# CONFIG_RTC_DRV_RX8581 is not set + +# +# SPI RTC drivers +# + +# +# Platform RTC drivers +# +CONFIG_RTC_DRV_CMOS=y +# CONFIG_RTC_DRV_DS1286 is not set +# CONFIG_RTC_DRV_DS1511 is not set +# CONFIG_RTC_DRV_DS1553 is not set +# CONFIG_RTC_DRV_DS1742 is not set +# CONFIG_RTC_DRV_STK17TA8 is not set +# CONFIG_RTC_DRV_M48T86 is not set +# CONFIG_RTC_DRV_M48T35 is not set +# CONFIG_RTC_DRV_M48T59 is not set +# CONFIG_RTC_DRV_BQ4802 is not set +# CONFIG_RTC_DRV_V3020 is not set + +# +# on-CPU RTC drivers +# +# CONFIG_DMADEVICES is not set +# CONFIG_AUXDISPLAY is not set +# CONFIG_UIO is not set +# CONFIG_STAGING is not set + +# +# File systems +# +CONFIG_EXT2_FS=y +CONFIG_EXT2_FS_XATTR=y +CONFIG_EXT2_FS_POSIX_ACL=y +CONFIG_EXT2_FS_SECURITY=y +# CONFIG_EXT2_FS_XIP is not set +CONFIG_EXT3_FS=y +# CONFIG_EXT3_DEFAULTS_TO_ORDERED is not set +CONFIG_EXT3_FS_XATTR=y +CONFIG_EXT3_FS_POSIX_ACL=y +CONFIG_EXT3_FS_SECURITY=y +# CONFIG_EXT4_FS is not set +CONFIG_JBD=y +# CONFIG_JBD_DEBUG is not set +CONFIG_JBD2=m +# CONFIG_JBD2_DEBUG is not set +CONFIG_FS_MBCACHE=y +CONFIG_REISERFS_FS=m +# CONFIG_REISERFS_CHECK is not set +# CONFIG_REISERFS_PROC_INFO is not set +CONFIG_REISERFS_FS_XATTR=y +CONFIG_REISERFS_FS_POSIX_ACL=y +CONFIG_REISERFS_FS_SECURITY=y +CONFIG_JFS_FS=m +CONFIG_JFS_POSIX_ACL=y +CONFIG_JFS_SECURITY=y +# CONFIG_JFS_DEBUG is not set +# CONFIG_JFS_STATISTICS is not set +CONFIG_FS_POSIX_ACL=y +CONFIG_FILE_LOCKING=y +CONFIG_XFS_FS=m +CONFIG_XFS_QUOTA=y +CONFIG_XFS_POSIX_ACL=y +CONFIG_XFS_RT=y +# CONFIG_XFS_DEBUG is not set +# CONFIG_GFS2_FS is not set +CONFIG_OCFS2_FS=m +CONFIG_OCFS2_FS_O2CB=m +CONFIG_OCFS2_FS_STATS=y +CONFIG_OCFS2_DEBUG_MASKLOG=y +# CONFIG_OCFS2_DEBUG_FS is not set +# CONFIG_OCFS2_FS_POSIX_ACL is not set +# CONFIG_BTRFS_FS is not set +CONFIG_DNOTIFY=y +CONFIG_INOTIFY=y +CONFIG_INOTIFY_USER=y +CONFIG_QUOTA=y +# CONFIG_QUOTA_NETLINK_INTERFACE is not set +CONFIG_PRINT_QUOTA_WARNING=y +CONFIG_QUOTA_TREE=m +CONFIG_QFMT_V1=m +CONFIG_QFMT_V2=m +CONFIG_QUOTACTL=y +CONFIG_AUTOFS_FS=m +CONFIG_AUTOFS4_FS=m +CONFIG_FUSE_FS=m + +# +# Caches +# +# CONFIG_FSCACHE is not set + +# +# CD-ROM/DVD Filesystems +# +CONFIG_ISO9660_FS=m +CONFIG_JOLIET=y +CONFIG_ZISOFS=y +CONFIG_UDF_FS=m +CONFIG_UDF_NLS=y + +# +# DOS/FAT/NT Filesystems +# +CONFIG_FAT_FS=m +CONFIG_MSDOS_FS=m +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=y + +# +# Pseudo filesystems +# +CONFIG_PROC_FS=y +CONFIG_PROC_KCORE=y +CONFIG_PROC_SYSCTL=y +CONFIG_PROC_PAGE_MONITOR=y +CONFIG_SYSFS=y +CONFIG_TMPFS=y +# CONFIG_TMPFS_POSIX_ACL is not set +# CONFIG_HUGETLB_PAGE is not set +CONFIG_CONFIGFS_FS=m +CONFIG_MISC_FILESYSTEMS=y +CONFIG_ADFS_FS=m +# CONFIG_ADFS_FS_RW is not set +CONFIG_AFFS_FS=m +# CONFIG_ECRYPT_FS is not set +CONFIG_HFS_FS=m +CONFIG_HFSPLUS_FS=m +CONFIG_BEFS_FS=m +# CONFIG_BEFS_DEBUG is not set +CONFIG_BFS_FS=m +CONFIG_EFS_FS=m +CONFIG_CRAMFS=y +# CONFIG_SQUASHFS is not set +CONFIG_VXFS_FS=m +CONFIG_MINIX_FS=m +# CONFIG_OMFS_FS is not set +CONFIG_HPFS_FS=m +CONFIG_QNX4FS_FS=m +CONFIG_ROMFS_FS=m +CONFIG_ROMFS_BACKED_BY_BLOCK=y +# CONFIG_ROMFS_BACKED_BY_MTD is not set +# CONFIG_ROMFS_BACKED_BY_BOTH is not set +CONFIG_ROMFS_ON_BLOCK=y +CONFIG_SYSV_FS=m +CONFIG_UFS_FS=m +# CONFIG_UFS_FS_WRITE is not set +# CONFIG_UFS_DEBUG is not set +# CONFIG_NILFS2_FS is not set +CONFIG_NETWORK_FILESYSTEMS=y +CONFIG_NFS_FS=m +CONFIG_NFS_V3=y +CONFIG_NFS_V3_ACL=y +CONFIG_NFS_V4=y +CONFIG_NFSD=m +CONFIG_NFSD_V2_ACL=y +CONFIG_NFSD_V3=y +CONFIG_NFSD_V3_ACL=y +CONFIG_NFSD_V4=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_GSS=m +CONFIG_RPCSEC_GSS_KRB5=m +CONFIG_RPCSEC_GSS_SPKM3=m +CONFIG_SMB_FS=m +# CONFIG_SMB_NLS_DEFAULT is not set +CONFIG_CIFS=m +# CONFIG_CIFS_STATS is not set +# CONFIG_CIFS_WEAK_PW_HASH is not set +# CONFIG_CIFS_UPCALL is not set +# CONFIG_CIFS_XATTR is not set +# CONFIG_CIFS_DEBUG2 is not set +# CONFIG_CIFS_DFS_UPCALL is not set +# CONFIG_CIFS_EXPERIMENTAL is not set +CONFIG_NCP_FS=m +CONFIG_NCPFS_PACKET_SIGNING=y +CONFIG_NCPFS_IOCTL_LOCKING=y +CONFIG_NCPFS_STRONG=y +CONFIG_NCPFS_NFS_NS=y +CONFIG_NCPFS_OS2_NS=y +# CONFIG_NCPFS_SMALLDOS is not set +CONFIG_NCPFS_NLS=y +CONFIG_NCPFS_EXTRAS=y +CONFIG_CODA_FS=m +CONFIG_AFS_FS=m +# CONFIG_AFS_DEBUG is not set + +# +# Partition Types +# +CONFIG_PARTITION_ADVANCED=y +CONFIG_ACORN_PARTITION=y +# CONFIG_ACORN_PARTITION_CUMANA is not set +# CONFIG_ACORN_PARTITION_EESOX is not set +CONFIG_ACORN_PARTITION_ICS=y +# CONFIG_ACORN_PARTITION_ADFS is not set +# CONFIG_ACORN_PARTITION_POWERTEC is not set +CONFIG_ACORN_PARTITION_RISCIX=y +CONFIG_OSF_PARTITION=y +CONFIG_AMIGA_PARTITION=y +CONFIG_ATARI_PARTITION=y +CONFIG_MAC_PARTITION=y +CONFIG_MSDOS_PARTITION=y +CONFIG_BSD_DISKLABEL=y +CONFIG_MINIX_SUBPARTITION=y +CONFIG_SOLARIS_X86_PARTITION=y +CONFIG_UNIXWARE_DISKLABEL=y +CONFIG_LDM_PARTITION=y +# CONFIG_LDM_DEBUG is not set +CONFIG_SGI_PARTITION=y +CONFIG_ULTRIX_PARTITION=y +CONFIG_SUN_PARTITION=y +CONFIG_KARMA_PARTITION=y +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=m +CONFIG_NLS_CODEPAGE_775=m +CONFIG_NLS_CODEPAGE_850=m +CONFIG_NLS_CODEPAGE_852=m +CONFIG_NLS_CODEPAGE_855=m +CONFIG_NLS_CODEPAGE_857=m +CONFIG_NLS_CODEPAGE_860=m +CONFIG_NLS_CODEPAGE_861=m +CONFIG_NLS_CODEPAGE_862=m +CONFIG_NLS_CODEPAGE_863=m +CONFIG_NLS_CODEPAGE_864=m +CONFIG_NLS_CODEPAGE_865=m +CONFIG_NLS_CODEPAGE_866=m +CONFIG_NLS_CODEPAGE_869=m +CONFIG_NLS_CODEPAGE_936=m +CONFIG_NLS_CODEPAGE_950=m +CONFIG_NLS_CODEPAGE_932=m +CONFIG_NLS_CODEPAGE_949=m +CONFIG_NLS_CODEPAGE_874=m +CONFIG_NLS_ISO8859_8=m +CONFIG_NLS_CODEPAGE_1250=m +CONFIG_NLS_CODEPAGE_1251=m +CONFIG_NLS_ASCII=m +CONFIG_NLS_ISO8859_1=m +CONFIG_NLS_ISO8859_2=m +CONFIG_NLS_ISO8859_3=m +CONFIG_NLS_ISO8859_4=m +CONFIG_NLS_ISO8859_5=m +CONFIG_NLS_ISO8859_6=m +CONFIG_NLS_ISO8859_7=m +CONFIG_NLS_ISO8859_9=m +CONFIG_NLS_ISO8859_13=m +CONFIG_NLS_ISO8859_14=m +CONFIG_NLS_ISO8859_15=m +CONFIG_NLS_KOI8_R=m +CONFIG_NLS_KOI8_U=m +CONFIG_NLS_UTF8=m +# CONFIG_DLM is not set + +# +# Kernel hacking +# +CONFIG_TRACE_IRQFLAGS_SUPPORT=y +# CONFIG_PRINTK_TIME is not set +CONFIG_ENABLE_WARN_DEPRECATED=y +CONFIG_ENABLE_MUST_CHECK=y +CONFIG_FRAME_WARN=1024 +CONFIG_MAGIC_SYSRQ=y +CONFIG_UNUSED_SYMBOLS=y +CONFIG_DEBUG_FS=y +# CONFIG_HEADERS_CHECK is not set +# CONFIG_DEBUG_KERNEL is not set +# CONFIG_DEBUG_MEMORY_INIT is not set +# CONFIG_RCU_CPU_STALL_DETECTOR is not set +CONFIG_SYSCTL_SYSCALL_CHECK=y +CONFIG_TRACING_SUPPORT=y + +# +# Tracers +# +# CONFIG_IRQSOFF_TRACER is not set +# CONFIG_SCHED_TRACER is not set +# CONFIG_CONTEXT_SWITCH_TRACER is not set +# CONFIG_EVENT_TRACER is not set +# CONFIG_BOOT_TRACER is not set +# CONFIG_TRACE_BRANCH_PROFILING is not set +# CONFIG_KMEMTRACE is not set +# CONFIG_WORKQUEUE_TRACER is not set +# CONFIG_BLK_DEV_IO_TRACE is not set +# CONFIG_DYNAMIC_DEBUG is not set +# CONFIG_SAMPLES is not set +CONFIG_HAVE_ARCH_KGDB=y +CONFIG_CMDLINE="" + +# +# Security options +# +CONFIG_KEYS=y +# CONFIG_KEYS_DEBUG_PROC_KEYS is not set +CONFIG_SECURITY=y +# CONFIG_SECURITYFS is not set +CONFIG_SECURITY_NETWORK=y +CONFIG_SECURITY_NETWORK_XFRM=y +# CONFIG_SECURITY_PATH is not set +# CONFIG_SECURITY_FILE_CAPABILITIES is not set +# CONFIG_SECURITY_ROOTPLUG is not set +CONFIG_SECURITY_DEFAULT_MMAP_MIN_ADDR=0 +CONFIG_SECURITY_SELINUX=y +CONFIG_SECURITY_SELINUX_BOOTPARAM=y +CONFIG_SECURITY_SELINUX_BOOTPARAM_VALUE=0 +CONFIG_SECURITY_SELINUX_DISABLE=y +CONFIG_SECURITY_SELINUX_DEVELOP=y +CONFIG_SECURITY_SELINUX_AVC_STATS=y +CONFIG_SECURITY_SELINUX_CHECKREQPROT_VALUE=1 +# CONFIG_SECURITY_SELINUX_POLICYDB_VERSION_MAX is not set +# CONFIG_SECURITY_TOMOYO is not set +CONFIG_XOR_BLOCKS=m +CONFIG_ASYNC_CORE=m +CONFIG_ASYNC_MEMCPY=m +CONFIG_ASYNC_XOR=m +CONFIG_CRYPTO=y + +# +# Crypto core or helper +# +# CONFIG_CRYPTO_FIPS is not set +CONFIG_CRYPTO_ALGAPI=y +CONFIG_CRYPTO_ALGAPI2=y +CONFIG_CRYPTO_AEAD=m +CONFIG_CRYPTO_AEAD2=y +CONFIG_CRYPTO_BLKCIPHER=y +CONFIG_CRYPTO_BLKCIPHER2=y +CONFIG_CRYPTO_HASH=y +CONFIG_CRYPTO_HASH2=y +CONFIG_CRYPTO_RNG2=y +CONFIG_CRYPTO_PCOMP=y +CONFIG_CRYPTO_MANAGER=y +CONFIG_CRYPTO_MANAGER2=y +# CONFIG_CRYPTO_GF128MUL is not set +CONFIG_CRYPTO_NULL=m +CONFIG_CRYPTO_WORKQUEUE=y +# CONFIG_CRYPTO_CRYPTD is not set +CONFIG_CRYPTO_AUTHENC=m +CONFIG_CRYPTO_TEST=m + +# +# Authenticated Encryption with Associated Data +# +# CONFIG_CRYPTO_CCM is not set +# CONFIG_CRYPTO_GCM is not set +# CONFIG_CRYPTO_SEQIV is not set + +# +# Block modes +# +CONFIG_CRYPTO_CBC=y +# CONFIG_CRYPTO_CTR is not set +# CONFIG_CRYPTO_CTS is not set +CONFIG_CRYPTO_ECB=m +# CONFIG_CRYPTO_LRW is not set +# CONFIG_CRYPTO_PCBC is not set +# CONFIG_CRYPTO_XTS is not set + +# +# Hash modes +# +CONFIG_CRYPTO_HMAC=y +# CONFIG_CRYPTO_XCBC is not set + +# +# Digest +# +CONFIG_CRYPTO_CRC32C=m +CONFIG_CRYPTO_MD4=m +CONFIG_CRYPTO_MD5=y +CONFIG_CRYPTO_MICHAEL_MIC=m +# CONFIG_CRYPTO_RMD128 is not set +# CONFIG_CRYPTO_RMD160 is not set +# CONFIG_CRYPTO_RMD256 is not set +# CONFIG_CRYPTO_RMD320 is not set +CONFIG_CRYPTO_SHA1=m +CONFIG_CRYPTO_SHA256=m +CONFIG_CRYPTO_SHA512=m +CONFIG_CRYPTO_TGR192=m +CONFIG_CRYPTO_WP512=m + +# +# Ciphers +# +CONFIG_CRYPTO_AES=m +CONFIG_CRYPTO_ANUBIS=m +CONFIG_CRYPTO_ARC4=m +CONFIG_CRYPTO_BLOWFISH=m +# CONFIG_CRYPTO_CAMELLIA is not set +CONFIG_CRYPTO_CAST5=m +CONFIG_CRYPTO_CAST6=m +CONFIG_CRYPTO_DES=m +# CONFIG_CRYPTO_FCRYPT is not set +CONFIG_CRYPTO_KHAZAD=m +# CONFIG_CRYPTO_SALSA20 is not set +# CONFIG_CRYPTO_SEED is not set +CONFIG_CRYPTO_SERPENT=m +CONFIG_CRYPTO_TEA=m +CONFIG_CRYPTO_TWOFISH=m +CONFIG_CRYPTO_TWOFISH_COMMON=m + +# +# Compression +# +CONFIG_CRYPTO_DEFLATE=m +# CONFIG_CRYPTO_ZLIB is not set +# CONFIG_CRYPTO_LZO is not set + +# +# Random Number Generation +# +# CONFIG_CRYPTO_ANSI_CPRNG is not set +CONFIG_CRYPTO_HW=y +# CONFIG_CRYPTO_DEV_HIFN_795X is not set +# CONFIG_BINARY_PRINTF is not set + +# +# Library routines +# +CONFIG_BITREVERSE=y +CONFIG_GENERIC_FIND_LAST_BIT=y +CONFIG_CRC_CCITT=m +CONFIG_CRC16=m +# CONFIG_CRC_T10DIF is not set +CONFIG_CRC_ITU_T=m +CONFIG_CRC32=y +# CONFIG_CRC7 is not set +CONFIG_LIBCRC32C=m +CONFIG_AUDIT_GENERIC=y +CONFIG_ZLIB_INFLATE=y +CONFIG_ZLIB_DEFLATE=m +CONFIG_DECOMPRESS_GZIP=y +CONFIG_TEXTSEARCH=y +CONFIG_TEXTSEARCH_KMP=m +CONFIG_TEXTSEARCH_BM=m +CONFIG_TEXTSEARCH_FSM=m +CONFIG_HAS_IOMEM=y +CONFIG_HAS_IOPORT=y +CONFIG_HAS_DMA=y +CONFIG_NLATTR=y diff -Nur linux-2.6.30.5.orig/arch/mips/configs/yeeloong2f_defconfig linux-2.6.30.5/arch/mips/configs/yeeloong2f_defconfig --- linux-2.6.30.5.orig/arch/mips/configs/yeeloong2f_defconfig 1970-01-01 01:00:00.000000000 +0100 +++ linux-2.6.30.5/arch/mips/configs/yeeloong2f_defconfig 2009-08-23 19:01:04.000000000 +0200 @@ -0,0 +1,2591 @@ +# +# Automatically generated make config: don't edit +# Linux kernel version: 2.6.31-rc2 +# Sat Jul 11 00:34:44 2009 +# +CONFIG_MIPS=y + +# +# Machine selection +# +# CONFIG_MACH_ALCHEMY is not set +# CONFIG_AR7 is not set +# CONFIG_BASLER_EXCITE is not set +# CONFIG_BCM47XX is not set +# CONFIG_MIPS_COBALT is not set +# CONFIG_MACH_DECSTATION is not set +# CONFIG_MACH_JAZZ is not set +# CONFIG_LASAT is not set +CONFIG_MACH_LOONGSON=y +# CONFIG_MIPS_MALTA is not set +# CONFIG_MIPS_SIM is not set +# CONFIG_NEC_MARKEINS is not set +# CONFIG_MACH_VR41XX is not set +# CONFIG_NXP_STB220 is not set +# CONFIG_NXP_STB225 is not set +# CONFIG_PNX8550_JBS is not set +# CONFIG_PNX8550_STB810 is not set +# CONFIG_PMC_MSP is not set +# CONFIG_PMC_YOSEMITE is not set +# CONFIG_SGI_IP22 is not set +# CONFIG_SGI_IP27 is not set +# CONFIG_SGI_IP28 is not set +# CONFIG_SGI_IP32 is not set +# CONFIG_SIBYTE_CRHINE is not set +# CONFIG_SIBYTE_CARMEL is not set +# CONFIG_SIBYTE_CRHONE is not set +# CONFIG_SIBYTE_RHONE is not set +# CONFIG_SIBYTE_SWARM is not set +# CONFIG_SIBYTE_LITTLESUR is not set +# CONFIG_SIBYTE_SENTOSA is not set +# CONFIG_SIBYTE_BIGSUR is not set +# CONFIG_SNI_RM is not set +# CONFIG_MACH_TX39XX is not set +# CONFIG_MACH_TX49XX is not set +# CONFIG_MIKROTIK_RB532 is not set +# CONFIG_WR_PPMC is not set +# CONFIG_CAVIUM_OCTEON_SIMULATOR is not set +# CONFIG_CAVIUM_OCTEON_REFERENCE_BOARD is not set +# CONFIG_ALCHEMY_GPIO_INDIRECT is not set +CONFIG_ARCH_SPARSEMEM_ENABLE=y +# CONFIG_LEMOTE_FULOONG2E is not set +# CONFIG_LEMOTE_FULOONG2F is not set +CONFIG_LEMOTE_YEELOONG2F=y +CONFIG_CS5536=y +CONFIG_SYS_HAS_MACH_PROM_INIT_CMDLINE=y +CONFIG_CS5536_MFGPT=y +CONFIG_UCA_SIZE=0x400000 +CONFIG_RWSEM_GENERIC_SPINLOCK=y +# CONFIG_ARCH_HAS_ILOG2_U32 is not set +# CONFIG_ARCH_HAS_ILOG2_U64 is not set +CONFIG_ARCH_SUPPORTS_OPROFILE=y +CONFIG_GENERIC_FIND_NEXT_BIT=y +CONFIG_GENERIC_HWEIGHT=y +CONFIG_GENERIC_CALIBRATE_DELAY=y +CONFIG_GENERIC_CLOCKEVENTS=y +CONFIG_GENERIC_TIME=y +CONFIG_GENERIC_CMOS_UPDATE=y +CONFIG_SCHED_OMIT_FRAME_POINTER=y +CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y +CONFIG_DMA_NONCOHERENT=y +CONFIG_DMA_NEED_PCI_MAP_STATE=y +CONFIG_EARLY_PRINTK=y +CONFIG_SYS_HAS_EARLY_PRINTK=y +CONFIG_SYS_SUPPORTS_HOTPLUG_CPU=y +CONFIG_I8259=y +# CONFIG_NO_IOPORT is not set +CONFIG_GENERIC_ISA_DMA=y +CONFIG_GENERIC_ISA_DMA_SUPPORT_BROKEN=y +# CONFIG_CPU_BIG_ENDIAN is not set +CONFIG_CPU_LITTLE_ENDIAN=y +CONFIG_SYS_SUPPORTS_LITTLE_ENDIAN=y +CONFIG_IRQ_CPU=y +CONFIG_BOOT_ELF32=y +CONFIG_MIPS_L1_CACHE_SHIFT=5 + +# +# CPU selection +# +# CONFIG_CPU_LOONGSON2E is not set +CONFIG_CPU_LOONGSON2F=y +# CONFIG_CPU_MIPS32_R1 is not set +# CONFIG_CPU_MIPS32_R2 is not set +# CONFIG_CPU_MIPS64_R1 is not set +# CONFIG_CPU_MIPS64_R2 is not set +# CONFIG_CPU_R3000 is not set +# CONFIG_CPU_TX39XX is not set +# CONFIG_CPU_VR41XX is not set +# CONFIG_CPU_R4300 is not set +# CONFIG_CPU_R4X00 is not set +# CONFIG_CPU_TX49XX is not set +# CONFIG_CPU_R5000 is not set +# CONFIG_CPU_R5432 is not set +# CONFIG_CPU_R5500 is not set +# CONFIG_CPU_R6000 is not set +# CONFIG_CPU_NEVADA is not set +# CONFIG_CPU_R8000 is not set +# CONFIG_CPU_R10000 is not set +# CONFIG_CPU_RM7000 is not set +# CONFIG_CPU_RM9000 is not set +# CONFIG_CPU_SB1 is not set +# CONFIG_CPU_CAVIUM_OCTEON is not set +CONFIG_CPU_LOONGSON2=y +CONFIG_SYS_HAS_CPU_LOONGSON2F=y +CONFIG_SYS_SUPPORTS_32BIT_KERNEL=y +CONFIG_SYS_SUPPORTS_64BIT_KERNEL=y +CONFIG_CPU_SUPPORTS_32BIT_KERNEL=y +CONFIG_CPU_SUPPORTS_64BIT_KERNEL=y + +# +# Kernel type +# +# CONFIG_32BIT is not set +CONFIG_64BIT=y +# CONFIG_PAGE_SIZE_4KB is not set +# CONFIG_PAGE_SIZE_8KB is not set +CONFIG_PAGE_SIZE_16KB=y +# CONFIG_PAGE_SIZE_32KB is not set +# CONFIG_PAGE_SIZE_64KB is not set +CONFIG_BOARD_SCACHE=y +CONFIG_MIPS_MT_DISABLED=y +# CONFIG_MIPS_MT_SMP is not set +# CONFIG_MIPS_MT_SMTC is not set +CONFIG_CPU_HAS_WB=y +CONFIG_CPU_HAS_SYNC=y +CONFIG_GENERIC_HARDIRQS=y +CONFIG_GENERIC_IRQ_PROBE=y +CONFIG_CPU_SUPPORTS_HIGHMEM=y +CONFIG_SYS_SUPPORTS_HIGHMEM=y +CONFIG_ARCH_FLATMEM_ENABLE=y +CONFIG_ARCH_POPULATES_NODE_MAP=y +CONFIG_SELECT_MEMORY_MODEL=y +# CONFIG_FLATMEM_MANUAL is not set +# CONFIG_DISCONTIGMEM_MANUAL is not set +CONFIG_SPARSEMEM_MANUAL=y +CONFIG_SPARSEMEM=y +CONFIG_HAVE_MEMORY_PRESENT=y +CONFIG_SPARSEMEM_STATIC=y + +# +# Memory hotplug is currently incompatible with Software Suspend +# +CONFIG_PAGEFLAGS_EXTENDED=y +CONFIG_SPLIT_PTLOCK_CPUS=4 +CONFIG_PHYS_ADDR_T_64BIT=y +CONFIG_ZONE_DMA_FLAG=0 +CONFIG_VIRT_TO_BUS=y +CONFIG_HAVE_MLOCK=y +CONFIG_HAVE_MLOCKED_PAGE_BIT=y +CONFIG_DEFAULT_MMAP_MIN_ADDR=4096 +CONFIG_TICK_ONESHOT=y +CONFIG_NO_HZ=y +CONFIG_HIGH_RES_TIMERS=y +CONFIG_GENERIC_CLOCKEVENTS_BUILD=y +# CONFIG_HZ_48 is not set +# CONFIG_HZ_100 is not set +# CONFIG_HZ_128 is not set +CONFIG_HZ_250=y +# CONFIG_HZ_256 is not set +# CONFIG_HZ_1000 is not set +# CONFIG_HZ_1024 is not set +CONFIG_SYS_SUPPORTS_ARBIT_HZ=y +CONFIG_HZ=250 +# CONFIG_PREEMPT_NONE is not set +CONFIG_PREEMPT_VOLUNTARY=y +# CONFIG_PREEMPT is not set +CONFIG_KEXEC=y +# CONFIG_SECCOMP is not set +CONFIG_LOCKDEP_SUPPORT=y +CONFIG_STACKTRACE_SUPPORT=y +CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" +CONFIG_CONSTRUCTORS=y + +# +# General setup +# +CONFIG_EXPERIMENTAL=y +CONFIG_BROKEN_ON_SMP=y +CONFIG_INIT_ENV_ARG_LIMIT=32 +CONFIG_LOCALVERSION="" +# CONFIG_LOCALVERSION_AUTO is not set +CONFIG_SWAP=y +CONFIG_SYSVIPC=y +CONFIG_SYSVIPC_SYSCTL=y +CONFIG_POSIX_MQUEUE=y +CONFIG_POSIX_MQUEUE_SYSCTL=y +CONFIG_BSD_PROCESS_ACCT=y +CONFIG_BSD_PROCESS_ACCT_V3=y +# CONFIG_TASKSTATS is not set +CONFIG_AUDIT=y + +# +# RCU Subsystem +# +CONFIG_CLASSIC_RCU=y +# CONFIG_TREE_RCU is not set +# CONFIG_PREEMPT_RCU is not set +# CONFIG_TREE_RCU_TRACE is not set +# CONFIG_PREEMPT_RCU_TRACE is not set +CONFIG_IKCONFIG=y +CONFIG_IKCONFIG_PROC=y +CONFIG_LOG_BUF_SHIFT=15 +# CONFIG_GROUP_SCHED is not set +# CONFIG_CGROUPS is not set +CONFIG_SYSFS_DEPRECATED=y +CONFIG_SYSFS_DEPRECATED_V2=y +# CONFIG_RELAY is not set +# CONFIG_NAMESPACES is not set +CONFIG_BLK_DEV_INITRD=y +CONFIG_INITRAMFS_SOURCE="" +CONFIG_RD_GZIP=y +# CONFIG_RD_BZIP2 is not set +# CONFIG_RD_LZMA is not set +CONFIG_CC_OPTIMIZE_FOR_SIZE=y +CONFIG_SYSCTL=y +CONFIG_ANON_INODES=y +CONFIG_EMBEDDED=y +CONFIG_SYSCTL_SYSCALL=y +CONFIG_KALLSYMS=y +# CONFIG_KALLSYMS_EXTRA_PASS is not set +CONFIG_HOTPLUG=y +CONFIG_PRINTK=y +CONFIG_BUG=y +CONFIG_ELF_CORE=y +CONFIG_PCSPKR_PLATFORM=y +CONFIG_BASE_FULL=y +CONFIG_FUTEX=y +CONFIG_EPOLL=y +CONFIG_SIGNALFD=y +CONFIG_TIMERFD=y +CONFIG_EVENTFD=y +CONFIG_SHMEM=y +CONFIG_AIO=y + +# +# Performance Counters +# +CONFIG_VM_EVENT_COUNTERS=y +CONFIG_PCI_QUIRKS=y +# CONFIG_STRIP_ASM_SYMS is not set +CONFIG_COMPAT_BRK=y +CONFIG_SLAB=y +# CONFIG_SLUB is not set +# CONFIG_SLOB is not set +CONFIG_PROFILING=y +CONFIG_TRACEPOINTS=y +CONFIG_MARKERS=y +CONFIG_OPROFILE=m +CONFIG_HAVE_OPROFILE=y +CONFIG_HAVE_SYSCALL_WRAPPERS=y + +# +# GCOV-based kernel profiling +# +# CONFIG_GCOV_KERNEL is not set +# CONFIG_SLOW_WORK is not set +# CONFIG_HAVE_GENERIC_DMA_COHERENT is not set +CONFIG_SLABINFO=y +CONFIG_RT_MUTEXES=y +CONFIG_BASE_SMALL=0 +CONFIG_MODULES=y +# CONFIG_MODULE_FORCE_LOAD is not set +CONFIG_MODULE_UNLOAD=y +CONFIG_MODULE_FORCE_UNLOAD=y +CONFIG_MODVERSIONS=y +# CONFIG_MODULE_SRCVERSION_ALL is not set +CONFIG_BLOCK=y +# CONFIG_BLK_DEV_BSG is not set +# CONFIG_BLK_DEV_INTEGRITY is not set +CONFIG_BLOCK_COMPAT=y + +# +# IO Schedulers +# +CONFIG_IOSCHED_NOOP=y +CONFIG_IOSCHED_AS=y +CONFIG_IOSCHED_DEADLINE=y +CONFIG_IOSCHED_CFQ=y +# CONFIG_DEFAULT_AS is not set +# CONFIG_DEFAULT_DEADLINE is not set +CONFIG_DEFAULT_CFQ=y +# CONFIG_DEFAULT_NOOP is not set +CONFIG_DEFAULT_IOSCHED="cfq" +# CONFIG_PROBE_INITRD_HEADER is not set +CONFIG_FREEZER=y + +# +# Bus options (PCI, PCMCIA, EISA, ISA, TC) +# +CONFIG_HW_HAS_PCI=y +CONFIG_PCI=y +CONFIG_PCI_DOMAINS=y +# CONFIG_ARCH_SUPPORTS_MSI is not set +CONFIG_PCI_LEGACY=y +# CONFIG_PCI_STUB is not set +# CONFIG_PCI_IOV is not set +CONFIG_ISA=y +CONFIG_MMU=y +# CONFIG_PCCARD is not set +CONFIG_HOTPLUG_PCI=m +CONFIG_HOTPLUG_PCI_FAKE=m +CONFIG_HOTPLUG_PCI_CPCI=y +CONFIG_HOTPLUG_PCI_SHPC=m + +# +# Executable file formats +# +CONFIG_BINFMT_ELF=y +# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set +# CONFIG_HAVE_AOUT is not set +CONFIG_BINFMT_MISC=m +CONFIG_MIPS32_COMPAT=y +CONFIG_COMPAT=y +CONFIG_SYSVIPC_COMPAT=y +CONFIG_MIPS32_O32=y +CONFIG_MIPS32_N32=y +CONFIG_BINFMT_ELF32=y + +# +# Power management options +# +CONFIG_ARCH_HIBERNATION_POSSIBLE=y +CONFIG_ARCH_SUSPEND_POSSIBLE=y +CONFIG_PM=y +# CONFIG_PM_DEBUG is not set +CONFIG_PM_SLEEP=y +CONFIG_SUSPEND=y +CONFIG_SUSPEND_FREEZER=y +CONFIG_HIBERNATION_NVS=y +CONFIG_HIBERNATION=y +CONFIG_PM_STD_PARTITION="/dev/hda3" + +# +# CPU Frequency scaling +# +CONFIG_CPU_FREQ=y +CONFIG_CPU_FREQ_TABLE=y +# CONFIG_CPU_FREQ_DEBUG is not set +CONFIG_CPU_FREQ_STAT=y +# CONFIG_CPU_FREQ_STAT_DETAILS is not set +# CONFIG_CPU_FREQ_DEFAULT_GOV_PERFORMANCE is not set +# CONFIG_CPU_FREQ_DEFAULT_GOV_POWERSAVE is not set +# CONFIG_CPU_FREQ_DEFAULT_GOV_USERSPACE is not set +# CONFIG_CPU_FREQ_DEFAULT_GOV_ONDEMAND is not set +CONFIG_CPU_FREQ_DEFAULT_GOV_CONSERVATIVE=y +CONFIG_CPU_FREQ_GOV_PERFORMANCE=y +# CONFIG_CPU_FREQ_GOV_POWERSAVE is not set +# CONFIG_CPU_FREQ_GOV_USERSPACE is not set +# CONFIG_CPU_FREQ_GOV_ONDEMAND is not set +CONFIG_CPU_FREQ_GOV_CONSERVATIVE=y +CONFIG_LOONGSON2F_CPU_FREQ=y +CONFIG_NET=y + +# +# Networking options +# +CONFIG_PACKET=y +CONFIG_PACKET_MMAP=y +CONFIG_UNIX=y +CONFIG_XFRM=y +CONFIG_XFRM_USER=m +# CONFIG_XFRM_SUB_POLICY is not set +# CONFIG_XFRM_MIGRATE is not set +# CONFIG_XFRM_STATISTICS is not set +CONFIG_XFRM_IPCOMP=m +CONFIG_NET_KEY=m +# CONFIG_NET_KEY_MIGRATE is not set +CONFIG_INET=y +CONFIG_IP_MULTICAST=y +CONFIG_IP_ADVANCED_ROUTER=y +CONFIG_ASK_IP_FIB_HASH=y +# CONFIG_IP_FIB_TRIE is not set +CONFIG_IP_FIB_HASH=y +CONFIG_IP_MULTIPLE_TABLES=y +CONFIG_IP_ROUTE_MULTIPATH=y +CONFIG_IP_ROUTE_VERBOSE=y +# CONFIG_IP_PNP is not set +CONFIG_NET_IPIP=m +CONFIG_NET_IPGRE=m +CONFIG_NET_IPGRE_BROADCAST=y +CONFIG_IP_MROUTE=y +CONFIG_IP_PIMSM_V1=y +CONFIG_IP_PIMSM_V2=y +# CONFIG_ARPD is not set +CONFIG_SYN_COOKIES=y +CONFIG_INET_AH=m +CONFIG_INET_ESP=m +CONFIG_INET_IPCOMP=m +CONFIG_INET_XFRM_TUNNEL=m +CONFIG_INET_TUNNEL=m +CONFIG_INET_XFRM_MODE_TRANSPORT=m +CONFIG_INET_XFRM_MODE_TUNNEL=m +CONFIG_INET_XFRM_MODE_BEET=y +CONFIG_INET_LRO=y +CONFIG_INET_DIAG=m +CONFIG_INET_TCP_DIAG=m +CONFIG_TCP_CONG_ADVANCED=y +CONFIG_TCP_CONG_BIC=y +CONFIG_TCP_CONG_CUBIC=m +CONFIG_TCP_CONG_WESTWOOD=m +CONFIG_TCP_CONG_HTCP=m +CONFIG_TCP_CONG_HSTCP=m +CONFIG_TCP_CONG_HYBLA=m +CONFIG_TCP_CONG_VEGAS=m +CONFIG_TCP_CONG_SCALABLE=m +CONFIG_TCP_CONG_LP=m +CONFIG_TCP_CONG_VENO=m +# CONFIG_TCP_CONG_YEAH is not set +# CONFIG_TCP_CONG_ILLINOIS is not set +CONFIG_DEFAULT_BIC=y +# CONFIG_DEFAULT_CUBIC is not set +# CONFIG_DEFAULT_HTCP is not set +# CONFIG_DEFAULT_VEGAS is not set +# CONFIG_DEFAULT_WESTWOOD is not set +# CONFIG_DEFAULT_RENO is not set +CONFIG_DEFAULT_TCP_CONG="bic" +# CONFIG_TCP_MD5SIG is not set +CONFIG_IPV6=m +CONFIG_IPV6_PRIVACY=y +# CONFIG_IPV6_ROUTER_PREF is not set +# CONFIG_IPV6_OPTIMISTIC_DAD is not set +CONFIG_INET6_AH=m +CONFIG_INET6_ESP=m +CONFIG_INET6_IPCOMP=m +# CONFIG_IPV6_MIP6 is not set +CONFIG_INET6_XFRM_TUNNEL=m +CONFIG_INET6_TUNNEL=m +CONFIG_INET6_XFRM_MODE_TRANSPORT=m +CONFIG_INET6_XFRM_MODE_TUNNEL=m +CONFIG_INET6_XFRM_MODE_BEET=m +# CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION is not set +CONFIG_IPV6_SIT=m +CONFIG_IPV6_NDISC_NODETYPE=y +CONFIG_IPV6_TUNNEL=m +# CONFIG_IPV6_MULTIPLE_TABLES is not set +# CONFIG_IPV6_MROUTE is not set +# CONFIG_NETLABEL is not set +CONFIG_NETWORK_SECMARK=y +CONFIG_NETFILTER=y +# CONFIG_NETFILTER_DEBUG is not set +CONFIG_NETFILTER_ADVANCED=y +CONFIG_BRIDGE_NETFILTER=y + +# +# Core Netfilter Configuration +# +CONFIG_NETFILTER_NETLINK=m +CONFIG_NETFILTER_NETLINK_QUEUE=m +CONFIG_NETFILTER_NETLINK_LOG=m +# CONFIG_NF_CONNTRACK is not set +# CONFIG_NETFILTER_TPROXY is not set +CONFIG_NETFILTER_XTABLES=m +CONFIG_NETFILTER_XT_TARGET_CLASSIFY=m +# CONFIG_NETFILTER_XT_TARGET_DSCP is not set +CONFIG_NETFILTER_XT_TARGET_HL=m +# CONFIG_NETFILTER_XT_TARGET_LED is not set +CONFIG_NETFILTER_XT_TARGET_MARK=m +# CONFIG_NETFILTER_XT_TARGET_NFLOG is not set +CONFIG_NETFILTER_XT_TARGET_NFQUEUE=m +# CONFIG_NETFILTER_XT_TARGET_RATEEST is not set +# CONFIG_NETFILTER_XT_TARGET_TRACE is not set +CONFIG_NETFILTER_XT_TARGET_SECMARK=m +# CONFIG_NETFILTER_XT_TARGET_TCPMSS is not set +# CONFIG_NETFILTER_XT_TARGET_TCPOPTSTRIP is not set +CONFIG_NETFILTER_XT_MATCH_COMMENT=m +CONFIG_NETFILTER_XT_MATCH_DCCP=m +# CONFIG_NETFILTER_XT_MATCH_DSCP is not set +CONFIG_NETFILTER_XT_MATCH_ESP=m +# CONFIG_NETFILTER_XT_MATCH_HASHLIMIT is not set +CONFIG_NETFILTER_XT_MATCH_HL=m +# CONFIG_NETFILTER_XT_MATCH_IPRANGE is not set +CONFIG_NETFILTER_XT_MATCH_LENGTH=m +CONFIG_NETFILTER_XT_MATCH_LIMIT=m +CONFIG_NETFILTER_XT_MATCH_MAC=m +CONFIG_NETFILTER_XT_MATCH_MARK=m +CONFIG_NETFILTER_XT_MATCH_MULTIPORT=m +# CONFIG_NETFILTER_XT_MATCH_OWNER is not set +CONFIG_NETFILTER_XT_MATCH_POLICY=m +CONFIG_NETFILTER_XT_MATCH_PHYSDEV=m +CONFIG_NETFILTER_XT_MATCH_PKTTYPE=m +CONFIG_NETFILTER_XT_MATCH_QUOTA=m +# CONFIG_NETFILTER_XT_MATCH_RATEEST is not set +CONFIG_NETFILTER_XT_MATCH_REALM=m +# CONFIG_NETFILTER_XT_MATCH_RECENT is not set +CONFIG_NETFILTER_XT_MATCH_SCTP=m +CONFIG_NETFILTER_XT_MATCH_STATISTIC=m +CONFIG_NETFILTER_XT_MATCH_STRING=m +CONFIG_NETFILTER_XT_MATCH_TCPMSS=m +# CONFIG_NETFILTER_XT_MATCH_TIME is not set +# CONFIG_NETFILTER_XT_MATCH_U32 is not set +# CONFIG_NETFILTER_XT_MATCH_OSF is not set +CONFIG_IP_VS=m +# CONFIG_IP_VS_IPV6 is not set +# CONFIG_IP_VS_DEBUG is not set +CONFIG_IP_VS_TAB_BITS=12 + +# +# IPVS transport protocol load balancing support +# +CONFIG_IP_VS_PROTO_TCP=y +CONFIG_IP_VS_PROTO_UDP=y +CONFIG_IP_VS_PROTO_AH_ESP=y +CONFIG_IP_VS_PROTO_ESP=y +CONFIG_IP_VS_PROTO_AH=y + +# +# IPVS scheduler +# +CONFIG_IP_VS_RR=m +CONFIG_IP_VS_WRR=m +CONFIG_IP_VS_LC=m +CONFIG_IP_VS_WLC=m +CONFIG_IP_VS_LBLC=m +CONFIG_IP_VS_LBLCR=m +CONFIG_IP_VS_DH=m +CONFIG_IP_VS_SH=m +CONFIG_IP_VS_SED=m +CONFIG_IP_VS_NQ=m + +# +# IPVS application helper +# +CONFIG_IP_VS_FTP=m + +# +# IP: Netfilter Configuration +# +# CONFIG_NF_DEFRAG_IPV4 is not set +CONFIG_IP_NF_QUEUE=m +CONFIG_IP_NF_IPTABLES=m +CONFIG_IP_NF_MATCH_ADDRTYPE=m +CONFIG_IP_NF_MATCH_AH=m +CONFIG_IP_NF_MATCH_ECN=m +CONFIG_IP_NF_MATCH_TTL=m +CONFIG_IP_NF_FILTER=m +CONFIG_IP_NF_TARGET_REJECT=m +CONFIG_IP_NF_TARGET_LOG=m +CONFIG_IP_NF_TARGET_ULOG=m +CONFIG_IP_NF_MANGLE=m +CONFIG_IP_NF_TARGET_ECN=m +CONFIG_IP_NF_TARGET_TTL=m +CONFIG_IP_NF_RAW=m +# CONFIG_IP_NF_SECURITY is not set +CONFIG_IP_NF_ARPTABLES=m +CONFIG_IP_NF_ARPFILTER=m +CONFIG_IP_NF_ARP_MANGLE=m + +# +# IPv6: Netfilter Configuration +# +CONFIG_IP6_NF_QUEUE=m +CONFIG_IP6_NF_IPTABLES=m +CONFIG_IP6_NF_MATCH_AH=m +CONFIG_IP6_NF_MATCH_EUI64=m +CONFIG_IP6_NF_MATCH_FRAG=m +CONFIG_IP6_NF_MATCH_OPTS=m +CONFIG_IP6_NF_MATCH_HL=m +CONFIG_IP6_NF_MATCH_IPV6HEADER=m +# CONFIG_IP6_NF_MATCH_MH is not set +CONFIG_IP6_NF_MATCH_RT=m +CONFIG_IP6_NF_TARGET_HL=m +CONFIG_IP6_NF_TARGET_LOG=m +CONFIG_IP6_NF_FILTER=m +CONFIG_IP6_NF_TARGET_REJECT=m +CONFIG_IP6_NF_MANGLE=m +CONFIG_IP6_NF_RAW=m +# CONFIG_IP6_NF_SECURITY is not set + +# +# DECnet: Netfilter Configuration +# +CONFIG_DECNET_NF_GRABULATOR=m +CONFIG_BRIDGE_NF_EBTABLES=m +CONFIG_BRIDGE_EBT_BROUTE=m +CONFIG_BRIDGE_EBT_T_FILTER=m +CONFIG_BRIDGE_EBT_T_NAT=m +CONFIG_BRIDGE_EBT_802_3=m +CONFIG_BRIDGE_EBT_AMONG=m +CONFIG_BRIDGE_EBT_ARP=m +CONFIG_BRIDGE_EBT_IP=m +# CONFIG_BRIDGE_EBT_IP6 is not set +CONFIG_BRIDGE_EBT_LIMIT=m +CONFIG_BRIDGE_EBT_MARK=m +CONFIG_BRIDGE_EBT_PKTTYPE=m +CONFIG_BRIDGE_EBT_STP=m +CONFIG_BRIDGE_EBT_VLAN=m +CONFIG_BRIDGE_EBT_ARPREPLY=m +CONFIG_BRIDGE_EBT_DNAT=m +CONFIG_BRIDGE_EBT_MARK_T=m +CONFIG_BRIDGE_EBT_REDIRECT=m +CONFIG_BRIDGE_EBT_SNAT=m +CONFIG_BRIDGE_EBT_LOG=m +CONFIG_BRIDGE_EBT_ULOG=m +# CONFIG_BRIDGE_EBT_NFLOG is not set +CONFIG_IP_DCCP=m +CONFIG_INET_DCCP_DIAG=m + +# +# DCCP CCIDs Configuration (EXPERIMENTAL) +# +# CONFIG_IP_DCCP_CCID2_DEBUG is not set +CONFIG_IP_DCCP_CCID3=y +# CONFIG_IP_DCCP_CCID3_DEBUG is not set +CONFIG_IP_DCCP_CCID3_RTO=100 +CONFIG_IP_DCCP_TFRC_LIB=y +CONFIG_IP_SCTP=m +# CONFIG_SCTP_DBG_MSG is not set +# CONFIG_SCTP_DBG_OBJCNT is not set +# CONFIG_SCTP_HMAC_NONE is not set +# CONFIG_SCTP_HMAC_SHA1 is not set +CONFIG_SCTP_HMAC_MD5=y +CONFIG_TIPC=m +CONFIG_TIPC_ADVANCED=y +CONFIG_TIPC_ZONES=3 +CONFIG_TIPC_CLUSTERS=1 +CONFIG_TIPC_NODES=255 +CONFIG_TIPC_SLAVE_NODES=0 +CONFIG_TIPC_PORTS=8191 +CONFIG_TIPC_LOG=0 +# CONFIG_TIPC_DEBUG is not set +CONFIG_ATM=y +CONFIG_ATM_CLIP=y +# CONFIG_ATM_CLIP_NO_ICMP is not set +CONFIG_ATM_LANE=m +CONFIG_ATM_MPOA=m +CONFIG_ATM_BR2684=m +# CONFIG_ATM_BR2684_IPFILTER is not set +CONFIG_STP=m +CONFIG_BRIDGE=m +# CONFIG_NET_DSA is not set +CONFIG_VLAN_8021Q=m +# CONFIG_VLAN_8021Q_GVRP is not set +CONFIG_DECNET=m +# CONFIG_DECNET_ROUTER is not set +CONFIG_LLC=m +CONFIG_LLC2=m +CONFIG_IPX=m +# CONFIG_IPX_INTERN is not set +CONFIG_ATALK=m +CONFIG_DEV_APPLETALK=m +# CONFIG_COPS is not set +CONFIG_IPDDP=m +CONFIG_IPDDP_ENCAP=y +CONFIG_IPDDP_DECAP=y +CONFIG_X25=m +CONFIG_LAPB=m +CONFIG_ECONET=m +CONFIG_ECONET_AUNUDP=y +CONFIG_ECONET_NATIVE=y +CONFIG_WAN_ROUTER=m +# CONFIG_PHONET is not set +# CONFIG_IEEE802154 is not set +CONFIG_NET_SCHED=y + +# +# Queueing/Scheduling +# +CONFIG_NET_SCH_CBQ=m +CONFIG_NET_SCH_HTB=m +CONFIG_NET_SCH_HFSC=m +CONFIG_NET_SCH_ATM=m +CONFIG_NET_SCH_PRIO=m +# CONFIG_NET_SCH_MULTIQ is not set +CONFIG_NET_SCH_RED=m +CONFIG_NET_SCH_SFQ=m +CONFIG_NET_SCH_TEQL=m +CONFIG_NET_SCH_TBF=m +CONFIG_NET_SCH_GRED=m +CONFIG_NET_SCH_DSMARK=m +CONFIG_NET_SCH_NETEM=m +# CONFIG_NET_SCH_DRR is not set +CONFIG_NET_SCH_INGRESS=m + +# +# Classification +# +CONFIG_NET_CLS=y +CONFIG_NET_CLS_BASIC=m +CONFIG_NET_CLS_TCINDEX=m +CONFIG_NET_CLS_ROUTE4=m +CONFIG_NET_CLS_ROUTE=y +CONFIG_NET_CLS_FW=m +CONFIG_NET_CLS_U32=m +CONFIG_CLS_U32_PERF=y +CONFIG_CLS_U32_MARK=y +CONFIG_NET_CLS_RSVP=m +CONFIG_NET_CLS_RSVP6=m +# CONFIG_NET_CLS_FLOW is not set +CONFIG_NET_EMATCH=y +CONFIG_NET_EMATCH_STACK=32 +CONFIG_NET_EMATCH_CMP=m +CONFIG_NET_EMATCH_NBYTE=m +CONFIG_NET_EMATCH_U32=m +CONFIG_NET_EMATCH_META=m +CONFIG_NET_EMATCH_TEXT=m +CONFIG_NET_CLS_ACT=y +CONFIG_NET_ACT_POLICE=m +CONFIG_NET_ACT_GACT=m +CONFIG_GACT_PROB=y +CONFIG_NET_ACT_MIRRED=m +CONFIG_NET_ACT_IPT=m +# CONFIG_NET_ACT_NAT is not set +CONFIG_NET_ACT_PEDIT=m +CONFIG_NET_ACT_SIMP=m +# CONFIG_NET_ACT_SKBEDIT is not set +CONFIG_NET_CLS_IND=y +CONFIG_NET_SCH_FIFO=y +# CONFIG_DCB is not set + +# +# Network testing +# +CONFIG_NET_PKTGEN=m +# CONFIG_NET_DROP_MONITOR is not set +CONFIG_HAMRADIO=y + +# +# Packet Radio protocols +# +CONFIG_AX25=m +# CONFIG_AX25_DAMA_SLAVE is not set +CONFIG_NETROM=m +CONFIG_ROSE=m + +# +# AX.25 network device drivers +# +CONFIG_MKISS=m +CONFIG_6PACK=m +CONFIG_BPQETHER=m +CONFIG_BAYCOM_SER_FDX=m +CONFIG_BAYCOM_SER_HDX=m +CONFIG_YAM=m +# CONFIG_CAN is not set +CONFIG_IRDA=m + +# +# IrDA protocols +# +CONFIG_IRLAN=m +CONFIG_IRNET=m +CONFIG_IRCOMM=m +# CONFIG_IRDA_ULTRA is not set + +# +# IrDA options +# +CONFIG_IRDA_CACHE_LAST_LSAP=y +CONFIG_IRDA_FAST_RR=y +CONFIG_IRDA_DEBUG=y + +# +# Infrared-port device drivers +# + +# +# SIR device drivers +# +CONFIG_IRTTY_SIR=m + +# +# Dongle support +# +CONFIG_DONGLE=y +CONFIG_ESI_DONGLE=m +CONFIG_ACTISYS_DONGLE=m +CONFIG_TEKRAM_DONGLE=m +CONFIG_TOIM3232_DONGLE=m +CONFIG_LITELINK_DONGLE=m +CONFIG_MA600_DONGLE=m +CONFIG_GIRBIL_DONGLE=m +CONFIG_MCP2120_DONGLE=m +CONFIG_OLD_BELKIN_DONGLE=m +CONFIG_ACT200L_DONGLE=m +# CONFIG_KINGSUN_DONGLE is not set +# CONFIG_KSDAZZLE_DONGLE is not set +# CONFIG_KS959_DONGLE is not set + +# +# FIR device drivers +# +CONFIG_USB_IRDA=m +CONFIG_SIGMATEL_FIR=m +CONFIG_VLSI_FIR=m +CONFIG_MCS_FIR=m +CONFIG_BT=m +CONFIG_BT_L2CAP=m +CONFIG_BT_SCO=m +CONFIG_BT_RFCOMM=m +CONFIG_BT_RFCOMM_TTY=y +CONFIG_BT_BNEP=m +CONFIG_BT_BNEP_MC_FILTER=y +CONFIG_BT_BNEP_PROTO_FILTER=y +CONFIG_BT_HIDP=m + +# +# Bluetooth device drivers +# +# CONFIG_BT_HCIBTUSB is not set +# CONFIG_BT_HCIBTSDIO is not set +CONFIG_BT_HCIUART=m +CONFIG_BT_HCIUART_H4=y +CONFIG_BT_HCIUART_BCSP=y +# CONFIG_BT_HCIUART_LL is not set +CONFIG_BT_HCIBCM203X=m +CONFIG_BT_HCIBPA10X=m +CONFIG_BT_HCIBFUSB=m +CONFIG_BT_HCIVHCI=m +CONFIG_AF_RXRPC=m +# CONFIG_AF_RXRPC_DEBUG is not set +# CONFIG_RXKAD is not set +CONFIG_FIB_RULES=y +CONFIG_WIRELESS=y +CONFIG_CFG80211=y +# CONFIG_CFG80211_REG_DEBUG is not set +# CONFIG_CFG80211_DEBUGFS is not set +CONFIG_WIRELESS_OLD_REGULATORY=y +CONFIG_WIRELESS_EXT=y +CONFIG_WIRELESS_EXT_SYSFS=y +# CONFIG_LIB80211 is not set +CONFIG_MAC80211=y +CONFIG_MAC80211_DEFAULT_PS=y +CONFIG_MAC80211_DEFAULT_PS_VALUE=1 + +# +# Rate control algorithm selection +# +CONFIG_MAC80211_RC_PID=y +CONFIG_MAC80211_RC_MINSTREL=y +# CONFIG_MAC80211_RC_DEFAULT_PID is not set +CONFIG_MAC80211_RC_DEFAULT_MINSTREL=y +CONFIG_MAC80211_RC_DEFAULT="minstrel" +# CONFIG_MAC80211_MESH is not set +# CONFIG_MAC80211_LEDS is not set +# CONFIG_MAC80211_DEBUGFS is not set +# CONFIG_MAC80211_DEBUG_MENU is not set +# CONFIG_WIMAX 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=m +CONFIG_FIRMWARE_IN_KERNEL=y +CONFIG_EXTRA_FIRMWARE="" +# CONFIG_SYS_HYPERVISOR is not set +CONFIG_CONNECTOR=m +CONFIG_MTD=m +# CONFIG_MTD_DEBUG is not set +CONFIG_MTD_CONCAT=m +CONFIG_MTD_PARTITIONS=y +# CONFIG_MTD_TESTS is not set +# CONFIG_MTD_REDBOOT_PARTS is not set +# CONFIG_MTD_AR7_PARTS is not set + +# +# User Modules And Translation Layers +# +CONFIG_MTD_CHAR=m +CONFIG_MTD_BLKDEVS=m +CONFIG_MTD_BLOCK=m +# CONFIG_MTD_BLOCK_RO is not set +# CONFIG_FTL is not set +# CONFIG_NFTL is not set +# CONFIG_INFTL is not set +# CONFIG_RFD_FTL is not set +# CONFIG_SSFDC is not set +# CONFIG_MTD_OOPS is not set + +# +# RAM/ROM/Flash chip drivers +# +CONFIG_MTD_CFI=m +CONFIG_MTD_JEDECPROBE=m +CONFIG_MTD_GEN_PROBE=m +# CONFIG_MTD_CFI_ADV_OPTIONS is not set +CONFIG_MTD_MAP_BANK_WIDTH_1=y +CONFIG_MTD_MAP_BANK_WIDTH_2=y +CONFIG_MTD_MAP_BANK_WIDTH_4=y +# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set +# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set +# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set +CONFIG_MTD_CFI_I1=y +CONFIG_MTD_CFI_I2=y +# CONFIG_MTD_CFI_I4 is not set +# CONFIG_MTD_CFI_I8 is not set +CONFIG_MTD_CFI_INTELEXT=m +CONFIG_MTD_CFI_AMDSTD=m +CONFIG_MTD_CFI_STAA=m +CONFIG_MTD_CFI_UTIL=m +CONFIG_MTD_RAM=m +CONFIG_MTD_ROM=m +CONFIG_MTD_ABSENT=m + +# +# Mapping drivers for chip access +# +CONFIG_MTD_COMPLEX_MAPPINGS=y +CONFIG_MTD_PHYSMAP=m +CONFIG_MTD_PHYSMAP_COMPAT=y +CONFIG_MTD_PHYSMAP_START=0x8000000 +CONFIG_MTD_PHYSMAP_LEN=0 +CONFIG_MTD_PHYSMAP_BANKWIDTH=2 +CONFIG_MTD_PCI=m +# CONFIG_MTD_INTEL_VR_NOR is not set +CONFIG_MTD_PLATRAM=m + +# +# Self-contained MTD device drivers +# +CONFIG_MTD_PMC551=m +# CONFIG_MTD_PMC551_BUGFIX is not set +# CONFIG_MTD_PMC551_DEBUG is not set +CONFIG_MTD_DATAFLASH=m +# CONFIG_MTD_DATAFLASH_WRITE_VERIFY is not set +# CONFIG_MTD_DATAFLASH_OTP is not set +CONFIG_MTD_M25P80=m +CONFIG_M25PXX_USE_FAST_READ=y +CONFIG_MTD_SLRAM=m +CONFIG_MTD_PHRAM=m +CONFIG_MTD_MTDRAM=m +CONFIG_MTDRAM_TOTAL_SIZE=4096 +CONFIG_MTDRAM_ERASE_SIZE=128 +CONFIG_MTD_BLOCK2MTD=m + +# +# Disk-On-Chip Device Drivers +# +CONFIG_MTD_DOC2000=m +CONFIG_MTD_DOC2001=m +CONFIG_MTD_DOC2001PLUS=m +CONFIG_MTD_DOCPROBE=m +CONFIG_MTD_DOCECC=m +# CONFIG_MTD_DOCPROBE_ADVANCED is not set +CONFIG_MTD_DOCPROBE_ADDRESS=0 +# CONFIG_MTD_NAND is not set +CONFIG_MTD_NAND_IDS=m +# CONFIG_MTD_ONENAND is not set + +# +# LPDDR flash memory drivers +# +# CONFIG_MTD_LPDDR is not set + +# +# UBI - Unsorted block images +# +# CONFIG_MTD_UBI is not set +# CONFIG_PARPORT is not set +CONFIG_PNP=y +CONFIG_PNP_DEBUG_MESSAGES=y + +# +# Protocols +# +CONFIG_ISAPNP=y +# CONFIG_PNPACPI 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=m +CONFIG_BLK_DEV_NBD=m +# 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=8192 +# CONFIG_BLK_DEV_XIP is not set +CONFIG_CDROM_PKTCDVD=m +CONFIG_CDROM_PKTCDVD_BUFFERS=8 +# CONFIG_CDROM_PKTCDVD_WCACHE is not set +CONFIG_ATA_OVER_ETH=m +# CONFIG_BLK_DEV_HD is not set +CONFIG_MISC_DEVICES=y +# CONFIG_PHANTOM is not set +# CONFIG_SGI_IOC4 is not set +# CONFIG_TIFM_CORE is not set +# CONFIG_ICS932S401 is not set +# CONFIG_ENCLOSURE_SERVICES is not set +# CONFIG_HP_ILO is not set +# CONFIG_ISL29003 is not set +# CONFIG_C2PORT is not set + +# +# EEPROM support +# +# CONFIG_EEPROM_AT24 is not set +# CONFIG_EEPROM_AT25 is not set +# CONFIG_EEPROM_LEGACY is not set +# CONFIG_EEPROM_MAX6875 is not set +CONFIG_EEPROM_93CX6=y +# CONFIG_CB710_CORE is not set +CONFIG_HAVE_IDE=y +CONFIG_IDE=y + +# +# Please see Documentation/ide/ide.txt for help/info on IDE drives +# +CONFIG_IDE_XFER_MODE=y +CONFIG_IDE_TIMINGS=y +CONFIG_IDE_ATAPI=y +# CONFIG_BLK_DEV_IDE_SATA is not set +CONFIG_IDE_GD=y +CONFIG_IDE_GD_ATA=y +# CONFIG_IDE_GD_ATAPI is not set +CONFIG_BLK_DEV_IDECD=m +CONFIG_BLK_DEV_IDECD_VERBOSE_ERRORS=y +# CONFIG_BLK_DEV_IDETAPE is not set +CONFIG_IDE_TASK_IOCTL=y +CONFIG_IDE_PROC_FS=y + +# +# IDE chipset support/bugfixes +# +# CONFIG_IDE_GENERIC is not set +# CONFIG_BLK_DEV_PLATFORM is not set +# CONFIG_BLK_DEV_IDEPNP is not set +CONFIG_BLK_DEV_IDEDMA_SFF=y + +# +# PCI IDE chipsets support +# +CONFIG_BLK_DEV_IDEPCI=y +# CONFIG_IDEPCI_PCIBUS_ORDER is not set +# CONFIG_BLK_DEV_OFFBOARD is not set +CONFIG_BLK_DEV_GENERIC=y +# CONFIG_BLK_DEV_OPTI621 is not set +CONFIG_BLK_DEV_IDEDMA_PCI=y +# CONFIG_BLK_DEV_AEC62XX is not set +# CONFIG_BLK_DEV_ALI15X3 is not set +CONFIG_BLK_DEV_AMD74XX=y +# CONFIG_BLK_DEV_CMD64X is not set +# CONFIG_BLK_DEV_TRIFLEX is not set +# CONFIG_BLK_DEV_CS5520 is not set +# CONFIG_BLK_DEV_CS5530 is not set +# CONFIG_BLK_DEV_HPT366 is not set +# CONFIG_BLK_DEV_JMICRON is not set +# CONFIG_BLK_DEV_SC1200 is not set +# CONFIG_BLK_DEV_PIIX is not set +# CONFIG_BLK_DEV_IT8172 is not set +# CONFIG_BLK_DEV_IT8213 is not set +# CONFIG_BLK_DEV_IT821X is not set +# CONFIG_BLK_DEV_NS87415 is not set +# CONFIG_BLK_DEV_PDC202XX_OLD is not set +# CONFIG_BLK_DEV_PDC202XX_NEW is not set +# CONFIG_BLK_DEV_SVWKS is not set +# CONFIG_BLK_DEV_SIIMAGE is not set +# CONFIG_BLK_DEV_SLC90E66 is not set +# CONFIG_BLK_DEV_TRM290 is not set +# CONFIG_BLK_DEV_VIA82CXXX is not set +# CONFIG_BLK_DEV_TC86C001 is not set + +# +# Other IDE chipsets support +# + +# +# Note: most of these also require special kernel boot parameters +# +# CONFIG_BLK_DEV_4DRIVES is not set +# CONFIG_BLK_DEV_ALI14XX is not set +# CONFIG_BLK_DEV_DTC2278 is not set +# CONFIG_BLK_DEV_HT6560B is not set +# CONFIG_BLK_DEV_QD65XX is not set +# CONFIG_BLK_DEV_UMC8672 is not set +CONFIG_BLK_DEV_IDEDMA=y + +# +# SCSI device support +# +CONFIG_RAID_ATTRS=m +CONFIG_SCSI=y +CONFIG_SCSI_DMA=y +# CONFIG_SCSI_TGT is not set +CONFIG_SCSI_NETLINK=y +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=m +CONFIG_BLK_DEV_SR_VENDOR=y +CONFIG_CHR_DEV_SG=m +# CONFIG_CHR_DEV_SCH is not set +CONFIG_SCSI_MULTI_LUN=y +CONFIG_SCSI_CONSTANTS=y +CONFIG_SCSI_LOGGING=y +# CONFIG_SCSI_SCAN_ASYNC is not set +CONFIG_SCSI_WAIT_SCAN=m + +# +# SCSI Transports +# +CONFIG_SCSI_SPI_ATTRS=m +CONFIG_SCSI_FC_ATTRS=m +CONFIG_SCSI_ISCSI_ATTRS=m +# CONFIG_SCSI_SAS_LIBSAS is not set +CONFIG_SCSI_SRP_ATTRS=m +# CONFIG_SCSI_LOWLEVEL is not set +# CONFIG_SCSI_DH is not set +# CONFIG_SCSI_OSD_INITIATOR is not set +# CONFIG_ATA is not set +CONFIG_MD=y +CONFIG_BLK_DEV_MD=m +CONFIG_MD_LINEAR=m +CONFIG_MD_RAID0=m +CONFIG_MD_RAID1=m +CONFIG_MD_RAID10=m +CONFIG_MD_RAID456=m +CONFIG_MD_RAID6_PQ=m +CONFIG_MD_MULTIPATH=m +CONFIG_MD_FAULTY=m +CONFIG_BLK_DEV_DM=m +# CONFIG_DM_DEBUG is not set +CONFIG_DM_CRYPT=m +CONFIG_DM_SNAPSHOT=m +CONFIG_DM_MIRROR=m +# CONFIG_DM_LOG_USERSPACE is not set +CONFIG_DM_ZERO=m +CONFIG_DM_MULTIPATH=m +# CONFIG_DM_MULTIPATH_QL is not set +# CONFIG_DM_MULTIPATH_ST is not set +# CONFIG_DM_DELAY is not set +# CONFIG_DM_UEVENT is not set +# CONFIG_FUSION is not set + +# +# IEEE 1394 (FireWire) support +# + +# +# You can enable one or both FireWire driver stacks. +# + +# +# See the help texts for more information. +# +# CONFIG_FIREWIRE is not set +# CONFIG_IEEE1394 is not set +# CONFIG_I2O is not set +CONFIG_NETDEVICES=y +CONFIG_IFB=m +CONFIG_DUMMY=m +# CONFIG_BONDING is not set +CONFIG_MACVLAN=m +# CONFIG_EQUALIZER is not set +CONFIG_TUN=m +CONFIG_VETH=m +# CONFIG_NET_SB1000 is not set +# CONFIG_ARCNET is not set +CONFIG_PHYLIB=m + +# +# MII PHY device drivers +# +CONFIG_MARVELL_PHY=m +CONFIG_DAVICOM_PHY=m +CONFIG_QSEMI_PHY=m +CONFIG_LXT_PHY=m +CONFIG_CICADA_PHY=m +CONFIG_VITESSE_PHY=m +CONFIG_SMSC_PHY=m +# CONFIG_BROADCOM_PHY is not set +# CONFIG_ICPLUS_PHY is not set +CONFIG_REALTEK_PHY=m +# CONFIG_NATIONAL_PHY is not set +# CONFIG_STE10XP is not set +# CONFIG_LSI_ET1011C_PHY is not set +# CONFIG_MDIO_BITBANG is not set +CONFIG_NET_ETHERNET=y +CONFIG_MII=y +# CONFIG_AX88796 is not set +# CONFIG_HAPPYMEAL is not set +# CONFIG_SUNGEM is not set +# CONFIG_CASSINI is not set +# CONFIG_NET_VENDOR_3COM is not set +# CONFIG_NET_VENDOR_SMC is not set +# CONFIG_SMC91X is not set +# CONFIG_DM9000 is not set +# CONFIG_ENC28J60 is not set +# CONFIG_ETHOC is not set +# CONFIG_NET_VENDOR_RACAL is not set +# CONFIG_DNET is not set +# CONFIG_NET_TULIP is not set +# CONFIG_AT1700 is not set +# CONFIG_DEPCA is not set +# CONFIG_HP100 is not set +# CONFIG_NET_ISA is not set +# CONFIG_IBM_NEW_EMAC_ZMII is not set +# CONFIG_IBM_NEW_EMAC_RGMII is not set +# CONFIG_IBM_NEW_EMAC_TAH is not set +# CONFIG_IBM_NEW_EMAC_EMAC4 is not set +# CONFIG_IBM_NEW_EMAC_NO_FLOW_CTRL is not set +# CONFIG_IBM_NEW_EMAC_MAL_CLR_ICINTSTAT is not set +# CONFIG_IBM_NEW_EMAC_MAL_COMMON_ERR is not set +CONFIG_NET_PCI=y +# CONFIG_PCNET32 is not set +# CONFIG_AMD8111_ETH is not set +# CONFIG_ADAPTEC_STARFIRE is not set +# CONFIG_AC3200 is not set +# CONFIG_APRICOT is not set +# CONFIG_B44 is not set +# CONFIG_FORCEDETH is not set +# CONFIG_CS89x0 is not set +# CONFIG_TC35815 is not set +# CONFIG_E100 is not set +# CONFIG_FEALNX is not set +# CONFIG_NATSEMI is not set +# CONFIG_NE2K_PCI is not set +CONFIG_8139CP=m +CONFIG_8139TOO=y +# CONFIG_8139TOO_PIO is not set +CONFIG_8139TOO_TUNE_TWISTER=y +# CONFIG_8139TOO_8129 is not set +# CONFIG_8139_OLD_RX_RESET is not set +# CONFIG_R6040 is not set +# CONFIG_SIS900 is not set +# CONFIG_EPIC100 is not set +# CONFIG_SMSC9420 is not set +# CONFIG_SUNDANCE is not set +# CONFIG_TLAN is not set +# CONFIG_KS8842 is not set +# CONFIG_VIA_RHINE is not set +# CONFIG_SC92031 is not set +# CONFIG_ATL2 is not set +# CONFIG_NETDEV_1000 is not set +# CONFIG_NETDEV_10000 is not set +# CONFIG_TR is not set + +# +# Wireless LAN +# +# CONFIG_WLAN_PRE80211 is not set +CONFIG_WLAN_80211=y +# CONFIG_LIBERTAS is not set +# CONFIG_LIBERTAS_THINFIRM is not set +# CONFIG_ATMEL is not set +# CONFIG_AT76C50X_USB is not set +# CONFIG_PRISM54 is not set +# CONFIG_USB_ZD1201 is not set +# CONFIG_USB_NET_RNDIS_WLAN is not set +# CONFIG_RTL8180 is not set +CONFIG_RTL8187B=y +# CONFIG_ADM8211 is not set +# CONFIG_MAC80211_HWSIM is not set +# CONFIG_MWL8K is not set +# CONFIG_P54_COMMON is not set +# CONFIG_ATH5K is not set +# CONFIG_ATH9K is not set +# CONFIG_AR9170_USB is not set +# CONFIG_IPW2100 is not set +# CONFIG_IPW2200 is not set +# CONFIG_IWLWIFI is not set +# CONFIG_HOSTAP is not set +# CONFIG_B43 is not set +# CONFIG_B43LEGACY is not set +# CONFIG_ZD1211RW is not set +# CONFIG_RT2X00 is not set +# CONFIG_HERMES is not set +# CONFIG_WL12XX is not set +# CONFIG_IWM is not set + +# +# Enable WiMAX (Networking options) to see the WiMAX drivers +# + +# +# USB Network Adapters +# +CONFIG_USB_CATC=m +CONFIG_USB_KAWETH=m +CONFIG_USB_PEGASUS=m +CONFIG_USB_RTL8150=m +CONFIG_USB_USBNET=m +CONFIG_USB_NET_AX8817X=m +CONFIG_USB_NET_CDCETHER=m +# CONFIG_USB_NET_CDC_EEM is not set +# CONFIG_USB_NET_DM9601 is not set +# CONFIG_USB_NET_SMSC95XX is not set +CONFIG_USB_NET_GL620A=m +CONFIG_USB_NET_NET1080=m +CONFIG_USB_NET_PLUSB=m +# CONFIG_USB_NET_MCS7830 is not set +CONFIG_USB_NET_RNDIS_HOST=m +CONFIG_USB_NET_CDC_SUBSET=m +CONFIG_USB_ALI_M5632=y +CONFIG_USB_AN2720=y +CONFIG_USB_BELKIN=y +CONFIG_USB_ARMLINUX=y +CONFIG_USB_EPSON2888=y +# CONFIG_USB_KC2190 is not set +CONFIG_USB_NET_ZAURUS=m +# CONFIG_USB_NET_INT51X1 is not set +# CONFIG_WAN is not set +# CONFIG_ATM_DRIVERS is not set +# CONFIG_FDDI is not set +# CONFIG_HIPPI is not set +CONFIG_PPP=m +CONFIG_PPP_MULTILINK=y +CONFIG_PPP_FILTER=y +CONFIG_PPP_ASYNC=m +CONFIG_PPP_SYNC_TTY=m +CONFIG_PPP_DEFLATE=m +CONFIG_PPP_BSDCOMP=m +CONFIG_PPP_MPPE=m +CONFIG_PPPOE=m +CONFIG_PPPOATM=m +# CONFIG_PPPOL2TP is not set +# CONFIG_SLIP is not set +CONFIG_SLHC=m +# CONFIG_NET_FC is not set +CONFIG_NETCONSOLE=y +# CONFIG_NETCONSOLE_DYNAMIC is not set +CONFIG_NETPOLL=y +# CONFIG_NETPOLL_TRAP is not set +CONFIG_NET_POLL_CONTROLLER=y +# CONFIG_ISDN is not set +# CONFIG_PHONE 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=y +CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024 +CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768 +CONFIG_INPUT_JOYDEV=m +CONFIG_INPUT_EVDEV=m +# CONFIG_INPUT_EVBUG is not set + +# +# Input Device Drivers +# +CONFIG_INPUT_KEYBOARD=y +CONFIG_KEYBOARD_ATKBD=y +CONFIG_KEYBOARD_SUNKBD=m +CONFIG_KEYBOARD_LKKBD=m +CONFIG_KEYBOARD_XTKBD=m +CONFIG_KEYBOARD_NEWTON=m +# CONFIG_KEYBOARD_STOWAWAY is not set +# CONFIG_KEYBOARD_LM8323 is not set +CONFIG_INPUT_MOUSE=y +CONFIG_MOUSE_PS2=y +CONFIG_MOUSE_PS2_ALPS=y +CONFIG_MOUSE_PS2_LOGIPS2PP=y +CONFIG_MOUSE_PS2_SYNAPTICS=y +CONFIG_MOUSE_PS2_TRACKPOINT=y +# CONFIG_MOUSE_PS2_ELANTECH is not set +# CONFIG_MOUSE_PS2_TOUCHKIT is not set +CONFIG_MOUSE_SERIAL=m +# CONFIG_MOUSE_APPLETOUCH is not set +# CONFIG_MOUSE_BCM5974 is not set +CONFIG_MOUSE_INPORT=m +# CONFIG_MOUSE_ATIXL is not set +CONFIG_MOUSE_LOGIBM=m +CONFIG_MOUSE_PC110PAD=m +CONFIG_MOUSE_VSXXXAA=m +# CONFIG_MOUSE_SYNAPTICS_I2C is not set +# CONFIG_INPUT_JOYSTICK is not set +# CONFIG_INPUT_TABLET is not set +# CONFIG_INPUT_TOUCHSCREEN is not set +CONFIG_INPUT_MISC=y +CONFIG_INPUT_PCSPKR=m +# CONFIG_INPUT_ATI_REMOTE is not set +# CONFIG_INPUT_ATI_REMOTE2 is not set +# CONFIG_INPUT_KEYSPAN_REMOTE is not set +# CONFIG_INPUT_POWERMATE is not set +# CONFIG_INPUT_YEALINK is not set +# CONFIG_INPUT_CM109 is not set +CONFIG_INPUT_UINPUT=m + +# +# Hardware I/O ports +# +CONFIG_SERIO=y +CONFIG_SERIO_I8042=y +CONFIG_SERIO_SERPORT=m +CONFIG_SERIO_PCIPS2=m +CONFIG_SERIO_LIBPS2=y +CONFIG_SERIO_RAW=m +CONFIG_GAMEPORT=m +CONFIG_GAMEPORT_NS558=m +CONFIG_GAMEPORT_L4=m +CONFIG_GAMEPORT_EMU10K1=m +CONFIG_GAMEPORT_FM801=m + +# +# Character devices +# +CONFIG_VT=y +CONFIG_CONSOLE_TRANSLATIONS=y +CONFIG_VT_CONSOLE=y +CONFIG_HW_CONSOLE=y +# CONFIG_VT_HW_CONSOLE_BINDING is not set +CONFIG_DEVKMEM=y +CONFIG_SERIAL_NONSTANDARD=y +# CONFIG_COMPUTONE is not set +# CONFIG_ROCKETPORT is not set +# CONFIG_CYCLADES is not set +# CONFIG_DIGIEPCA is not set +# CONFIG_MOXA_INTELLIO is not set +# CONFIG_MOXA_SMARTIO is not set +# CONFIG_ISI is not set +# CONFIG_SYNCLINKMP is not set +# CONFIG_SYNCLINK_GT is not set +# CONFIG_N_HDLC is not set +# CONFIG_RISCOM8 is not set +# CONFIG_SPECIALIX is not set +# CONFIG_SX is not set +# CONFIG_RIO is not set +CONFIG_STALDRV=y +# CONFIG_STALLION is not set +# CONFIG_ISTALLION is not set +# CONFIG_NOZOMI is not set + +# +# Serial drivers +# +CONFIG_SERIAL_8250=y +CONFIG_SERIAL_8250_CONSOLE=y +# CONFIG_SERIAL_8250_PCI is not set +# CONFIG_SERIAL_8250_PNP is not set +CONFIG_SERIAL_8250_NR_UARTS=16 +CONFIG_SERIAL_8250_RUNTIME_UARTS=4 +CONFIG_SERIAL_8250_EXTENDED=y +CONFIG_SERIAL_8250_MANY_PORTS=y +CONFIG_SERIAL_8250_FOURPORT=y +# CONFIG_SERIAL_8250_ACCENT is not set +# CONFIG_SERIAL_8250_BOCA is not set +# CONFIG_SERIAL_8250_EXAR_ST16C554 is not set +CONFIG_SERIAL_8250_HUB6=m +CONFIG_SERIAL_8250_SHARE_IRQ=y +# CONFIG_SERIAL_8250_DETECT_IRQ is not set +CONFIG_SERIAL_8250_RSA=y + +# +# Non-8250 serial port support +# +# CONFIG_SERIAL_MAX3100 is not set +CONFIG_SERIAL_CORE=y +CONFIG_SERIAL_CORE_CONSOLE=y +# CONFIG_SERIAL_JSM is not set +CONFIG_UNIX98_PTYS=y +# CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set +CONFIG_LEGACY_PTYS=y +CONFIG_LEGACY_PTY_COUNT=16 +CONFIG_IPMI_HANDLER=m +# CONFIG_IPMI_PANIC_EVENT is not set +CONFIG_IPMI_DEVICE_INTERFACE=m +CONFIG_IPMI_SI=m +CONFIG_IPMI_WATCHDOG=m +CONFIG_IPMI_POWEROFF=m +CONFIG_HW_RANDOM=y +# CONFIG_HW_RANDOM_TIMERIOMEM is not set +# CONFIG_DTLK is not set +# CONFIG_R3964 is not set +# CONFIG_APPLICOM is not set +CONFIG_RAW_DRIVER=m +CONFIG_MAX_RAW_DEVS=256 +# CONFIG_TCG_TPM is not set +CONFIG_DEVPORT=y +CONFIG_I2C=m +CONFIG_I2C_BOARDINFO=y +CONFIG_I2C_CHARDEV=m +CONFIG_I2C_HELPER_AUTO=y +CONFIG_I2C_ALGOBIT=m +CONFIG_I2C_ALGOPCA=m + +# +# I2C Hardware Bus support +# + +# +# PC SMBus host controller drivers +# +CONFIG_I2C_ALI1535=m +CONFIG_I2C_ALI1563=m +CONFIG_I2C_ALI15X3=m +CONFIG_I2C_AMD756=m +CONFIG_I2C_AMD8111=m +CONFIG_I2C_I801=m +# CONFIG_I2C_ISCH is not set +CONFIG_I2C_PIIX4=m +CONFIG_I2C_NFORCE2=m +CONFIG_I2C_SIS5595=m +CONFIG_I2C_SIS630=m +CONFIG_I2C_SIS96X=m +CONFIG_I2C_VIA=m +CONFIG_I2C_VIAPRO=m + +# +# I2C system bus drivers (mostly embedded / system-on-chip) +# +CONFIG_I2C_OCORES=m +# CONFIG_I2C_SIMTEC is not set + +# +# External I2C/SMBus adapter drivers +# +CONFIG_I2C_PARPORT_LIGHT=m +# CONFIG_I2C_TAOS_EVM is not set +# CONFIG_I2C_TINY_USB is not set + +# +# Graphics adapter I2C/DDC channel drivers +# +CONFIG_I2C_VOODOO3=m + +# +# Other I2C/SMBus bus drivers +# +# CONFIG_I2C_ELEKTOR is not set +CONFIG_I2C_PCA_ISA=m +# CONFIG_I2C_PCA_PLATFORM is not set +CONFIG_I2C_STUB=m + +# +# Miscellaneous I2C Chip support +# +# CONFIG_DS1682 is not set +CONFIG_SENSORS_PCF8574=m +# CONFIG_PCF8575 is not set +# CONFIG_SENSORS_PCA9539 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 +CONFIG_SPI=y +CONFIG_SPI_MASTER=y + +# +# SPI Master Controller Drivers +# +CONFIG_SPI_BITBANG=m + +# +# SPI Protocol Masters +# +# CONFIG_SPI_SPIDEV is not set +# CONFIG_SPI_TLE62X0 is not set + +# +# PPS support +# +# CONFIG_PPS is not set +# CONFIG_W1 is not set +# CONFIG_POWER_SUPPLY is not set +# CONFIG_HWMON is not set +# CONFIG_THERMAL is not set +# CONFIG_THERMAL_HWMON is not set +CONFIG_WATCHDOG=y +# CONFIG_WATCHDOG_NOWAYOUT is not set + +# +# Watchdog Device Drivers +# +CONFIG_SOFT_WATCHDOG=m +# CONFIG_ALIM7101_WDT is not set + +# +# ISA-based Watchdog Cards +# +# CONFIG_PCWATCHDOG is not set +# CONFIG_MIXCOMWD is not set +# CONFIG_WDT is not set + +# +# PCI-based Watchdog Cards +# +# CONFIG_PCIPCWATCHDOG is not set +# CONFIG_WDTPCI is not set + +# +# USB-based Watchdog Cards +# +# CONFIG_USBPCWATCHDOG is not set +CONFIG_SSB_POSSIBLE=y + +# +# Sonics Silicon Backplane +# +# CONFIG_SSB is not set + +# +# Multifunction device drivers +# +# CONFIG_MFD_CORE is not set +# CONFIG_MFD_SM501 is not set +# CONFIG_HTC_PASIC3 is not set +# CONFIG_MFD_TMIO is not set +# CONFIG_MFD_WM8400 is not set +# CONFIG_MFD_WM8350_I2C is not set +# CONFIG_MFD_PCF50633 is not set +# CONFIG_AB3100_CORE is not set +# CONFIG_EZX_PCAP is not set +# CONFIG_REGULATOR is not set +# CONFIG_MEDIA_SUPPORT is not set + +# +# Graphics support +# +CONFIG_DRM=m +CONFIG_DRM_TDFX=m +CONFIG_DRM_R128=m +CONFIG_DRM_RADEON=m +CONFIG_DRM_MGA=m +CONFIG_DRM_VIA=m +CONFIG_DRM_SAVAGE=m +# CONFIG_VGASTATE is not set +# CONFIG_VIDEO_OUTPUT_CONTROL is not set +CONFIG_FB=y +CONFIG_FIRMWARE_EDID=y +# CONFIG_FB_DDC is not set +# CONFIG_FB_BOOT_VESA_SUPPORT is not set +CONFIG_FB_CFB_FILLRECT=y +CONFIG_FB_CFB_COPYAREA=y +CONFIG_FB_CFB_IMAGEBLIT=y +# CONFIG_FB_CFB_REV_PIXELS_IN_BYTE is not set +CONFIG_FB_SYS_FILLRECT=m +CONFIG_FB_SYS_COPYAREA=m +CONFIG_FB_SYS_IMAGEBLIT=m +# CONFIG_FB_FOREIGN_ENDIAN is not set +CONFIG_FB_SYS_FOPS=m +# CONFIG_FB_SVGALIB is not set +# CONFIG_FB_MACMODES is not set +# CONFIG_FB_BACKLIGHT is not set +CONFIG_FB_MODE_HELPERS=y +CONFIG_FB_TILEBLITTING=y + +# +# Frame buffer hardware drivers +# +# CONFIG_FB_CIRRUS is not set +# CONFIG_FB_PM2 is not set +# CONFIG_FB_CYBER2000 is not set +# CONFIG_FB_ASILIANT is not set +# CONFIG_FB_IMSTT is not set +# CONFIG_FB_UVESA is not set +# CONFIG_FB_S1D13XXX is not set +# CONFIG_FB_NVIDIA is not set +# CONFIG_FB_RIVA is not set +# CONFIG_FB_MATROX is not set +# CONFIG_FB_RADEON is not set +# CONFIG_FB_ATY128 is not set +# CONFIG_FB_ATY is not set +# CONFIG_FB_S3 is not set +# CONFIG_FB_SAVAGE is not set +# CONFIG_FB_SIS is not set +# CONFIG_FB_VIA is not set +# CONFIG_FB_NEOMAGIC is not set +# CONFIG_FB_KYRO is not set +# CONFIG_FB_3DFX is not set +# CONFIG_FB_VOODOO1 is not set +# CONFIG_FB_VT8623 is not set +# CONFIG_FB_TRIDENT is not set +# CONFIG_FB_ARK is not set +# CONFIG_FB_PM3 is not set +# CONFIG_FB_CARMINE is not set +CONFIG_FB_SM7XX=y +CONFIG_FB_SM7XX_ACCEL=y +# CONFIG_FB_SM7XX_DUALHEAD is not set +CONFIG_FB_VIRTUAL=m +# CONFIG_FB_METRONOME is not set +# CONFIG_FB_MB862XX is not set +# CONFIG_FB_BROADSHEET is not set +CONFIG_BACKLIGHT_LCD_SUPPORT=y +# CONFIG_LCD_CLASS_DEVICE is not set +CONFIG_BACKLIGHT_CLASS_DEVICE=y +CONFIG_BACKLIGHT_GENERIC=y + +# +# Display device support +# +# CONFIG_DISPLAY_SUPPORT is not set + +# +# Console display driver support +# +# CONFIG_VGA_CONSOLE is not set +# CONFIG_MDA_CONSOLE is not set +CONFIG_DUMMY_CONSOLE=y +CONFIG_FRAMEBUFFER_CONSOLE=y +# CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY is not set +CONFIG_FRAMEBUFFER_CONSOLE_ROTATION=y +# CONFIG_FONTS is not set +CONFIG_FONT_8x8=y +CONFIG_FONT_8x16=y +# CONFIG_LOGO is not set +CONFIG_SOUND=y +CONFIG_SOUND_OSS_CORE=y +CONFIG_SND=y +CONFIG_SND_TIMER=y +CONFIG_SND_PCM=y +CONFIG_SND_RAWMIDI=m +CONFIG_SND_SEQUENCER=m +CONFIG_SND_SEQ_DUMMY=m +CONFIG_SND_OSSEMUL=y +CONFIG_SND_MIXER_OSS=m +CONFIG_SND_PCM_OSS=m +CONFIG_SND_PCM_OSS_PLUGINS=y +CONFIG_SND_SEQUENCER_OSS=y +# CONFIG_SND_HRTIMER is not set +# CONFIG_SND_DYNAMIC_MINORS is not set +CONFIG_SND_SUPPORT_OLD_API=y +CONFIG_SND_VERBOSE_PROCFS=y +# CONFIG_SND_VERBOSE_PRINTK is not set +# CONFIG_SND_DEBUG is not set +CONFIG_SND_VMASTER=y +CONFIG_SND_RAWMIDI_SEQ=m +# CONFIG_SND_OPL3_LIB_SEQ is not set +# CONFIG_SND_OPL4_LIB_SEQ is not set +# CONFIG_SND_SBAWE_SEQ is not set +# CONFIG_SND_EMU10K1_SEQ is not set +CONFIG_SND_AC97_CODEC=y +CONFIG_SND_DRIVERS=y +CONFIG_SND_DUMMY=m +# CONFIG_SND_VIRMIDI is not set +CONFIG_SND_MTPAV=m +# CONFIG_SND_SERIAL_U16550 is not set +# CONFIG_SND_MPU401 is not set +# CONFIG_SND_AC97_POWER_SAVE is not set +CONFIG_SND_PCI=y +# CONFIG_SND_AD1889 is not set +# CONFIG_SND_ALS300 is not set +# CONFIG_SND_ALI5451 is not set +# CONFIG_SND_ATIIXP is not set +# CONFIG_SND_ATIIXP_MODEM is not set +# CONFIG_SND_AU8810 is not set +# CONFIG_SND_AU8820 is not set +# CONFIG_SND_AU8830 is not set +# CONFIG_SND_AW2 is not set +# CONFIG_SND_AZT3328 is not set +# CONFIG_SND_BT87X is not set +# CONFIG_SND_CA0106 is not set +# CONFIG_SND_CMIPCI is not set +# CONFIG_SND_OXYGEN is not set +# CONFIG_SND_CS4281 is not set +# CONFIG_SND_CS46XX is not set +CONFIG_SND_CS5535AUDIO=y +# CONFIG_SND_CTXFI is not set +# CONFIG_SND_DARLA20 is not set +# CONFIG_SND_GINA20 is not set +# CONFIG_SND_LAYLA20 is not set +# CONFIG_SND_DARLA24 is not set +# CONFIG_SND_GINA24 is not set +# CONFIG_SND_LAYLA24 is not set +# CONFIG_SND_MONA is not set +# CONFIG_SND_MIA is not set +# CONFIG_SND_ECHO3G is not set +# CONFIG_SND_INDIGO is not set +# CONFIG_SND_INDIGOIO is not set +# CONFIG_SND_INDIGODJ is not set +# CONFIG_SND_INDIGOIOX is not set +# CONFIG_SND_INDIGODJX is not set +# CONFIG_SND_EMU10K1 is not set +# CONFIG_SND_EMU10K1X is not set +# CONFIG_SND_ENS1370 is not set +# CONFIG_SND_ENS1371 is not set +# CONFIG_SND_ES1938 is not set +# CONFIG_SND_ES1968 is not set +# CONFIG_SND_FM801 is not set +# CONFIG_SND_HDA_INTEL is not set +# CONFIG_SND_HDSP is not set +# CONFIG_SND_HDSPM is not set +# CONFIG_SND_HIFIER is not set +# CONFIG_SND_ICE1712 is not set +# CONFIG_SND_ICE1724 is not set +# CONFIG_SND_INTEL8X0 is not set +# CONFIG_SND_INTEL8X0M is not set +# CONFIG_SND_KORG1212 is not set +# CONFIG_SND_LX6464ES is not set +# CONFIG_SND_MAESTRO3 is not set +# CONFIG_SND_MIXART is not set +# CONFIG_SND_NM256 is not set +# CONFIG_SND_PCXHR is not set +# CONFIG_SND_RIPTIDE is not set +# CONFIG_SND_RME32 is not set +# CONFIG_SND_RME96 is not set +# CONFIG_SND_RME9652 is not set +# CONFIG_SND_SONICVIBES is not set +# CONFIG_SND_TRIDENT is not set +# CONFIG_SND_VIA82XX is not set +# CONFIG_SND_VIA82XX_MODEM is not set +# CONFIG_SND_VIRTUOSO is not set +# CONFIG_SND_VX222 is not set +# CONFIG_SND_YMFPCI is not set +# CONFIG_SND_SPI is not set +# CONFIG_SND_MIPS is not set +# CONFIG_SND_USB is not set +# CONFIG_SND_SOC is not set +# CONFIG_SOUND_PRIME is not set +CONFIG_AC97_BUS=y +CONFIG_HID_SUPPORT=y +CONFIG_HID=y +# CONFIG_HID_DEBUG is not set +CONFIG_HIDRAW=y + +# +# USB Input Devices +# +CONFIG_USB_HID=y +# CONFIG_HID_PID is not set +CONFIG_USB_HIDDEV=y + +# +# Special HID drivers +# +# CONFIG_HID_A4TECH is not set +# CONFIG_HID_APPLE is not set +# CONFIG_HID_BELKIN is not set +# CONFIG_HID_CHERRY is not set +# CONFIG_HID_CHICONY is not set +# CONFIG_HID_CYPRESS is not set +# CONFIG_HID_DRAGONRISE is not set +# CONFIG_HID_EZKEY is not set +# CONFIG_HID_KYE is not set +# CONFIG_HID_GYRATION is not set +# CONFIG_HID_KENSINGTON is not set +# CONFIG_HID_LOGITECH is not set +# CONFIG_HID_MICROSOFT is not set +# CONFIG_HID_MONTEREY is not set +# CONFIG_HID_NTRIG is not set +# CONFIG_HID_PANTHERLORD is not set +# CONFIG_HID_PETALYNX is not set +# CONFIG_HID_SAMSUNG is not set +# CONFIG_HID_SONY is not set +# CONFIG_HID_SUNPLUS is not set +# CONFIG_HID_GREENASIA is not set +# CONFIG_HID_SMARTJOYPLUS is not set +# CONFIG_HID_TOPSEED is not set +# CONFIG_HID_THRUSTMASTER is not set +# CONFIG_HID_WACOM is not set +# CONFIG_HID_ZEROPLUS 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 +# CONFIG_USB_ANNOUNCE_NEW_DEVICES is not set + +# +# Miscellaneous USB options +# +CONFIG_USB_DEVICEFS=y +CONFIG_USB_DEVICE_CLASS=y +CONFIG_USB_DYNAMIC_MINORS=y +# CONFIG_USB_SUSPEND is not set +# CONFIG_USB_OTG is not set +# CONFIG_USB_OTG_WHITELIST is not set +# CONFIG_USB_OTG_BLACKLIST_HUB is not set +CONFIG_USB_MON=m +# CONFIG_USB_WUSB is not set +# CONFIG_USB_WUSB_CBAF is not set + +# +# USB Host Controller Drivers +# +# CONFIG_USB_C67X00_HCD is not set +# CONFIG_USB_XHCI_HCD is not set +CONFIG_USB_EHCI_HCD=y +CONFIG_USB_EHCI_ROOT_HUB_TT=y +# CONFIG_USB_EHCI_TT_NEWSCHED is not set +# CONFIG_USB_OXU210HP_HCD is not set +# CONFIG_USB_ISP116X_HCD is not set +# CONFIG_USB_ISP1760_HCD is not set +CONFIG_USB_OHCI_HCD=m +# CONFIG_USB_OHCI_BIG_ENDIAN_DESC is not set +# CONFIG_USB_OHCI_BIG_ENDIAN_MMIO is not set +CONFIG_USB_OHCI_LITTLE_ENDIAN=y +CONFIG_USB_UHCI_HCD=m +# CONFIG_USB_SL811_HCD is not set +CONFIG_USB_R8A66597_HCD=y +# CONFIG_USB_WHCI_HCD is not set +# CONFIG_USB_HWA_HCD is not set + +# +# USB Device Class drivers +# +CONFIG_USB_ACM=m +CONFIG_USB_PRINTER=m +# CONFIG_USB_WDM is not set +# CONFIG_USB_TMC is not set + +# +# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may +# + +# +# also be needed; see USB_STORAGE Help for more info +# +CONFIG_USB_STORAGE=y +# CONFIG_USB_STORAGE_DEBUG is not set +CONFIG_USB_STORAGE_DATAFAB=y +CONFIG_USB_STORAGE_FREECOM=y +CONFIG_USB_STORAGE_ISD200=y +CONFIG_USB_STORAGE_USBAT=y +CONFIG_USB_STORAGE_SDDR09=y +CONFIG_USB_STORAGE_SDDR55=y +CONFIG_USB_STORAGE_JUMPSHOT=y +CONFIG_USB_STORAGE_ALAUDA=y +CONFIG_USB_STORAGE_ONETOUCH=y +CONFIG_USB_STORAGE_KARMA=y +CONFIG_USB_STORAGE_CYPRESS_ATACB=y +# CONFIG_USB_LIBUSUAL is not set + +# +# USB Imaging devices +# +CONFIG_USB_MDC800=m +CONFIG_USB_MICROTEK=m + +# +# USB port drivers +# +CONFIG_USB_SERIAL=m +CONFIG_USB_EZUSB=y +CONFIG_USB_SERIAL_GENERIC=y +# CONFIG_USB_SERIAL_AIRCABLE is not set +CONFIG_USB_SERIAL_ARK3116=m +CONFIG_USB_SERIAL_BELKIN=m +# CONFIG_USB_SERIAL_CH341 is not set +# CONFIG_USB_SERIAL_WHITEHEAT is not set +CONFIG_USB_SERIAL_DIGI_ACCELEPORT=m +# CONFIG_USB_SERIAL_CP210X is not set +CONFIG_USB_SERIAL_CYPRESS_M8=m +CONFIG_USB_SERIAL_EMPEG=m +CONFIG_USB_SERIAL_FTDI_SIO=m +CONFIG_USB_SERIAL_FUNSOFT=m +CONFIG_USB_SERIAL_VISOR=m +CONFIG_USB_SERIAL_IPAQ=m +CONFIG_USB_SERIAL_IR=m +CONFIG_USB_SERIAL_EDGEPORT=m +CONFIG_USB_SERIAL_EDGEPORT_TI=m +CONFIG_USB_SERIAL_GARMIN=m +CONFIG_USB_SERIAL_IPW=m +# CONFIG_USB_SERIAL_IUU is not set +CONFIG_USB_SERIAL_KEYSPAN_PDA=m +# CONFIG_USB_SERIAL_KEYSPAN is not set +CONFIG_USB_SERIAL_KLSI=m +CONFIG_USB_SERIAL_KOBIL_SCT=m +CONFIG_USB_SERIAL_MCT_U232=m +# CONFIG_USB_SERIAL_MOS7720 is not set +# CONFIG_USB_SERIAL_MOS7840 is not set +# CONFIG_USB_SERIAL_MOTOROLA is not set +CONFIG_USB_SERIAL_NAVMAN=m +CONFIG_USB_SERIAL_PL2303=m +# CONFIG_USB_SERIAL_OTI6858 is not set +# CONFIG_USB_SERIAL_QUALCOMM is not set +# CONFIG_USB_SERIAL_SPCP8X5 is not set +CONFIG_USB_SERIAL_HP4X=m +CONFIG_USB_SERIAL_SAFE=m +# CONFIG_USB_SERIAL_SAFE_PADDED is not set +# CONFIG_USB_SERIAL_SIEMENS_MPI is not set +CONFIG_USB_SERIAL_SIERRAWIRELESS=m +# CONFIG_USB_SERIAL_SYMBOL is not set +CONFIG_USB_SERIAL_TI=m +CONFIG_USB_SERIAL_CYBERJACK=m +CONFIG_USB_SERIAL_XIRCOM=m +CONFIG_USB_SERIAL_OPTION=m +CONFIG_USB_SERIAL_OMNINET=m +# CONFIG_USB_SERIAL_OPTICON is not set +# CONFIG_USB_SERIAL_DEBUG 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_SEVSEG is not set +CONFIG_USB_RIO500=m +# 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_IDMOUSE=m +# CONFIG_USB_FTDI_ELAN is not set +CONFIG_USB_APPLEDISPLAY=m +CONFIG_USB_SISUSBVGA=m +CONFIG_USB_SISUSBVGA_CON=y +CONFIG_USB_LD=m +# CONFIG_USB_TRANCEVIBRATOR is not set +# CONFIG_USB_IOWARRIOR is not set +CONFIG_USB_TEST=m +# CONFIG_USB_ISIGHTFW is not set +# CONFIG_USB_VST is not set +CONFIG_USB_ATM=m +CONFIG_USB_SPEEDTOUCH=m +CONFIG_USB_CXACRU=m +CONFIG_USB_UEAGLEATM=m +CONFIG_USB_XUSBATM=m +# CONFIG_USB_GADGET is not set + +# +# OTG and related infrastructure +# +# CONFIG_NOP_USB_XCEIV is not set +# CONFIG_UWB is not set +CONFIG_MMC=m +# CONFIG_MMC_DEBUG is not set +# CONFIG_MMC_UNSAFE_RESUME is not set + +# +# MMC/SD/SDIO Card Drivers +# +# CONFIG_MMC_BLOCK is not set +# CONFIG_SDIO_UART is not set +# CONFIG_MMC_TEST is not set + +# +# MMC/SD/SDIO Host Controller Drivers +# +# CONFIG_MMC_SDHCI is not set +# CONFIG_MMC_TIFM_SD is not set +# CONFIG_MMC_SPI is not set +# CONFIG_MMC_CB710 is not set +# CONFIG_MMC_VIA_SDMMC is not set +# CONFIG_MEMSTICK is not set +CONFIG_NEW_LEDS=y +CONFIG_LEDS_CLASS=m + +# +# LED drivers +# +# CONFIG_LEDS_PCA9532 is not set +# CONFIG_LEDS_LP3944 is not set +# CONFIG_LEDS_PCA955X is not set +# CONFIG_LEDS_DAC124S085 is not set +# CONFIG_LEDS_BD2802 is not set + +# +# LED Triggers +# +CONFIG_LEDS_TRIGGERS=y +CONFIG_LEDS_TRIGGER_TIMER=m +# CONFIG_LEDS_TRIGGER_IDE_DISK is not set +CONFIG_LEDS_TRIGGER_HEARTBEAT=m +# CONFIG_LEDS_TRIGGER_BACKLIGHT is not set +# CONFIG_LEDS_TRIGGER_DEFAULT_ON is not set + +# +# iptables trigger is under Netfilter config (LED target) +# +# CONFIG_ACCESSIBILITY is not set +# CONFIG_INFINIBAND 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 is not set +# 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 +# CONFIG_RTC_DRV_S35390A is not set +# CONFIG_RTC_DRV_FM3130 is not set +# CONFIG_RTC_DRV_RX8581 is not set +# CONFIG_RTC_DRV_RX8025 is not set + +# +# SPI RTC drivers +# +# CONFIG_RTC_DRV_M41T94 is not set +# CONFIG_RTC_DRV_DS1305 is not set +# CONFIG_RTC_DRV_DS1390 is not set +# CONFIG_RTC_DRV_MAX6902 is not set +# CONFIG_RTC_DRV_R9701 is not set +# CONFIG_RTC_DRV_RS5C348 is not set +# CONFIG_RTC_DRV_DS3234 is not set + +# +# Platform RTC drivers +# +CONFIG_RTC_DRV_CMOS=y +# CONFIG_RTC_DRV_DS1286 is not set +# CONFIG_RTC_DRV_DS1511 is not set +# CONFIG_RTC_DRV_DS1553 is not set +# CONFIG_RTC_DRV_DS1742 is not set +# CONFIG_RTC_DRV_STK17TA8 is not set +# CONFIG_RTC_DRV_M48T86 is not set +# CONFIG_RTC_DRV_M48T35 is not set +# CONFIG_RTC_DRV_M48T59 is not set +# CONFIG_RTC_DRV_BQ4802 is not set +# CONFIG_RTC_DRV_V3020 is not set + +# +# on-CPU RTC drivers +# +# CONFIG_DMADEVICES is not set +# CONFIG_AUXDISPLAY is not set +# CONFIG_UIO is not set + +# +# TI VLYNQ +# +# CONFIG_STAGING is not set +CONFIG_LOONGSON_PLATFORM_DEVICES=y +CONFIG_EC_KB3310B=y +# CONFIG_EC_KB3310B_DEBUG is not set +CONFIG_PMON_FLASH=m + +# +# File systems +# +CONFIG_EXT2_FS=y +CONFIG_EXT2_FS_XATTR=y +CONFIG_EXT2_FS_POSIX_ACL=y +CONFIG_EXT2_FS_SECURITY=y +# CONFIG_EXT2_FS_XIP is not set +CONFIG_EXT3_FS=y +# CONFIG_EXT3_DEFAULTS_TO_ORDERED is not set +CONFIG_EXT3_FS_XATTR=y +CONFIG_EXT3_FS_POSIX_ACL=y +CONFIG_EXT3_FS_SECURITY=y +CONFIG_EXT4_FS=m +CONFIG_EXT4DEV_COMPAT=y +CONFIG_EXT4_FS_XATTR=y +CONFIG_EXT4_FS_POSIX_ACL=y +CONFIG_EXT4_FS_SECURITY=y +CONFIG_JBD=y +# CONFIG_JBD_DEBUG is not set +CONFIG_JBD2=m +# CONFIG_JBD2_DEBUG is not set +CONFIG_FS_MBCACHE=y +CONFIG_REISERFS_FS=m +# CONFIG_REISERFS_CHECK is not set +# CONFIG_REISERFS_PROC_INFO is not set +CONFIG_REISERFS_FS_XATTR=y +CONFIG_REISERFS_FS_POSIX_ACL=y +CONFIG_REISERFS_FS_SECURITY=y +CONFIG_JFS_FS=m +CONFIG_JFS_POSIX_ACL=y +CONFIG_JFS_SECURITY=y +# CONFIG_JFS_DEBUG is not set +# CONFIG_JFS_STATISTICS is not set +CONFIG_FS_POSIX_ACL=y +CONFIG_XFS_FS=m +CONFIG_XFS_QUOTA=y +CONFIG_XFS_POSIX_ACL=y +CONFIG_XFS_RT=y +# CONFIG_XFS_DEBUG is not set +# CONFIG_GFS2_FS is not set +CONFIG_OCFS2_FS=m +CONFIG_OCFS2_FS_O2CB=m +CONFIG_OCFS2_FS_STATS=y +CONFIG_OCFS2_DEBUG_MASKLOG=y +# CONFIG_OCFS2_DEBUG_FS is not set +# CONFIG_OCFS2_FS_POSIX_ACL is not set +# CONFIG_BTRFS_FS is not set +CONFIG_FILE_LOCKING=y +CONFIG_FSNOTIFY=y +CONFIG_DNOTIFY=y +CONFIG_INOTIFY=y +CONFIG_INOTIFY_USER=y +CONFIG_QUOTA=y +# CONFIG_QUOTA_NETLINK_INTERFACE is not set +CONFIG_PRINT_QUOTA_WARNING=y +CONFIG_QUOTA_TREE=m +CONFIG_QFMT_V1=m +CONFIG_QFMT_V2=m +CONFIG_QUOTACTL=y +CONFIG_AUTOFS_FS=m +CONFIG_AUTOFS4_FS=m +CONFIG_FUSE_FS=m +# CONFIG_CUSE is not set + +# +# Caches +# +# CONFIG_FSCACHE is not set + +# +# CD-ROM/DVD Filesystems +# +CONFIG_ISO9660_FS=m +CONFIG_JOLIET=y +CONFIG_ZISOFS=y +CONFIG_UDF_FS=m +CONFIG_UDF_NLS=y + +# +# DOS/FAT/NT Filesystems +# +CONFIG_FAT_FS=m +CONFIG_MSDOS_FS=m +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=y + +# +# Pseudo filesystems +# +CONFIG_PROC_FS=y +CONFIG_PROC_KCORE=y +CONFIG_PROC_SYSCTL=y +CONFIG_PROC_PAGE_MONITOR=y +CONFIG_SYSFS=y +CONFIG_TMPFS=y +# CONFIG_TMPFS_POSIX_ACL is not set +# CONFIG_HUGETLB_PAGE is not set +CONFIG_CONFIGFS_FS=m +CONFIG_MISC_FILESYSTEMS=y +CONFIG_ADFS_FS=m +# CONFIG_ADFS_FS_RW is not set +CONFIG_AFFS_FS=m +# CONFIG_ECRYPT_FS is not set +CONFIG_HFS_FS=m +CONFIG_HFSPLUS_FS=m +CONFIG_BEFS_FS=m +# CONFIG_BEFS_DEBUG is not set +CONFIG_BFS_FS=m +CONFIG_EFS_FS=m +CONFIG_JFFS2_FS=m +CONFIG_JFFS2_FS_DEBUG=0 +CONFIG_JFFS2_FS_WRITEBUFFER=y +# CONFIG_JFFS2_FS_WBUF_VERIFY is not set +# CONFIG_JFFS2_SUMMARY is not set +CONFIG_JFFS2_FS_XATTR=y +CONFIG_JFFS2_FS_POSIX_ACL=y +CONFIG_JFFS2_FS_SECURITY=y +# CONFIG_JFFS2_COMPRESSION_OPTIONS is not set +CONFIG_JFFS2_ZLIB=y +# CONFIG_JFFS2_LZO is not set +CONFIG_JFFS2_RTIME=y +# CONFIG_JFFS2_RUBIN is not set +CONFIG_CRAMFS=y +# CONFIG_SQUASHFS is not set +CONFIG_VXFS_FS=m +CONFIG_MINIX_FS=m +# CONFIG_OMFS_FS is not set +CONFIG_HPFS_FS=m +CONFIG_QNX4FS_FS=m +CONFIG_ROMFS_FS=m +CONFIG_ROMFS_BACKED_BY_BLOCK=y +# CONFIG_ROMFS_BACKED_BY_MTD is not set +# CONFIG_ROMFS_BACKED_BY_BOTH is not set +CONFIG_ROMFS_ON_BLOCK=y +CONFIG_SYSV_FS=m +CONFIG_UFS_FS=m +# CONFIG_UFS_FS_WRITE is not set +# CONFIG_UFS_DEBUG is not set +# CONFIG_NILFS2_FS is not set +CONFIG_NETWORK_FILESYSTEMS=y +CONFIG_NFS_FS=m +CONFIG_NFS_V3=y +CONFIG_NFS_V3_ACL=y +CONFIG_NFS_V4=y +# CONFIG_NFS_V4_1 is not set +CONFIG_NFSD=m +CONFIG_NFSD_V2_ACL=y +CONFIG_NFSD_V3=y +CONFIG_NFSD_V3_ACL=y +CONFIG_NFSD_V4=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_GSS=m +CONFIG_RPCSEC_GSS_KRB5=m +CONFIG_RPCSEC_GSS_SPKM3=m +CONFIG_SMB_FS=m +# CONFIG_SMB_NLS_DEFAULT is not set +CONFIG_CIFS=m +# CONFIG_CIFS_STATS is not set +# CONFIG_CIFS_WEAK_PW_HASH is not set +# CONFIG_CIFS_UPCALL is not set +# CONFIG_CIFS_XATTR is not set +# CONFIG_CIFS_DEBUG2 is not set +# CONFIG_CIFS_DFS_UPCALL is not set +# CONFIG_CIFS_EXPERIMENTAL is not set +CONFIG_NCP_FS=m +CONFIG_NCPFS_PACKET_SIGNING=y +CONFIG_NCPFS_IOCTL_LOCKING=y +CONFIG_NCPFS_STRONG=y +CONFIG_NCPFS_NFS_NS=y +CONFIG_NCPFS_OS2_NS=y +# CONFIG_NCPFS_SMALLDOS is not set +CONFIG_NCPFS_NLS=y +CONFIG_NCPFS_EXTRAS=y +CONFIG_CODA_FS=m +CONFIG_AFS_FS=m +# CONFIG_AFS_DEBUG is not set + +# +# Partition Types +# +CONFIG_PARTITION_ADVANCED=y +CONFIG_ACORN_PARTITION=y +# CONFIG_ACORN_PARTITION_CUMANA is not set +# CONFIG_ACORN_PARTITION_EESOX is not set +CONFIG_ACORN_PARTITION_ICS=y +# CONFIG_ACORN_PARTITION_ADFS is not set +# CONFIG_ACORN_PARTITION_POWERTEC is not set +CONFIG_ACORN_PARTITION_RISCIX=y +CONFIG_OSF_PARTITION=y +CONFIG_AMIGA_PARTITION=y +CONFIG_ATARI_PARTITION=y +CONFIG_MAC_PARTITION=y +CONFIG_MSDOS_PARTITION=y +CONFIG_BSD_DISKLABEL=y +CONFIG_MINIX_SUBPARTITION=y +CONFIG_SOLARIS_X86_PARTITION=y +CONFIG_UNIXWARE_DISKLABEL=y +CONFIG_LDM_PARTITION=y +# CONFIG_LDM_DEBUG is not set +CONFIG_SGI_PARTITION=y +CONFIG_ULTRIX_PARTITION=y +CONFIG_SUN_PARTITION=y +CONFIG_KARMA_PARTITION=y +CONFIG_EFI_PARTITION=y +# CONFIG_SYSV68_PARTITION is not set +CONFIG_NLS=y +CONFIG_NLS_DEFAULT="utf-8" +CONFIG_NLS_CODEPAGE_437=m +# CONFIG_NLS_CODEPAGE_737 is not set +# CONFIG_NLS_CODEPAGE_775 is not set +CONFIG_NLS_CODEPAGE_850=m +# 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=m +CONFIG_NLS_CODEPAGE_950=m +CONFIG_NLS_CODEPAGE_932=m +CONFIG_NLS_CODEPAGE_949=m +# CONFIG_NLS_CODEPAGE_874 is not set +# CONFIG_NLS_ISO8859_8 is not set +CONFIG_NLS_CODEPAGE_1250=m +CONFIG_NLS_CODEPAGE_1251=m +CONFIG_NLS_ASCII=m +# CONFIG_NLS_ISO8859_1 is not set +# 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=m +CONFIG_NLS_KOI8_U=m +CONFIG_NLS_UTF8=m +# CONFIG_DLM is not set + +# +# Kernel hacking +# +CONFIG_TRACE_IRQFLAGS_SUPPORT=y +# CONFIG_PRINTK_TIME is not set +CONFIG_ENABLE_WARN_DEPRECATED=y +CONFIG_ENABLE_MUST_CHECK=y +CONFIG_FRAME_WARN=1024 +CONFIG_MAGIC_SYSRQ=y +CONFIG_UNUSED_SYMBOLS=y +CONFIG_DEBUG_FS=y +# CONFIG_HEADERS_CHECK is not set +# CONFIG_DEBUG_KERNEL is not set +CONFIG_STACKTRACE=y +# CONFIG_DEBUG_MEMORY_INIT is not set +# CONFIG_RCU_CPU_STALL_DETECTOR is not set +CONFIG_SYSCTL_SYSCALL_CHECK=y +CONFIG_NOP_TRACER=y +CONFIG_RING_BUFFER=y +CONFIG_EVENT_TRACING=y +CONFIG_CONTEXT_SWITCH_TRACER=y +CONFIG_TRACING=y +CONFIG_TRACING_SUPPORT=y +# CONFIG_FTRACE is not set +# CONFIG_DYNAMIC_DEBUG is not set +# CONFIG_SAMPLES is not set +CONFIG_HAVE_ARCH_KGDB=y +CONFIG_CMDLINE="" + +# +# Security options +# +CONFIG_KEYS=y +# CONFIG_KEYS_DEBUG_PROC_KEYS is not set +CONFIG_SECURITY=y +# CONFIG_SECURITYFS is not set +CONFIG_SECURITY_NETWORK=y +CONFIG_SECURITY_NETWORK_XFRM=y +# CONFIG_SECURITY_PATH is not set +# CONFIG_SECURITY_FILE_CAPABILITIES is not set +# CONFIG_SECURITY_ROOTPLUG is not set +CONFIG_SECURITY_SELINUX=y +CONFIG_SECURITY_SELINUX_BOOTPARAM=y +CONFIG_SECURITY_SELINUX_BOOTPARAM_VALUE=0 +CONFIG_SECURITY_SELINUX_DISABLE=y +CONFIG_SECURITY_SELINUX_DEVELOP=y +CONFIG_SECURITY_SELINUX_AVC_STATS=y +CONFIG_SECURITY_SELINUX_CHECKREQPROT_VALUE=1 +# CONFIG_SECURITY_SELINUX_POLICYDB_VERSION_MAX is not set +# CONFIG_SECURITY_TOMOYO is not set +CONFIG_XOR_BLOCKS=m +CONFIG_ASYNC_CORE=m +CONFIG_ASYNC_MEMCPY=m +CONFIG_ASYNC_XOR=m +CONFIG_CRYPTO=y + +# +# Crypto core or helper +# +# CONFIG_CRYPTO_FIPS is not set +CONFIG_CRYPTO_ALGAPI=y +CONFIG_CRYPTO_ALGAPI2=y +CONFIG_CRYPTO_AEAD=m +CONFIG_CRYPTO_AEAD2=y +CONFIG_CRYPTO_BLKCIPHER=y +CONFIG_CRYPTO_BLKCIPHER2=y +CONFIG_CRYPTO_HASH=y +CONFIG_CRYPTO_HASH2=y +CONFIG_CRYPTO_RNG2=y +CONFIG_CRYPTO_PCOMP=y +CONFIG_CRYPTO_MANAGER=y +CONFIG_CRYPTO_MANAGER2=y +# CONFIG_CRYPTO_GF128MUL is not set +CONFIG_CRYPTO_NULL=m +CONFIG_CRYPTO_WORKQUEUE=y +# CONFIG_CRYPTO_CRYPTD is not set +CONFIG_CRYPTO_AUTHENC=m +CONFIG_CRYPTO_TEST=m + +# +# Authenticated Encryption with Associated Data +# +# CONFIG_CRYPTO_CCM is not set +# CONFIG_CRYPTO_GCM is not set +# CONFIG_CRYPTO_SEQIV is not set + +# +# Block modes +# +CONFIG_CRYPTO_CBC=m +# CONFIG_CRYPTO_CTR is not set +# CONFIG_CRYPTO_CTS is not set +CONFIG_CRYPTO_ECB=y +# CONFIG_CRYPTO_LRW is not set +# CONFIG_CRYPTO_PCBC is not set +# CONFIG_CRYPTO_XTS is not set + +# +# Hash modes +# +CONFIG_CRYPTO_HMAC=y +# CONFIG_CRYPTO_XCBC is not set + +# +# Digest +# +CONFIG_CRYPTO_CRC32C=m +CONFIG_CRYPTO_MD4=m +CONFIG_CRYPTO_MD5=y +CONFIG_CRYPTO_MICHAEL_MIC=m +# CONFIG_CRYPTO_RMD128 is not set +# CONFIG_CRYPTO_RMD160 is not set +# CONFIG_CRYPTO_RMD256 is not set +# CONFIG_CRYPTO_RMD320 is not set +CONFIG_CRYPTO_SHA1=m +CONFIG_CRYPTO_SHA256=m +CONFIG_CRYPTO_SHA512=m +CONFIG_CRYPTO_TGR192=m +CONFIG_CRYPTO_WP512=m + +# +# Ciphers +# +CONFIG_CRYPTO_AES=y +CONFIG_CRYPTO_ANUBIS=m +CONFIG_CRYPTO_ARC4=y +CONFIG_CRYPTO_BLOWFISH=m +# CONFIG_CRYPTO_CAMELLIA is not set +CONFIG_CRYPTO_CAST5=m +CONFIG_CRYPTO_CAST6=m +CONFIG_CRYPTO_DES=m +# CONFIG_CRYPTO_FCRYPT is not set +CONFIG_CRYPTO_KHAZAD=m +# CONFIG_CRYPTO_SALSA20 is not set +# CONFIG_CRYPTO_SEED is not set +CONFIG_CRYPTO_SERPENT=m +CONFIG_CRYPTO_TEA=m +CONFIG_CRYPTO_TWOFISH=m +CONFIG_CRYPTO_TWOFISH_COMMON=m + +# +# Compression +# +CONFIG_CRYPTO_DEFLATE=m +# CONFIG_CRYPTO_ZLIB is not set +# CONFIG_CRYPTO_LZO is not set + +# +# Random Number Generation +# +# CONFIG_CRYPTO_ANSI_CPRNG is not set +CONFIG_CRYPTO_HW=y +# CONFIG_CRYPTO_DEV_HIFN_795X is not set +CONFIG_BINARY_PRINTF=y + +# +# Library routines +# +CONFIG_BITREVERSE=y +CONFIG_GENERIC_FIND_LAST_BIT=y +CONFIG_CRC_CCITT=m +CONFIG_CRC16=m +# CONFIG_CRC_T10DIF is not set +CONFIG_CRC_ITU_T=m +CONFIG_CRC32=y +# CONFIG_CRC7 is not set +CONFIG_LIBCRC32C=m +CONFIG_AUDIT_GENERIC=y +CONFIG_ZLIB_INFLATE=y +CONFIG_ZLIB_DEFLATE=m +CONFIG_DECOMPRESS_GZIP=y +CONFIG_TEXTSEARCH=y +CONFIG_TEXTSEARCH_KMP=m +CONFIG_TEXTSEARCH_BM=m +CONFIG_TEXTSEARCH_FSM=m +CONFIG_HAS_IOMEM=y +CONFIG_HAS_IOPORT=y +CONFIG_HAS_DMA=y +CONFIG_NLATTR=y diff -Nur linux-2.6.30.5.orig/arch/mips/include/asm/bootinfo.h linux-2.6.30.5/arch/mips/include/asm/bootinfo.h --- linux-2.6.30.5.orig/arch/mips/include/asm/bootinfo.h 2009-08-16 23:19:38.000000000 +0200 +++ linux-2.6.30.5/arch/mips/include/asm/bootinfo.h 2009-08-23 19:01:04.000000000 +0200 @@ -7,6 +7,7 @@ * Copyright (C) 1995, 1996 Andreas Busse * Copyright (C) 1995, 1996 Stoned Elipot * Copyright (C) 1995, 1996 Paul M. Antoine. + * Copyright (C) 2009 Zhang Le */ #ifndef _ASM_BOOTINFO_H #define _ASM_BOOTINFO_H @@ -57,6 +58,16 @@ #define MACH_MIKROTIK_RB532 0 /* Mikrotik RouterBoard 532 */ #define MACH_MIKROTIK_RB532A 1 /* Mikrotik RouterBoard 532A */ +/* + * Valid machtype for group Loongson + */ +#define MACH_LOONGSON_UNKNOWN 0 +#define MACH_LEMOTE_FL2E 1 +#define MACH_LEMOTE_FL2F 2 +#define MACH_LEMOTE_YL2F89 3 +#define MACH_LEMOTE_YL2F7 4 +#define MACH_LOONGSON_END 5 + #define CL_SIZE COMMAND_LINE_SIZE extern char *system_type; diff -Nur linux-2.6.30.5.orig/arch/mips/include/asm/bug.h linux-2.6.30.5/arch/mips/include/asm/bug.h --- linux-2.6.30.5.orig/arch/mips/include/asm/bug.h 2009-08-16 23:19:38.000000000 +0200 +++ linux-2.6.30.5/arch/mips/include/asm/bug.h 2009-08-23 19:01:04.000000000 +0200 @@ -5,6 +5,8 @@ #ifdef CONFIG_BUG +#include + #include static inline void __noreturn BUG(void) diff -Nur linux-2.6.30.5.orig/arch/mips/include/asm/mach-lemote/cpu-feature-overrides.h linux-2.6.30.5/arch/mips/include/asm/mach-lemote/cpu-feature-overrides.h --- linux-2.6.30.5.orig/arch/mips/include/asm/mach-lemote/cpu-feature-overrides.h 2009-08-16 23:19:38.000000000 +0200 +++ linux-2.6.30.5/arch/mips/include/asm/mach-lemote/cpu-feature-overrides.h 1970-01-01 01:00:00.000000000 +0100 @@ -1,59 +0,0 @@ -/* - * This file is subject to the terms and conditions of the GNU General Public - * License. See the file "COPYING" in the main directory of this archive - * for more details. - * - * Copyright (C) 2009 Wu Zhangjin - * Copyright (C) 2009 Philippe Vachon - * Copyright (C) 2009 Zhang Le - * - * reference: /proc/cpuinfo, - * arch/mips/kernel/cpu-probe.c(cpu_probe_legacy), - * arch/mips/kernel/proc.c(show_cpuinfo), - * loongson2f user manual. - */ - -#ifndef __ASM_MACH_LEMOTE_CPU_FEATURE_OVERRIDES_H -#define __ASM_MACH_LEMOTE_CPU_FEATURE_OVERRIDES_H - -#define cpu_dcache_line_size() 32 -#define cpu_icache_line_size() 32 -#define cpu_scache_line_size() 32 - - -#define cpu_has_32fpr 1 -#define cpu_has_3k_cache 0 -#define cpu_has_4k_cache 1 -#define cpu_has_4kex 1 -#define cpu_has_64bits 1 -#define cpu_has_cache_cdex_p 0 -#define cpu_has_cache_cdex_s 0 -#define cpu_has_counter 1 -#define cpu_has_dc_aliases 1 -#define cpu_has_divec 0 -#define cpu_has_dsp 0 -#define cpu_has_ejtag 0 -#define cpu_has_fpu 1 -#define cpu_has_ic_fills_f_dc 0 -#define cpu_has_inclusive_pcaches 1 -#define cpu_has_llsc 1 -#define cpu_has_mcheck 0 -#define cpu_has_mdmx 0 -#define cpu_has_mips16 0 -#define cpu_has_mips32r1 0 -#define cpu_has_mips32r2 0 -#define cpu_has_mips3d 0 -#define cpu_has_mips64r1 0 -#define cpu_has_mips64r2 0 -#define cpu_has_mipsmt 0 -#define cpu_has_prefetch 0 -#define cpu_has_smartmips 0 -#define cpu_has_tlb 1 -#define cpu_has_tx39_cache 0 -#define cpu_has_userlocal 0 -#define cpu_has_vce 0 -#define cpu_has_vtag_icache 0 -#define cpu_has_watch 1 -#define cpu_icache_snoops_remote_store 1 - -#endif /* __ASM_MACH_LEMOTE_CPU_FEATURE_OVERRIDES_H */ diff -Nur linux-2.6.30.5.orig/arch/mips/include/asm/mach-lemote/mc146818rtc.h linux-2.6.30.5/arch/mips/include/asm/mach-lemote/mc146818rtc.h --- linux-2.6.30.5.orig/arch/mips/include/asm/mach-lemote/mc146818rtc.h 2009-08-16 23:19:38.000000000 +0200 +++ linux-2.6.30.5/arch/mips/include/asm/mach-lemote/mc146818rtc.h 1970-01-01 01:00:00.000000000 +0100 @@ -1,36 +0,0 @@ -/* - * This file is subject to the terms and conditions of the GNU General Public - * License. See the file "COPYING" in the main directory of this archive - * for more details. - * - * Copyright (C) 1998, 2001, 03, 07 by Ralf Baechle (ralf@linux-mips.org) - * - * RTC routines for PC style attached Dallas chip. - */ -#ifndef __ASM_MACH_LEMOTE_MC146818RTC_H -#define __ASM_MACH_LEMOTE_MC146818RTC_H - -#include - -#define RTC_PORT(x) (0x70 + (x)) -#define RTC_IRQ 8 - -static inline unsigned char CMOS_READ(unsigned long addr) -{ - outb_p(addr, RTC_PORT(0)); - return inb_p(RTC_PORT(1)); -} - -static inline void CMOS_WRITE(unsigned char data, unsigned long addr) -{ - outb_p(addr, RTC_PORT(0)); - outb_p(data, RTC_PORT(1)); -} - -#define RTC_ALWAYS_BCD 0 - -#ifndef mc146818_decode_year -#define mc146818_decode_year(year) ((year) < 70 ? (year) + 2000 : (year) + 1970) -#endif - -#endif /* __ASM_MACH_LEMOTE_MC146818RTC_H */ diff -Nur linux-2.6.30.5.orig/arch/mips/include/asm/mach-lemote/pci.h linux-2.6.30.5/arch/mips/include/asm/mach-lemote/pci.h --- linux-2.6.30.5.orig/arch/mips/include/asm/mach-lemote/pci.h 2009-08-16 23:19:38.000000000 +0200 +++ linux-2.6.30.5/arch/mips/include/asm/mach-lemote/pci.h 1970-01-01 01:00:00.000000000 +0100 @@ -1,30 +0,0 @@ -/* - * Copyright (c) 2008 Zhang Le - * - * 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., 675 Mass Ave, Cambridge, MA - * 02139, USA. - */ - -#ifndef _LEMOTE_PCI_H_ -#define _LEMOTE_PCI_H_ - -#define LOONGSON2E_PCI_MEM_START 0x14000000UL -#define LOONGSON2E_PCI_MEM_END 0x1fffffffUL -#define LOONGSON2E_PCI_IO_START 0x00004000UL -#define LOONGSON2E_IO_PORT_BASE 0x1fd00000UL - -#endif /* !_LEMOTE_PCI_H_ */ diff -Nur linux-2.6.30.5.orig/arch/mips/include/asm/mach-lemote/war.h linux-2.6.30.5/arch/mips/include/asm/mach-lemote/war.h --- linux-2.6.30.5.orig/arch/mips/include/asm/mach-lemote/war.h 2009-08-16 23:19:38.000000000 +0200 +++ linux-2.6.30.5/arch/mips/include/asm/mach-lemote/war.h 1970-01-01 01:00:00.000000000 +0100 @@ -1,25 +0,0 @@ -/* - * This file is subject to the terms and conditions of the GNU General Public - * License. See the file "COPYING" in the main directory of this archive - * for more details. - * - * Copyright (C) 2002, 2004, 2007 by Ralf Baechle - */ -#ifndef __ASM_MIPS_MACH_LEMOTE_WAR_H -#define __ASM_MIPS_MACH_LEMOTE_WAR_H - -#define R4600_V1_INDEX_ICACHEOP_WAR 0 -#define R4600_V1_HIT_CACHEOP_WAR 0 -#define R4600_V2_HIT_CACHEOP_WAR 0 -#define R5432_CP0_INTERRUPT_WAR 0 -#define BCM1250_M3_WAR 0 -#define SIBYTE_1956_WAR 0 -#define MIPS4K_ICACHE_REFILL_WAR 0 -#define MIPS_CACHE_SYNC_WAR 0 -#define TX49XX_ICACHE_INDEX_INV_WAR 0 -#define RM9000_CDEX_SMP_WAR 0 -#define ICACHE_REFILLS_WORKAROUND_WAR 0 -#define R10000_LLSC_WAR 0 -#define MIPS34K_MISSED_ITLB_WAR 0 - -#endif /* __ASM_MIPS_MACH_LEMOTE_WAR_H */ diff -Nur linux-2.6.30.5.orig/arch/mips/include/asm/mach-loongson/clock.h linux-2.6.30.5/arch/mips/include/asm/mach-loongson/clock.h --- linux-2.6.30.5.orig/arch/mips/include/asm/mach-loongson/clock.h 1970-01-01 01:00:00.000000000 +0100 +++ linux-2.6.30.5/arch/mips/include/asm/mach-loongson/clock.h 2009-08-23 19:01:04.000000000 +0200 @@ -0,0 +1,64 @@ +#ifndef __ASM_MIPS_CLOCK_H +#define __ASM_MIPS_CLOCK_H + +#include +#include +#include +#include + +extern void (*cpu_wait) (void); + +struct clk; + +struct clk_ops { + void (*init) (struct clk *clk); + void (*enable) (struct clk *clk); + void (*disable) (struct clk *clk); + void (*recalc) (struct clk *clk); + int (*set_rate) (struct clk *clk, unsigned long rate, int algo_id); + long (*round_rate) (struct clk *clk, unsigned long rate); +}; + +struct clk { + struct list_head node; + const char *name; + int id; + struct module *owner; + + struct clk *parent; + struct clk_ops *ops; + + struct kref kref; + + unsigned long rate; + unsigned long flags; +}; + +#define CLK_ALWAYS_ENABLED (1 << 0) +#define CLK_RATE_PROPAGATES (1 << 1) + +/* Should be defined by processor-specific code */ +void arch_init_clk_ops(struct clk_ops **, int type); + +int clk_init(void); + +int __clk_enable(struct clk *); +void __clk_disable(struct clk *); + +void clk_recalc_rate(struct clk *); + +int clk_register(struct clk *); +void clk_unregister(struct clk *); + +/* the exported API, in addition to clk_set_rate */ +/** + * clk_set_rate_ex - set the clock rate for a clock source, with additional parameter + * @clk: clock source + * @rate: desired clock rate in Hz + * @algo_id: algorithm id to be passed down to ops->set_rate + * + * Returns success (0) or negative errno. + */ +int clk_set_rate_ex(struct clk *clk, unsigned long rate, int algo_id); + +#endif /* __ASM_MIPS_CLOCK_H */ diff -Nur linux-2.6.30.5.orig/arch/mips/include/asm/mach-loongson/cmdline.h linux-2.6.30.5/arch/mips/include/asm/mach-loongson/cmdline.h --- linux-2.6.30.5.orig/arch/mips/include/asm/mach-loongson/cmdline.h 1970-01-01 01:00:00.000000000 +0100 +++ linux-2.6.30.5/arch/mips/include/asm/mach-loongson/cmdline.h 2009-08-23 19:01:04.000000000 +0200 @@ -0,0 +1,9 @@ +/* machine-specific command line initialization */ +#ifdef CONFIG_SYS_HAS_MACH_PROM_INIT_CMDLINE +extern void __init mach_prom_init_cmdline(void); +#else +void __init mach_prom_init_cmdline(void) +{ +} +#endif + diff -Nur linux-2.6.30.5.orig/arch/mips/include/asm/mach-loongson/cpu-feature-overrides.h linux-2.6.30.5/arch/mips/include/asm/mach-loongson/cpu-feature-overrides.h --- linux-2.6.30.5.orig/arch/mips/include/asm/mach-loongson/cpu-feature-overrides.h 1970-01-01 01:00:00.000000000 +0100 +++ linux-2.6.30.5/arch/mips/include/asm/mach-loongson/cpu-feature-overrides.h 2009-08-23 19:01:04.000000000 +0200 @@ -0,0 +1,59 @@ +/* + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + * + * Copyright (C) 2009 Wu Zhangjin + * Copyright (C) 2009 Philippe Vachon + * Copyright (C) 2009 Zhang Le + * + * reference: /proc/cpuinfo, + * arch/mips/kernel/cpu-probe.c(cpu_probe_legacy), + * arch/mips/kernel/proc.c(show_cpuinfo), + * loongson2f user manual. + */ + +#ifndef __ASM_MACH_LEMOTE_CPU_FEATURE_OVERRIDES_H +#define __ASM_MACH_LEMOTE_CPU_FEATURE_OVERRIDES_H + +#define cpu_dcache_line_size() 32 +#define cpu_icache_line_size() 32 +#define cpu_scache_line_size() 32 + + +#define cpu_has_32fpr 1 +#define cpu_has_3k_cache 0 +#define cpu_has_4k_cache 1 +#define cpu_has_4kex 1 +#define cpu_has_64bits 1 +#define cpu_has_cache_cdex_p 0 +#define cpu_has_cache_cdex_s 0 +#define cpu_has_counter 1 +#define cpu_has_dc_aliases 1 +#define cpu_has_divec 0 +#define cpu_has_dsp 0 +#define cpu_has_ejtag 0 +#define cpu_has_fpu 1 +#define cpu_has_ic_fills_f_dc 0 +#define cpu_has_inclusive_pcaches 1 +#define cpu_has_llsc 1 +#define cpu_has_mcheck 0 +#define cpu_has_mdmx 0 +#define cpu_has_mips16 0 +#define cpu_has_mips32r1 0 +#define cpu_has_mips32r2 0 +#define cpu_has_mips3d 0 +#define cpu_has_mips64r1 0 +#define cpu_has_mips64r2 0 +#define cpu_has_mipsmt 0 +#define cpu_has_prefetch 0 +#define cpu_has_smartmips 0 +#define cpu_has_tlb 1 +#define cpu_has_tx39_cache 0 +#define cpu_has_userlocal 0 +#define cpu_has_vce 0 +#define cpu_has_vtag_icache 0 +#define cpu_has_watch 1 +#define cpu_icache_snoops_remote_store 1 + +#endif /* __ASM_MACH_LEMOTE_CPU_FEATURE_OVERRIDES_H */ diff -Nur linux-2.6.30.5.orig/arch/mips/include/asm/mach-loongson/cs5536/cs5536.h linux-2.6.30.5/arch/mips/include/asm/mach-loongson/cs5536/cs5536.h --- linux-2.6.30.5.orig/arch/mips/include/asm/mach-loongson/cs5536/cs5536.h 1970-01-01 01:00:00.000000000 +0100 +++ linux-2.6.30.5/arch/mips/include/asm/mach-loongson/cs5536/cs5536.h 2009-08-23 19:01:04.000000000 +0200 @@ -0,0 +1,382 @@ +/* + * The header file of cs5536 sourth bridge. + * + * Copyright (C) 2007 Lemote, Inc. & Institute of Computing Technology + * Author : jlliu + */ + +#ifndef _CS5536_H +#define _CS5536_H + +#include + +extern void _rdmsr(u32 msr, u32 *hi, u32 *lo); +extern void _wrmsr(u32 msr, u32 hi, u32 lo); + +/* + * MSR module base + */ +#define CS5536_SB_MSR_BASE (0x00000000) +#define CS5536_GLIU_MSR_BASE (0x10000000) +#define CS5536_ILLEGAL_MSR_BASE (0x20000000) +#define CS5536_USB_MSR_BASE (0x40000000) +#define CS5536_IDE_MSR_BASE (0x60000000) +#define CS5536_DIVIL_MSR_BASE (0x80000000) +#define CS5536_ACC_MSR_BASE (0xa0000000) +#define CS5536_UNUSED_MSR_BASE (0xc0000000) +#define CS5536_GLCP_MSR_BASE (0xe0000000) + +#define SB_MSR_REG(offset) (CS5536_SB_MSR_BASE | (offset)) +#define GLIU_MSR_REG(offset) (CS5536_GLIU_MSR_BASE | (offset)) +#define ILLEGAL_MSR_REG(offset) (CS5536_ILLEGAL_MSR_BASE | (offset)) +#define USB_MSR_REG(offset) (CS5536_USB_MSR_BASE | (offset)) +#define IDE_MSR_REG(offset) (CS5536_IDE_MSR_BASE | (offset)) +#define DIVIL_MSR_REG(offset) (CS5536_DIVIL_MSR_BASE | (offset)) +#define ACC_MSR_REG(offset) (CS5536_ACC_MSR_BASE | (offset)) +#define UNUSED_MSR_REG(offset) (CS5536_UNUSED_MSR_BASE | (offset)) +#define GLCP_MSR_REG(offset) (CS5536_GLCP_MSR_BASE | (offset)) + +/* + * BAR SPACE OF VIRTUAL PCI : + * range for pci probe use, length is the actual size. + */ +/* IO space for all DIVIL modules */ +#define CS5536_IRQ_RANGE 0xffffffe0 /* USERD FOR PCI PROBE */ +#define CS5536_IRQ_LENGTH 0x20 /* THE REGS ACTUAL LENGTH */ +#define CS5536_SMB_RANGE 0xfffffff8 +#define CS5536_SMB_LENGTH 0x08 +#define CS5536_GPIO_RANGE 0xffffff00 +#define CS5536_GPIO_LENGTH 0x100 +#define CS5536_MFGPT_RANGE 0xffffffc0 +#define CS5536_MFGPT_LENGTH 0x40 +#define CS5536_ACPI_RANGE 0xffffffe0 +#define CS5536_ACPI_LENGTH 0x20 +#define CS5536_PMS_RANGE 0xffffff80 +#define CS5536_PMS_LENGTH 0x80 +/* MEM space for 4KB nand flash; IO space for 16B nor flash. */ +#ifdef CS5536_NOR_FLASH +#define CS5536_FLSH_LENGTH 0x10 +#define CS5536_FLSH_RANGE 0xfffffff0 +#else +#define CS5536_FLSH_RANGE 0xfffff000 +#define CS5536_FLSH_LENGTH 0x1000 +#endif +/* IO space for IDE */ +#define CS5536_IDE_RANGE 0xfffffff0 +#define CS5536_IDE_LENGTH 0x10 +/* IO space for ACC */ +#define CS5536_ACC_RANGE 0xffffff80 +#define CS5536_ACC_LENGTH 0x80 +/* MEM space for ALL USB modules */ +#define CS5536_OHCI_RANGE 0xfffff000 +#define CS5536_OHCI_LENGTH 0x1000 +#define CS5536_EHCI_RANGE 0xfffff000 +#define CS5536_EHCI_LENGTH 0x1000 +#define CS5536_UDC_RANGE 0xffffe000 +#define CS5536_UDC_LENGTH 0x2000 +#define CS5536_OTG_RANGE 0xfffff000 +#define CS5536_OTG_LENGTH 0x1000 + +/* + * PCI MSR ACCESS + */ +#define PCI_MSR_CTRL 0xF0 +#define PCI_MSR_ADDR 0xF4 +#define PCI_MSR_DATA_LO 0xF8 +#define PCI_MSR_DATA_HI 0xFC + +/**************** MSR *****************************/ + +/* + * GLIU STANDARD MSR + */ +#define GLIU_CAP 0x00 +#define GLIU_CONFIG 0x01 +#define GLIU_SMI 0x02 +#define GLIU_ERROR 0x03 +#define GLIU_PM 0x04 +#define GLIU_DIAG 0x05 + +/* + * GLIU SPEC. MSR + */ +#define GLIU_P2D_BM0 0x20 +#define GLIU_P2D_BM1 0x21 +#define GLIU_P2D_BM2 0x22 +#define GLIU_P2D_BMK0 0x23 +#define GLIU_P2D_BMK1 0x24 +#define GLIU_P2D_BM3 0x25 +#define GLIU_P2D_BM4 0x26 +#define GLIU_COH 0x80 +#define GLIU_PAE 0x81 +#define GLIU_ARB 0x82 +#define GLIU_ASMI 0x83 +#define GLIU_AERR 0x84 +#define GLIU_DEBUG 0x85 +#define GLIU_PHY_CAP 0x86 +#define GLIU_NOUT_RESP 0x87 +#define GLIU_NOUT_WDATA 0x88 +#define GLIU_WHOAMI 0x8B +#define GLIU_SLV_DIS 0x8C +#define GLIU_IOD_BM0 0xE0 +#define GLIU_IOD_BM1 0xE1 +#define GLIU_IOD_BM2 0xE2 +#define GLIU_IOD_BM3 0xE3 +#define GLIU_IOD_BM4 0xE4 +#define GLIU_IOD_BM5 0xE5 +#define GLIU_IOD_BM6 0xE6 +#define GLIU_IOD_BM7 0xE7 +#define GLIU_IOD_BM8 0xE8 +#define GLIU_IOD_BM9 0xE9 +#define GLIU_IOD_SC0 0xEA +#define GLIU_IOD_SC1 0xEB +#define GLIU_IOD_SC2 0xEC +#define GLIU_IOD_SC3 0xED +#define GLIU_IOD_SC4 0xEE +#define GLIU_IOD_SC5 0xEF +#define GLIU_IOD_SC6 0xF0 +#define GLIU_IOD_SC7 0xF1 + +/* + * SB STANDARD + */ +#define SB_CAP 0x00 +#define SB_CONFIG 0x01 +#define SB_SMI 0x02 +#define SB_ERROR 0x03 +#define SB_MAR_ERR_EN 0x00000001 +#define SB_TAR_ERR_EN 0x00000002 +#define SB_RSVD_BIT1 0x00000004 +#define SB_EXCEP_ERR_EN 0x00000008 +#define SB_SYSE_ERR_EN 0x00000010 +#define SB_PARE_ERR_EN 0x00000020 +#define SB_TAS_ERR_EN 0x00000040 +#define SB_MAR_ERR_FLAG 0x00010000 +#define SB_TAR_ERR_FLAG 0x00020000 +#define SB_RSVD_BIT2 0x00040000 +#define SB_EXCEP_ERR_FLAG 0x00080000 +#define SB_SYSE_ERR_FLAG 0x00100000 +#define SB_PARE_ERR_FLAG 0x00200000 +#define SB_TAS_ERR_FLAG 0x00400000 +#define SB_PM 0x04 +#define SB_DIAG 0x05 + +/* + * SB SPEC. + */ +#define SB_CTRL 0x10 +#define SB_R0 0x20 +#define SB_R1 0x21 +#define SB_R2 0x22 +#define SB_R3 0x23 +#define SB_R4 0x24 +#define SB_R5 0x25 +#define SB_R6 0x26 +#define SB_R7 0x27 +#define SB_R8 0x28 +#define SB_R9 0x29 +#define SB_R10 0x2A +#define SB_R11 0x2B +#define SB_R12 0x2C +#define SB_R13 0x2D +#define SB_R14 0x2E +#define SB_R15 0x2F + +/* + * GLCP STANDARD + */ +#define GLCP_CAP 0x00 +#define GLCP_CONFIG 0x01 +#define GLCP_SMI 0x02 +#define GLCP_ERROR 0x03 +#define GLCP_PM 0x04 +#define GLCP_DIAG 0x05 + +/* + * GLCP SPEC. + */ +#define GLCP_CLK_DIS_DELAY 0x08 +#define GLCP_PM_CLK_DISABLE 0x09 +#define GLCP_GLB_PM 0x0B +#define GLCP_DBG_OUT 0x0C +#define GLCP_RSVD1 0x0D +#define GLCP_SOFT_COM 0x0E +#define SOFT_BAR_SMB_FLAG 0x00000001 +#define SOFT_BAR_GPIO_FLAG 0x00000002 +#define SOFT_BAR_MFGPT_FLAG 0x00000004 +#define SOFT_BAR_IRQ_FLAG 0x00000008 +#define SOFT_BAR_PMS_FLAG 0x00000010 +#define SOFT_BAR_ACPI_FLAG 0x00000020 +#define SOFT_BAR_FLSH0_FLAG 0x00000040 +#define SOFT_BAR_FLSH1_FLAG 0x00000080 +#define SOFT_BAR_FLSH2_FLAG 0x00000100 +#define SOFT_BAR_FLSH3_FLAG 0x00000200 +#define SOFT_BAR_IDE_FLAG 0x00000400 +#define SOFT_BAR_ACC_FLAG 0x00000800 +#define SOFT_BAR_OHCI_FLAG 0x00001000 +#define SOFT_BAR_EHCI_FLAG 0x00002000 +#define SOFT_BAR_UDC_FLAG 0x00004000 +#define SOFT_BAR_OTG_FLAG 0x00008000 +#define GLCP_RSVD2 0x0F +#define GLCP_CLK_OFF 0x10 +#define GLCP_CLK_ACTIVE 0x11 +#define GLCP_CLK_DISABLE 0x12 +#define GLCP_CLK4ACK 0x13 +#define GLCP_SYS_RST 0x14 +#define GLCP_RSVD3 0x15 +#define GLCP_DBG_CLK_CTRL 0x16 +#define GLCP_CHIP_REV_ID 0x17 + +/* + * DIVIL STANDARD + */ +#define DIVIL_CAP 0x00 +#define DIVIL_CONFIG 0x01 +#define DIVIL_SMI 0x02 +#define DIVIL_ERROR 0x03 +#define DIVIL_PM 0x04 +#define DIVIL_DIAG 0x05 + +/* + * DIVIL SPEC. + */ +#define DIVIL_LBAR_IRQ 0x08 +#define DIVIL_LBAR_KEL 0x09 +#define DIVIL_LBAR_SMB 0x0B +#define DIVIL_LBAR_GPIO 0x0C +#define DIVIL_LBAR_MFGPT 0x0D +#define DIVIL_LBAR_ACPI 0x0E +#define DIVIL_LBAR_PMS 0x0F +#define DIVIL_LBAR_FLSH0 0x10 +#define DIVIL_LBAR_FLSH1 0x11 +#define DIVIL_LBAR_FLSH2 0x12 +#define DIVIL_LBAR_FLSH3 0x13 +#define DIVIL_LEG_IO 0x14 +#define DIVIL_BALL_OPTS 0x15 +#define DIVIL_SOFT_IRQ 0x16 +#define DIVIL_SOFT_RESET 0x17 +/* NOR FLASH */ +#define NORF_CTRL 0x18 +#define NORF_T01 0x19 +#define NORF_T23 0x1A +/* NAND FLASH */ +#define NANDF_DATA 0x1B +#define NANDF_CTRL 0x1C +#define NANDF_RSVD 0x1D +/* KEL Keyboard Emulation Logic */ +#define KEL_CTRL 0x1F +/* PIC */ +#define PIC_YSEL_LOW 0x20 +#define PIC_YSEL_LOW_USB_SHIFT 8 +#define PIC_YSEL_LOW_ACC_SHIFT 16 +#define PIC_YSEL_LOW_FLASH_SHIFT 24 +#define PIC_YSEL_HIGH 0x21 +#define PIC_ZSEL_LOW 0x22 +#define PIC_ZSEL_HIGH 0x23 +#define PIC_IRQM_PRIM 0x24 +#define PIC_IRQM_LPC 0x25 +#define PIC_XIRR_STS_LOW 0x26 +#define PIC_XIRR_STS_HIGH 0x27 +#define PCI_SHDW 0x34 +/* MFGPT */ +#define MFGPT_IRQ 0x28 +#define MFGPT_NR 0x29 +#define MFGPT_RSVD 0x2A +#define MFGPT_SETUP 0x2B +/* FLOPPY */ +#define FLPY_3F2_SHDW 0x30 +#define FLPY_3F7_SHDW 0x31 +#define FLPY_372_SHDW 0x32 +#define FLPY_377_SHDW 0x33 +/* PIT */ +#define PIT_SHDW 0x36 +#define PIT_CNTRL 0x37 +/* UART */ +#define UART1_MOD 0x38 +#define UART1_DONG 0x39 +#define UART1_CONF 0x3A +#define UART1_RSVD 0x3B +#define UART2_MOD 0x3C +#define UART2_DONG 0x3D +#define UART2_CONF 0x3E +#define UART2_RSVD 0x3F +/* DMA */ +#define DIVIL_AC_DMA 0x1E +#define DMA_MAP 0x40 +#define DMA_SHDW_CH0 0x41 +#define DMA_SHDW_CH1 0x42 +#define DMA_SHDW_CH2 0x43 +#define DMA_SHDW_CH3 0x44 +#define DMA_SHDW_CH4 0x45 +#define DMA_SHDW_CH5 0x46 +#define DMA_SHDW_CH6 0x47 +#define DMA_SHDW_CH7 0x48 +#define DMA_MSK_SHDW 0x49 +/* LPC */ +#define LPC_EADDR 0x4C +#define LPC_ESTAT 0x4D +#define LPC_SIRQ 0x4E +#define LPC_RSVD 0x4F +/* PMC */ +#define PMC_LTMR 0x50 +#define PMC_RSVD 0x51 +/* RTC */ +#define RTC_RAM_LOCK 0x54 +#define RTC_DOMA_OFFSET 0x55 +#define RTC_MONA_OFFSET 0x56 +#define RTC_CEN_OFFSET 0x57 + +/* + * IDE STANDARD + */ +#define IDE_CAP 0x00 +#define IDE_CONFIG 0x01 +#define IDE_SMI 0x02 +#define IDE_ERROR 0x03 +#define IDE_PM 0x04 +#define IDE_DIAG 0x05 + +/* + * IDE SPEC. + */ +#define IDE_IO_BAR 0x08 +#define IDE_CFG 0x10 +#define IDE_DTC 0x12 +#define IDE_CAST 0x13 +#define IDE_ETC 0x14 +#define IDE_INTERNAL_PM 0x15 + +/* + * ACC STANDARD + */ +#define ACC_CAP 0x00 +#define ACC_CONFIG 0x01 +#define ACC_SMI 0x02 +#define ACC_ERROR 0x03 +#define ACC_PM 0x04 +#define ACC_DIAG 0x05 + +/* + * USB STANDARD + */ +#define USB_CAP 0x00 +#define USB_CONFIG 0x01 +#define USB_SMI 0x02 +#define USB_ERROR 0x03 +#define USB_PM 0x04 +#define USB_DIAG 0x05 + +/* + * USB SPEC. + */ +#define USB_OHCI 0x08 +#define USB_EHCI 0x09 +#define USB_UDC 0x0A +#define USB_OTG 0x0B + +/****************** NATIVE ***************************/ +/* GPIO : I/O SPACE; REG : 32BITS */ +#define GPIOL_OUT_VAL 0x00 +#define GPIOL_OUT_EN 0x04 + +#endif /* _CS5536_H */ diff -Nur linux-2.6.30.5.orig/arch/mips/include/asm/mach-loongson/cs5536/cs5536_mfgpt.h linux-2.6.30.5/arch/mips/include/asm/mach-loongson/cs5536/cs5536_mfgpt.h --- linux-2.6.30.5.orig/arch/mips/include/asm/mach-loongson/cs5536/cs5536_mfgpt.h 1970-01-01 01:00:00.000000000 +0100 +++ linux-2.6.30.5/arch/mips/include/asm/mach-loongson/cs5536/cs5536_mfgpt.h 2009-08-23 19:01:04.000000000 +0200 @@ -0,0 +1,27 @@ +/* + * cs5536 mfgpt header file + */ + +#ifndef _CS5536_MFGPT_H +#define _CS5536_MFGPT_H + +#include + +extern u32 mfgpt_base; +extern void setup_mfgpt_timer(void); + +#if 1 +#define MFGPT_TICK_RATE 14318000 +#else +#define MFGPT_TICK_RATE (14318180 / 8) +#endif +#define COMPARE ((MFGPT_TICK_RATE + HZ/2) / HZ) + +#define CS5536_MFGPT_INTR 5 + +#define MFGPT_BASE mfgpt_base +#define MFGPT0_CMP2 (MFGPT_BASE + 2) +#define MFGPT0_CNT (MFGPT_BASE + 4) +#define MFGPT0_SETUP (MFGPT_BASE + 6) + +#endif /*!_CS5536_MFGPT_H */ diff -Nur linux-2.6.30.5.orig/arch/mips/include/asm/mach-loongson/cs5536/cs5536_pci.h linux-2.6.30.5/arch/mips/include/asm/mach-loongson/cs5536/cs5536_pci.h --- linux-2.6.30.5.orig/arch/mips/include/asm/mach-loongson/cs5536/cs5536_pci.h 1970-01-01 01:00:00.000000000 +0100 +++ linux-2.6.30.5/arch/mips/include/asm/mach-loongson/cs5536/cs5536_pci.h 2009-08-23 19:01:04.000000000 +0200 @@ -0,0 +1,174 @@ +/* + * the definition file of cs5536 Virtual Support Module(VSM). + * pci configuration space can be accessed through the VSM, so + * there is no need of the MSR read/write now, except the spec. + * MSR registers which are not implemented yet. + * + * Copyright (C) 2007 Lemote Inc. & Insititute of Computing Technology + * Author : jlliu, liujl@lemote.com + */ + +#ifndef _CS5536_PCI_H +#define _CS5536_PCI_H + +#include +#include + +extern void cs5536_pci_conf_write4(int function, int reg, u32 value); +extern u32 cs5536_pci_conf_read4(int function, int reg); + +#define CS5536_FLASH_INTR 6 +#define CS5536_ACC_INTR 9 +#define CS5536_IDE_INTR 14 +#define CS5536_USB_INTR 11 +#define CS5536_UART1_INTR 4 +#define CS5536_UART2_INTR 3 + +/************** PCI BUS DEVICE FUNCTION ***************/ + +/* + * PCI bus device function + */ +#define PCI_BUS_CS5536 0 +#define PCI_IDSEL_CS5536 14 + +/********** STANDARD PCI-2.2 EXPANSION ****************/ + +/* + * PCI configuration space + * we have to virtualize the PCI configure space head, so we should + * define the necessary IDs and some others. + */ + +/* CONFIG of PCI VENDOR ID*/ +#define CFG_PCI_VENDOR_ID(mod_dev_id, sys_vendor_id) \ + (((mod_dev_id) << 16) | (sys_vendor_id)) + +/* VENDOR ID */ +#define CS5536_VENDOR_ID 0x1022 + +/* DEVICE ID */ +#define CS5536_ISA_DEVICE_ID 0x2090 +#define CS5536_FLASH_DEVICE_ID 0x2091 +#define CS5536_IDE_DEVICE_ID 0x209a +#define CS5536_ACC_DEVICE_ID 0x2093 +#define CS5536_OHCI_DEVICE_ID 0x2094 +#define CS5536_EHCI_DEVICE_ID 0x2095 +#define CS5536_UDC_DEVICE_ID 0x2096 +#define CS5536_OTG_DEVICE_ID 0x2097 + +/* CLASS CODE : CLASS SUB-CLASS INTERFACE */ +#define CS5536_ISA_CLASS_CODE 0x060100 +#define CS5536_FLASH_CLASS_CODE 0x050100 +#define CS5536_IDE_CLASS_CODE 0x010180 +#define CS5536_ACC_CLASS_CODE 0x040100 +#define CS5536_OHCI_CLASS_CODE 0x0C0310 +#define CS5536_EHCI_CLASS_CODE 0x0C0320 +#define CS5536_UDC_CLASS_CODE 0x0C03FE +#define CS5536_OTG_CLASS_CODE 0x0C0380 + +/* BHLC : BIST HEADER-TYPE LATENCY-TIMER CACHE-LINE-SIZE */ + +#define CFG_PCI_CACHE_LINE_SIZE(header_type, latency_timer) \ + ((PCI_NONE_BIST << 24) | ((header_type) << 16) \ + | ((latency_timer) << 8) | PCI_NORMAL_CACHE_LINE_SIZE); + +#define PCI_NONE_BIST 0x00 /* RO not implemented yet. */ +#define PCI_BRIDGE_HEADER_TYPE 0x80 /* RO */ +#define PCI_NORMAL_HEADER_TYPE 0x00 +#define PCI_NORMAL_LATENCY_TIMER 0x00 +#define PCI_NORMAL_CACHE_LINE_SIZE 0x08 /* RW */ + +/* BAR */ +#define PCI_BAR0_REG 0x10 +#define PCI_BAR1_REG 0x14 +#define PCI_BAR2_REG 0x18 +#define PCI_BAR3_REG 0x1c +#define PCI_BAR4_REG 0x20 +#define PCI_BAR5_REG 0x24 +#define PCI_BAR_COUNT 6 +#define PCI_BAR_RANGE_MASK 0xFFFFFFFF + +/* CARDBUS CIS POINTER */ +#define PCI_CARDBUS_CIS_POINTER 0x00000000 + +/* SUBSYSTEM VENDOR ID */ +#define CS5536_SUB_VENDOR_ID CS5536_VENDOR_ID + +/* SUBSYSTEM ID */ +#define CS5536_ISA_SUB_ID CS5536_ISA_DEVICE_ID +#define CS5536_FLASH_SUB_ID CS5536_FLASH_DEVICE_ID +#define CS5536_IDE_SUB_ID CS5536_IDE_DEVICE_ID +#define CS5536_ACC_SUB_ID CS5536_ACC_DEVICE_ID +#define CS5536_OHCI_SUB_ID CS5536_OHCI_DEVICE_ID +#define CS5536_EHCI_SUB_ID CS5536_EHCI_DEVICE_ID +#define CS5536_UDC_SUB_ID CS5536_UDC_DEVICE_ID +#define CS5536_OTG_SUB_ID CS5536_OTG_DEVICE_ID + +/* EXPANSION ROM BAR */ +#define PCI_EXPANSION_ROM_BAR 0x00000000 + +/* CAPABILITIES POINTER */ +#define PCI_CAPLIST_POINTER 0x00000000 +#define PCI_CAPLIST_USB_POINTER 0x40 +/* INTERRUPT */ + +#define CFG_PCI_INTERRUPT_LINE(pin, mod_intr) \ + ((PCI_MAX_LATENCY << 24) | (PCI_MIN_GRANT << 16) | \ + ((pin) << 8) | (mod_intr)) + +#define PCI_MAX_LATENCY 0x40 +#define PCI_MIN_GRANT 0x00 +#define PCI_DEFAULT_PIN 0x01 + +/*********** EXPANSION PCI REG ************************/ + +/* + * ISA EXPANSION + */ +#define PCI_UART1_INT_REG 0x50 +#define PCI_UART2_INT_REG 0x54 +#define PCI_ISA_FIXUP_REG 0x58 + +/* + * FLASH EXPANSION + */ +#define PCI_FLASH_INT_REG 0x50 +#define PCI_NOR_FLASH_CTRL_REG 0x40 +#define PCI_NOR_FLASH_T01_REG 0x44 +#define PCI_NOR_FLASH_T23_REG 0x48 +#define PCI_NAND_FLASH_TDATA_REG 0x60 +#define PCI_NAND_FLASH_TCTRL_REG 0x64 +#define PCI_NAND_FLASH_RSVD_REG 0x68 +#define PCI_FLASH_SELECT_REG 0x70 + +/* + * IDE EXPANSION + */ +#define PCI_IDE_CFG_REG 0x40 +#define CS5536_IDE_FLASH_SIGNATURE 0xDEADBEEF +#define PCI_IDE_DTC_REG 0x48 +#define PCI_IDE_CAST_REG 0x4C +#define PCI_IDE_ETC_REG 0x50 +#define PCI_IDE_PM_REG 0x54 +#define PCI_IDE_INT_REG 0x60 + +/* + * ACC EXPANSION + */ +#define PCI_ACC_INT_REG 0x50 + +/* + * OHCI EXPANSION : INTTERUPT IS IMPLEMENTED BY THE OHCI + */ +#define PCI_OHCI_PM_REG 0x40 +#define PCI_OHCI_INT_REG 0x50 + +/* + * EHCI EXPANSION + */ +#define PCI_EHCI_LEGSMIEN_REG 0x50 +#define PCI_EHCI_LEGSMISTS_REG 0x54 +#define PCI_EHCI_FLADJ_REG 0x60 + +#endif /* _CS5536_PCI_H_ */ diff -Nur linux-2.6.30.5.orig/arch/mips/include/asm/mach-loongson/cs5536/cs5536_vsm.h linux-2.6.30.5/arch/mips/include/asm/mach-loongson/cs5536/cs5536_vsm.h --- linux-2.6.30.5.orig/arch/mips/include/asm/mach-loongson/cs5536/cs5536_vsm.h 1970-01-01 01:00:00.000000000 +0100 +++ linux-2.6.30.5/arch/mips/include/asm/mach-loongson/cs5536/cs5536_vsm.h 2009-08-23 19:01:04.000000000 +0200 @@ -0,0 +1,59 @@ +/* + * the Virtual Support Module(VSM) read/write interfaces + * + * Copyright (C) 2009 Lemote, Inc. & Institute of Computing Technology + * Author: Wu Zhangjin + */ + +#ifndef _CS5536_VSM_H +#define _CS5536_VSM_H + +#include + +#define DECLARE_CS5536_MODULE(name) \ +extern void pci_##name##_write_reg(int reg, u32 value); \ +extern u32 pci_##name##_read_reg(int reg); + +#define DEFINE_CS5536_MODULE(name) \ +void pci_##name##_write_reg(int reg, u32 value)\ +{ \ + return; \ +} \ +u32 pci_##name##_read_reg(int reg) \ +{ \ + return 0xffffffff; \ +} \ + +/* core modules of cs5536 */ + +/* ide module */ +DECLARE_CS5536_MODULE(ide) +/* acc module */ +DECLARE_CS5536_MODULE(acc) +/* ohci module */ +DECLARE_CS5536_MODULE(ohci) +/* isa module */ +DECLARE_CS5536_MODULE(isa) +/* ehci module */ +DECLARE_CS5536_MODULE(ehci) + +/* selective modules of cs5536 */ +/* flash(nor or nand flash) module */ +#ifdef CONFIG_CS5536_FLASH + DECLARE_CS5536_MODULE(flash) +#else + DEFINE_CS5536_MODULE(flash) +#endif +/* otg module */ +#ifdef CONFIG_CS5536_OTG + DECLARE_CS5536_MODULE(otg) +#else + DEFINE_CS5536_MODULE(otg) +#endif +/* udc module */ +#ifdef CONFIG_CS5536_UDC + DECLARE_CS5536_MODULE(udc) +#else + DEFINE_CS5536_MODULE(udc) +#endif +#endif /* _CS5536_VSM_H */ diff -Nur linux-2.6.30.5.orig/arch/mips/include/asm/mach-loongson/dbg.h linux-2.6.30.5/arch/mips/include/asm/mach-loongson/dbg.h --- linux-2.6.30.5.orig/arch/mips/include/asm/mach-loongson/dbg.h 1970-01-01 01:00:00.000000000 +0100 +++ linux-2.6.30.5/arch/mips/include/asm/mach-loongson/dbg.h 2009-08-23 19:01:04.000000000 +0200 @@ -0,0 +1,17 @@ +/* + * Copyright (C) 2009 Lemote Inc. & Insititute of Computing Technology + * + * 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. + */ + +#ifndef _ASM_MACH_LOONGSON_DBG_H_ +#define _ASM_MACH_LOONGSON_DBG_H_ + +/* serial port print support */ +extern void prom_putchar(char c); +extern void prom_printf(char *fmt, ...); + +#endif /* _ASM_MACH_LOONGSON_DBG_H_ */ diff -Nur linux-2.6.30.5.orig/arch/mips/include/asm/mach-loongson/dma-coherence.h linux-2.6.30.5/arch/mips/include/asm/mach-loongson/dma-coherence.h --- linux-2.6.30.5.orig/arch/mips/include/asm/mach-loongson/dma-coherence.h 1970-01-01 01:00:00.000000000 +0100 +++ linux-2.6.30.5/arch/mips/include/asm/mach-loongson/dma-coherence.h 2009-08-23 19:01:04.000000000 +0200 @@ -0,0 +1,70 @@ +/* + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + * + * Copyright (C) 2006, 07 Ralf Baechle + * Copyright (C) 2007 Lemote, Inc. & Institute of Computing Technology + * Author: Fuxin Zhang, zhangfx@lemote.com + * + */ +#ifndef __ASM_MACH_LOONGSON_DMA_COHERENCE_H +#define __ASM_MACH_LOONGSON_DMA_COHERENCE_H + +struct device; + +static inline dma_addr_t plat_map_dma_mem(struct device *dev, void *addr, + size_t size) +{ + return virt_to_phys(addr) | 0x80000000; +} + +static inline dma_addr_t plat_map_dma_mem_page(struct device *dev, + struct page *page) +{ + return page_to_phys(page) | 0x80000000; +} + +static inline unsigned long plat_dma_addr_to_phys(dma_addr_t dma_addr) +{ +#if defined(CONFIG_CPU_LOONGSON2F) && defined(CONFIG_64BIT) + return (dma_addr > 0x8fffffff) ? dma_addr : (dma_addr & 0x0fffffff); +#else + return dma_addr & 0x7fffffff; +#endif +} + +static inline void plat_unmap_dma_mem(struct device *dev, dma_addr_t dma_addr) +{ +} + +static inline int plat_dma_supported(struct device *dev, u64 mask) +{ + /* + * we fall back to GFP_DMA when the mask isn't all 1s, + * so we can't guarantee allocations that must be + * within a tighter range than GFP_DMA.. + */ + if (mask < DMA_BIT_MASK(24)) + return 0; + + return 1; +} + +static inline void plat_extra_sync_for_device(struct device *dev) +{ + return; +} + +static inline int plat_dma_mapping_error(struct device *dev, + dma_addr_t dma_addr) +{ + return 0; +} + +static inline int plat_device_is_coherent(struct device *dev) +{ + return 0; +} + +#endif /* __ASM_MACH_LOONGSON_DMA_COHERENCE_H */ diff -Nur linux-2.6.30.5.orig/arch/mips/include/asm/mach-loongson/loongson.h linux-2.6.30.5/arch/mips/include/asm/mach-loongson/loongson.h --- linux-2.6.30.5.orig/arch/mips/include/asm/mach-loongson/loongson.h 1970-01-01 01:00:00.000000000 +0100 +++ linux-2.6.30.5/arch/mips/include/asm/mach-loongson/loongson.h 2009-08-23 19:01:04.000000000 +0200 @@ -0,0 +1,319 @@ +/* + * Copyright (c) 2009 Philippe Vachon + * + * Copyright (C) 2009 Lemote, Inc. & Institute of Computing Technology + * Author: Wu Zhangjin + * + * 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. + * + */ + +#ifndef __LOONGSON_H +#define __LOONGSON_H + +#include +#include + +/* loongson internal northbridge initialization */ +extern void bonito_irq_init(void); + +/* environment arguments from bootloader */ +extern unsigned long bus_clock, cpu_clock_freq; +extern unsigned long memsize, highmemsize; + +/* loongson-based machines specific reboot setup */ +extern void loongson_reboot_setup(void); + +/* loongson-specific command line, env and memory initialization */ +extern void __init prom_init_memory(void); +extern void __init prom_init_cmdline(void); +extern void __init prom_init_env(void); + +/* irq operation functions */ +extern void bonito_irqdispatch(void); +extern void i8259_irqdispatch(void); +extern void __init bonito_irq_init(void); +extern void __init set_irq_trigger_mode(void); +extern int mach_i8259_irq(void); +extern void mach_irq_dispatch(unsigned int pending); + +/* machine-specific reboot/halt operation */ +extern void mach_prepare_reboot(void); +extern void mach_prepare_shutdown(void); + +/* We need this in some places... */ +#define delay() ({ \ + int x; \ + for (x = 0; x < 100000; x++) \ + __asm__ __volatile__(""); \ +}) + +/* loongson-specific cpu frequency relative stuff */ +#ifdef CONFIG_LOONGSON2F_CPU_FREQ +#include +extern void loongson2f_cpu_wait(void); +extern struct cpufreq_frequency_table loongson2f_clockmod_table[]; +#endif + +#define LOONGSON_REG(x) \ + (*(u32 *)((char *)CKSEG1ADDR(LOONGSON_REG_BASE) + (x))) + +#define LOONGSON_IRQ_BASE 32 +#define LOONGSON_PERFCNT_IRQ (MIPS_CPU_IRQ_BASE + 6) /* cpu perf counter */ + +#define LOONGSON_FLASH_BASE 0x1c000000 +#define LOONGSON_FLASH_SIZE 0x02000000 /* 32M */ +#define LOONGSON_FLASH_TOP (LOONGSON_FLASH_BASE+LOONGSON_FLASH_SIZE-1) + +#define LOONGSON_LIO0_BASE 0x1e000000 +#define LOONGSON_LIO0_SIZE 0x01C00000 /* 28M */ +#define LOONGSON_LIO0_TOP (LOONGSON_LIO0_BASE+LOONGSON_LIO0_SIZE-1) + +#define LOONGSON_BOOT_BASE 0x1fc00000 +#define LOONGSON_BOOT_SIZE 0x00100000 /* 1M */ +#define LOONGSON_BOOT_TOP (LOONGSON_BOOT_BASE+LOONGSON_BOOT_SIZE-1) +#define LOONGSON_REG_BASE 0x1fe00000 +#define LOONGSON_REG_SIZE 0x00100000 /* 256Bytes + 256Bytes + ??? */ +#define LOONGSON_REG_TOP (LOONGSON_REG_BASE+LOONGSON_REG_SIZE-1) + +#define LOONGSON_LIO1_BASE 0x1ff00000 +#define LOONGSON_LIO1_SIZE 0x00100000 /* 1M */ +#define LOONGSON_LIO1_TOP (LOONGSON_LIO1_BASE+LOONGSON_LIO1_SIZE-1) + +#define LOONGSON_PCILO0_BASE 0x10000000 +#define LOONGSON_PCILO1_BASE 0x14000000 +#define LOONGSON_PCILO2_BASE 0x18000000 +#define LOONGSON_PCILO_BASE LOONGSON_PCILO0_BASE +#define LOONGSON_PCILO_SIZE 0x0c000000 /* 64M * 3 */ +#define LOONGSON_PCILO_TOP (LOONGSON_PCILO0_BASE+LOONGSON_PCILO_SIZE-1) + +#define LOONGSON_PCICFG_BASE 0x1fe80000 +#define LOONGSON_PCICFG_SIZE 0x00000800 /* 2K */ +#define LOONGSON_PCICFG_TOP (LOONGSON_PCICFG_BASE+LOONGSON_PCICFG_SIZE-1) +#define LOONGSON_PCIIO_BASE 0x1fd00000 +#define LOONGSON_PCIIO_SIZE 0x00100000 /* 1M */ +#define LOONGSON_PCIIO_TOP (LOONGSON_PCIIO_BASE+LOONGSON_PCIIO_SIZE-1) + +/* Loongson Register Bases */ + +#define LOONGSON_PCICONFIGBASE 0x00 +#define LOONGSON_REGBASE 0x100 + +/* PCI Configuration Registers */ + +#define LOONGSON_PCI_REG(x) LOONGSON_REG(LOONGSON_PCICONFIGBASE + (x)) +#define LOONGSON_PCIDID LOONGSON_PCI_REG(0x00) +#define LOONGSON_PCICMD LOONGSON_PCI_REG(0x04) +#define LOONGSON_PCICLASS LOONGSON_PCI_REG(0x08) +#define LOONGSON_PCILTIMER LOONGSON_PCI_REG(0x0c) +#define LOONGSON_PCIBASE0 LOONGSON_PCI_REG(0x10) +#define LOONGSON_PCIBASE1 LOONGSON_PCI_REG(0x14) +#define LOONGSON_PCIBASE2 LOONGSON_PCI_REG(0x18) +#define LOONGSON_PCIBASE3 LOONGSON_PCI_REG(0x1c) +#define LOONGSON_PCIBASE4 LOONGSON_PCI_REG(0x20) +#define LOONGSON_PCIEXPRBASE LOONGSON_PCI_REG(0x30) +#define LOONGSON_PCIINT LOONGSON_PCI_REG(0x3c) + +#define LOONGSON_PCI_ISR4C LOONGSON_PCI_REG(0x4c) + +#define LOONGSON_PCICMD_PERR_CLR 0x80000000 +#define LOONGSON_PCICMD_SERR_CLR 0x40000000 +#define LOONGSON_PCICMD_MABORT_CLR 0x20000000 +#define LOONGSON_PCICMD_MTABORT_CLR 0x10000000 +#define LOONGSON_PCICMD_TABORT_CLR 0x08000000 +#define LOONGSON_PCICMD_MPERR_CLR 0x01000000 +#define LOONGSON_PCICMD_PERRRESPEN 0x00000040 +#define LOONGSON_PCICMD_ASTEPEN 0x00000080 +#define LOONGSON_PCICMD_SERREN 0x00000100 +#define LOONGSON_PCILTIMER_BUSLATENCY 0x0000ff00 +#define LOONGSON_PCILTIMER_BUSLATENCY_SHIFT 8 + +/* Loongson h/w Configuration */ + +#define LOONGSON_GENCFG_OFFSET 0x4 +#define LOONGSON_GENCFG LOONGSON_REG(LOONGSON_REGBASE + LOONGSON_GENCFG_OFFSET) + +#define LOONGSON_GENCFG_DEBUGMODE 0x00000001 +#define LOONGSON_GENCFG_SNOOPEN 0x00000002 +#define LOONGSON_GENCFG_CPUSELFRESET 0x00000004 + +#define LOONGSON_GENCFG_FORCE_IRQA 0x00000008 +#define LOONGSON_GENCFG_IRQA_ISOUT 0x00000010 +#define LOONGSON_GENCFG_IRQA_FROM_INT1 0x00000020 +#define LOONGSON_GENCFG_BYTESWAP 0x00000040 + +#define LOONGSON_GENCFG_UNCACHED 0x00000080 +#define LOONGSON_GENCFG_PREFETCHEN 0x00000100 +#define LOONGSON_GENCFG_WBEHINDEN 0x00000200 +#define LOONGSON_GENCFG_CACHEALG 0x00000c00 +#define LOONGSON_GENCFG_CACHEALG_SHIFT 10 +#define LOONGSON_GENCFG_PCIQUEUE 0x00001000 +#define LOONGSON_GENCFG_CACHESTOP 0x00002000 +#define LOONGSON_GENCFG_MSTRBYTESWAP 0x00004000 +#define LOONGSON_GENCFG_BUSERREN 0x00008000 +#define LOONGSON_GENCFG_NORETRYTIMEOUT 0x00010000 +#define LOONGSON_GENCFG_SHORTCOPYTIMEOUT 0x00020000 + +/* PCI address map control */ + +#define LOONGSON_PCIMAP LOONGSON_REG(LOONGSON_REGBASE + 0x10) +#define LOONGSON_PCIMEMBASECFG LOONGSON_REG(LOONGSON_REGBASE + 0x14) +#define LOONGSON_PCIMAP_CFG LOONGSON_REG(LOONGSON_REGBASE + 0x18) + +/* GPIO Regs - r/w */ + +#define LOONGSON_GPIODATA LOONGSON_REG(LOONGSON_REGBASE + 0x1c) +#define LOONGSON_GPIOIE LOONGSON_REG(LOONGSON_REGBASE + 0x20) + +/* ICU Configuration Regs - r/w */ + +#define LOONGSON_INTEDGE LOONGSON_REG(LOONGSON_REGBASE + 0x24) +#define LOONGSON_INTSTEER LOONGSON_REG(LOONGSON_REGBASE + 0x28) +#define LOONGSON_INTPOL LOONGSON_REG(LOONGSON_REGBASE + 0x2c) + +/* ICU Enable Regs - IntEn & IntISR are r/o. */ + +#define LOONGSON_INTENSET LOONGSON_REG(LOONGSON_REGBASE + 0x30) +#define LOONGSON_INTENCLR LOONGSON_REG(LOONGSON_REGBASE + 0x34) +#define LOONGSON_INTEN LOONGSON_REG(LOONGSON_REGBASE + 0x38) +#define LOONGSON_INTISR LOONGSON_REG(LOONGSON_REGBASE + 0x3c) + +/* ICU */ +#define LOONGSON_ICU_MBOXES 0x0000000f +#define LOONGSON_ICU_MBOXES_SHIFT 0 +#define LOONGSON_ICU_DMARDY 0x00000010 +#define LOONGSON_ICU_DMAEMPTY 0x00000020 +#define LOONGSON_ICU_COPYRDY 0x00000040 +#define LOONGSON_ICU_COPYEMPTY 0x00000080 +#define LOONGSON_ICU_COPYERR 0x00000100 +#define LOONGSON_ICU_PCIIRQ 0x00000200 +#define LOONGSON_ICU_MASTERERR 0x00000400 +#define LOONGSON_ICU_SYSTEMERR 0x00000800 +#define LOONGSON_ICU_DRAMPERR 0x00001000 +#define LOONGSON_ICU_RETRYERR 0x00002000 +#define LOONGSON_ICU_GPIOS 0x01ff0000 +#define LOONGSON_ICU_GPIOS_SHIFT 16 +#define LOONGSON_ICU_GPINS 0x7e000000 +#define LOONGSON_ICU_GPINS_SHIFT 25 +#define LOONGSON_ICU_MBOX(N) (1<<(LOONGSON_ICU_MBOXES_SHIFT+(N))) +#define LOONGSON_ICU_GPIO(N) (1<<(LOONGSON_ICU_GPIOS_SHIFT+(N))) +#define LOONGSON_ICU_GPIN(N) (1<<(LOONGSON_ICU_GPINS_SHIFT+(N))) + +/* PCI prefetch window base & mask */ + +#define LOONGSON_MEM_WIN_BASE_L LOONGSON_REG(LOONGSON_REGBASE + 0x40) +#define LOONGSON_MEM_WIN_BASE_H LOONGSON_REG(LOONGSON_REGBASE + 0x44) +#define LOONGSON_MEM_WIN_MASK_L LOONGSON_REG(LOONGSON_REGBASE + 0x48) +#define LOONGSON_MEM_WIN_MASK_H LOONGSON_REG(LOONGSON_REGBASE + 0x4c) + +/* PCI_Hit*_Sel_* */ + +#define LOONGSON_PCI_HIT0_SEL_L LOONGSON_REG(LOONGSON_REGBASE + 0x50) +#define LOONGSON_PCI_HIT0_SEL_H LOONGSON_REG(LOONGSON_REGBASE + 0x54) +#define LOONGSON_PCI_HIT1_SEL_L LOONGSON_REG(LOONGSON_REGBASE + 0x58) +#define LOONGSON_PCI_HIT1_SEL_H LOONGSON_REG(LOONGSON_REGBASE + 0x5c) +#define LOONGSON_PCI_HIT2_SEL_L LOONGSON_REG(LOONGSON_REGBASE + 0x60) +#define LOONGSON_PCI_HIT2_SEL_H LOONGSON_REG(LOONGSON_REGBASE + 0x64) + +/* PXArb Config & Status */ + +#define LOONGSON_PXARB_CFG LOONGSON_REG(LOONGSON_REGBASE + 0x68) +#define LOONGSON_PXARB_STATUS LOONGSON_REG(LOONGSON_REGBASE + 0x6c) + +/* Chip Config */ +#define LOONGSON_CHIPCFG0 LOONGSON_REG(LOONGSON_REGBASE + 0x80) + +/* pcimap */ + +#define LOONGSON_PCIMAP_PCIMAP_LO0 0x0000003f +#define LOONGSON_PCIMAP_PCIMAP_LO0_SHIFT 0 +#define LOONGSON_PCIMAP_PCIMAP_LO1 0x00000fc0 +#define LOONGSON_PCIMAP_PCIMAP_LO1_SHIFT 6 +#define LOONGSON_PCIMAP_PCIMAP_LO2 0x0003f000 +#define LOONGSON_PCIMAP_PCIMAP_LO2_SHIFT 12 +#define LOONGSON_PCIMAP_PCIMAP_2 0x00040000 +#define LOONGSON_PCIMAP_WIN(WIN, ADDR) \ + ((((ADDR)>>26) & LOONGSON_PCIMAP_PCIMAP_LO0) << ((WIN)*6)) + +/* + * address windows configuration module + * + * loongson2e do not have this module + */ +#if defined(CONFIG_CPU_LOONGSON2F) && defined(CONFIG_64BIT) + +/* address window config module base address */ +#define LOONGSON_ADDRWINCFG_BASE 0x3ff00000ul +#define LOONGSON_ADDRWINCFG_SIZE 0x180 + +extern unsigned long _loongson_addrwincfg_base; +#define LOONGSON_ADDRWINCFG(offset) \ + (*(u64 *)(_loongson_addrwincfg_base + (offset))) + +#define CPU_WIN0_BASE LOONGSON_ADDRWINCFG(0x00) +#define CPU_WIN1_BASE LOONGSON_ADDRWINCFG(0x08) +#define CPU_WIN2_BASE LOONGSON_ADDRWINCFG(0x10) +#define CPU_WIN3_BASE LOONGSON_ADDRWINCFG(0x18) + +#define CPU_WIN0_MASK LOONGSON_ADDRWINCFG(0x20) +#define CPU_WIN1_MASK LOONGSON_ADDRWINCFG(0x28) +#define CPU_WIN2_MASK LOONGSON_ADDRWINCFG(0x30) +#define CPU_WIN3_MASK LOONGSON_ADDRWINCFG(0x38) + +#define CPU_WIN0_MMAP LOONGSON_ADDRWINCFG(0x40) +#define CPU_WIN1_MMAP LOONGSON_ADDRWINCFG(0x48) +#define CPU_WIN2_MMAP LOONGSON_ADDRWINCFG(0x50) +#define CPU_WIN3_MMAP LOONGSON_ADDRWINCFG(0x58) + +#define PCIDMA_WIN0_BASE LOONGSON_ADDRWINCFG(0x60) +#define PCIDMA_WIN1_BASE LOONGSON_ADDRWINCFG(0x68) +#define PCIDMA_WIN2_BASE LOONGSON_ADDRWINCFG(0x70) +#define PCIDMA_WIN3_BASE LOONGSON_ADDRWINCFG(0x78) + +#define PCIDMA_WIN0_MASK LOONGSON_ADDRWINCFG(0x80) +#define PCIDMA_WIN1_MASK LOONGSON_ADDRWINCFG(0x88) +#define PCIDMA_WIN2_MASK LOONGSON_ADDRWINCFG(0x90) +#define PCIDMA_WIN3_MASK LOONGSON_ADDRWINCFG(0x98) + +#define PCIDMA_WIN0_MMAP LOONGSON_ADDRWINCFG(0xa0) +#define PCIDMA_WIN1_MMAP LOONGSON_ADDRWINCFG(0xa8) +#define PCIDMA_WIN2_MMAP LOONGSON_ADDRWINCFG(0xb0) +#define PCIDMA_WIN3_MMAP LOONGSON_ADDRWINCFG(0xb8) + +#define ADDRWIN_WIN0 0 +#define ADDRWIN_WIN1 1 +#define ADDRWIN_WIN2 2 +#define ADDRWIN_WIN3 3 + +#define ADDRWIN_MAP_DST_DDR 0 +#define ADDRWIN_MAP_DST_PCI 1 +#define ADDRWIN_MAP_DST_LIO 1 + +/* + * s: CPU, PCIDMA + * d: DDR, PCI, LIO + * win: 0, 1, 2, 3 + * src: map source + * dst: map destination + * size: ~mask + 1 + */ +#define LOONGSON_ADDRWIN_CFG(s, d, w, src, dst, size) do {\ + s##_WIN##w##_BASE = (src); \ + s##_WIN##w##_MMAP = (src) | ADDRWIN_MAP_DST_##d; \ + s##_WIN##w##_MASK = ~(size-1); \ +} while (0) + +#define LOONGSON_ADDRWIN_CPUTOPCI(win, src, dst, size) \ + LOONGSON_ADDRWIN_CFG(CPU, PCI, win, src, dst, size) +#define LOONGSON_ADDRWIN_CPUTODDR(win, src, dst, size) \ + LOONGSON_ADDRWIN_CFG(CPU, DDR, win, src, dst, size) +#define LOONGSON_ADDRWIN_PCITODDR(win, src, dst, size) \ + LOONGSON_ADDRWIN_CFG(PCIDMA, DDR, win, src, dst, size) + +#endif /* ! CONFIG_CPU_LOONGSON2F && CONFIG_64BIT */ + +#endif /* __LOONGSON_H */ + diff -Nur linux-2.6.30.5.orig/arch/mips/include/asm/mach-loongson/machine.h linux-2.6.30.5/arch/mips/include/asm/mach-loongson/machine.h --- linux-2.6.30.5.orig/arch/mips/include/asm/mach-loongson/machine.h 1970-01-01 01:00:00.000000000 +0100 +++ linux-2.6.30.5/arch/mips/include/asm/mach-loongson/machine.h 2009-08-23 19:01:04.000000000 +0200 @@ -0,0 +1,76 @@ +/* + * board-specific header file + * + * Copyright (c) 2009 Wu Zhangjin + * + * Copyright (C) 2009 Zhang Le + * + * 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. + */ + +#ifndef __MACHINE_H +#define __MACHINE_H + +#ifdef CONFIG_LEMOTE_FULOONG2E + +#define MACHTYPE MACH_LEMOTE_FL2E + +#define LOONGSON_UART_BASE (LOONGSON_PCIIO_BASE + 0x3f8) +#define LOONGSON_UART_BAUD 1843200 +#define LOONGSON_UART_IOTYPE UPIO_PORT + +#define LOONGSON_NORTH_BRIDGE_IRQ (MIPS_CPU_IRQ_BASE + 2) +#define LOONGSON_UART_IRQ (MIPS_CPU_IRQ_BASE + 4) +#define LOONGSON_SOUTH_BRIDGE_IRQ (MIPS_CPU_IRQ_BASE + 5) +#define LOONGSON_TIMER_IRQ (MIPS_CPU_IRQ_BASE + 7) +#define LOONGSON_DMATIMEOUT_IRQ (LOONGSON_IRQ_BASE + 10) + +#elif defined(CONFIG_LEMOTE_FULOONG2F) + +#define MACHTYPE MACH_LEMOTE_FL2F + +#define LOONGSON_UART_BASE (LOONGSON_PCIIO_BASE + 0x2f8) +#define LOONGSON_UART_BAUD 1843200 +#define LOONGSON_UART_IOTYPE UPIO_PORT + +#else /* CONFIG_CPU_YEELOONG2F */ + +#define MACHTYPE MACH_LEMOTE_YL2F89 + +/* yeeloong use the CPU serial port of Loongson2F */ +#define LOONGSON_UART_BASE (LOONGSON_LIO1_BASE + 0x3f8) +#define LOONGSON_UART_BAUD 3686400 +#define LOONGSON_UART_IOTYPE UPIO_MEM + +#endif /* !CONFIG_LEMOTE_FULOONG2E */ + +/* fuloong2f and yeeloong2f have the same IRQ control interface */ +#if defined(CONFIG_LEMOTE_FULOONG2F) || defined(CONFIG_LEMOTE_YEELOONG2F) + +#define LOONGSON_TIMER_IRQ (MIPS_CPU_IRQ_BASE + 7) /* cpu timer */ +#define LOONGSON_NORTH_BRIDGE_IRQ (MIPS_CPU_IRQ_BASE + 6) /* bonito */ +#define LOONGSON_UART_IRQ (MIPS_CPU_IRQ_BASE + 3) /* cpu serial port */ +#define LOONGSON_SOUTH_BRIDGE_IRQ (MIPS_CPU_IRQ_BASE + 2) /* i8259 */ + +#define LOONGSON_INT_BIT_GPIO1 (1 << 1) +#define LOONGSON_INT_BIT_GPIO2 (1 << 2) +#define LOONGSON_INT_BIT_GPIO3 (1 << 3) +#define LOONGSON_INT_BIT_PCI_INTA (1 << 4) +#define LOONGSON_INT_BIT_PCI_INTB (1 << 5) +#define LOONGSON_INT_BIT_PCI_INTC (1 << 6) +#define LOONGSON_INT_BIT_PCI_INTD (1 << 7) +#define LOONGSON_INT_BIT_PCI_PERR (1 << 8) +#define LOONGSON_INT_BIT_PCI_SERR (1 << 9) +#define LOONGSON_INT_BIT_DDR (1 << 10) +#define LOONGSON_INT_BIT_INT0 (1 << 11) +#define LOONGSON_INT_BIT_INT1 (1 << 12) +#define LOONGSON_INT_BIT_INT2 (1 << 13) +#define LOONGSON_INT_BIT_INT3 (1 << 14) + +#endif + +#endif /* ! __MACHINE_H */ diff -Nur linux-2.6.30.5.orig/arch/mips/include/asm/mach-loongson/mc146818rtc.h linux-2.6.30.5/arch/mips/include/asm/mach-loongson/mc146818rtc.h --- linux-2.6.30.5.orig/arch/mips/include/asm/mach-loongson/mc146818rtc.h 1970-01-01 01:00:00.000000000 +0100 +++ linux-2.6.30.5/arch/mips/include/asm/mach-loongson/mc146818rtc.h 2009-08-23 19:01:04.000000000 +0200 @@ -0,0 +1,36 @@ +/* + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + * + * Copyright (C) 1998, 2001, 03, 07 by Ralf Baechle (ralf@linux-mips.org) + * + * RTC routines for PC style attached Dallas chip. + */ +#ifndef __ASM_MACH_LOONGSON_MC146818RTC_H +#define __ASM_MACH_LOONGSON_MC146818RTC_H + +#include + +#define RTC_PORT(x) (0x70 + (x)) +#define RTC_IRQ 8 + +static inline unsigned char CMOS_READ(unsigned long addr) +{ + outb_p(addr, RTC_PORT(0)); + return inb_p(RTC_PORT(1)); +} + +static inline void CMOS_WRITE(unsigned char data, unsigned long addr) +{ + outb_p(addr, RTC_PORT(0)); + outb_p(data, RTC_PORT(1)); +} + +#define RTC_ALWAYS_BCD 0 + +#ifndef mc146818_decode_year +#define mc146818_decode_year(year) ((year) < 70 ? (year) + 2000 : (year) + 1970) +#endif + +#endif /* __ASM_MACH_LOONGSON_MC146818RTC_H */ diff -Nur linux-2.6.30.5.orig/arch/mips/include/asm/mach-loongson/mem.h linux-2.6.30.5/arch/mips/include/asm/mach-loongson/mem.h --- linux-2.6.30.5.orig/arch/mips/include/asm/mach-loongson/mem.h 1970-01-01 01:00:00.000000000 +0100 +++ linux-2.6.30.5/arch/mips/include/asm/mach-loongson/mem.h 2009-08-23 19:01:04.000000000 +0200 @@ -0,0 +1,31 @@ +#ifndef __MEM_H +#define __MEM_H + +/* + * high memory space + * + * in loongson2e, starts from 512M + * in loongson2f, starts from 2G + 256M + */ +#ifdef CONFIG_CPU_LOONGSON2E +#define LOONGSON_HIGHMEM_START 0x20000000 +#else +#define LOONGSON_HIGHMEM_START 0x90000000 +#endif + +/* + * the peripheral registers(MMIO): + * + * On the Lemote Loongson 2e system, reside between 0x1000:0000 and 0x2000:0000. + * On the Lemote Loongson 2f system, reside between 0x1000:0000 and 0x8000:0000. + */ + +#define LOONGSON_MMIO_MEM_START 0x10000000 + +#ifdef CONFIG_CPU_LOONGSON2E +#define LOONGSON_MMIO_MEM_END 0x20000000 +#else +#define LOONGSON_MMIO_MEM_END 0x80000000 +#endif + +#endif /* !__MEM_H */ diff -Nur linux-2.6.30.5.orig/arch/mips/include/asm/mach-loongson/pci.h linux-2.6.30.5/arch/mips/include/asm/mach-loongson/pci.h --- linux-2.6.30.5.orig/arch/mips/include/asm/mach-loongson/pci.h 1970-01-01 01:00:00.000000000 +0100 +++ linux-2.6.30.5/arch/mips/include/asm/mach-loongson/pci.h 2009-08-23 19:01:04.000000000 +0200 @@ -0,0 +1,59 @@ +/* + * Copyright (c) 2008 Zhang Le + * Copyright (c) 2009 Wu Zhangjin + * + * 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., 675 Mass Ave, Cambridge, MA + * 02139, USA. + */ + +#ifndef _LOONGSON_PCI_H_ +#define _LOONGSON_PCI_H_ + +extern struct pci_ops loongson_pci_ops; + +/* this is an offset from mips_io_port_base */ +#define LOONGSON_PCI_IO_START 0x00004000UL + +#if defined(CONFIG_CPU_LOONGSON2F) && defined(CONFIG_64BIT) + +/* + * we use address window2 to map cpu address space to pci space + * window2: cpu [1G, 2G] -> pci [1G, 2G] + * why not use window 0 & 1? because they are used by cpu when booting. + * window0: cpu [0, 256M] -> ddr [0, 256M] + * window1: cpu [256M, 512M] -> pci [256M, 512M] + */ + +/* the smallest LOONGSON_CPU_MEM_SRC can be 512M */ +#define LOONGSON_CPU_MEM_SRC 0x40000000ul /* 1G */ +#define LOONGSON_PCI_MEM_DST LOONGSON_CPU_MEM_SRC + +#define LOONGSON_PCI_MEM_START LOONGSON_PCI_MEM_DST +#define LOONGSON_PCI_MEM_END (0x80000000ul-1) /* 2G */ + +#define MMAP_CPUTOPCI_SIZE (LOONGSON_PCI_MEM_END - \ + LOONGSON_PCI_MEM_START + 1) + +#else /* loongson2f/32bit & loongson2e */ + +#define LOONGSON_PCI_MEM_START 0x14000000UL +#define LOONGSON_PCI_MEM_END 0x1fffffffUL + +#endif /* !(defined(CONFIG_CPU_LOONGSON2F) && defined(CONFIG_64BIT))*/ + + +#endif /* !_LOONGSON_PCI_H_ */ diff -Nur linux-2.6.30.5.orig/arch/mips/include/asm/mach-loongson/war.h linux-2.6.30.5/arch/mips/include/asm/mach-loongson/war.h --- linux-2.6.30.5.orig/arch/mips/include/asm/mach-loongson/war.h 1970-01-01 01:00:00.000000000 +0100 +++ linux-2.6.30.5/arch/mips/include/asm/mach-loongson/war.h 2009-08-23 19:01:04.000000000 +0200 @@ -0,0 +1,25 @@ +/* + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + * + * Copyright (C) 2002, 2004, 2007 by Ralf Baechle + */ +#ifndef __ASM_MIPS_MACH_LOONGSON_WAR_H +#define __ASM_MIPS_MACH_LOONGSON_WAR_H + +#define R4600_V1_INDEX_ICACHEOP_WAR 0 +#define R4600_V1_HIT_CACHEOP_WAR 0 +#define R4600_V2_HIT_CACHEOP_WAR 0 +#define R5432_CP0_INTERRUPT_WAR 0 +#define BCM1250_M3_WAR 0 +#define SIBYTE_1956_WAR 0 +#define MIPS4K_ICACHE_REFILL_WAR 0 +#define MIPS_CACHE_SYNC_WAR 0 +#define TX49XX_ICACHE_INDEX_INV_WAR 0 +#define RM9000_CDEX_SMP_WAR 0 +#define ICACHE_REFILLS_WORKAROUND_WAR 0 +#define R10000_LLSC_WAR 0 +#define MIPS34K_MISSED_ITLB_WAR 0 + +#endif /* __ASM_MIPS_MACH_LOONGSON_WAR_H */ diff -Nur linux-2.6.30.5.orig/arch/mips/include/asm/mips-boards/bonito64.h linux-2.6.30.5/arch/mips/include/asm/mips-boards/bonito64.h --- linux-2.6.30.5.orig/arch/mips/include/asm/mips-boards/bonito64.h 2009-08-16 23:19:38.000000000 +0200 +++ linux-2.6.30.5/arch/mips/include/asm/mips-boards/bonito64.h 2009-08-23 19:01:04.000000000 +0200 @@ -26,11 +26,6 @@ /* offsets from base register */ #define BONITO(x) (x) -#elif defined(CONFIG_LEMOTE_FULONG) - -#define BONITO(x) (*(volatile u32 *)((char *)CKSEG1ADDR(BONITO_REG_BASE) + (x))) -#define BONITO_IRQ_BASE 32 - #else /* diff -Nur linux-2.6.30.5.orig/arch/mips/include/asm/page.h linux-2.6.30.5/arch/mips/include/asm/page.h --- linux-2.6.30.5.orig/arch/mips/include/asm/page.h 2009-08-16 23:19:38.000000000 +0200 +++ linux-2.6.30.5/arch/mips/include/asm/page.h 2009-08-23 19:01:04.000000000 +0200 @@ -179,8 +179,9 @@ #endif -#define virt_to_page(kaddr) pfn_to_page(PFN_DOWN(virt_to_phys(kaddr))) -#define virt_addr_valid(kaddr) pfn_valid(PFN_DOWN(virt_to_phys(kaddr))) +#define virt_to_page(kaddr) \ + pfn_to_page(PFN_DOWN(virt_to_phys((void *)kaddr))) +#define virt_addr_valid(kaddr) pfn_valid(PFN_DOWN(virt_to_phys((void *)kaddr))) #define VM_DATA_DEFAULT_FLAGS (VM_READ | VM_WRITE | VM_EXEC | \ VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC) diff -Nur linux-2.6.30.5.orig/arch/mips/include/asm/pci.h linux-2.6.30.5/arch/mips/include/asm/pci.h --- linux-2.6.30.5.orig/arch/mips/include/asm/pci.h 2009-08-16 23:19:38.000000000 +0200 +++ linux-2.6.30.5/arch/mips/include/asm/pci.h 2009-08-23 19:01:04.000000000 +0200 @@ -56,7 +56,7 @@ /* * board supplied pci irq fixup routine */ -extern int pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin); +extern int pcibios_map_irq(struct pci_dev *dev, u8 slot, u8 pin); /* Can be used to override the logic in pci_scan_bus for skipping diff -Nur linux-2.6.30.5.orig/arch/mips/include/asm/pgtable.h linux-2.6.30.5/arch/mips/include/asm/pgtable.h --- linux-2.6.30.5.orig/arch/mips/include/asm/pgtable.h 2009-08-16 23:19:38.000000000 +0200 +++ linux-2.6.30.5/arch/mips/include/asm/pgtable.h 2009-08-23 19:01:04.000000000 +0200 @@ -370,6 +370,19 @@ #include /* + * uncache accelerate for video memory access + */ +#ifdef CONFIG_LOONGSON2F +#define __HAVE_PHYS_MEM_ACCESS_PROT + +struct file; +pgprot_t phys_mem_access_prot(struct file *file, unsigned long pfn, + unsigned long size, pgprot_t vma_prot); +int phys_mem_access_prot_allowed(struct file *file, unsigned long pfn, + unsigned long size, pgprot_t *vma_prot); +#endif + +/* * We provide our own get_unmapped area to cope with the virtual aliasing * constraints placed on us by the cache architecture. */ diff -Nur linux-2.6.30.5.orig/arch/mips/include/asm/stackframe.h linux-2.6.30.5/arch/mips/include/asm/stackframe.h --- linux-2.6.30.5.orig/arch/mips/include/asm/stackframe.h 2009-08-16 23:19:38.000000000 +0200 +++ linux-2.6.30.5/arch/mips/include/asm/stackframe.h 2009-08-23 19:01:04.000000000 +0200 @@ -117,6 +117,20 @@ .endm #else .macro get_saved_sp /* Uniprocessor variation */ +#ifdef CONFIG_CPU_LOONGSON2 + move k0, ra + jal 2008f + nop +2008 : jal 2008f + nop +2008 : jal 2008f + nop +2008 : jal 2008f + nop +2008 : move ra, k0 + li k0, 3 + mtc0 k0, $22 +#endif #if defined(CONFIG_32BIT) || defined(KBUILD_64BIT_SYM32) lui k1, %hi(kernelsp) #else diff -Nur linux-2.6.30.5.orig/arch/mips/include/asm/suspend.h linux-2.6.30.5/arch/mips/include/asm/suspend.h --- linux-2.6.30.5.orig/arch/mips/include/asm/suspend.h 2009-08-16 23:19:38.000000000 +0200 +++ linux-2.6.30.5/arch/mips/include/asm/suspend.h 2009-08-23 20:29:58.000000000 +0200 @@ -1,6 +1,9 @@ #ifndef __ASM_SUSPEND_H #define __ASM_SUSPEND_H -/* Somewhen... Maybe :-) */ +static inline int arch_prepare_suspend(void) { return 0; } + +/* References to section boundaries */ +extern const void __nosave_begin, __nosave_end; #endif /* __ASM_SUSPEND_H */ diff -Nur linux-2.6.30.5.orig/arch/mips/Kconfig linux-2.6.30.5/arch/mips/Kconfig --- linux-2.6.30.5.orig/arch/mips/Kconfig 2009-08-16 23:19:38.000000000 +0200 +++ linux-2.6.30.5/arch/mips/Kconfig 2009-08-23 19:01:56.000000000 +0200 @@ -6,7 +6,7 @@ select HAVE_ARCH_KGDB # Horrible source of confusion. Die, die, die ... select EMBEDDED - select RTC_LIB + select RTC_LIB if !MACH_LOONGSON mainmenu "Linux/MIPS Kernel Configuration" @@ -154,30 +154,19 @@ select SYS_SUPPORTS_64BIT_KERNEL if BROKEN select SYS_SUPPORTS_LITTLE_ENDIAN -config LEMOTE_FULONG - bool "Lemote Fulong mini-PC" - select ARCH_SPARSEMEM_ENABLE - select CEVT_R4K - select CSRC_R4K - select SYS_HAS_CPU_LOONGSON2 - select DMA_NONCOHERENT - select BOOT_ELF32 - select BOARD_SCACHE - select HAVE_STD_PC_SERIAL_PORT - select HW_HAS_PCI - select I8259 - select ISA - select IRQ_CPU - select SYS_SUPPORTS_32BIT_KERNEL - select SYS_SUPPORTS_64BIT_KERNEL - select SYS_SUPPORTS_LITTLE_ENDIAN - select SYS_SUPPORTS_HIGHMEM - select SYS_HAS_EARLY_PRINTK - select GENERIC_ISA_DMA_SUPPORT_BROKEN - select CPU_HAS_WB - help - Lemote Fulong mini-PC board based on the Chinese Loongson-2E CPU and - an FPGA northbridge +config MACH_LOONGSON + bool "Loongson family of machines" + select HAVE_KERNEL_GZIP + select HAVE_KERNEL_BZIP2 + select HAVE_KERNEL_LZMA + select LOONGSON_PLATFORM_DEVICES + help + This enables the support of Loongson family of machines. + + Loongson is a family of general-purpose MIPS-compatible CPUs. + developed at Institute of Computing Technology (ICT), + Chinese Academy of Sciences (CAS) in the People's Republic + of China. The chief architect is Professor Weiwu Hu. config MIPS_MALTA bool "MIPS Malta board" @@ -643,6 +632,7 @@ source "arch/mips/txx9/Kconfig" source "arch/mips/vr41xx/Kconfig" source "arch/mips/cavium-octeon/Kconfig" +source "arch/mips/loongson/Kconfig" endmenu @@ -1005,16 +995,29 @@ prompt "CPU type" default CPU_R4X00 -config CPU_LOONGSON2 - bool "Loongson 2" - depends on SYS_HAS_CPU_LOONGSON2 - select CPU_SUPPORTS_32BIT_KERNEL - select CPU_SUPPORTS_64BIT_KERNEL - select CPU_SUPPORTS_HIGHMEM +config CPU_LOONGSON2E + bool "Loongson 2E" + depends on SYS_HAS_CPU_LOONGSON2E + select CPU_LOONGSON2 help The Loongson 2E processor implements the MIPS III instruction set with many extensions. + It has an internal FPGA northbridge, which is compatiable to + bonito64. + +config CPU_LOONGSON2F + bool "Loongson 2F" + depends on SYS_HAS_CPU_LOONGSON2F + select CPU_LOONGSON2 + help + The Loongson 2F processor implements the MIPS III instruction set + with many extensions. + + Loongson2F have built-in DDR2 and PCIX controller. The PCIX controller + have a similar programming interface with FPGA northbridge used in + Loongson2E. + config CPU_MIPS32_R1 bool "MIPS32 Release 1" depends on SYS_HAS_CPU_MIPS32_R1 @@ -1253,7 +1256,16 @@ endchoice -config SYS_HAS_CPU_LOONGSON2 +config CPU_LOONGSON2 + bool + select CPU_SUPPORTS_32BIT_KERNEL + select CPU_SUPPORTS_64BIT_KERNEL + select CPU_SUPPORTS_HIGHMEM + +config SYS_HAS_CPU_LOONGSON2E + bool + +config SYS_HAS_CPU_LOONGSON2F bool config SYS_HAS_CPU_MIPS32_R1 @@ -2121,14 +2133,35 @@ menu "Power management options" +config ARCH_HIBERNATION_POSSIBLE + def_bool y + depends on SYS_SUPPORTS_HOTPLUG_CPU || !SMP + config ARCH_SUSPEND_POSSIBLE - def_bool y - depends on !SMP + def_bool y + depends on SYS_SUPPORTS_HOTPLUG_CPU || !SMP source "kernel/power/Kconfig" endmenu +menu "CPU Frequency scaling" + +source "drivers/cpufreq/Kconfig" + +config LOONGSON2F_CPU_FREQ + bool "Loongson-2F CPU Frequency driver" + depends on CPU_LOONGSON2F && CPU_FREQ && (CS5536_MFGPT || I8253) + select CPU_FREQ_TABLE + help + This adds the cpufreq driver for Loongson-2F. + + For details, take a look at . + + If unsure, say N. + +endmenu + source "net/Kconfig" source "drivers/Kconfig" diff -Nur linux-2.6.30.5.orig/arch/mips/kernel/asm-offsets.c linux-2.6.30.5/arch/mips/kernel/asm-offsets.c --- linux-2.6.30.5.orig/arch/mips/kernel/asm-offsets.c 2009-08-16 23:19:38.000000000 +0200 +++ linux-2.6.30.5/arch/mips/kernel/asm-offsets.c 2009-08-23 21:30:52.000000000 +0200 @@ -14,6 +14,7 @@ #include #include #include +#include #include #include @@ -326,3 +327,15 @@ BLANK(); } #endif + +#ifdef CONFIG_HIBERNATION +void output_pbe_defines(void) +{ + COMMENT(" Linux struct pbe offsets. "); + OFFSET(PBE_ADDRESS, pbe, address); + OFFSET(PBE_ORIG_ADDRESS, pbe, orig_address); + OFFSET(PBE_NEXT, pbe, next); + DEFINE(PBE_SIZE, sizeof(struct pbe)); + BLANK(); +} +#endif diff -Nur linux-2.6.30.5.orig/arch/mips/kernel/i8259.c linux-2.6.30.5/arch/mips/kernel/i8259.c --- linux-2.6.30.5.orig/arch/mips/kernel/i8259.c 2009-08-16 23:19:38.000000000 +0200 +++ linux-2.6.30.5/arch/mips/kernel/i8259.c 2009-08-23 19:01:04.000000000 +0200 @@ -177,10 +177,12 @@ outb(cached_slave_mask, PIC_SLAVE_IMR); outb(0x60+(irq&7), PIC_SLAVE_CMD);/* 'Specific EOI' to slave */ outb(0x60+PIC_CASCADE_IR, PIC_MASTER_CMD); /* 'Specific EOI' to master-IRQ2 */ + inb(PIC_MASTER_CMD); /* flush posted write */ } else { inb(PIC_MASTER_IMR); /* DUMMY - (do we need this?) */ outb(cached_master_mask, PIC_MASTER_IMR); outb(0x60+irq, PIC_MASTER_CMD); /* 'Specific EOI to master */ + inb(PIC_MASTER_CMD); /* flush posted write */ } smtc_im_ack_irq(irq); spin_unlock_irqrestore(&i8259A_lock, flags); diff -Nur linux-2.6.30.5.orig/arch/mips/kernel/loongson2f_freq.c linux-2.6.30.5/arch/mips/kernel/loongson2f_freq.c --- linux-2.6.30.5.orig/arch/mips/kernel/loongson2f_freq.c 1970-01-01 01:00:00.000000000 +0100 +++ linux-2.6.30.5/arch/mips/kernel/loongson2f_freq.c 2009-08-23 19:01:04.000000000 +0200 @@ -0,0 +1,216 @@ +/* + * arch/mips/kernel/cpufreq.c + * + * cpufreq driver for the loongson-2f processors. + * + * Copyright (C) 2006 - 2008 Lemote Inc. & Insititute of Computing Technology + * Author: Yanhua, yanh@lemote.com + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include /* set_cpus_allowed() */ +#include +#include + +#include +#include + +static uint nowait; + +static struct clk *cpuclk; + +static void (*saved_cpu_wait) (void); + +static int loongson2f_cpu_freq_notifier(struct notifier_block *nb, + unsigned long val, void *data); + +static struct notifier_block loongson2f_cpufreq_notifier_block = { + .notifier_call = loongson2f_cpu_freq_notifier +}; + +static int loongson2f_cpu_freq_notifier(struct notifier_block *nb, + unsigned long val, void *data) +{ + if (val == CPUFREQ_POSTCHANGE) + current_cpu_data.udelay_val = loops_per_jiffy; + + return 0; +} + +static unsigned int loongson2f_cpufreq_get(unsigned int cpu) +{ + return clk_get_rate(cpuclk); +} + +/* + * Here we notify other drivers of the proposed change and the final change. + */ +static int loongson2f_cpufreq_target(struct cpufreq_policy *policy, + unsigned int target_freq, + unsigned int relation) +{ + unsigned int cpu = policy->cpu; + unsigned int newstate = 0; + cpumask_t cpus_allowed; + struct cpufreq_freqs freqs; + long freq; + + if (!cpu_online(cpu)) + return -ENODEV; + + cpus_allowed = current->cpus_allowed; + set_cpus_allowed(current, cpumask_of_cpu(cpu)); + +#ifdef CONFIG_SMP + BUG_ON(smp_processor_id() != cpu); +#endif + + if (cpufreq_frequency_table_target + (policy, &loongson2f_clockmod_table[0], target_freq, relation, + &newstate)) + return -EINVAL; + + freq = + cpu_clock_freq / 1000 * loongson2f_clockmod_table[newstate].index / + 8; + if (freq < policy->min || freq > policy->max) + return -EINVAL; + + pr_debug("cpufreq: requested frequency %u Hz\n", target_freq * 1000); + + freqs.cpu = cpu; + freqs.old = loongson2f_cpufreq_get(cpu); + freqs.new = freq; + freqs.flags = 0; + + if (freqs.new == freqs.old) + return 0; + + /* notifiers */ + cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE); + + set_cpus_allowed(current, cpus_allowed); + + /* setting the cpu frequency */ + clk_set_rate(cpuclk, freq); + + /* notifiers */ + cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE); + + pr_debug("cpufreq: set frequency %lu kHz\n", freq); + + return 0; +} + +static int loongson2f_cpufreq_cpu_init(struct cpufreq_policy *policy) +{ + int i; + int result; + + if (!cpu_online(policy->cpu)) + return -ENODEV; + + cpuclk = clk_get(NULL, "cpu_clk"); + if (IS_ERR(cpuclk)) { + printk(KERN_ERR "cpufreq: couldn't get CPU clk\n"); + return PTR_ERR(cpuclk); + } + + cpuclk->rate = cpu_clock_freq / 1000; + if (!cpuclk->rate) + return -EINVAL; + + /* clock table init */ + for (i = 2; + (loongson2f_clockmod_table[i].frequency != CPUFREQ_TABLE_END); + i++) { + loongson2f_clockmod_table[i].frequency = (cpuclk->rate * i) / 8; + } + + policy->cur = loongson2f_cpufreq_get(policy->cpu); + + cpufreq_frequency_table_get_attr(&loongson2f_clockmod_table[0], + policy->cpu); + + result = + cpufreq_frequency_table_cpuinfo(policy, + &loongson2f_clockmod_table[0]); + if (result) + return result; + + return 0; +} + +static int loongson2f_cpufreq_verify(struct cpufreq_policy *policy) +{ + return cpufreq_frequency_table_verify(policy, + &loongson2f_clockmod_table[0]); +} + +static int loongson2f_cpufreq_exit(struct cpufreq_policy *policy) +{ + clk_put(cpuclk); + return 0; +} + +static struct freq_attr *loongson2f_table_attr[] = { + &cpufreq_freq_attr_scaling_available_freqs, + NULL, +}; + +static struct cpufreq_driver loongson2f_cpufreq_driver = { + .owner = THIS_MODULE, + .name = "loongson2f", + .init = loongson2f_cpufreq_cpu_init, + .verify = loongson2f_cpufreq_verify, + .target = loongson2f_cpufreq_target, + .get = loongson2f_cpufreq_get, + .exit = loongson2f_cpufreq_exit, + .attr = loongson2f_table_attr, +}; + +static int __init loongson2f_cpufreq_module_init(void) +{ + int result; + + printk(KERN_INFO "cpufreq: Loongson-2F CPU frequency driver.\n"); + result = cpufreq_register_driver(&loongson2f_cpufreq_driver); + + if (!result && !nowait) { + saved_cpu_wait = cpu_wait; + cpu_wait = loongson2f_cpu_wait; + } + + cpufreq_register_notifier(&loongson2f_cpufreq_notifier_block, + CPUFREQ_TRANSITION_NOTIFIER); + return result; +} + +static void __exit loongson2f_cpufreq_module_exit(void) +{ + if (!nowait && saved_cpu_wait) + cpu_wait = saved_cpu_wait; + cpufreq_unregister_driver(&loongson2f_cpufreq_driver); + cpufreq_unregister_notifier(&loongson2f_cpufreq_notifier_block, + CPUFREQ_TRANSITION_NOTIFIER); +} + +module_init(loongson2f_cpufreq_module_init); +module_exit(loongson2f_cpufreq_module_exit); + +module_param(nowait, uint, 0644); +MODULE_PARM_DESC(nowait, "Disable Loongson-2F specific wait"); + +MODULE_AUTHOR("Yanhua "); +MODULE_DESCRIPTION("cpufreq driver for Loongson2F"); +MODULE_LICENSE("GPL"); diff -Nur linux-2.6.30.5.orig/arch/mips/kernel/Makefile linux-2.6.30.5/arch/mips/kernel/Makefile --- linux-2.6.30.5.orig/arch/mips/kernel/Makefile 2009-08-16 23:19:38.000000000 +0200 +++ linux-2.6.30.5/arch/mips/kernel/Makefile 2009-08-23 19:01:04.000000000 +0200 @@ -73,6 +73,7 @@ obj-$(CONFIG_MIPS32_COMPAT) += linux32.o ptrace32.o signal32.o obj-$(CONFIG_MIPS32_N32) += binfmt_elfn32.o scall64-n32.o signal_n32.o obj-$(CONFIG_MIPS32_O32) += binfmt_elfo32.o scall64-o32.o +obj-$(CONFIG_LOONGSON2F_CPU_FREQ) += loongson2f_freq.o obj-$(CONFIG_KGDB) += kgdb.o obj-$(CONFIG_PROC_FS) += proc.o diff -Nur linux-2.6.30.5.orig/arch/mips/lemote/lm2e/bonito-irq.c linux-2.6.30.5/arch/mips/lemote/lm2e/bonito-irq.c --- linux-2.6.30.5.orig/arch/mips/lemote/lm2e/bonito-irq.c 2009-08-16 23:19:38.000000000 +0200 +++ linux-2.6.30.5/arch/mips/lemote/lm2e/bonito-irq.c 1970-01-01 01:00:00.000000000 +0100 @@ -1,74 +0,0 @@ -/* - * Copyright 2001 MontaVista Software Inc. - * Author: Jun Sun, jsun@mvista.com or jsun@junsun.net - * Copyright (C) 2000, 2001 Ralf Baechle (ralf@gnu.org) - * - * Copyright (C) 2007 Lemote Inc. & Insititute of Computing Technology - * Author: Fuxin Zhang, zhangfx@lemote.com - * - * 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 SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN - * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF - * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON - * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * 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., - * 675 Mass Ave, Cambridge, MA 02139, USA. - * - */ -#include -#include -#include -#include -#include -#include - -#include - - -static inline void bonito_irq_enable(unsigned int irq) -{ - BONITO_INTENSET = (1 << (irq - BONITO_IRQ_BASE)); - mmiowb(); -} - -static inline void bonito_irq_disable(unsigned int irq) -{ - BONITO_INTENCLR = (1 << (irq - BONITO_IRQ_BASE)); - mmiowb(); -} - -static struct irq_chip bonito_irq_type = { - .name = "bonito_irq", - .ack = bonito_irq_disable, - .mask = bonito_irq_disable, - .mask_ack = bonito_irq_disable, - .unmask = bonito_irq_enable, -}; - -static struct irqaction dma_timeout_irqaction = { - .handler = no_action, - .name = "dma_timeout", -}; - -void bonito_irq_init(void) -{ - u32 i; - - for (i = BONITO_IRQ_BASE; i < BONITO_IRQ_BASE + 32; i++) { - set_irq_chip_and_handler(i, &bonito_irq_type, handle_level_irq); - } - - setup_irq(BONITO_IRQ_BASE + 10, &dma_timeout_irqaction); -} diff -Nur linux-2.6.30.5.orig/arch/mips/lemote/lm2e/dbg_io.c linux-2.6.30.5/arch/mips/lemote/lm2e/dbg_io.c --- linux-2.6.30.5.orig/arch/mips/lemote/lm2e/dbg_io.c 2009-08-16 23:19:38.000000000 +0200 +++ linux-2.6.30.5/arch/mips/lemote/lm2e/dbg_io.c 1970-01-01 01:00:00.000000000 +0100 @@ -1,146 +0,0 @@ -/* - * Copyright 2001 MontaVista Software Inc. - * Author: Jun Sun, jsun@mvista.com or jsun@junsun.net - * Copyright (C) 2000, 2001 Ralf Baechle (ralf@gnu.org) - * - * Copyright (C) 2007 Lemote Inc. & Insititute of Computing Technology - * Author: Fuxin Zhang, zhangfx@lemote.com - * - * 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 SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN - * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF - * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON - * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * 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., - * 675 Mass Ave, Cambridge, MA 02139, USA. - * - */ - -#include -#include -#include - -#include - -#define UART16550_BAUD_2400 2400 -#define UART16550_BAUD_4800 4800 -#define UART16550_BAUD_9600 9600 -#define UART16550_BAUD_19200 19200 -#define UART16550_BAUD_38400 38400 -#define UART16550_BAUD_57600 57600 -#define UART16550_BAUD_115200 115200 - -#define UART16550_PARITY_NONE 0 -#define UART16550_PARITY_ODD 0x08 -#define UART16550_PARITY_EVEN 0x18 -#define UART16550_PARITY_MARK 0x28 -#define UART16550_PARITY_SPACE 0x38 - -#define UART16550_DATA_5BIT 0x0 -#define UART16550_DATA_6BIT 0x1 -#define UART16550_DATA_7BIT 0x2 -#define UART16550_DATA_8BIT 0x3 - -#define UART16550_STOP_1BIT 0x0 -#define UART16550_STOP_2BIT 0x4 - -/* ----------------------------------------------------- */ - -/* === CONFIG === */ -#ifdef CONFIG_64BIT -#define BASE (0xffffffffbfd003f8) -#else -#define BASE (0xbfd003f8) -#endif - -#define MAX_BAUD BASE_BAUD -/* === END OF CONFIG === */ - -#define REG_OFFSET 1 - -/* register offset */ -#define OFS_RCV_BUFFER 0 -#define OFS_TRANS_HOLD 0 -#define OFS_SEND_BUFFER 0 -#define OFS_INTR_ENABLE (1*REG_OFFSET) -#define OFS_INTR_ID (2*REG_OFFSET) -#define OFS_DATA_FORMAT (3*REG_OFFSET) -#define OFS_LINE_CONTROL (3*REG_OFFSET) -#define OFS_MODEM_CONTROL (4*REG_OFFSET) -#define OFS_RS232_OUTPUT (4*REG_OFFSET) -#define OFS_LINE_STATUS (5*REG_OFFSET) -#define OFS_MODEM_STATUS (6*REG_OFFSET) -#define OFS_RS232_INPUT (6*REG_OFFSET) -#define OFS_SCRATCH_PAD (7*REG_OFFSET) - -#define OFS_DIVISOR_LSB (0*REG_OFFSET) -#define OFS_DIVISOR_MSB (1*REG_OFFSET) - -/* memory-mapped read/write of the port */ -#define UART16550_READ(y) readb((char *)BASE + (y)) -#define UART16550_WRITE(y, z) writeb(z, (char *)BASE + (y)) - -void debugInit(u32 baud, u8 data, u8 parity, u8 stop) -{ - u32 divisor; - - /* disable interrupts */ - UART16550_WRITE(OFS_INTR_ENABLE, 0); - - /* set up buad rate */ - /* set DIAB bit */ - UART16550_WRITE(OFS_LINE_CONTROL, 0x80); - - /* set divisor */ - divisor = MAX_BAUD / baud; - UART16550_WRITE(OFS_DIVISOR_LSB, divisor & 0xff); - UART16550_WRITE(OFS_DIVISOR_MSB, (divisor & 0xff00) >> 8); - - /* clear DIAB bit */ - UART16550_WRITE(OFS_LINE_CONTROL, 0x0); - - /* set data format */ - UART16550_WRITE(OFS_DATA_FORMAT, data | parity | stop); -} - -static int remoteDebugInitialized; - -u8 getDebugChar(void) -{ - if (!remoteDebugInitialized) { - remoteDebugInitialized = 1; - debugInit(UART16550_BAUD_115200, - UART16550_DATA_8BIT, - UART16550_PARITY_NONE, UART16550_STOP_1BIT); - } - - while ((UART16550_READ(OFS_LINE_STATUS) & 0x1) == 0) ; - return UART16550_READ(OFS_RCV_BUFFER); -} - -int putDebugChar(u8 byte) -{ - if (!remoteDebugInitialized) { - remoteDebugInitialized = 1; - /* - debugInit(UART16550_BAUD_115200, - UART16550_DATA_8BIT, - UART16550_PARITY_NONE, UART16550_STOP_1BIT); */ - } - - while ((UART16550_READ(OFS_LINE_STATUS) & 0x20) == 0) ; - UART16550_WRITE(OFS_SEND_BUFFER, byte); - return 1; -} diff -Nur linux-2.6.30.5.orig/arch/mips/lemote/lm2e/irq.c linux-2.6.30.5/arch/mips/lemote/lm2e/irq.c --- linux-2.6.30.5.orig/arch/mips/lemote/lm2e/irq.c 2009-08-16 23:19:38.000000000 +0200 +++ linux-2.6.30.5/arch/mips/lemote/lm2e/irq.c 1970-01-01 01:00:00.000000000 +0100 @@ -1,143 +0,0 @@ -/* - * Copyright (C) 2007 Lemote Inc. & Insititute of Computing Technology - * Author: Fuxin Zhang, zhangfx@lemote.com - * - * 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 SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN - * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF - * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON - * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * 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., - * 675 Mass Ave, Cambridge, MA 02139, USA. - * - */ -#include -#include -#include -#include -#include - -#include -#include -#include -#include - - -/* - * the first level int-handler will jump here if it is a bonito irq - */ -static void bonito_irqdispatch(void) -{ - u32 int_status; - int i; - - /* workaround the IO dma problem: let cpu looping to allow DMA finish */ - int_status = BONITO_INTISR; - if (int_status & (1 << 10)) { - while (int_status & (1 << 10)) { - udelay(1); - int_status = BONITO_INTISR; - } - } - - /* Get pending sources, masked by current enables */ - int_status = BONITO_INTISR & BONITO_INTEN; - - if (int_status != 0) { - i = __ffs(int_status); - int_status &= ~(1 << i); - do_IRQ(BONITO_IRQ_BASE + i); - } -} - -static void i8259_irqdispatch(void) -{ - int irq; - - irq = i8259_irq(); - if (irq >= 0) { - do_IRQ(irq); - } else { - spurious_interrupt(); - } - -} - -asmlinkage void plat_irq_dispatch(void) -{ - unsigned int pending = read_c0_cause() & read_c0_status() & ST0_IM; - - if (pending & CAUSEF_IP7) { - do_IRQ(MIPS_CPU_IRQ_BASE + 7); - } else if (pending & CAUSEF_IP5) { - i8259_irqdispatch(); - } else if (pending & CAUSEF_IP2) { - bonito_irqdispatch(); - } else { - spurious_interrupt(); - } -} - -static struct irqaction cascade_irqaction = { - .handler = no_action, - .name = "cascade", -}; - -void __init arch_init_irq(void) -{ - extern void bonito_irq_init(void); - - /* - * Clear all of the interrupts while we change the able around a bit. - * int-handler is not on bootstrap - */ - clear_c0_status(ST0_IM | ST0_BEV); - local_irq_disable(); - - /* most bonito irq should be level triggered */ - BONITO_INTEDGE = BONITO_ICU_SYSTEMERR | BONITO_ICU_MASTERERR | - BONITO_ICU_RETRYERR | BONITO_ICU_MBOXES; - BONITO_INTSTEER = 0; - - /* - * Mask out all interrupt by writing "1" to all bit position in - * the interrupt reset reg. - */ - BONITO_INTENCLR = ~0; - - /* init all controller - * 0-15 ------> i8259 interrupt - * 16-23 ------> mips cpu interrupt - * 32-63 ------> bonito irq - */ - - /* Sets the first-level interrupt dispatcher. */ - mips_cpu_irq_init(); - init_i8259_irqs(); - bonito_irq_init(); - - /* - printk("GPIODATA=%x, GPIOIE=%x\n", BONITO_GPIODATA, BONITO_GPIOIE); - printk("INTEN=%x, INTSET=%x, INTCLR=%x, INTISR=%x\n", - BONITO_INTEN, BONITO_INTENSET, - BONITO_INTENCLR, BONITO_INTISR); - */ - - /* bonito irq at IP2 */ - setup_irq(MIPS_CPU_IRQ_BASE + 2, &cascade_irqaction); - /* 8259 irq at IP5 */ - setup_irq(MIPS_CPU_IRQ_BASE + 5, &cascade_irqaction); - -} diff -Nur linux-2.6.30.5.orig/arch/mips/lemote/lm2e/Makefile linux-2.6.30.5/arch/mips/lemote/lm2e/Makefile --- linux-2.6.30.5.orig/arch/mips/lemote/lm2e/Makefile 2009-08-16 23:19:38.000000000 +0200 +++ linux-2.6.30.5/arch/mips/lemote/lm2e/Makefile 1970-01-01 01:00:00.000000000 +0100 @@ -1,7 +0,0 @@ -# -# Makefile for Lemote Fulong mini-PC board. -# - -obj-y += setup.o prom.o reset.o irq.o pci.o bonito-irq.o dbg_io.o mem.o - -EXTRA_CFLAGS += -Werror diff -Nur linux-2.6.30.5.orig/arch/mips/lemote/lm2e/mem.c linux-2.6.30.5/arch/mips/lemote/lm2e/mem.c --- linux-2.6.30.5.orig/arch/mips/lemote/lm2e/mem.c 2009-08-16 23:19:38.000000000 +0200 +++ linux-2.6.30.5/arch/mips/lemote/lm2e/mem.c 1970-01-01 01:00:00.000000000 +0100 @@ -1,23 +0,0 @@ -/* - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - */ -#include -#include -#include - -/* override of arch/mips/mm/cache.c: __uncached_access */ -int __uncached_access(struct file *file, unsigned long addr) -{ - if (file->f_flags & O_SYNC) - return 1; - - /* - * On the Lemote Loongson 2e system, the peripheral registers - * reside between 0x1000:0000 and 0x2000:0000. - */ - return addr >= __pa(high_memory) || - ((addr >= 0x10000000) && (addr < 0x20000000)); -} diff -Nur linux-2.6.30.5.orig/arch/mips/lemote/lm2e/pci.c linux-2.6.30.5/arch/mips/lemote/lm2e/pci.c --- linux-2.6.30.5.orig/arch/mips/lemote/lm2e/pci.c 2009-08-16 23:19:38.000000000 +0200 +++ linux-2.6.30.5/arch/mips/lemote/lm2e/pci.c 1970-01-01 01:00:00.000000000 +0100 @@ -1,97 +0,0 @@ -/* - * pci.c - * - * Copyright (C) 2007 Lemote, Inc. & Institute of Computing Technology - * Author: Fuxin Zhang, zhangfx@lemote.com - * - * 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 SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN - * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF - * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON - * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * 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., - * 675 Mass Ave, Cambridge, MA 02139, USA. - * - */ -#include -#include -#include -#include -#include -#include - -extern struct pci_ops bonito64_pci_ops; - -static struct resource loongson2e_pci_mem_resource = { - .name = "LOONGSON2E PCI MEM", - .start = LOONGSON2E_PCI_MEM_START, - .end = LOONGSON2E_PCI_MEM_END, - .flags = IORESOURCE_MEM, -}; - -static struct resource loongson2e_pci_io_resource = { - .name = "LOONGSON2E PCI IO MEM", - .start = LOONGSON2E_PCI_IO_START, - .end = IO_SPACE_LIMIT, - .flags = IORESOURCE_IO, -}; - -static struct pci_controller loongson2e_pci_controller = { - .pci_ops = &bonito64_pci_ops, - .io_resource = &loongson2e_pci_io_resource, - .mem_resource = &loongson2e_pci_mem_resource, - .mem_offset = 0x00000000UL, - .io_offset = 0x00000000UL, -}; - -static void __init ict_pcimap(void) -{ - /* - * local to PCI mapping: [256M,512M] -> [256M,512M]; differ from PMON - * - * CPU address space [256M,448M] is window for accessing pci space - * we set pcimap_lo[0,1,2] to map it to pci space [256M,448M] - * pcimap: bit18,pcimap_2; bit[17-12],lo2;bit[11-6],lo1;bit[5-0],lo0 - */ - /* 1,00 0110 ,0001 01,00 0000 */ - BONITO_PCIMAP = 0x46140; - - /* 1, 00 0010, 0000,01, 00 0000 */ - /* BONITO_PCIMAP = 0x42040; */ - - /* - * PCI to local mapping: [2G,2G+256M] -> [0,256M] - */ - BONITO_PCIBASE0 = 0x80000000; - BONITO_PCIBASE1 = 0x00800000; - BONITO_PCIBASE2 = 0x90000000; - -} - -static int __init pcibios_init(void) -{ - ict_pcimap(); - - loongson2e_pci_controller.io_map_base = - (unsigned long) ioremap(LOONGSON2E_IO_PORT_BASE, - loongson2e_pci_io_resource.end - - loongson2e_pci_io_resource.start + 1); - - register_pci_controller(&loongson2e_pci_controller); - - return 0; -} - -arch_initcall(pcibios_init); diff -Nur linux-2.6.30.5.orig/arch/mips/lemote/lm2e/prom.c linux-2.6.30.5/arch/mips/lemote/lm2e/prom.c --- linux-2.6.30.5.orig/arch/mips/lemote/lm2e/prom.c 2009-08-16 23:19:38.000000000 +0200 +++ linux-2.6.30.5/arch/mips/lemote/lm2e/prom.c 1970-01-01 01:00:00.000000000 +0100 @@ -1,97 +0,0 @@ -/* - * Based on Ocelot Linux port, which is - * Copyright 2001 MontaVista Software Inc. - * Author: jsun@mvista.com or jsun@junsun.net - * - * Copyright 2003 ICT CAS - * Author: Michael Guo - * - * Copyright (C) 2007 Lemote Inc. & Insititute of Computing Technology - * Author: Fuxin Zhang, zhangfx@lemote.com - * - * 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. - */ -#include -#include -#include - -extern unsigned long bus_clock; -extern unsigned long cpu_clock_freq; -extern unsigned int memsize, highmemsize; -extern int putDebugChar(unsigned char byte); - -static int argc; -/* pmon passes arguments in 32bit pointers */ -static int *arg; -static int *env; - -const char *get_system_type(void) -{ - return "lemote-fulong"; -} - -void __init prom_init_cmdline(void) -{ - int i; - long l; - - /* arg[0] is "g", the rest is boot parameters */ - arcs_cmdline[0] = '\0'; - for (i = 1; i < argc; i++) { - l = (long)arg[i]; - if (strlen(arcs_cmdline) + strlen(((char *)l) + 1) - >= sizeof(arcs_cmdline)) - break; - strcat(arcs_cmdline, ((char *)l)); - strcat(arcs_cmdline, " "); - } -} - -void __init prom_init(void) -{ - long l; - argc = fw_arg0; - arg = (int *)fw_arg1; - env = (int *)fw_arg2; - - prom_init_cmdline(); - - if ((strstr(arcs_cmdline, "console=")) == NULL) - strcat(arcs_cmdline, " console=ttyS0,115200"); - if ((strstr(arcs_cmdline, "root=")) == NULL) - strcat(arcs_cmdline, " root=/dev/hda1"); - -#define parse_even_earlier(res, option, p) \ -do { \ - if (strncmp(option, (char *)p, strlen(option)) == 0) \ - res = simple_strtol((char *)p + strlen(option"="), \ - NULL, 10); \ -} while (0) - - l = (long)*env; - while (l != 0) { - parse_even_earlier(bus_clock, "busclock", l); - parse_even_earlier(cpu_clock_freq, "cpuclock", l); - parse_even_earlier(memsize, "memsize", l); - parse_even_earlier(highmemsize, "highmemsize", l); - env++; - l = (long)*env; - } - if (memsize == 0) - memsize = 256; - - pr_info("busclock=%ld, cpuclock=%ld,memsize=%d,highmemsize=%d\n", - bus_clock, cpu_clock_freq, memsize, highmemsize); -} - -void __init prom_free_prom_memory(void) -{ -} - -void prom_putchar(char c) -{ - putDebugChar(c); -} diff -Nur linux-2.6.30.5.orig/arch/mips/lemote/lm2e/reset.c linux-2.6.30.5/arch/mips/lemote/lm2e/reset.c --- linux-2.6.30.5.orig/arch/mips/lemote/lm2e/reset.c 2009-08-16 23:19:38.000000000 +0200 +++ linux-2.6.30.5/arch/mips/lemote/lm2e/reset.c 1970-01-01 01:00:00.000000000 +0100 @@ -1,41 +0,0 @@ -/* - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - * - * Copyright (C) 2007 Lemote, Inc. & Institute of Computing Technology - * Author: Fuxin Zhang, zhangfx@lemote.com - */ -#include - -#include - -static void loongson2e_restart(char *command) -{ -#ifdef CONFIG_32BIT - *(unsigned long *)0xbfe00104 &= ~(1 << 2); - *(unsigned long *)0xbfe00104 |= (1 << 2); -#else - *(unsigned long *)0xffffffffbfe00104 &= ~(1 << 2); - *(unsigned long *)0xffffffffbfe00104 |= (1 << 2); -#endif - __asm__ __volatile__("jr\t%0"::"r"(0xbfc00000)); -} - -static void loongson2e_halt(void) -{ - while (1) ; -} - -static void loongson2e_power_off(void) -{ - loongson2e_halt(); -} - -void mips_reboot_setup(void) -{ - _machine_restart = loongson2e_restart; - _machine_halt = loongson2e_halt; - pm_power_off = loongson2e_power_off; -} diff -Nur linux-2.6.30.5.orig/arch/mips/lemote/lm2e/setup.c linux-2.6.30.5/arch/mips/lemote/lm2e/setup.c --- linux-2.6.30.5.orig/arch/mips/lemote/lm2e/setup.c 2009-08-16 23:19:38.000000000 +0200 +++ linux-2.6.30.5/arch/mips/lemote/lm2e/setup.c 1970-01-01 01:00:00.000000000 +0100 @@ -1,111 +0,0 @@ -/* - * BRIEF MODULE DESCRIPTION - * setup.c - board dependent boot routines - * - * Copyright (C) 2007 Lemote Inc. & Insititute of Computing Technology - * Author: Fuxin Zhang, zhangfx@lemote.com - * - * 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 SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN - * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF - * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON - * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * 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., - * 675 Mass Ave, Cambridge, MA 02139, USA. - * - */ -#include -#include -#include - -#include -#include -#include -#include -#include - -#ifdef CONFIG_VT -#include -#include -#endif - -extern void mips_reboot_setup(void); - -unsigned long cpu_clock_freq; -unsigned long bus_clock; -unsigned int memsize; -unsigned int highmemsize = 0; - -void __init plat_time_init(void) -{ - /* setup mips r4k timer */ - mips_hpt_frequency = cpu_clock_freq / 2; -} - -unsigned long read_persistent_clock(void) -{ - return mc146818_get_cmos_time(); -} - -void (*__wbflush)(void); -EXPORT_SYMBOL(__wbflush); - -static void wbflush_loongson2e(void) -{ - asm(".set\tpush\n\t" - ".set\tnoreorder\n\t" - ".set mips3\n\t" - "sync\n\t" - "nop\n\t" - ".set\tpop\n\t" - ".set mips0\n\t"); -} - -void __init plat_mem_setup(void) -{ - set_io_port_base((unsigned long)ioremap(LOONGSON2E_IO_PORT_BASE, - IO_SPACE_LIMIT - LOONGSON2E_PCI_IO_START + 1)); - mips_reboot_setup(); - - __wbflush = wbflush_loongson2e; - - add_memory_region(0x0, (memsize << 20), BOOT_MEM_RAM); -#ifdef CONFIG_64BIT - if (highmemsize > 0) { - add_memory_region(0x20000000, highmemsize << 20, BOOT_MEM_RAM); - } -#endif - -#ifdef CONFIG_VT -#if defined(CONFIG_VGA_CONSOLE) - conswitchp = &vga_con; - - screen_info = (struct screen_info) { - 0, 25, /* orig-x, orig-y */ - 0, /* unused */ - 0, /* orig-video-page */ - 0, /* orig-video-mode */ - 80, /* orig-video-cols */ - 0, 0, 0, /* ega_ax, ega_bx, ega_cx */ - 25, /* orig-video-lines */ - VIDEO_TYPE_VGAC, /* orig-video-isVGA */ - 16 /* orig-video-points */ - }; -#elif defined(CONFIG_DUMMY_CONSOLE) - conswitchp = &dummy_con; -#endif -#endif - -} diff -Nur linux-2.6.30.5.orig/arch/mips/loongson/common/bonito-irq.c linux-2.6.30.5/arch/mips/loongson/common/bonito-irq.c --- linux-2.6.30.5.orig/arch/mips/loongson/common/bonito-irq.c 1970-01-01 01:00:00.000000000 +0100 +++ linux-2.6.30.5/arch/mips/loongson/common/bonito-irq.c 2009-08-23 19:01:04.000000000 +0200 @@ -0,0 +1,78 @@ +/* + * Copyright 2001 MontaVista Software Inc. + * Author: Jun Sun, jsun@mvista.com or jsun@junsun.net + * Copyright (C) 2000, 2001 Ralf Baechle (ralf@gnu.org) + * + * Copyright (C) 2007 Lemote Inc. & Insititute of Computing Technology + * Author: Fuxin Zhang, zhangfx@lemote.com + * + * 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 SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN + * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * 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., + * 675 Mass Ave, Cambridge, MA 02139, USA. + * + */ + +#include + +#include +#include + +static inline void bonito_irq_enable(unsigned int irq) +{ + LOONGSON_INTENSET = (1 << (irq - LOONGSON_IRQ_BASE)); + /* flush posted write */ + (void)LOONGSON_INTENSET; + mmiowb(); +} + +static inline void bonito_irq_disable(unsigned int irq) +{ + LOONGSON_INTENCLR = (1 << (irq - LOONGSON_IRQ_BASE)); + /* flush posted write */ + (void)LOONGSON_INTENCLR; + mmiowb(); +} + +static struct irq_chip bonito_irq_type = { + .name = "bonito_irq", + .ack = bonito_irq_disable, + .mask = bonito_irq_disable, + .mask_ack = bonito_irq_disable, + .unmask = bonito_irq_enable, +}; + +/* there is no need to handle dma timeout in loongson-2f based machines */ +#ifdef CONFIG_CPU_LOONGSON2E +static struct irqaction dma_timeout_irqaction = { + .handler = no_action, + .name = "dma_timeout", +}; +#endif + +void bonito_irq_init(void) +{ + u32 i; + + for (i = LOONGSON_IRQ_BASE; i < LOONGSON_IRQ_BASE + 32; i++) + set_irq_chip_and_handler(i, &bonito_irq_type, handle_level_irq); + +#ifdef CONFIG_CPU_LOONGSON2E + setup_irq(LOONGSON_DMATIMEOUT_IRQ, &dma_timeout_irqaction); +#endif +} diff -Nur linux-2.6.30.5.orig/arch/mips/loongson/common/clock.c linux-2.6.30.5/arch/mips/loongson/common/clock.c --- linux-2.6.30.5.orig/arch/mips/loongson/common/clock.c 1970-01-01 01:00:00.000000000 +0100 +++ linux-2.6.30.5/arch/mips/loongson/common/clock.c 2009-08-23 19:01:04.000000000 +0200 @@ -0,0 +1,166 @@ +/* + * arch/mips/loongson/common/clock.c + * + * Copyright (C) 2006 - 2008 Lemote Inc. & Insititute of Computing Technology + * Author: Yanhua, yanh@lemote.com + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + */ + +#include +#include + +#include +#include + +static LIST_HEAD(clock_list); +static DEFINE_SPINLOCK(clock_lock); +static DEFINE_MUTEX(clock_list_sem); + +/* Minimum CLK support */ +enum { + DC_ZERO, DC_25PT = 2, DC_37PT, DC_50PT, DC_62PT, DC_75PT, + DC_87PT, DC_DISABLE, DC_RESV +}; + +struct cpufreq_frequency_table loongson2f_clockmod_table[] = { + {DC_RESV, CPUFREQ_ENTRY_INVALID}, + {DC_ZERO, CPUFREQ_ENTRY_INVALID}, + {DC_25PT, 0}, + {DC_37PT, 0}, + {DC_50PT, 0}, + {DC_62PT, 0}, + {DC_75PT, 0}, + {DC_87PT, 0}, + {DC_DISABLE, 0}, + {DC_RESV, CPUFREQ_TABLE_END}, +}; +EXPORT_SYMBOL_GPL(loongson2f_clockmod_table); + +static struct clk cpu_clk = { + .name = "cpu_clk", + .flags = CLK_ALWAYS_ENABLED | CLK_RATE_PROPAGATES, + .rate = 800000000, +}; + +struct clk *clk_get(struct device *dev, const char *id) +{ + return &cpu_clk; +} +EXPORT_SYMBOL(clk_get); + +static void propagate_rate(struct clk *clk) +{ + struct clk *clkp; + + list_for_each_entry(clkp, &clock_list, node) { + if (likely(clkp->parent != clk)) + continue; + if (likely(clkp->ops && clkp->ops->recalc)) + clkp->ops->recalc(clkp); + if (unlikely(clkp->flags & CLK_RATE_PROPAGATES)) + propagate_rate(clkp); + } +} + +int clk_enable(struct clk *clk) +{ + return 0; +} +EXPORT_SYMBOL(clk_enable); + +void clk_disable(struct clk *clk) +{ +} +EXPORT_SYMBOL(clk_disable); + +unsigned long clk_get_rate(struct clk *clk) +{ + return (unsigned long)clk->rate; +} +EXPORT_SYMBOL(clk_get_rate); + +void clk_put(struct clk *clk) +{ +} +EXPORT_SYMBOL(clk_put); + +int clk_set_rate(struct clk *clk, unsigned long rate) +{ + return clk_set_rate_ex(clk, rate, 0); +} +EXPORT_SYMBOL_GPL(clk_set_rate); + +int clk_set_rate_ex(struct clk *clk, unsigned long rate, int algo_id) +{ + int ret = 0; + int regval; + int i; + + if (likely(clk->ops && clk->ops->set_rate)) { + unsigned long flags; + + spin_lock_irqsave(&clock_lock, flags); + ret = clk->ops->set_rate(clk, rate, algo_id); + spin_unlock_irqrestore(&clock_lock, flags); + } + + if (unlikely(clk->flags & CLK_RATE_PROPAGATES)) + propagate_rate(clk); + + for (i = 0; loongson2f_clockmod_table[i].frequency != CPUFREQ_TABLE_END; + i++) { + if (loongson2f_clockmod_table[i].frequency == + CPUFREQ_ENTRY_INVALID) + continue; + if (rate == loongson2f_clockmod_table[i].frequency) + break; + } + if (rate != loongson2f_clockmod_table[i].frequency) + return -ENOTSUPP; + + clk->rate = rate; + + regval = LOONGSON_CHIPCFG0; + regval = (regval & ~0x7) | (loongson2f_clockmod_table[i].index - 1); + LOONGSON_CHIPCFG0 = regval; + + return ret; +} +EXPORT_SYMBOL_GPL(clk_set_rate_ex); + +long clk_round_rate(struct clk *clk, unsigned long rate) +{ + if (likely(clk->ops && clk->ops->round_rate)) { + unsigned long flags, rounded; + + spin_lock_irqsave(&clock_lock, flags); + rounded = clk->ops->round_rate(clk, rate); + spin_unlock_irqrestore(&clock_lock, flags); + + return rounded; + } + + return rate; +} +EXPORT_SYMBOL_GPL(clk_round_rate); + +/* + * This is the simple version of Loongson-2F wait + * Maybe we need do this in interrupt disabled content + */ +DEFINE_SPINLOCK(loongson2f_wait_lock); +void loongson2f_cpu_wait(void) +{ + u32 cpu_freq; + unsigned long flags; + + spin_lock_irqsave(&loongson2f_wait_lock, flags); + cpu_freq = LOONGSON_CHIPCFG0; + LOONGSON_CHIPCFG0 &= ~0x7; /* Put CPU into wait mode */ + LOONGSON_CHIPCFG0 = cpu_freq; /* Restore CPU state */ + spin_unlock_irqrestore(&loongson2f_wait_lock, flags); +} +EXPORT_SYMBOL_GPL(loongson2f_cpu_wait); diff -Nur linux-2.6.30.5.orig/arch/mips/loongson/common/cmdline.c linux-2.6.30.5/arch/mips/loongson/common/cmdline.c --- linux-2.6.30.5.orig/arch/mips/loongson/common/cmdline.c 1970-01-01 01:00:00.000000000 +0100 +++ linux-2.6.30.5/arch/mips/loongson/common/cmdline.c 2009-08-23 19:01:04.000000000 +0200 @@ -0,0 +1,57 @@ +/* + * Based on Ocelot Linux port, which is + * Copyright 2001 MontaVista Software Inc. + * Author: jsun@mvista.com or jsun@junsun.net + * + * Copyright 2003 ICT CAS + * Author: Michael Guo + * + * Copyright (C) 2007 Lemote Inc. & Insititute of Computing Technology + * Author: Fuxin Zhang, zhangfx@lemote.com + * + * Copyright (C) 2009 Lemote Inc. & Insititute of Computing Technology + * Author: Wu Zhangjin, wuzj@lemote.com + * + * 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. + */ + +#include + +#include +#include + +int prom_argc; +/* pmon passes arguments in 32bit pointers */ +int *_prom_argv; + +void __init prom_init_cmdline(void) +{ + int i; + long l; + + /* firmware arguments are initialized in head.S */ + prom_argc = fw_arg0; + _prom_argv = (int *)fw_arg1; + + /* arg[0] is "g", the rest is boot parameters */ + arcs_cmdline[0] = '\0'; + for (i = 1; i < prom_argc; i++) { + l = (long)_prom_argv[i]; + if (strlen(arcs_cmdline) + strlen(((char *)l) + 1) + >= sizeof(arcs_cmdline)) + break; + strcat(arcs_cmdline, ((char *)l)); + strcat(arcs_cmdline, " "); + } + + /* machine specific prom_init_cmdline */ + mach_prom_init_cmdline(); + + if ((strstr(arcs_cmdline, "console=")) == NULL) + strcat(arcs_cmdline, " console=tty"); + if ((strstr(arcs_cmdline, "root=")) == NULL) + strcat(arcs_cmdline, " root=/dev/sda1"); +} diff -Nur linux-2.6.30.5.orig/arch/mips/loongson/common/cs5536/cs5536_acc.c linux-2.6.30.5/arch/mips/loongson/common/cs5536/cs5536_acc.c --- linux-2.6.30.5.orig/arch/mips/loongson/common/cs5536/cs5536_acc.c 1970-01-01 01:00:00.000000000 +0100 +++ linux-2.6.30.5/arch/mips/loongson/common/cs5536/cs5536_acc.c 2009-08-23 19:01:04.000000000 +0200 @@ -0,0 +1,156 @@ +/* + * the ACC Virtual Support Module of AMD CS5536 + * + * Copyright (C) 2007 Lemote, Inc. & Institute of Computing Technology + * Author : jlliu, liujl@lemote.com + * + * Copyright (C) 2009 Lemote, Inc. & Institute of Computing Technology + * Author: Wu Zhangjin, wuzj@lemote.com + * + * 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. + */ + +#include +#include + +/* + * acc_write: acc write transfering + */ + +void pci_acc_write_reg(int reg, u32 value) +{ + u32 hi = 0, lo = value; + + switch (reg) { + case PCI_COMMAND: + _rdmsr(GLIU_MSR_REG(GLIU_PAE), &hi, &lo); + if (value & PCI_COMMAND_MASTER) + lo |= (0x03 << 8); + else + lo &= ~(0x03 << 8); + _wrmsr(GLIU_MSR_REG(GLIU_PAE), hi, lo); + break; + case PCI_STATUS: + if (value & PCI_STATUS_PARITY) { + _rdmsr(SB_MSR_REG(SB_ERROR), &hi, &lo); + if (lo & SB_PARE_ERR_FLAG) { + lo = (lo & 0x0000ffff) | SB_PARE_ERR_FLAG; + _wrmsr(SB_MSR_REG(SB_ERROR), hi, lo); + } + } + break; + case PCI_BAR0_REG: + if (value == PCI_BAR_RANGE_MASK) { + _rdmsr(GLCP_MSR_REG(GLCP_SOFT_COM), &hi, &lo); + lo |= SOFT_BAR_ACC_FLAG; + _wrmsr(GLCP_MSR_REG(GLCP_SOFT_COM), hi, lo); + } else if (value & 0x01) { + value &= 0xfffffffc; + hi = 0xA0000000 | ((value & 0x000ff000) >> 12); + lo = 0x000fff80 | ((value & 0x00000fff) << 20); + _wrmsr(GLIU_MSR_REG(GLIU_IOD_BM1), hi, lo); + } + break; + case PCI_ACC_INT_REG: + _rdmsr(DIVIL_MSR_REG(PIC_YSEL_LOW), &hi, &lo); + /* disable all the usb interrupt in PIC */ + lo &= ~(0xf << PIC_YSEL_LOW_ACC_SHIFT); + if (value) /* enable all the acc interrupt in PIC */ + lo |= (CS5536_ACC_INTR << PIC_YSEL_LOW_ACC_SHIFT); + _wrmsr(DIVIL_MSR_REG(PIC_YSEL_LOW), hi, lo); + break; + default: + break; + } + + return; +} + +/* + * acc_read: acc read transfering + */ + +u32 pci_acc_read_reg(int reg) +{ + u32 hi, lo; + u32 conf_data = 0; + + switch (reg) { + case PCI_VENDOR_ID: + conf_data = + CFG_PCI_VENDOR_ID(CS5536_ACC_DEVICE_ID, CS5536_VENDOR_ID); + break; + case PCI_COMMAND: + _rdmsr(GLIU_MSR_REG(GLIU_IOD_BM1), &hi, &lo); + if (((lo & 0xfff00000) || (hi & 0x000000ff)) + && ((hi & 0xf0000000) == 0xa0000000)) + conf_data |= PCI_COMMAND_IO; + _rdmsr(GLIU_MSR_REG(GLIU_PAE), &hi, &lo); + if ((lo & 0x300) == 0x300) + conf_data |= PCI_COMMAND_MASTER; + break; + case PCI_STATUS: + conf_data |= PCI_STATUS_66MHZ; + conf_data |= PCI_STATUS_FAST_BACK; + _rdmsr(SB_MSR_REG(SB_ERROR), &hi, &lo); + if (lo & SB_PARE_ERR_FLAG) + conf_data |= PCI_STATUS_PARITY; + conf_data |= PCI_STATUS_DEVSEL_MEDIUM; + break; + case PCI_CLASS_REVISION: + _rdmsr(ACC_MSR_REG(ACC_CAP), &hi, &lo); + conf_data = lo & 0x000000ff; + conf_data |= (CS5536_ACC_CLASS_CODE << 8); + break; + case PCI_CACHE_LINE_SIZE: + conf_data = + CFG_PCI_CACHE_LINE_SIZE(PCI_NORMAL_HEADER_TYPE, + PCI_NORMAL_LATENCY_TIMER); + break; + case PCI_BAR0_REG: + _rdmsr(GLCP_MSR_REG(GLCP_SOFT_COM), &hi, &lo); + if (lo & SOFT_BAR_ACC_FLAG) { + conf_data = CS5536_ACC_RANGE | + PCI_BASE_ADDRESS_SPACE_IO; + lo &= ~SOFT_BAR_ACC_FLAG; + _wrmsr(GLCP_MSR_REG(GLCP_SOFT_COM), hi, lo); + } else { + _rdmsr(GLIU_MSR_REG(GLIU_IOD_BM1), &hi, &lo); + conf_data = (hi & 0x000000ff) << 12; + conf_data |= (lo & 0xfff00000) >> 20; + conf_data |= 0x01; + conf_data &= ~0x02; + } + break; + case PCI_BAR1_REG: + case PCI_BAR2_REG: + case PCI_BAR3_REG: + case PCI_BAR4_REG: + case PCI_BAR5_REG: + break; + case PCI_CARDBUS_CIS: + conf_data = PCI_CARDBUS_CIS_POINTER; + break; + case PCI_SUBSYSTEM_VENDOR_ID: + conf_data = + CFG_PCI_VENDOR_ID(CS5536_ACC_SUB_ID, CS5536_SUB_VENDOR_ID); + break; + case PCI_ROM_ADDRESS: + conf_data = PCI_EXPANSION_ROM_BAR; + break; + case PCI_CAPABILITY_LIST: + conf_data = PCI_CAPLIST_USB_POINTER; + break; + case PCI_INTERRUPT_LINE: + conf_data = + CFG_PCI_INTERRUPT_LINE(PCI_DEFAULT_PIN, CS5536_ACC_INTR); + break; + default: + break; + } + + return conf_data; +} diff -Nur linux-2.6.30.5.orig/arch/mips/loongson/common/cs5536/cs5536_ehci.c linux-2.6.30.5/arch/mips/loongson/common/cs5536/cs5536_ehci.c --- linux-2.6.30.5.orig/arch/mips/loongson/common/cs5536/cs5536_ehci.c 1970-01-01 01:00:00.000000000 +0100 +++ linux-2.6.30.5/arch/mips/loongson/common/cs5536/cs5536_ehci.c 2009-08-23 19:01:04.000000000 +0200 @@ -0,0 +1,166 @@ +/* + * the EHCI Virtual Support Module of AMD CS5536 + * + * Copyright (C) 2007 Lemote, Inc. & Institute of Computing Technology + * Author : jlliu, liujl@lemote.com + * + * Copyright (C) 2009 Lemote, Inc. & Institute of Computing Technology + * Author: Wu Zhangjin, wuzj@lemote.com + * + * 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. + */ + +#include +#include + +void pci_ehci_write_reg(int reg, u32 value) +{ + u32 hi = 0, lo = value; + + switch (reg) { + case PCI_COMMAND: + _rdmsr(USB_MSR_REG(USB_EHCI), &hi, &lo); + if (value & PCI_COMMAND_MASTER) + hi |= PCI_COMMAND_MASTER; + else + hi &= ~PCI_COMMAND_MASTER; + + if (value & PCI_COMMAND_MEMORY) + hi |= PCI_COMMAND_MEMORY; + else + hi &= ~PCI_COMMAND_MEMORY; + _wrmsr(USB_MSR_REG(USB_EHCI), hi, lo); + break; + case PCI_STATUS: + if (value & PCI_STATUS_PARITY) { + _rdmsr(SB_MSR_REG(SB_ERROR), &hi, &lo); + if (lo & SB_PARE_ERR_FLAG) { + lo = (lo & 0x0000ffff) | SB_PARE_ERR_FLAG; + _wrmsr(SB_MSR_REG(SB_ERROR), hi, lo); + } + } + break; + case PCI_BAR0_REG: + if (value == PCI_BAR_RANGE_MASK) { + _rdmsr(GLCP_MSR_REG(GLCP_SOFT_COM), &hi, &lo); + lo |= SOFT_BAR_EHCI_FLAG; + _wrmsr(GLCP_MSR_REG(GLCP_SOFT_COM), hi, lo); + } else if ((value & 0x01) == 0x00) { + _wrmsr(USB_MSR_REG(USB_EHCI), hi, lo); + + value &= 0xfffffff0; + hi = 0x40000000 | ((value & 0xff000000) >> 24); + lo = 0x000fffff | ((value & 0x00fff000) << 8); + _wrmsr(GLIU_MSR_REG(GLIU_P2D_BM4), hi, lo); + } + break; + case PCI_EHCI_LEGSMIEN_REG: + _rdmsr(USB_MSR_REG(USB_EHCI), &hi, &lo); + hi &= 0x003f0000; + hi |= (value & 0x3f) << 16; + _wrmsr(USB_MSR_REG(USB_EHCI), hi, lo); + break; + case PCI_EHCI_FLADJ_REG: + _rdmsr(USB_MSR_REG(USB_EHCI), &hi, &lo); + hi &= ~0x00003f00; + hi |= value & 0x00003f00; + _wrmsr(USB_MSR_REG(USB_EHCI), hi, lo); + break; + default: + break; + } + + return; +} + +u32 pci_ehci_read_reg(int reg) +{ + u32 conf_data = 0; + u32 hi, lo; + + switch (reg) { + case PCI_VENDOR_ID: + conf_data = + CFG_PCI_VENDOR_ID(CS5536_EHCI_DEVICE_ID, CS5536_VENDOR_ID); + break; + case PCI_COMMAND: + _rdmsr(USB_MSR_REG(USB_EHCI), &hi, &lo); + if (hi & PCI_COMMAND_MASTER) + conf_data |= PCI_COMMAND_MASTER; + if (hi & PCI_COMMAND_MEMORY) + conf_data |= PCI_COMMAND_MEMORY; + break; + case PCI_STATUS: + conf_data |= PCI_STATUS_66MHZ; + conf_data |= PCI_STATUS_FAST_BACK; + _rdmsr(SB_MSR_REG(SB_ERROR), &hi, &lo); + if (lo & SB_PARE_ERR_FLAG) + conf_data |= PCI_STATUS_PARITY; + conf_data |= PCI_STATUS_DEVSEL_MEDIUM; + break; + case PCI_CLASS_REVISION: + _rdmsr(USB_MSR_REG(USB_CAP), &hi, &lo); + conf_data = lo & 0x000000ff; + conf_data |= (CS5536_EHCI_CLASS_CODE << 8); + break; + case PCI_CACHE_LINE_SIZE: + conf_data = + CFG_PCI_CACHE_LINE_SIZE(PCI_NORMAL_HEADER_TYPE, + PCI_NORMAL_LATENCY_TIMER); + break; + case PCI_BAR0_REG: + _rdmsr(GLCP_MSR_REG(GLCP_SOFT_COM), &hi, &lo); + if (lo & SOFT_BAR_EHCI_FLAG) { + conf_data = CS5536_EHCI_RANGE | + PCI_BASE_ADDRESS_SPACE_MEMORY; + lo &= ~SOFT_BAR_EHCI_FLAG; + _wrmsr(GLCP_MSR_REG(GLCP_SOFT_COM), hi, lo); + } else { + _rdmsr(USB_MSR_REG(USB_EHCI), &hi, &lo); + conf_data = lo & 0xfffff000; + } + break; + case PCI_BAR1_REG: + case PCI_BAR2_REG: + case PCI_BAR3_REG: + case PCI_BAR4_REG: + case PCI_BAR5_REG: + break; + case PCI_CARDBUS_CIS: + conf_data = PCI_CARDBUS_CIS_POINTER; + break; + case PCI_SUBSYSTEM_VENDOR_ID: + conf_data = + CFG_PCI_VENDOR_ID(CS5536_EHCI_SUB_ID, CS5536_SUB_VENDOR_ID); + break; + case PCI_ROM_ADDRESS: + conf_data = PCI_EXPANSION_ROM_BAR; + break; + case PCI_CAPABILITY_LIST: + conf_data = PCI_CAPLIST_USB_POINTER; + break; + case PCI_INTERRUPT_LINE: + conf_data = + CFG_PCI_INTERRUPT_LINE(PCI_DEFAULT_PIN, CS5536_USB_INTR); + break; + case PCI_EHCI_LEGSMIEN_REG: + _rdmsr(USB_MSR_REG(USB_EHCI), &hi, &lo); + conf_data = (hi & 0x003f0000) >> 16; + break; + case PCI_EHCI_LEGSMISTS_REG: + _rdmsr(USB_MSR_REG(USB_EHCI), &hi, &lo); + conf_data = (hi & 0x3f000000) >> 24; + break; + case PCI_EHCI_FLADJ_REG: + _rdmsr(USB_MSR_REG(USB_EHCI), &hi, &lo); + conf_data = hi & 0x00003f00; + break; + default: + break; + } + + return conf_data; +} diff -Nur linux-2.6.30.5.orig/arch/mips/loongson/common/cs5536/cs5536_flash.c linux-2.6.30.5/arch/mips/loongson/common/cs5536/cs5536_flash.c --- linux-2.6.30.5.orig/arch/mips/loongson/common/cs5536/cs5536_flash.c 1970-01-01 01:00:00.000000000 +0100 +++ linux-2.6.30.5/arch/mips/loongson/common/cs5536/cs5536_flash.c 2009-08-23 19:01:04.000000000 +0200 @@ -0,0 +1,452 @@ +/* + * the FLASH Virtual Support Module of AMD CS5536 + * + * Copyright (C) 2007 Lemote, Inc. & Institute of Computing Technology + * Author : jlliu, liujl@lemote.com + * + * Copyright (C) 2009 Lemote, Inc. & Institute of Computing Technology + * Author: Wu Zhangjin, wuzj@lemote.com + * + * 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. + */ + +#include +#include + +/* + * enable the region of flashs(NOR or NAND) + * + * the same as the DIVIL other modules above, two groups of regs should be + * modified here to control the region. DIVIL flash LBAR and the + * RCONFx(6~9 reserved). + */ +static void flash_lbar_enable(void) +{ + u32 hi, lo; + int offset; + + for (offset = DIVIL_LBAR_FLSH0; offset <= DIVIL_LBAR_FLSH3; offset++) { + _rdmsr(DIVIL_MSR_REG(offset), &hi, &lo); + hi |= 0x1; + _wrmsr(DIVIL_MSR_REG(offset), hi, lo); + } + + for (offset = SB_R6; offset <= SB_R9; offset++) { + _rdmsr(SB_MSR_REG(offset), &hi, &lo); + lo |= 0x1; + _wrmsr(SB_MSR_REG(offset), hi, lo); + } + + return; +} + +/* + * disable the region of flashs(NOR or NAND) + */ +static void flash_lbar_disable(void) +{ + u32 hi, lo; + int offset; + + for (offset = DIVIL_LBAR_FLSH0; offset <= DIVIL_LBAR_FLSH3; offset++) { + _rdmsr(DIVIL_MSR_REG(offset), &hi, &lo); + hi &= ~0x01; + _wrmsr(DIVIL_MSR_REG(offset), hi, lo); + } + for (offset = SB_R6; offset <= SB_R9; offset++) { + _rdmsr(SB_MSR_REG(offset), &hi, &lo); + lo &= ~0x01; + _wrmsr(SB_MSR_REG(offset), hi, lo); + } + + return; +} + +#ifndef CONFIG_CS5536_NOR_FLASH /* for nand flash */ + +void pci_flash_write_bar(int n, u32 value) +{ + u32 hi = 0, lo = value; + + if (value == PCI_BAR_RANGE_MASK) { + /* make the flag for reading the bar length. */ + _rdmsr(GLCP_MSR_REG(GLCP_SOFT_COM), &hi, &lo); + lo |= (SOFT_BAR_FLSH0_FLAG << n); + _wrmsr(GLCP_MSR_REG(GLCP_SOFT_COM), hi, lo); + } else if ((value & 0x01) == 0x00) { + /* mem space nand flash native reg base addr */ + hi = 0xfffff007; + lo &= CS5536_FLSH_RANGE; + _wrmsr(DIVIL_MSR_REG(DIVIL_LBAR_FLSH0 + n), hi, lo); + + /* RCONFx is 4KB in units for mem space. */ + hi = ((value & 0xfffff000) << 12) | + ((CS5536_FLSH_LENGTH & 0xfffff000) - (1 << 12)) | 0x00; + lo = ((value & 0xfffff000) << 12) | 0x01; + _wrmsr(SB_MSR_REG(SB_R6 + n), hi, lo); + } + return; +} + +void pci_flash_write_reg(int reg, u32 value) +{ + u32 hi = 0, lo = value; + + switch (reg) { + case PCI_COMMAND: + if (value & PCI_COMMAND_MEMORY) + flash_lbar_enable(); + else + flash_lbar_disable(); + break; + case PCI_STATUS: + if (value & PCI_STATUS_PARITY) { + _rdmsr(SB_MSR_REG(SB_ERROR), &hi, &lo); + if (lo & SB_PARE_ERR_FLAG) { + lo = (lo & 0x0000ffff) | SB_PARE_ERR_FLAG; + _wrmsr(SB_MSR_REG(SB_ERROR), hi, lo); + } + } + break; + case PCI_BAR0_REG: + pci_flash_write_bar(0, value); + break; + case PCI_BAR1_REG: + pci_flash_write_bar(1, value); + break; + case PCI_BAR2_REG: + pci_flash_write_bar(2, value); + break; + case PCI_BAR3_REG: + pci_flash_write_bar(3, value); + break; + case PCI_FLASH_INT_REG: + _rdmsr(DIVIL_MSR_REG(PIC_YSEL_LOW), &hi, &lo); + /* disable all the flash interrupt in PIC */ + lo &= ~(0xf << PIC_YSEL_LOW_FLASH_SHIFT); + if (value) /* enable all the flash interrupt in PIC */ + lo |= (CS5536_FLASH_INTR << PIC_YSEL_LOW_FLASH_SHIFT); + _wrmsr(DIVIL_MSR_REG(PIC_YSEL_LOW), hi, lo); + break; + case PCI_NAND_FLASH_TDATA_REG: + _wrmsr(DIVIL_MSR_REG(NANDF_DATA), hi, lo); + break; + case PCI_NAND_FLASH_TCTRL_REG: + lo &= 0x00000fff; + _wrmsr(DIVIL_MSR_REG(NANDF_CTRL), hi, lo); + break; + case PCI_NAND_FLASH_RSVD_REG: + _wrmsr(DIVIL_MSR_REG(NANDF_RSVD), hi, lo); + break; + case PCI_FLASH_SELECT_REG: + if (value == CS5536_IDE_FLASH_SIGNATURE) { + _rdmsr(DIVIL_MSR_REG(DIVIL_BALL_OPTS), &hi, &lo); + lo &= ~0x01; + _wrmsr(DIVIL_MSR_REG(DIVIL_BALL_OPTS), hi, lo); + } + break; + default: + break; + } + + return; +} + +u32 pci_flash_read_bar(int n) +{ + u32 hi, lo; + u32 conf_data = 0; + + _rdmsr(GLCP_MSR_REG(GLCP_SOFT_COM), &hi, &lo); + if (lo & (SOFT_BAR_FLSH0_FLAG << n)) { + conf_data = CS5536_FLSH_RANGE | PCI_BASE_ADDRESS_SPACE_MEMORY; + lo &= ~(SOFT_BAR_FLSH0_FLAG << n); + _wrmsr(GLCP_MSR_REG(GLCP_SOFT_COM), hi, lo); + } else { + _rdmsr(DIVIL_MSR_REG(DIVIL_LBAR_FLSH0 + n), &hi, &lo); + conf_data = lo; + conf_data &= ~0x0f; + } + + return conf_data; +} + +u32 pci_flash_read_reg(int reg) +{ + u32 conf_data = 0; + u32 hi, lo; + + switch (reg) { + case PCI_VENDOR_ID: + conf_data = + CFG_PCI_VENDOR_ID(CS5536_FLASH_DEVICE_ID, CS5536_VENDOR_ID); + break; + case PCI_COMMAND: + /* we just read one lbar for returning. */ + _rdmsr(DIVIL_MSR_REG(DIVIL_LBAR_FLSH0), &hi, &lo); + if (hi & 0x1) + conf_data |= PCI_COMMAND_MEMORY; + break; + case PCI_STATUS: + conf_data |= PCI_STATUS_66MHZ; + conf_data |= PCI_STATUS_FAST_BACK; + _rdmsr(SB_MSR_REG(SB_ERROR), &hi, &lo); + if (lo & SB_PARE_ERR_FLAG) + conf_data |= PCI_STATUS_PARITY; + conf_data |= PCI_STATUS_DEVSEL_MEDIUM; + break; + case PCI_CLASS_REVISION: + _rdmsr(DIVIL_MSR_REG(DIVIL_CAP), &hi, &lo); + conf_data = lo & 0x000000ff; + conf_data |= (CS5536_FLASH_CLASS_CODE << 8); + break; + case PCI_CACHE_LINE_SIZE: + conf_data = + CFG_PCI_CACHE_LINE_SIZE(PCI_NORMAL_HEADER_TYPE, + PCI_NORMAL_LATENCY_TIMER); + break; + case PCI_BAR0_REG: + return pci_flash_read_bar(0); + break; + case PCI_BAR1_REG: + return pci_flash_read_bar(1); + break; + case PCI_BAR2_REG: + return pci_flash_read_bar(2); + break; + case PCI_BAR3_REG: + return pci_flash_read_bar(3); + break; + case PCI_CARDBUS_CIS: + conf_data = PCI_CARDBUS_CIS_POINTER; + break; + case PCI_SUBSYSTEM_VENDOR_ID: + conf_data = + CFG_PCI_VENDOR_ID(CS5536_FLASH_SUB_ID, + CS5536_SUB_VENDOR_ID); + break; + case PCI_ROM_ADDRESS: + conf_data = PCI_EXPANSION_ROM_BAR; + break; + case PCI_CAPABILITY_LIST: + conf_data = PCI_CAPLIST_POINTER; + break; + case PCI_INTERRUPT_LINE: + conf_data = + CFG_PCI_INTERRUPT_LINE(PCI_DEFAULT_PIN, CS5536_FLASH_INTR); + break; + case PCI_NAND_FLASH_TDATA_REG: + _rdmsr(DIVIL_MSR_REG(NANDF_DATA), &hi, &lo); + conf_data = lo; + break; + case PCI_NAND_FLASH_TCTRL_REG: + _rdmsr(DIVIL_MSR_REG(NANDF_CTRL), &hi, &lo); + conf_data = lo & 0x00000fff; + break; + case PCI_NAND_FLASH_RSVD_REG: + _rdmsr(DIVIL_MSR_REG(NANDF_RSVD), &hi, &lo); + conf_data = lo; + break; + case PCI_FLASH_SELECT_REG: + _rdmsr(DIVIL_MSR_REG(DIVIL_BALL_OPTS), &hi, &lo); + conf_data = lo & 0x01; + break; + default: + break; + } + return 0; +} + +#else /* CONFIG_CS5536_NOR_FLASH */ + +void pci_flash_write_bar(int n, u32 value) +{ + u32 hi = 0, lo = value; + + if (value == PCI_BAR_RANGE_MASK) { + _rdmsr(GLCP_MSR_REG(GLCP_SOFT_COM), &hi, &lo); + lo |= (SOFT_BAR_FLSH0_FLAG << n); + _wrmsr(GLCP_MSR_REG(GLCP_SOFT_COM), hi, lo); + } else if (value & 0x01) { + /* IO space of 16bytes nor flash */ + hi = 0x0000fff1; + lo &= CS5536_FLSH_RANGE; + _wrmsr(DIVIL_MSR_REG(DIVIL_LBAR_FLSH0 + n), hi, lo); + + /* RCONFx used for 16bytes reserved. */ + hi = ((value & 0x000ffffc) << 12) | ((CS5536_FLSH_LENGTH - 4) + << 12) | 0x01; + lo = ((value & 0x000ffffc) << 12) | 0x01; + _wrmsr(SB_MSR_REG(SB_R6 + n), hi, lo); + } + return; +} + +void pci_flash_write_reg(int reg, u32 value) +{ + u32 hi = 0, lo = value; + + switch (reg) { + case PCI_COMMAND: + if (value & PCI_COMMAND_IO) + flash_lbar_enable(); + else + flash_lbar_disable(); + break; + case PCI_STATUS: + if (value & PCI_STATUS_PARITY) { + _rdmsr(SB_MSR_REG(SB_ERROR), &hi, &lo); + if (lo & SB_PARE_ERR_FLAG) { + lo = (lo & 0x0000ffff) | SB_PARE_ERR_FLAG; + _wrmsr(SB_MSR_REG(SB_ERROR), hi, lo); + } + } + break; + case PCI_BAR0_REG: + pci_flash_write_bar(0, value); + break; + case PCI_BAR1_REG: + pci_flash_write_bar(1, value); + break; + case PCI_BAR2_REG: + pci_flash_write_bar(2, value); + break; + case PCI_BAR3_REG: + pci_flash_write_bar(3, value); + break; + case PCI_FLASH_INT_REG: + _rdmsr(DIVIL_MSR_REG(PIC_YSEL_LOW), &hi, &lo); + /* disable all the flash interrupt in PIC */ + lo &= ~(0xf << PIC_YSEL_LOW_FLASH_SHIFT); + if (value) /* enable all the flash interrupt in PIC */ + lo |= (CS5536_FLASH_INTR << PIC_YSEL_LOW_FLASH_SHIFT); + _wrmsr(DIVIL_MSR_REG(PIC_YSEL_LOW), hi, lo); + break; + case PCI_NOR_FLASH_CTRL_REG: + lo &= 0x000000ff; + _wrmsr(DIVIL_MSR_REG(NORF_CTRL), hi, lo); + break; + case PCI_NOR_FLASH_T01_REG: + _wrmsr(DIVIL_MSR_REG(NORF_T01), hi, lo); + break; + case PCI_NOR_FLASH_T23_REG: + _wrmsr(DIVIL_MSR_REG(NORF_T23), hi, lo); + break; + case PCI_FLASH_SELECT_REG: + if (value == CS5536_IDE_FLASH_SIGNATURE) { + _rdmsr(DIVIL_MSR_REG(DIVIL_BALL_OPTS), &hi, &lo); + lo &= ~0x01; + _wrmsr(DIVIL_MSR_REG(DIVIL_BALL_OPTS), hi, lo); + } + break; + default: + break; + } + return; +} + +u32 pci_flash_read_bar(int n) +{ + u32 hi, lo; + u32 conf_data = 0; + + _rdmsr(GLCP_MSR_REG(GLCP_SOFT_COM), &hi, &lo); + if (lo & (SOFT_BAR_FLSH0_FLAG << n)) { + conf_data = CS5536_FLSH_RANGE | PCI_BASE_ADDRESS_SPACE_IO; + lo &= ~(SOFT_BAR_FLSH0_FLAG << n); + _wrmsr(GLCP_MSR_REG(GLCP_SOFT_COM), hi, lo); + } else { + _rdmsr(DIVIL_MSR_REG(DIVIL_LBAR_FLSH0 + n), &hi, &lo); + conf_data = lo & 0x0000ffff; + conf_data |= 0x01; + conf_data &= ~0x02; + } + + return conf_data; +} + +u32 pci_flash_read_reg(int reg) +{ + u32 conf_data = 0; + u32 hi, lo; + + switch (reg) { + case PCI_VENDOR_ID: + conf_data = + CFG_PCI_VENDOR_ID(CS5536_FLASH_DEVICE_ID, CS5536_VENDOR_ID); + break; + case PCI_COMMAND: + /* we just check one flash bar for returning. */ + _rdmsr(DIVIL_MSR_REG(DIVIL_LBAR_FLSH0), &hi, &lo); + if (hi & PCI_COMMAND_IO) + conf_data |= PCI_COMMAND_IO; + break; + case PCI_STATUS: + conf_data |= PCI_STATUS_66MHZ; + conf_data |= PCI_STATUS_FAST_BACK; + _rdmsr(SB_MSR_REG(SB_ERROR), &hi, &lo); + if (lo & SB_PARE_ERR_FLAG) + conf_data |= PCI_STATUS_PARITY; + conf_data |= PCI_STATUS_DEVSEL_MEDIUM; + break; + case PCI_CLASS_REVISION: + _rdmsr(DIVIL_MSR_REG(DIVIL_CAP), &hi, &lo); + conf_data = lo & 0x000000ff; + conf_data |= (CS5536_FLASH_CLASS_CODE << 8); + break; + case PCI_CACHE_LINE_SIZE: + conf_data = + CFG_PCI_CACHE_LINE_SIZE(PCI_NORMAL_HEADER_TYPE, + PCI_NORMAL_LATENCY_TIMER); + break; + case PCI_BAR0_REG: + return pci_flash_read_bar(0); + break; + case PCI_BAR1_REG: + return pci_flash_read_bar(1); + break; + case PCI_BAR2_REG: + return pci_flash_read_bar(2); + break; + case PCI_BAR3_REG: + return pci_flash_read_bar(3); + break; + case PCI_CARDBUS_CIS: + conf_data = PCI_CARDBUS_CIS_POINTER; + break; + case PCI_SUBSYSTEM_VENDOR_ID: + conf_data = + CFG_PCI_VENDOR_ID(CS5536_FLASH_SUB_ID, + CS5536_SUB_VENDOR_ID); + break; + case PCI_ROM_ADDRESS: + conf_data = PCI_EXPANSION_ROM_BAR; + break; + case PCI_CAPABILITY_LIST: + conf_data = PCI_CAPLIST_POINTER; + break; + case PCI_INTERRUPT_LINE: + conf_data = + CFG_PCI_INTERRUPT_LINE(PCI_DEFAULT_PIN, CS5536_FLASH_INTR); + break; + case PCI_NOR_FLASH_CTRL_REG: + _rdmsr(DIVIL_MSR_REG(NORF_CTRL), &hi, &lo); + conf_data = lo & 0x000000ff; + break; + case PCI_NOR_FLASH_T01_REG: + _rdmsr(DIVIL_MSR_REG(NORF_T01), &hi, &lo); + conf_data = lo; + break; + case PCI_NOR_FLASH_T23_REG: + _rdmsr(DIVIL_MSR_REG(NORF_T23), &hi, &lo); + conf_data = lo; + break; + default: + break; + } + return conf_data; +} +#endif /* CONFIG_CS5536_NOR_FLASH */ diff -Nur linux-2.6.30.5.orig/arch/mips/loongson/common/cs5536/cs5536_ide.c linux-2.6.30.5/arch/mips/loongson/common/cs5536/cs5536_ide.c --- linux-2.6.30.5.orig/arch/mips/loongson/common/cs5536/cs5536_ide.c 1970-01-01 01:00:00.000000000 +0100 +++ linux-2.6.30.5/arch/mips/loongson/common/cs5536/cs5536_ide.c 2009-08-23 19:01:04.000000000 +0200 @@ -0,0 +1,194 @@ +/* + * the IDE Virtual Support Module of AMD CS5536 + * + * Copyright (C) 2007 Lemote, Inc. & Institute of Computing Technology + * Author : jlliu, liujl@lemote.com + * + * Copyright (C) 2009 Lemote, Inc. & Institute of Computing Technology + * Author: Wu Zhangjin, wuzj@lemote.com + * + * 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. + */ + +#include +#include + +/* + * ide_write : ide write transfering + */ +void pci_ide_write_reg(int reg, u32 value) +{ + u32 hi = 0, lo = value; + + switch (reg) { + case PCI_COMMAND: + _rdmsr(GLIU_MSR_REG(GLIU_PAE), &hi, &lo); + if (value & PCI_COMMAND_MASTER) + lo |= (0x03 << 4); + else + lo &= ~(0x03 << 4); + _wrmsr(GLIU_MSR_REG(GLIU_PAE), hi, lo); + break; + case PCI_STATUS: + if (value & PCI_STATUS_PARITY) { + _rdmsr(SB_MSR_REG(SB_ERROR), &hi, &lo); + if (lo & SB_PARE_ERR_FLAG) { + lo = (lo & 0x0000ffff) | SB_PARE_ERR_FLAG; + _wrmsr(SB_MSR_REG(SB_ERROR), hi, lo); + } + } + break; + case PCI_CACHE_LINE_SIZE: + value &= 0x0000ff00; + _rdmsr(SB_MSR_REG(SB_CTRL), &hi, &lo); + hi &= 0xffffff00; + hi |= (value >> 8); + _wrmsr(SB_MSR_REG(SB_CTRL), hi, lo); + break; + case PCI_BAR4_REG: + if (value == PCI_BAR_RANGE_MASK) { + _rdmsr(GLCP_MSR_REG(GLCP_SOFT_COM), &hi, &lo); + lo |= SOFT_BAR_IDE_FLAG; + _wrmsr(GLCP_MSR_REG(GLCP_SOFT_COM), hi, lo); + } else if (value & 0x01) { + lo = (value & 0xfffffff0) | 0x1; + _wrmsr(IDE_MSR_REG(IDE_IO_BAR), hi, lo); + + value &= 0xfffffffc; + hi = 0x60000000 | ((value & 0x000ff000) >> 12); + lo = 0x000ffff0 | ((value & 0x00000fff) << 20); + _wrmsr(GLIU_MSR_REG(GLIU_IOD_BM2), hi, lo); + } + break; + case PCI_IDE_CFG_REG: + if (value == CS5536_IDE_FLASH_SIGNATURE) { + _rdmsr(DIVIL_MSR_REG(DIVIL_BALL_OPTS), &hi, &lo); + lo |= 0x01; + _wrmsr(DIVIL_MSR_REG(DIVIL_BALL_OPTS), hi, lo); + } else + _wrmsr(IDE_MSR_REG(IDE_CFG), hi, lo); + break; + case PCI_IDE_DTC_REG: + _wrmsr(IDE_MSR_REG(IDE_DTC), hi, lo); + break; + case PCI_IDE_CAST_REG: + _wrmsr(IDE_MSR_REG(IDE_CAST), hi, lo); + break; + case PCI_IDE_ETC_REG: + _wrmsr(IDE_MSR_REG(IDE_ETC), hi, lo); + break; + case PCI_IDE_PM_REG: + _wrmsr(IDE_MSR_REG(IDE_INTERNAL_PM), hi, lo); + break; + default: + break; + } + + return; +} + +/* + * ide_read : ide read tranfering. + */ +u32 pci_ide_read_reg(int reg) +{ + u32 conf_data = 0; + u32 hi, lo; + + switch (reg) { + case PCI_VENDOR_ID: + conf_data = + CFG_PCI_VENDOR_ID(CS5536_IDE_DEVICE_ID, CS5536_VENDOR_ID); + break; + case PCI_COMMAND: + _rdmsr(IDE_MSR_REG(IDE_IO_BAR), &hi, &lo); + if (lo & 0xfffffff0) + conf_data |= PCI_COMMAND_IO; + _rdmsr(GLIU_MSR_REG(GLIU_PAE), &hi, &lo); + if ((lo & 0x30) == 0x30) + conf_data |= PCI_COMMAND_MASTER; + break; + case PCI_STATUS: + conf_data |= PCI_STATUS_66MHZ; + conf_data |= PCI_STATUS_FAST_BACK; + _rdmsr(SB_MSR_REG(SB_ERROR), &hi, &lo); + if (lo & SB_PARE_ERR_FLAG) + conf_data |= PCI_STATUS_PARITY; + conf_data |= PCI_STATUS_DEVSEL_MEDIUM; + break; + case PCI_CLASS_REVISION: + _rdmsr(IDE_MSR_REG(IDE_CAP), &hi, &lo); + conf_data = lo & 0x000000ff; + conf_data |= (CS5536_IDE_CLASS_CODE << 8); + break; + case PCI_CACHE_LINE_SIZE: + _rdmsr(SB_MSR_REG(SB_CTRL), &hi, &lo); + hi &= 0x000000f8; + conf_data = CFG_PCI_CACHE_LINE_SIZE(PCI_NORMAL_HEADER_TYPE, hi); + break; + case PCI_BAR0_REG: + case PCI_BAR1_REG: + case PCI_BAR2_REG: + case PCI_BAR3_REG: + break; + case PCI_BAR4_REG: + _rdmsr(GLCP_MSR_REG(GLCP_SOFT_COM), &hi, &lo); + if (lo & SOFT_BAR_IDE_FLAG) { + conf_data = CS5536_IDE_RANGE | + PCI_BASE_ADDRESS_SPACE_IO; + lo &= ~SOFT_BAR_IDE_FLAG; + _wrmsr(GLCP_MSR_REG(GLCP_SOFT_COM), hi, lo); + } else { + _rdmsr(IDE_MSR_REG(IDE_IO_BAR), &hi, &lo); + conf_data = lo & 0xfffffff0; + conf_data |= 0x01; + conf_data &= ~0x02; + } + break; + case PCI_BAR5_REG: + break; + case PCI_CARDBUS_CIS: + conf_data = PCI_CARDBUS_CIS_POINTER; + break; + case PCI_SUBSYSTEM_VENDOR_ID: + conf_data = + CFG_PCI_VENDOR_ID(CS5536_IDE_SUB_ID, CS5536_SUB_VENDOR_ID); + break; + case PCI_ROM_ADDRESS: + conf_data = PCI_EXPANSION_ROM_BAR; + break; + case PCI_CAPABILITY_LIST: + conf_data = PCI_CAPLIST_POINTER; + break; + case PCI_INTERRUPT_LINE: + conf_data = + CFG_PCI_INTERRUPT_LINE(PCI_DEFAULT_PIN, CS5536_IDE_INTR); + break; + case PCI_IDE_CFG_REG: + _rdmsr(IDE_MSR_REG(IDE_CFG), &hi, &lo); + conf_data = lo; + break; + case PCI_IDE_DTC_REG: + _rdmsr(IDE_MSR_REG(IDE_DTC), &hi, &lo); + conf_data = lo; + break; + case PCI_IDE_CAST_REG: + _rdmsr(IDE_MSR_REG(IDE_CAST), &hi, &lo); + conf_data = lo; + break; + case PCI_IDE_ETC_REG: + _rdmsr(IDE_MSR_REG(IDE_ETC), &hi, &lo); + conf_data = lo; + case PCI_IDE_PM_REG: + _rdmsr(IDE_MSR_REG(IDE_INTERNAL_PM), &hi, &lo); + conf_data = lo; + break; + default: + break; + } + + return conf_data; +} diff -Nur linux-2.6.30.5.orig/arch/mips/loongson/common/cs5536/cs5536_isa.c linux-2.6.30.5/arch/mips/loongson/common/cs5536/cs5536_isa.c --- linux-2.6.30.5.orig/arch/mips/loongson/common/cs5536/cs5536_isa.c 1970-01-01 01:00:00.000000000 +0100 +++ linux-2.6.30.5/arch/mips/loongson/common/cs5536/cs5536_isa.c 2009-08-23 19:01:04.000000000 +0200 @@ -0,0 +1,376 @@ +/* + * the ISA Virtual Support Module of AMD CS5536 + * + * Copyright (C) 2007 Lemote, Inc. & Institute of Computing Technology + * Author : jlliu, liujl@lemote.com + * + * Copyright (C) 2009 Lemote, Inc. & Institute of Computing Technology + * Author: Wu Zhangjin, wuzj@lemote.com + * + * 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. + */ + +#include +#include + +/* common variables for PCI_ISA_READ/WRITE_BAR */ +static const u32 divil_msr_reg[6] = { + DIVIL_MSR_REG(DIVIL_LBAR_SMB), DIVIL_MSR_REG(DIVIL_LBAR_GPIO), + DIVIL_MSR_REG(DIVIL_LBAR_MFGPT), DIVIL_MSR_REG(DIVIL_LBAR_IRQ), + DIVIL_MSR_REG(DIVIL_LBAR_PMS), DIVIL_MSR_REG(DIVIL_LBAR_ACPI), +}; + +static const u32 soft_bar_flag[6] = { + SOFT_BAR_SMB_FLAG, SOFT_BAR_GPIO_FLAG, SOFT_BAR_MFGPT_FLAG, + SOFT_BAR_IRQ_FLAG, SOFT_BAR_PMS_FLAG, SOFT_BAR_ACPI_FLAG, +}; + +static const u32 sb_msr_reg[6] = { + SB_MSR_REG(SB_R0), SB_MSR_REG(SB_R1), SB_MSR_REG(SB_R2), + SB_MSR_REG(SB_R3), SB_MSR_REG(SB_R4), SB_MSR_REG(SB_R5), +}; + +static const u32 bar_space_range[6] = { + CS5536_SMB_RANGE, CS5536_GPIO_RANGE, CS5536_MFGPT_RANGE, + CS5536_IRQ_RANGE, CS5536_PMS_RANGE, CS5536_ACPI_RANGE, +}; + +static const int bar_space_len[6] = { + CS5536_SMB_LENGTH, CS5536_GPIO_LENGTH, CS5536_MFGPT_LENGTH, + CS5536_IRQ_LENGTH, CS5536_PMS_LENGTH, CS5536_ACPI_LENGTH, +}; + +/* + * enable the divil module bar space. + * + * For all the DIVIL module LBAR, you should control the DIVIL LBAR reg + * and the RCONFx(0~5) reg to use the modules. + */ +static void divil_lbar_enable(void) +{ + u32 hi, lo; + int offset; + + /* + * The DIVIL IRQ is not used yet. and make the RCONF0 reserved. + */ + + for (offset = DIVIL_LBAR_SMB; offset <= DIVIL_LBAR_PMS; offset++) { + _rdmsr(DIVIL_MSR_REG(offset), &hi, &lo); + hi |= 0x01; + _wrmsr(DIVIL_MSR_REG(DIVIL_LBAR_SMB), hi, lo); + } + return; +} + +/* + * disable the divil module bar space. + */ +static void divil_lbar_disable(void) +{ + u32 hi, lo; + int offset; + + for (offset = DIVIL_LBAR_SMB; offset <= DIVIL_LBAR_PMS; offset++) { + _rdmsr(DIVIL_MSR_REG(offset), &hi, &lo); + hi &= ~0x01; + _wrmsr(DIVIL_MSR_REG(DIVIL_LBAR_SMB), hi, lo); + } + return; +} + +/* + * BAR write: write value to the n BAR + */ + +void pci_isa_write_bar(int n, u32 value) +{ + u32 hi = 0, lo = value; + + if (value == PCI_BAR_RANGE_MASK) { + _rdmsr(GLCP_MSR_REG(GLCP_SOFT_COM), &hi, &lo); + lo |= soft_bar_flag[n]; + _wrmsr(GLCP_MSR_REG(GLCP_SOFT_COM), hi, lo); + } else if (value & 0x01) { + /* NATIVE reg */ + hi = 0x0000f001; + lo &= bar_space_range[n]; + _wrmsr(divil_msr_reg[n], hi, lo); + + /* RCONFx is 4bytes in units for I/O space */ + hi = ((value & 0x000ffffc) << 12) | + ((bar_space_len[n] - 4) << 12) | 0x01; + lo = ((value & 0x000ffffc) << 12) | 0x01; + _wrmsr(sb_msr_reg[n], hi, lo); + } + + return; +} + +/* + * BAR read: read the n BAR + */ + +u32 pci_isa_read_bar(int n) +{ + u32 conf_data = 0; + u32 hi, lo; + + _rdmsr(GLCP_MSR_REG(GLCP_SOFT_COM), &hi, &lo); + if (lo & soft_bar_flag[n]) { + conf_data = bar_space_range[n] | PCI_BASE_ADDRESS_SPACE_IO; + lo &= ~soft_bar_flag[n]; + _wrmsr(GLCP_MSR_REG(GLCP_SOFT_COM), hi, lo); + } else { + _rdmsr(divil_msr_reg[n], &hi, &lo); + conf_data = lo & bar_space_range[n]; + conf_data |= 0x01; + conf_data &= ~0x02; + } + return conf_data; +} + +/* + * isa_write : isa write transfering. + * WE assume that the ISA is not the BUS MASTER.!!! + */ +/* FAST BACK TO BACK '1' for BUS MASTER '0' for BUS SALVE */ +/* COMMAND : + * bit0 : IO SPACE ENABLE + * bit1 : MEMORY SPACE ENABLE(ignore) + * bit2 : BUS MASTER ENABLE(ignore) + * bit3 : SPECIAL CYCLE(ignore)? default is ignored. + * bit4 : MEMORY WRITE and INVALIDATE(ignore) + * bit5 : VGA PALETTE(ignore) + * bit6 : PARITY ERROR(ignore)? : default is ignored. + * bit7 : WAIT CYCLE CONTROL(ignore) + * bit8 : SYSTEM ERROR(ignore) + * bit9 : FAST BACK TO BACK(ignore) + * bit10-bit15 : RESERVED + * STATUS : + * bit0-bit3 : RESERVED + * bit4 : CAPABILITY LIST(ignore) + * bit5 : 66MHZ CAPABLE + * bit6 : RESERVED + * bit7 : FAST BACK TO BACK(ignore) + * bit8 : DATA PARITY ERROR DETECED(ignore) + * bit9-bit10 : DEVSEL TIMING(ALL MEDIUM) + * bit11: SIGNALED TARGET ABORT + * bit12: RECEIVED TARGET ABORT + * bit13: RECEIVED MASTER ABORT + * bit14: SIGNALED SYSTEM ERROR + * bit15: DETECTED PARITY ERROR + */ + +void pci_isa_write_reg(int reg, u32 value) +{ + u32 hi = 0, lo = value; + u32 temp; + + switch (reg) { + case PCI_COMMAND: + if (value & PCI_COMMAND_IO) + divil_lbar_enable(); + else + divil_lbar_disable(); + break; + case PCI_STATUS: + _rdmsr(SB_MSR_REG(SB_ERROR), &hi, &lo); + temp = lo & 0x0000ffff; + if ((value & PCI_STATUS_SIG_TARGET_ABORT) && + (lo & SB_TAS_ERR_EN)) + temp |= SB_TAS_ERR_FLAG; + + if ((value & PCI_STATUS_REC_TARGET_ABORT) && + (lo & SB_TAR_ERR_EN)) + temp |= SB_TAR_ERR_FLAG; + + if ((value & PCI_STATUS_REC_MASTER_ABORT) + && (lo & SB_MAR_ERR_EN)) + temp |= SB_MAR_ERR_FLAG; + + if ((value & PCI_STATUS_DETECTED_PARITY) + && (lo & SB_PARE_ERR_EN)) + temp |= SB_PARE_ERR_FLAG; + + lo = temp; + _wrmsr(SB_MSR_REG(SB_ERROR), hi, lo); + break; + case PCI_CACHE_LINE_SIZE: + value &= 0x0000ff00; + _rdmsr(SB_MSR_REG(SB_CTRL), &hi, &lo); + hi &= 0xffffff00; + hi |= (value >> 8); + _wrmsr(SB_MSR_REG(SB_CTRL), hi, lo); + break; + case PCI_BAR0_REG: + pci_isa_write_bar(0, value); + break; + case PCI_BAR1_REG: + pci_isa_write_bar(1, value); + break; + case PCI_BAR2_REG: + pci_isa_write_bar(2, value); + break; + case PCI_BAR3_REG: + pci_isa_write_bar(3, value); + break; + case PCI_BAR4_REG: + pci_isa_write_bar(4, value); + break; + case PCI_BAR5_REG: + pci_isa_write_bar(5, value); + break; + case PCI_UART1_INT_REG: + _rdmsr(DIVIL_MSR_REG(PIC_YSEL_HIGH), &hi, &lo); + /* disable uart1 interrupt in PIC */ + lo &= ~(0xf << 24); + if (value) /* enable uart1 interrupt in PIC */ + lo |= (CS5536_UART1_INTR << 24); + _wrmsr(DIVIL_MSR_REG(PIC_YSEL_HIGH), hi, lo); + break; + case PCI_UART2_INT_REG: + _rdmsr(DIVIL_MSR_REG(PIC_YSEL_HIGH), &hi, &lo); + /* disable uart2 interrupt in PIC */ + lo &= ~(0xf << 28); + if (value) /* enable uart2 interrupt in PIC */ + lo |= (CS5536_UART2_INTR << 28); + _wrmsr(DIVIL_MSR_REG(PIC_YSEL_HIGH), hi, lo); + break; + case PCI_ISA_FIXUP_REG: + if (value) { + /* enable the TARGET ABORT/MASTER ABORT etc. */ + _rdmsr(SB_MSR_REG(SB_ERROR), &hi, &lo); + lo |= 0x00000063; + _wrmsr(SB_MSR_REG(SB_ERROR), hi, lo); + } + + default: + /* ALL OTHER PCI CONFIG SPACE HEADER IS NOT IMPLEMENTED. */ + break; + } + + return; +} + +/* + * isa_read : isa read transfering. + * we assume that the ISA is not the BUS MASTER. + */ + + /* COMMAND : + * bit0 : IO SPACE ENABLE + * bit1 : MEMORY SPACE ENABLE(ignore) + * bit2 : BUS MASTER ENABLE(ignore) + * bit3 : SPECIAL CYCLE(ignore)? default is ignored. + * bit4 : MEMORY WRITE and INVALIDATE(ignore) + * bit5 : VGA PALETTE(ignore) + * bit6 : PARITY ERROR(ignore)? : default is ignored. + * bit7 : WAIT CYCLE CONTROL(ignore) + * bit8 : SYSTEM ERROR(ignore) + * bit9 : FAST BACK TO BACK(ignore) + * bit10-bit15 : RESERVED + * STATUS : + * bit0-bit3 : RESERVED + * bit4 : CAPABILITY LIST(ignore) + * bit5 : 66MHZ CAPABLE + * bit6 : RESERVED + * bit7 : FAST BACK TO BACK(ignore) + * bit8 : DATA PARITY ERROR DETECED(ignore)? + * bit9-bit10 : DEVSEL TIMING(ALL MEDIUM) + * bit11: SIGNALED TARGET ABORT + * bit12: RECEIVED TARGET ABORT + * bit13: RECEIVED MASTER ABORT + * bit14: SIGNALED SYSTEM ERROR + * bit15: DETECTED PARITY ERROR(?) + */ + +u32 pci_isa_read_reg(int reg) +{ + u32 conf_data = 0; + u32 hi, lo; + + switch (reg) { + case PCI_VENDOR_ID: + conf_data = + CFG_PCI_VENDOR_ID(CS5536_ISA_DEVICE_ID, CS5536_VENDOR_ID); + break; + case PCI_COMMAND: + /* we just check the first LBAR for the IO enable bit, */ + /* maybe we should changed later. */ + _rdmsr(DIVIL_MSR_REG(DIVIL_LBAR_SMB), &hi, &lo); + if (hi & 0x01) + conf_data |= PCI_COMMAND_IO; + break; + case PCI_STATUS: + conf_data |= PCI_STATUS_66MHZ; + conf_data |= PCI_STATUS_DEVSEL_MEDIUM; + conf_data |= PCI_STATUS_FAST_BACK; + + _rdmsr(SB_MSR_REG(SB_ERROR), &hi, &lo); + if (lo & SB_TAS_ERR_FLAG) + conf_data |= PCI_STATUS_SIG_TARGET_ABORT; + if (lo & SB_TAR_ERR_FLAG) + conf_data |= PCI_STATUS_REC_TARGET_ABORT; + if (lo & SB_MAR_ERR_FLAG) + conf_data |= PCI_STATUS_REC_MASTER_ABORT; + if (lo & SB_PARE_ERR_FLAG) + conf_data |= PCI_STATUS_DETECTED_PARITY; + break; + case PCI_CLASS_REVISION: + _rdmsr(GLCP_MSR_REG(GLCP_CHIP_REV_ID), &hi, &lo); + conf_data = lo & 0x000000ff; + conf_data |= (CS5536_ISA_CLASS_CODE << 8); + break; + case PCI_CACHE_LINE_SIZE: + _rdmsr(SB_MSR_REG(SB_CTRL), &hi, &lo); + hi &= 0x000000f8; + conf_data = CFG_PCI_CACHE_LINE_SIZE(PCI_BRIDGE_HEADER_TYPE, hi); + break; + /* + * we only use the LBAR of DIVIL, no RCONF used. + * all of them are IO space. + */ + case PCI_BAR0_REG: + return pci_isa_read_bar(0); + break; + case PCI_BAR1_REG: + return pci_isa_read_bar(1); + break; + case PCI_BAR2_REG: + return pci_isa_read_bar(2); + break; + case PCI_BAR3_REG: + break; + case PCI_BAR4_REG: + return pci_isa_read_bar(4); + break; + case PCI_BAR5_REG: + return pci_isa_read_bar(5); + break; + case PCI_CARDBUS_CIS: + conf_data = PCI_CARDBUS_CIS_POINTER; + break; + case PCI_SUBSYSTEM_VENDOR_ID: + conf_data = + CFG_PCI_VENDOR_ID(CS5536_ISA_SUB_ID, CS5536_SUB_VENDOR_ID); + break; + case PCI_ROM_ADDRESS: + conf_data = PCI_EXPANSION_ROM_BAR; + break; + case PCI_CAPABILITY_LIST: + conf_data = PCI_CAPLIST_POINTER; + break; + case PCI_INTERRUPT_LINE: + /* no interrupt used here */ + conf_data = CFG_PCI_INTERRUPT_LINE(0x00, 0x00); + break; + default: + break; + } + + return conf_data; +} diff -Nur linux-2.6.30.5.orig/arch/mips/loongson/common/cs5536/cs5536_mfgpt.c linux-2.6.30.5/arch/mips/loongson/common/cs5536/cs5536_mfgpt.c --- linux-2.6.30.5.orig/arch/mips/loongson/common/cs5536/cs5536_mfgpt.c 1970-01-01 01:00:00.000000000 +0100 +++ linux-2.6.30.5/arch/mips/loongson/common/cs5536/cs5536_mfgpt.c 2009-08-23 19:01:04.000000000 +0200 @@ -0,0 +1,241 @@ +/* + * CS5536 General timer functions + * + * Copyright (C) 2007 Lemote Inc. & Insititute of Computing Technology + * Author: Yanhua, yanh@lemote.com + * + * Copyright (C) 2009 Lemote Inc. & Insititute of Computing Technology + * Author: Wu zhangjin, wuzj@lemote.com + * + * Reference: 'AMD Geode(TM) CS5536 Companion Device Data Book' + * + * 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. + */ + +#include +#include +#include +#include +#include +#include +#include + +#include + +#include + +DEFINE_SPINLOCK(mfgpt_lock); +EXPORT_SYMBOL(mfgpt_lock); + +u32 mfgpt_base; + +/* + * Initialize the MFGPT timer. + * + * This is also called after resume to bring the MFGPT into operation again. + */ +/* setup register bit fields: + * 15: counter enable + * 14: compare2 output status, write 1 to clear when in event mode + * 13: compare1 output status + * 12: setup(ro) + * 11: stop enable, stop on sleep + * 10: external enable + * 9:8 compare2 mode; 00: disable, 01: compare on equal; 10: compare on GE, + * 11 event: GE + irq + * 7:6 compare1 mode + * 5: reverse enable, bit reverse of the counter + * 4: clock select. 0: 32KHz, 1: 14.318MHz + * 3:0 counter prescaler scale factor. + * select the input clock divide-by value. 2^n + * bit 11:0 is write once + */ + +static void init_mfgpt_timer(enum clock_event_mode mode, + struct clock_event_device *evt) +{ + spin_lock(&mfgpt_lock); + + switch (mode) { + case CLOCK_EVT_MODE_PERIODIC: + outw(COMPARE, MFGPT0_CMP2); /* set comparator2 */ + outw(0, MFGPT0_CNT); /* set counter to 0 */ + /* enable counter, comparator2 to event mode, 14.318MHz clock */ + outw(0xe310, MFGPT0_SETUP); + break; + + case CLOCK_EVT_MODE_SHUTDOWN: + case CLOCK_EVT_MODE_UNUSED: + if (evt->mode == CLOCK_EVT_MODE_PERIODIC || + evt->mode == CLOCK_EVT_MODE_ONESHOT) { + /* disable counter */ + outw(inw(MFGPT0_SETUP) & 0x7fff, MFGPT0_SETUP); + } + break; + + case CLOCK_EVT_MODE_ONESHOT: + /* One shot setup */ + outw(0xe300, MFGPT0_SETUP); + break; + + case CLOCK_EVT_MODE_RESUME: + /* Nothing to do here */ + break; + } + spin_unlock(&mfgpt_lock); +} + +/* + * Program the next event in oneshot mode + * + * Delta is given in MFGPT ticks + */ +static int mfgpt_next_event(unsigned long delta, struct clock_event_device *evt) +{ + spin_lock(&mfgpt_lock); + outw(delta & 0xffff, MFGPT0_CMP2); /* set comparator2 */ + outw(0, MFGPT0_CNT); /* set counter to 0 */ + spin_unlock(&mfgpt_lock); + + return 0; +} + +static struct clock_event_device mfgpt_clockevent = { + .name = "mfgpt", + .features = CLOCK_EVT_FEAT_PERIODIC, + .set_mode = init_mfgpt_timer, + .set_next_event = mfgpt_next_event, + .irq = CS5536_MFGPT_INTR, +}; + +static irqreturn_t timer_interrupt(int irq, void *dev_id) +{ + u32 basehi; + + /* + * get MFGPT base address + * + * NOTE: do not remove me, it's need for the value of mfgpt_base is + * variable + */ + _rdmsr(CS5536_DIVIL_MSR_BASE + DIVIL_LBAR_MFGPT, &basehi, &mfgpt_base); + + /* ack */ + outw(inw(MFGPT0_SETUP) | 0x4000, MFGPT0_SETUP); + + mfgpt_clockevent.event_handler(&mfgpt_clockevent); + + return IRQ_HANDLED; +} + +static struct irqaction irq5 = { + .handler = timer_interrupt, + .flags = IRQF_TIMER | IRQF_DISABLED | IRQF_NOBALANCING, + .name = "timer" +}; + +/* + * Initialize the conversion factor and the min/max deltas of the clock event + * structure and register the clock event source with the framework. + */ +void __init setup_mfgpt_timer(void) +{ + u32 basehi; + struct clock_event_device *cd = &mfgpt_clockevent; + unsigned int cpu = smp_processor_id(); + + cd->cpumask = cpumask_of(cpu); + clockevent_set_clock(cd, MFGPT_TICK_RATE); + cd->max_delta_ns = clockevent_delta2ns(0xffff, cd); + cd->min_delta_ns = clockevent_delta2ns(0xf, cd); + + /* Enable MFGPT0 Comparator 2 Output to the Interrupt Mapper */ + _wrmsr(CS5536_DIVIL_MSR_BASE + MFGPT_IRQ, 0, 0x100); + + /* Enable Interrupt Gate 5 */ + _wrmsr(CS5536_DIVIL_MSR_BASE + PIC_ZSEL_LOW, 0, 0x50000); + + /* get MFGPT base address */ + _rdmsr(CS5536_DIVIL_MSR_BASE + DIVIL_LBAR_MFGPT, &basehi, &mfgpt_base); + + irq5.mask = cpumask_of_cpu(cpu); + + clockevents_register_device(cd); + + setup_irq(CS5536_MFGPT_INTR, &irq5); +} + +/* + * Since the MFGPT overflows every tick, its not very useful + * to just read by itself. So use jiffies to emulate a free + * running counter: + */ +static cycle_t mfgpt_read(struct clocksource *cs) +{ + unsigned long flags; + int count; + u32 jifs; + static int old_count; + static u32 old_jifs; + + spin_lock_irqsave(&mfgpt_lock, flags); + /* + * Although our caller may have the read side of xtime_lock, + * this is now a seqlock, and we are cheating in this routine + * by having side effects on state that we cannot undo if + * there is a collision on the seqlock and our caller has to + * retry. (Namely, old_jifs and old_count.) So we must treat + * jiffies as volatile despite the lock. We read jiffies + * before latching the timer count to guarantee that although + * the jiffies value might be older than the count (that is, + * the counter may underflow between the last point where + * jiffies was incremented and the point where we latch the + * count), it cannot be newer. + */ + jifs = jiffies; + /* read the count */ + count = inw(MFGPT0_CNT); + + /* + * It's possible for count to appear to go the wrong way for this + * reason: + * + * The timer counter underflows, but we haven't handled the resulting + * interrupt and incremented jiffies yet. + * + * Previous attempts to handle these cases intelligently were buggy, so + * we just do the simple thing now. + */ + if (count < old_count && jifs == old_jifs) + count = old_count; + + old_count = count; + old_jifs = jifs; + + spin_unlock_irqrestore(&mfgpt_lock, flags); + + return (cycle_t) (jifs * COMPARE) + count; +} + +static struct clocksource clocksource_mfgpt = { + .name = "mfgpt", + .rating = 120, /* Functional for real use, but not desired */ + .read = mfgpt_read, + .mask = CLOCKSOURCE_MASK(32), + .mult = 0, + .shift = 22, +}; + +int __init init_mfgpt_clocksource(void) +{ + if (num_possible_cpus() > 1) /* MFGPT does not scale! */ + return 0; + + clocksource_mfgpt.mult = clocksource_hz2mult(MFGPT_TICK_RATE, 22); + return clocksource_register(&clocksource_mfgpt); +} + +arch_initcall(init_mfgpt_clocksource); diff -Nur linux-2.6.30.5.orig/arch/mips/loongson/common/cs5536/cs5536_ohci.c linux-2.6.30.5/arch/mips/loongson/common/cs5536/cs5536_ohci.c --- linux-2.6.30.5.orig/arch/mips/loongson/common/cs5536/cs5536_ohci.c 1970-01-01 01:00:00.000000000 +0100 +++ linux-2.6.30.5/arch/mips/loongson/common/cs5536/cs5536_ohci.c 2009-08-23 19:01:04.000000000 +0200 @@ -0,0 +1,168 @@ +/* + * the OHCI Virtual Support Module of AMD CS5536 + * + * Copyright (C) 2007 Lemote, Inc. & Institute of Computing Technology + * Author : jlliu, liujl@lemote.com + * + * Copyright (C) 2009 Lemote, Inc. & Institute of Computing Technology + * Author: Wu Zhangjin, wuzj@lemote.com + * + * 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. + */ + +#include +#include + +/* + * ohci_write : ohci write transfering. + */ +void pci_ohci_write_reg(int reg, u32 value) +{ + u32 hi = 0, lo = value; + + switch (reg) { + case PCI_COMMAND: + _rdmsr(USB_MSR_REG(USB_OHCI), &hi, &lo); + if (value & PCI_COMMAND_MASTER) + hi |= PCI_COMMAND_MASTER; + else + hi &= ~PCI_COMMAND_MASTER; + + if (value & PCI_COMMAND_MEMORY) + hi |= PCI_COMMAND_MEMORY; + else + hi &= ~PCI_COMMAND_MEMORY; + _wrmsr(USB_MSR_REG(USB_OHCI), hi, lo); + break; + case PCI_STATUS: + if (value & PCI_STATUS_PARITY) { + _rdmsr(SB_MSR_REG(SB_ERROR), &hi, &lo); + if (lo & SB_PARE_ERR_FLAG) { + lo = (lo & 0x0000ffff) | SB_PARE_ERR_FLAG; + _wrmsr(SB_MSR_REG(SB_ERROR), hi, lo); + } + } + break; + case PCI_BAR0_REG: + if (value == PCI_BAR_RANGE_MASK) { + _rdmsr(GLCP_MSR_REG(GLCP_SOFT_COM), &hi, &lo); + lo |= SOFT_BAR_OHCI_FLAG; + _wrmsr(GLCP_MSR_REG(GLCP_SOFT_COM), hi, lo); + } else if ((value & 0x01) == 0x00) { + _wrmsr(USB_MSR_REG(USB_OHCI), hi, lo); + + value &= 0xfffffff0; + hi = 0x40000000 | ((value & 0xff000000) >> 24); + lo = 0x000fffff | ((value & 0x00fff000) << 8); + _wrmsr(GLIU_MSR_REG(GLIU_P2D_BM3), hi, lo); + } + break; + case PCI_INTERRUPT_LINE: + value &= 0x000000ff; + break; + case PCI_OHCI_PM_REG: + break; + case PCI_OHCI_INT_REG: + _rdmsr(DIVIL_MSR_REG(PIC_YSEL_LOW), &hi, &lo); + lo &= ~(0xf << PIC_YSEL_LOW_USB_SHIFT); + if (value) /* enable all the usb interrupt in PIC */ + lo |= (CS5536_USB_INTR << PIC_YSEL_LOW_USB_SHIFT); + _wrmsr(DIVIL_MSR_REG(PIC_YSEL_LOW), hi, lo); + break; + default: + break; + } + + return; +} + +/* + * ohci_read : ohci read transfering. + */ +u32 pci_ohci_read_reg(int reg) +{ + u32 conf_data = 0; + u32 hi, lo; + + switch (reg) { + case PCI_VENDOR_ID: + conf_data = + CFG_PCI_VENDOR_ID(CS5536_OHCI_DEVICE_ID, CS5536_VENDOR_ID); + break; + case PCI_COMMAND: + _rdmsr(USB_MSR_REG(USB_OHCI), &hi, &lo); + if (hi & PCI_COMMAND_MASTER) + conf_data |= PCI_COMMAND_MASTER; + if (hi & PCI_COMMAND_MEMORY) + conf_data |= PCI_COMMAND_MEMORY; + break; + case PCI_STATUS: + conf_data |= PCI_STATUS_66MHZ; + conf_data |= PCI_STATUS_FAST_BACK; + _rdmsr(SB_MSR_REG(SB_ERROR), &hi, &lo); + if (lo & SB_PARE_ERR_FLAG) + conf_data |= PCI_STATUS_PARITY; + conf_data |= PCI_STATUS_DEVSEL_MEDIUM; + break; + case PCI_CLASS_REVISION: + _rdmsr(USB_MSR_REG(USB_CAP), &hi, &lo); + conf_data = lo & 0x000000ff; + conf_data |= (CS5536_OHCI_CLASS_CODE << 8); + break; + case PCI_CACHE_LINE_SIZE: + conf_data = + CFG_PCI_CACHE_LINE_SIZE(PCI_NORMAL_HEADER_TYPE, + PCI_NORMAL_LATENCY_TIMER); + break; + case PCI_BAR0_REG: + _rdmsr(GLCP_MSR_REG(GLCP_SOFT_COM), &hi, &lo); + if (lo & SOFT_BAR_OHCI_FLAG) { + conf_data = CS5536_OHCI_RANGE | + PCI_BASE_ADDRESS_SPACE_MEMORY; + lo &= ~SOFT_BAR_OHCI_FLAG; + _wrmsr(GLCP_MSR_REG(GLCP_SOFT_COM), hi, lo); + } else { + _rdmsr(USB_MSR_REG(USB_OHCI), &hi, &lo); + conf_data = lo & 0xffffff00; + conf_data &= ~0x0000000f; /* 32bit mem */ + } + break; + case PCI_BAR1_REG: + case PCI_BAR2_REG: + case PCI_BAR3_REG: + case PCI_BAR4_REG: + case PCI_BAR5_REG: + break; + case PCI_CARDBUS_CIS: + conf_data = PCI_CARDBUS_CIS_POINTER; + break; + case PCI_SUBSYSTEM_VENDOR_ID: + conf_data = + CFG_PCI_VENDOR_ID(CS5536_OHCI_SUB_ID, CS5536_SUB_VENDOR_ID); + break; + case PCI_ROM_ADDRESS: + conf_data = PCI_EXPANSION_ROM_BAR; + break; + case PCI_CAPABILITY_LIST: + conf_data = PCI_CAPLIST_USB_POINTER; + break; + case PCI_INTERRUPT_LINE: + conf_data = + CFG_PCI_INTERRUPT_LINE(PCI_DEFAULT_PIN, CS5536_USB_INTR); + break; + case PCI_OHCI_PM_REG: + break; + case PCI_OHCI_INT_REG: + _rdmsr(DIVIL_MSR_REG(PIC_YSEL_LOW), &hi, &lo); + if ((lo & 0x00000f00) == CS5536_USB_INTR) + conf_data = 1; + break; + default: + break; + } + + return conf_data; +} diff -Nur linux-2.6.30.5.orig/arch/mips/loongson/common/cs5536/cs5536_otg.c linux-2.6.30.5/arch/mips/loongson/common/cs5536/cs5536_otg.c --- linux-2.6.30.5.orig/arch/mips/loongson/common/cs5536/cs5536_otg.c 1970-01-01 01:00:00.000000000 +0100 +++ linux-2.6.30.5/arch/mips/loongson/common/cs5536/cs5536_otg.c 2009-08-23 19:01:04.000000000 +0200 @@ -0,0 +1,138 @@ +/* + * the OTG Virtual Support Module of AMD CS5536 + * + * Copyright (C) 2007 Lemote, Inc. & Institute of Computing Technology + * Author : jlliu, liujl@lemote.com + * + * Copyright (C) 2009 Lemote, Inc. & Institute of Computing Technology + * Author: Wu Zhangjin, wuzj@lemote.com + * + * 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. + */ + +#include +#include + +void pci_otg_write_reg(int reg, u32 value) +{ + u32 hi = 0, lo = value; + + switch (reg) { + case PCI_COMMAND: + _rdmsr(USB_MSR_REG(USB_OTG), &hi, &lo); + if (value & PCI_COMMAND_MEMORY) + hi |= PCI_COMMAND_MEMORY; + else + hi &= ~PCI_COMMAND_MEMORY; + _wrmsr(USB_MSR_REG(USB_OTG), hi, lo); + break; + case PCI_STATUS: + if (value & PCI_STATUS_PARITY) { + _rdmsr(SB_MSR_REG(SB_ERROR), &hi, &lo); + if (lo & SB_PARE_ERR_FLAG) { + lo = (lo & 0x0000ffff) | SB_PARE_ERR_FLAG; + _wrmsr(SB_MSR_REG(SB_ERROR), hi, lo); + } + } + break; + case PCI_BAR0_REG: + if (value == PCI_BAR_RANGE_MASK) { + _rdmsr(GLCP_MSR_REG(GLCP_SOFT_COM), &hi, &lo); + lo |= SOFT_BAR_OTG_FLAG; + _wrmsr(GLCP_MSR_REG(GLCP_SOFT_COM), hi, lo); + } else if ((value & 0x01) == 0x00) { + _rdmsr(USB_MSR_REG(USB_OTG), &hi, &lo); + lo &= 0xffffff00; + _wrmsr(USB_MSR_REG(USB_OTG), hi, lo); + + value &= 0xfffffff0; + hi = 0x40000000 | ((value & 0xff000000) >> 24); + lo = 0x000fffff | ((value & 0x00fff000) << 8); + _wrmsr(GLIU_MSR_REG(GLIU_P2D_BM1), hi, lo); + } + break; + default: + break; + } + + return; +} + +u32 pci_otg_read_reg(int reg) +{ + u32 conf_data = 0; + u32 hi, lo; + + switch (reg) { + case PCI_VENDOR_ID: + conf_data = + CFG_PCI_VENDOR_ID(CS5536_OTG_DEVICE_ID, CS5536_VENDOR_ID); + break; + case PCI_COMMAND: + _rdmsr(USB_MSR_REG(USB_OTG), &hi, &lo); + if (hi & PCI_COMMAND_MEMORY) + conf_data |= PCI_COMMAND_MEMORY; + break; + case PCI_STATUS: + conf_data |= PCI_STATUS_66MHZ; + conf_data |= PCI_STATUS_FAST_BACK; + _rdmsr(SB_MSR_REG(SB_ERROR), &hi, &lo); + if (lo & SB_PARE_ERR_FLAG) + conf_data |= PCI_STATUS_PARITY; + conf_data |= PCI_STATUS_DEVSEL_MEDIUM; + break; + case PCI_CLASS_REVISION: + _rdmsr(USB_MSR_REG(USB_CAP), &hi, &lo); + conf_data = lo & 0x000000ff; + conf_data |= (CS5536_OTG_CLASS_CODE << 8); + break; + case PCI_CACHE_LINE_SIZE: + conf_data = + CFG_PCI_CACHE_LINE_SIZE(PCI_NORMAL_HEADER_TYPE, + PCI_NORMAL_LATENCY_TIMER); + break; + case PCI_BAR0_REG: + _rdmsr(GLCP_MSR_REG(GLCP_SOFT_COM), &hi, &lo); + if (lo & SOFT_BAR_OTG_FLAG) { + conf_data = CS5536_OTG_RANGE | + PCI_BASE_ADDRESS_SPACE_MEMORY; + lo &= ~SOFT_BAR_OTG_FLAG; + _wrmsr(GLCP_MSR_REG(GLCP_SOFT_COM), hi, lo); + } else { + _rdmsr(USB_MSR_REG(USB_OTG), &hi, &lo); + conf_data = lo & 0xffffff00; + conf_data &= ~0x0000000f; + } + break; + case PCI_BAR1_REG: + case PCI_BAR2_REG: + case PCI_BAR3_REG: + case PCI_BAR4_REG: + case PCI_BAR5_REG: + break; + case PCI_CARDBUS_CIS: + conf_data = PCI_CARDBUS_CIS_POINTER; + break; + case PCI_SUBSYSTEM_VENDOR_ID: + conf_data = + CFG_PCI_VENDOR_ID(CS5536_OTG_SUB_ID, CS5536_SUB_VENDOR_ID); + break; + case PCI_ROM_ADDRESS: + conf_data = PCI_EXPANSION_ROM_BAR; + break; + case PCI_CAPABILITY_LIST: + conf_data = PCI_CAPLIST_USB_POINTER; + break; + case PCI_INTERRUPT_LINE: + conf_data = + CFG_PCI_INTERRUPT_LINE(PCI_DEFAULT_PIN, CS5536_USB_INTR); + break; + default: + break; + } + + return conf_data; +} diff -Nur linux-2.6.30.5.orig/arch/mips/loongson/common/cs5536/cs5536_pci.c linux-2.6.30.5/arch/mips/loongson/common/cs5536/cs5536_pci.c --- linux-2.6.30.5.orig/arch/mips/loongson/common/cs5536/cs5536_pci.c 1970-01-01 01:00:00.000000000 +0100 +++ linux-2.6.30.5/arch/mips/loongson/common/cs5536/cs5536_pci.c 2009-08-23 19:01:04.000000000 +0200 @@ -0,0 +1,126 @@ +/* + * read/write operation to the PCI config space of CS5536 + * + * Copyright (C) 2007 Lemote, Inc. & Institute of Computing Technology + * Author : jlliu, liujl@lemote.com + * + * Copyright (C) 2009 Lemote, Inc. & Institute of Computing Technology + * Author: Wu Zhangjin, wuzj@lemote.com + * + * 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. + * + * the Virtual Support Module(VSM) for virtulizing the PCI + * configure space are defined in cs5536_modulename.c respectively, + * so you can select modules which have been used in his/her board. + * to archive this, you just need to add a "select CS5536_[MODULE]" + * option in your board in arch/mips/loongson/Kconfig + * + * after this virtulizing, user can access the PCI configure space + * directly as a normal multi-function PCI device which following + * the PCI-2.2 spec. + */ + +#include +#include + +enum { + CS5536_FUNC_START = -1, + CS5536_ISA_FUNC, + CS5536_FLASH_FUNC, + CS5536_IDE_FUNC, + CS5536_ACC_FUNC, + CS5536_OHCI_FUNC, + CS5536_EHCI_FUNC, + CS5536_UDC_FUNC, + CS5536_OTG_FUNC, + CS5536_FUNC_END, +}; + +/* + * write to PCI config space and transfer it to MSR write. + */ +void cs5536_pci_conf_write4(int function, int reg, u32 value) +{ + if ((function <= CS5536_FUNC_START) || (function >= CS5536_FUNC_END)) + return; + if ((reg < 0) || (reg > 0x100) || ((reg & 0x03) != 0)) + return; + + switch (function) { + case CS5536_ISA_FUNC: + pci_isa_write_reg(reg, value); + break; + case CS5536_FLASH_FUNC: + pci_flash_write_reg(reg, value); + break; + case CS5536_IDE_FUNC: + pci_ide_write_reg(reg, value); + break; + case CS5536_ACC_FUNC: + pci_acc_write_reg(reg, value); + break; + case CS5536_OHCI_FUNC: + pci_ohci_write_reg(reg, value); + break; + case CS5536_EHCI_FUNC: + pci_ehci_write_reg(reg, value); + break; + case CS5536_UDC_FUNC: + pci_udc_write_reg(reg, value); + break; + case CS5536_OTG_FUNC: + pci_otg_write_reg(reg, value); + break; + default: + break; + } + return; +} + +/* + * read PCI config space and transfer it to MSR access. + */ +u32 cs5536_pci_conf_read4(int function, int reg) +{ + u32 data = 0; + + if ((function <= CS5536_FUNC_START) || (function >= CS5536_FUNC_END)) + return 0; + if ((reg < 0) || ((reg & 0x03) != 0)) + return 0; + if (reg > 0x100) + return 0xffffffff; + + switch (function) { + case CS5536_ISA_FUNC: + data = pci_isa_read_reg(reg); + break; + case CS5536_FLASH_FUNC: + data = pci_flash_read_reg(reg); + break; + case CS5536_IDE_FUNC: + data = pci_ide_read_reg(reg); + break; + case CS5536_ACC_FUNC: + data = pci_acc_read_reg(reg); + break; + case CS5536_OHCI_FUNC: + data = pci_ohci_read_reg(reg); + break; + case CS5536_EHCI_FUNC: + data = pci_ehci_read_reg(reg); + break; + case CS5536_UDC_FUNC: + data = pci_udc_read_reg(reg); + break; + case CS5536_OTG_FUNC: + data = pci_otg_read_reg(reg); + break; + default: + break; + } + return data; +} diff -Nur linux-2.6.30.5.orig/arch/mips/loongson/common/cs5536/cs5536_udc.c linux-2.6.30.5/arch/mips/loongson/common/cs5536/cs5536_udc.c --- linux-2.6.30.5.orig/arch/mips/loongson/common/cs5536/cs5536_udc.c 1970-01-01 01:00:00.000000000 +0100 +++ linux-2.6.30.5/arch/mips/loongson/common/cs5536/cs5536_udc.c 2009-08-23 19:01:04.000000000 +0200 @@ -0,0 +1,143 @@ +/* + * the UDC Virtual Support Module of AMD CS5536 + * + * Copyright (C) 2007 Lemote, Inc. & Institute of Computing Technology + * Author : jlliu, liujl@lemote.com + * + * Copyright (C) 2009 Lemote, Inc. & Institute of Computing Technology + * Author: Wu Zhangjin, wuzj@lemote.com + * + * 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. + */ + +#include +#include + +void pci_udc_write_reg(int reg, u32 value) +{ + u32 hi = 0, lo = value; + + switch (reg) { + case PCI_COMMAND: + _rdmsr(USB_MSR_REG(USB_UDC), &hi, &lo); + if (value & PCI_COMMAND_MASTER) + hi |= PCI_COMMAND_MASTER; + else + hi &= ~PCI_COMMAND_MASTER; + + if (value & PCI_COMMAND_MEMORY) + hi |= PCI_COMMAND_MEMORY; + else + hi &= ~PCI_COMMAND_MEMORY; + _wrmsr(USB_MSR_REG(USB_UDC), hi, lo); + break; + case PCI_STATUS: + if (value & PCI_STATUS_PARITY) { + _rdmsr(SB_MSR_REG(SB_ERROR), &hi, &lo); + if (lo & SB_PARE_ERR_FLAG) { + lo = (lo & 0x0000ffff) | SB_PARE_ERR_FLAG; + _wrmsr(SB_MSR_REG(SB_ERROR), hi, lo); + } + } + break; + case PCI_BAR0_REG: + if (value == PCI_BAR_RANGE_MASK) { + _rdmsr(GLCP_MSR_REG(GLCP_SOFT_COM), &hi, &lo); + lo |= SOFT_BAR_UDC_FLAG; + _wrmsr(GLCP_MSR_REG(GLCP_SOFT_COM), hi, lo); + } else if ((value & 0x01) == 0x00) { + _wrmsr(USB_MSR_REG(USB_UDC), hi, lo); + + value &= 0xfffffff0; + hi = 0x40000000 | ((value & 0xff000000) >> 24); + lo = 0x000fffff | ((value & 0x00fff000) << 8); + _wrmsr(GLIU_MSR_REG(GLIU_P2D_BM0), hi, lo); + } + break; + default: + break; + } + + return; +} + +u32 pci_udc_read_reg(int reg) +{ + u32 conf_data = 0; + u32 hi, lo; + + switch (reg) { + case PCI_VENDOR_ID: + conf_data = + CFG_PCI_VENDOR_ID(CS5536_UDC_DEVICE_ID, CS5536_VENDOR_ID); + break; + case PCI_COMMAND: + _rdmsr(USB_MSR_REG(USB_UDC), &hi, &lo); + if (hi & PCI_COMMAND_MASTER) + conf_data |= PCI_COMMAND_MASTER; + if (hi & PCI_COMMAND_MEMORY) + conf_data |= PCI_COMMAND_MEMORY; + break; + case PCI_STATUS: + conf_data |= PCI_STATUS_66MHZ; + conf_data |= PCI_STATUS_FAST_BACK; + _rdmsr(SB_MSR_REG(SB_ERROR), &hi, &lo); + if (lo & SB_PARE_ERR_FLAG) + conf_data |= PCI_STATUS_PARITY; + conf_data |= PCI_STATUS_DEVSEL_MEDIUM; + break; + case PCI_CLASS_REVISION: + _rdmsr(USB_MSR_REG(USB_CAP), &hi, &lo); + conf_data = lo & 0x000000ff; + conf_data |= (CS5536_UDC_CLASS_CODE << 8); + break; + case PCI_CACHE_LINE_SIZE: + conf_data = + CFG_PCI_CACHE_LINE_SIZE(PCI_NORMAL_HEADER_TYPE, + PCI_NORMAL_LATENCY_TIMER); + break; + case PCI_BAR0_REG: + _rdmsr(GLCP_MSR_REG(GLCP_SOFT_COM), &hi, &lo); + if (lo & SOFT_BAR_UDC_FLAG) { + conf_data = CS5536_UDC_RANGE | + PCI_BASE_ADDRESS_SPACE_MEMORY; + lo &= ~SOFT_BAR_UDC_FLAG; + _wrmsr(GLCP_MSR_REG(GLCP_SOFT_COM), hi, lo); + } else { + _rdmsr(USB_MSR_REG(USB_UDC), &hi, &lo); + conf_data = lo & 0xfffff000; + conf_data &= ~0x0000000f; /* 32bit mem */ + } + break; + case PCI_BAR1_REG: + case PCI_BAR2_REG: + case PCI_BAR3_REG: + case PCI_BAR4_REG: + case PCI_BAR5_REG: + break; + case PCI_CARDBUS_CIS: + conf_data = PCI_CARDBUS_CIS_POINTER; + break; + case PCI_SUBSYSTEM_VENDOR_ID: + conf_data = + CFG_PCI_VENDOR_ID(CS5536_UDC_SUB_ID, CS5536_SUB_VENDOR_ID); + break; + case PCI_ROM_ADDRESS: + conf_data = PCI_EXPANSION_ROM_BAR; + break; + case PCI_CAPABILITY_LIST: + conf_data = PCI_CAPLIST_USB_POINTER; + break; + case PCI_INTERRUPT_LINE: + conf_data = + CFG_PCI_INTERRUPT_LINE(PCI_DEFAULT_PIN, CS5536_USB_INTR); + break; + default: + break; + } + + return conf_data; +} diff -Nur linux-2.6.30.5.orig/arch/mips/loongson/common/cs5536/Makefile linux-2.6.30.5/arch/mips/loongson/common/cs5536/Makefile --- linux-2.6.30.5.orig/arch/mips/loongson/common/cs5536/Makefile 1970-01-01 01:00:00.000000000 +0100 +++ linux-2.6.30.5/arch/mips/loongson/common/cs5536/Makefile 2009-08-23 19:01:04.000000000 +0200 @@ -0,0 +1,25 @@ +# +# Makefile for CS5536 support. +# + +# +# core modules +# +obj-$(CONFIG_CS5536) += cs5536_pci.o cs5536_ide.o cs5536_acc.o cs5536_ohci.o \ + cs5536_isa.o cs5536_ehci.o +# +# selective modules +# +# add a CS5536_[MODULE] to your board in arch/mips/loongson/Kconfig +# +obj-$(CONFIG_CS5536_FLASH) += cs5536_flash.o +obj-$(CONFIG_CS5536_NOR_FLASH) += cs5536_flash.o +obj-$(CONFIG_CS5536_OTG) += cs5536_otg.o +obj-$(CONFIG_CS5536_UDC) += cs5536_udc.o + +# +# Enable cs5536 mfgpt Timer +# +obj-$(CONFIG_CS5536_MFGPT) += cs5536_mfgpt.o + +EXTRA_CFLAGS += -Werror diff -Nur linux-2.6.30.5.orig/arch/mips/loongson/common/dbg.c linux-2.6.30.5/arch/mips/loongson/common/dbg.c --- linux-2.6.30.5.orig/arch/mips/loongson/common/dbg.c 1970-01-01 01:00:00.000000000 +0100 +++ linux-2.6.30.5/arch/mips/loongson/common/dbg.c 2009-08-23 19:01:04.000000000 +0200 @@ -0,0 +1,34 @@ +/* + * Copyright (C) 2009 Lemote Inc. & Insititute of Computing Technology + * + * 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. + */ + +#include +#include + +#define PROM_PRINTF_BUF_LEN 1024 + +void prom_printf(char *fmt, ...) +{ + static char buf[PROM_PRINTF_BUF_LEN]; + va_list args; + char *ptr; + + + va_start(args, fmt); + vscnprintf(buf, sizeof(buf), fmt, args); + + ptr = buf; + + while (*ptr != 0) { + if (*ptr == '\n') + prom_putchar('\r'); + + prom_putchar(*ptr++); + } + va_end(args); +} diff -Nur linux-2.6.30.5.orig/arch/mips/loongson/common/early_printk.c linux-2.6.30.5/arch/mips/loongson/common/early_printk.c --- linux-2.6.30.5.orig/arch/mips/loongson/common/early_printk.c 1970-01-01 01:00:00.000000000 +0100 +++ linux-2.6.30.5/arch/mips/loongson/common/early_printk.c 2009-08-23 19:01:04.000000000 +0200 @@ -0,0 +1,28 @@ +/* early printk support + * + * Copyright (c) 2009 Philippe Vachon + * + * 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. + */ + +#include +#include + +#include +#include + +void prom_putchar(char c) +{ + int timeout; + phys_addr_t uart_base = + (phys_addr_t) ioremap_nocache(LOONGSON_UART_BASE, 8); + char reg = readb((u8 *) (uart_base + UART_LSR)) & UART_LSR_THRE; + + for (timeout = 1024; reg == 0 && timeout > 0; timeout--) + reg = readb((u8 *) (uart_base + UART_LSR)) & UART_LSR_THRE; + + writeb(c, (u8 *) (uart_base + UART_TX)); +} diff -Nur linux-2.6.30.5.orig/arch/mips/loongson/common/env.c linux-2.6.30.5/arch/mips/loongson/common/env.c --- linux-2.6.30.5.orig/arch/mips/loongson/common/env.c 1970-01-01 01:00:00.000000000 +0100 +++ linux-2.6.30.5/arch/mips/loongson/common/env.c 2009-08-23 19:01:04.000000000 +0200 @@ -0,0 +1,59 @@ +/* + * Based on Ocelot Linux port, which is + * Copyright 2001 MontaVista Software Inc. + * Author: jsun@mvista.com or jsun@junsun.net + * + * Copyright 2003 ICT CAS + * Author: Michael Guo + * + * Copyright (C) 2007 Lemote Inc. & Insititute of Computing Technology + * Author: Fuxin Zhang, zhangfx@lemote.com + * + * Copyright (C) 2009 Lemote Inc. & Insititute of Computing Technology + * Author: Wu Zhangjin, wuzj@lemote.com + * + * 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. + */ + +#include + +#include + +unsigned long bus_clock, cpu_clock_freq; +unsigned long memsize, highmemsize; + +/* pmon passes arguments in 32bit pointers */ +int *_prom_envp; + +#define parse_even_earlier(res, option, p) \ +do { \ + if (strncmp(option, (char *)p, strlen(option)) == 0) \ + strict_strtol((char *)p + strlen(option"="), \ + 10, &res); \ +} while (0) + +void __init prom_init_env(void) +{ + long l; + + /* firmware arguments are initialized in head.S */ + _prom_envp = (int *)fw_arg2; + + l = (long)*_prom_envp; + while (l != 0) { + parse_even_earlier(bus_clock, "busclock", l); + parse_even_earlier(cpu_clock_freq, "cpuclock", l); + parse_even_earlier(memsize, "memsize", l); + parse_even_earlier(highmemsize, "highmemsize", l); + _prom_envp++; + l = (long)*_prom_envp; + } + if (memsize == 0) + memsize = 256; + + pr_info("busclock=%ld, cpuclock=%ld, memsize=%ld, highmemsize=%ld\n", + bus_clock, cpu_clock_freq, memsize, highmemsize); +} diff -Nur linux-2.6.30.5.orig/arch/mips/loongson/common/init.c linux-2.6.30.5/arch/mips/loongson/common/init.c --- linux-2.6.30.5.orig/arch/mips/loongson/common/init.c 1970-01-01 01:00:00.000000000 +0100 +++ linux-2.6.30.5/arch/mips/loongson/common/init.c 2009-08-23 19:01:04.000000000 +0200 @@ -0,0 +1,65 @@ +/* + * Based on Ocelot Linux port, which is + * Copyright 2001 MontaVista Software Inc. + * Author: jsun@mvista.com or jsun@junsun.net + * + * Copyright 2003 ICT CAS + * Author: Michael Guo + * + * Copyright (C) 2007 Lemote Inc. & Insititute of Computing Technology + * Author: Fuxin Zhang, zhangfx@lemote.com + * + * 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. + */ + +#include + +#include +#include + +#include + +#if defined(CONFIG_CPU_LOONGSON2F) && defined(CONFIG_64BIT) +unsigned long _loongson_addrwincfg_base; + +/* Loongson CPU address windows config space base address */ +static inline void set_loongson_addrwincfg_base(unsigned long base) +{ + *(unsigned long *)&_loongson_addrwincfg_base = base; + barrier(); +} +#endif + +/* stop all perf counters by default + * $24 is the control register of loongson perf counter + */ +static inline void stop_perf_counters(void) +{ + __write_64bit_c0_register($24, 0, 0); +} + +void __init prom_init(void) +{ + /* init several base address */ + set_io_port_base((unsigned long) + ioremap(LOONGSON_PCIIO_BASE, LOONGSON_PCIIO_SIZE)); + +#if defined(CONFIG_CPU_LOONGSON2F) && defined(CONFIG_64BIT) + set_loongson_addrwincfg_base((unsigned long) + ioremap(LOONGSON_ADDRWINCFG_BASE, + LOONGSON_ADDRWINCFG_SIZE)); +#endif + /* stop all perf counters */ + stop_perf_counters(); + + prom_init_cmdline(); + prom_init_env(); + prom_init_memory(); +} + +void __init prom_free_prom_memory(void) +{ +} diff -Nur linux-2.6.30.5.orig/arch/mips/loongson/common/irq.c linux-2.6.30.5/arch/mips/loongson/common/irq.c --- linux-2.6.30.5.orig/arch/mips/loongson/common/irq.c 1970-01-01 01:00:00.000000000 +0100 +++ linux-2.6.30.5/arch/mips/loongson/common/irq.c 2009-08-23 19:01:04.000000000 +0200 @@ -0,0 +1,120 @@ +/* + * Copyright 2001 MontaVista Software Inc. + * Author: Jun Sun, jsun@mvista.com or jsun@junsun.net + * Copyright (C) 2000, 2001 Ralf Baechle (ralf@gnu.org) + * + * Copyright (C) 2007 Lemote Inc. & Insititute of Computing Technology + * Author: Fuxin Zhang, zhangfx@lemote.com + * + * 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. + */ + +#include +#include + +#include +#include + +#include +#include + +/* + * the first level int-handler will jump here if it is a loongson irq + */ +void bonito_irqdispatch(void) +{ + u32 int_status; + int i; + + /* workaround the IO dma problem: let cpu looping to allow DMA finish */ + int_status = LOONGSON_INTISR; + while (int_status & (1 << 10)) { + udelay(1); + int_status = LOONGSON_INTISR; + } + + /* Get pending sources, masked by current enables */ + int_status = LOONGSON_INTISR & LOONGSON_INTEN; + + if (int_status != 0) { + i = __ffs(int_status); + int_status &= ~(1 << i); + do_IRQ(LOONGSON_IRQ_BASE + i); + } +} + +void i8259_irqdispatch(void) +{ + int irq; + + irq = mach_i8259_irq(); + if (irq < 0) + spurious_interrupt(); + else + do_IRQ(irq); +} + +asmlinkage void plat_irq_dispatch(void) +{ + unsigned int pending = read_c0_cause() & read_c0_status() & ST0_IM; + + mach_irq_dispatch(pending); +} + + +static struct irqaction cascade_irqaction = { + .handler = no_action, + .name = "cascade", +}; + +irqreturn_t ip6_action(int cpl, void *dev_id) +{ + return IRQ_HANDLED; +} + +static struct irqaction ip6_irqaction = { + .handler = ip6_action, + .name = "cascade", + .flags = IRQF_SHARED, +}; + +void __init arch_init_irq(void) +{ + /* + * Clear all of the interrupts while we change the able around a bit. + * int-handler is not on bootstrap + */ + clear_c0_status(ST0_IM | ST0_BEV); + local_irq_disable(); + + /* setting irq trigger mode */ + set_irq_trigger_mode(); + + /* no steer */ + LOONGSON_INTSTEER = 0; + + /* + * Mask out all interrupt by writing "1" to all bit position in + * the interrupt reset reg. + */ + LOONGSON_INTENCLR = ~0; + + /* init all controller + * 0-15 ------> i8259 interrupt + * 16-23 ------> mips cpu interrupt + * 32-63 ------> bonito irq + */ + + /* Sets the first-level interrupt dispatcher. */ + mips_cpu_irq_init(); + init_i8259_irqs(); + bonito_irq_init(); + + /* setup north bridge irq (bonito) */ + setup_irq(LOONGSON_NORTH_BRIDGE_IRQ, &ip6_irqaction); + /* setup source bridge irq (i8259) */ + setup_irq(LOONGSON_SOUTH_BRIDGE_IRQ, &cascade_irqaction); +} diff -Nur linux-2.6.30.5.orig/arch/mips/loongson/common/machtype.c linux-2.6.30.5/arch/mips/loongson/common/machtype.c --- linux-2.6.30.5.orig/arch/mips/loongson/common/machtype.c 1970-01-01 01:00:00.000000000 +0100 +++ linux-2.6.30.5/arch/mips/loongson/common/machtype.c 2009-08-23 19:01:04.000000000 +0200 @@ -0,0 +1,50 @@ +/* + * Copyright (C) 2009 Lemote Inc. & Insititute of Computing Technology + * Author: Wu Zhangjin, wuzj@lemote.com + * + * Copyright (c) 2009 Zhang Le + * + * 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. + */ + +#include +#include + +#include +#include + +static const char *system_types[] = { + [MACH_LOONGSON_UNKNOWN] "unknown loongson machine", + [MACH_LEMOTE_FL2E] "lemote-fuloong-2e-box", + [MACH_LEMOTE_FL2F] "lemote-fuloong-2f-box", + [MACH_LEMOTE_YL2F89] "lemote-yeeloong-2f-8.9inches", + [MACH_LEMOTE_YL2F7] "lemote-yeeloong-2f-7inches", + [MACH_LOONGSON_END] NULL, +}; + +const char *get_system_type(void) +{ + if (mips_machtype == MACH_UNKNOWN) + mips_machtype = MACHTYPE; + + return system_types[mips_machtype]; +} + +static __init int machtype_setup(char *str) +{ + int machtype = MACH_LEMOTE_FL2E; + + if (!str) + return -EINVAL; + + for (; system_types[machtype]; machtype++) + if (strstr(system_types[machtype], str)) { + mips_machtype = machtype; + break; + } + return 0; +} +__setup("machtype=", machtype_setup); diff -Nur linux-2.6.30.5.orig/arch/mips/loongson/common/Makefile linux-2.6.30.5/arch/mips/loongson/common/Makefile --- linux-2.6.30.5.orig/arch/mips/loongson/common/Makefile 1970-01-01 01:00:00.000000000 +0100 +++ linux-2.6.30.5/arch/mips/loongson/common/Makefile 2009-08-23 19:01:04.000000000 +0200 @@ -0,0 +1,37 @@ +# +# Makefile for loongson based machines. +# + +obj-y += setup.o init.o cmdline.o env.o time.o reset.o irq.o \ + pci.o bonito-irq.o mem.o machtype.o + +# +# Early printk support +# +obj-$(CONFIG_EARLY_PRINTK) += early_printk.o dbg.o + +# +# Enable RTC Class support +# +# please enable CONFIG_RTC_DRV_CMOS +# +obj-$(CONFIG_RTC_DRV_CMOS) += rtc.o + +# +# Enable CS5536 Virtual Support Module(VSM) for virtulize the PCI configure +# space +# +obj-$(CONFIG_CS5536) += cs5536/ + +# +# Enable fuloong(2f) and yeeloong(2f) cpu frequency scaling support +# This is based on CS5536 mfgpt timer +# +obj-$(CONFIG_LOONGSON2F_CPU_FREQ) += clock.o + +# +# Enable serial port +# +obj-$(CONFIG_SERIAL_8250) += serial.o + +EXTRA_CFLAGS += -Werror diff -Nur linux-2.6.30.5.orig/arch/mips/loongson/common/mem.c linux-2.6.30.5/arch/mips/loongson/common/mem.c --- linux-2.6.30.5.orig/arch/mips/loongson/common/mem.c 1970-01-01 01:00:00.000000000 +0100 +++ linux-2.6.30.5/arch/mips/loongson/common/mem.c 2009-08-23 19:01:04.000000000 +0200 @@ -0,0 +1,116 @@ +/* + * 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. + */ + +#include +#include + +#include + +#include +#include + +void __init prom_init_memory(void) +{ + add_memory_region(0x0, (memsize << 20), BOOT_MEM_RAM); +#ifdef CONFIG_64BIT +#ifdef CONFIG_CPU_LOONGSON2F + { + int bit; + + bit = fls(memsize + highmemsize); + if (bit != ffs(memsize + highmemsize)) + bit += 20; + else + bit = bit + 20 - 1; + + /* set cpu window3 to map CPU to DDR: 2G -> 2G */ + LOONGSON_ADDRWIN_CPUTODDR(ADDRWIN_WIN3, 0x80000000ul, + 0x80000000ul, (1 << bit)); + mmiowb(); + } +#endif /* CONFIG_CPU_LOONGSON2F */ + + if (highmemsize > 0) { + add_memory_region(LOONGSON_HIGHMEM_START, + highmemsize << 20, BOOT_MEM_RAM); + } +#endif /* CONFIG_64BIT */ +} + +/* override of arch/mips/mm/cache.c: __uncached_access */ +int __uncached_access(struct file *file, unsigned long addr) +{ + if (file->f_flags & O_SYNC) + return 1; + + return addr >= __pa(high_memory) || + ((addr >= LOONGSON_MMIO_MEM_START) && \ + (addr < LOONGSON_MMIO_MEM_END)); +} + +#if defined(CONFIG_CPU_LOONGSON2F) + +#include +#include +#include + +static unsigned long uca_start; +static unsigned long uca_size = CONFIG_UCA_SIZE; + +pgprot_t phys_mem_access_prot(struct file *file, unsigned long pfn, + unsigned long size, pgprot_t vma_prot) +{ + unsigned long offset = pfn << PAGE_SHIFT; + unsigned long end = offset + size; + + if (__uncached_access(file, offset)) { + if (((uca_start && offset) >= uca_start) && \ + (end <= (uca_start + uca_size))) + return __pgprot((pgprot_val(vma_prot) & \ + ~_CACHE_MASK) | \ + _CACHE_UNCACHED_ACCELERATED); + else + return pgprot_noncached(vma_prot); + } + return vma_prot; +} + +static int __init find_vga_mem_init(void) +{ + struct pci_dev *dev = 0; + struct resource *r; + int idx; + + if (uca_start) + return 0; + + for_each_pci_dev(dev) { + if ((dev->class >> 8) == PCI_CLASS_DISPLAY_VGA) { + for (idx = 0; idx < PCI_NUM_RESOURCES; idx++) { + r = &dev->resource[idx]; + if (!r->start && r->end) + continue; + if (r->flags & IORESOURCE_IO) + continue; + if (r->flags & IORESOURCE_MEM) { + uca_start = r->start; + + printk(KERN_INFO + "find the frame buffer:start=%lx\n", + uca_start); + + return 0; + } + } + + } + } + return 0; +} + +late_initcall(find_vga_mem_init); +#endif /* !CONFIG_CPU_LOONGSON2F */ diff -Nur linux-2.6.30.5.orig/arch/mips/loongson/common/pci.c linux-2.6.30.5/arch/mips/loongson/common/pci.c --- linux-2.6.30.5.orig/arch/mips/loongson/common/pci.c 1970-01-01 01:00:00.000000000 +0100 +++ linux-2.6.30.5/arch/mips/loongson/common/pci.c 2009-08-23 19:01:04.000000000 +0200 @@ -0,0 +1,109 @@ +/* + * Copyright (C) 2007 Lemote, Inc. & Institute of Computing Technology + * Author: Fuxin Zhang, zhangfx@lemote.com + * + * 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 SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN + * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * 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., + * 675 Mass Ave, Cambridge, MA 02139, USA. + * + */ + +#include + +#include +#include + +static struct resource loongson_pci_mem_resource = { + .name = "pci memory space", + .start = LOONGSON_PCI_MEM_START, + .end = LOONGSON_PCI_MEM_END, + .flags = IORESOURCE_MEM, +}; + +static struct resource loongson_pci_io_resource = { + .name = "pci io space", + .start = LOONGSON_PCI_IO_START, /* reserve regacy I/O space */ + .end = IO_SPACE_LIMIT, + .flags = IORESOURCE_IO, +}; + +static struct pci_controller loongson_pci_controller = { + .pci_ops = &loongson_pci_ops, + .io_resource = &loongson_pci_io_resource, + .mem_resource = &loongson_pci_mem_resource, + .mem_offset = 0x00000000UL, + .io_offset = 0x00000000UL, +}; + +static void __init ict_pcimap(void) +{ + /* + * local to PCI mapping for CPU accessing PCI space + * + * CPU address space [256M,448M] is window for accessing pci space + * we set pcimap_lo[0,1,2] to map it to pci space[0M,64M], [320M,448M] + * + * pcimap: PCI_MAP2 PCI_Mem_Lo2 PCI_Mem_Lo1 PCI_Mem_Lo0 + * [<2G] [384M,448M] [320M,384M] [0M,64M] + */ + LOONGSON_PCIMAP = LOONGSON_PCIMAP_PCIMAP_2 | + LOONGSON_PCIMAP_WIN(2, 0x18000000) | + LOONGSON_PCIMAP_WIN(1, 0x14000000) | + LOONGSON_PCIMAP_WIN(0, 0); + + /* + * PCI-DMA to local mapping: [2G,2G+256M] -> [0M,256M] + */ + LOONGSON_PCIBASE0 = 0x80000000ul; /* base: 2G -> mmap: 0M */ + /* size: 256M, burst transmission, pre-fetch enable, 64bit */ + LOONGSON_PCI_HIT0_SEL_L = 0xc000000cul; + LOONGSON_PCI_HIT0_SEL_H = 0xfffffffful; + LOONGSON_PCI_HIT1_SEL_L = 0x00000006ul; /* set this BAR as invalid */ + LOONGSON_PCI_HIT1_SEL_H = 0x00000000ul; + LOONGSON_PCI_HIT2_SEL_L = 0x00000006ul; /* set this BAR as invalid */ + LOONGSON_PCI_HIT2_SEL_H = 0x00000000ul; + + /* avoid deadlock of PCI reading/writing lock operation */ + LOONGSON_PCI_ISR4C = 0xd2000001ul; + + /* can not change gnt to break pci transfer when device's gnt not + deassert for some broken device */ + LOONGSON_PXARB_CFG = 0x00fe0105ul; + +#if defined(CONFIG_CPU_LOONGSON2F) && defined(CONFIG_64BIT) + /* + * set cpu addr window2 to map CPU address space to PCI address space + */ + LOONGSON_ADDRWIN_CPUTOPCI(ADDRWIN_WIN2, LOONGSON_CPU_MEM_SRC, + LOONGSON_PCI_MEM_DST, MMAP_CPUTOPCI_SIZE); +#endif +} + +static int __init pcibios_init(void) +{ + ict_pcimap(); + + loongson_pci_controller.io_map_base = mips_io_port_base; + + register_pci_controller(&loongson_pci_controller); + + return 0; +} + +arch_initcall(pcibios_init); diff -Nur linux-2.6.30.5.orig/arch/mips/loongson/common/reset.c linux-2.6.30.5/arch/mips/loongson/common/reset.c --- linux-2.6.30.5.orig/arch/mips/loongson/common/reset.c 1970-01-01 01:00:00.000000000 +0100 +++ linux-2.6.30.5/arch/mips/loongson/common/reset.c 2009-08-23 19:01:04.000000000 +0200 @@ -0,0 +1,38 @@ +/* + * 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. + * + * Copyright (C) 2007 Lemote, Inc. & Institute of Computing Technology + * Author: Fuxin Zhang, zhangfx@lemote.com + */ + +#include + +#include + +#include + +static void loongson_restart(char *command) +{ + /* perform board-specific pre-reboot operations */ + mach_prepare_reboot(); + + /* reboot via jumping to 0xbfc00000 */ + ((void (*)(void))ioremap_nocache(LOONGSON_BOOT_BASE, 4)) (); +} + +static void loongson_halt(void) +{ + mach_prepare_shutdown(); + while (1) + ; +} + +void __init loongson_reboot_setup(void) +{ + _machine_restart = loongson_restart; + _machine_halt = loongson_halt; + pm_power_off = loongson_halt; +} diff -Nur linux-2.6.30.5.orig/arch/mips/loongson/common/rtc.c linux-2.6.30.5/arch/mips/loongson/common/rtc.c --- linux-2.6.30.5.orig/arch/mips/loongson/common/rtc.c 1970-01-01 01:00:00.000000000 +0100 +++ linux-2.6.30.5/arch/mips/loongson/common/rtc.c 2009-08-23 19:01:04.000000000 +0200 @@ -0,0 +1,54 @@ +/* + * Registration of Cobalt RTC platform device. + * + * Copyright (C) 2007 Yoichi Yuasa + * Copyright (C) 2009 Wu Zhangjin + * + * 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., 51 Franklin Street, Fifth Floor, Boston, + * MA 02110-1301 USA + */ + +#include +#include +#include + +static struct resource rtc_cmos_resource[] = { + { + .start = RTC_PORT(0), + .end = RTC_PORT(1), + .flags = IORESOURCE_IO, + }, + { + .start = RTC_IRQ, + .end = RTC_IRQ, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct platform_device rtc_cmos_device = { + .name = "rtc_cmos", + .id = -1, + .num_resources = ARRAY_SIZE(rtc_cmos_resource), + .resource = rtc_cmos_resource +}; + +static __init int rtc_cmos_init(void) +{ + platform_device_register(&rtc_cmos_device); + + return 0; +} + +device_initcall(rtc_cmos_init); diff -Nur linux-2.6.30.5.orig/arch/mips/loongson/common/serial.c linux-2.6.30.5/arch/mips/loongson/common/serial.c --- linux-2.6.30.5.orig/arch/mips/loongson/common/serial.c 1970-01-01 01:00:00.000000000 +0100 +++ linux-2.6.30.5/arch/mips/loongson/common/serial.c 2009-08-23 19:01:04.000000000 +0200 @@ -0,0 +1,66 @@ +/* + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + * + * Copyright (C) 2007 Ralf Baechle (ralf@linux-mips.org) + * + * Copyright (C) 2009 Lemote, Inc. & Institute of Computing Technology + * Author: yanhua (yanhua@lemote.com) + * Author: Wu Zhangjin (wuzj@lemote.com) + */ + +#include +#include +#include + +#include +#include + +#define PORT(int, base_baud, io_type) \ +{ \ + .irq = int, \ + .uartclk = base_baud, \ + .iotype = io_type, \ + .flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST, \ + .regshift = 0, \ +} + +static struct plat_serial8250_port uart8250_data[] = { + PORT(LOONGSON_UART_IRQ, LOONGSON_UART_BAUD, LOONGSON_UART_IOTYPE), + {}, +}; + +static struct platform_device uart8250_device = { + .name = "serial8250", + .id = PLAT8250_DEV_PLATFORM, + .dev = { + .platform_data = uart8250_data, + }, +}; + +static inline void uart8250_init(void) +{ +#if (LOONGSON_UART_IOTYPE == UPIO_MEM) + uart8250_data[0].membase = + ioremap_nocache(LOONGSON_UART_BASE, 8); +#elif (LOONGSON_UART_IOTYPE == UPIO_PORT) + uart8250_data[0].iobase = + LOONGSON_UART_BASE - LOONGSON_PCIIO_BASE; + uart8250_data[0].irq -= MIPS_CPU_IRQ_BASE; +#else +#warning currently, no such iotype of uart used in loongson-based machines + +#endif +} + +static int __init serial_init(void) +{ + uart8250_init(); + + platform_device_register(&uart8250_device); + + return 0; +} + +device_initcall(serial_init); diff -Nur linux-2.6.30.5.orig/arch/mips/loongson/common/setup.c linux-2.6.30.5/arch/mips/loongson/common/setup.c --- linux-2.6.30.5.orig/arch/mips/loongson/common/setup.c 1970-01-01 01:00:00.000000000 +0100 +++ linux-2.6.30.5/arch/mips/loongson/common/setup.c 2009-08-23 19:01:04.000000000 +0200 @@ -0,0 +1,74 @@ +/* + * board dependent setup routines + * + * Copyright (C) 2007 Lemote Inc. & Insititute of Computing Technology + * Author: Fuxin Zhang, zhangfx@lemote.com + * + * Copyright (C) 2009 Lemote Inc. & Insititute of Computing Technology + * Author: Wu Zhangjin, wuzj@lemote.com + * + * 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. + */ + +#include + +#include + +#include + +void (*__wbflush) (void); +EXPORT_SYMBOL(__wbflush); + +static void loongson_wbflush(void) +{ + asm(".set\tpush\n\t" + ".set\tnoreorder\n\t" + ".set mips3\n\t" + "sync\n\t" + "nop\n\t" + ".set\tpop\n\t" + ".set mips0\n\t"); +} + +void __init loongson_wbflush_setup(void) +{ + __wbflush = loongson_wbflush; +} + +#if defined(CONFIG_VT) && defined(CONFIG_VGA_CONSOLE) +#include + +void __init loongson_screeninfo_setup(void) +{ + screen_info = (struct screen_info) { + 0, /* orig-x */ + 25, /* orig-y */ + 0, /* unused */ + 0, /* orig-video-page */ + 0, /* orig-video-mode */ + 80, /* orig-video-cols */ + 0, /* ega_ax */ + 0, /* ega_bx */ + 0, /* ega_cx */ + 25, /* orig-video-lines */ + VIDEO_TYPE_VGAC, /* orig-video-isVGA */ + 16 /* orig-video-points */ + }; +} +#else +void __init loongson_screeninfo_setup(void) +{ +} +#endif + +void __init plat_mem_setup(void) +{ + loongson_reboot_setup(); + + loongson_wbflush_setup(); + + loongson_screeninfo_setup(); +} diff -Nur linux-2.6.30.5.orig/arch/mips/loongson/common/time.c linux-2.6.30.5/arch/mips/loongson/common/time.c --- linux-2.6.30.5.orig/arch/mips/loongson/common/time.c 1970-01-01 01:00:00.000000000 +0100 +++ linux-2.6.30.5/arch/mips/loongson/common/time.c 2009-08-23 19:01:04.000000000 +0200 @@ -0,0 +1,34 @@ +/* + * board dependent boot routines + * + * Copyright (C) 2007 Lemote Inc. & Insititute of Computing Technology + * Author: Fuxin Zhang, zhangfx@lemote.com + * + * 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. + */ + +#include +#include + +#include +#ifdef CONFIG_CS5536_MFGPT +#include +#endif + +unsigned long read_persistent_clock(void) +{ + return mc146818_get_cmos_time(); +} + +void __init plat_time_init(void) +{ + /* setup mips r4k timer */ + mips_hpt_frequency = cpu_clock_freq / 2; + +#ifdef CONFIG_CS5536_MFGPT + setup_mfgpt_timer(); +#endif +} diff -Nur linux-2.6.30.5.orig/arch/mips/loongson/fuloong-2e/irq.c linux-2.6.30.5/arch/mips/loongson/fuloong-2e/irq.c --- linux-2.6.30.5.orig/arch/mips/loongson/fuloong-2e/irq.c 1970-01-01 01:00:00.000000000 +0100 +++ linux-2.6.30.5/arch/mips/loongson/fuloong-2e/irq.c 2009-08-23 19:01:04.000000000 +0200 @@ -0,0 +1,58 @@ +/* + * Copyright (C) 2007 Lemote Inc. & Insititute of Computing Technology + * Author: Fuxin Zhang, zhangfx@lemote.com + * + * 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 SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN + * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * 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., + * 675 Mass Ave, Cambridge, MA 02139, USA. + * + */ + +#include + +#include + +#include +#include + +int mach_i8259_irq(void) +{ + return i8259_irq(); +} + +void mach_irq_dispatch(unsigned int pending) +{ + if (pending & CAUSEF_IP7) + do_IRQ(LOONGSON_TIMER_IRQ); + else if (pending & CAUSEF_IP6) /* perf counter loverflow */ + do_IRQ(LOONGSON_PERFCNT_IRQ); + else if (pending & CAUSEF_IP5) + i8259_irqdispatch(); + else if (pending & CAUSEF_IP2) + bonito_irqdispatch(); + else + spurious_interrupt(); +} + +void __init set_irq_trigger_mode(void) +{ + /* most bonito irq should be level triggered */ + LOONGSON_INTEDGE = LOONGSON_ICU_SYSTEMERR | LOONGSON_ICU_MASTERERR | + LOONGSON_ICU_RETRYERR | LOONGSON_ICU_MBOXES; +} diff -Nur linux-2.6.30.5.orig/arch/mips/loongson/fuloong-2e/Makefile linux-2.6.30.5/arch/mips/loongson/fuloong-2e/Makefile --- linux-2.6.30.5.orig/arch/mips/loongson/fuloong-2e/Makefile 1970-01-01 01:00:00.000000000 +0100 +++ linux-2.6.30.5/arch/mips/loongson/fuloong-2e/Makefile 2009-08-23 19:01:04.000000000 +0200 @@ -0,0 +1,7 @@ +# +# Makefile for fuloong-2e +# + +obj-y += irq.o reset.o + +EXTRA_CFLAGS += -Werror diff -Nur linux-2.6.30.5.orig/arch/mips/loongson/fuloong-2e/reset.c linux-2.6.30.5/arch/mips/loongson/fuloong-2e/reset.c --- linux-2.6.30.5.orig/arch/mips/loongson/fuloong-2e/reset.c 1970-01-01 01:00:00.000000000 +0100 +++ linux-2.6.30.5/arch/mips/loongson/fuloong-2e/reset.c 2009-08-23 19:01:04.000000000 +0200 @@ -0,0 +1,26 @@ +/* Board-specific reboot/shutdown routines + * Copyright (c) 2009 Philippe Vachon + * + * Copyright (C) 2009 Lemote Inc. & Insititute of Computing Technology + * Author: Wu Zhangjin, wuzj@lemote.com + * + * 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. + */ + +#include +#include + +#include + +void mach_prepare_reboot(void) +{ + LOONGSON_GENCFG &= ~LOONGSON_GENCFG_CPUSELFRESET; + LOONGSON_GENCFG |= LOONGSON_GENCFG_CPUSELFRESET; +} + +void mach_prepare_shutdown(void) +{ +} diff -Nur linux-2.6.30.5.orig/arch/mips/loongson/fuloong-2f/irq.c linux-2.6.30.5/arch/mips/loongson/fuloong-2f/irq.c --- linux-2.6.30.5.orig/arch/mips/loongson/fuloong-2f/irq.c 1970-01-01 01:00:00.000000000 +0100 +++ linux-2.6.30.5/arch/mips/loongson/fuloong-2f/irq.c 2009-08-23 19:01:04.000000000 +0200 @@ -0,0 +1,53 @@ +/* + * Copyright (C) 2007 Lemote Inc. & Insititute of Computing Technology + * Author: Fuxin Zhang, zhangfx@lemote.com + * + * 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. + */ + +#include + +#include +#include + +int mach_i8259_irq(void) +{ + int irq, isr, imr; + + irq = -1; + + if ((LOONGSON_INTISR & LOONGSON_INTEN) & LOONGSON_INT_BIT_INT0) { + imr = inb(0x21) | (inb(0xa1) << 8); + isr = inb(0x20) | (inb(0xa0) << 8); + isr &= ~0x4; /* irq2 for cascade */ + isr &= ~imr; + irq = ffs(isr) - 1; + } + + return irq; +} + +void mach_irq_dispatch(unsigned int pending) +{ + if (pending & CAUSEF_IP7) + do_IRQ(LOONGSON_TIMER_IRQ); + else if (pending & CAUSEF_IP6) { + do_IRQ(LOONGSON_PERFCNT_IRQ); /* Perf counter overflow */ + bonito_irqdispatch(); /* North Bridge */ + } else if (pending & CAUSEF_IP3) /* CPU UART */ + do_IRQ(LOONGSON_UART_IRQ); + else if (pending & CAUSEF_IP2) /* South Bridge */ + i8259_irqdispatch(); + else + spurious_interrupt(); +} + +void __init set_irq_trigger_mode(void) +{ + /* setup cs5536 as high level trigger */ + LOONGSON_INTPOL = LOONGSON_INT_BIT_INT0 | LOONGSON_INT_BIT_INT1; + LOONGSON_INTEDGE &= ~(LOONGSON_INT_BIT_INT0 | LOONGSON_INT_BIT_INT1); +} diff -Nur linux-2.6.30.5.orig/arch/mips/loongson/fuloong-2f/Makefile linux-2.6.30.5/arch/mips/loongson/fuloong-2f/Makefile --- linux-2.6.30.5.orig/arch/mips/loongson/fuloong-2f/Makefile 1970-01-01 01:00:00.000000000 +0100 +++ linux-2.6.30.5/arch/mips/loongson/fuloong-2f/Makefile 2009-08-23 19:01:04.000000000 +0200 @@ -0,0 +1,5 @@ +# +# Makefile for fuloong-2f +# + +obj-y += irq.o reset.o diff -Nur linux-2.6.30.5.orig/arch/mips/loongson/fuloong-2f/reset.c linux-2.6.30.5/arch/mips/loongson/fuloong-2f/reset.c --- linux-2.6.30.5.orig/arch/mips/loongson/fuloong-2f/reset.c 1970-01-01 01:00:00.000000000 +0100 +++ linux-2.6.30.5/arch/mips/loongson/fuloong-2f/reset.c 2009-08-23 19:01:04.000000000 +0200 @@ -0,0 +1,65 @@ +/* Board-specific reboot/shutdown routines + * + * Copyright (c) 2009 Philippe Vachon + * + * Copyright (C) 2009 Lemote Inc. & Insititute of Computing Technology + * Author: Wu Zhangjin, wuzj@lemote.com + * + * 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. + */ + +#include +#include +#include + +#include + +/* cs5536 is the south bridge used by fuloong2f mini PC */ +#include + +void mach_prepare_reboot(void) +{ + /* + * reset cpu to full speed, this is needed when enabling cpu frequency + * scalling + */ + LOONGSON_CHIPCFG0 |= 0x7; + + /* send a reset signal to south bridge. + * + * NOTE: if enable "Power Management" in kernel, rtl8169 will not reset + * normally with this reset operation and it will not work in PMON, but + * you can type halt command and then reboot, seems the hardware reset + * logic not work normally. + */ + { + u32 hi, lo; + _rdmsr(DIVIL_MSR_REG(DIVIL_SOFT_RESET), &hi, &lo); + lo |= 0x00000001; + _wrmsr(DIVIL_MSR_REG(DIVIL_SOFT_RESET), hi, lo); + } +} + +void mach_prepare_shutdown(void) +{ + u32 hi, lo, val; + phys_addr_t gpio_base; + + _rdmsr(DIVIL_MSR_REG(DIVIL_LBAR_GPIO), &hi, &lo); + + gpio_base = mips_io_port_base | (lo & 0xff00); + + /* make cs5536 gpio13 output enable */ + val = (readl((u32 *) (gpio_base + GPIOL_OUT_EN)) & ~(1 << (16 + 13))) + | (1 << 13); + writel(val, (u32 *) (gpio_base + GPIOL_OUT_EN)); + mmiowb(); + /* make cs5536 gpio13 output low level voltage. */ + val = (readl((u32 *) (gpio_base + GPIOL_OUT_VAL)) & ~(1 << (13))) + | (1 << (16 + 13)); + writel(val, (u32 *) (gpio_base + GPIOL_OUT_VAL)); + mmiowb(); +} diff -Nur linux-2.6.30.5.orig/arch/mips/loongson/image/cache.c linux-2.6.30.5/arch/mips/loongson/image/cache.c --- linux-2.6.30.5.orig/arch/mips/loongson/image/cache.c 1970-01-01 01:00:00.000000000 +0100 +++ linux-2.6.30.5/arch/mips/loongson/image/cache.c 2009-08-23 19:01:04.000000000 +0200 @@ -0,0 +1,42 @@ +#include + +#define cache32_unroll32(base, op) \ + __asm__ __volatile__( \ + " .set push \n" \ + " .set noreorder \n" \ + " .set mips3 \n" \ + " cache %1, 0x000(%0); cache %1, 0x020(%0) \n" \ + " cache %1, 0x040(%0); cache %1, 0x060(%0) \n" \ + " cache %1, 0x080(%0); cache %1, 0x0a0(%0) \n" \ + " cache %1, 0x0c0(%0); cache %1, 0x0e0(%0) \n" \ + " cache %1, 0x100(%0); cache %1, 0x120(%0) \n" \ + " cache %1, 0x140(%0); cache %1, 0x160(%0) \n" \ + " cache %1, 0x180(%0); cache %1, 0x1a0(%0) \n" \ + " cache %1, 0x1c0(%0); cache %1, 0x1e0(%0) \n" \ + " cache %1, 0x200(%0); cache %1, 0x220(%0) \n" \ + " cache %1, 0x240(%0); cache %1, 0x260(%0) \n" \ + " cache %1, 0x280(%0); cache %1, 0x2a0(%0) \n" \ + " cache %1, 0x2c0(%0); cache %1, 0x2e0(%0) \n" \ + " cache %1, 0x300(%0); cache %1, 0x320(%0) \n" \ + " cache %1, 0x340(%0); cache %1, 0x360(%0) \n" \ + " cache %1, 0x380(%0); cache %1, 0x3a0(%0) \n" \ + " cache %1, 0x3c0(%0); cache %1, 0x3e0(%0) \n" \ + " .set pop \n" \ + : \ + : "r" (base), \ + "i" (op)); + +void flush_cache_all(void) +{ + unsigned long start = CKSEG0ADDR(0x80000000); + unsigned long end = start + MEM_SIZE_M * 1024 / 4; + unsigned long lsize = 32; + unsigned long addr; + + int i; + + for (i = 0; i < 4; i++) { + for (addr = start; addr < end; addr += lsize * 32) + cache32_unroll32(addr | i, 0x03); /* Index Writeback scache */ + } +} diff -Nur linux-2.6.30.5.orig/arch/mips/loongson/image/dbg.c linux-2.6.30.5/arch/mips/loongson/image/dbg.c --- linux-2.6.30.5.orig/arch/mips/loongson/image/dbg.c 1970-01-01 01:00:00.000000000 +0100 +++ linux-2.6.30.5/arch/mips/loongson/image/dbg.c 2009-08-23 19:01:04.000000000 +0200 @@ -0,0 +1,61 @@ +/* serial port debug support */ + +#ifdef SERIAL_PORT_DEBUG + +#include +#include + +#include + +#include +#include + +#define UART_BASE CKSEG1ADDR(LOONGSON_UART_BASE) + +void putc(char c) +{ + int timeout; + char reg; + + reg = *((char *)(UART_BASE + UART_LSR)) & UART_LSR_THRE; + for (timeout = 1024; reg == 0 && timeout > 0; timeout--) + reg = (*((char *)(UART_BASE + UART_LSR))) & UART_LSR_THRE; + + *((char *)(UART_BASE + UART_TX)) = c; +} + +void puts(const char *s) +{ + char c; + while ((c = *s++) != '\0') { + putc(c); + if (c == '\n') + putc('\r'); + } +} + +void puthex(unsigned long val) +{ + + unsigned char buf[10]; + int i; + for (i = 7; i >= 0; i--) { + buf[i] = "0123456789ABCDEF"[val & 0x0F]; + val >>= 4; + } + buf[8] = '\0'; + puts(buf); +} +#else +void putc(char c) +{ +} + +void puts(const char *s) +{ +} + +void puthex(unsigned long val) +{ +} +#endif diff -Nur linux-2.6.30.5.orig/arch/mips/loongson/image/decompress.c linux-2.6.30.5/arch/mips/loongson/image/decompress.c --- linux-2.6.30.5.orig/arch/mips/loongson/image/decompress.c 1970-01-01 01:00:00.000000000 +0100 +++ linux-2.6.30.5/arch/mips/loongson/image/decompress.c 2009-08-23 19:01:04.000000000 +0200 @@ -0,0 +1,134 @@ +/* + * Misc. bootloader code for many machines. + * + * Copyright 2001 MontaVista Software Inc. + * Author: Matt Porter Derived from + * arch/ppc/boot/prep/misc.c + * + * Copyright (C) 2009 Lemote, Inc. & Institute of Computing Technology + * Author: Wu Zhangjin + * + * 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. + */ + +#include +#include +#include + +/* These two variables specify the free mem region + * that can be used for temporary malloc area + * + * Here is toally 15M + */ +#define FREE_MEM_START CKSEG0ADDR(0x83000000) +#define FREE_MEM_END CKSEG0ADDR(0x83f00000) + +unsigned long free_mem_ptr; +unsigned long free_mem_end_ptr; +char *zimage_start; + +/* The linker tells us where the image is. */ +extern unsigned char __image_begin, __image_end; +extern unsigned char __ramdisk_begin, __ramdisk_end; +unsigned long initrd_size; + +/* debug interface via searil port */ +extern void puts(const char *s); +extern void puthex(unsigned long val); +void error(char *x) +{ + puts("\n\n"); + puts(x); + puts("\n\n -- System halted"); + + while (1) + ; /* Halt */ +} + +/* cache fulshing support */ +extern void flush_cache_all(void); + +/* gunzip declarations */ +#define STATIC static + +#ifdef CONFIG_KERNEL_GZIP +#include "../../../../lib/decompress_inflate.c" +#elif defined(CONFIG_KERNEL_BZIP2) +#include "../../../../lib/decompress_bunzip2.c" +#elif defined(CONFIG_KERNEL_LZMA) +#include "../../../../lib/decompress_unlzma.c" +#endif + +void decompress_kernel(unsigned long load_addr, int num_words, + unsigned long cksum, unsigned long *sp) +{ + extern unsigned long start; + int zimage_size; + + initrd_size = (unsigned long)(&__ramdisk_end) - + (unsigned long)(&__ramdisk_begin); + + /* + * Reveal where we were loaded at and where we + * were relocated to. + */ + puts("loaded at: "); + puthex(load_addr); + puts(" "); + puthex((unsigned long)(load_addr + (4 * num_words))); + puts("\n"); + if ((unsigned long)load_addr != (unsigned long)&start) { + puts("relocated to: "); + puthex((unsigned long)&start); + puts(" "); + puthex((unsigned long)((unsigned long)&start + + (4 * num_words))); + puts("\n"); + } + + /* + * We link ourself to an arbitrary low address. When we run, we + * relocate outself to that address. __image_beign points to + * the part of the image where the zImage is. -- Tom + */ + zimage_start = (char *)(unsigned long)(&__image_begin); + zimage_size = (unsigned long)(&__image_end) - + (unsigned long)(&__image_begin); + + /* + * The zImage and initrd will be between start and _end, so they've + * already been moved once. We're good to go now. -- Tom + */ + puts("zimage at: "); + puthex((unsigned long)zimage_start); + puts(" "); + puthex((unsigned long)(zimage_size + zimage_start)); + puts("\n"); + + if (initrd_size) { + puts("initrd at: "); + puthex((unsigned long)(&__ramdisk_begin)); + puts(" "); + puthex((unsigned long)(&__ramdisk_end)); + puts("\n"); + } + + /* assume the chunk below 8M is free */ + free_mem_ptr = FREE_MEM_START; + free_mem_end_ptr = FREE_MEM_END; + + /* Display standard Linux/MIPS boot prompt for kernel args */ + puts("Uncompressing Linux at load address "); + puthex(VMLINUX_LOAD_ADDRESS); + puts("\n"); + /* I don't like this hard coded gunzip size (fixme) */ + decompress(zimage_start, zimage_size, 0, 0, + (void *)VMLINUX_LOAD_ADDRESS, 0, error); +#if 1 + flush_cache_all(); +#endif + puts("Now, booting the kernel...\n"); +} diff -Nur linux-2.6.30.5.orig/arch/mips/loongson/image/dummy.c linux-2.6.30.5/arch/mips/loongson/image/dummy.c --- linux-2.6.30.5.orig/arch/mips/loongson/image/dummy.c 1970-01-01 01:00:00.000000000 +0100 +++ linux-2.6.30.5/arch/mips/loongson/image/dummy.c 2009-08-23 19:01:04.000000000 +0200 @@ -0,0 +1,4 @@ +int main(void) +{ + return 0; +} diff -Nur linux-2.6.30.5.orig/arch/mips/loongson/image/head.S linux-2.6.30.5/arch/mips/loongson/image/head.S --- linux-2.6.30.5.orig/arch/mips/loongson/image/head.S 1970-01-01 01:00:00.000000000 +0100 +++ linux-2.6.30.5/arch/mips/loongson/image/head.S 2009-08-23 19:01:04.000000000 +0200 @@ -0,0 +1,100 @@ +/* + * arch/mips/kernel/head.S + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + * + * Copyright (C) 1994, 1995 Waldorf Electronics + * Written by Ralf Baechle and Andreas Busse + * Copyright (C) 1995 - 1999 Ralf Baechle + * Copyright (C) 1996 Paul M. Antoine + * Modified for DECStation and hence R3000 support by Paul M. Antoine + * Further modifications by David S. Miller and Harald Koerfgen + * Copyright (C) 1999 Silicon Graphics, Inc. + * + * Head.S contains the MIPS exception handler and startup code. + * + ************************************************************************** + * 9 Nov, 2000. + * Added Cache Error exception handler and SBDDP EJTAG debug exception. + * + * Kevin Kissell, kevink@mips.com and Carsten Langgaard, carstenl@mips.com + * Copyright (C) 2000 MIPS Technologies, Inc. All rights reserved. + ************************************************************************** + */ +#include +#include + +#include +#include +#include +#include +#include +#include + +#define IndexInvalidate_I 0x00 +#define IndexWriteBack_D 0x01 + + .set noreorder + .cprestore + LEAF(start) +start: + bal locate + nop +locate: + subu s8, ra, 8 /* Where we were loaded */ + PTR_LA sp, (.stack + 8192) + + move s0, a0 /* Save boot rom start args */ + move s1, a1 + move s2, a2 + move s3, a3 + + PTR_LA a0, start /* Where we were linked to run */ + + move a1, s8 + PTR_LA a2, _edata + subu t1, a2, a0 + srl t1, t1, 2 + + /* copy text section */ + li t0, 0 +1: lw v0, 0(a1) + nop + sw v0, 0(a0) + xor t0, t0, v0 + addu a0, 4 + bne a2, a0, 1b + addu a1, 4 + + /* Clear BSS */ + PTR_LA a0, _edata + PTR_LA a2, _end +2: sw zero, 0(a0) + bne a2, a0, 2b + addu a0, 4 + + move a0, s8 /* load address */ + move a1, t1 /* length in words */ + move a2, t0 /* checksum */ + move a3, sp + + PTR_LA ra, 1f + PTR_LA k0, decompress_kernel + jr k0 + nop +1: + + move a0, s0 + move a1, s1 + move a2, s2 + move a3, s3 + li k0, KERNEL_ENTRY + jr k0 + nop +3: + b 3b + END(start) + + .comm .stack,4096*2,4 diff -Nur linux-2.6.30.5.orig/arch/mips/loongson/image/ld.script linux-2.6.30.5/arch/mips/loongson/image/ld.script --- linux-2.6.30.5.orig/arch/mips/loongson/image/ld.script 1970-01-01 01:00:00.000000000 +0100 +++ linux-2.6.30.5/arch/mips/loongson/image/ld.script 2009-08-23 19:01:04.000000000 +0200 @@ -0,0 +1,152 @@ +OUTPUT_ARCH(mips) +ENTRY(start) +SECTIONS +{ + /* Read-only sections, merged into text segment: */ + /* . = 0x81000000; */ /* 32bit */ + /* . = 0xffffffff81000000; */ /* 64bit */ + .init : { *(.init) } =0 + .text : + { + _ftext = . ; + *(.text) + *(.rodata) + *(.rodata1) + /* .gnu.warning sections are handled specially by elf32.em. */ + *(.gnu.warning) + } =0 + .kstrtab : { *(.kstrtab) } + + . = ALIGN(16); /* Exception table */ + __start___ex_table = .; + __ex_table : { *(__ex_table) } + __stop___ex_table = .; + + __start___dbe_table = .; /* Exception table for data bus errors */ + __dbe_table : { *(__dbe_table) } + __stop___dbe_table = .; + + __start___ksymtab = .; /* Kernel symbol table */ + __ksymtab : { *(__ksymtab) } + __stop___ksymtab = .; + + _etext = .; + + . = ALIGN(8192); + .data.init_task : { *(.data.init_task) } + + /* Startup code */ + . = ALIGN(4096); + __init_begin = .; + .text.init : { *(.text.init) } + .data.init : { *(.data.init) } + . = ALIGN(16); + __setup_start = .; + .setup.init : { *(.setup.init) } + __setup_end = .; + __initcall_start = .; + .initcall.init : { *(.initcall.init) } + __initcall_end = .; + . = ALIGN(4096); /* Align double page for init_task_union */ + __init_end = .; + + . = ALIGN(4096); + .data.page_aligned : { *(.data.idt) } + + . = ALIGN(32); + .data.cacheline_aligned : { *(.data.cacheline_aligned) } + + .fini : { *(.fini) } =0 + .reginfo : { *(.reginfo) } + /* Adjust the address for the data segment. We want to adjust up to + the same address within the page on the next page up. It would + be more correct to do this: + . = .; + The current expression does not correctly handle the case of a + text segment ending precisely at the end of a page; it causes the + data segment to skip a page. The above expression does not have + this problem, but it will currently (2/95) cause BFD to allocate + a single segment, combining both text and data, for this case. + This will prevent the text segment from being shared among + multiple executions of the program; I think that is more + important than losing a page of the virtual address space (note + that no actual memory is lost; the page which is skipped can not + be referenced). */ + . = .; + .data : + { + _fdata = . ; + *(.data) + + /* Put the compressed image here, so bss is on the end. */ + __image_begin = .; + *(.image) + __image_end = .; + /* Align the initial ramdisk image (INITRD) on page boundaries. */ + . = ALIGN(4096); + __ramdisk_begin = .; + *(.initrd) + __ramdisk_end = .; + . = ALIGN(4096); + + CONSTRUCTORS + } + .data1 : { *(.data1) } + _gp = . + 0x8000; + .lit8 : { *(.lit8) } + .lit4 : { *(.lit4) } + .ctors : { *(.ctors) } + .dtors : { *(.dtors) } + .got : { *(.got.plt) *(.got) } + .dynamic : { *(.dynamic) } + /* We want the small data sections together, so single-instruction offsets + can access them all, and initialized data all before uninitialized, so + we can shorten the on-disk segment size. */ + .sdata : { *(.sdata) } + . = ALIGN(4); + _edata = .; + PROVIDE (edata = .); + + __bss_start = .; + _fbss = .; + .sbss : { *(.sbss) *(.scommon) } + .bss : + { + *(.dynbss) + *(.bss) + *(COMMON) + . = ALIGN(4); + _end = . ; + PROVIDE (end = .); + } + + /* Sections to be discarded */ + /DISCARD/ : + { + *(.text.exit) + *(.data.exit) + *(.exitcall.exit) + } + + /* This is the MIPS specific mdebug section. */ + .mdebug : { *(.mdebug) } + /* These are needed for ELF backends which have not yet been + converted to the new style linker. */ + .stab 0 : { *(.stab) } + .stabstr 0 : { *(.stabstr) } + /* DWARF debug sections. + Symbols in the .debug DWARF section are relative to the beginning of the + section so we begin .debug at 0. It's not clear yet what needs to happen + for the others. */ + .debug 0 : { *(.debug) } + .debug_srcinfo 0 : { *(.debug_srcinfo) } + .debug_aranges 0 : { *(.debug_aranges) } + .debug_pubnames 0 : { *(.debug_pubnames) } + .debug_sfnames 0 : { *(.debug_sfnames) } + .line 0 : { *(.line) } + /* These must appear regardless of . */ + .gptab.sdata : { *(.gptab.data) *(.gptab.sdata) } + .gptab.sbss : { *(.gptab.bss) *(.gptab.sbss) } + .comment : { *(.comment) } + .note : { *(.note) } +} diff -Nur linux-2.6.30.5.orig/arch/mips/loongson/image/Makefile linux-2.6.30.5/arch/mips/loongson/image/Makefile --- linux-2.6.30.5.orig/arch/mips/loongson/image/Makefile 1970-01-01 01:00:00.000000000 +0100 +++ linux-2.6.30.5/arch/mips/loongson/image/Makefile 2009-08-23 19:01:04.000000000 +0200 @@ -0,0 +1,61 @@ +# +# arch/mips/zboot/Makefile +# +# This file is subject to the terms and conditions of the GNU General Public +# License. See the file "COPYING" in the main directory of this archive +# for more details. + +# Adapted for MIPS Pete Popov, Dan Malek +# +# Copyright (C) 1994 by Linus Torvalds +# Adapted for PowerPC by Gary Thomas +# modified by Cort (cort@cs.nmt.edu) +# +# Copyright (C) 2009 Lemote Inc. & Insititute of Computing Technology +# Author: Wu Zhangjin +# + +# Assume you have at least a 256M memory, this is used in cache.c +KBUILD_CFLAGS := $(LINUXINCLUDE) $(KBUILD_CFLAGS) -D__KERNEL__ -DMEM_SIZE_M=256 -DSERIAL_PORT_DEBUG +KBUILD_AFLAGS := $(LINUXINCLUDE) $(KBUILD_AFLAGS) -D__ASSEMBLY__ \ + -DKERNEL_ENTRY=0x$(shell $(NM) $(objtree)/$(KBUILD_IMAGE) | grep kernel_entry | cut -f1 -d \ ) + +OBJECTS := $(obj)/head.o $(obj)/decompress.o $(obj)/mem.o $(obj)/cache.o $(obj)/dbg.o + +OBJCOPYFLAGS_vmlinux.bin := $(OBJCOPYFLAGS) -O binary -R .comment -S +$(obj)/vmlinux.bin: $(KBUILD_IMAGE) + $(call if_changed,objcopy) + +suffix_$(CONFIG_KERNEL_GZIP) = gz +suffix_$(CONFIG_KERNEL_BZIP2) = bz2 +suffix_$(CONFIG_KERNEL_LZMA) = lzma +tool_$(CONFIG_KERNEL_GZIP) = gzip +tool_$(CONFIG_KERNEL_BZIP2) = bzip2 +tool_$(CONFIG_KERNEL_LZMA) = lzma +$(obj)/vmlinux.$(suffix_y): $(obj)/vmlinux.bin + $(call if_changed,$(tool_y)) + +$(obj)/piggy.o: $(obj)/vmlinux.$(suffix_y) $(obj)/dummy.o + $(Q)$(OBJCOPY) $(OBJCOPYFLAGS) \ + --add-section=.image=$< \ + --set-section-flags=.image=contents,alloc,load,readonly,data \ + $(obj)/dummy.o $@ + +# The start address of the compressed kernel, Z_KERNEL_START > KERNEL_START + KERNEL_SIZE +LDFLAGS_vmlinuz := $(LDFLAGS) -Ttext 0x$(if $(CONFIG_64BIT),ffffffff,)81000000 -T +$(obj)/vmlinuz: $(src)/ld.script $(OBJECTS) $(obj)/piggy.o + $(call if_changed,ld) + +OBJCOPYFLAGS_zImage := $(OBJCOPYFLAGS) -R .comment -R .stab -R .stabstr -R .initrd -R .sysmap +$(obj)/zImage: $(obj)/vmlinuz + $(call if_changed,objcopy) + +zImage: $(obj)/zImage + $(Q)ln -sf $< $(objtree)/vmlinuz + $(Q)echo " SYMLINK $(objtree)/"vmlinuz + +clean: +clean-files += *.o \ + zImage* \ + vmlinu* \ + $(objtree)/vmlinuz diff -Nur linux-2.6.30.5.orig/arch/mips/loongson/image/mem.c linux-2.6.30.5/arch/mips/loongson/image/mem.c --- linux-2.6.30.5.orig/arch/mips/loongson/image/mem.c 1970-01-01 01:00:00.000000000 +0100 +++ linux-2.6.30.5/arch/mips/loongson/image/mem.c 2009-08-23 19:01:04.000000000 +0200 @@ -0,0 +1,24 @@ +/* memory opernation support */ + +#include + +void *memset(void *s, int c, size_t n) +{ + int i; + char *ss = s; + + for (i = 0; i < n; i++) + ss[i] = c; + return s; +} + +void *memcpy(void *dest, const void *src, size_t n) +{ + int i; + const char *s = src; + char *d = dest; + + for (i = 0; i < n; i++) + d[i] = s[i]; + return dest; +} diff -Nur linux-2.6.30.5.orig/arch/mips/loongson/Kconfig linux-2.6.30.5/arch/mips/loongson/Kconfig --- linux-2.6.30.5.orig/arch/mips/loongson/Kconfig 1970-01-01 01:00:00.000000000 +0100 +++ linux-2.6.30.5/arch/mips/loongson/Kconfig 2009-08-23 19:01:04.000000000 +0200 @@ -0,0 +1,136 @@ +choice + prompt "Machine Type" + depends on MACH_LOONGSON + +config LEMOTE_FULOONG2E + bool "Lemote Fuloong(2e) mini-PC" + select ARCH_SPARSEMEM_ENABLE + select CEVT_R4K + select CSRC_R4K + select SYS_HAS_CPU_LOONGSON2E + select DMA_NONCOHERENT + select BOOT_ELF32 + select BOARD_SCACHE + select HW_HAS_PCI + select I8259 + select ISA + select IRQ_CPU + select SYS_SUPPORTS_32BIT_KERNEL + select SYS_SUPPORTS_64BIT_KERNEL + select SYS_SUPPORTS_LITTLE_ENDIAN + select SYS_SUPPORTS_HIGHMEM + select SYS_HAS_EARLY_PRINTK + select GENERIC_HARDIRQS_NO__DO_IRQ + select GENERIC_ISA_DMA_SUPPORT_BROKEN + select CPU_HAS_WB + help + Lemote Fuloong(2e) mini-PC board based on the Chinese Loongson-2E CPU and + an FPGA northbridge + + Lemote Fuloong(2e) mini PC have a VIA686B south bridge. + +config LEMOTE_FULOONG2F + bool "Lemote Fuloong(2f) mini-PC" + select ARCH_SPARSEMEM_ENABLE + select CEVT_R4K if !CS5536_MFGPT + select CSRC_R4K if !CS5536_MFGPT + select SYS_HAS_CPU_LOONGSON2F + select DMA_NONCOHERENT + select BOOT_ELF32 + select BOARD_SCACHE + select HW_HAS_PCI + select I8259 + select ISA + select IRQ_CPU + select SYS_SUPPORTS_32BIT_KERNEL + select SYS_SUPPORTS_64BIT_KERNEL + select SYS_SUPPORTS_LITTLE_ENDIAN + select SYS_SUPPORTS_HIGHMEM + select SYS_HAS_EARLY_PRINTK + select GENERIC_HARDIRQS_NO__DO_IRQ + select GENERIC_ISA_DMA_SUPPORT_BROKEN + select CPU_HAS_WB + select CS5536 + help + Lemote Fuloong(2f) mini-PC board based on the Chinese Loongson-2F + CPU, which has an internal DDR and PCIX controller. the PCIX + controller have the similiar programming interface of the FPGA north + bridge of LOONGSON2E. + + Lemote Fuloong(2f) mini PC have an AMD CS5536 south bridge. + +config LEMOTE_YEELOONG2F + bool "Lemote Yeeloong(2f) mini Notebook" + select ARCH_SPARSEMEM_ENABLE + select CEVT_R4K if !CS5536_MFGPT + select CSRC_R4K if !CS5536_MFGPT + select SYS_HAS_CPU_LOONGSON2F + select DMA_NONCOHERENT + select BOOT_ELF32 + select BOARD_SCACHE + select HW_HAS_PCI + select I8259 + select ISA + select IRQ_CPU + select SYS_SUPPORTS_32BIT_KERNEL + select SYS_SUPPORTS_64BIT_KERNEL + select SYS_SUPPORTS_LITTLE_ENDIAN + select SYS_SUPPORTS_HIGHMEM + select SYS_HAS_EARLY_PRINTK + select SYS_HAS_MACH_PROM_INIT_CMDLINE + select GENERIC_HARDIRQS_NO__DO_IRQ + select GENERIC_ISA_DMA_SUPPORT_BROKEN + select EC_KB3310B if PM + select CPU_HAS_WB + select CS5536 + help + Lemote Laptop based on the Chinese Loongson-2F CPU, which has an + internal DDR and PCIX controller. the PCIX controller have the + similiar programming interface of the FPGA north bridge of + LOONGSON2E. + + Lemote Yeeloong(2f) laptop have an AMD CS5536 south bridge and an EC + controller. + +endchoice + +config CS5536 + bool + +config CS5536_FLASH + bool + depends on CS5536 + +config CS5536_NOR_FLASH + bool + depends on CS5536_FLASH + +config CS5536_OTG + bool + depends on CS5536 + +config CS5536_UDC + bool + depends on CS5536 + +config SYS_HAS_MACH_PROM_INIT_CMDLINE + bool + +config CS5536_MFGPT + bool "Using cs5536's MFGPT as system clock" + depends on CS5536 + help + This is needed if cpufreq and oprofile is enabled in Loongson2(F) + machines + +config UCA_SIZE + hex "Uncache Accelerated Region size" + depends on CPU_LOONGSON2F + default 0x400000 if LEMOTE_YEELOONG2F + default 0x2000000 if LEMOTE_FULOONG2F + help + Uncached Acceleration(UCA) can greatly improve video performance. + Normally the Video memory can be accessed in Uncached Accelerated mode, + other peripheral spaces not. + + Specify a zeroed size to disable this feature. diff -Nur linux-2.6.30.5.orig/arch/mips/loongson/Makefile linux-2.6.30.5/arch/mips/loongson/Makefile --- linux-2.6.30.5.orig/arch/mips/loongson/Makefile 1970-01-01 01:00:00.000000000 +0100 +++ linux-2.6.30.5/arch/mips/loongson/Makefile 2009-08-23 19:01:04.000000000 +0200 @@ -0,0 +1,23 @@ +# +# Common code for all Loongson based systems +# + +obj-$(CONFIG_MACH_LOONGSON) += common/ + +# +# Lemote Fuloong mini-PC (Loongson 2E-based) +# + +obj-$(CONFIG_LEMOTE_FULOONG2E) += fuloong-2e/ + +# +# Lemote Fuloong mini-PC (Loongson 2F-based) +# + +obj-$(CONFIG_LEMOTE_FULOONG2F) += fuloong-2f/ + +# +# Lemote Yeeloong mini-PC (Loongson 2F-based) +# + +obj-$(CONFIG_LEMOTE_YEELOONG2F) += yeeloong-2f/ diff -Nur linux-2.6.30.5.orig/arch/mips/loongson/yeeloong-2f/init.c linux-2.6.30.5/arch/mips/loongson/yeeloong-2f/init.c --- linux-2.6.30.5.orig/arch/mips/loongson/yeeloong-2f/init.c 1970-01-01 01:00:00.000000000 +0100 +++ linux-2.6.30.5/arch/mips/loongson/yeeloong-2f/init.c 2009-08-23 19:01:04.000000000 +0200 @@ -0,0 +1,80 @@ +/* + * board specific init routines + * + * Copyright (C) 2007 Lemote Inc. & Insititute of Computing Technology + * Author: Fuxin Zhang, zhangfx@lemote.com + * + * Copyright (C) 2009 Lemote Inc. & Insititute of Computing Technology + * Author: Wu Zhangjin, wuzj@lemote.com + * + * 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. + */ + +#include + +#include + +#include + +void __init mach_prom_init_cmdline(void) +{ + /* set lpc irq to quiet mode */ + _wrmsr(DIVIL_MSR_REG(DIVIL_LEG_IO), 0x00, 0x16000003); + + /*Emulate post for usb */ + _wrmsr(USB_MSR_REG(USB_CONFIG), 0x4, 0xBF000); + + if (strstr(arcs_cmdline, "no_auto_cmd") == NULL) { + unsigned char default_root[50] = "/dev/sda1"; + char *pmon_ver, *ec_ver, *p, version[60], ec_version[64]; + + p = arcs_cmdline; + + pmon_ver = strstr(arcs_cmdline, "PMON_VER"); + if (pmon_ver) { + p = strstr(pmon_ver, " "); + if (p) + *p++ = '\0'; + strncpy(version, pmon_ver, 60); + } else + strncpy(version, "PMON_VER=Unknown", 60); + + ec_ver = strstr(p, "EC_VER"); + if (ec_ver) { + p = strstr(ec_ver, " "); + if (p) + *p = '\0'; + strncpy(ec_version, ec_ver, 64); + } else + strncpy(ec_version, "EC_VER=Unknown", 64); + + p = strstr(arcs_cmdline, "root="); + if (p) { + strncpy(default_root, p, sizeof(default_root)); + p = strstr(default_root, " "); + if (p) + *p = '\0'; + } + + memset(arcs_cmdline, 0, sizeof(arcs_cmdline)); + strcat(arcs_cmdline, version); + strcat(arcs_cmdline, " "); + strcat(arcs_cmdline, ec_version); + strcat(arcs_cmdline, " "); + strcat(arcs_cmdline, default_root); + strcat(arcs_cmdline, " console=tty"); + } + + /* + * automatically pass the vga argument via machtype argument if + * vga is not passed: yeeloong-7inch's vga mode is 800x480x24 + */ + + if ((strstr(arcs_cmdline, "vga") == NULL) + && (strstr(arcs_cmdline, "machtype") != NULL) + && (strstr(arcs_cmdline, "7inch") != NULL)) + strcat(arcs_cmdline, " vga=800x480x16"); +} diff -Nur linux-2.6.30.5.orig/arch/mips/loongson/yeeloong-2f/irq.c linux-2.6.30.5/arch/mips/loongson/yeeloong-2f/irq.c --- linux-2.6.30.5.orig/arch/mips/loongson/yeeloong-2f/irq.c 1970-01-01 01:00:00.000000000 +0100 +++ linux-2.6.30.5/arch/mips/loongson/yeeloong-2f/irq.c 2009-08-23 19:01:04.000000000 +0200 @@ -0,0 +1,53 @@ +/* + * Copyright (C) 2007 Lemote Inc. & Insititute of Computing Technology + * Author: Fuxin Zhang, zhangfx@lemote.com + * + * 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. + */ + +#include + +#include +#include + +int mach_i8259_irq(void) +{ + int irq, isr, imr; + + irq = -1; + + if ((LOONGSON_INTISR & LOONGSON_INTEN) & LOONGSON_INT_BIT_INT0) { + imr = inb(0x21) | (inb(0xa1) << 8); + isr = inb(0x20) | (inb(0xa0) << 8); + isr &= ~0x4; /* irq2 for cascade */ + isr &= ~imr; + irq = ffs(isr) - 1; + } + + return irq; +} + +void mach_irq_dispatch(unsigned int pending) +{ + if (pending & CAUSEF_IP7) + do_IRQ(LOONGSON_TIMER_IRQ); + else if (pending & CAUSEF_IP6) { + do_IRQ(LOONGSON_PERFCNT_IRQ); /* Perf counter overflow */ + bonito_irqdispatch(); /* North Bridge */ + } else if (pending & CAUSEF_IP3) /* CPU UART */ + do_IRQ(LOONGSON_UART_IRQ); + else if (pending & CAUSEF_IP2) /* South Bridge */ + i8259_irqdispatch(); + else + spurious_interrupt(); +} + +void __init set_irq_trigger_mode(void) +{ + /* setup cs5536 as high level trigger */ + LOONGSON_INTPOL = LOONGSON_INT_BIT_INT0 | LOONGSON_INT_BIT_INT1; + LOONGSON_INTEDGE &= ~(LOONGSON_INT_BIT_INT0 | LOONGSON_INT_BIT_INT1); +} diff -Nur linux-2.6.30.5.orig/arch/mips/loongson/yeeloong-2f/Makefile linux-2.6.30.5/arch/mips/loongson/yeeloong-2f/Makefile --- linux-2.6.30.5.orig/arch/mips/loongson/yeeloong-2f/Makefile 1970-01-01 01:00:00.000000000 +0100 +++ linux-2.6.30.5/arch/mips/loongson/yeeloong-2f/Makefile 2009-08-23 19:01:04.000000000 +0200 @@ -0,0 +1,11 @@ +# +# Makefile for fuloong-2f +# + +obj-y += init.o irq.o reset.o + +# +# Power Management Support +# + +obj-$(CONFIG_PM) += pm.o diff -Nur linux-2.6.30.5.orig/arch/mips/loongson/yeeloong-2f/pm.c linux-2.6.30.5/arch/mips/loongson/yeeloong-2f/pm.c --- linux-2.6.30.5.orig/arch/mips/loongson/yeeloong-2f/pm.c 1970-01-01 01:00:00.000000000 +0100 +++ linux-2.6.30.5/arch/mips/loongson/yeeloong-2f/pm.c 2009-08-23 19:01:04.000000000 +0200 @@ -0,0 +1,321 @@ +/* + * loongson-specific STR/Standby + * + * Copyright (C) 2009 Lemote Inc. & Insititute of Computing Technology + * Author: Wu Zhangjin + * + * 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. + */ + +#include +#include +#include + +#include +#include +#include + +#include + +#ifdef CONFIG_CS5536_MFGPT +#include +#endif + +#include "../../../../drivers/platform/loongson/ec_kb3310b/ec.h" +#include "../../../../drivers/platform/loongson/ec_kb3310b/ec_misc_fn.h" + +/* debug functions */ +extern void prom_printf(char *fmt, ...); + +/* i8042 keyboard operations: drivers/input/serio/i8042.c */ +extern int i8042_enable_kbd_port(void); +extern void i8042_flush(void); + +static unsigned int cached_master_mask; /* i8259A */ +static unsigned int cached_slave_mask; +static unsigned int cached_bonito_irq_mask; /* bonito */ + +void arch_suspend_enable_irqs(void) +{ + /* enable all mips interrupts */ + local_irq_enable(); + + /* only enable the cached interrupts of i8259A */ + outb(cached_slave_mask, PIC_SLAVE_IMR); + outb(cached_master_mask, PIC_MASTER_IMR); + + /* enable all cached interrupts of bonito */ + LOONGSON_INTENSET = cached_bonito_irq_mask; + (void)LOONGSON_INTENSET; + mmiowb(); +} + +void arch_suspend_disable_irqs(void) +{ + /* disable all mips interrupts */ + local_irq_disable(); + + /* disable all interrupts of i8259A */ + cached_slave_mask = inb(PIC_SLAVE_IMR); + cached_master_mask = inb(PIC_MASTER_IMR); + + outb(0xff, PIC_SLAVE_IMR); + inb(PIC_SLAVE_IMR); + outb(0xff, PIC_MASTER_IMR); + inb(PIC_MASTER_IMR); + + /* disable all interrupts of bonito */ + cached_bonito_irq_mask = LOONGSON_INTEN; + LOONGSON_INTENCLR = 0xffff; + (void)LOONGSON_INTENCLR; + mmiowb(); +} + +#define I8042_KBD_IRQ 1 +#define SCI_IRQ_NUM 0x0A /* system control interface */ + +/* i8042, sci are connnectted to i8259A */ +static void setup_wakeup_interrupt(void) +{ + int irq_mask; + + /* open the keyboard irq in i8259A */ + outb((0xff & ~(1 << I8042_KBD_IRQ)), PIC_MASTER_IMR); + irq_mask = inb(PIC_MASTER_IMR); + /* enable keyboard port */ + i8042_enable_kbd_port(); + + /* there is a need to wakeup the cpu via sci interrupt with relative + * lid openning event + */ + outb(irq_mask & ~(1 << (SCI_IRQ_NUM - 8)), PIC_MASTER_IMR); + inb(PIC_MASTER_IMR); + outb(0xff & ~(1 << (SCI_IRQ_NUM - 8)), PIC_SLAVE_IMR); + inb(PIC_SLAVE_IMR); +} + +extern int ec_query_seq(unsigned char cmd); +extern int sci_get_event_num(void); + +static int wakeup_loongson(void) +{ + int irq; + + /* query the interrupt number */ + irq = mach_i8259_irq(); + if (irq < 0) + return 0; + prom_printf("irq = %d\n", irq); + + if (irq == I8042_KBD_IRQ) + return 1; + else if (irq == SCI_IRQ_NUM) { + int ret, sci_event; + /* query the event number */ + ret = ec_query_seq(CMD_GET_EVENT_NUM); + if (ret < 0) + return 0; + sci_event = sci_get_event_num(); + prom_printf("sci event = %d\n", sci_event); + if (sci_event < 0) + return 0; + if (sci_event == SCI_EVENT_NUM_LID) { + int lid_status; + /* check the LID status */ + lid_status = ec_read(REG_LID_DETECT); + prom_printf("lid status = %d\n", lid_status); + /* wakeup cpu when people open the LID */ + if (lid_status == BIT_LID_DETECT_ON) + return 1; + } + } + return 0; +} + +static void wait_for_wakeup_events(void) +{ +wait: + if (!wakeup_loongson()) { + LOONGSON_CHIPCFG0 &= ~0x7; + goto wait; + } +} + +/* stop all perf counters by default + * $24 is the control register of loongson perf counter + */ +static inline void stop_perf_counters(void) +{ + __write_64bit_c0_register($24, 0, 0); +} + + +static void loongson_suspend_enter(void) +{ + static unsigned int cached_cpu_freq; + + prom_printf("suspend: try to setup the wakeup interrupt (keyboard interrupt)\n"); + setup_wakeup_interrupt(); + + /* stop all perf counters */ + stop_perf_counters(); + + cached_cpu_freq = LOONGSON_CHIPCFG0; + + /* handle the old delayed kbd interrupt */ + LOONGSON_CHIPCFG0 &= ~0x7; /* Put CPU into wait mode */ + i8042_flush(); + + /* handle the real wakeup interrupt */ + LOONGSON_CHIPCFG0 &= ~0x7; + mmiowb(); + + /* if the events are really what we want to wakeup cpu, wake up it, + * otherwise, we Put CPU into wait mode again. + */ + prom_printf("suspend: here we wait for several events to wake up cpu\n"); + wait_for_wakeup_events(); + + LOONGSON_CHIPCFG0 = cached_cpu_freq; + mmiowb(); +} + +static unsigned int cached_camera_status; +static unsigned int cached_mute_status; + +static void mach_suspend(void) +{ + unsigned int value; + + /* LCD backlight off */ + ec_write(REG_BACKLIGHT_CTRL, BIT_BACKLIGHT_OFF); + + /* close lcd output */ + outb(0x31, 0x3c4); + value = inb(0x3c5); + value = (value & 0xf8) | 0x02; + outb(0x31, 0x3c4); + outb(value, 0x3c5); + + /* close vga output */ + outb(0x21, 0x3c4); + value = inb(0x3c5); + value |= (1 << 7); + outb(0x21, 0x3c4); + outb(value, 0x3c5); + + /* poweroff three usb ports */ + ec_write(0xf461, 0x00); + ec_write(0xf462, 0x00); + ec_write(0xf463, 0x00); + + /* poweroff camera */ + cached_camera_status = ec_read(REG_CAMERA_STATUS); + if (cached_camera_status) { + value = ec_read(REG_CAMERA_CONTROL); + ec_write(REG_CAMERA_CONTROL, value | (1 << 1)); + } + + /* MUTE */ + cached_mute_status = ec_read(REG_AUDIO_MUTE); + ec_write(REG_AUDIO_MUTE, BIT_AUDIO_MUTE_ON); + + /* minimize the speed of FAN */ + ec_write(0xf459, 1); /* change the fan to manual mode */ + ec_write(0xf4cc, 1); /* change the speed to the lowest one, not turn it off */ + +#ifdef CONFIG_CS5536_MFGPT + /* stop counting of cs5536 mfgpt timer */ + outw(inw(MFGPT0_SETUP) | (1 << 11) , MFGPT0_SETUP); +#endif +} + +static void mach_resume(void) +{ + unsigned int value; + + /* LCD backlight on */ + ec_write(REG_BACKLIGHT_CTRL, BIT_BACKLIGHT_ON); + + /* open lcd output */ + outb(0x31, 0x3c4); + value = inb(0x3c5); + value = (value & 0xf8) | 0x03; + outb(0x31, 0x3c4); + outb(value, 0x3c5); + + /* open vga output */ + outb(0x21, 0x3c4); + value = inb(0x3c5); + value &= ~(1 << 7); + outb(0x21, 0x3c4); + outb(value, 0x3c5); + + /* there is a need to enable the bonito interrupt here to fix the + * problem of powering on usb ports */ + LOONGSON_INTENSET = cached_bonito_irq_mask; + (void)LOONGSON_INTENSET; + mmiowb(); + /* power on three usb ports */ + ec_write(0xf461, 0x01); + ec_write(0xf462, 0x01); + ec_write(0xf463, 0x01); + + /* resume camera */ + ec_write(REG_CAMERA_CONTROL, cached_camera_status); + + /* resume the status of mute */ + ec_write(REG_AUDIO_MUTE, cached_mute_status); + + /* resume FAN */ + ec_write(0xf459, 0); /* change the fan to auto mode */ + +#ifdef CONFIG_CS5536_MFGPT + /* enable counting of cs5536 mfgpt timer */ + outw(inw(MFGPT0_SETUP) & ~(1 << 11) , MFGPT0_SETUP); +#endif +} + +static int loongson_pm_enter(suspend_state_t state) +{ + prom_printf("suspend: try to call mach specific suspend\n"); + mach_suspend(); + + prom_printf("suspend: Enter into the wait mode of loongson cpu\n"); + loongson_suspend_enter(); + prom_printf("resume: waked up from wait mode of loongson cpu\n"); + + mach_resume(); + prom_printf("resume: return from mach specific resume\n"); + + return 0; +} + +static int loongson_pm_valid_state(suspend_state_t state) +{ + switch (state) { + case PM_SUSPEND_ON: + case PM_SUSPEND_STANDBY: + case PM_SUSPEND_MEM: + return 1; + + default: + return 0; + } +} + +static struct platform_suspend_ops loongson_pm_ops = { + .valid = loongson_pm_valid_state, + .enter = loongson_pm_enter, +}; + +static int __init loongson_pm_init(void) +{ + suspend_set_ops(&loongson_pm_ops); + + return 0; +} +arch_initcall(loongson_pm_init); diff -Nur linux-2.6.30.5.orig/arch/mips/loongson/yeeloong-2f/reset.c linux-2.6.30.5/arch/mips/loongson/yeeloong-2f/reset.c --- linux-2.6.30.5.orig/arch/mips/loongson/yeeloong-2f/reset.c 1970-01-01 01:00:00.000000000 +0100 +++ linux-2.6.30.5/arch/mips/loongson/yeeloong-2f/reset.c 2009-08-23 19:01:04.000000000 +0200 @@ -0,0 +1,91 @@ +/* Board-specific reboot/shutdown routines + * Copyright (c) 2009 Philippe Vachon + * + * Copyright (C) 2009 Lemote Inc. & Insititute of Computing Technology + * Author: Wu Zhangjin, wuzj@lemote.com + * + * 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. + */ + +#include +#include + +#include +#include + +/* + * The following registers are determined by the EC index configuration. + * 1, fill the PORT_HIGH as EC register high part. + * 2, fill the PORT_LOW as EC register low part. + * 3, fill the PORT_DATA as EC register write data or get the data from it. + */ +#define EC_RESET_IO_PORT_HIGH 0x0381 +#define EC_RESET_IO_PORT_LOW 0x0382 +#define EC_RESET_IO_PORT_DATA 0x0383 +#define REG_RESET_HIGH 0xF4 /* reset the machine auto-clear : rd/wr */ +#define REG_RESET_LOW 0xEC +#define BIT_RESET_ON (1 << 0) + +/* 7inch yeeloong have the different shutdown hardware logic from 8.9inch */ +#define EC_SHUTDOWN_IO_PORT_HIGH 0xff2d +#define EC_SHUTDOWN_IO_PORT_LOW 0xff2e +#define EC_SHUTDOWN_IO_PORT_DATA 0xff2f +#define REG_SHUTDOWN_HIGH 0xFC +#define REG_SHUTDOWN_LOW 0x29 +#define BIT_SHUTDOWN_ON (1 << 1) + +void mach_prepare_reboot(void) +{ + /* + * reset cpu to full speed, this is needed when enabling cpu frequency + * scalling + */ + LOONGSON_CHIPCFG0 |= 0x7; + + /* sending an reset signal to EC(embedded controller) */ + writeb(REG_RESET_HIGH, + (u8 *) (mips_io_port_base + EC_RESET_IO_PORT_HIGH)); + writeb(REG_RESET_LOW, + (u8 *) (mips_io_port_base + EC_RESET_IO_PORT_LOW)); + mmiowb(); + writeb(BIT_RESET_ON, + (u8 *) (mips_io_port_base + EC_RESET_IO_PORT_DATA)); + mmiowb(); +} + +void mach_prepare_shutdown(void) +{ + const char *system_type = get_system_type(); + + if (strstr(system_type, "8.9inch") != NULL) { + /* cpu-gpio0 output low */ + LOONGSON_GPIODATA &= ~0x00000001; + /* cpu-gpio0 as output */ + LOONGSON_GPIOIE &= ~0x00000001; + } else if (strstr(system_type, "7inch") != NULL) { + u8 val; + u64 i; + + writeb(REG_SHUTDOWN_HIGH, + (u8 *) (mips_io_port_base + EC_SHUTDOWN_IO_PORT_HIGH)); + writeb(REG_SHUTDOWN_LOW, + (u8 *) (mips_io_port_base + EC_SHUTDOWN_IO_PORT_LOW)); + mmiowb(); + val = + readb((u8 *) (mips_io_port_base + + EC_SHUTDOWN_IO_PORT_DATA)); + writeb(val & (~BIT_SHUTDOWN_ON), + (u8 *) (mips_io_port_base + EC_SHUTDOWN_IO_PORT_DATA)); + mmiowb(); + /* need enough wait here... how many microseconds needs? */ + for (i = 0; i < 0x10000; i++) + delay(); + writeb(val | BIT_SHUTDOWN_ON, + (u8 *) (mips_io_port_base + EC_SHUTDOWN_IO_PORT_DATA)); + mmiowb(); + } else + printk(KERN_INFO "you can shutdown the power safely now!\n"); +} diff -Nur linux-2.6.30.5.orig/arch/mips/Makefile linux-2.6.30.5/arch/mips/Makefile --- linux-2.6.30.5.orig/arch/mips/Makefile 2009-08-16 23:19:38.000000000 +0200 +++ linux-2.6.30.5/arch/mips/Makefile 2009-08-23 20:58:41.000000000 +0200 @@ -120,7 +120,14 @@ cflags-$(CONFIG_CPU_VR41XX) += -march=r4100 -Wa,--trap cflags-$(CONFIG_CPU_R4X00) += -march=r4600 -Wa,--trap cflags-$(CONFIG_CPU_TX49XX) += -march=r4600 -Wa,--trap -cflags-$(CONFIG_CPU_LOONGSON2) += -march=r4600 -Wa,--trap + +# only gcc >= 4.4 have the loongson-specific support +cflags-$(CONFIG_CPU_LOONGSON2) += -Wa,--trap +cflags-$(CONFIG_CPU_LOONGSON2E) += \ + $(call cc-option,-march=loongson2e,-march=r4600) +cflags-$(CONFIG_CPU_LOONGSON2F) += \ + $(call cc-option,-march=loongson2f,-march=r4600) + cflags-$(CONFIG_CPU_MIPS32_R1) += $(call cc-option,-march=mips32,-mips32 -U_MIPS_ISA -D_MIPS_ISA=_MIPS_ISA_MIPS32) \ -Wa,-mips32 -Wa,--trap cflags-$(CONFIG_CPU_MIPS32_R2) += $(call cc-option,-march=mips32r2,-mips32r2 -U_MIPS_ISA -D_MIPS_ISA=_MIPS_ISA_MIPS32) \ @@ -305,11 +312,15 @@ load-$(CONFIG_WR_PPMC) += 0xffffffff80100000 # -# lemote fulong mini-PC board +# loongson family machines # -core-$(CONFIG_LEMOTE_FULONG) +=arch/mips/lemote/lm2e/ -load-$(CONFIG_LEMOTE_FULONG) +=0xffffffff80100000 -cflags-$(CONFIG_LEMOTE_FULONG) += -I$(srctree)/arch/mips/include/asm/mach-lemote +all-$(CONFIG_MACH_LOONGSON) += zImage +core-$(CONFIG_MACH_LOONGSON) +=arch/mips/loongson/ +cflags-$(CONFIG_MACH_LOONGSON) += -I$(srctree)/arch/mips/include/asm/mach-loongson \ + -mno-branch-likely +load-$(CONFIG_LEMOTE_FULOONG2E) +=0xffffffff80100000 +load-$(CONFIG_LEMOTE_FULOONG2F) +=0xffffffff80200000 +load-$(CONFIG_LEMOTE_YEELOONG2F) +=0xffffffff80200000 # # MIPS Malta board @@ -675,11 +686,19 @@ drivers-$(CONFIG_OPROFILE) += arch/mips/oprofile/ +# suspend and hibernation support +drivers-$(CONFIG_PM) += arch/mips/power/ + ifdef CONFIG_LASAT rom.bin rom.sw: vmlinux $(Q)$(MAKE) $(build)=arch/mips/lasat/image $@ endif +ifdef CONFIG_MACH_LOONGSON +zImage: vmlinux + $(Q)$(MAKE) $(build)=arch/mips/loongson/image $@ +endif + # # Some machines like the Indy need 32-bit ELF binaries for booting purposes. # Other need ECOFF, so we build a 32-bit ELF binary for them which we then @@ -728,6 +747,7 @@ archclean: @$(MAKE) $(clean)=arch/mips/boot + @$(MAKE) $(clean)=arch/mips/loongson/image @$(MAKE) $(clean)=arch/mips/lasat define archhelp diff -Nur linux-2.6.30.5.orig/arch/mips/mm/uasm.c linux-2.6.30.5/arch/mips/mm/uasm.c --- linux-2.6.30.5.orig/arch/mips/mm/uasm.c 2009-08-16 23:19:38.000000000 +0200 +++ linux-2.6.30.5/arch/mips/mm/uasm.c 2009-08-23 19:01:04.000000000 +0200 @@ -15,6 +15,7 @@ #include #include #include +#include #include #include diff -Nur linux-2.6.30.5.orig/arch/mips/oprofile/common.c linux-2.6.30.5/arch/mips/oprofile/common.c --- linux-2.6.30.5.orig/arch/mips/oprofile/common.c 2009-08-16 23:19:38.000000000 +0200 +++ linux-2.6.30.5/arch/mips/oprofile/common.c 2009-08-23 19:01:04.000000000 +0200 @@ -16,6 +16,7 @@ extern struct op_mips_model op_model_mipsxx_ops __attribute__((weak)); extern struct op_mips_model op_model_rm9000_ops __attribute__((weak)); +extern struct op_mips_model op_model_loongson2_ops __attribute__((weak)); static struct op_mips_model *model; @@ -93,6 +94,10 @@ case CPU_RM9000: lmodel = &op_model_rm9000_ops; break; + + case CPU_LOONGSON2: + lmodel = &op_model_loongson2_ops; + break; }; if (!lmodel) diff -Nur linux-2.6.30.5.orig/arch/mips/oprofile/Makefile linux-2.6.30.5/arch/mips/oprofile/Makefile --- linux-2.6.30.5.orig/arch/mips/oprofile/Makefile 2009-08-16 23:19:38.000000000 +0200 +++ linux-2.6.30.5/arch/mips/oprofile/Makefile 2009-08-23 19:01:04.000000000 +0200 @@ -15,3 +15,4 @@ oprofile-$(CONFIG_CPU_R10000) += op_model_mipsxx.o oprofile-$(CONFIG_CPU_SB1) += op_model_mipsxx.o oprofile-$(CONFIG_CPU_RM9000) += op_model_rm9000.o +oprofile-$(CONFIG_CPU_LOONGSON2) += op_model_loongson2.o diff -Nur linux-2.6.30.5.orig/arch/mips/oprofile/op_model_loongson2.c linux-2.6.30.5/arch/mips/oprofile/op_model_loongson2.c --- linux-2.6.30.5.orig/arch/mips/oprofile/op_model_loongson2.c 1970-01-01 01:00:00.000000000 +0100 +++ linux-2.6.30.5/arch/mips/oprofile/op_model_loongson2.c 2009-08-23 19:01:04.000000000 +0200 @@ -0,0 +1,186 @@ +/* + * Loongson2 performance counter driver for oprofile + * + * Copyright (C) 2009 Lemote Inc. & Insititute of Computing Technology + * Author: Yanhua + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + * + */ +#include +#include +#include +#include +#include +#include +#include + +#include +#include /* LOONGSON_PERFCNT_IRQ */ +#include "op_impl.h" + +/* + * a patch should be sent to oprofile with the loongson-specific support. + * otherwise, the oprofile tool will not recognize this and complain about + * "cpu_type 'unset' is not valid". + */ +#define LOONGSON_CPU_TYPE "mips/loongson2" + +#define LOONGSON_COUNTER1_EVENT(event) ((event & 0x0f) << 5) +#define LOONGSON_COUNTER2_EVENT(event) ((event & 0x0f) << 9) + +#define LOONGSON_PERFCNT_EXL (1UL << 0) +#define LOONGSON_PERFCNT_KERNEL (1UL << 1) +#define LOONGSON_PERFCNT_SUPERVISOR (1UL << 2) +#define LOONGSON_PERFCNT_USER (1UL << 3) +#define LOONGSON_PERFCNT_INT_EN (1UL << 4) +#define LOONGSON_PERFCNT_OVERFLOW (1ULL << 31) + +/* Loongson2 performance counter register */ +#define read_c0_perflo() __read_64bit_c0_register($24, 0) +#define write_c0_perflo(val) __write_64bit_c0_register($24, 0, val) +#define read_c0_perfhi() __read_64bit_c0_register($25, 0) +#define write_c0_perfhi(val) __write_64bit_c0_register($25, 0, val) + +static struct loongson2_register_config { + unsigned int ctrl; + unsigned long long reset_counter1; + unsigned long long reset_counter2; + int cnt1_enable, cnt2_enable; +} reg; + +DEFINE_SPINLOCK(sample_lock); + +static char *oprofid = "LoongsonPerf"; +static irqreturn_t loongson2_perfcount_handler(int irq, void *dev_id); +/* Compute all of the registers in preparation for enabling profiling. */ + +static void loongson2_reg_setup(struct op_counter_config *cfg) +{ + unsigned int ctrl = 0; + + reg.reset_counter1 = 0; + reg.reset_counter2 = 0; + /* Compute the performance counter ctrl word. */ + /* For now count kernel and user mode */ + if (cfg[0].enabled) { + ctrl |= LOONGSON_COUNTER1_EVENT(cfg[0].event) | + LOONGSON_PERFCNT_INT_EN; + if (cfg[0].kernel) + ctrl |= LOONGSON_PERFCNT_KERNEL; + if (cfg[0].user) + ctrl |= LOONGSON_PERFCNT_USER; + reg.reset_counter1 = 0x80000000ULL - cfg[0].count; + } + + if (cfg[1].enabled) { + ctrl |= LOONGSON_COUNTER2_EVENT(cfg[1].event) | + LOONGSON_PERFCNT_INT_EN; + if (cfg[1].kernel) + ctrl |= LOONGSON_PERFCNT_KERNEL; + if (cfg[1].user) + ctrl |= LOONGSON_PERFCNT_USER; + reg.reset_counter2 = (0x80000000ULL - cfg[1].count); + } + + if (cfg[0].enabled || cfg[1].enabled) + ctrl |= LOONGSON_PERFCNT_EXL; + + reg.ctrl = ctrl; + + reg.cnt1_enable = cfg[0].enabled; + reg.cnt2_enable = cfg[1].enabled; + +} + +/* Program all of the registers in preparation for enabling profiling. */ + +static void loongson2_cpu_setup(void *args) +{ + uint64_t perfcount; + + perfcount = (reg.reset_counter2 << 32) | reg.reset_counter1; + write_c0_perfhi(perfcount); +} + +static void loongson2_cpu_start(void *args) +{ + /* Start all counters on current CPU */ + if (reg.cnt1_enable || reg.cnt2_enable) + write_c0_perflo(reg.ctrl); +} + +static void loongson2_cpu_stop(void *args) +{ + /* Stop all counters on current CPU */ + write_c0_perflo(0); + memset(®, 0, sizeof(reg)); +} + +static irqreturn_t loongson2_perfcount_handler(int irq, void *dev_id) +{ + uint64_t counter, counter1, counter2; + struct pt_regs *regs = get_irq_regs(); + int enabled; + unsigned long flags; + + /* + * LOONGSON2 defines two 32-bit performance counters. + * To avoid a race updating the registers we need to stop the counters + * while we're messing with + * them ... + */ + + /* Check whether the irq belongs to me */ + enabled = reg.cnt1_enable | reg.cnt2_enable; + if (!enabled) + return IRQ_NONE; + + counter = read_c0_perfhi(); + counter1 = counter & 0xffffffff; + counter2 = counter >> 32; + + spin_lock_irqsave(&sample_lock, flags); + + if (counter1 & LOONGSON_PERFCNT_OVERFLOW) { + if (reg.cnt1_enable) + oprofile_add_sample(regs, 0); + counter1 = reg.reset_counter1; + } + if (counter2 & LOONGSON_PERFCNT_OVERFLOW) { + if (reg.cnt2_enable) + oprofile_add_sample(regs, 1); + counter2 = reg.reset_counter2; + } + + spin_unlock_irqrestore(&sample_lock, flags); + + write_c0_perfhi((counter2 << 32) | counter1); + + return IRQ_HANDLED; +} + +static int __init loongson2_init(void) +{ + return request_irq(LOONGSON_PERFCNT_IRQ, loongson2_perfcount_handler, + IRQF_SHARED, "Perfcounter", oprofid); +} + +static void loongson2_exit(void) +{ + write_c0_perflo(0); + free_irq(LOONGSON_PERFCNT_IRQ, oprofid); +} + +struct op_mips_model op_model_loongson2_ops = { + .reg_setup = loongson2_reg_setup, + .cpu_setup = loongson2_cpu_setup, + .init = loongson2_init, + .exit = loongson2_exit, + .cpu_start = loongson2_cpu_start, + .cpu_stop = loongson2_cpu_stop, + .cpu_type = LOONGSON_CPU_TYPE, + .num_counters = 2 +}; diff -Nur linux-2.6.30.5.orig/arch/mips/pci/fixup-fuloong2e.c linux-2.6.30.5/arch/mips/pci/fixup-fuloong2e.c --- linux-2.6.30.5.orig/arch/mips/pci/fixup-fuloong2e.c 1970-01-01 01:00:00.000000000 +0100 +++ linux-2.6.30.5/arch/mips/pci/fixup-fuloong2e.c 2009-08-23 19:01:04.000000000 +0200 @@ -0,0 +1,243 @@ +/* + * fixup-fuloong2e.c + * + * Copyright (C) 2004 ICT CAS + * Author: Li xiaoyu, ICT CAS + * lixy@ict.ac.cn + * + * Copyright (C) 2007 Lemote, Inc. & Institute of Computing Technology + * Author: Fuxin Zhang, zhangfx@lemote.com + * + * 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 SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN + * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * 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., + * 675 Mass Ave, Cambridge, MA 02139, USA. + * + */ +#include +#include + +#include + +/* South bridge slot number is set by the pci probe process */ +static u8 sb_slot = 5; + +int __init pcibios_map_irq(struct pci_dev *dev, u8 slot, u8 pin) +{ + int irq = 0; + + if (slot == sb_slot) { + switch (PCI_FUNC(dev->devfn)) { + case 2: + irq = 10; + break; + case 3: + irq = 11; + break; + case 5: + irq = 9; + break; + } + } else { + irq = LOONGSON_IRQ_BASE + 25 + pin; + } + return irq; + +} + +/* Do platform specific device initialization at pci_enable_device() time */ +int pcibios_plat_dev_init(struct pci_dev *dev) +{ + return 0; +} + +static void __init fuloong2e_nec_fixup(struct pci_dev *pdev) +{ + unsigned int val; + + /* Configues port 1, 2, 3, 4 to be validate*/ + pci_read_config_dword(pdev, 0xe0, &val); + pci_write_config_dword(pdev, 0xe0, (val & ~7) | 0x4); + + /* System clock is 48-MHz Oscillator. */ + pci_write_config_dword(pdev, 0xe4, 1 << 5); +} + +static void __init fuloong2e_686b_func0_fixup(struct pci_dev *pdev) +{ + unsigned char c; + + sb_slot = PCI_SLOT(pdev->devfn); + + printk(KERN_INFO "via686b fix: ISA bridge\n"); + + /* Enable I/O Recovery time */ + pci_write_config_byte(pdev, 0x40, 0x08); + + /* Enable ISA refresh */ + pci_write_config_byte(pdev, 0x41, 0x01); + + /* disable ISA line buffer */ + pci_write_config_byte(pdev, 0x45, 0x00); + + /* Gate INTR, and flush line buffer */ + pci_write_config_byte(pdev, 0x46, 0xe0); + + /* Disable PCI Delay Transaction, Enable EISA ports 4D0/4D1. */ + /* pci_write_config_byte(pdev, 0x47, 0x20); */ + + /* + * enable PCI Delay Transaction, Enable EISA ports 4D0/4D1. + * enable time-out timer + */ + pci_write_config_byte(pdev, 0x47, 0xe6); + + /* + * enable level trigger on pci irqs: 9,10,11,13 + * important! without this PCI interrupts won't work + */ + outb(0x2e, 0x4d1); + + /* 512 K PCI Decode */ + pci_write_config_byte(pdev, 0x48, 0x01); + + /* Wait for PGNT before grant to ISA Master/DMA */ + pci_write_config_byte(pdev, 0x4a, 0x84); + + /* + * Plug'n'Play + * + * Parallel DRQ 3, Floppy DRQ 2 (default) + */ + pci_write_config_byte(pdev, 0x50, 0x0e); + + /* + * IRQ Routing for Floppy and Parallel port + * + * IRQ 6 for floppy, IRQ 7 for parallel port + */ + pci_write_config_byte(pdev, 0x51, 0x76); + + /* IRQ Routing for serial ports (take IRQ 3 and 4) */ + pci_write_config_byte(pdev, 0x52, 0x34); + + /* All IRQ's level triggered. */ + pci_write_config_byte(pdev, 0x54, 0x00); + + /* route PIRQA-D irq */ + pci_write_config_byte(pdev, 0x55, 0x90); /* bit 7-4, PIRQA */ + pci_write_config_byte(pdev, 0x56, 0xba); /* bit 7-4, PIRQC; */ + /* 3-0, PIRQB */ + pci_write_config_byte(pdev, 0x57, 0xd0); /* bit 7-4, PIRQD */ + + /* enable function 5/6, audio/modem */ + pci_read_config_byte(pdev, 0x85, &c); + c &= ~(0x3 << 2); + pci_write_config_byte(pdev, 0x85, c); + + printk(KERN_INFO"via686b fix: ISA bridge done\n"); +} + +static void __init fuloong2e_686b_func1_fixup(struct pci_dev *pdev) +{ + printk(KERN_INFO"via686b fix: IDE\n"); + + /* Modify IDE controller setup */ + pci_write_config_byte(pdev, PCI_LATENCY_TIMER, 48); + pci_write_config_byte(pdev, PCI_COMMAND, + PCI_COMMAND_IO | PCI_COMMAND_MEMORY | + PCI_COMMAND_MASTER); + pci_write_config_byte(pdev, 0x40, 0x0b); + /* legacy mode */ + pci_write_config_byte(pdev, 0x42, 0x09); + +#if 1/* play safe, otherwise we may see notebook's usb keyboard lockup */ + /* disable read prefetch/write post buffers */ + pci_write_config_byte(pdev, 0x41, 0x02); + + /* use 3/4 as fifo thresh hold */ + pci_write_config_byte(pdev, 0x43, 0x0a); + pci_write_config_byte(pdev, 0x44, 0x00); + + pci_write_config_byte(pdev, 0x45, 0x00); +#else + pci_write_config_byte(pdev, 0x41, 0xc2); + pci_write_config_byte(pdev, 0x43, 0x35); + pci_write_config_byte(pdev, 0x44, 0x1c); + + pci_write_config_byte(pdev, 0x45, 0x10); +#endif + + printk(KERN_INFO"via686b fix: IDE done\n"); +} + +static void __init fuloong2e_686b_func2_fixup(struct pci_dev *pdev) +{ + /* irq routing */ + pci_write_config_byte(pdev, PCI_INTERRUPT_LINE, 10); +} + +static void __init fuloong2e_686b_func3_fixup(struct pci_dev *pdev) +{ + /* irq routing */ + pci_write_config_byte(pdev, PCI_INTERRUPT_LINE, 11); +} + +static void __init fuloong2e_686b_func5_fixup(struct pci_dev *pdev) +{ + unsigned int val; + unsigned char c; + + /* enable IO */ + pci_write_config_byte(pdev, PCI_COMMAND, + PCI_COMMAND_IO | PCI_COMMAND_MEMORY | + PCI_COMMAND_MASTER); + pci_read_config_dword(pdev, 0x4, &val); + pci_write_config_dword(pdev, 0x4, val | 1); + + /* route ac97 IRQ */ + pci_write_config_byte(pdev, 0x3c, 9); + + pci_read_config_byte(pdev, 0x8, &c); + + /* link control: enable link & SGD PCM output */ + pci_write_config_byte(pdev, 0x41, 0xcc); + + /* disable game port, FM, midi, sb, enable write to reg2c-2f */ + pci_write_config_byte(pdev, 0x42, 0x20); + + /* we are using Avance logic codec */ + pci_write_config_word(pdev, 0x2c, 0x1005); + pci_write_config_word(pdev, 0x2e, 0x4710); + pci_read_config_dword(pdev, 0x2c, &val); + + pci_write_config_byte(pdev, 0x42, 0x0); +} + +DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C686, + fuloong2e_686b_func0_fixup); +DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C586_1, + fuloong2e_686b_func1_fixup); +DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C586_2, + fuloong2e_686b_func2_fixup); +DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C586_3, + fuloong2e_686b_func3_fixup); +DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C686_5, + fuloong2e_686b_func5_fixup); +DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_NEC, PCI_DEVICE_ID_NEC_USB, + fuloong2e_nec_fixup); diff -Nur linux-2.6.30.5.orig/arch/mips/pci/fixup-lemote2f.c linux-2.6.30.5/arch/mips/pci/fixup-lemote2f.c --- linux-2.6.30.5.orig/arch/mips/pci/fixup-lemote2f.c 1970-01-01 01:00:00.000000000 +0100 +++ linux-2.6.30.5/arch/mips/pci/fixup-lemote2f.c 2009-08-23 19:01:04.000000000 +0200 @@ -0,0 +1,171 @@ +/* + * Copyright (C) 2008 Lemote Technology + * Copyright (C) 2004 ICT CAS + * Author: Li xiaoyu, lixy@ict.ac.cn + * + * Copyright (C) 2007 Lemote, Inc. & Institute of Computing Technology + * Author: Fuxin Zhang, zhangfx@lemote.com + * + * 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. + */ +#include +#include + +#include +#include +#include + +/* PCI interrupt pins + * + * These should not be changed, or you should consider loongson2f interrupt + * register and your pci card dispatch + */ + +#define PCIA 4 +#define PCIB 5 +#define PCIC 6 +#define PCID 7 + +/* all the pci device has the PCIA pin, check the datasheet. */ +static char irq_tab[][5] __initdata = { + /* INTA INTB INTC INTD */ + {0, 0, 0, 0, 0}, /* 11: Unused */ + {0, 0, 0, 0, 0}, /* 12: Unused */ + {0, 0, 0, 0, 0}, /* 13: Unused */ + {0, 0, 0, 0, 0}, /* 14: Unused */ + {0, 0, 0, 0, 0}, /* 15: Unused */ + {0, 0, 0, 0, 0}, /* 16: Unused */ + {0, PCIA, 0, 0, 0}, /* 17: RTL8110-0 */ + {0, PCIB, 0, 0, 0}, /* 18: RTL8110-1 */ + {0, PCIC, 0, 0, 0}, /* 19: SiI3114 */ + {0, PCID, 0, 0, 0}, /* 20: 3-ports nec usb */ + {0, PCIA, PCIB, PCIC, PCID}, /* 21: PCI-SLOT */ + {0, 0, 0, 0, 0}, /* 22: Unused */ + {0, 0, 0, 0, 0}, /* 23: Unused */ + {0, 0, 0, 0, 0}, /* 24: Unused */ + {0, 0, 0, 0, 0}, /* 25: Unused */ + {0, 0, 0, 0, 0}, /* 26: Unused */ + {0, 0, 0, 0, 0}, /* 27: Unused */ +}; + +int __init pcibios_map_irq(struct pci_dev *dev, u8 slot, u8 pin) +{ + int virq; + + if ((PCI_SLOT(dev->devfn) != PCI_IDSEL_CS5536) + && (PCI_SLOT(dev->devfn) < 32)) { + virq = irq_tab[slot][pin]; + printk(KERN_INFO "slot: %d, pin: %d, irq: %d\n", slot, pin, + virq + LOONGSON_IRQ_BASE); + if (virq != 0) + return LOONGSON_IRQ_BASE + virq; + else + return 0; + } else if (PCI_SLOT(dev->devfn) == PCI_IDSEL_CS5536) { /* cs5536 */ + switch (PCI_FUNC(dev->devfn)) { + case 2: + pci_write_config_byte(dev, PCI_INTERRUPT_LINE, + CS5536_IDE_INTR); + return 14; /* for IDE */ + case 3: + pci_write_config_byte(dev, PCI_INTERRUPT_LINE, + CS5536_ACC_INTR); + return 9; /* for AUDIO */ + case 4: /* for OHCI */ + case 5: /* for EHCI */ + case 6: /* for UDC */ + case 7: /* for OTG */ + pci_write_config_byte(dev, PCI_INTERRUPT_LINE, + CS5536_USB_INTR); + return 11; + } + return dev->irq; + } else { + printk(KERN_INFO " strange pci slot number.\n"); + return 0; + } +} + +/* Do platform specific device initialization at pci_enable_device() time */ +int pcibios_plat_dev_init(struct pci_dev *dev) +{ + return 0; +} + +/* CS5536 SPEC. fixup */ +static void __init loongson_cs5536_isa_fixup(struct pci_dev *pdev) +{ + /* the uart1 and uart2 interrupt in PIC is enabled as default */ + pci_write_config_dword(pdev, PCI_UART1_INT_REG, 1); + pci_write_config_dword(pdev, PCI_UART2_INT_REG, 1); + return; +} + +static void __init loongson_cs5536_ide_fixup(struct pci_dev *pdev) +{ + /* setting the mutex pin as IDE function */ + pci_write_config_dword(pdev, PCI_IDE_CFG_REG, + CS5536_IDE_FLASH_SIGNATURE); + return; +} + +static void __init loongson_cs5536_acc_fixup(struct pci_dev *pdev) +{ + u8 val; + + /* enable the AUDIO interrupt in PIC */ + pci_write_config_dword(pdev, PCI_ACC_INT_REG, 1); + +#if 1 + pci_read_config_byte(pdev, PCI_LATENCY_TIMER, &val); + printk(KERN_INFO "cs5536 acc latency 0x%x\n", val); + pci_write_config_byte(pdev, PCI_LATENCY_TIMER, 0xc0); +#endif + return; +} + +static void __init loongson_cs5536_ohci_fixup(struct pci_dev *pdev) +{ + /* enable the OHCI interrupt in PIC */ + /* THE OHCI, EHCI, UDC, OTG are shared with interrupt in PIC */ + pci_write_config_dword(pdev, PCI_OHCI_INT_REG, 1); + return; +} + +static void __init loongson_cs5536_ehci_fixup(struct pci_dev *pdev) +{ + u32 hi, lo; + + /* Serial short detect enable */ + _rdmsr(USB_MSR_REG(USB_CONFIG), &hi, &lo); + _wrmsr(USB_MSR_REG(USB_CONFIG), (1 << 1) | (1 << 2) | (1 << 3), lo); + + /* setting the USB2.0 micro frame length */ + pci_write_config_dword(pdev, PCI_EHCI_FLADJ_REG, 0x2000); + return; +} + +static void __init loongson_nec_fixup(struct pci_dev *pdev) +{ + unsigned int val; + + pci_read_config_dword(pdev, 0xe0, &val); + /* Only 2 port be used */ + pci_write_config_dword(pdev, 0xe0, (val & ~3) | 0x2); +} + +DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_CS5536_ISA, + loongson_cs5536_isa_fixup); +DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_CS5536_OHC, + loongson_cs5536_ohci_fixup); +DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_CS5536_EHC, + loongson_cs5536_ehci_fixup); +DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_CS5536_AUDIO, + loongson_cs5536_acc_fixup); +DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_CS5536_IDE, + loongson_cs5536_ide_fixup); +DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_NEC, PCI_DEVICE_ID_NEC_USB, + loongson_nec_fixup); diff -Nur linux-2.6.30.5.orig/arch/mips/pci/fixup-lm2e.c linux-2.6.30.5/arch/mips/pci/fixup-lm2e.c --- linux-2.6.30.5.orig/arch/mips/pci/fixup-lm2e.c 2009-08-16 23:19:38.000000000 +0200 +++ linux-2.6.30.5/arch/mips/pci/fixup-lm2e.c 1970-01-01 01:00:00.000000000 +0100 @@ -1,242 +0,0 @@ -/* - * fixup-lm2e.c - * - * Copyright (C) 2004 ICT CAS - * Author: Li xiaoyu, ICT CAS - * lixy@ict.ac.cn - * - * Copyright (C) 2007 Lemote, Inc. & Institute of Computing Technology - * Author: Fuxin Zhang, zhangfx@lemote.com - * - * 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 SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN - * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF - * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON - * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * 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., - * 675 Mass Ave, Cambridge, MA 02139, USA. - * - */ -#include -#include -#include - -/* South bridge slot number is set by the pci probe process */ -static u8 sb_slot = 5; - -int __init pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) -{ - int irq = 0; - - if (slot == sb_slot) { - switch (PCI_FUNC(dev->devfn)) { - case 2: - irq = 10; - break; - case 3: - irq = 11; - break; - case 5: - irq = 9; - break; - } - } else { - irq = BONITO_IRQ_BASE + 25 + pin; - } - return irq; - -} - -/* Do platform specific device initialization at pci_enable_device() time */ -int pcibios_plat_dev_init(struct pci_dev *dev) -{ - return 0; -} - -static void __init loongson2e_nec_fixup(struct pci_dev *pdev) -{ - unsigned int val; - - /* Configues port 1, 2, 3, 4 to be validate*/ - pci_read_config_dword(pdev, 0xe0, &val); - pci_write_config_dword(pdev, 0xe0, (val & ~7) | 0x4); - - /* System clock is 48-MHz Oscillator. */ - pci_write_config_dword(pdev, 0xe4, 1 << 5); -} - -static void __init loongson2e_686b_func0_fixup(struct pci_dev *pdev) -{ - unsigned char c; - - sb_slot = PCI_SLOT(pdev->devfn); - - printk(KERN_INFO "via686b fix: ISA bridge\n"); - - /* Enable I/O Recovery time */ - pci_write_config_byte(pdev, 0x40, 0x08); - - /* Enable ISA refresh */ - pci_write_config_byte(pdev, 0x41, 0x01); - - /* disable ISA line buffer */ - pci_write_config_byte(pdev, 0x45, 0x00); - - /* Gate INTR, and flush line buffer */ - pci_write_config_byte(pdev, 0x46, 0xe0); - - /* Disable PCI Delay Transaction, Enable EISA ports 4D0/4D1. */ - /* pci_write_config_byte(pdev, 0x47, 0x20); */ - - /* - * enable PCI Delay Transaction, Enable EISA ports 4D0/4D1. - * enable time-out timer - */ - pci_write_config_byte(pdev, 0x47, 0xe6); - - /* - * enable level trigger on pci irqs: 9,10,11,13 - * important! without this PCI interrupts won't work - */ - outb(0x2e, 0x4d1); - - /* 512 K PCI Decode */ - pci_write_config_byte(pdev, 0x48, 0x01); - - /* Wait for PGNT before grant to ISA Master/DMA */ - pci_write_config_byte(pdev, 0x4a, 0x84); - - /* - * Plug'n'Play - * - * Parallel DRQ 3, Floppy DRQ 2 (default) - */ - pci_write_config_byte(pdev, 0x50, 0x0e); - - /* - * IRQ Routing for Floppy and Parallel port - * - * IRQ 6 for floppy, IRQ 7 for parallel port - */ - pci_write_config_byte(pdev, 0x51, 0x76); - - /* IRQ Routing for serial ports (take IRQ 3 and 4) */ - pci_write_config_byte(pdev, 0x52, 0x34); - - /* All IRQ's level triggered. */ - pci_write_config_byte(pdev, 0x54, 0x00); - - /* route PIRQA-D irq */ - pci_write_config_byte(pdev, 0x55, 0x90); /* bit 7-4, PIRQA */ - pci_write_config_byte(pdev, 0x56, 0xba); /* bit 7-4, PIRQC; */ - /* 3-0, PIRQB */ - pci_write_config_byte(pdev, 0x57, 0xd0); /* bit 7-4, PIRQD */ - - /* enable function 5/6, audio/modem */ - pci_read_config_byte(pdev, 0x85, &c); - c &= ~(0x3 << 2); - pci_write_config_byte(pdev, 0x85, c); - - printk(KERN_INFO"via686b fix: ISA bridge done\n"); -} - -static void __init loongson2e_686b_func1_fixup(struct pci_dev *pdev) -{ - printk(KERN_INFO"via686b fix: IDE\n"); - - /* Modify IDE controller setup */ - pci_write_config_byte(pdev, PCI_LATENCY_TIMER, 48); - pci_write_config_byte(pdev, PCI_COMMAND, - PCI_COMMAND_IO | PCI_COMMAND_MEMORY | - PCI_COMMAND_MASTER); - pci_write_config_byte(pdev, 0x40, 0x0b); - /* legacy mode */ - pci_write_config_byte(pdev, 0x42, 0x09); - -#if 1/* play safe, otherwise we may see notebook's usb keyboard lockup */ - /* disable read prefetch/write post buffers */ - pci_write_config_byte(pdev, 0x41, 0x02); - - /* use 3/4 as fifo thresh hold */ - pci_write_config_byte(pdev, 0x43, 0x0a); - pci_write_config_byte(pdev, 0x44, 0x00); - - pci_write_config_byte(pdev, 0x45, 0x00); -#else - pci_write_config_byte(pdev, 0x41, 0xc2); - pci_write_config_byte(pdev, 0x43, 0x35); - pci_write_config_byte(pdev, 0x44, 0x1c); - - pci_write_config_byte(pdev, 0x45, 0x10); -#endif - - printk(KERN_INFO"via686b fix: IDE done\n"); -} - -static void __init loongson2e_686b_func2_fixup(struct pci_dev *pdev) -{ - /* irq routing */ - pci_write_config_byte(pdev, PCI_INTERRUPT_LINE, 10); -} - -static void __init loongson2e_686b_func3_fixup(struct pci_dev *pdev) -{ - /* irq routing */ - pci_write_config_byte(pdev, PCI_INTERRUPT_LINE, 11); -} - -static void __init loongson2e_686b_func5_fixup(struct pci_dev *pdev) -{ - unsigned int val; - unsigned char c; - - /* enable IO */ - pci_write_config_byte(pdev, PCI_COMMAND, - PCI_COMMAND_IO | PCI_COMMAND_MEMORY | - PCI_COMMAND_MASTER); - pci_read_config_dword(pdev, 0x4, &val); - pci_write_config_dword(pdev, 0x4, val | 1); - - /* route ac97 IRQ */ - pci_write_config_byte(pdev, 0x3c, 9); - - pci_read_config_byte(pdev, 0x8, &c); - - /* link control: enable link & SGD PCM output */ - pci_write_config_byte(pdev, 0x41, 0xcc); - - /* disable game port, FM, midi, sb, enable write to reg2c-2f */ - pci_write_config_byte(pdev, 0x42, 0x20); - - /* we are using Avance logic codec */ - pci_write_config_word(pdev, 0x2c, 0x1005); - pci_write_config_word(pdev, 0x2e, 0x4710); - pci_read_config_dword(pdev, 0x2c, &val); - - pci_write_config_byte(pdev, 0x42, 0x0); -} - -DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C686, - loongson2e_686b_func0_fixup); -DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C586_1, - loongson2e_686b_func1_fixup); -DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C586_2, - loongson2e_686b_func2_fixup); -DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C586_3, - loongson2e_686b_func3_fixup); -DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C686_5, - loongson2e_686b_func5_fixup); -DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_NEC, PCI_DEVICE_ID_NEC_USB, - loongson2e_nec_fixup); diff -Nur linux-2.6.30.5.orig/arch/mips/pci/Makefile linux-2.6.30.5/arch/mips/pci/Makefile --- linux-2.6.30.5.orig/arch/mips/pci/Makefile 2009-08-16 23:19:38.000000000 +0200 +++ linux-2.6.30.5/arch/mips/pci/Makefile 2009-08-23 19:01:04.000000000 +0200 @@ -26,7 +26,9 @@ obj-$(CONFIG_SOC_AU1500) += fixup-au1000.o ops-au1000.o obj-$(CONFIG_SOC_AU1550) += fixup-au1000.o ops-au1000.o obj-$(CONFIG_SOC_PNX8550) += fixup-pnx8550.o ops-pnx8550.o -obj-$(CONFIG_LEMOTE_FULONG) += fixup-lm2e.o ops-bonito64.o +obj-$(CONFIG_LEMOTE_FULOONG2E) += fixup-fuloong2e.o ops-loongson2.o +obj-$(CONFIG_LEMOTE_FULOONG2F) += fixup-lemote2f.o ops-loongson2.o +obj-$(CONFIG_LEMOTE_YEELOONG2F) += fixup-lemote2f.o ops-loongson2.o obj-$(CONFIG_MIPS_MALTA) += fixup-malta.o obj-$(CONFIG_PMC_MSP7120_GW) += fixup-pmcmsp.o ops-pmcmsp.o obj-$(CONFIG_PMC_MSP7120_EVAL) += fixup-pmcmsp.o ops-pmcmsp.o diff -Nur linux-2.6.30.5.orig/arch/mips/pci/ops-bonito64.c linux-2.6.30.5/arch/mips/pci/ops-bonito64.c --- linux-2.6.30.5.orig/arch/mips/pci/ops-bonito64.c 2009-08-16 23:19:38.000000000 +0200 +++ linux-2.6.30.5/arch/mips/pci/ops-bonito64.c 2009-08-23 19:01:04.000000000 +0200 @@ -29,20 +29,16 @@ #define PCI_ACCESS_READ 0 #define PCI_ACCESS_WRITE 1 -#ifdef CONFIG_LEMOTE_FULONG -#define CFG_SPACE_REG(offset) (void *)CKSEG1ADDR(BONITO_PCICFG_BASE | (offset)) -#define ID_SEL_BEGIN 11 -#else -#define CFG_SPACE_REG(offset) (void *)CKSEG1ADDR(_pcictrl_bonito_pcicfg + (offset)) +#define CFG_SPACE_REG(offset) \ + (void *)CKSEG1ADDR(_pcictrl_bonito_pcicfg + (offset)) #define ID_SEL_BEGIN 10 -#endif #define MAX_DEV_NUM (31 - ID_SEL_BEGIN) static int bonito64_pcibios_config_access(unsigned char access_type, struct pci_bus *bus, unsigned int devfn, int where, - u32 * data) + u32 *data) { u32 busnum = bus->number; u32 addr, type; @@ -77,10 +73,9 @@ addrp = CFG_SPACE_REG(addr & 0xffff); if (access_type == PCI_ACCESS_WRITE) { writel(cpu_to_le32(*data), addrp); -#ifndef CONFIG_LEMOTE_FULONG /* Wait till done */ - while (BONITO_PCIMSTAT & 0xF); -#endif + while (BONITO_PCIMSTAT & 0xF) + ; } else { *data = le32_to_cpu(readl(addrp)); } @@ -107,7 +102,7 @@ * read/write a 32bit word and mask/modify the data we actually want. */ static int bonito64_pcibios_read(struct pci_bus *bus, unsigned int devfn, - int where, int size, u32 * val) + int where, int size, u32 *val) { u32 data = 0; @@ -144,7 +139,7 @@ data = val; else { if (bonito64_pcibios_config_access(PCI_ACCESS_READ, bus, devfn, - where, &data)) + where, &data)) return -1; if (size == 1) diff -Nur linux-2.6.30.5.orig/arch/mips/pci/ops-loongson2.c linux-2.6.30.5/arch/mips/pci/ops-loongson2.c --- linux-2.6.30.5.orig/arch/mips/pci/ops-loongson2.c 1970-01-01 01:00:00.000000000 +0100 +++ linux-2.6.30.5/arch/mips/pci/ops-loongson2.c 2009-08-23 19:01:04.000000000 +0200 @@ -0,0 +1,213 @@ +/* + * Copyright (C) 1999, 2000, 2004 MIPS Technologies, Inc. + * All rights reserved. + * Authors: Carsten Langgaard + * Maciej W. Rozycki + * + * This program is free software; you can distribute it and/or modify it + * under the terms of the GNU General Public License (Version 2) as + * published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA. + * + * MIPS boards specific PCI support. + */ +#include +#include +#include +#include + +#include + +#ifdef CONFIG_CS5536 +#include +#include +#endif + +#define PCI_ACCESS_READ 0 +#define PCI_ACCESS_WRITE 1 + +#define CFG_SPACE_REG(offset) \ + (void *)CKSEG1ADDR(LOONGSON_PCICFG_BASE | (offset)) +#define ID_SEL_BEGIN 11 +#define MAX_DEV_NUM (31 - ID_SEL_BEGIN) + + +static int loongson_pcibios_config_access(unsigned char access_type, + struct pci_bus *bus, + unsigned int devfn, int where, + u32 *data) +{ + u32 busnum = bus->number; + u32 addr, type; + u32 dummy; + void *addrp; + int device = PCI_SLOT(devfn); + int function = PCI_FUNC(devfn); + int reg = where & ~3; + + if (busnum == 0) { + /* board-specific part,currently,only fuloong2f,yeeloong2f + * use CS5536, fuloong2e use via686b, gdium has no + * south bridge + */ +#ifdef CONFIG_CS5536 + /* cs5536_pci_conf_read4/write4() will call _rdmsr/_wrmsr() + * to access the regsters 0xf4,0xf8,0xfc, which is bigger than + * 0xf0, so, it will not go this branch, but the others. so, + * no calling dead loop here. + */ + if ((PCI_IDSEL_CS5536 == device) && (reg < 0xF0)) { + switch (access_type) { + case PCI_ACCESS_READ: + *data = cs5536_pci_conf_read4(function, reg); + break; + case PCI_ACCESS_WRITE: + cs5536_pci_conf_write4(function, reg, *data); + break; + } + return 0; + } +#endif + /* Type 0 configuration for onboard PCI bus */ + if (device > MAX_DEV_NUM) + return -1; + + addr = (1 << (device + ID_SEL_BEGIN)) | (function << 8) | reg; + type = 0; + } else { + /* Type 1 configuration for offboard PCI bus */ + addr = (busnum << 16) | (device << 11) | (function << 8) | reg; + type = 0x10000; + } + + /* Clear aborts */ + LOONGSON_PCICMD |= LOONGSON_PCICMD_MABORT_CLR | \ + LOONGSON_PCICMD_MTABORT_CLR; + + LOONGSON_PCIMAP_CFG = (addr >> 16) | type; + + /* Flush Bonito register block */ + dummy = LOONGSON_PCIMAP_CFG; + mmiowb(); + + addrp = CFG_SPACE_REG(addr & 0xffff); + if (access_type == PCI_ACCESS_WRITE) + writel(cpu_to_le32(*data), addrp); + else + *data = le32_to_cpu(readl(addrp)); + + /* Detect Master/Target abort */ + if (LOONGSON_PCICMD & (LOONGSON_PCICMD_MABORT_CLR | + LOONGSON_PCICMD_MTABORT_CLR)) { + /* Error occurred */ + + /* Clear bits */ + LOONGSON_PCICMD |= (LOONGSON_PCICMD_MABORT_CLR | + LOONGSON_PCICMD_MTABORT_CLR); + + return -1; + } + + return 0; + +} + + +/* + * We can't address 8 and 16 bit words directly. Instead we have to + * read/write a 32bit word and mask/modify the data we actually want. + */ +static int loongson_pcibios_read(struct pci_bus *bus, unsigned int devfn, + int where, int size, u32 *val) +{ + u32 data = 0; + + if ((size == 2) && (where & 1)) + return PCIBIOS_BAD_REGISTER_NUMBER; + else if ((size == 4) && (where & 3)) + return PCIBIOS_BAD_REGISTER_NUMBER; + + if (loongson_pcibios_config_access(PCI_ACCESS_READ, bus, devfn, where, + &data)) + return -1; + + if (size == 1) + *val = (data >> ((where & 3) << 3)) & 0xff; + else if (size == 2) + *val = (data >> ((where & 3) << 3)) & 0xffff; + else + *val = data; + + return PCIBIOS_SUCCESSFUL; +} + +static int loongson_pcibios_write(struct pci_bus *bus, unsigned int devfn, + int where, int size, u32 val) +{ + u32 data = 0; + + if ((size == 2) && (where & 1)) + return PCIBIOS_BAD_REGISTER_NUMBER; + else if ((size == 4) && (where & 3)) + return PCIBIOS_BAD_REGISTER_NUMBER; + + if (size == 4) + data = val; + else { + if (loongson_pcibios_config_access(PCI_ACCESS_READ, bus, devfn, + where, &data)) + return -1; + + if (size == 1) + data = (data & ~(0xff << ((where & 3) << 3))) | + (val << ((where & 3) << 3)); + else if (size == 2) + data = (data & ~(0xffff << ((where & 3) << 3))) | + (val << ((where & 3) << 3)); + } + + if (loongson_pcibios_config_access(PCI_ACCESS_WRITE, bus, devfn, where, + &data)) + return -1; + + return PCIBIOS_SUCCESSFUL; +} + +struct pci_ops loongson_pci_ops = { + .read = loongson_pcibios_read, + .write = loongson_pcibios_write +}; + +#ifdef CONFIG_CS5536 +void _rdmsr(u32 msr, u32 *hi, u32 *lo) +{ + struct pci_bus bus = { + .number = PCI_BUS_CS5536 + }; + u32 devfn = PCI_DEVFN(PCI_IDSEL_CS5536, 0); + loongson_pcibios_write(&bus, devfn, PCI_MSR_ADDR, 4, msr); + loongson_pcibios_read(&bus, devfn, PCI_MSR_DATA_LO, 4, lo); + loongson_pcibios_read(&bus, devfn, PCI_MSR_DATA_HI, 4, hi); +} +EXPORT_SYMBOL(_rdmsr); + +void _wrmsr(u32 msr, u32 hi, u32 lo) +{ + struct pci_bus bus = { + .number = PCI_BUS_CS5536 + }; + u32 devfn = PCI_DEVFN(PCI_IDSEL_CS5536, 0); + loongson_pcibios_write(&bus, devfn, PCI_MSR_ADDR, 4, msr); + loongson_pcibios_write(&bus, devfn, PCI_MSR_DATA_LO, 4, lo); + loongson_pcibios_write(&bus, devfn, PCI_MSR_DATA_HI, 4, hi); +} +EXPORT_SYMBOL(_wrmsr); +#endif diff -Nur linux-2.6.30.5.orig/arch/mips/power/cpu.c linux-2.6.30.5/arch/mips/power/cpu.c --- linux-2.6.30.5.orig/arch/mips/power/cpu.c 1970-01-01 01:00:00.000000000 +0100 +++ linux-2.6.30.5/arch/mips/power/cpu.c 2009-08-23 19:01:04.000000000 +0200 @@ -0,0 +1,60 @@ +/* + * Suspend support specific for mips. + * + * Licensed under the GPLv2 + * + * Copyright (C) 2009 Lemote Inc. & Insititute of Computing Technology + * Author: Hu Hongbing + * Wu Zhangjin + */ +#include +#include +#include +#include + +static u32 saved_status; +struct pt_regs saved_regs; + +void save_processor_state(void) +{ + saved_status = read_c0_status(); + + if (is_fpu_owner()) + save_fp(current); + if (cpu_has_dsp) + save_dsp(current); +} + +void restore_processor_state(void) +{ + write_c0_status(saved_status); + + if (is_fpu_owner()) + restore_fp(current); + if (cpu_has_dsp) + restore_dsp(current); +} + +int pfn_in_system_ram(unsigned long pfn) +{ + int i; + + for (i = 0; i < boot_mem_map.nr_map; i++) { + if (boot_mem_map.map[i].type == BOOT_MEM_RAM) { + if ((pfn >= (boot_mem_map.map[i].addr >> PAGE_SHIFT)) && + ((pfn) < ((boot_mem_map.map[i].addr + + boot_mem_map.map[i].size) >> PAGE_SHIFT))) + return 1; + } + } + return 0; +} + +int pfn_is_nosave(unsigned long pfn) +{ + unsigned long nosave_begin_pfn = PFN_DOWN(__pa(&__nosave_begin)); + unsigned long nosave_end_pfn = PFN_UP(__pa(&__nosave_end)); + + return ((pfn >= nosave_begin_pfn) && (pfn < nosave_end_pfn)) + || !pfn_in_system_ram(pfn); +} diff -Nur linux-2.6.30.5.orig/arch/mips/power/hibernate.S linux-2.6.30.5/arch/mips/power/hibernate.S --- linux-2.6.30.5.orig/arch/mips/power/hibernate.S 1970-01-01 01:00:00.000000000 +0100 +++ linux-2.6.30.5/arch/mips/power/hibernate.S 2009-08-23 19:01:04.000000000 +0200 @@ -0,0 +1,61 @@ +/* + * Hibernation support specific for mips - temporary page tables + * + * Licensed under the GPLv2 + * + * Copyright (C) 2009 Lemote Inc. & Insititute of Computing Technology + * Author: Hu Hongbing + * Wu Zhangjin + */ +#include +#include +#include + +.text +LEAF(swsusp_arch_suspend) + PTR_LA t0, saved_regs + PTR_S ra, PT_R31(t0) + PTR_S sp, PT_R29(t0) + PTR_S fp, PT_R30(t0) + PTR_S gp, PT_R28(t0) + PTR_S s0, PT_R16(t0) + PTR_S s1, PT_R17(t0) + PTR_S s2, PT_R18(t0) + PTR_S s3, PT_R19(t0) + PTR_S s4, PT_R20(t0) + PTR_S s5, PT_R21(t0) + PTR_S s6, PT_R22(t0) + PTR_S s7, PT_R23(t0) + j swsusp_save +END(swsusp_arch_suspend) + +LEAF(swsusp_arch_resume) + PTR_L t0, restore_pblist +0: + PTR_L t1, PBE_ADDRESS(t0) /* source */ + PTR_L t2, PBE_ORIG_ADDRESS(t0) /* destination */ + PTR_ADDIU t3, t1, _PAGE_SIZE +1: + REG_L t8, (t1) + REG_S t8, (t2) + PTR_ADDIU t1, t1, SZREG + PTR_ADDIU t2, t2, SZREG + bne t1, t3, 1b + PTR_L t0, PBE_NEXT(t0) + bnez t0, 0b + PTR_LA t0, saved_regs + PTR_L ra, PT_R31(t0) + PTR_L sp, PT_R29(t0) + PTR_L fp, PT_R30(t0) + PTR_L gp, PT_R28(t0) + PTR_L s0, PT_R16(t0) + PTR_L s1, PT_R17(t0) + PTR_L s2, PT_R18(t0) + PTR_L s3, PT_R19(t0) + PTR_L s4, PT_R20(t0) + PTR_L s5, PT_R21(t0) + PTR_L s6, PT_R22(t0) + PTR_L s7, PT_R23(t0) + PTR_LI v0, 0x0 + jr ra +END(swsusp_arch_resume) diff -Nur linux-2.6.30.5.orig/arch/mips/power/Makefile linux-2.6.30.5/arch/mips/power/Makefile --- linux-2.6.30.5.orig/arch/mips/power/Makefile 1970-01-01 01:00:00.000000000 +0100 +++ linux-2.6.30.5/arch/mips/power/Makefile 2009-08-23 19:01:04.000000000 +0200 @@ -0,0 +1 @@ +obj-$(CONFIG_HIBERNATION) += cpu.o hibernate.o diff -Nur linux-2.6.30.5.orig/drivers/input/serio/i8042.c linux-2.6.30.5/drivers/input/serio/i8042.c --- linux-2.6.30.5.orig/drivers/input/serio/i8042.c 2009-08-16 23:19:38.000000000 +0200 +++ linux-2.6.30.5/drivers/input/serio/i8042.c 2009-08-23 19:01:04.000000000 +0200 @@ -143,7 +143,7 @@ * of the i8042 down the toilet. */ -static int i8042_flush(void) +int i8042_flush(void) { unsigned long flags; unsigned char data, str; @@ -390,10 +390,10 @@ } /* - * i8042_enable_kbd_port enables keybaord port on chip + * i8042_enable_kbd_port enables keyboard port on chip */ -static int i8042_enable_kbd_port(void) +int i8042_enable_kbd_port(void) { i8042_ctr &= ~I8042_CTR_KBDDIS; i8042_ctr |= I8042_CTR_KBDINT; diff -Nur linux-2.6.30.5.orig/drivers/net/wireless/Kconfig linux-2.6.30.5/drivers/net/wireless/Kconfig --- linux-2.6.30.5.orig/drivers/net/wireless/Kconfig 2009-08-16 23:19:38.000000000 +0200 +++ linux-2.6.30.5/drivers/net/wireless/Kconfig 2009-08-23 19:01:04.000000000 +0200 @@ -416,7 +416,7 @@ config RTL8187 tristate "Realtek 8187 and 8187B USB support" - depends on MAC80211 && USB && WLAN_80211 + depends on MAC80211 && USB && WLAN_80211 && !LEMOTE_YEELOONG2F select EEPROM_93CX6 ---help--- This is a driver for RTL8187 and RTL8187B based cards. @@ -434,6 +434,16 @@ Thanks to Realtek for their support! +config RTL8187B + tristate "Realtek 8187B wifi support for yeeloong2f laptop" + depends on MAC80211 && USB && WLAN_80211 && LEMOTE_YEELOONG2F + select EEPROM_93CX6 + ---help--- + This is a driver for RTL8187B based cards, this driver is especially + for yeeloon2f laptop. + + Thanks to Realtek for their support! + config ADM8211 tristate "ADMtek ADM8211 support" depends on MAC80211 && PCI && WLAN_80211 && EXPERIMENTAL diff -Nur linux-2.6.30.5.orig/drivers/net/wireless/Makefile linux-2.6.30.5/drivers/net/wireless/Makefile --- linux-2.6.30.5.orig/drivers/net/wireless/Makefile 2009-08-16 23:19:38.000000000 +0200 +++ linux-2.6.30.5/drivers/net/wireless/Makefile 2009-08-23 19:01:04.000000000 +0200 @@ -34,6 +34,7 @@ obj-$(CONFIG_ZD1211RW) += zd1211rw/ obj-$(CONFIG_RTL8180) += rtl818x/ obj-$(CONFIG_RTL8187) += rtl818x/ +obj-$(CONFIG_RTL8187B) += rtl8187b/ # 16-bit wireless PCMCIA client drivers obj-$(CONFIG_PCMCIA_RAYCS) += ray_cs.o diff -Nur linux-2.6.30.5.orig/drivers/net/wireless/rtl8187b/dot11d.h linux-2.6.30.5/drivers/net/wireless/rtl8187b/dot11d.h --- linux-2.6.30.5.orig/drivers/net/wireless/rtl8187b/dot11d.h 1970-01-01 01:00:00.000000000 +0100 +++ linux-2.6.30.5/drivers/net/wireless/rtl8187b/dot11d.h 2009-08-23 19:01:04.000000000 +0200 @@ -0,0 +1,102 @@ +#ifndef __INC_DOT11D_H +#define __INC_DOT11D_H + +#include "ieee80211/ieee80211.h" + +//#define ENABLE_DOT11D + +//#define DOT11D_MAX_CHNL_NUM 83 + +typedef struct _CHNL_TXPOWER_TRIPLE { + u8 FirstChnl; + u8 NumChnls; + u8 MaxTxPowerInDbm; +}CHNL_TXPOWER_TRIPLE, *PCHNL_TXPOWER_TRIPLE; + +typedef enum _DOT11D_STATE { + DOT11D_STATE_NONE = 0, + DOT11D_STATE_LEARNED, + DOT11D_STATE_DONE, +}DOT11D_STATE; + +typedef struct _RT_DOT11D_INFO { + //DECLARE_RT_OBJECT(RT_DOT11D_INFO); + + bool bEnabled; // dot11MultiDomainCapabilityEnabled + + u16 CountryIeLen; // > 0 if CountryIeBuf[] contains valid country information element. + u8 CountryIeBuf[MAX_IE_LEN]; + u8 CountryIeSrcAddr[6]; // Source AP of the country IE. + u8 CountryIeWatchdog; + + u8 channel_map[MAX_CHANNEL_NUMBER+1]; //!!!Value 0: Invalid, 1: Valid (active scan), 2: Valid (passive scan) + //u8 ChnlListLen; // #Bytes valid in ChnlList[]. + //u8 ChnlList[DOT11D_MAX_CHNL_NUM]; + u8 MaxTxPwrDbmList[MAX_CHANNEL_NUMBER+1]; + + DOT11D_STATE State; +}RT_DOT11D_INFO, *PRT_DOT11D_INFO; +#define eqMacAddr(a,b) ( ((a)[0]==(b)[0] && (a)[1]==(b)[1] && (a)[2]==(b)[2] && (a)[3]==(b)[3] && (a)[4]==(b)[4] && (a)[5]==(b)[5]) ? 1:0 ) +#define cpMacAddr(des,src) ((des)[0]=(src)[0],(des)[1]=(src)[1],(des)[2]=(src)[2],(des)[3]=(src)[3],(des)[4]=(src)[4],(des)[5]=(src)[5]) +#define GET_DOT11D_INFO(__pIeeeDev) ((PRT_DOT11D_INFO)((__pIeeeDev)->pDot11dInfo)) + +#define IS_DOT11D_ENABLE(__pIeeeDev) GET_DOT11D_INFO(__pIeeeDev)->bEnabled +#define IS_COUNTRY_IE_VALID(__pIeeeDev) (GET_DOT11D_INFO(__pIeeeDev)->CountryIeLen > 0) + +#define IS_EQUAL_CIE_SRC(__pIeeeDev, __pTa) eqMacAddr(GET_DOT11D_INFO(__pIeeeDev)->CountryIeSrcAddr, __pTa) +#define UPDATE_CIE_SRC(__pIeeeDev, __pTa) cpMacAddr(GET_DOT11D_INFO(__pIeeeDev)->CountryIeSrcAddr, __pTa) + +#define IS_COUNTRY_IE_CHANGED(__pIeeeDev, __Ie) \ + (((__Ie).Length == 0 || (__Ie).Length != GET_DOT11D_INFO(__pIeeeDev)->CountryIeLen) ? \ + FALSE : \ + (!memcmp(GET_DOT11D_INFO(__pIeeeDev)->CountryIeBuf, (__Ie).Octet, (__Ie).Length))) + +#define CIE_WATCHDOG_TH 1 +#define GET_CIE_WATCHDOG(__pIeeeDev) GET_DOT11D_INFO(__pIeeeDev)->CountryIeWatchdog +#define RESET_CIE_WATCHDOG(__pIeeeDev) GET_CIE_WATCHDOG(__pIeeeDev) = 0 +#define UPDATE_CIE_WATCHDOG(__pIeeeDev) ++GET_CIE_WATCHDOG(__pIeeeDev) + +#define IS_DOT11D_STATE_DONE(__pIeeeDev) (GET_DOT11D_INFO(__pIeeeDev)->State == DOT11D_STATE_DONE) + + +void +Dot11d_Init( + struct ieee80211_device *dev + ); + +void +Dot11d_Reset( + struct ieee80211_device *dev + ); + +void +Dot11d_UpdateCountryIe( + struct ieee80211_device *dev, + u8 * pTaddr, + u16 CoutryIeLen, + u8 * pCoutryIe + ); + +u8 +DOT11D_GetMaxTxPwrInDbm( + struct ieee80211_device *dev, + u8 Channel + ); + +void +DOT11D_ScanComplete( + struct ieee80211_device * dev + ); + +int IsLegalChannel( + struct ieee80211_device * dev, + u8 channel +); + +int ToLegalChannel( + struct ieee80211_device * dev, + u8 channel +); + +void dump_chnl_map(u8 * channel_map); +#endif // #ifndef __INC_DOT11D_H diff -Nur linux-2.6.30.5.orig/drivers/net/wireless/rtl8187b/ieee80211/arc4.c linux-2.6.30.5/drivers/net/wireless/rtl8187b/ieee80211/arc4.c --- linux-2.6.30.5.orig/drivers/net/wireless/rtl8187b/ieee80211/arc4.c 1970-01-01 01:00:00.000000000 +0100 +++ linux-2.6.30.5/drivers/net/wireless/rtl8187b/ieee80211/arc4.c 2009-08-23 19:01:04.000000000 +0200 @@ -0,0 +1,103 @@ +/* + * Cryptographic API + * + * ARC4 Cipher Algorithm + * + * Jon Oberheide + * + * 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. + * + */ +#include +#include +#include "rtl_crypto.h" + +#define ARC4_MIN_KEY_SIZE 1 +#define ARC4_MAX_KEY_SIZE 256 +#define ARC4_BLOCK_SIZE 1 + +struct arc4_ctx { + u8 S[256]; + u8 x, y; +}; + +static int arc4_set_key(void *ctx_arg, const u8 *in_key, unsigned int key_len, u32 *flags) +{ + struct arc4_ctx *ctx = ctx_arg; + int i, j = 0, k = 0; + + ctx->x = 1; + ctx->y = 0; + + for(i = 0; i < 256; i++) + ctx->S[i] = i; + + for(i = 0; i < 256; i++) + { + u8 a = ctx->S[i]; + j = (j + in_key[k] + a) & 0xff; + ctx->S[i] = ctx->S[j]; + ctx->S[j] = a; + if(++k >= key_len) + k = 0; + } + + return 0; +} + +static void arc4_crypt(void *ctx_arg, u8 *out, const u8 *in) +{ + struct arc4_ctx *ctx = ctx_arg; + + u8 *const S = ctx->S; + u8 x = ctx->x; + u8 y = ctx->y; + u8 a, b; + + a = S[x]; + y = (y + a) & 0xff; + b = S[y]; + S[x] = b; + S[y] = a; + x = (x + 1) & 0xff; + *out++ = *in ^ S[(a + b) & 0xff]; + + ctx->x = x; + ctx->y = y; +} + +static struct crypto_alg arc4_alg = { + .cra_name = "arc4", + .cra_flags = CRYPTO_ALG_TYPE_CIPHER, + .cra_blocksize = ARC4_BLOCK_SIZE, + .cra_ctxsize = sizeof(struct arc4_ctx), + .cra_module = THIS_MODULE, + .cra_list = LIST_HEAD_INIT(arc4_alg.cra_list), + .cra_u = { .cipher = { + .cia_min_keysize = ARC4_MIN_KEY_SIZE, + .cia_max_keysize = ARC4_MAX_KEY_SIZE, + .cia_setkey = arc4_set_key, + .cia_encrypt = arc4_crypt, + .cia_decrypt = arc4_crypt } } +}; + +static int __init arc4_init(void) +{ + return crypto_register_alg(&arc4_alg); +} + + +static void __exit arc4_exit(void) +{ + crypto_unregister_alg(&arc4_alg); +} + +module_init(arc4_init); +module_exit(arc4_exit); + +MODULE_LICENSE("GPL"); +MODULE_DESCRIPTION("ARC4 Cipher Algorithm"); +MODULE_AUTHOR("Jon Oberheide "); diff -Nur linux-2.6.30.5.orig/drivers/net/wireless/rtl8187b/ieee80211/dot11d.c linux-2.6.30.5/drivers/net/wireless/rtl8187b/ieee80211/dot11d.c --- linux-2.6.30.5.orig/drivers/net/wireless/rtl8187b/ieee80211/dot11d.c 1970-01-01 01:00:00.000000000 +0100 +++ linux-2.6.30.5/drivers/net/wireless/rtl8187b/ieee80211/dot11d.c 2009-08-23 19:01:04.000000000 +0200 @@ -0,0 +1,245 @@ +#ifdef ENABLE_DOT11D +//----------------------------------------------------------------------------- +// File: +// Dot11d.c +// +// Description: +// Implement 802.11d. +// +//----------------------------------------------------------------------------- + +#include "dot11d.h" + +void +Dot11d_Init(struct ieee80211_device *ieee) +{ + PRT_DOT11D_INFO pDot11dInfo = GET_DOT11D_INFO(ieee); + + pDot11dInfo->bEnabled = 0; + + pDot11dInfo->State = DOT11D_STATE_NONE; + pDot11dInfo->CountryIeLen = 0; + memset(pDot11dInfo->channel_map, 0, MAX_CHANNEL_NUMBER+1); + memset(pDot11dInfo->MaxTxPwrDbmList, 0xFF, MAX_CHANNEL_NUMBER+1); + RESET_CIE_WATCHDOG(ieee); + + //printk("Dot11d_Init()\n"); +} + +// +// Description: +// Reset to the state as we are just entering a regulatory domain. +// +void +Dot11d_Reset(struct ieee80211_device *ieee) +{ + u32 i; + PRT_DOT11D_INFO pDot11dInfo = GET_DOT11D_INFO(ieee); + + // Clear old channel map + memset(pDot11dInfo->channel_map, 0, MAX_CHANNEL_NUMBER+1); + memset(pDot11dInfo->MaxTxPwrDbmList, 0xFF, MAX_CHANNEL_NUMBER+1); + // Set new channel map + for (i=1; i<=11; i++) { + (pDot11dInfo->channel_map)[i] = 1; + } + for (i=12; i<=14; i++) { + (pDot11dInfo->channel_map)[i] = 2; + } + + pDot11dInfo->State = DOT11D_STATE_NONE; + pDot11dInfo->CountryIeLen = 0; + RESET_CIE_WATCHDOG(ieee); + + //printk("Dot11d_Reset()\n"); +} + +// +// Description: +// Update country IE from Beacon or Probe Resopnse +// and configure PHY for operation in the regulatory domain. +// +// TODO: +// Configure Tx power. +// +// Assumption: +// 1. IS_DOT11D_ENABLE() is TRUE. +// 2. Input IE is an valid one. +// +void +Dot11d_UpdateCountryIe( + struct ieee80211_device *dev, + u8 * pTaddr, + u16 CoutryIeLen, + u8 * pCoutryIe + ) +{ + PRT_DOT11D_INFO pDot11dInfo = GET_DOT11D_INFO(dev); + u8 i, j, NumTriples, MaxChnlNum; + PCHNL_TXPOWER_TRIPLE pTriple; + + if((CoutryIeLen - 3)%3 != 0) + { + printk("Dot11d_UpdateCountryIe(): Invalid country IE, skip it........1\n"); + Dot11d_Reset(dev); + return; + } + + memset(pDot11dInfo->channel_map, 0, MAX_CHANNEL_NUMBER+1); + memset(pDot11dInfo->MaxTxPwrDbmList, 0xFF, MAX_CHANNEL_NUMBER+1); + MaxChnlNum = 0; + NumTriples = (CoutryIeLen - 3) / 3; // skip 3-byte country string. + pTriple = (PCHNL_TXPOWER_TRIPLE)(pCoutryIe + 3); + for(i = 0; i < NumTriples; i++) + { + if(MaxChnlNum >= pTriple->FirstChnl) + { // It is not in a monotonically increasing order, so stop processing. + printk("Dot11d_UpdateCountryIe(): Invalid country IE, skip it........1\n"); + Dot11d_Reset(dev); + return; + } + if(MAX_CHANNEL_NUMBER < (pTriple->FirstChnl + pTriple->NumChnls)) + { // It is not a valid set of channel id, so stop processing. + printk("Dot11d_UpdateCountryIe(): Invalid country IE, skip it........2\n"); + Dot11d_Reset(dev); + return; + } + + for(j = 0 ; j < pTriple->NumChnls; j++) + { + pDot11dInfo->channel_map[pTriple->FirstChnl + j] = 1; + pDot11dInfo->MaxTxPwrDbmList[pTriple->FirstChnl + j] = pTriple->MaxTxPowerInDbm; + MaxChnlNum = pTriple->FirstChnl + j; + } + + pTriple = (PCHNL_TXPOWER_TRIPLE)((u8*)pTriple + 3); + } +#if 1 + //printk("Dot11d_UpdateCountryIe(): Channel List:\n"); + printk("Channel List:"); + for(i=1; i<= MAX_CHANNEL_NUMBER; i++) + if(pDot11dInfo->channel_map[i] > 0) + printk(" %d", i); + printk("\n"); +#endif + + UPDATE_CIE_SRC(dev, pTaddr); + + pDot11dInfo->CountryIeLen = CoutryIeLen; + memcpy(pDot11dInfo->CountryIeBuf, pCoutryIe,CoutryIeLen); + pDot11dInfo->State = DOT11D_STATE_LEARNED; +} + +void dump_chnl_map(u8 * channel_map) +{ + int i; + printk("Channel List:"); + for(i=1; i<= MAX_CHANNEL_NUMBER; i++) + if(channel_map[i] > 0) + printk(" %d(%d)", i, channel_map[i]); + printk("\n"); +} + +u8 +DOT11D_GetMaxTxPwrInDbm( + struct ieee80211_device *dev, + u8 Channel + ) +{ + PRT_DOT11D_INFO pDot11dInfo = GET_DOT11D_INFO(dev); + u8 MaxTxPwrInDbm = 255; + + if(MAX_CHANNEL_NUMBER < Channel) + { + printk("DOT11D_GetMaxTxPwrInDbm(): Invalid Channel\n"); + return MaxTxPwrInDbm; + } + if(pDot11dInfo->channel_map[Channel]) + { + MaxTxPwrInDbm = pDot11dInfo->MaxTxPwrDbmList[Channel]; + } + + return MaxTxPwrInDbm; +} + + +void +DOT11D_ScanComplete( + struct ieee80211_device * dev + ) +{ + PRT_DOT11D_INFO pDot11dInfo = GET_DOT11D_INFO(dev); + + switch(pDot11dInfo->State) + { + case DOT11D_STATE_LEARNED: + pDot11dInfo->State = DOT11D_STATE_DONE; + break; + + case DOT11D_STATE_DONE: + if( GET_CIE_WATCHDOG(dev) == 0 ) + { // Reset country IE if previous one is gone. + Dot11d_Reset(dev); + } + break; + case DOT11D_STATE_NONE: + break; + } +} + +int IsLegalChannel( + struct ieee80211_device * dev, + u8 channel +) +{ + PRT_DOT11D_INFO pDot11dInfo = GET_DOT11D_INFO(dev); + + if(MAX_CHANNEL_NUMBER < channel) + { + printk("IsLegalChannel(): Invalid Channel\n"); + return 0; + } + if(pDot11dInfo->channel_map[channel] > 0) + return 1; + return 0; +} + +int ToLegalChannel( + struct ieee80211_device * dev, + u8 channel +) +{ + PRT_DOT11D_INFO pDot11dInfo = GET_DOT11D_INFO(dev); + u8 default_chn = 0; + u32 i = 0; + + for (i=1; i<= MAX_CHANNEL_NUMBER; i++) + { + if(pDot11dInfo->channel_map[i] > 0) + { + default_chn = i; + break; + } + } + + if(MAX_CHANNEL_NUMBER < channel) + { + printk("IsLegalChannel(): Invalid Channel\n"); + return default_chn; + } + + if(pDot11dInfo->channel_map[channel] > 0) + return channel; + + return default_chn; +} + +EXPORT_SYMBOL(Dot11d_Init); +EXPORT_SYMBOL(Dot11d_Reset); +EXPORT_SYMBOL(Dot11d_UpdateCountryIe); +EXPORT_SYMBOL(DOT11D_GetMaxTxPwrInDbm); +EXPORT_SYMBOL(DOT11D_ScanComplete); +EXPORT_SYMBOL(IsLegalChannel); +EXPORT_SYMBOL(ToLegalChannel); +#endif + diff -Nur linux-2.6.30.5.orig/drivers/net/wireless/rtl8187b/ieee80211/dot11d.h linux-2.6.30.5/drivers/net/wireless/rtl8187b/ieee80211/dot11d.h --- linux-2.6.30.5.orig/drivers/net/wireless/rtl8187b/ieee80211/dot11d.h 1970-01-01 01:00:00.000000000 +0100 +++ linux-2.6.30.5/drivers/net/wireless/rtl8187b/ieee80211/dot11d.h 2009-08-23 19:01:04.000000000 +0200 @@ -0,0 +1,102 @@ +#ifndef __INC_DOT11D_H +#define __INC_DOT11D_H + +#include "ieee80211.h" + +//#define ENABLE_DOT11D + +//#define DOT11D_MAX_CHNL_NUM 83 + +typedef struct _CHNL_TXPOWER_TRIPLE { + u8 FirstChnl; + u8 NumChnls; + u8 MaxTxPowerInDbm; +}CHNL_TXPOWER_TRIPLE, *PCHNL_TXPOWER_TRIPLE; + +typedef enum _DOT11D_STATE { + DOT11D_STATE_NONE = 0, + DOT11D_STATE_LEARNED, + DOT11D_STATE_DONE, +}DOT11D_STATE; + +typedef struct _RT_DOT11D_INFO { + //DECLARE_RT_OBJECT(RT_DOT11D_INFO); + + bool bEnabled; // dot11MultiDomainCapabilityEnabled + + u16 CountryIeLen; // > 0 if CountryIeBuf[] contains valid country information element. + u8 CountryIeBuf[MAX_IE_LEN]; + u8 CountryIeSrcAddr[6]; // Source AP of the country IE. + u8 CountryIeWatchdog; + + u8 channel_map[MAX_CHANNEL_NUMBER+1]; //!!!Value 0: Invalid, 1: Valid (active scan), 2: Valid (passive scan) + //u8 ChnlListLen; // #Bytes valid in ChnlList[]. + //u8 ChnlList[DOT11D_MAX_CHNL_NUM]; + u8 MaxTxPwrDbmList[MAX_CHANNEL_NUMBER+1]; + + DOT11D_STATE State; +}RT_DOT11D_INFO, *PRT_DOT11D_INFO; +#define eqMacAddr(a,b) ( ((a)[0]==(b)[0] && (a)[1]==(b)[1] && (a)[2]==(b)[2] && (a)[3]==(b)[3] && (a)[4]==(b)[4] && (a)[5]==(b)[5]) ? 1:0 ) +#define cpMacAddr(des,src) ((des)[0]=(src)[0],(des)[1]=(src)[1],(des)[2]=(src)[2],(des)[3]=(src)[3],(des)[4]=(src)[4],(des)[5]=(src)[5]) +#define GET_DOT11D_INFO(__pIeeeDev) ((PRT_DOT11D_INFO)((__pIeeeDev)->pDot11dInfo)) + +#define IS_DOT11D_ENABLE(__pIeeeDev) GET_DOT11D_INFO(__pIeeeDev)->bEnabled +#define IS_COUNTRY_IE_VALID(__pIeeeDev) (GET_DOT11D_INFO(__pIeeeDev)->CountryIeLen > 0) + +#define IS_EQUAL_CIE_SRC(__pIeeeDev, __pTa) eqMacAddr(GET_DOT11D_INFO(__pIeeeDev)->CountryIeSrcAddr, __pTa) +#define UPDATE_CIE_SRC(__pIeeeDev, __pTa) cpMacAddr(GET_DOT11D_INFO(__pIeeeDev)->CountryIeSrcAddr, __pTa) + +#define IS_COUNTRY_IE_CHANGED(__pIeeeDev, __Ie) \ + (((__Ie).Length == 0 || (__Ie).Length != GET_DOT11D_INFO(__pIeeeDev)->CountryIeLen) ? \ + FALSE : \ + (!memcmp(GET_DOT11D_INFO(__pIeeeDev)->CountryIeBuf, (__Ie).Octet, (__Ie).Length))) + +#define CIE_WATCHDOG_TH 1 +#define GET_CIE_WATCHDOG(__pIeeeDev) GET_DOT11D_INFO(__pIeeeDev)->CountryIeWatchdog +#define RESET_CIE_WATCHDOG(__pIeeeDev) GET_CIE_WATCHDOG(__pIeeeDev) = 0 +#define UPDATE_CIE_WATCHDOG(__pIeeeDev) ++GET_CIE_WATCHDOG(__pIeeeDev) + +#define IS_DOT11D_STATE_DONE(__pIeeeDev) (GET_DOT11D_INFO(__pIeeeDev)->State == DOT11D_STATE_DONE) + + +void +Dot11d_Init( + struct ieee80211_device *dev + ); + +void +Dot11d_Reset( + struct ieee80211_device *dev + ); + +void +Dot11d_UpdateCountryIe( + struct ieee80211_device *dev, + u8 * pTaddr, + u16 CoutryIeLen, + u8 * pCoutryIe + ); + +u8 +DOT11D_GetMaxTxPwrInDbm( + struct ieee80211_device *dev, + u8 Channel + ); + +void +DOT11D_ScanComplete( + struct ieee80211_device * dev + ); + +int IsLegalChannel( + struct ieee80211_device * dev, + u8 channel +); + +int ToLegalChannel( + struct ieee80211_device * dev, + u8 channel +); + +void dump_chnl_map(u8 * channel_map); +#endif // #ifndef __INC_DOT11D_H diff -Nur linux-2.6.30.5.orig/drivers/net/wireless/rtl8187b/ieee80211/ieee80211_crypt.c linux-2.6.30.5/drivers/net/wireless/rtl8187b/ieee80211/ieee80211_crypt.c --- linux-2.6.30.5.orig/drivers/net/wireless/rtl8187b/ieee80211/ieee80211_crypt.c 1970-01-01 01:00:00.000000000 +0100 +++ linux-2.6.30.5/drivers/net/wireless/rtl8187b/ieee80211/ieee80211_crypt.c 2009-08-23 19:01:04.000000000 +0200 @@ -0,0 +1,275 @@ +/* + * Host AP crypto routines + * + * Copyright (c) 2002-2003, Jouni Malinen + * Portions Copyright (C) 2004, Intel Corporation + * + * 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. See README and COPYING for + * more details. + * + */ + +//#include +#include +#include +#include +#include +#include +#include + +#include "ieee80211.h" + +MODULE_AUTHOR("Jouni Malinen"); +MODULE_DESCRIPTION("HostAP crypto"); +MODULE_LICENSE("GPL"); + +struct ieee80211_crypto_alg { + struct list_head list; + struct ieee80211_crypto_ops *ops; +}; + + +struct ieee80211_crypto { + struct list_head algs; + spinlock_t lock; +}; + +static struct ieee80211_crypto *hcrypt; + +void ieee80211_crypt_deinit_entries(struct ieee80211_device *ieee, + int force) +{ + struct list_head *ptr, *n; + struct ieee80211_crypt_data *entry; + + for (ptr = ieee->crypt_deinit_list.next, n = ptr->next; + ptr != &ieee->crypt_deinit_list; ptr = n, n = ptr->next) { + entry = list_entry(ptr, struct ieee80211_crypt_data, list); + + if (atomic_read(&entry->refcnt) != 0 && !force) + continue; + + list_del(ptr); + + if (entry->ops) { + entry->ops->deinit(entry->priv); +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0) + module_put(entry->ops->owner); +#else + __MOD_DEC_USE_COUNT(entry->ops->owner); +#endif + } + kfree(entry); + } +} + +void ieee80211_crypt_deinit_handler(unsigned long data) +{ + struct ieee80211_device *ieee = (struct ieee80211_device *)data; + unsigned long flags; + + spin_lock_irqsave(&ieee->lock, flags); + ieee80211_crypt_deinit_entries(ieee, 0); + if (!list_empty(&ieee->crypt_deinit_list)) { + printk(KERN_DEBUG "%s: entries remaining in delayed crypt " + "deletion list\n", ieee->dev->name); + ieee->crypt_deinit_timer.expires = jiffies + HZ; + add_timer(&ieee->crypt_deinit_timer); + } + spin_unlock_irqrestore(&ieee->lock, flags); + +} + +void ieee80211_crypt_delayed_deinit(struct ieee80211_device *ieee, + struct ieee80211_crypt_data **crypt) +{ + struct ieee80211_crypt_data *tmp; + unsigned long flags; + + if (*crypt == NULL) + return; + + tmp = *crypt; + *crypt = NULL; + + /* must not run ops->deinit() while there may be pending encrypt or + * decrypt operations. Use a list of delayed deinits to avoid needing + * locking. */ + + spin_lock_irqsave(&ieee->lock, flags); + list_add(&tmp->list, &ieee->crypt_deinit_list); + if (!timer_pending(&ieee->crypt_deinit_timer)) { + ieee->crypt_deinit_timer.expires = jiffies + HZ; + add_timer(&ieee->crypt_deinit_timer); + } + spin_unlock_irqrestore(&ieee->lock, flags); +} + +int ieee80211_register_crypto_ops(struct ieee80211_crypto_ops *ops) +{ + unsigned long flags; + struct ieee80211_crypto_alg *alg; + + if (hcrypt == NULL) + return -1; + + alg = kmalloc(sizeof(*alg), GFP_KERNEL); + if (alg == NULL) + return -ENOMEM; + + memset(alg, 0, sizeof(*alg)); + alg->ops = ops; + + spin_lock_irqsave(&hcrypt->lock, flags); + list_add(&alg->list, &hcrypt->algs); + spin_unlock_irqrestore(&hcrypt->lock, flags); + + printk(KERN_DEBUG "ieee80211_crypt: registered algorithm '%s'\n", + ops->name); + + return 0; +} + +int ieee80211_unregister_crypto_ops(struct ieee80211_crypto_ops *ops) +{ + unsigned long flags; + struct list_head *ptr; + struct ieee80211_crypto_alg *del_alg = NULL; + + if (hcrypt == NULL) + return -1; + + spin_lock_irqsave(&hcrypt->lock, flags); + for (ptr = hcrypt->algs.next; ptr != &hcrypt->algs; ptr = ptr->next) { + struct ieee80211_crypto_alg *alg = + (struct ieee80211_crypto_alg *) ptr; + if (alg->ops == ops) { + list_del(&alg->list); + del_alg = alg; + break; + } + } + spin_unlock_irqrestore(&hcrypt->lock, flags); + + if (del_alg) { + printk(KERN_DEBUG "ieee80211_crypt: unregistered algorithm " + "'%s'\n", ops->name); + kfree(del_alg); + } + + return del_alg ? 0 : -1; +} + + +struct ieee80211_crypto_ops * ieee80211_get_crypto_ops(const char *name) +{ + unsigned long flags; + struct list_head *ptr; + struct ieee80211_crypto_alg *found_alg = NULL; + + if (hcrypt == NULL) + return NULL; + + spin_lock_irqsave(&hcrypt->lock, flags); + for (ptr = hcrypt->algs.next; ptr != &hcrypt->algs; ptr = ptr->next) { + struct ieee80211_crypto_alg *alg = + (struct ieee80211_crypto_alg *) ptr; + if (strcmp(alg->ops->name, name) == 0) { + found_alg = alg; + break; + } + } + spin_unlock_irqrestore(&hcrypt->lock, flags); + + if (found_alg) + return found_alg->ops; + else + return NULL; +} + + +static void * ieee80211_crypt_null_init(int keyidx) { return (void *) 1; } +static void ieee80211_crypt_null_deinit(void *priv) {} + +static struct ieee80211_crypto_ops ieee80211_crypt_null = { + .name = "NULL", + .init = ieee80211_crypt_null_init, + .deinit = ieee80211_crypt_null_deinit, + .encrypt_mpdu = NULL, + .decrypt_mpdu = NULL, + .encrypt_msdu = NULL, + .decrypt_msdu = NULL, + .set_key = NULL, + .get_key = NULL, + .extra_prefix_len = 0, + .extra_postfix_len = 0, + .owner = THIS_MODULE, +}; + + +int __init ieee80211_crypto_init(void) +{ + int ret = -ENOMEM; + + hcrypt = kmalloc(sizeof(*hcrypt), GFP_KERNEL); + if (!hcrypt) + goto out; + + memset(hcrypt, 0, sizeof(*hcrypt)); + INIT_LIST_HEAD(&hcrypt->algs); + spin_lock_init(&hcrypt->lock); + + ret = ieee80211_register_crypto_ops(&ieee80211_crypt_null); + if (ret < 0) { + kfree(hcrypt); + hcrypt = NULL; + } +out: + return ret; +} + + +void __exit ieee80211_crypto_deinit(void) +{ + struct list_head *ptr, *n; + + if (hcrypt == NULL) + return; + + for (ptr = hcrypt->algs.next, n = ptr->next; ptr != &hcrypt->algs; + ptr = n, n = ptr->next) { + struct ieee80211_crypto_alg *alg = + (struct ieee80211_crypto_alg *) ptr; + list_del(ptr); + printk(KERN_DEBUG "ieee80211_crypt: unregistered algorithm " + "'%s' (deinit)\n", alg->ops->name); + kfree(alg); + } + + kfree(hcrypt); +} + +#if 0 +#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)) +EXPORT_SYMBOL(ieee80211_crypt_deinit_entries); +EXPORT_SYMBOL(ieee80211_crypt_deinit_handler); +EXPORT_SYMBOL(ieee80211_crypt_delayed_deinit); + +EXPORT_SYMBOL(ieee80211_register_crypto_ops); +EXPORT_SYMBOL(ieee80211_unregister_crypto_ops); +EXPORT_SYMBOL(ieee80211_get_crypto_ops); +#else +EXPORT_SYMBOL_NOVERS(ieee80211_crypt_deinit_entries); +EXPORT_SYMBOL_NOVERS(ieee80211_crypt_deinit_handler); +EXPORT_SYMBOL_NOVERS(ieee80211_crypt_delayed_deinit); + +EXPORT_SYMBOL_NOVERS(ieee80211_register_crypto_ops); +EXPORT_SYMBOL_NOVERS(ieee80211_unregister_crypto_ops); +EXPORT_SYMBOL_NOVERS(ieee80211_get_crypto_ops); +#endif + +module_init(ieee80211_crypto_init); +module_exit(ieee80211_crypto_deinit); +#endif diff -Nur linux-2.6.30.5.orig/drivers/net/wireless/rtl8187b/ieee80211/ieee80211_crypt_ccmp.c linux-2.6.30.5/drivers/net/wireless/rtl8187b/ieee80211/ieee80211_crypt_ccmp.c --- linux-2.6.30.5.orig/drivers/net/wireless/rtl8187b/ieee80211/ieee80211_crypt_ccmp.c 1970-01-01 01:00:00.000000000 +0100 +++ linux-2.6.30.5/drivers/net/wireless/rtl8187b/ieee80211/ieee80211_crypt_ccmp.c 2009-08-23 19:01:04.000000000 +0200 @@ -0,0 +1,524 @@ +/* + * Host AP crypt: host-based CCMP encryption implementation for Host AP driver + * + * Copyright (c) 2003-2004, Jouni Malinen + * + * 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. See README and COPYING for + * more details. + */ + +//#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "ieee80211.h" + +#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)) +#include "rtl_crypto.h" +#else +#include +#endif +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20) + #include +#else + #include +#endif + +//#include + +MODULE_AUTHOR("Jouni Malinen"); +MODULE_DESCRIPTION("Host AP crypt: CCMP"); +MODULE_LICENSE("GPL"); + +#define AES_BLOCK_LEN 16 +#define CCMP_HDR_LEN 8 +#define CCMP_MIC_LEN 8 +#define CCMP_TK_LEN 16 +#define CCMP_PN_LEN 6 + +struct ieee80211_ccmp_data { + u8 key[CCMP_TK_LEN]; + int key_set; + + u8 tx_pn[CCMP_PN_LEN]; + u8 rx_pn[CCMP_PN_LEN]; + + u32 dot11RSNAStatsCCMPFormatErrors; + u32 dot11RSNAStatsCCMPReplays; + u32 dot11RSNAStatsCCMPDecryptErrors; + + int key_idx; + + struct crypto_tfm *tfm; + + /* scratch buffers for virt_to_page() (crypto API) */ + u8 tx_b0[AES_BLOCK_LEN], tx_b[AES_BLOCK_LEN], + tx_e[AES_BLOCK_LEN], tx_s0[AES_BLOCK_LEN]; + u8 rx_b0[AES_BLOCK_LEN], rx_b[AES_BLOCK_LEN], rx_a[AES_BLOCK_LEN]; +}; + +void ieee80211_ccmp_aes_encrypt(struct crypto_tfm *tfm, + const u8 pt[16], u8 ct[16]) +{ + #if(LINUX_VERSION_CODE < KERNEL_VERSION(2,6,21)) + struct scatterlist src, dst; + + src.page = virt_to_page(pt); + src.offset = offset_in_page(pt); + src.length = AES_BLOCK_LEN; + + dst.page = virt_to_page(ct); + dst.offset = offset_in_page(ct); + dst.length = AES_BLOCK_LEN; + + crypto_cipher_encrypt(tfm, &dst, &src, AES_BLOCK_LEN); + #else + crypto_cipher_encrypt_one((void*)tfm, ct, pt); + #endif +} + +static void * ieee80211_ccmp_init(int key_idx) +{ + struct ieee80211_ccmp_data *priv; + + priv = kmalloc(sizeof(*priv), GFP_ATOMIC); + if (priv == NULL) + goto fail; + memset(priv, 0, sizeof(*priv)); + priv->key_idx = key_idx; + + #if(LINUX_VERSION_CODE < KERNEL_VERSION(2,6,21)) + priv->tfm = crypto_alloc_tfm("aes", 0); + if (priv->tfm == NULL) { + printk(KERN_DEBUG "ieee80211_crypt_ccmp: could not allocate " + "crypto API aes\n"); + goto fail; + } + #else + priv->tfm = (void*)crypto_alloc_cipher("aes", 0, CRYPTO_ALG_ASYNC); + if (IS_ERR(priv->tfm)) { + printk(KERN_DEBUG "ieee80211_crypt_ccmp: could not allocate " + "crypto API aes\n"); + priv->tfm = NULL; + goto fail; + } + #endif + return priv; + +fail: + if (priv) { + if (priv->tfm) + #if(LINUX_VERSION_CODE < KERNEL_VERSION(2,6,21)) + crypto_free_tfm(priv->tfm); + #else + crypto_free_cipher((void*)priv->tfm); + #endif + kfree(priv); + } + + return NULL; +} + + +static void ieee80211_ccmp_deinit(void *priv) +{ + struct ieee80211_ccmp_data *_priv = priv; + if (_priv && _priv->tfm) + #if(LINUX_VERSION_CODE < KERNEL_VERSION(2,6,21)) + crypto_free_tfm(_priv->tfm); + #else + crypto_free_cipher((void*)_priv->tfm); + #endif + kfree(priv); +} + + +static inline void xor_block(u8 *b, u8 *a, size_t len) +{ + int i; + for (i = 0; i < len; i++) + b[i] ^= a[i]; +} + +#ifndef JOHN_CCMP +static void ccmp_init_blocks(struct crypto_tfm *tfm, + struct ieee80211_hdr *hdr, + u8 *pn, size_t dlen, u8 *b0, u8 *auth, + u8 *s0) +{ + u8 *pos, qc = 0; + size_t aad_len; + u16 fc; + int a4_included, qc_included; + u8 aad[2 * AES_BLOCK_LEN]; + + fc = le16_to_cpu(hdr->frame_ctl); + a4_included = ((fc & (IEEE80211_FCTL_TODS | IEEE80211_FCTL_FROMDS)) == + (IEEE80211_FCTL_TODS | IEEE80211_FCTL_FROMDS)); + /* + qc_included = ((WLAN_FC_GET_TYPE(fc) == IEEE80211_FTYPE_DATA) && + (WLAN_FC_GET_STYPE(fc) & 0x08)); + */ + // fixed by David :2006.9.6 + qc_included = ((WLAN_FC_GET_TYPE(fc) == IEEE80211_FTYPE_DATA) && + (WLAN_FC_GET_STYPE(fc) & 0x80)); + aad_len = 22; + if (a4_included) + aad_len += 6; + if (qc_included) { + pos = (u8 *) &hdr->addr4; + if (a4_included) + pos += 6; + qc = *pos & 0x0f; + aad_len += 2; + } + /* CCM Initial Block: + * Flag (Include authentication header, M=3 (8-octet MIC), + * L=1 (2-octet Dlen)) + * Nonce: 0x00 | A2 | PN + * Dlen */ + b0[0] = 0x59; + b0[1] = qc; + memcpy(b0 + 2, hdr->addr2, ETH_ALEN); + memcpy(b0 + 8, pn, CCMP_PN_LEN); + b0[14] = (dlen >> 8) & 0xff; + b0[15] = dlen & 0xff; + + /* AAD: + * FC with bits 4..6 and 11..13 masked to zero; 14 is always one + * A1 | A2 | A3 + * SC with bits 4..15 (seq#) masked to zero + * A4 (if present) + * QC (if present) + */ + pos = (u8 *) hdr; + aad[0] = 0; /* aad_len >> 8 */ + aad[1] = aad_len & 0xff; + aad[2] = pos[0] & 0x8f; + aad[3] = pos[1] & 0xc7; + memcpy(aad + 4, hdr->addr1, 3 * ETH_ALEN); + pos = (u8 *) &hdr->seq_ctl; + aad[22] = pos[0] & 0x0f; + aad[23] = 0; /* all bits masked */ + memset(aad + 24, 0, 8); + if (a4_included) + memcpy(aad + 24, hdr->addr4, ETH_ALEN); + if (qc_included) { + aad[a4_included ? 30 : 24] = qc; + /* rest of QC masked */ + } + + /* Start with the first block and AAD */ + ieee80211_ccmp_aes_encrypt(tfm, b0, auth); + xor_block(auth, aad, AES_BLOCK_LEN); + ieee80211_ccmp_aes_encrypt(tfm, auth, auth); + xor_block(auth, &aad[AES_BLOCK_LEN], AES_BLOCK_LEN); + ieee80211_ccmp_aes_encrypt(tfm, auth, auth); + b0[0] &= 0x07; + b0[14] = b0[15] = 0; + ieee80211_ccmp_aes_encrypt(tfm, b0, s0); +} +#endif + +static int ieee80211_ccmp_encrypt(struct sk_buff *skb, int hdr_len, void *priv) +{ + struct ieee80211_ccmp_data *key = priv; + int data_len, i; + u8 *pos; + struct ieee80211_hdr *hdr; +#ifndef JOHN_CCMP + int blocks, last, len; + u8 *mic; + u8 *b0 = key->tx_b0; + u8 *b = key->tx_b; + u8 *e = key->tx_e; + u8 *s0 = key->tx_s0; +#endif + if (skb_headroom(skb) < CCMP_HDR_LEN || + skb_tailroom(skb) < CCMP_MIC_LEN || + skb->len < hdr_len) + return -1; + + data_len = skb->len - hdr_len; + pos = skb_push(skb, CCMP_HDR_LEN); + memmove(pos, pos + CCMP_HDR_LEN, hdr_len); + pos += hdr_len; +// mic = skb_put(skb, CCMP_MIC_LEN); + + i = CCMP_PN_LEN - 1; + while (i >= 0) { + key->tx_pn[i]++; + if (key->tx_pn[i] != 0) + break; + i--; + } + + *pos++ = key->tx_pn[5]; + *pos++ = key->tx_pn[4]; + *pos++ = 0; + *pos++ = (key->key_idx << 6) | (1 << 5) /* Ext IV included */; + *pos++ = key->tx_pn[3]; + *pos++ = key->tx_pn[2]; + *pos++ = key->tx_pn[1]; + *pos++ = key->tx_pn[0]; + + hdr = (struct ieee80211_hdr *) skb->data; +#ifndef JOHN_CCMP + //mic is moved to here by john + mic = skb_put(skb, CCMP_MIC_LEN); + + ccmp_init_blocks(key->tfm, hdr, key->tx_pn, data_len, b0, b, s0); + + blocks = (data_len + AES_BLOCK_LEN - 1) / AES_BLOCK_LEN; + last = data_len % AES_BLOCK_LEN; + + for (i = 1; i <= blocks; i++) { + len = (i == blocks && last) ? last : AES_BLOCK_LEN; + /* Authentication */ + xor_block(b, pos, len); + ieee80211_ccmp_aes_encrypt(key->tfm, b, b); + /* Encryption, with counter */ + b0[14] = (i >> 8) & 0xff; + b0[15] = i & 0xff; + ieee80211_ccmp_aes_encrypt(key->tfm, b0, e); + xor_block(pos, e, len); + pos += len; + } + + for (i = 0; i < CCMP_MIC_LEN; i++) + mic[i] = b[i] ^ s0[i]; +#endif + return 0; +} + + +static int ieee80211_ccmp_decrypt(struct sk_buff *skb, int hdr_len, void *priv) +{ + struct ieee80211_ccmp_data *key = priv; + u8 keyidx, *pos; + struct ieee80211_hdr *hdr; + u8 pn[6]; +#ifndef JOHN_CCMP + size_t data_len = skb->len - hdr_len - CCMP_HDR_LEN - CCMP_MIC_LEN; + u8 *mic = skb->data + skb->len - CCMP_MIC_LEN; + u8 *b0 = key->rx_b0; + u8 *b = key->rx_b; + u8 *a = key->rx_a; + int i, blocks, last, len; +#endif + if (skb->len < hdr_len + CCMP_HDR_LEN + CCMP_MIC_LEN) { + key->dot11RSNAStatsCCMPFormatErrors++; + return -1; + } + + hdr = (struct ieee80211_hdr *) skb->data; + pos = skb->data + hdr_len; + keyidx = pos[3]; + if (!(keyidx & (1 << 5))) { + if (net_ratelimit()) { + printk(KERN_DEBUG "CCMP: received packet without ExtIV" + " flag from " MAC_FMT "\n", MAC_ARG(hdr->addr2)); + } + key->dot11RSNAStatsCCMPFormatErrors++; + return -2; + } + keyidx >>= 6; + if (key->key_idx != keyidx) { + printk(KERN_DEBUG "CCMP: RX tkey->key_idx=%d frame " + "keyidx=%d priv=%p\n", key->key_idx, keyidx, priv); + return -6; + } + if (!key->key_set) { + if (net_ratelimit()) { + printk(KERN_DEBUG "CCMP: received packet from " MAC_FMT + " with keyid=%d that does not have a configured" + " key\n", MAC_ARG(hdr->addr2), keyidx); + } + return -3; + } + + pn[0] = pos[7]; + pn[1] = pos[6]; + pn[2] = pos[5]; + pn[3] = pos[4]; + pn[4] = pos[1]; + pn[5] = pos[0]; + pos += 8; +#if 0 + if (memcmp(pn, key->rx_pn, CCMP_PN_LEN) <= 0) { + if (net_ratelimit()) { + printk(KERN_DEBUG "CCMP: replay detected: STA=" MAC_FMT + " previous PN %02x%02x%02x%02x%02x%02x " + "received PN %02x%02x%02x%02x%02x%02x\n", + MAC_ARG(hdr->addr2), MAC_ARG(key->rx_pn), + MAC_ARG(pn)); + } + key->dot11RSNAStatsCCMPReplays++; + return -4; + } +#endif +#ifndef JOHN_CCMP + ccmp_init_blocks(key->tfm, hdr, pn, data_len, b0, a, b); + xor_block(mic, b, CCMP_MIC_LEN); + + blocks = (data_len + AES_BLOCK_LEN - 1) / AES_BLOCK_LEN; + last = data_len % AES_BLOCK_LEN; + + for (i = 1; i <= blocks; i++) { + len = (i == blocks && last) ? last : AES_BLOCK_LEN; + /* Decrypt, with counter */ + b0[14] = (i >> 8) & 0xff; + b0[15] = i & 0xff; + ieee80211_ccmp_aes_encrypt(key->tfm, b0, b); + xor_block(pos, b, len); + /* Authentication */ + xor_block(a, pos, len); + ieee80211_ccmp_aes_encrypt(key->tfm, a, a); + pos += len; + } + + if (memcmp(mic, a, CCMP_MIC_LEN) != 0) { + if (net_ratelimit()) { + printk(KERN_DEBUG "CCMP: decrypt failed: STA=" + MAC_FMT "\n", MAC_ARG(hdr->addr2)); + } + key->dot11RSNAStatsCCMPDecryptErrors++; + return -5; + } + + memcpy(key->rx_pn, pn, CCMP_PN_LEN); + +#endif + /* Remove hdr and MIC */ + memmove(skb->data + CCMP_HDR_LEN, skb->data, hdr_len); + skb_pull(skb, CCMP_HDR_LEN); + skb_trim(skb, skb->len - CCMP_MIC_LEN); + + return keyidx; +} + + +static int ieee80211_ccmp_set_key(void *key, int len, u8 *seq, void *priv) +{ + struct ieee80211_ccmp_data *data = priv; + int keyidx; + struct crypto_tfm *tfm = data->tfm; + + keyidx = data->key_idx; + memset(data, 0, sizeof(*data)); + data->key_idx = keyidx; + data->tfm = tfm; + if (len == CCMP_TK_LEN) { + memcpy(data->key, key, CCMP_TK_LEN); + data->key_set = 1; + if (seq) { + data->rx_pn[0] = seq[5]; + data->rx_pn[1] = seq[4]; + data->rx_pn[2] = seq[3]; + data->rx_pn[3] = seq[2]; + data->rx_pn[4] = seq[1]; + data->rx_pn[5] = seq[0]; + } + crypto_cipher_setkey((void*)data->tfm, data->key, CCMP_TK_LEN); + } else if (len == 0) + data->key_set = 0; + else + return -1; + + return 0; +} + + +static int ieee80211_ccmp_get_key(void *key, int len, u8 *seq, void *priv) +{ + struct ieee80211_ccmp_data *data = priv; + + if (len < CCMP_TK_LEN) + return -1; + + if (!data->key_set) + return 0; + memcpy(key, data->key, CCMP_TK_LEN); + + if (seq) { + seq[0] = data->tx_pn[5]; + seq[1] = data->tx_pn[4]; + seq[2] = data->tx_pn[3]; + seq[3] = data->tx_pn[2]; + seq[4] = data->tx_pn[1]; + seq[5] = data->tx_pn[0]; + } + + return CCMP_TK_LEN; +} + + +static char * ieee80211_ccmp_print_stats(char *p, void *priv) +{ + struct ieee80211_ccmp_data *ccmp = priv; + p += sprintf(p, "key[%d] alg=CCMP key_set=%d " + "tx_pn=%02x%02x%02x%02x%02x%02x " + "rx_pn=%02x%02x%02x%02x%02x%02x " + "format_errors=%d replays=%d decrypt_errors=%d\n", + ccmp->key_idx, ccmp->key_set, + MAC_ARG(ccmp->tx_pn), MAC_ARG(ccmp->rx_pn), + ccmp->dot11RSNAStatsCCMPFormatErrors, + ccmp->dot11RSNAStatsCCMPReplays, + ccmp->dot11RSNAStatsCCMPDecryptErrors); + + return p; +} + +void ieee80211_ccmp_null(void) +{ + // printk("============>%s()\n", __FUNCTION__); + return; +} +static struct ieee80211_crypto_ops ieee80211_crypt_ccmp = { + .name = "CCMP", + .init = ieee80211_ccmp_init, + .deinit = ieee80211_ccmp_deinit, + .encrypt_mpdu = ieee80211_ccmp_encrypt, + .decrypt_mpdu = ieee80211_ccmp_decrypt, + .encrypt_msdu = NULL, + .decrypt_msdu = NULL, + .set_key = ieee80211_ccmp_set_key, + .get_key = ieee80211_ccmp_get_key, + .print_stats = ieee80211_ccmp_print_stats, + .extra_prefix_len = CCMP_HDR_LEN, + .extra_postfix_len = CCMP_MIC_LEN, + .owner = THIS_MODULE, +}; + + +int __init ieee80211_crypto_ccmp_init(void) +{ + return ieee80211_register_crypto_ops(&ieee80211_crypt_ccmp); +} + + +void __exit ieee80211_crypto_ccmp_exit(void) +{ + ieee80211_unregister_crypto_ops(&ieee80211_crypt_ccmp); +} +#if 0 +#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)) +EXPORT_SYMBOL(ieee80211_ccmp_null); +#else +EXPORT_SYMBOL_NOVERS(ieee80211_ccmp_null); +#endif + +module_init(ieee80211_crypto_ccmp_init); +module_exit(ieee80211_crypto_ccmp_exit); +#endif diff -Nur linux-2.6.30.5.orig/drivers/net/wireless/rtl8187b/ieee80211/ieee80211_crypt.h linux-2.6.30.5/drivers/net/wireless/rtl8187b/ieee80211/ieee80211_crypt.h --- linux-2.6.30.5.orig/drivers/net/wireless/rtl8187b/ieee80211/ieee80211_crypt.h 1970-01-01 01:00:00.000000000 +0100 +++ linux-2.6.30.5/drivers/net/wireless/rtl8187b/ieee80211/ieee80211_crypt.h 2009-08-23 19:01:04.000000000 +0200 @@ -0,0 +1,91 @@ +/* + * Original code based on Host AP (software wireless LAN access point) driver + * for Intersil Prism2/2.5/3. + * + * Copyright (c) 2001-2002, SSH Communications Security Corp and Jouni Malinen + * + * Copyright (c) 2002-2003, Jouni Malinen + * + * Adaption to a generic IEEE 802.11 stack by James Ketrenos + * + * + * Copyright (c) 2004, Intel Corporation + * + * 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. See README and COPYING for + * more details. + */ + +/* + * This file defines the interface to the ieee80211 crypto module. + */ +#ifndef IEEE80211_CRYPT_H +#define IEEE80211_CRYPT_H + +#include + +struct ieee80211_crypto_ops { + const char *name; + + /* init new crypto context (e.g., allocate private data space, + * select IV, etc.); returns NULL on failure or pointer to allocated + * private data on success */ + void * (*init)(int keyidx); + + /* deinitialize crypto context and free allocated private data */ + void (*deinit)(void *priv); + + /* encrypt/decrypt return < 0 on error or >= 0 on success. The return + * value from decrypt_mpdu is passed as the keyidx value for + * decrypt_msdu. skb must have enough head and tail room for the + * encryption; if not, error will be returned; these functions are + * called for all MPDUs (i.e., fragments). + */ + int (*encrypt_mpdu)(struct sk_buff *skb, int hdr_len, void *priv); + int (*decrypt_mpdu)(struct sk_buff *skb, int hdr_len, void *priv); + + /* These functions are called for full MSDUs, i.e. full frames. + * These can be NULL if full MSDU operations are not needed. */ + int (*encrypt_msdu)(struct sk_buff *skb, int hdr_len, void *priv); + int (*decrypt_msdu)(struct sk_buff *skb, int keyidx, int hdr_len, + void *priv); + + int (*set_key)(void *key, int len, u8 *seq, void *priv); + int (*get_key)(void *key, int len, u8 *seq, void *priv); + + /* procfs handler for printing out key information and possible + * statistics */ + char * (*print_stats)(char *p, void *priv); + + /* maximum number of bytes added by encryption; encrypt buf is + * allocated with extra_prefix_len bytes, copy of in_buf, and + * extra_postfix_len; encrypt need not use all this space, but + * the result must start at the beginning of the buffer and correct + * length must be returned */ + int extra_prefix_len, extra_postfix_len; + + struct module *owner; +}; + +struct ieee80211_crypt_data { + struct list_head list; /* delayed deletion list */ + struct ieee80211_crypto_ops *ops; + void *priv; + atomic_t refcnt; +}; + +int ieee80211_register_crypto_ops(struct ieee80211_crypto_ops *ops); +int ieee80211_unregister_crypto_ops(struct ieee80211_crypto_ops *ops); +struct ieee80211_crypto_ops * ieee80211_get_crypto_ops(const char *name); +void ieee80211_crypt_deinit_entries(struct ieee80211_device *, int); +void ieee80211_crypt_deinit_handler(unsigned long); +void ieee80211_crypt_delayed_deinit(struct ieee80211_device *ieee, + struct ieee80211_crypt_data **crypt); +#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)) +#define offset_in_page(p) ((unsigned long)(p) & ~PAGE_MASK) +#define crypto_alloc_tfm crypto_alloc_tfm_rtl +#define crypto_free_tfm crypto_free_tfm_rtl +#endif + +#endif diff -Nur linux-2.6.30.5.orig/drivers/net/wireless/rtl8187b/ieee80211/ieee80211_crypt_tkip.c linux-2.6.30.5/drivers/net/wireless/rtl8187b/ieee80211/ieee80211_crypt_tkip.c --- linux-2.6.30.5.orig/drivers/net/wireless/rtl8187b/ieee80211/ieee80211_crypt_tkip.c 1970-01-01 01:00:00.000000000 +0100 +++ linux-2.6.30.5/drivers/net/wireless/rtl8187b/ieee80211/ieee80211_crypt_tkip.c 2009-08-23 19:01:04.000000000 +0200 @@ -0,0 +1,996 @@ +/* + * Host AP crypt: host-based TKIP encryption implementation for Host AP driver + * + * Copyright (c) 2003-2004, Jouni Malinen + * + * 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. See README and COPYING for + * more details. + */ + +//#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "ieee80211.h" + +#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)) +#include "rtl_crypto.h" +#else +#include +#endif +//#include +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20) + #include +#else + #include +#endif + +#include + +MODULE_AUTHOR("Jouni Malinen"); +MODULE_DESCRIPTION("Host AP crypt: TKIP"); +MODULE_LICENSE("GPL"); + +struct ieee80211_tkip_data { +#define TKIP_KEY_LEN 32 + u8 key[TKIP_KEY_LEN]; + int key_set; + + u32 tx_iv32; + u16 tx_iv16; + u16 tx_ttak[5]; + int tx_phase1_done; + + u32 rx_iv32; + u16 rx_iv16; + u16 rx_ttak[5]; + int rx_phase1_done; + u32 rx_iv32_new; + u16 rx_iv16_new; + + u32 dot11RSNAStatsTKIPReplays; + u32 dot11RSNAStatsTKIPICVErrors; + u32 dot11RSNAStatsTKIPLocalMICFailures; + + int key_idx; + + #if(LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,21)) + struct crypto_blkcipher *rx_tfm_arc4; + struct crypto_hash *rx_tfm_michael; + struct crypto_blkcipher *tx_tfm_arc4; + struct crypto_hash *tx_tfm_michael; + #endif + + struct crypto_tfm *tfm_arc4; + struct crypto_tfm *tfm_michael; + + /* scratch buffers for virt_to_page() (crypto API) */ + u8 rx_hdr[16], tx_hdr[16]; +}; + +static void * ieee80211_tkip_init(int key_idx) +{ + struct ieee80211_tkip_data *priv; + + priv = kmalloc(sizeof(*priv), GFP_ATOMIC); + if (priv == NULL) + goto fail; + memset(priv, 0, sizeof(*priv)); + priv->key_idx = key_idx; + + #if(LINUX_VERSION_CODE < KERNEL_VERSION(2,6,21)) + priv->tfm_arc4 = crypto_alloc_tfm("arc4", 0); + if (priv->tfm_arc4 == NULL) { + printk(KERN_DEBUG "ieee80211_crypt_tkip: could not allocate " + "crypto API arc4\n"); + goto fail; + } + + priv->tfm_michael = crypto_alloc_tfm("michael_mic", 0); + if (priv->tfm_michael == NULL) { + printk(KERN_DEBUG "ieee80211_crypt_tkip: could not allocate " + "crypto API michael_mic\n"); + goto fail; + } + + #else + priv->tx_tfm_arc4 = crypto_alloc_blkcipher("ecb(arc4)", 0, + CRYPTO_ALG_ASYNC); + if (IS_ERR(priv->tx_tfm_arc4)) { + printk(KERN_DEBUG "ieee80211_crypt_tkip: could not allocate " + "crypto API arc4\n"); + priv->tx_tfm_arc4 = NULL; + goto fail; + } + + priv->tx_tfm_michael = crypto_alloc_hash("michael_mic", 0, + CRYPTO_ALG_ASYNC); + if (IS_ERR(priv->tx_tfm_michael)) { + printk(KERN_DEBUG "ieee80211_crypt_tkip: could not allocate " + "crypto API michael_mic\n"); + priv->tx_tfm_michael = NULL; + goto fail; + } + + priv->rx_tfm_arc4 = crypto_alloc_blkcipher("ecb(arc4)", 0, + CRYPTO_ALG_ASYNC); + if (IS_ERR(priv->rx_tfm_arc4)) { + printk(KERN_DEBUG "ieee80211_crypt_tkip: could not allocate " + "crypto API arc4\n"); + priv->rx_tfm_arc4 = NULL; + goto fail; + } + + priv->rx_tfm_michael = crypto_alloc_hash("michael_mic", 0, + CRYPTO_ALG_ASYNC); + if (IS_ERR(priv->rx_tfm_michael)) { + printk(KERN_DEBUG "ieee80211_crypt_tkip: could not allocate " + "crypto API michael_mic\n"); + priv->rx_tfm_michael = NULL; + goto fail; + } + #endif + return priv; + +fail: + if (priv) { + #if(LINUX_VERSION_CODE < KERNEL_VERSION(2,6,21)) + if (priv->tfm_michael) + crypto_free_tfm(priv->tfm_michael); + if (priv->tfm_arc4) + crypto_free_tfm(priv->tfm_arc4); + #else + if (priv->tx_tfm_michael) + crypto_free_hash(priv->tx_tfm_michael); + if (priv->tx_tfm_arc4) + crypto_free_blkcipher(priv->tx_tfm_arc4); + if (priv->rx_tfm_michael) + crypto_free_hash(priv->rx_tfm_michael); + if (priv->rx_tfm_arc4) + crypto_free_blkcipher(priv->rx_tfm_arc4); + #endif + kfree(priv); + } + + return NULL; +} + + +static void ieee80211_tkip_deinit(void *priv) +{ + struct ieee80211_tkip_data *_priv = priv; + #if(LINUX_VERSION_CODE < KERNEL_VERSION(2,6,21)) + if (_priv && _priv->tfm_michael) + crypto_free_tfm(_priv->tfm_michael); + if (_priv && _priv->tfm_arc4) + crypto_free_tfm(_priv->tfm_arc4); + #else + if (_priv) { + if (_priv->tx_tfm_michael) + crypto_free_hash(_priv->tx_tfm_michael); + if (_priv->tx_tfm_arc4) + crypto_free_blkcipher(_priv->tx_tfm_arc4); + if (_priv->rx_tfm_michael) + crypto_free_hash(_priv->rx_tfm_michael); + if (_priv->rx_tfm_arc4) + crypto_free_blkcipher(_priv->rx_tfm_arc4); + } + #endif + kfree(priv); +} + + +static inline u16 RotR1(u16 val) +{ + return (val >> 1) | (val << 15); +} + + +static inline u8 Lo8(u16 val) +{ + return val & 0xff; +} + + +static inline u8 Hi8(u16 val) +{ + return val >> 8; +} + + +static inline u16 Lo16(u32 val) +{ + return val & 0xffff; +} + + +static inline u16 Hi16(u32 val) +{ + return val >> 16; +} + + +static inline u16 Mk16(u8 hi, u8 lo) +{ + return lo | (((u16) hi) << 8); +} + + +static inline u16 Mk16_le(u16 *v) +{ + return le16_to_cpu(*v); +} + + +static const u16 Sbox[256] = +{ + 0xC6A5, 0xF884, 0xEE99, 0xF68D, 0xFF0D, 0xD6BD, 0xDEB1, 0x9154, + 0x6050, 0x0203, 0xCEA9, 0x567D, 0xE719, 0xB562, 0x4DE6, 0xEC9A, + 0x8F45, 0x1F9D, 0x8940, 0xFA87, 0xEF15, 0xB2EB, 0x8EC9, 0xFB0B, + 0x41EC, 0xB367, 0x5FFD, 0x45EA, 0x23BF, 0x53F7, 0xE496, 0x9B5B, + 0x75C2, 0xE11C, 0x3DAE, 0x4C6A, 0x6C5A, 0x7E41, 0xF502, 0x834F, + 0x685C, 0x51F4, 0xD134, 0xF908, 0xE293, 0xAB73, 0x6253, 0x2A3F, + 0x080C, 0x9552, 0x4665, 0x9D5E, 0x3028, 0x37A1, 0x0A0F, 0x2FB5, + 0x0E09, 0x2436, 0x1B9B, 0xDF3D, 0xCD26, 0x4E69, 0x7FCD, 0xEA9F, + 0x121B, 0x1D9E, 0x5874, 0x342E, 0x362D, 0xDCB2, 0xB4EE, 0x5BFB, + 0xA4F6, 0x764D, 0xB761, 0x7DCE, 0x527B, 0xDD3E, 0x5E71, 0x1397, + 0xA6F5, 0xB968, 0x0000, 0xC12C, 0x4060, 0xE31F, 0x79C8, 0xB6ED, + 0xD4BE, 0x8D46, 0x67D9, 0x724B, 0x94DE, 0x98D4, 0xB0E8, 0x854A, + 0xBB6B, 0xC52A, 0x4FE5, 0xED16, 0x86C5, 0x9AD7, 0x6655, 0x1194, + 0x8ACF, 0xE910, 0x0406, 0xFE81, 0xA0F0, 0x7844, 0x25BA, 0x4BE3, + 0xA2F3, 0x5DFE, 0x80C0, 0x058A, 0x3FAD, 0x21BC, 0x7048, 0xF104, + 0x63DF, 0x77C1, 0xAF75, 0x4263, 0x2030, 0xE51A, 0xFD0E, 0xBF6D, + 0x814C, 0x1814, 0x2635, 0xC32F, 0xBEE1, 0x35A2, 0x88CC, 0x2E39, + 0x9357, 0x55F2, 0xFC82, 0x7A47, 0xC8AC, 0xBAE7, 0x322B, 0xE695, + 0xC0A0, 0x1998, 0x9ED1, 0xA37F, 0x4466, 0x547E, 0x3BAB, 0x0B83, + 0x8CCA, 0xC729, 0x6BD3, 0x283C, 0xA779, 0xBCE2, 0x161D, 0xAD76, + 0xDB3B, 0x6456, 0x744E, 0x141E, 0x92DB, 0x0C0A, 0x486C, 0xB8E4, + 0x9F5D, 0xBD6E, 0x43EF, 0xC4A6, 0x39A8, 0x31A4, 0xD337, 0xF28B, + 0xD532, 0x8B43, 0x6E59, 0xDAB7, 0x018C, 0xB164, 0x9CD2, 0x49E0, + 0xD8B4, 0xACFA, 0xF307, 0xCF25, 0xCAAF, 0xF48E, 0x47E9, 0x1018, + 0x6FD5, 0xF088, 0x4A6F, 0x5C72, 0x3824, 0x57F1, 0x73C7, 0x9751, + 0xCB23, 0xA17C, 0xE89C, 0x3E21, 0x96DD, 0x61DC, 0x0D86, 0x0F85, + 0xE090, 0x7C42, 0x71C4, 0xCCAA, 0x90D8, 0x0605, 0xF701, 0x1C12, + 0xC2A3, 0x6A5F, 0xAEF9, 0x69D0, 0x1791, 0x9958, 0x3A27, 0x27B9, + 0xD938, 0xEB13, 0x2BB3, 0x2233, 0xD2BB, 0xA970, 0x0789, 0x33A7, + 0x2DB6, 0x3C22, 0x1592, 0xC920, 0x8749, 0xAAFF, 0x5078, 0xA57A, + 0x038F, 0x59F8, 0x0980, 0x1A17, 0x65DA, 0xD731, 0x84C6, 0xD0B8, + 0x82C3, 0x29B0, 0x5A77, 0x1E11, 0x7BCB, 0xA8FC, 0x6DD6, 0x2C3A, +}; + + +static inline u16 _S_(u16 v) +{ + u16 t = Sbox[Hi8(v)]; + return Sbox[Lo8(v)] ^ ((t << 8) | (t >> 8)); +} + +#ifndef JOHN_TKIP +#define PHASE1_LOOP_COUNT 8 + +static void tkip_mixing_phase1(u16 *TTAK, const u8 *TK, const u8 *TA, u32 IV32) +{ + int i, j; + + /* Initialize the 80-bit TTAK from TSC (IV32) and TA[0..5] */ + TTAK[0] = Lo16(IV32); + TTAK[1] = Hi16(IV32); + TTAK[2] = Mk16(TA[1], TA[0]); + TTAK[3] = Mk16(TA[3], TA[2]); + TTAK[4] = Mk16(TA[5], TA[4]); + + for (i = 0; i < PHASE1_LOOP_COUNT; i++) { + j = 2 * (i & 1); + TTAK[0] += _S_(TTAK[4] ^ Mk16(TK[1 + j], TK[0 + j])); + TTAK[1] += _S_(TTAK[0] ^ Mk16(TK[5 + j], TK[4 + j])); + TTAK[2] += _S_(TTAK[1] ^ Mk16(TK[9 + j], TK[8 + j])); + TTAK[3] += _S_(TTAK[2] ^ Mk16(TK[13 + j], TK[12 + j])); + TTAK[4] += _S_(TTAK[3] ^ Mk16(TK[1 + j], TK[0 + j])) + i; + } +} + + +static void tkip_mixing_phase2(u8 *WEPSeed, const u8 *TK, const u16 *TTAK, + u16 IV16) +{ + /* Make temporary area overlap WEP seed so that the final copy can be + * avoided on little endian hosts. */ + u16 *PPK = (u16 *) &WEPSeed[4]; + + /* Step 1 - make copy of TTAK and bring in TSC */ + PPK[0] = TTAK[0]; + PPK[1] = TTAK[1]; + PPK[2] = TTAK[2]; + PPK[3] = TTAK[3]; + PPK[4] = TTAK[4]; + PPK[5] = TTAK[4] + IV16; + + /* Step 2 - 96-bit bijective mixing using S-box */ + PPK[0] += _S_(PPK[5] ^ Mk16_le((u16 *) &TK[0])); + PPK[1] += _S_(PPK[0] ^ Mk16_le((u16 *) &TK[2])); + PPK[2] += _S_(PPK[1] ^ Mk16_le((u16 *) &TK[4])); + PPK[3] += _S_(PPK[2] ^ Mk16_le((u16 *) &TK[6])); + PPK[4] += _S_(PPK[3] ^ Mk16_le((u16 *) &TK[8])); + PPK[5] += _S_(PPK[4] ^ Mk16_le((u16 *) &TK[10])); + + PPK[0] += RotR1(PPK[5] ^ Mk16_le((u16 *) &TK[12])); + PPK[1] += RotR1(PPK[0] ^ Mk16_le((u16 *) &TK[14])); + PPK[2] += RotR1(PPK[1]); + PPK[3] += RotR1(PPK[2]); + PPK[4] += RotR1(PPK[3]); + PPK[5] += RotR1(PPK[4]); + + /* Step 3 - bring in last of TK bits, assign 24-bit WEP IV value + * WEPSeed[0..2] is transmitted as WEP IV */ + WEPSeed[0] = Hi8(IV16); + WEPSeed[1] = (Hi8(IV16) | 0x20) & 0x7F; + WEPSeed[2] = Lo8(IV16); + WEPSeed[3] = Lo8((PPK[5] ^ Mk16_le((u16 *) &TK[0])) >> 1); + +#ifdef __BIG_ENDIAN + { + int i; + for (i = 0; i < 6; i++) + PPK[i] = (PPK[i] << 8) | (PPK[i] >> 8); + } +#endif +} +#endif +static int ieee80211_tkip_encrypt(struct sk_buff *skb, int hdr_len, void *priv) +{ + struct ieee80211_tkip_data *tkey = priv; + #if(LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,21)) + struct blkcipher_desc desc = {.tfm = tkey->tx_tfm_arc4}; + #endif + int len; + u8 *pos; + struct ieee80211_hdr *hdr; +#ifndef JOHN_TKIP + u8 rc4key[16],*icv; + u32 crc; + struct scatterlist sg; +#endif + #if(LINUX_VERSION_CODE >=KERNEL_VERSION(2,6,21)) + int ret; + #endif + + if (skb_headroom(skb) < 8 || skb_tailroom(skb) < 4 || + skb->len < hdr_len) + return -1; + + hdr = (struct ieee80211_hdr *) skb->data; +#if 0 +printk("@@ tkey\n"); +printk("%x|", ((u32*)tkey->key)[0]); +printk("%x|", ((u32*)tkey->key)[1]); +printk("%x|", ((u32*)tkey->key)[2]); +printk("%x|", ((u32*)tkey->key)[3]); +printk("%x|", ((u32*)tkey->key)[4]); +printk("%x|", ((u32*)tkey->key)[5]); +printk("%x|", ((u32*)tkey->key)[6]); +printk("%x\n", ((u32*)tkey->key)[7]); +#endif + +#ifndef JOHN_TKIP + if (!tkey->tx_phase1_done) { + tkip_mixing_phase1(tkey->tx_ttak, tkey->key, hdr->addr2, + tkey->tx_iv32); + tkey->tx_phase1_done = 1; + } + tkip_mixing_phase2(rc4key, tkey->key, tkey->tx_ttak, tkey->tx_iv16); + +#else + tkey->tx_phase1_done = 1; +#endif /*JOHN_TKIP*/ + + len = skb->len - hdr_len; + pos = skb_push(skb, 8); + memmove(pos, pos + 8, hdr_len); + pos += hdr_len; + +#ifdef JOHN_TKIP + *pos++ = Hi8(tkey->tx_iv16); + *pos++ = (Hi8(tkey->tx_iv16) | 0x20) & 0x7F; + *pos++ = Lo8(tkey->tx_iv16); +#else + *pos++ = rc4key[0]; + *pos++ = rc4key[1]; + *pos++ = rc4key[2]; +#endif + *pos++ = (tkey->key_idx << 6) | (1 << 5) /* Ext IV included */; + *pos++ = tkey->tx_iv32 & 0xff; + *pos++ = (tkey->tx_iv32 >> 8) & 0xff; + *pos++ = (tkey->tx_iv32 >> 16) & 0xff; + *pos++ = (tkey->tx_iv32 >> 24) & 0xff; +#ifndef JOHN_TKIP + icv = skb_put(skb, 4); +#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)) + crc = ~crc32_le(~0, pos, len); +#else + crc = ~ether_crc_le(len, pos); +#endif + icv[0] = crc; + icv[1] = crc >> 8; + icv[2] = crc >> 16; + icv[3] = crc >> 24; + #if(LINUX_VERSION_CODE < KERNEL_VERSION(2,6,21)) + crypto_cipher_setkey(tkey->tfm_arc4, rc4key, 16); + sg.page = virt_to_page(pos); + sg.offset = offset_in_page(pos); + sg.length = len + 4; + crypto_cipher_encrypt(tkey->tfm_arc4, &sg, &sg, len + 4); + #else + crypto_blkcipher_setkey(tkey->tx_tfm_arc4, rc4key, 16); + #if(LINUX_VERSION_CODE < KERNEL_VERSION(2,6,24)) + sg.page = virt_to_page(pos); + sg.offset = offset_in_page(pos); + sg.length = len + 4; + #else + sg_init_one(&sg, pos, len + 4); + #endif + ret= crypto_blkcipher_encrypt(&desc, &sg, &sg, len + 4); + #endif +#endif + tkey->tx_iv16++; + if (tkey->tx_iv16 == 0) { + tkey->tx_phase1_done = 0; + tkey->tx_iv32++; + } +#ifndef JOHN_TKIP + #if(LINUX_VERSION_CODE = KERNEL_VERSION(2,6,21)) + struct blkcipher_desc desc = {.tfm = tkey->rx_tfm_arc4}; + #endif + u8 keyidx, *pos; + u32 iv32; + u16 iv16; + struct ieee80211_hdr *hdr; +#ifndef JOHN_TKIP + u8 icv[4]; + u32 crc; + struct scatterlist sg; + u8 rc4key[16]; + int plen; +#endif + if (skb->len < hdr_len + 8 + 4) + return -1; + + hdr = (struct ieee80211_hdr *) skb->data; + pos = skb->data + hdr_len; + keyidx = pos[3]; + if (!(keyidx & (1 << 5))) { + if (net_ratelimit()) { + printk(KERN_DEBUG "TKIP: received packet without ExtIV" + " flag from " MAC_FMT "\n", MAC_ARG(hdr->addr2)); + } + return -2; + } + keyidx >>= 6; + if (tkey->key_idx != keyidx) { + printk(KERN_DEBUG "TKIP: RX tkey->key_idx=%d frame " + "keyidx=%d priv=%p\n", tkey->key_idx, keyidx, priv); + return -6; + } + if (!tkey->key_set) { + if (net_ratelimit()) { + printk(KERN_DEBUG "TKIP: received packet from " MAC_FMT + " with keyid=%d that does not have a configured" + " key\n", MAC_ARG(hdr->addr2), keyidx); + } + return -3; + } + iv16 = (pos[0] << 8) | pos[2]; + iv32 = pos[4] | (pos[5] << 8) | (pos[6] << 16) | (pos[7] << 24); + pos += 8; +#ifndef JOHN_TKIP +#if 0 + if (iv32 < tkey->rx_iv32 || + (iv32 == tkey->rx_iv32 && iv16 <= tkey->rx_iv16)) { + if (net_ratelimit()) { + printk(KERN_DEBUG "TKIP: replay detected: STA=" MAC_FMT + " previous TSC %08x%04x received TSC " + "%08x%04x\n", MAC_ARG(hdr->addr2), + tkey->rx_iv32, tkey->rx_iv16, iv32, iv16); + } + tkey->dot11RSNAStatsTKIPReplays++; + return -4; + } +#endif + if (iv32 != tkey->rx_iv32 || !tkey->rx_phase1_done) { + tkip_mixing_phase1(tkey->rx_ttak, tkey->key, hdr->addr2, iv32); + tkey->rx_phase1_done = 1; + } + tkip_mixing_phase2(rc4key, tkey->key, tkey->rx_ttak, iv16); + + plen = skb->len - hdr_len - 12; + #if(LINUX_VERSION_CODE tfm_arc4, rc4key, 16); + sg.page = virt_to_page(pos); + sg.offset = offset_in_page(pos); + sg.length = plen + 4; + crypto_cipher_decrypt(tkey->tfm_arc4, &sg, &sg, plen + 4); + #else + crypto_blkcipher_setkey(tkey->rx_tfm_arc4, rc4key, 16); + #if (LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 24)) + sg.page = virt_to_page(pos); + sg.offset = offset_in_page(pos); + sg.length = plen + 4; + #else + sg_init_one(&sg, pos, plen + 4); + #endif + if (crypto_blkcipher_decrypt(&desc, &sg, &sg, plen + 4)) { + if (net_ratelimit()) { + printk(KERN_DEBUG ": TKIP: failed to decrypt " + "received packet from " MAC_FMT "\n", + MAC_ARG(hdr->addr2)); + } + return -7; + } + #endif + +#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)) + crc = ~crc32_le(~0, pos, plen); +#else + crc = ~ether_crc_le(plen, pos); +#endif + icv[0] = crc; + icv[1] = crc >> 8; + icv[2] = crc >> 16; + icv[3] = crc >> 24; + if (memcmp(icv, pos + plen, 4) != 0) { + if (iv32 != tkey->rx_iv32) { + /* Previously cached Phase1 result was already lost, so + * it needs to be recalculated for the next packet. */ + tkey->rx_phase1_done = 0; + } + if (net_ratelimit()) { + printk(KERN_DEBUG "TKIP: ICV error detected: STA=" + MAC_FMT "\n", MAC_ARG(hdr->addr2)); + } + tkey->dot11RSNAStatsTKIPICVErrors++; + return -5; + } + +#endif /* JOHN_TKIP */ + + /* Update real counters only after Michael MIC verification has + * completed */ + tkey->rx_iv32_new = iv32; + tkey->rx_iv16_new = iv16; + + /* Remove IV and ICV */ + memmove(skb->data + 8, skb->data, hdr_len); + skb_pull(skb, 8); + skb_trim(skb, skb->len - 4); + +//john's test +#ifdef JOHN_DUMP +if( ((u16*)skb->data)[0] & 0x4000){ + printk("@@ rx decrypted skb->data"); + int i; + for(i=0;ilen;i++){ + if( (i%24)==0 ) printk("\n"); + printk("%2x ", ((u8*)skb->data)[i]); + } + printk("\n"); +} +#endif /*JOHN_DUMP*/ + return keyidx; +} + +#if(LINUX_VERSION_CODE < KERNEL_VERSION(2,6,21)) +static int michael_mic(struct ieee80211_tkip_data *tkey, u8 *key, u8 *hdr, + u8 *data, size_t data_len, u8 *mic) +{ + struct scatterlist sg[2]; +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20) + struct hash_desc desc; + int ret=0; +#endif + if (tkey->tfm_michael == NULL) { + printk(KERN_WARNING "michael_mic: tfm_michael == NULL\n"); + return -1; + } + sg[0].page = virt_to_page(hdr); + sg[0].offset = offset_in_page(hdr); + sg[0].length = 16; + + sg[1].page = virt_to_page(data); + sg[1].offset = offset_in_page(data); + sg[1].length = data_len; + + //crypto_digest_init(tkey->tfm_michael); + //crypto_digest_setkey(tkey->tfm_michael, key, 8); + //crypto_digest_update(tkey->tfm_michael, sg, 2); + //crypto_digest_final(tkey->tfm_michael, mic); + + //return 0; +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20) + crypto_digest_init(tkey->tfm_michael); + crypto_digest_setkey(tkey->tfm_michael, key, 8); + crypto_digest_update(tkey->tfm_michael, sg, 2); + crypto_digest_final(tkey->tfm_michael, mic); + + return 0; +#else +if (crypto_hash_setkey(tkey->tfm_michael, key, 8)) + return -1; + +// return 0; + desc.tfm = tkey->tfm_michael; + desc.flags = 0; + ret = crypto_hash_digest(&desc, sg, data_len + 16, mic); + return ret; +#endif +} +#else +static int michael_mic(struct crypto_hash *tfm_michael, u8 * key, u8 * hdr, + u8 * data, size_t data_len, u8 * mic) +{ + struct hash_desc desc; + struct scatterlist sg[2]; + + if (tfm_michael == NULL) { + printk(KERN_WARNING "michael_mic: tfm_michael == NULL\n"); + return -1; + } +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,24) + sg[0].page = virt_to_page(hdr); + sg[0].offset = offset_in_page(hdr); + sg[0].length = 16; + + sg[1].page = virt_to_page(data); + sg[1].offset = offset_in_page(data); + sg[1].length = data_len; +#else + sg_init_table(sg, 2); + sg_set_buf(&sg[0], hdr, 16); + sg_set_buf(&sg[1], data, data_len); +#endif + if (crypto_hash_setkey(tfm_michael, key, 8)) + return -1; + + desc.tfm = tfm_michael; + desc.flags = 0; + return crypto_hash_digest(&desc, sg, data_len + 16, mic); +} +#endif + + + +static void michael_mic_hdr(struct sk_buff *skb, u8 *hdr) +{ + struct ieee80211_hdr *hdr11; + + hdr11 = (struct ieee80211_hdr *) skb->data; + switch (le16_to_cpu(hdr11->frame_ctl) & + (IEEE80211_FCTL_FROMDS | IEEE80211_FCTL_TODS)) { + case IEEE80211_FCTL_TODS: + memcpy(hdr, hdr11->addr3, ETH_ALEN); /* DA */ + memcpy(hdr + ETH_ALEN, hdr11->addr2, ETH_ALEN); /* SA */ + break; + case IEEE80211_FCTL_FROMDS: + memcpy(hdr, hdr11->addr1, ETH_ALEN); /* DA */ + memcpy(hdr + ETH_ALEN, hdr11->addr3, ETH_ALEN); /* SA */ + break; + case IEEE80211_FCTL_FROMDS | IEEE80211_FCTL_TODS: + memcpy(hdr, hdr11->addr3, ETH_ALEN); /* DA */ + memcpy(hdr + ETH_ALEN, hdr11->addr4, ETH_ALEN); /* SA */ + break; + case 0: + memcpy(hdr, hdr11->addr1, ETH_ALEN); /* DA */ + memcpy(hdr + ETH_ALEN, hdr11->addr2, ETH_ALEN); /* SA */ + break; + } + + hdr[12] = 0; /* priority */ + + hdr[13] = hdr[14] = hdr[15] = 0; /* reserved */ +} + + +static int ieee80211_michael_mic_add(struct sk_buff *skb, int hdr_len, void *priv) +{ + struct ieee80211_tkip_data *tkey = priv; + u8 *pos; + struct ieee80211_hdr *hdr; + + hdr = (struct ieee80211_hdr *) skb->data; + + if (skb_tailroom(skb) < 8 || skb->len < hdr_len) { + printk(KERN_DEBUG "Invalid packet for Michael MIC add " + "(tailroom=%d hdr_len=%d skb->len=%d)\n", + skb_tailroom(skb), hdr_len, skb->len); + return -1; + } + + michael_mic_hdr(skb, tkey->tx_hdr); + + // { david, 2006.9.1 + // fix the wpa process with wmm enabled. + if(IEEE80211_QOS_HAS_SEQ(le16_to_cpu(hdr->frame_ctl))) { + tkey->tx_hdr[12] = *(skb->data + hdr_len - 2) & 0x07; + } + // } + pos = skb_put(skb, 8); + #if(LINUX_VERSION_CODE < KERNEL_VERSION(2,6,21)) + if (michael_mic(tkey, &tkey->key[16], tkey->tx_hdr, + skb->data + hdr_len, skb->len - 8 - hdr_len, pos)) + #else + if (michael_mic(tkey->tx_tfm_michael, &tkey->key[16], tkey->tx_hdr, + skb->data + hdr_len, skb->len - 8 - hdr_len, pos)) + #endif + return -1; + + return 0; +} + + +#if WIRELESS_EXT >= 18 +static void ieee80211_michael_mic_failure(struct net_device *dev, + struct ieee80211_hdr *hdr, + int keyidx) +{ + union iwreq_data wrqu; + struct iw_michaelmicfailure ev; + + /* TODO: needed parameters: count, keyid, key type, TSC */ + memset(&ev, 0, sizeof(ev)); + ev.flags = keyidx & IW_MICFAILURE_KEY_ID; + if (hdr->addr1[0] & 0x01) + ev.flags |= IW_MICFAILURE_GROUP; + else + ev.flags |= IW_MICFAILURE_PAIRWISE; + ev.src_addr.sa_family = ARPHRD_ETHER; + memcpy(ev.src_addr.sa_data, hdr->addr2, ETH_ALEN); + memset(&wrqu, 0, sizeof(wrqu)); + wrqu.data.length = sizeof(ev); + wireless_send_event(dev, IWEVMICHAELMICFAILURE, &wrqu, (char *) &ev); +} +#elif WIRELESS_EXT >= 15 +static void ieee80211_michael_mic_failure(struct net_device *dev, + struct ieee80211_hdr *hdr, + int keyidx) +{ + union iwreq_data wrqu; + char buf[128]; + + /* TODO: needed parameters: count, keyid, key type, TSC */ + sprintf(buf, "MLME-MICHAELMICFAILURE.indication(keyid=%d %scast addr=" + MAC_FMT ")", keyidx, hdr->addr1[0] & 0x01 ? "broad" : "uni", + MAC_ARG(hdr->addr2)); + memset(&wrqu, 0, sizeof(wrqu)); + wrqu.data.length = strlen(buf); + wireless_send_event(dev, IWEVCUSTOM, &wrqu, buf); +} +#else /* WIRELESS_EXT >= 15 */ +static inline void ieee80211_michael_mic_failure(struct net_device *dev, + struct ieee80211_hdr *hdr, + int keyidx) +{ +} +#endif /* WIRELESS_EXT >= 15 */ + + +static int ieee80211_michael_mic_verify(struct sk_buff *skb, int keyidx, + int hdr_len, void *priv) +{ + struct ieee80211_tkip_data *tkey = priv; + u8 mic[8]; + struct ieee80211_hdr *hdr; + + hdr = (struct ieee80211_hdr *) skb->data; + + if (!tkey->key_set) + return -1; + + michael_mic_hdr(skb, tkey->rx_hdr); + // { david, 2006.9.1 + // fix the wpa process with wmm enabled. + if(IEEE80211_QOS_HAS_SEQ(le16_to_cpu(hdr->frame_ctl))) { + tkey->rx_hdr[12] = *(skb->data + hdr_len - 2) & 0x07; + } + // } + #if(LINUX_VERSION_CODE < KERNEL_VERSION(2,6,21)) + if (michael_mic(tkey, &tkey->key[24], tkey->rx_hdr, + skb->data + hdr_len, skb->len - 8 - hdr_len, mic)) + #else + if (michael_mic(tkey->rx_tfm_michael, &tkey->key[24], tkey->rx_hdr, + skb->data + hdr_len, skb->len - 8 - hdr_len, mic)) + #endif + return -1; + if (memcmp(mic, skb->data + skb->len - 8, 8) != 0) { + struct ieee80211_hdr *hdr; + hdr = (struct ieee80211_hdr *) skb->data; + printk(KERN_DEBUG "%s: Michael MIC verification failed for " + "MSDU from " MAC_FMT " keyidx=%d\n", + skb->dev ? skb->dev->name : "N/A", MAC_ARG(hdr->addr2), + keyidx); + if (skb->dev) + ieee80211_michael_mic_failure(skb->dev, hdr, keyidx); + tkey->dot11RSNAStatsTKIPLocalMICFailures++; + return -1; + } + + /* Update TSC counters for RX now that the packet verification has + * completed. */ + tkey->rx_iv32 = tkey->rx_iv32_new; + tkey->rx_iv16 = tkey->rx_iv16_new; + + skb_trim(skb, skb->len - 8); + + return 0; +} + + +static int ieee80211_tkip_set_key(void *key, int len, u8 *seq, void *priv) +{ + struct ieee80211_tkip_data *tkey = priv; + int keyidx; + #if(LINUX_VERSION_CODE < KERNEL_VERSION(2,6,21)) + struct crypto_tfm *tfm = tkey->tfm_michael; + struct crypto_tfm *tfm2 = tkey->tfm_arc4; + #else + struct crypto_hash *tfm = tkey->tx_tfm_michael; + struct crypto_blkcipher *tfm2 = tkey->tx_tfm_arc4; + struct crypto_hash *tfm3 = tkey->rx_tfm_michael; + struct crypto_blkcipher *tfm4 = tkey->rx_tfm_arc4; + #endif + + keyidx = tkey->key_idx; + memset(tkey, 0, sizeof(*tkey)); + tkey->key_idx = keyidx; + + #if(LINUX_VERSION_CODE < KERNEL_VERSION(2,6,21)) + tkey->tfm_michael = tfm; + tkey->tfm_arc4 = tfm2; + #else + tkey->tx_tfm_michael = tfm; + tkey->tx_tfm_arc4 = tfm2; + tkey->rx_tfm_michael = tfm3; + tkey->rx_tfm_arc4 = tfm4; + #endif + + if (len == TKIP_KEY_LEN) { + memcpy(tkey->key, key, TKIP_KEY_LEN); + tkey->key_set = 1; + tkey->tx_iv16 = 1; /* TSC is initialized to 1 */ + if (seq) { + tkey->rx_iv32 = (seq[5] << 24) | (seq[4] << 16) | + (seq[3] << 8) | seq[2]; + tkey->rx_iv16 = (seq[1] << 8) | seq[0]; + } + } else if (len == 0) + tkey->key_set = 0; + else + return -1; + + return 0; +} + + +static int ieee80211_tkip_get_key(void *key, int len, u8 *seq, void *priv) +{ + struct ieee80211_tkip_data *tkey = priv; + + if (len < TKIP_KEY_LEN) + return -1; + + if (!tkey->key_set) + return 0; + memcpy(key, tkey->key, TKIP_KEY_LEN); + + if (seq) { + /* Return the sequence number of the last transmitted frame. */ + u16 iv16 = tkey->tx_iv16; + u32 iv32 = tkey->tx_iv32; + if (iv16 == 0) + iv32--; + iv16--; + seq[0] = tkey->tx_iv16; + seq[1] = tkey->tx_iv16 >> 8; + seq[2] = tkey->tx_iv32; + seq[3] = tkey->tx_iv32 >> 8; + seq[4] = tkey->tx_iv32 >> 16; + seq[5] = tkey->tx_iv32 >> 24; + } + + return TKIP_KEY_LEN; +} + + +static char * ieee80211_tkip_print_stats(char *p, void *priv) +{ + struct ieee80211_tkip_data *tkip = priv; + p += sprintf(p, "key[%d] alg=TKIP key_set=%d " + "tx_pn=%02x%02x%02x%02x%02x%02x " + "rx_pn=%02x%02x%02x%02x%02x%02x " + "replays=%d icv_errors=%d local_mic_failures=%d\n", + tkip->key_idx, tkip->key_set, + (tkip->tx_iv32 >> 24) & 0xff, + (tkip->tx_iv32 >> 16) & 0xff, + (tkip->tx_iv32 >> 8) & 0xff, + tkip->tx_iv32 & 0xff, + (tkip->tx_iv16 >> 8) & 0xff, + tkip->tx_iv16 & 0xff, + (tkip->rx_iv32 >> 24) & 0xff, + (tkip->rx_iv32 >> 16) & 0xff, + (tkip->rx_iv32 >> 8) & 0xff, + tkip->rx_iv32 & 0xff, + (tkip->rx_iv16 >> 8) & 0xff, + tkip->rx_iv16 & 0xff, + tkip->dot11RSNAStatsTKIPReplays, + tkip->dot11RSNAStatsTKIPICVErrors, + tkip->dot11RSNAStatsTKIPLocalMICFailures); + return p; +} + + +static struct ieee80211_crypto_ops ieee80211_crypt_tkip = { + .name = "TKIP", + .init = ieee80211_tkip_init, + .deinit = ieee80211_tkip_deinit, + .encrypt_mpdu = ieee80211_tkip_encrypt, + .decrypt_mpdu = ieee80211_tkip_decrypt, + .encrypt_msdu = ieee80211_michael_mic_add, + .decrypt_msdu = ieee80211_michael_mic_verify, + .set_key = ieee80211_tkip_set_key, + .get_key = ieee80211_tkip_get_key, + .print_stats = ieee80211_tkip_print_stats, + .extra_prefix_len = 4 + 4, /* IV + ExtIV */ + .extra_postfix_len = 8 + 4, /* MIC + ICV */ + .owner = THIS_MODULE, +}; + + +int __init ieee80211_crypto_tkip_init(void) +{ + return ieee80211_register_crypto_ops(&ieee80211_crypt_tkip); +} + + +void __exit ieee80211_crypto_tkip_exit(void) +{ + ieee80211_unregister_crypto_ops(&ieee80211_crypt_tkip); +} + + +void ieee80211_tkip_null(void) +{ +// printk("============>%s()\n", __FUNCTION__); + return; +} + +#if 0 +#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)) +EXPORT_SYMBOL(ieee80211_tkip_null); +#else +EXPORT_SYMBOL_NOVERS(ieee80211_tkip_null); +#endif + + +module_init(ieee80211_crypto_tkip_init); +module_exit(ieee80211_crypto_tkip_exit); +#endif diff -Nur linux-2.6.30.5.orig/drivers/net/wireless/rtl8187b/ieee80211/ieee80211_crypt_wep.c linux-2.6.30.5/drivers/net/wireless/rtl8187b/ieee80211/ieee80211_crypt_wep.c --- linux-2.6.30.5.orig/drivers/net/wireless/rtl8187b/ieee80211/ieee80211_crypt_wep.c 1970-01-01 01:00:00.000000000 +0100 +++ linux-2.6.30.5/drivers/net/wireless/rtl8187b/ieee80211/ieee80211_crypt_wep.c 2009-08-23 19:01:04.000000000 +0200 @@ -0,0 +1,383 @@ +/* + * Host AP crypt: host-based WEP encryption implementation for Host AP driver + * + * Copyright (c) 2002-2004, Jouni Malinen + * + * 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. See README and COPYING for + * more details. + */ + +//#include +#include +#include +#include +#include +#include +#include +#include + +#include "ieee80211.h" + +#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)) +#include "rtl_crypto.h" +#else +#include +#endif + +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20) + #include +#else + #include +#endif +//#include +#include + +MODULE_AUTHOR("Jouni Malinen"); +MODULE_DESCRIPTION("Host AP crypt: WEP"); +MODULE_LICENSE("GPL"); + + +struct prism2_wep_data { + u32 iv; +#define WEP_KEY_LEN 13 + u8 key[WEP_KEY_LEN + 1]; + u8 key_len; + u8 key_idx; + #if(LINUX_VERSION_CODE < KERNEL_VERSION(2,6,21)) + struct crypto_tfm *tfm; + #else + struct crypto_blkcipher *tx_tfm; + struct crypto_blkcipher *rx_tfm; + #endif +}; + + +static void * prism2_wep_init(int keyidx) +{ + struct prism2_wep_data *priv; + + priv = kmalloc(sizeof(*priv), GFP_ATOMIC); + if (priv == NULL) + goto fail; + memset(priv, 0, sizeof(*priv)); + priv->key_idx = keyidx; + #if(LINUX_VERSION_CODE < KERNEL_VERSION(2,6,21)) + priv->tfm = crypto_alloc_tfm("arc4", 0); + if (priv->tfm == NULL) { + printk(KERN_DEBUG "ieee80211_crypt_wep: could not allocate " + "crypto API arc4\n"); + goto fail; + } + #else + priv->tx_tfm = crypto_alloc_blkcipher("ecb(arc4)", 0, CRYPTO_ALG_ASYNC); + if (IS_ERR(priv->tx_tfm)) { + printk(KERN_DEBUG "ieee80211_crypt_wep: could not allocate " + "crypto API arc4\n"); + priv->tx_tfm = NULL; + goto fail; + } + priv->rx_tfm = crypto_alloc_blkcipher("ecb(arc4)", 0, CRYPTO_ALG_ASYNC); + if (IS_ERR(priv->rx_tfm)) { + printk(KERN_DEBUG "ieee80211_crypt_wep: could not allocate " + "crypto API arc4\n"); + priv->rx_tfm = NULL; + goto fail; + } + #endif + + /* start WEP IV from a random value */ + get_random_bytes(&priv->iv, 4); + + return priv; + +fail: + #if(LINUX_VERSION_CODE < KERNEL_VERSION(2,6,21)) + if (priv) { + if (priv->tfm) + crypto_free_tfm(priv->tfm); + kfree(priv); + } + #else + if (priv) { + if (priv->tx_tfm) + crypto_free_blkcipher(priv->tx_tfm); + if (priv->rx_tfm) + crypto_free_blkcipher(priv->rx_tfm); + kfree(priv); + } + #endif + return NULL; +} + + +static void prism2_wep_deinit(void *priv) +{ + struct prism2_wep_data *_priv = priv; + #if(LINUX_VERSION_CODE < KERNEL_VERSION(2,6,21)) + if (_priv && _priv->tfm) + crypto_free_tfm(_priv->tfm); + #else + if (_priv) { + if (_priv->tx_tfm) + crypto_free_blkcipher(_priv->tx_tfm); + if (_priv->rx_tfm) + crypto_free_blkcipher(_priv->rx_tfm); + } + #endif + kfree(priv); +} + + +/* Perform WEP encryption on given skb that has at least 4 bytes of headroom + * for IV and 4 bytes of tailroom for ICV. Both IV and ICV will be transmitted, + * so the payload length increases with 8 bytes. + * + * WEP frame payload: IV + TX key idx, RC4(data), ICV = RC4(CRC32(data)) + */ +static int prism2_wep_encrypt(struct sk_buff *skb, int hdr_len, void *priv) +{ + struct prism2_wep_data *wep = priv; +#if(LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,21)) + struct blkcipher_desc desc = {.tfm = wep->tx_tfm}; +#endif + u32 klen, len; + u8 key[WEP_KEY_LEN + 3]; + u8 *pos; +#ifndef JOHN_HWSEC + u32 crc; + u8 *icv; + struct scatterlist sg; +#endif + if (skb_headroom(skb) < 4 || skb_tailroom(skb) < 4 || + skb->len < hdr_len) + return -1; + + len = skb->len - hdr_len; + pos = skb_push(skb, 4); + memmove(pos, pos + 4, hdr_len); + pos += hdr_len; + + klen = 3 + wep->key_len; + + wep->iv++; + + /* Fluhrer, Mantin, and Shamir have reported weaknesses in the key + * scheduling algorithm of RC4. At least IVs (KeyByte + 3, 0xff, N) + * can be used to speedup attacks, so avoid using them. */ + if ((wep->iv & 0xff00) == 0xff00) { + u8 B = (wep->iv >> 16) & 0xff; + if (B >= 3 && B < klen) + wep->iv += 0x0100; + } + + /* Prepend 24-bit IV to RC4 key and TX frame */ + *pos++ = key[0] = (wep->iv >> 16) & 0xff; + *pos++ = key[1] = (wep->iv >> 8) & 0xff; + *pos++ = key[2] = wep->iv & 0xff; + *pos++ = wep->key_idx << 6; + + /* Copy rest of the WEP key (the secret part) */ + memcpy(key + 3, wep->key, wep->key_len); + +#ifndef JOHN_HWSEC + /* Append little-endian CRC32 and encrypt it to produce ICV */ +#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)) + crc = ~crc32_le(~0, pos, len); +#else + crc = ~ether_crc_le(len, pos); +#endif + icv = skb_put(skb, 4); + icv[0] = crc; + icv[1] = crc >> 8; + icv[2] = crc >> 16; + icv[3] = crc >> 24; + + #if(LINUX_VERSION_CODE < KERNEL_VERSION(2,6,21)) + crypto_cipher_setkey(wep->tfm, key, klen); + sg.page = virt_to_page(pos); + sg.offset = offset_in_page(pos); + sg.length = len + 4; + crypto_cipher_encrypt(wep->tfm, &sg, &sg, len + 4); + + return 0; + #else + crypto_blkcipher_setkey(wep->tx_tfm, key, klen); + #if (LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 24)) + sg.page = virt_to_page(pos); + sg.offset = offset_in_page(pos); + sg.length = len + 4; + #else + sg_init_one(&sg, pos, len + 4); + #endif + return crypto_blkcipher_encrypt(&desc, &sg, &sg, len + 4); + #endif +#endif /* JOHN_HWSEC */ + return 0; +} + + +/* Perform WEP decryption on given buffer. Buffer includes whole WEP part of + * the frame: IV (4 bytes), encrypted payload (including SNAP header), + * ICV (4 bytes). len includes both IV and ICV. + * + * Returns 0 if frame was decrypted successfully and ICV was correct and -1 on + * failure. If frame is OK, IV and ICV will be removed. + */ +static int prism2_wep_decrypt(struct sk_buff *skb, int hdr_len, void *priv) +{ + struct prism2_wep_data *wep = priv; + #if(LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,21)) + struct blkcipher_desc desc = {.tfm = wep->rx_tfm}; + #endif + u32 klen, plen; + u8 key[WEP_KEY_LEN + 3]; + u8 keyidx, *pos; +#ifndef JOHN_HWSEC + u32 crc; + u8 icv[4]; + struct scatterlist sg; +#endif + if (skb->len < hdr_len + 8) + return -1; + + pos = skb->data + hdr_len; + key[0] = *pos++; + key[1] = *pos++; + key[2] = *pos++; + keyidx = *pos++ >> 6; + if (keyidx != wep->key_idx) + return -1; + + klen = 3 + wep->key_len; + + /* Copy rest of the WEP key (the secret part) */ + memcpy(key + 3, wep->key, wep->key_len); + + /* Apply RC4 to data and compute CRC32 over decrypted data */ + plen = skb->len - hdr_len - 8; +#ifndef JOHN_HWSEC +#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,21)) + crypto_cipher_setkey(wep->tfm, key, klen); + sg.page = virt_to_page(pos); + sg.offset = offset_in_page(pos); + sg.length = plen + 4; + crypto_cipher_decrypt(wep->tfm, &sg, &sg, plen + 4); +#else + crypto_blkcipher_setkey(wep->rx_tfm, key, klen); + #if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,24)) + sg.page = virt_to_page(pos); + sg.offset = offset_in_page(pos); + sg.length = plen + 4; + #else + sg_init_one(&sg, pos, plen + 4); + #endif + if (crypto_blkcipher_decrypt(&desc, &sg, &sg, plen + 4)) + return -7; +#endif + +#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)) + crc = ~crc32_le(~0, pos, plen); +#else + crc = ~ether_crc_le(plen, pos); +#endif + icv[0] = crc; + icv[1] = crc >> 8; + icv[2] = crc >> 16; + icv[3] = crc >> 24; + + if (memcmp(icv, pos + plen, 4) != 0) { + /* ICV mismatch - drop frame */ + return -2; + } +#endif /* JOHN_HWSEC */ + + /* Remove IV and ICV */ + memmove(skb->data + 4, skb->data, hdr_len); + skb_pull(skb, 4); + skb_trim(skb, skb->len - 4); + return 0; +} + + +static int prism2_wep_set_key(void *key, int len, u8 *seq, void *priv) +{ + struct prism2_wep_data *wep = priv; + + if (len < 0 || len > WEP_KEY_LEN) + return -1; + + memcpy(wep->key, key, len); + wep->key_len = len; + + return 0; +} + + +static int prism2_wep_get_key(void *key, int len, u8 *seq, void *priv) +{ + struct prism2_wep_data *wep = priv; + + if (len < wep->key_len) + return -1; + + memcpy(key, wep->key, wep->key_len); + + return wep->key_len; +} + + +static char * prism2_wep_print_stats(char *p, void *priv) +{ + struct prism2_wep_data *wep = priv; + p += sprintf(p, "key[%d] alg=WEP len=%d\n", + wep->key_idx, wep->key_len); + return p; +} + + +static struct ieee80211_crypto_ops ieee80211_crypt_wep = { + .name = "WEP", + .init = prism2_wep_init, + .deinit = prism2_wep_deinit, + .encrypt_mpdu = prism2_wep_encrypt, + .decrypt_mpdu = prism2_wep_decrypt, + .encrypt_msdu = NULL, + .decrypt_msdu = NULL, + .set_key = prism2_wep_set_key, + .get_key = prism2_wep_get_key, + .print_stats = prism2_wep_print_stats, + .extra_prefix_len = 4, /* IV */ + .extra_postfix_len = 4, /* ICV */ + .owner = THIS_MODULE, +}; + + +int __init ieee80211_crypto_wep_init(void) +{ + return ieee80211_register_crypto_ops(&ieee80211_crypt_wep); +} + + +void __exit ieee80211_crypto_wep_exit(void) +{ + ieee80211_unregister_crypto_ops(&ieee80211_crypt_wep); +} + + +void ieee80211_wep_null(void) +{ +// printk("============>%s()\n", __FUNCTION__); + return; +} +#if 0 +#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)) +EXPORT_SYMBOL(ieee80211_wep_null); +#else +EXPORT_SYMBOL_NOVERS(ieee80211_wep_null); +#endif + +module_init(ieee80211_crypto_wep_init); +module_exit(ieee80211_crypto_wep_exit); +#endif diff -Nur linux-2.6.30.5.orig/drivers/net/wireless/rtl8187b/ieee80211/ieee80211.h linux-2.6.30.5/drivers/net/wireless/rtl8187b/ieee80211/ieee80211.h --- linux-2.6.30.5.orig/drivers/net/wireless/rtl8187b/ieee80211/ieee80211.h 1970-01-01 01:00:00.000000000 +0100 +++ linux-2.6.30.5/drivers/net/wireless/rtl8187b/ieee80211/ieee80211.h 2009-08-23 19:01:04.000000000 +0200 @@ -0,0 +1,1913 @@ +/* + * Merged with mainline ieee80211.h in Aug 2004. Original ieee802_11 + * remains copyright by the original authors + * + * Portions of the merged code are based on Host AP (software wireless + * LAN access point) driver for Intersil Prism2/2.5/3. + * + * Copyright (c) 2001-2002, SSH Communications Security Corp and Jouni Malinen + * + * Copyright (c) 2002-2003, Jouni Malinen + * + * Adaption to a generic IEEE 802.11 stack by James Ketrenos + * + * Copyright (c) 2004, Intel Corporation + * + * Modified for Realtek's wi-fi cards by Andrea Merello + * + * + * 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. See README and COPYING for + * more details. + */ +#ifndef IEEE80211_H +#define IEEE80211_H +#include /* ETH_ALEN */ +#include /* ARRAY_SIZE */ +#include +#include +#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)) +#include +#else +#include +#include +#endif +#include +#include + +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,13)) +#include +#endif +/* +#ifndef bool +#define bool int +#endif + +#ifndef true +#define true 1 +#endif + +#ifndef false +#define false 0 +#endif +*/ +#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20)) +#ifndef bool +typedef enum{false = 0, true} bool; +#endif +#endif +//#ifdef JOHN_HWSEC +#define KEY_TYPE_NA 0x0 +#define KEY_TYPE_WEP40 0x1 +#define KEY_TYPE_TKIP 0x2 +#define KEY_TYPE_CCMP 0x4 +#define KEY_TYPE_WEP104 0x5 +//#endif + + +#define aSifsTime 10 + +#define MGMT_QUEUE_NUM 5 + + +#define IEEE_CMD_SET_WPA_PARAM 1 +#define IEEE_CMD_SET_WPA_IE 2 +#define IEEE_CMD_SET_ENCRYPTION 3 +#define IEEE_CMD_MLME 4 + +#define IEEE_PARAM_WPA_ENABLED 1 +#define IEEE_PARAM_TKIP_COUNTERMEASURES 2 +#define IEEE_PARAM_DROP_UNENCRYPTED 3 +#define IEEE_PARAM_PRIVACY_INVOKED 4 +#define IEEE_PARAM_AUTH_ALGS 5 +#define IEEE_PARAM_IEEE_802_1X 6 +//It should consistent with the driver_XXX.c +// David, 2006.9.26 +#define IEEE_PARAM_WPAX_SELECT 7 +//Added for notify the encryption type selection +// David, 2006.9.26 +#define IEEE_PROTO_WPA 1 +#define IEEE_PROTO_RSN 2 +//Added for notify the encryption type selection +// David, 2006.9.26 +#define IEEE_WPAX_USEGROUP 0 +#define IEEE_WPAX_WEP40 1 +#define IEEE_WPAX_TKIP 2 +#define IEEE_WPAX_WRAP 3 +#define IEEE_WPAX_CCMP 4 +#define IEEE_WPAX_WEP104 5 + +#define IEEE_KEY_MGMT_IEEE8021X 1 +#define IEEE_KEY_MGMT_PSK 2 + + + +#define IEEE_MLME_STA_DEAUTH 1 +#define IEEE_MLME_STA_DISASSOC 2 + + +#define IEEE_CRYPT_ERR_UNKNOWN_ALG 2 +#define IEEE_CRYPT_ERR_UNKNOWN_ADDR 3 +#define IEEE_CRYPT_ERR_CRYPT_INIT_FAILED 4 +#define IEEE_CRYPT_ERR_KEY_SET_FAILED 5 +#define IEEE_CRYPT_ERR_TX_KEY_SET_FAILED 6 +#define IEEE_CRYPT_ERR_CARD_CONF_FAILED 7 + + +#define IEEE_CRYPT_ALG_NAME_LEN 16 + +//#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,10)) +#define ieee80211_wx_get_scan ieee80211_wx_get_scan_rtl +#define ieee80211_wx_set_encode ieee80211_wx_set_encode_rtl +#define ieee80211_wx_get_encode ieee80211_wx_get_encode_rtl +//////////////////////////////// +// added for kernel conflict under FC5 +#define ieee80211_wx_get_name ieee80211_wx_get_name_rtl +#define free_ieee80211 free_ieee80211_rtl +#define alloc_ieee80211 alloc_ieee80211_rtl +/////////////////////////////// +//#endif +#define ieee80211_rx ieee80211_rx_rtl +#define ieee80211_wake_queue ieee80211_wake_queue_rtl +#define ieee80211_stop_queue ieee80211_stop_queue_rtl +#define ieee80211_wx_set_auth ieee80211_wx_set_auth_rtl +#define ieee80211_get_crypto_ops ieee80211_get_crypto_ops_rtl +#define ieee80211_crypt_delayed_deinit ieee80211_crypt_delayed_deinit_rtl + +#define ieee80211_start_scan ieee80211_start_scan_rtl +#define ieee80211_register_crypto_ops ieee80211_register_crypto_ops_rtl +#define ieee80211_unregister_crypto_ops ieee80211_unregister_crypto_ops_rtl +#define ieee80211_crypt_deinit_entries ieee80211_crypt_deinit_entries_rtl +#define ieee80211_crypt_deinit_handler ieee80211_crypt_deinit_handler_rtl +typedef struct ieee_param { + u32 cmd; + u8 sta_addr[ETH_ALEN]; + union { + struct { + u8 name; + u32 value; + } wpa_param; + struct { + u32 len; + u8 reserved[32]; + u8 data[0]; + } wpa_ie; + struct{ + int command; + int reason_code; + } mlme; + struct { + u8 alg[IEEE_CRYPT_ALG_NAME_LEN]; + u8 set_tx; + u32 err; + u8 idx; + u8 seq[8]; /* sequence counter (set: RX, get: TX) */ + u16 key_len; + u8 key[0]; + } crypt; + + } u; +}ieee_param; + + +#if WIRELESS_EXT < 17 +#define IW_QUAL_QUAL_INVALID 0x10 +#define IW_QUAL_LEVEL_INVALID 0x20 +#define IW_QUAL_NOISE_INVALID 0x40 +#define IW_QUAL_QUAL_UPDATED 0x1 +#define IW_QUAL_LEVEL_UPDATED 0x2 +#define IW_QUAL_NOISE_UPDATED 0x4 +#endif + +#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)) +static inline void tq_init(struct tq_struct * task, void(*func)(void *), void *data) +{ + task->routine = func; + task->data = data; + //task->next = NULL; + INIT_LIST_HEAD(&task->list); + task->sync = 0; +} +#endif + +// linux under 2.6.9 release may not support it, so modify it for common use +#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,9)) +//#define MSECS(t) (1000 * ((t) / HZ) + 1000 * ((t) % HZ) / HZ) +#define MSECS(t) (HZ * ((t) / 1000) + (HZ * ((t) % 1000)) / 1000) +static inline unsigned long msleep_interruptible_rtl(unsigned int msecs) +{ + unsigned long timeout = MSECS(msecs) + 1; + + while (timeout) { + set_current_state(TASK_UNINTERRUPTIBLE); + timeout = schedule_timeout(timeout); + } + return timeout; +} +#else +#define MSECS(t) msecs_to_jiffies(t) +#define msleep_interruptible_rtl msleep_interruptible +#endif + +#define IEEE80211_DATA_LEN 2304 +/* Maximum size for the MA-UNITDATA primitive, 802.11 standard section + 6.2.1.1.2. + + The figure in section 7.1.2 suggests a body size of up to 2312 + bytes is allowed, which is a bit confusing, I suspect this + represents the 2304 bytes of real data, plus a possible 8 bytes of + WEP IV and ICV. (this interpretation suggested by Ramiro Barreiro) */ + + +#define IEEE80211_HLEN 30 +#define IEEE80211_FRAME_LEN (IEEE80211_DATA_LEN + IEEE80211_HLEN) + +/* this is stolen and modified from the madwifi driver*/ +#define IEEE80211_FC0_TYPE_MASK 0x0c +#define IEEE80211_FC0_TYPE_DATA 0x08 +#define IEEE80211_FC0_SUBTYPE_MASK 0xB0 +#define IEEE80211_FC0_SUBTYPE_QOS 0x80 + +#define IEEE80211_QOS_HAS_SEQ(fc) \ + (((fc) & (IEEE80211_FC0_TYPE_MASK | IEEE80211_FC0_SUBTYPE_MASK)) == \ + (IEEE80211_FC0_TYPE_DATA | IEEE80211_FC0_SUBTYPE_QOS)) + +/* this is stolen from ipw2200 driver */ +#define IEEE_IBSS_MAC_HASH_SIZE 31 +#define IEEE_MESH_MAC_HASH_SIZE 31 +struct ieee_ibss_seq { + u8 mac[ETH_ALEN]; + u16 seq_num[17]; + u16 frag_num[17]; + unsigned long packet_time[17]; + struct list_head list; +}; + +struct ieee_mesh_seq { + u8 mac[ETH_ALEN]; + u16 seq_num; + u16 frag_num; + unsigned long packet_time; + struct list_head list; +}; + +struct ieee80211_hdr { + u16 frame_ctl; + u16 duration_id; + u8 addr1[ETH_ALEN]; + u8 addr2[ETH_ALEN]; + u8 addr3[ETH_ALEN]; + u16 seq_ctl; + u8 addr4[ETH_ALEN]; +} __attribute__ ((packed)); + +struct ieee80211_hdr_QOS { + u16 frame_ctl; + u16 duration_id; + u8 addr1[ETH_ALEN]; + u8 addr2[ETH_ALEN]; + u8 addr3[ETH_ALEN]; + u16 seq_ctl; + u8 addr4[ETH_ALEN]; + u16 QOS_ctl; +} __attribute__ ((packed)); + +struct ieee80211_hdr_3addr { + u16 frame_ctl; + u16 duration_id; + u8 addr1[ETH_ALEN]; + u8 addr2[ETH_ALEN]; + u8 addr3[ETH_ALEN]; + u16 seq_ctl; +} __attribute__ ((packed)); + +struct ieee80211_hdr_3addr_QOS { + u16 frame_ctl; + u16 duration_id; + u8 addr1[ETH_ALEN]; + u8 addr2[ETH_ALEN]; + u8 addr3[ETH_ALEN]; + u16 seq_ctl; + u16 QOS_ctl; +} __attribute__ ((packed)); + +enum eap_type { + EAP_PACKET = 0, + EAPOL_START, + EAPOL_LOGOFF, + EAPOL_KEY, + EAPOL_ENCAP_ASF_ALERT +}; + +//by lizhaoming for LED 2008.6.23 from r8187_led.h +#ifdef LED +typedef enum _LED_CTL_MODE { + LED_CTL_POWER_ON, + LED_CTL_POWER_OFF, + LED_CTL_LINK, + LED_CTL_NO_LINK, + LED_CTL_TX, + LED_CTL_RX, + LED_CTL_SITE_SURVEY, +} LED_CTL_MODE; +#endif + +static const char *eap_types[] = { + [EAP_PACKET] = "EAP-Packet", + [EAPOL_START] = "EAPOL-Start", + [EAPOL_LOGOFF] = "EAPOL-Logoff", + [EAPOL_KEY] = "EAPOL-Key", + [EAPOL_ENCAP_ASF_ALERT] = "EAPOL-Encap-ASF-Alert" +}; + +static inline const char *eap_get_type(int type) +{ + return (type >= ARRAY_SIZE(eap_types)) ? "Unknown" : eap_types[type]; +} + +struct eapol { + u8 snap[6]; + u16 ethertype; + u8 version; + u8 type; + u16 length; +} __attribute__ ((packed)); + +#define IEEE80211_3ADDR_LEN 24 +#define IEEE80211_4ADDR_LEN 30 +#define IEEE80211_FCS_LEN 4 + +#define MIN_FRAG_THRESHOLD 256U +#define MAX_FRAG_THRESHOLD 2346U + +/* Frame control field constants */ +#define IEEE80211_FCTL_VERS 0x0002 +#define IEEE80211_FCTL_FTYPE 0x000c +#define IEEE80211_FCTL_STYPE 0x00f0 +#define IEEE80211_FCTL_TODS 0x0100 +#define IEEE80211_FCTL_FROMDS 0x0200 +#define IEEE80211_FCTL_DSTODS 0x0300 //added by david +#define IEEE80211_FCTL_MOREFRAGS 0x0400 +#define IEEE80211_FCTL_RETRY 0x0800 +#define IEEE80211_FCTL_PM 0x1000 +#define IEEE80211_FCTL_MOREDATA 0x2000 +#define IEEE80211_FCTL_WEP 0x4000 +#define IEEE80211_FCTL_ORDER 0x8000 + +#define IEEE80211_FTYPE_MGMT 0x0000 +#define IEEE80211_FTYPE_CTL 0x0004 +#define IEEE80211_FTYPE_DATA 0x0008 + +/* management */ +#define IEEE80211_STYPE_ASSOC_REQ 0x0000 +#define IEEE80211_STYPE_ASSOC_RESP 0x0010 +#define IEEE80211_STYPE_REASSOC_REQ 0x0020 +#define IEEE80211_STYPE_REASSOC_RESP 0x0030 +#define IEEE80211_STYPE_PROBE_REQ 0x0040 +#define IEEE80211_STYPE_PROBE_RESP 0x0050 +#define IEEE80211_STYPE_BEACON 0x0080 +#define IEEE80211_STYPE_ATIM 0x0090 +#define IEEE80211_STYPE_DISASSOC 0x00A0 +#define IEEE80211_STYPE_AUTH 0x00B0 +#define IEEE80211_STYPE_DEAUTH 0x00C0 +#define IEEE80211_STYPE_MANAGE_ACT 0x00D0 + +/* control */ +#define IEEE80211_STYPE_PSPOLL 0x00A0 +#define IEEE80211_STYPE_RTS 0x00B0 +#define IEEE80211_STYPE_CTS 0x00C0 +#define IEEE80211_STYPE_ACK 0x00D0 +#define IEEE80211_STYPE_CFEND 0x00E0 +#define IEEE80211_STYPE_CFENDACK 0x00F0 + +/* data */ +#define IEEE80211_STYPE_DATA 0x0000 +#define IEEE80211_STYPE_DATA_CFACK 0x0010 +#define IEEE80211_STYPE_DATA_CFPOLL 0x0020 +#define IEEE80211_STYPE_DATA_CFACKPOLL 0x0030 +#define IEEE80211_STYPE_NULLFUNC 0x0040 +#define IEEE80211_STYPE_CFACK 0x0050 +#define IEEE80211_STYPE_CFPOLL 0x0060 +#define IEEE80211_STYPE_CFACKPOLL 0x0070 +#define IEEE80211_STYPE_QOS_DATA 0x0080 //added for WMM 2006/8/2 +#define IEEE80211_STYPE_QOS_NULL 0x00C0 + + +#define IEEE80211_SCTL_FRAG 0x000F +#define IEEE80211_SCTL_SEQ 0xFFF0 + + +/* debug macros */ + +#ifdef CONFIG_IEEE80211_DEBUG +extern u32 ieee80211_debug_level; +#define IEEE80211_DEBUG(level, fmt, args...) \ +do { if (ieee80211_debug_level & (level)) \ + printk(KERN_DEBUG "ieee80211: %c %s " fmt, \ + in_interrupt() ? 'I' : 'U', __FUNCTION__ , ## args); } while (0) +#else +#define IEEE80211_DEBUG(level, fmt, args...) do {} while (0) +#endif /* CONFIG_IEEE80211_DEBUG */ + +/* + * To use the debug system; + * + * If you are defining a new debug classification, simply add it to the #define + * list here in the form of: + * + * #define IEEE80211_DL_xxxx VALUE + * + * shifting value to the left one bit from the previous entry. xxxx should be + * the name of the classification (for example, WEP) + * + * You then need to either add a IEEE80211_xxxx_DEBUG() macro definition for your + * classification, or use IEEE80211_DEBUG(IEEE80211_DL_xxxx, ...) whenever you want + * to send output to that classification. + * + * To add your debug level to the list of levels seen when you perform + * + * % cat /proc/net/ipw/debug_level + * + * you simply need to add your entry to the ipw_debug_levels array. + * + * If you do not see debug_level in /proc/net/ipw then you do not have + * CONFIG_IEEE80211_DEBUG defined in your kernel configuration + * + */ + +#define IEEE80211_DL_INFO (1<<0) +#define IEEE80211_DL_WX (1<<1) +#define IEEE80211_DL_SCAN (1<<2) +#define IEEE80211_DL_STATE (1<<3) +#define IEEE80211_DL_MGMT (1<<4) +#define IEEE80211_DL_FRAG (1<<5) +#define IEEE80211_DL_EAP (1<<6) +#define IEEE80211_DL_DROP (1<<7) + +#define IEEE80211_DL_TX (1<<8) +#define IEEE80211_DL_RX (1<<9) + +#define IEEE80211_ERROR(f, a...) printk(KERN_ERR "ieee80211: " f, ## a) +#define IEEE80211_WARNING(f, a...) printk(KERN_WARNING "ieee80211: " f, ## a) +#define IEEE80211_DEBUG_INFO(f, a...) IEEE80211_DEBUG(IEEE80211_DL_INFO, f, ## a) + +#define IEEE80211_DEBUG_WX(f, a...) IEEE80211_DEBUG(IEEE80211_DL_WX, f, ## a) +#define IEEE80211_DEBUG_SCAN(f, a...) IEEE80211_DEBUG(IEEE80211_DL_SCAN, f, ## a) +#define IEEE80211_DEBUG_STATE(f, a...) IEEE80211_DEBUG(IEEE80211_DL_STATE, f, ## a) +#define IEEE80211_DEBUG_MGMT(f, a...) IEEE80211_DEBUG(IEEE80211_DL_MGMT, f, ## a) +#define IEEE80211_DEBUG_FRAG(f, a...) IEEE80211_DEBUG(IEEE80211_DL_FRAG, f, ## a) +#define IEEE80211_DEBUG_EAP(f, a...) IEEE80211_DEBUG(IEEE80211_DL_EAP, f, ## a) +#define IEEE80211_DEBUG_DROP(f, a...) IEEE80211_DEBUG(IEEE80211_DL_DROP, f, ## a) +#define IEEE80211_DEBUG_TX(f, a...) IEEE80211_DEBUG(IEEE80211_DL_TX, f, ## a) +#define IEEE80211_DEBUG_RX(f, a...) IEEE80211_DEBUG(IEEE80211_DL_RX, f, ## a) +#include +#include +#include /* ARPHRD_ETHER */ + +#ifndef WIRELESS_SPY +#define WIRELESS_SPY // enable iwspy support +#endif +#include // new driver API + +#ifndef ETH_P_PAE +#define ETH_P_PAE 0x888E /* Port Access Entity (IEEE 802.1X) */ +#endif /* ETH_P_PAE */ + +#define ETH_P_PREAUTH 0x88C7 /* IEEE 802.11i pre-authentication */ + +#ifndef ETH_P_80211_RAW +#define ETH_P_80211_RAW (ETH_P_ECONET + 1) +#endif + +/* IEEE 802.11 defines */ + +#define P80211_OUI_LEN 3 + +struct ieee80211_snap_hdr { + + u8 dsap; /* always 0xAA */ + u8 ssap; /* always 0xAA */ + u8 ctrl; /* always 0x03 */ + u8 oui[P80211_OUI_LEN]; /* organizational universal id */ + +} __attribute__ ((packed)); + +#define SNAP_SIZE sizeof(struct ieee80211_snap_hdr) + +#define WLAN_FC_GET_TYPE(fc) ((fc) & IEEE80211_FCTL_FTYPE) +#define WLAN_FC_GET_STYPE(fc) ((fc) & IEEE80211_FCTL_STYPE) + +#define WLAN_GET_SEQ_FRAG(seq) ((seq) & IEEE80211_SCTL_FRAG) +#define WLAN_GET_SEQ_SEQ(seq) ((seq) & IEEE80211_SCTL_SEQ) + +/* Authentication algorithms */ +#define WLAN_AUTH_OPEN 0 +#define WLAN_AUTH_SHARED_KEY 1 + +#define WLAN_AUTH_CHALLENGE_LEN 128 + +#define WLAN_CAPABILITY_BSS (1<<0) +#define WLAN_CAPABILITY_IBSS (1<<1) +#define WLAN_CAPABILITY_CF_POLLABLE (1<<2) +#define WLAN_CAPABILITY_CF_POLL_REQUEST (1<<3) +#define WLAN_CAPABILITY_PRIVACY (1<<4) +#define WLAN_CAPABILITY_SHORT_PREAMBLE (1<<5) +#define WLAN_CAPABILITY_PBCC (1<<6) +#define WLAN_CAPABILITY_CHANNEL_AGILITY (1<<7) +#define WLAN_CAPABILITY_SHORT_SLOT (1<<10) + +/* Status codes */ +#define WLAN_STATUS_SUCCESS 0 +#define WLAN_STATUS_UNSPECIFIED_FAILURE 1 +#define WLAN_STATUS_CAPS_UNSUPPORTED 10 +#define WLAN_STATUS_REASSOC_NO_ASSOC 11 +#define WLAN_STATUS_ASSOC_DENIED_UNSPEC 12 +#define WLAN_STATUS_NOT_SUPPORTED_AUTH_ALG 13 +#define WLAN_STATUS_UNKNOWN_AUTH_TRANSACTION 14 +#define WLAN_STATUS_CHALLENGE_FAIL 15 +#define WLAN_STATUS_AUTH_TIMEOUT 16 +#define WLAN_STATUS_AP_UNABLE_TO_HANDLE_NEW_STA 17 +#define WLAN_STATUS_ASSOC_DENIED_RATES 18 +/* 802.11b */ +#define WLAN_STATUS_ASSOC_DENIED_NOSHORT 19 +#define WLAN_STATUS_ASSOC_DENIED_NOPBCC 20 +#define WLAN_STATUS_ASSOC_DENIED_NOAGILITY 21 + +/* Reason codes */ +#define WLAN_REASON_UNSPECIFIED 1 +#define WLAN_REASON_PREV_AUTH_NOT_VALID 2 +#define WLAN_REASON_DEAUTH_LEAVING 3 +#define WLAN_REASON_DISASSOC_DUE_TO_INACTIVITY 4 +#define WLAN_REASON_DISASSOC_AP_BUSY 5 +#define WLAN_REASON_CLASS2_FRAME_FROM_NONAUTH_STA 6 +#define WLAN_REASON_CLASS3_FRAME_FROM_NONASSOC_STA 7 +#define WLAN_REASON_DISASSOC_STA_HAS_LEFT 8 +#define WLAN_REASON_STA_REQ_ASSOC_WITHOUT_AUTH 9 + + +/* Information Element IDs */ +#define WLAN_EID_SSID 0 +#define WLAN_EID_SUPP_RATES 1 +#define WLAN_EID_FH_PARAMS 2 +#define WLAN_EID_DS_PARAMS 3 +#define WLAN_EID_CF_PARAMS 4 +#define WLAN_EID_TIM 5 +#define WLAN_EID_IBSS_PARAMS 6 +#define WLAN_EID_CHALLENGE 16 +#define WLAN_EID_RSN 48 +#define WLAN_EID_GENERIC 221 + +#define IEEE80211_MGMT_HDR_LEN 24 +#define IEEE80211_DATA_HDR3_LEN 24 +#define IEEE80211_DATA_HDR4_LEN 30 + + +#define IEEE80211_STATMASK_SIGNAL (1<<0) +#define IEEE80211_STATMASK_RSSI (1<<1) +#define IEEE80211_STATMASK_NOISE (1<<2) +#define IEEE80211_STATMASK_RATE (1<<3) +#define IEEE80211_STATMASK_WEMASK 0x7 + + +#define IEEE80211_CCK_MODULATION (1<<0) +#define IEEE80211_OFDM_MODULATION (1<<1) + +#define IEEE80211_24GHZ_BAND (1<<0) +#define IEEE80211_52GHZ_BAND (1<<1) + +#define IEEE80211_CCK_RATE_LEN 4 +#define IEEE80211_CCK_RATE_1MB 0x02 +#define IEEE80211_CCK_RATE_2MB 0x04 +#define IEEE80211_CCK_RATE_5MB 0x0B +#define IEEE80211_CCK_RATE_11MB 0x16 +#define IEEE80211_OFDM_RATE_LEN 8 +#define IEEE80211_OFDM_RATE_6MB 0x0C +#define IEEE80211_OFDM_RATE_9MB 0x12 +#define IEEE80211_OFDM_RATE_12MB 0x18 +#define IEEE80211_OFDM_RATE_18MB 0x24 +#define IEEE80211_OFDM_RATE_24MB 0x30 +#define IEEE80211_OFDM_RATE_36MB 0x48 +#define IEEE80211_OFDM_RATE_48MB 0x60 +#define IEEE80211_OFDM_RATE_54MB 0x6C +#define IEEE80211_BASIC_RATE_MASK 0x80 + +#define IEEE80211_CCK_RATE_1MB_MASK (1<<0) +#define IEEE80211_CCK_RATE_2MB_MASK (1<<1) +#define IEEE80211_CCK_RATE_5MB_MASK (1<<2) +#define IEEE80211_CCK_RATE_11MB_MASK (1<<3) +#define IEEE80211_OFDM_RATE_6MB_MASK (1<<4) +#define IEEE80211_OFDM_RATE_9MB_MASK (1<<5) +#define IEEE80211_OFDM_RATE_12MB_MASK (1<<6) +#define IEEE80211_OFDM_RATE_18MB_MASK (1<<7) +#define IEEE80211_OFDM_RATE_24MB_MASK (1<<8) +#define IEEE80211_OFDM_RATE_36MB_MASK (1<<9) +#define IEEE80211_OFDM_RATE_48MB_MASK (1<<10) +#define IEEE80211_OFDM_RATE_54MB_MASK (1<<11) + +#define IEEE80211_CCK_RATES_MASK 0x0000000F +#define IEEE80211_CCK_BASIC_RATES_MASK (IEEE80211_CCK_RATE_1MB_MASK | \ + IEEE80211_CCK_RATE_2MB_MASK) +#define IEEE80211_CCK_DEFAULT_RATES_MASK (IEEE80211_CCK_BASIC_RATES_MASK | \ + IEEE80211_CCK_RATE_5MB_MASK | \ + IEEE80211_CCK_RATE_11MB_MASK) + +#define IEEE80211_OFDM_RATES_MASK 0x00000FF0 +#define IEEE80211_OFDM_BASIC_RATES_MASK (IEEE80211_OFDM_RATE_6MB_MASK | \ + IEEE80211_OFDM_RATE_12MB_MASK | \ + IEEE80211_OFDM_RATE_24MB_MASK) +#define IEEE80211_OFDM_DEFAULT_RATES_MASK (IEEE80211_OFDM_BASIC_RATES_MASK | \ + IEEE80211_OFDM_RATE_9MB_MASK | \ + IEEE80211_OFDM_RATE_18MB_MASK | \ + IEEE80211_OFDM_RATE_36MB_MASK | \ + IEEE80211_OFDM_RATE_48MB_MASK | \ + IEEE80211_OFDM_RATE_54MB_MASK) +#define IEEE80211_DEFAULT_RATES_MASK (IEEE80211_OFDM_DEFAULT_RATES_MASK | \ + IEEE80211_CCK_DEFAULT_RATES_MASK) + +#define IEEE80211_NUM_OFDM_RATES 8 +#define IEEE80211_NUM_CCK_RATES 4 +#define IEEE80211_OFDM_SHIFT_MASK_A 4 + + + + +/* NOTE: This data is for statistical purposes; not all hardware provides this + * information for frames received. Not setting these will not cause + * any adverse affects. */ +struct ieee80211_rx_stats { + u32 mac_time[2]; + u8 signalstrength; + s8 rssi; + u8 signal; + u8 noise; + u16 rate; /* in 100 kbps */ + u8 received_channel; + u8 control; + u8 mask; + u8 freq; + u16 len; + u8 nic_type; +}; + +/* IEEE 802.11 requires that STA supports concurrent reception of at least + * three fragmented frames. This define can be increased to support more + * concurrent frames, but it should be noted that each entry can consume about + * 2 kB of RAM and increasing cache size will slow down frame reassembly. */ +#define IEEE80211_FRAG_CACHE_LEN 4 + +struct ieee80211_frag_entry { + unsigned long first_frag_time; + unsigned int seq; + unsigned int last_frag; + struct sk_buff *skb; + u8 src_addr[ETH_ALEN]; + u8 dst_addr[ETH_ALEN]; +}; + +struct ieee80211_stats { + unsigned int tx_unicast_frames; + unsigned int tx_multicast_frames; + unsigned int tx_fragments; + unsigned int tx_unicast_octets; + unsigned int tx_multicast_octets; + unsigned int tx_deferred_transmissions; + unsigned int tx_single_retry_frames; + unsigned int tx_multiple_retry_frames; + unsigned int tx_retry_limit_exceeded; + unsigned int tx_discards; + unsigned int rx_unicast_frames; + unsigned int rx_multicast_frames; + unsigned int rx_fragments; + unsigned int rx_unicast_octets; + unsigned int rx_multicast_octets; + unsigned int rx_fcs_errors; + unsigned int rx_discards_no_buffer; + unsigned int tx_discards_wrong_sa; + unsigned int rx_discards_undecryptable; + unsigned int rx_message_in_msg_fragments; + unsigned int rx_message_in_bad_msg_fragments; +}; + +struct ieee80211_softmac_stats{ + unsigned int rx_ass_ok; + unsigned int rx_ass_err; + unsigned int rx_probe_rq; + unsigned int tx_probe_rs; + unsigned int tx_beacons; + unsigned int rx_auth_rq; + unsigned int rx_auth_rs_ok; + unsigned int rx_auth_rs_err; + unsigned int tx_auth_rq; + unsigned int no_auth_rs; + unsigned int no_ass_rs; + unsigned int tx_ass_rq; + unsigned int rx_ass_rq; + unsigned int tx_probe_rq; + unsigned int reassoc; + unsigned int swtxstop; + unsigned int swtxawake; +}; + +struct ieee80211_device; + +#include "ieee80211_crypt.h" + +#define SEC_KEY_1 (1<<0) +#define SEC_KEY_2 (1<<1) +#define SEC_KEY_3 (1<<2) +#define SEC_KEY_4 (1<<3) +#define SEC_ACTIVE_KEY (1<<4) +#define SEC_AUTH_MODE (1<<5) +#define SEC_UNICAST_GROUP (1<<6) +#define SEC_LEVEL (1<<7) +#define SEC_ENABLED (1<<8) + +#define SEC_LEVEL_0 0 /* None */ +#define SEC_LEVEL_1 1 /* WEP 40 and 104 bit */ +#define SEC_LEVEL_2 2 /* Level 1 + TKIP */ +#define SEC_LEVEL_2_CKIP 3 /* Level 1 + CKIP */ +#define SEC_LEVEL_3 4 /* Level 2 + CCMP */ + +#define WEP_KEYS 4 +#define WEP_KEY_LEN 13 +#define ALG_KEY_LEN 32 + +#ifdef _RTL8187_EXT_PATCH_ +#define MAX_MP 16 +#endif +struct ieee80211_security { + u16 active_key:2, + enabled:1, + auth_mode:2, + auth_algo:4, + unicast_uses_group:1; + u8 key_sizes[WEP_KEYS]; + u8 keys[WEP_KEYS][ALG_KEY_LEN]; + u8 level; + u16 flags; +} __attribute__ ((packed)); + + +/* + + 802.11 data frame from AP + + ,-------------------------------------------------------------------. +Bytes | 2 | 2 | 6 | 6 | 6 | 2 | 0..2312 | 4 | + |------|------|---------|---------|---------|------|---------|------| +Desc. | ctrl | dura | DA/RA | TA | SA | Sequ | frame | fcs | + | | tion | (BSSID) | | | ence | data | | + `-------------------------------------------------------------------' + +Total: 28-2340 bytes + +*/ + +struct ieee80211_header_data { + u16 frame_ctl; + u16 duration_id; + u8 addr1[6]; + u8 addr2[6]; + u8 addr3[6]; + u16 seq_ctrl; +}; + +#define BEACON_PROBE_SSID_ID_POSITION 12 + +/* Management Frame Information Element Types */ +#define MFIE_TYPE_SSID 0 +#define MFIE_TYPE_RATES 1 +#define MFIE_TYPE_FH_SET 2 +#define MFIE_TYPE_DS_SET 3 +#define MFIE_TYPE_CF_SET 4 +#define MFIE_TYPE_TIM 5 +#define MFIE_TYPE_IBSS_SET 6 +#define MFIE_TYPE_COUNTRY 7 +#define MFIE_TYPE_CHALLENGE 16 +#define MFIE_TYPE_ERP 42 +#define MFIE_TYPE_RSN 48 +#define MFIE_TYPE_RATES_EX 50 +#define MFIE_TYPE_GENERIC 221 + +#ifdef ENABLE_DOT11D +typedef enum +{ + COUNTRY_CODE_FCC = 0, + COUNTRY_CODE_IC = 1, + COUNTRY_CODE_ETSI = 2, + COUNTRY_CODE_SPAIN = 3, + COUNTRY_CODE_FRANCE = 4, + COUNTRY_CODE_MKK = 5, + COUNTRY_CODE_MKK1 = 6, + COUNTRY_CODE_ISRAEL = 7, + COUNTRY_CODE_TELEC = 8, + COUNTRY_CODE_GLOBAL_DOMAIN = 9, + COUNTRY_CODE_WORLD_WIDE_13_INDEX = 10 +}country_code_type_t; +#endif + + +struct ieee80211_info_element_hdr { + u8 id; + u8 len; +} __attribute__ ((packed)); + +struct ieee80211_info_element { + u8 id; + u8 len; + u8 data[0]; +} __attribute__ ((packed)); + +/* + * These are the data types that can make up management packets + * + u16 auth_algorithm; + u16 auth_sequence; + u16 beacon_interval; + u16 capability; + u8 current_ap[ETH_ALEN]; + u16 listen_interval; + struct { + u16 association_id:14, reserved:2; + } __attribute__ ((packed)); + u32 time_stamp[2]; + u16 reason; + u16 status; +*/ + +#define IEEE80211_DEFAULT_TX_ESSID "Penguin" +#define IEEE80211_DEFAULT_BASIC_RATE 10 +#define IEEE80211_DEFAULT_MESHID "802.11s" +#define IEEE80211_DEFAULT_MESH_CHAN 1 + +struct ieee80211_authentication { + struct ieee80211_header_data header; + u16 algorithm; + u16 transaction; + u16 status; + //struct ieee80211_info_element_hdr info_element; +} __attribute__ ((packed)); + + +struct ieee80211_probe_response { + struct ieee80211_header_data header; + u32 time_stamp[2]; + u16 beacon_interval; + u16 capability; + struct ieee80211_info_element info_element; +} __attribute__ ((packed)); + +struct ieee80211_probe_request { + struct ieee80211_header_data header; + /*struct ieee80211_info_element info_element;*/ +} __attribute__ ((packed)); + +struct ieee80211_assoc_request_frame { + struct ieee80211_hdr_3addr header; + u16 capability; + u16 listen_interval; + //u8 current_ap[ETH_ALEN]; + struct ieee80211_info_element_hdr info_element; +} __attribute__ ((packed)); + +struct ieee80211_assoc_response_frame { + struct ieee80211_hdr_3addr header; + u16 capability; + u16 status; + u16 aid; + struct ieee80211_info_element info_element; /* supported rates */ +} __attribute__ ((packed)); + + +struct ieee80211_txb { + u8 nr_frags; + u8 encrypted; + u16 reserved; + u16 frag_size; + u16 payload_size; + struct sk_buff *fragments[0]; +}; + +struct ieee80211_wmm_ac_param { + u8 ac_aci_acm_aifsn; + u8 ac_ecwmin_ecwmax; + u16 ac_txop_limit; +}; + +struct ieee80211_wmm_ts_info { + u8 ac_dir_tid; + u8 ac_up_psb; + u8 reserved; +} __attribute__ ((packed)); + +struct ieee80211_wmm_tspec_elem { + struct ieee80211_wmm_ts_info ts_info; + u16 norm_msdu_size; + u16 max_msdu_size; + u32 min_serv_inter; + u32 max_serv_inter; + u32 inact_inter; + u32 suspen_inter; + u32 serv_start_time; + u32 min_data_rate; + u32 mean_data_rate; + u32 peak_data_rate; + u32 max_burst_size; + u32 delay_bound; + u32 min_phy_rate; + u16 surp_band_allow; + u16 medium_time; +}__attribute__((packed)); + +enum {WMM_all_frame, WMM_two_frame, WMM_four_frame, WMM_six_frame}; +#define MAX_SP_Len (WMM_all_frame << 4) +#define IEEE80211_QOS_TID 0x0f +#define QOS_CTL_NOTCONTAIN_ACK (0x01 << 5) + +/* SWEEP TABLE ENTRIES NUMBER*/ +#define MAX_SWEEP_TAB_ENTRIES 42 +#define MAX_SWEEP_TAB_ENTRIES_PER_PACKET 7 +/* MAX_RATES_LENGTH needs to be 12. The spec says 8, and many APs + * only use 8, and then use extended rates for the remaining supported + * rates. Other APs, however, stick all of their supported rates on the + * main rates information element... */ +#define MAX_RATES_LENGTH ((u8)12) +#define MAX_RATES_EX_LENGTH ((u8)16) +#define MAX_NETWORK_COUNT 128 +#ifdef ENABLE_DOT11D +#define MAX_CHANNEL_NUMBER 165 //YJ,modified,080625 +#define MAX_IE_LEN 0xFF //+YJ,080625 +#else +#define MAX_CHANNEL_NUMBER 161 +#endif + +//#define IEEE80211_SOFTMAC_SCAN_TIME 400 +#define IEEE80211_SOFTMAC_SCAN_TIME 100//lzm mod 081209 +//(HZ / 2) +#define IEEE80211_SOFTMAC_ASSOC_RETRY_TIME (HZ * 2) + +#define CRC_LENGTH 4U + +#define MAX_WPA_IE_LEN 64 + +#define NETWORK_EMPTY_ESSID (1<<0) +#define NETWORK_HAS_OFDM (1<<1) +#define NETWORK_HAS_CCK (1<<2) + +#define IEEE80211_DTIM_MBCAST 4 +#define IEEE80211_DTIM_UCAST 2 +#define IEEE80211_DTIM_VALID 1 +#define IEEE80211_DTIM_INVALID 0 + +#define IEEE80211_PS_DISABLED 0 +#define IEEE80211_PS_UNICAST IEEE80211_DTIM_UCAST +#define IEEE80211_PS_MBCAST IEEE80211_DTIM_MBCAST + +//added by David for QoS 2006/6/30 +//#define WMM_Hang_8187 +#ifdef WMM_Hang_8187 +#undef WMM_Hang_8187 +#endif + +#define WME_AC_BE 0x00 +#define WME_AC_BK 0x01 +#define WME_AC_VI 0x02 +#define WME_AC_VO 0x03 +#define WME_ACI_MASK 0x03 +#define WME_AIFSN_MASK 0x03 +#define WME_AC_PRAM_LEN 16 + +//UP Mapping to AC, using in MgntQuery_SequenceNumber() and maybe for DSCP +//#define UP2AC(up) ((up<3) ? ((up==0)?1:0) : (up>>1)) +#define UP2AC(up) ( \ + ((up) < 1) ? WME_AC_BE : \ + ((up) < 3) ? WME_AC_BK : \ + ((up) < 4) ? WME_AC_BE : \ + ((up) < 6) ? WME_AC_VI : \ + WME_AC_VO) +//AC Mapping to UP, using in Tx part for selecting the corresponding TX queue +#define AC2UP(_ac) ( \ + ((_ac) == WME_AC_VO) ? 6 : \ + ((_ac) == WME_AC_VI) ? 5 : \ + ((_ac) == WME_AC_BK) ? 1 : \ + 0) + +#define ETHER_ADDR_LEN 6 /* length of an Ethernet address */ +struct ether_header { + u8 ether_dhost[ETHER_ADDR_LEN]; + u8 ether_shost[ETHER_ADDR_LEN]; + u16 ether_type; +} __attribute__((packed)); + +#ifndef ETHERTYPE_PAE +#define ETHERTYPE_PAE 0x888e /* EAPOL PAE/802.1x */ +#endif +#ifndef ETHERTYPE_IP +#define ETHERTYPE_IP 0x0800 /* IP protocol */ +#endif + +struct ieee80211_network { + /* These entries are used to identify a unique network */ + u8 bssid[ETH_ALEN]; + u8 channel; + /* Ensure null-terminated for any debug msgs */ + u8 ssid[IW_ESSID_MAX_SIZE + 1]; + u8 ssid_len; + + /* These are network statistics */ + struct ieee80211_rx_stats stats; + u16 capability; + u8 rates[MAX_RATES_LENGTH]; + u8 rates_len; + u8 rates_ex[MAX_RATES_EX_LENGTH]; + u8 rates_ex_len; + unsigned long last_scanned; + u8 mode; + u8 flags; + u32 last_associate; + u32 time_stamp[2]; + u16 beacon_interval; + u16 listen_interval; + u16 atim_window; + u8 wpa_ie[MAX_WPA_IE_LEN]; + size_t wpa_ie_len; + u8 rsn_ie[MAX_WPA_IE_LEN]; + size_t rsn_ie_len; + u8 dtim_period; + u8 dtim_data; + u32 last_dtim_sta_time[2]; +#ifdef _RTL8187_EXT_PATCH_ + void *ext_entry; +#endif + struct list_head list; + //appeded for QoS + u8 wmm_info; + struct ieee80211_wmm_ac_param wmm_param[4]; + u8 QoS_Enable; + u8 SignalStrength; +#ifdef THOMAS_TURBO + u8 Turbo_Enable;//enable turbo mode, added by thomas +#endif + +#ifdef ENABLE_DOT11D + u16 CountryIeLen; + u8 CountryIeBuf[MAX_IE_LEN]; +#endif + +}; + +enum ieee80211_state { + + /* the card is not linked at all */ + IEEE80211_NOLINK = 0, + + /* IEEE80211_ASSOCIATING* are for BSS client mode + * the driver shall not perform RX filtering unless + * the state is LINKED. + * The driver shall just check for the state LINKED and + * defaults to NOLINK for ALL the other states (including + * LINKED_SCANNING) + */ + + /* the association procedure will start (wq scheduling)*/ + IEEE80211_ASSOCIATING, + IEEE80211_ASSOCIATING_RETRY, + + /* the association procedure is sending AUTH request*/ + IEEE80211_ASSOCIATING_AUTHENTICATING, + + /* the association procedure has successfully authentcated + * and is sending association request + */ + IEEE80211_ASSOCIATING_AUTHENTICATED, + + /* the link is ok. the card associated to a BSS or linked + * to a ibss cell or acting as an AP and creating the bss + */ + IEEE80211_LINKED, + + /* same as LINKED, but the driver shall apply RX filter + * rules as we are in NO_LINK mode. As the card is still + * logically linked, but it is doing a syncro site survey + * then it will be back to LINKED state. + */ + IEEE80211_LINKED_SCANNING, +//by amy for mesh + IEEE80211_MESH_SCANNING, + IEEE80211_MESH_LINKED, +//by amy for mesh + +}; + +#define DEFAULT_MAX_SCAN_AGE (15 * HZ) +#define DEFAULT_FTS 2346 +#define MAC_FMT "%02x:%02x:%02x:%02x:%02x:%02x" +#define MAC_ARG(x) ((u8*)(x))[0],((u8*)(x))[1],((u8*)(x))[2],((u8*)(x))[3],((u8*)(x))[4],((u8*)(x))[5] + + +#if (LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,11)) +extern inline int is_multicast_ether_addr(const u8 *addr) +{ + return ((addr[0] != 0xff) && (0x01 & addr[0])); +} +#endif + +#if (LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,13)) +extern inline int is_broadcast_ether_addr(const u8 *addr) +{ + return ((addr[0] == 0xff) && (addr[1] == 0xff) && (addr[2] == 0xff) && \ + (addr[3] == 0xff) && (addr[4] == 0xff) && (addr[5] == 0xff)); +} +#endif + +#define CFG_IEEE80211_RESERVE_FCS (1<<0) +#define CFG_IEEE80211_COMPUTE_FCS (1<<1) + +typedef struct tx_pending_t{ + int frag; + struct ieee80211_txb *txb; +}tx_pending_t; + +#ifdef _RTL8187_EXT_PATCH_ +struct ieee80211_crypt_data_list{ + u8 used; + u8 mac_addr[ETH_ALEN]; //record mac_add + struct ieee80211_crypt_data *crypt[WEP_KEYS]; +}__attribute__((packed)); + +#endif + +struct ieee80211_device { + struct net_device *dev; + + /* Bookkeeping structures */ + struct net_device_stats stats; + struct ieee80211_stats ieee_stats; + struct ieee80211_softmac_stats softmac_stats; + + /* Probe / Beacon management */ + struct list_head network_free_list; + struct list_head network_list; + struct ieee80211_network *networks; + int scans; + int scan_age; + + int iw_mode; /* operating mode (IW_MODE_*) */ +#ifdef _RTL8187_EXT_PATCH_ + int iw_ext_mode; // if iw_mode == iw_ext_mode, do ext_patch_**(); +#endif + + spinlock_t lock; + spinlock_t wpax_suitlist_lock; + + int tx_headroom; /* Set to size of any additional room needed at front + * of allocated Tx SKBs */ + u32 config; + + /* WEP and other encryption related settings at the device level */ + int open_wep; /* Set to 1 to allow unencrypted frames */ + + int reset_on_keychange; /* Set to 1 if the HW needs to be reset on + * WEP key changes */ + + /* If the host performs {en,de}cryption, then set to 1 */ + int host_encrypt; + int host_decrypt; + int ieee802_1x; /* is IEEE 802.1X used */ + + /* WPA data */ + int wpa_enabled; + int drop_unencrypted; + int tkip_countermeasures; + int privacy_invoked; + size_t wpa_ie_len; + u8 *wpa_ie; + +//#ifdef JOHN_TKIP + u8 ap_mac_addr[6]; + u16 pairwise_key_type; + u16 broadcast_key_type; +//#endif + struct list_head crypt_deinit_list; +#ifdef _RTL8187_EXT_PATCH_ + struct ieee80211_crypt_data_list* cryptlist[MAX_MP]; +#else + struct ieee80211_crypt_data *crypt[WEP_KEYS]; +#endif + int tx_keyidx; /* default TX key index (crypt[tx_keyidx]) */ + struct timer_list crypt_deinit_timer; + + int bcrx_sta_key; /* use individual keys to override default keys even + * with RX of broad/multicast frames */ + + /* Fragmentation structures */ + // each streaming contain a entry + struct ieee80211_frag_entry frag_cache[17][IEEE80211_FRAG_CACHE_LEN]; + unsigned int frag_next_idx[17]; + u16 fts; /* Fragmentation Threshold */ + + /* This stores infos for the current network. + * Either the network we are associated in INFRASTRUCTURE + * or the network that we are creating in MASTER mode. + * ad-hoc is a mixture ;-). + * Note that in infrastructure mode, even when not associated, + * fields bssid and essid may be valid (if wpa_set and essid_set + * are true) as thy carry the value set by the user via iwconfig + */ + struct ieee80211_network current_network; + + + enum ieee80211_state state; + + int short_slot; + int mode; /* A, B, G */ + int modulation; /* CCK, OFDM */ + int freq_band; /* 2.4Ghz, 5.2Ghz, Mixed */ + int abg_true; /* ABG flag */ + + /* used for forcing the ibss workqueue to terminate + * without wait for the syncro scan to terminate + */ + short sync_scan_hurryup; + +#ifdef ENABLE_DOT11D + void * pDot11dInfo; + bool bGlobalDomain; + bool bWorldWide13;//lzm add 20081205 + + // For Liteon Ch12~13 passive scan + u8 MinPassiveChnlNum; + u8 IbssStartChnl; +#else + /* map of allowed channels. 0 is dummy */ + // FIXME: remeber to default to a basic channel plan depending of the PHY type + int channel_map[MAX_CHANNEL_NUMBER+1]; +#endif + + int rate; /* current rate */ + int basic_rate; + //FIXME: pleace callback, see if redundant with softmac_features + short active_scan; + +#ifdef _RTL8187_EXT_PATCH_ +// short ch_lock; + short meshScanMode; +#endif + /* this contains flags for selectively enable softmac support */ + u16 softmac_features; + + /* if the sequence control field is not filled by HW */ + u16 seq_ctrl[5]; + + /* association procedure transaction sequence number */ + u16 associate_seq; + + /* AID for RTXed association responses */ + u16 assoc_id; + + /* power save mode related*/ + short ps; + short sta_sleep; + int ps_timeout; + struct tasklet_struct ps_task; + u32 ps_th; + u32 ps_tl; + + short raw_tx; + /* used if IEEE_SOFTMAC_TX_QUEUE is set */ + short queue_stop; + short scanning; + short scan_watchdog;//lzm add 081215 for roaming + short proto_started; + + struct semaphore wx_sem; + struct semaphore scan_sem; + struct semaphore ips_sem; + spinlock_t mgmt_tx_lock; + spinlock_t beacon_lock; + spinlock_t beaconflag_lock; + short beacon_txing; + + short wap_set; + short ssid_set; + + u8 wpax_type_set; //{added by David, 2006.9.28} + u32 wpax_type_notify; //{added by David, 2006.9.26} + + /* QoS related flag */ + char init_wmmparam_flag; + + /* for discarding duplicated packets in IBSS */ + struct list_head ibss_mac_hash[IEEE_IBSS_MAC_HASH_SIZE]; + + /* for discarding duplicated packets in Mesh */ //added by david 2008.2.28/ + struct list_head mesh_mac_hash[IEEE_MESH_MAC_HASH_SIZE]; + + /* for discarding duplicated packets in BSS */ + u16 last_rxseq_num[17]; /* rx seq previous per-tid */ + u16 last_rxfrag_num[17];/* tx frag previous per-tid */ + unsigned long last_packet_time[17]; + + /* for PS mode */ + unsigned long last_rx_ps_time; + + /* used if IEEE_SOFTMAC_SINGLE_QUEUE is set */ + struct sk_buff *mgmt_queue_ring[MGMT_QUEUE_NUM]; + int mgmt_queue_head; + int mgmt_queue_tail; +//by amy for ps + bool bInactivePs; + bool actscanning; + u16 ListenInterval; + u32 NumRxData; + unsigned long NumRxDataInPeriod; //YJ,add,080828 + unsigned long NumRxBcnInPeriod; //YJ,add,080828 +//by amy for ps + short meshid_set; + /* used if IEEE_SOFTMAC_TX_QUEUE is set */ + struct tx_pending_t tx_pending; + + /* used if IEEE_SOFTMAC_ASSOCIATE is set */ + struct timer_list associate_timer; + + /* used if IEEE_SOFTMAC_BEACONS is set */ + struct timer_list beacon_timer; +#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0) + struct work_struct associate_complete_wq; +// struct work_struct associate_retry_wq; +// struct work_struct start_ibss_wq; + struct work_struct associate_procedure_wq; + struct work_struct ips_leave_wq; //YJ,add,081230,for IPS + bool bHwRadioOff;//by lizhaoming +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20) + struct delayed_work softmac_scan_wq; + struct delayed_work start_ibss_wq; + struct delayed_work associate_retry_wq; +//by amy for rate adaptive + struct delayed_work rate_adapter_wq; +//by amy for rate adaptive + struct delayed_work watch_dog_wq; + struct delayed_work hw_dig_wq; + struct delayed_work tx_pw_wq; + +//Added for RF power on power off by lizhaoming 080512 +#ifdef POLLING_METHOD_FOR_RADIO + struct delayed_work GPIOChangeRFWorkItem; +#endif + +#ifdef SW_ANTE_DIVERSITY + struct delayed_work SwAntennaWorkItem; +#endif + +#else + struct work_struct softmac_scan_wq; + struct work_struct start_ibss_wq; + struct work_struct associate_retry_wq; +//by amy for rate adaptive + struct work_struct rate_adapter_wq; +//by amy for rate adaptive + struct work_struct watch_dog_wq; + struct work_struct hw_dig_wq; + struct work_struct tx_pw_wq; + +//Added for RF power on power off by lizhaoming 080512 +#ifdef POLLING_METHOD_FOR_RADIO + struct work_struct GPIOChangeRFWorkItem; +#endif + +#ifdef SW_ANTE_DIVERSITY + struct work_struct SwAntennaWorkItem; +#endif + +#endif + +//struct work_struct softmac_scan_wq; + struct work_struct wx_sync_scan_wq; + struct work_struct wmm_param_update_wq; +#ifdef _RTL8187_EXT_PATCH_ + struct work_struct ext_stop_scan_wq; + struct work_struct ext_send_beacon_wq; +#endif + struct workqueue_struct *wq; +#else + /* used for periodly scan */ + struct timer_list scan_timer; + + struct tq_struct associate_complete_wq; + struct tq_struct associate_retry_wq; + struct tq_struct start_ibss_wq; + struct tq_struct associate_procedure_wq; + struct tq_struct ips_leave_wq; //YJ,add,081230,for IPS + struct tq_struct softmac_scan_wq; + struct tq_struct wx_sync_scan_wq; + struct tq_struct wmm_param_update_wq; +#ifdef _RTL8187_EXT_PATCH_ + struct tq_struct ext_stop_scan_wq; + struct tq_struct ext_send_beacon_wq; +#endif +#endif + + /* Callback functions */ + void (*set_security)(struct net_device *dev, + struct ieee80211_security *sec); + + /* Used to TX data frame by using txb structs. + * this is not used if in the softmac_features + * is set the flag IEEE_SOFTMAC_TX_QUEUE + */ + int (*hard_start_xmit)(struct ieee80211_txb *txb, + struct net_device *dev); + + int (*reset_port)(struct net_device *dev); + + /* Softmac-generated frames (mamagement) are TXed via this + * callback if the flag IEEE_SOFTMAC_SINGLE_QUEUE is + * not set. As some cards may have different HW queues that + * one might want to use for data and management frames + * the option to have two callbacks might be useful. + * This fucntion can't sleep. + */ + int (*softmac_hard_start_xmit)(struct sk_buff *skb, + struct net_device *dev); + + /* used instead of hard_start_xmit (not softmac_hard_start_xmit) + * if the IEEE_SOFTMAC_TX_QUEUE feature is used to TX data + * frames. I the option IEEE_SOFTMAC_SINGLE_QUEUE is also set + * then also management frames are sent via this callback. + * This function can't sleep. + */ + void (*softmac_data_hard_start_xmit)(struct sk_buff *skb, + struct net_device *dev,int rate); + + /* stops the HW queue for DATA frames. Useful to avoid + * waste time to TX data frame when we are reassociating + * This function can sleep. + */ + void (*data_hard_stop)(struct net_device *dev); + + /* OK this is complementar to data_poll_hard_stop */ + void (*data_hard_resume)(struct net_device *dev); + + /* ask to the driver to retune the radio . + * This function can sleep. the driver should ensure + * the radio has been swithced before return. + */ + void (*set_chan)(struct net_device *dev,short ch); + + /* These are not used if the ieee stack takes care of + * scanning (IEEE_SOFTMAC_SCAN feature set). + * In this case only the set_chan is used. + * + * The syncro version is similar to the start_scan but + * does not return until all channels has been scanned. + * this is called in user context and should sleep, + * it is called in a work_queue when swithcing to ad-hoc mode + * or in behalf of iwlist scan when the card is associated + * and root user ask for a scan. + * the fucntion stop_scan should stop both the syncro and + * background scanning and can sleep. + * The fucntion start_scan should initiate the background + * scanning and can't sleep. + */ + void (*scan_syncro)(struct net_device *dev); + void (*start_scan)(struct net_device *dev); + void (*stop_scan)(struct net_device *dev); + + /* indicate the driver that the link state is changed + * for example it may indicate the card is associated now. + * Driver might be interested in this to apply RX filter + * rules or simply light the LINK led + */ + void (*link_change)(struct net_device *dev); + + /* these two function indicates to the HW when to start + * and stop to send beacons. This is used when the + * IEEE_SOFTMAC_BEACONS is not set. For now the + * stop_send_bacons is NOT guaranteed to be called only + * after start_send_beacons. + */ + void (*start_send_beacons) (struct net_device *dev); + void (*stop_send_beacons) (struct net_device *dev); + + /* power save mode related */ + void (*sta_wake_up) (struct net_device *dev); + void (*ps_request_tx_ack) (struct net_device *dev); + void (*enter_sleep_state) (struct net_device *dev, u32 th, u32 tl); + short (*ps_is_queue_empty) (struct net_device *dev); + +//by lizhaoming for LED 2008.6.23 +#ifdef LED + void (*ieee80211_led_contorl) (struct net_device *dev, LED_CTL_MODE LedAction); +#endif +#ifdef CONFIG_IPS + void (*ieee80211_ips_leave) (struct net_device *dev); +#endif + /* QoS related */ + //void (*wmm_param_update) (struct net_device *dev, u8 *ac_param); + //void (*wmm_param_update) (struct ieee80211_device *ieee); + + +#ifdef _RTL8187_EXT_PATCH_ + + /// ieee80211_softmac.c + int (*ext_patch_ieee80211_start_protocol) (struct ieee80211_device *ieee); // start special mode + + short (*ext_patch_ieee80211_probe_req_1) (struct ieee80211_device *ieee); // return = 0: no more phases, >0: another phase + u8* (*ext_patch_ieee80211_probe_req_2) (struct ieee80211_device *ieee, struct sk_buff *skb, u8 *tag); // return tag + + void (*ext_patch_ieee80211_stop_protocol) (struct ieee80211_device *ieee); // stop timer + + void (*ext_patch_ieee80211_association_req_1) (struct ieee80211_assoc_request_frame *hdr); + u8* (*ext_patch_ieee80211_association_req_2) (struct ieee80211_device *ieee, struct ieee80211_network *pstat, struct sk_buff *skb); + + int (*ext_patch_ieee80211_rx_frame_softmac_on_assoc_req) (struct ieee80211_device *ieee, struct sk_buff *skb); + int (*ext_patch_ieee80211_rx_frame_softmac_on_assoc_rsp) (struct ieee80211_device *ieee, struct sk_buff *skb); + + void (*ext_patch_ieee80211_assoc_resp_by_net_1) (struct ieee80211_assoc_response_frame *assoc); + u8* (*ext_patch_ieee80211_assoc_resp_by_net_2) (struct ieee80211_device *ieee, struct ieee80211_network *pstat, int pkt_type, struct sk_buff *skb); + + int (*ext_patch_ieee80211_ext_stop_scan_wq_set_channel) (struct ieee80211_device *ieee); + + int (*ext_patch_ieee80211_softmac_xmit_get_rate) (struct ieee80211_device *ieee, struct sk_buff *skb); + + int (*ext_patch_ieee80211_rx_frame_softmac_on_auth)(struct ieee80211_device *ieee, struct sk_buff *skb, struct ieee80211_rx_stats *rx_stats); + int (*ext_patch_ieee80211_rx_frame_softmac_on_deauth)(struct ieee80211_device *ieee, struct sk_buff *skb, struct ieee80211_rx_stats *rx_stats); +//by amy for mesh + void (*ext_patch_ieee80211_start_mesh)(struct ieee80211_device *ieee); +//by amy for mesh + // ieee80211_rx.c + // rz + void (*ext_patch_ieee80211_rx_mgt_on_probe_req) ( struct ieee80211_device *ieee, struct ieee80211_probe_request *beacon, struct ieee80211_rx_stats *stats); + unsigned int(*ext_patch_ieee80211_process_probe_response_1)(struct ieee80211_device *ieee, struct ieee80211_probe_response *beacon, struct ieee80211_rx_stats *stats); + + void (*ext_patch_ieee80211_rx_mgt_update_expire) ( struct ieee80211_device *ieee, struct sk_buff *skb); + struct sk_buff* (*ext_patch_get_beacon_get_probersp)(struct ieee80211_device *ieee, u8 *dest, struct ieee80211_network *net); + + // success(return 0) is responsible to free skb + int (*ext_patch_ieee80211_rx_on_rx) (struct ieee80211_device *ieee, struct sk_buff *skb, struct ieee80211_rx_stats *rx_stats, u16 type, u16 stype); + + int (*ext_patch_ieee80211_rx_frame_get_hdrlen) (struct ieee80211_device *ieee, struct sk_buff *skb); + + // Check whether or not accept the incoming frame. return 0: not accept, >0: accept + int (*ext_patch_ieee80211_rx_is_valid_framectl) (struct ieee80211_device *ieee, u16 fc, u16 type, u16 stype); + + // return > 0 is success. 0 when failed + // success(return >0) is responsible to free skb + int (*ext_patch_ieee80211_rx_process_dataframe) (struct ieee80211_device *ieee, struct sk_buff *skb, struct ieee80211_rx_stats *rx_stats); + + /* added by david for setting acl dynamically */ + u8 (*ext_patch_ieee80211_acl_query) (struct ieee80211_device *ieee, u8 *sa); + + // int (*ext_patch_is_duplicate_packet) (struct ieee80211_device *ieee, struct ieee80211_hdr *header, u16 type, u16 stype); + + // ieee80211_tx.c + + // locked by ieee->lock. Call ieee80211_softmac_xmit afterward + struct ieee80211_txb* (*ext_patch_ieee80211_xmit) (struct sk_buff *skb, struct net_device *dev); + + +#endif // _RTL8187_EXT_PATCH_ + + /* This must be the last item so that it points to the data + * allocated beyond this structure by alloc_ieee80211 */ + u8 priv[0]; +}; + +#define IEEE_A (1<<0) +#define IEEE_B (1<<1) +#define IEEE_G (1<<2) +#define IEEE_MODE_MASK (IEEE_A|IEEE_B|IEEE_G) + +/* Generate a 802.11 header */ + +/* Uses the channel change callback directly + * instead of [start/stop] scan callbacks + */ +#define IEEE_SOFTMAC_SCAN (1<<2) + +/* Perform authentication and association handshake */ +#define IEEE_SOFTMAC_ASSOCIATE (1<<3) + +/* Generate probe requests */ +#define IEEE_SOFTMAC_PROBERQ (1<<4) + +/* Generate respones to probe requests */ +#define IEEE_SOFTMAC_PROBERS (1<<5) + +/* The ieee802.11 stack will manages the netif queue + * wake/stop for the driver, taking care of 802.11 + * fragmentation. See softmac.c for details. */ +#define IEEE_SOFTMAC_TX_QUEUE (1<<7) + +/* Uses only the softmac_data_hard_start_xmit + * even for TX management frames. + */ +#define IEEE_SOFTMAC_SINGLE_QUEUE (1<<8) + +/* Generate beacons. The stack will enqueue beacons + * to the card + */ +#define IEEE_SOFTMAC_BEACONS (1<<6) +#ifdef _RTL8187_EXT_PATCH_ +extern inline int ieee80211_find_MP(struct ieee80211_device* ieee, const u8* addr, u8 set) +{ + int i=0; + for (i=1; icryptlist[i]->used == 0)&&set) + {//entry is empty + memcpy(ieee->cryptlist[i]->mac_addr, addr, ETH_ALEN); + ieee->cryptlist[i]->used = 1; + return i; + } + else if (0 == memcmp(ieee->cryptlist[i]->mac_addr, addr, ETH_ALEN)) //find matched entry + { + return i; + } + } + return -1; +} +#endif + + + +static inline void *ieee80211_priv(struct net_device *dev) +{ +#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0) + return ((struct ieee80211_device *)netdev_priv(dev))->priv; +#else + return ((struct ieee80211_device *)dev->priv)->priv; +#endif +} + +extern inline int ieee80211_is_empty_essid(const char *essid, int essid_len) +{ + /* Single white space is for Linksys APs */ + if (essid_len == 1 && essid[0] == ' ') + return 1; + + /* Otherwise, if the entire essid is 0, we assume it is hidden */ + while (essid_len) { + essid_len--; + if (essid[essid_len] != '\0') + return 0; + } + + return 1; +} + +extern inline int ieee80211_is_valid_mode(struct ieee80211_device *ieee, int mode) +{ + /* + * It is possible for both access points and our device to support + * combinations of modes, so as long as there is one valid combination + * of ap/device supported modes, then return success + * + */ + if ((mode & IEEE_A) && + (ieee->modulation & IEEE80211_OFDM_MODULATION) && + (ieee->freq_band & IEEE80211_52GHZ_BAND)) + return 1; + + if ((mode & IEEE_G) && + (ieee->modulation & IEEE80211_OFDM_MODULATION) && + (ieee->freq_band & IEEE80211_24GHZ_BAND)) + return 1; + + if ((mode & IEEE_B) && + (ieee->modulation & IEEE80211_CCK_MODULATION) && + (ieee->freq_band & IEEE80211_24GHZ_BAND)) + return 1; + + return 0; +} + +extern inline int ieee80211_get_hdrlen(u16 fc) +{ + int hdrlen = 24; + + switch (WLAN_FC_GET_TYPE(fc)) { + case IEEE80211_FTYPE_DATA: + if ((fc & IEEE80211_FCTL_FROMDS) && (fc & IEEE80211_FCTL_TODS)) + hdrlen = 30; /* Addr4 */ + if(IEEE80211_QOS_HAS_SEQ(fc)) + hdrlen += 2; /* QOS ctrl*/ + break; + case IEEE80211_FTYPE_CTL: + switch (WLAN_FC_GET_STYPE(fc)) { + case IEEE80211_STYPE_CTS: + case IEEE80211_STYPE_ACK: + hdrlen = 10; + break; + default: + hdrlen = 16; + break; + } + break; + } + + return hdrlen; +} + + + +/* ieee80211.c */ +extern void free_ieee80211(struct net_device *dev); +extern struct net_device *alloc_ieee80211(int sizeof_priv); + +extern int ieee80211_set_encryption(struct ieee80211_device *ieee); + +/* ieee80211_tx.c */ + +extern int ieee80211_encrypt_fragment( + struct ieee80211_device *ieee, + struct sk_buff *frag, + int hdr_len); + +extern int ieee80211_xmit(struct sk_buff *skb, + struct net_device *dev); +extern void ieee80211_txb_free(struct ieee80211_txb *); + + +/* ieee80211_rx.c */ +extern int ieee80211_rx(struct ieee80211_device *ieee, struct sk_buff *skb, + struct ieee80211_rx_stats *rx_stats); +extern void ieee80211_rx_mgt(struct ieee80211_device *ieee, + struct ieee80211_hdr *header, + struct ieee80211_rx_stats *stats); + +/* ieee80211_wx.c */ +extern int ieee80211_wx_get_scan(struct ieee80211_device *ieee, + struct iw_request_info *info, + union iwreq_data *wrqu, char *key); +extern int ieee80211_wx_set_encode(struct ieee80211_device *ieee, + struct iw_request_info *info, + union iwreq_data *wrqu, char *key); +extern int ieee80211_wx_get_encode(struct ieee80211_device *ieee, + struct iw_request_info *info, + union iwreq_data *wrqu, char *key); +extern int ieee80211_wx_set_encode_ext(struct ieee80211_device *ieee, + struct iw_request_info *info, + union iwreq_data* wrqu, char *extra); +int ieee80211_wx_set_auth(struct ieee80211_device *ieee, + struct iw_request_info *info, + struct iw_param *data, char *extra); +int ieee80211_wx_set_mlme(struct ieee80211_device *ieee, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra); + +int ieee80211_wx_set_gen_ie(struct ieee80211_device *ieee, u8 *ie, size_t len); +/* ieee80211_softmac.c */ +extern short ieee80211_is_54g(struct ieee80211_network net); +extern short ieee80211_is_shortslot(struct ieee80211_network net); +extern int ieee80211_rx_frame_softmac(struct ieee80211_device *ieee, struct sk_buff *skb, + struct ieee80211_rx_stats *rx_stats, u16 type, + u16 stype); +extern void ieee80211_softmac_new_net(struct ieee80211_device *ieee, struct ieee80211_network *net); + +extern void ieee80211_softmac_xmit(struct ieee80211_txb *txb, struct ieee80211_device *ieee); +extern void ieee80211_softmac_check_all_nets(struct ieee80211_device *ieee); +extern void ieee80211_start_bss(struct ieee80211_device *ieee); +extern void ieee80211_start_master_bss(struct ieee80211_device *ieee); +extern void ieee80211_start_ibss(struct ieee80211_device *ieee); +extern void ieee80211_softmac_init(struct ieee80211_device *ieee); +extern void ieee80211_softmac_free(struct ieee80211_device *ieee); +extern void ieee80211_associate_abort(struct ieee80211_device *ieee); +extern void ieee80211_disassociate(struct ieee80211_device *ieee); +extern void ieee80211_stop_scan(struct ieee80211_device *ieee); +extern void ieee80211_start_scan_syncro(struct ieee80211_device *ieee); +extern void ieee80211_check_all_nets(struct ieee80211_device *ieee); +extern void ieee80211_start_protocol(struct ieee80211_device *ieee); +extern void ieee80211_stop_protocol(struct ieee80211_device *ieee); +extern void ieee80211_softmac_start_protocol(struct ieee80211_device *ieee); +extern void ieee80211_softmac_stop_protocol(struct ieee80211_device *ieee); +extern void ieee80211_reset_queue(struct ieee80211_device *ieee); +extern void ieee80211_wake_queue(struct ieee80211_device *ieee); +extern void ieee80211_stop_queue(struct ieee80211_device *ieee); +extern struct sk_buff *ieee80211_get_beacon(struct ieee80211_device *ieee); +extern void ieee80211_start_send_beacons(struct ieee80211_device *ieee); +extern void ieee80211_stop_send_beacons(struct ieee80211_device *ieee); +extern int ieee80211_wpa_supplicant_ioctl(struct ieee80211_device *ieee, struct iw_point *p); +extern void notify_wx_assoc_event(struct ieee80211_device *ieee); +extern void ieee80211_ps_tx_ack(struct ieee80211_device *ieee, short success); +extern void ieee80211_start_scan(struct ieee80211_device *ieee); + +#ifdef _RTL8187_EXT_PATCH_ +extern void ieee80211_rx_auth_rq(struct ieee80211_device *ieee, struct sk_buff *skb); +extern void ieee80211_ext_issue_assoc_req(struct ieee80211_device *ieee, struct ieee80211_network *pstat); +extern void ieee80211_associate_step1(struct ieee80211_device *ieee); +extern void ieee80211_ext_issue_disassoc(struct ieee80211_device *ieee, struct ieee80211_network *pstat, int reason, unsigned char extReason); +extern void ieee80211_ext_issue_assoc_rsp(struct ieee80211_device *ieee, u8 *dest, unsigned short status, struct ieee80211_network *pstat, int pkt_type); +extern void softmac_mgmt_xmit(struct sk_buff *skb, struct ieee80211_device *ieee); +extern struct sk_buff* ieee80211_ext_probe_resp_by_net(struct ieee80211_device *ieee, u8 *dest, struct ieee80211_network *net); +extern int ieee80211_network_init(struct ieee80211_device *ieee, struct ieee80211_probe_response *beacon, struct ieee80211_network *network, struct ieee80211_rx_stats *stats); +extern struct ieee80211_txb *ieee80211_alloc_txb(int nr_frags, int txb_size, int gfp_mask); +extern void ieee80211_ext_send_11s_beacon(struct ieee80211_device *ieee); +extern struct ieee80211_txb *ieee80211_ext_alloc_txb(struct sk_buff *skb, struct net_device *dev, struct ieee80211_hdr_3addr *header, int hdr_len, u8 isQoS, u16 *pQOS_ctl, int isEncrypt, struct ieee80211_crypt_data* crypt); +extern struct ieee80211_txb *ieee80211_ext_reuse_txb(struct sk_buff *skb, struct net_device *dev, struct ieee80211_hdr_3addr *header, int hdr_len, u8 isQoS, u16 *pQOS_ctl, int isEncrypt, struct ieee80211_crypt_data* crypt); +extern int ieee_ext_skb_p80211_to_ether(struct sk_buff *skb, int hdrlen, u8 *dst, u8 *src); +#endif + +/* ieee80211_crypt_ccmp&tkip&wep.c */ +extern void ieee80211_tkip_null(void); +extern void ieee80211_wep_null(void); +extern void ieee80211_ccmp_null(void); +/* ieee80211_softmac_wx.c */ + +extern int ieee80211_wx_get_wap(struct ieee80211_device *ieee, + struct iw_request_info *info, + union iwreq_data *wrqu, char *ext); + +extern int ieee80211_wx_set_wap(struct ieee80211_device *ieee, + struct iw_request_info *info, + union iwreq_data *awrq, + char *extra); + +extern int ieee80211_wx_get_essid(struct ieee80211_device *ieee, struct iw_request_info *a,union iwreq_data *wrqu,char *b); + +extern int ieee80211_wx_set_rate(struct ieee80211_device *ieee, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra); + +extern int ieee80211_wx_get_rate(struct ieee80211_device *ieee, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra); + +extern int ieee80211_wx_set_mode(struct ieee80211_device *ieee, struct iw_request_info *a, + union iwreq_data *wrqu, char *b); + +extern int ieee80211_wx_set_scan(struct ieee80211_device *ieee, struct iw_request_info *a, + union iwreq_data *wrqu, char *b); + +extern int ieee80211_wx_set_essid(struct ieee80211_device *ieee, + struct iw_request_info *a, + union iwreq_data *wrqu, char *extra); + +extern int ieee80211_wx_get_mode(struct ieee80211_device *ieee, struct iw_request_info *a, + union iwreq_data *wrqu, char *b); + +extern int ieee80211_wx_set_freq(struct ieee80211_device *ieee, struct iw_request_info *a, + union iwreq_data *wrqu, char *b); + +extern int ieee80211_wx_get_freq(struct ieee80211_device *ieee, struct iw_request_info *a, + union iwreq_data *wrqu, char *b); + +//extern void ieee80211_wx_sync_scan_wq(struct ieee80211_device *ieee); +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)) +extern void ieee80211_wx_sync_scan_wq(struct work_struct *work); +#else + extern void ieee80211_wx_sync_scan_wq(struct ieee80211_device *ieee); +#endif +extern int ieee80211_wx_set_rawtx(struct ieee80211_device *ieee, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra); + +extern int ieee80211_wx_get_name(struct ieee80211_device *ieee, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra); + +extern int ieee80211_wx_set_power(struct ieee80211_device *ieee, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra); + +extern int ieee80211_wx_get_power(struct ieee80211_device *ieee, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra); + +extern const long ieee80211_wlan_frequencies[]; + +extern inline void ieee80211_increment_scans(struct ieee80211_device *ieee) +{ + ieee->scans++; +} + +extern inline int ieee80211_get_scans(struct ieee80211_device *ieee) +{ + return ieee->scans; +} + +static inline const char *escape_essid(const char *essid, u8 essid_len) { + static char escaped[IW_ESSID_MAX_SIZE * 2 + 1]; + const char *s = essid; + char *d = escaped; + + if (ieee80211_is_empty_essid(essid, essid_len)) { + memcpy(escaped, "", sizeof("")); + return escaped; + } + + essid_len = min(essid_len, (u8)IW_ESSID_MAX_SIZE); + while (essid_len--) { + if (*s == '\0') { + *d++ = '\\'; + *d++ = '0'; + s++; + } else { + *d++ = *s++; + } + } + *d = '\0'; + return escaped; +} +#endif /* IEEE80211_H */ diff -Nur linux-2.6.30.5.orig/drivers/net/wireless/rtl8187b/ieee80211/ieee80211_module.c linux-2.6.30.5/drivers/net/wireless/rtl8187b/ieee80211/ieee80211_module.c --- linux-2.6.30.5.orig/drivers/net/wireless/rtl8187b/ieee80211/ieee80211_module.c 1970-01-01 01:00:00.000000000 +0100 +++ linux-2.6.30.5/drivers/net/wireless/rtl8187b/ieee80211/ieee80211_module.c 2009-08-23 19:01:04.000000000 +0200 @@ -0,0 +1,385 @@ +/******************************************************************************* + + Copyright(c) 2004 Intel Corporation. All rights reserved. + + Portions of this file are based on the WEP enablement code provided by the + Host AP project hostap-drivers v0.1.3 + Copyright (c) 2001-2002, SSH Communications Security Corp and Jouni Malinen + + Copyright (c) 2002-2003, Jouni Malinen + + This program is free software; you can redistribute it and/or modify it + under the terms of version 2 of the GNU General Public License as + published by the Free Software Foundation. + + 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. + + The full GNU General Public License is included in this distribution in the + file called LICENSE. + + Contact Information: + James P. Ketrenos + Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 + +*******************************************************************************/ + +#include +//#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "ieee80211.h" + +MODULE_DESCRIPTION("802.11 data/management/control stack"); +MODULE_AUTHOR("Copyright (C) 2004 Intel Corporation "); +MODULE_LICENSE("GPL"); + +#define DRV_NAME "ieee80211" + +static inline int ieee80211_networks_allocate(struct ieee80211_device *ieee) +{ + if (ieee->networks) + return 0; + + ieee->networks = kmalloc( + MAX_NETWORK_COUNT * sizeof(struct ieee80211_network), + GFP_KERNEL); + if (!ieee->networks) { + printk(KERN_WARNING "%s: Out of memory allocating beacons\n", + ieee->dev->name); + return -ENOMEM; + } + + memset(ieee->networks, 0, + MAX_NETWORK_COUNT * sizeof(struct ieee80211_network)); + + return 0; +} + +static inline void ieee80211_networks_free(struct ieee80211_device *ieee) +{ + if (!ieee->networks) + return; + kfree(ieee->networks); + ieee->networks = NULL; +} + +static inline void ieee80211_networks_initialize(struct ieee80211_device *ieee) +{ + int i; + + INIT_LIST_HEAD(&ieee->network_free_list); + INIT_LIST_HEAD(&ieee->network_list); + for (i = 0; i < MAX_NETWORK_COUNT; i++) + list_add_tail(&ieee->networks[i].list, &ieee->network_free_list); +} + + +struct net_device *alloc_ieee80211(int sizeof_priv) +{ + struct ieee80211_device *ieee; + struct net_device *dev; + int i,err; + + IEEE80211_DEBUG_INFO("Initializing...\n"); + + dev = alloc_etherdev(sizeof(struct ieee80211_device) + sizeof_priv); + if (!dev) { + IEEE80211_ERROR("Unable to network device.\n"); + goto failed; + } + +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)) + ieee = netdev_priv(dev); +#else + ieee = (struct ieee80211_device *)dev->priv; +#endif + + ieee->dev = dev; + + err = ieee80211_networks_allocate(ieee); + if (err) { + IEEE80211_ERROR("Unable to allocate beacon storage: %d\n", + err); + goto failed; + } + ieee80211_networks_initialize(ieee); + + /* Default fragmentation threshold is maximum payload size */ + ieee->fts = DEFAULT_FTS; + ieee->scan_age = DEFAULT_MAX_SCAN_AGE; + ieee->open_wep = 1; + + /* Default to enabling full open WEP with host based encrypt/decrypt */ + ieee->host_encrypt = 1; + ieee->host_decrypt = 1; + ieee->ieee802_1x = 1; /* Default to supporting 802.1x */ + + INIT_LIST_HEAD(&ieee->crypt_deinit_list); + init_timer(&ieee->crypt_deinit_timer); + ieee->crypt_deinit_timer.data = (unsigned long)ieee; + ieee->crypt_deinit_timer.function = ieee80211_crypt_deinit_handler; + + spin_lock_init(&ieee->lock); + spin_lock_init(&ieee->wpax_suitlist_lock); + + ieee->wpax_type_set = 0; + ieee->wpa_enabled = 0; + ieee->tkip_countermeasures = 0; + ieee->drop_unencrypted = 0; + ieee->privacy_invoked = 0; + ieee->ieee802_1x = 1; + ieee->raw_tx = 0; +#ifdef _RTL8187_EXT_PATCH_ + for (i=0; icryptlist[i] = (struct ieee80211_crypt_data_list*) kmalloc(sizeof(struct ieee80211_crypt_data_list), GFP_KERNEL); + if (NULL == ieee->cryptlist[i]) + { + printk("error kmalloc cryptlist\n"); + goto failed; + } + memset(ieee->cryptlist[i], 0, sizeof(struct ieee80211_crypt_data_list)); + + } +#endif + ieee80211_softmac_init(ieee); + + for (i = 0; i < IEEE_IBSS_MAC_HASH_SIZE; i++) + INIT_LIST_HEAD(&ieee->ibss_mac_hash[i]); + + for (i = 0; i < IEEE_MESH_MAC_HASH_SIZE; i++) + INIT_LIST_HEAD(&ieee->mesh_mac_hash[i]); + + for (i = 0; i < 17; i++) { + ieee->last_rxseq_num[i] = -1; + ieee->last_rxfrag_num[i] = -1; + ieee->last_packet_time[i] = 0; + } +#if 1 //added these to autoload encryption module. WB + ieee80211_tkip_null(); + ieee80211_wep_null(); + ieee80211_ccmp_null(); +#endif + return dev; + + failed: +#ifdef _RTL8187_EXT_PATCH_ + for (i=0; icryptlist[i]==NULL){ + continue; + } + kfree(ieee->cryptlist[i]); + ieee->cryptlist[i] = NULL; + + } +#endif + if (dev) +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)) + free_netdev(dev); +#else + kfree(dev); +#endif + return NULL; +} + + +void free_ieee80211(struct net_device *dev) +{ +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)) + struct ieee80211_device *ieee = netdev_priv(dev); +#else + struct ieee80211_device *ieee = (struct ieee80211_device *)dev->priv; +#endif + int i;//,j; + struct list_head *p, *q; + + + ieee80211_softmac_free(ieee); + del_timer_sync(&ieee->crypt_deinit_timer); + ieee80211_crypt_deinit_entries(ieee, 1); +#if 1 + ieee80211_tkip_null(); + ieee80211_wep_null(); + ieee80211_ccmp_null(); +#endif + for (i = 0; i < WEP_KEYS; i++) { +#ifdef _RTL8187_EXT_PATCH_ +{ + // int j; + for (j=0;jcryptlist[j] == NULL) + continue; + struct ieee80211_crypt_data *crypt = ieee->cryptlist[j]->crypt[i]; +#else + struct ieee80211_crypt_data *crypt = ieee->crypt[i]; +#endif + if (crypt) { + if (crypt->ops) { + crypt->ops->deinit(crypt->priv); +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0) + module_put(crypt->ops->owner); +#else + __MOD_DEC_USE_COUNT(crypt->ops->owner); +#endif + } + kfree(crypt); +#ifdef _RTL8187_EXT_PATCH_ + ieee->cryptlist[j]->crypt[i] = NULL; + //kfree(ieee->cryptlist[j]); + //ieee->cryptlist[j] = NULL; +#else + ieee->crypt[i] = NULL; +#endif + } +#ifdef _RTL8187_EXT_PATCH_ + } + } +#endif +} +#ifdef _RTL8187_EXT_PATCH_ +for(j=0;jcryptlist[j]) + { + kfree(ieee->cryptlist[j]); + ieee->cryptlist[j] = NULL; + } + } + + for (i = 0; i < IEEE_MESH_MAC_HASH_SIZE; i++) { + list_for_each_safe(p, q, &ieee->mesh_mac_hash[i]) { + kfree(list_entry(p, struct ieee_mesh_seq, list)); + list_del(p); + } + } +#endif + ieee80211_networks_free(ieee); + + for (i = 0; i < IEEE_IBSS_MAC_HASH_SIZE; i++) { + list_for_each_safe(p, q, &ieee->ibss_mac_hash[i]) { + kfree(list_entry(p, struct ieee_ibss_seq, list)); + list_del(p); + } + } + +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)) + free_netdev(dev); +#else + kfree(dev); +#endif +} + +#ifdef CONFIG_IEEE80211_DEBUG + +static int debug = 0; +u32 ieee80211_debug_level = 0; +struct proc_dir_entry *ieee80211_proc = NULL; + +static int show_debug_level(char *page, char **start, off_t offset, + int count, int *eof, void *data) +{ + return snprintf(page, count, "0x%08X\n", ieee80211_debug_level); +} + +static int store_debug_level(struct file *file, const char *buffer, + unsigned long count, void *data) +{ + char buf[] = "0x00000000"; + unsigned long len = min(sizeof(buf) - 1, (u32)count); + char *p = (char *)buf; + unsigned long val; + + if (copy_from_user(buf, buffer, len)) + return count; + buf[len] = 0; + if (p[1] == 'x' || p[1] == 'X' || p[0] == 'x' || p[0] == 'X') { + p++; + if (p[0] == 'x' || p[0] == 'X') + p++; + val = simple_strtoul(p, &p, 16); + } else + val = simple_strtoul(p, &p, 10); + if (p == buf) + printk(KERN_INFO DRV_NAME + ": %s is not in hex or decimal form.\n", buf); + else + ieee80211_debug_level = val; + + return strnlen(buf, count); +} + +static int __init ieee80211_init(void) +{ + struct proc_dir_entry *e; + + ieee80211_debug_level = debug; + ieee80211_proc = create_proc_entry(DRV_NAME, S_IFDIR, proc_net); + if (ieee80211_proc == NULL) { + IEEE80211_ERROR("Unable to create " DRV_NAME + " proc directory\n"); + return -EIO; + } + e = create_proc_entry("debug_level", S_IFREG | S_IRUGO | S_IWUSR, + ieee80211_proc); + if (!e) { + remove_proc_entry(DRV_NAME, proc_net); + ieee80211_proc = NULL; + return -EIO; + } + e->read_proc = show_debug_level; + e->write_proc = store_debug_level; + e->data = NULL; + + return 0; +} + +static void __exit ieee80211_exit(void) +{ + if (ieee80211_proc) { + remove_proc_entry("debug_level", ieee80211_proc); + remove_proc_entry(DRV_NAME, proc_net); + ieee80211_proc = NULL; + } +} + +#include +module_param(debug, int, 0444); +MODULE_PARM_DESC(debug, "debug output mask"); + + +module_exit(ieee80211_exit); +module_init(ieee80211_init); +#endif +#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)) +EXPORT_SYMBOL(alloc_ieee80211); +EXPORT_SYMBOL(free_ieee80211); +#else +EXPORT_SYMBOL_NOVERS(alloc_ieee80211); +EXPORT_SYMBOL_NOVERS(free_ieee80211); +#endif diff -Nur linux-2.6.30.5.orig/drivers/net/wireless/rtl8187b/ieee80211/ieee80211_rx.c linux-2.6.30.5/drivers/net/wireless/rtl8187b/ieee80211/ieee80211_rx.c --- linux-2.6.30.5.orig/drivers/net/wireless/rtl8187b/ieee80211/ieee80211_rx.c 1970-01-01 01:00:00.000000000 +0100 +++ linux-2.6.30.5/drivers/net/wireless/rtl8187b/ieee80211/ieee80211_rx.c 2009-08-23 19:01:04.000000000 +0200 @@ -0,0 +1,2074 @@ +/* + * Original code based Host AP (software wireless LAN access point) driver + * for Intersil Prism2/2.5/3 - hostap.o module, common routines + * + * Copyright (c) 2001-2002, SSH Communications Security Corp and Jouni Malinen + * + * Copyright (c) 2002-2003, Jouni Malinen + * Copyright (c) 2004, Intel Corporation + * + * 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. See README and COPYING for + * more details. + ****************************************************************************** + + Few modifications for Realtek's Wi-Fi drivers by + Andrea Merello + + A special thanks goes to Realtek for their support ! + +******************************************************************************/ + + +#include +//#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "ieee80211.h" +#ifdef ENABLE_DOT11D +#include "dot11d.h" +#endif + +static inline void ieee80211_monitor_rx(struct ieee80211_device *ieee, + struct sk_buff *skb, + struct ieee80211_rx_stats *rx_stats) +{ + struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; + u16 fc = le16_to_cpu(hdr->frame_ctl); + + skb->dev = ieee->dev; +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,22) + skb_reset_mac_header(skb); +#else + skb->mac.raw = skb->data; +#endif + + //skb->mac.raw = skb->data; + skb_pull(skb, ieee80211_get_hdrlen(fc)); + skb->pkt_type = PACKET_OTHERHOST; + skb->protocol = __constant_htons(ETH_P_80211_RAW); + memset(skb->cb, 0, sizeof(skb->cb)); + netif_rx(skb); +} + + +/* Called only as a tasklet (software IRQ) */ +static struct ieee80211_frag_entry * +ieee80211_frag_cache_find(struct ieee80211_device *ieee, unsigned int seq, + unsigned int frag, u8 tid,u8 *src, u8 *dst) +{ + struct ieee80211_frag_entry *entry; + int i; + + for (i = 0; i < IEEE80211_FRAG_CACHE_LEN; i++) { + entry = &ieee->frag_cache[tid][i]; + if (entry->skb != NULL && + time_after(jiffies, entry->first_frag_time + 2 * HZ)) { + IEEE80211_DEBUG_FRAG( + "expiring fragment cache entry " + "seq=%u last_frag=%u\n", + entry->seq, entry->last_frag); + dev_kfree_skb_any(entry->skb); + entry->skb = NULL; + } + + if (entry->skb != NULL && entry->seq == seq && + (entry->last_frag + 1 == frag || frag == -1) && + memcmp(entry->src_addr, src, ETH_ALEN) == 0 && + memcmp(entry->dst_addr, dst, ETH_ALEN) == 0) + return entry; + } + + return NULL; +} + +/* Called only as a tasklet (software IRQ) */ +static struct sk_buff * +ieee80211_frag_cache_get(struct ieee80211_device *ieee, + struct ieee80211_hdr *hdr) +{ + struct sk_buff *skb = NULL; + u16 fc = le16_to_cpu(hdr->frame_ctl); + u16 sc = le16_to_cpu(hdr->seq_ctl); + unsigned int frag = WLAN_GET_SEQ_FRAG(sc); + unsigned int seq = WLAN_GET_SEQ_SEQ(sc); + struct ieee80211_frag_entry *entry; + struct ieee80211_hdr_3addr_QOS *hdr_3addr_QoS; + struct ieee80211_hdr_QOS *hdr_4addr_QoS; + u8 tid; + +#ifdef _RTL8187_EXT_PATCH_ + if(ieee->iw_mode == ieee->iw_ext_mode) + { + tid = (hdr->addr2[ETH_ALEN-2] ^ hdr->addr2[ETH_ALEN-1]) & IEEE80211_QOS_TID; + } + else +#endif + if (((fc & IEEE80211_FCTL_DSTODS) == IEEE80211_FCTL_DSTODS)&&IEEE80211_QOS_HAS_SEQ(fc)) { + hdr_4addr_QoS = (struct ieee80211_hdr_QOS *)hdr; + tid = le16_to_cpu(hdr_4addr_QoS->QOS_ctl) & IEEE80211_QOS_TID; + tid = UP2AC(tid); + tid ++; + } else if (IEEE80211_QOS_HAS_SEQ(fc)) { + hdr_3addr_QoS = (struct ieee80211_hdr_3addr_QOS *)hdr; + tid = le16_to_cpu(hdr_3addr_QoS->QOS_ctl) & IEEE80211_QOS_TID; + tid = UP2AC(tid); + tid ++; + } else { + tid = 0; + } + + if (frag == 0) { + /* Reserve enough space to fit maximum frame length */ + skb = dev_alloc_skb(ieee->dev->mtu + + sizeof(struct ieee80211_hdr) + + 8 /* LLC */ + + 2 /* alignment */ + + 8 /* WEP */ + + ETH_ALEN /* WDS */ + + (IEEE80211_QOS_HAS_SEQ(fc)?2:0) /* QOS Control */); + if (skb == NULL) + return NULL; + + entry = &ieee->frag_cache[tid][ieee->frag_next_idx[tid]]; + ieee->frag_next_idx[tid]++; + if (ieee->frag_next_idx[tid] >= IEEE80211_FRAG_CACHE_LEN) + ieee->frag_next_idx[tid] = 0; + + if (entry->skb != NULL) + dev_kfree_skb_any(entry->skb); + + entry->first_frag_time = jiffies; + entry->seq = seq; + entry->last_frag = frag; + entry->skb = skb; + memcpy(entry->src_addr, hdr->addr2, ETH_ALEN); + memcpy(entry->dst_addr, hdr->addr1, ETH_ALEN); + } else { + /* received a fragment of a frame for which the head fragment + * should have already been received */ + entry = ieee80211_frag_cache_find(ieee, seq, frag, tid,hdr->addr2, + hdr->addr1); + if (entry != NULL) { + entry->last_frag = frag; + skb = entry->skb; + } + } + + return skb; +} + + +/* Called only as a tasklet (software IRQ) */ +static int ieee80211_frag_cache_invalidate(struct ieee80211_device *ieee, + struct ieee80211_hdr *hdr) +{ + u16 fc = le16_to_cpu(hdr->frame_ctl); + u16 sc = le16_to_cpu(hdr->seq_ctl); + unsigned int seq = WLAN_GET_SEQ_SEQ(sc); + struct ieee80211_frag_entry *entry; + struct ieee80211_hdr_3addr_QOS *hdr_3addr_QoS; + struct ieee80211_hdr_QOS *hdr_4addr_QoS; + u8 tid; + +#ifdef _RTL8187_EXT_PATCH_ + if(ieee->iw_mode == ieee->iw_ext_mode) + { + tid = (hdr->addr2[ETH_ALEN-2] ^ hdr->addr2[ETH_ALEN-1]) & IEEE80211_QOS_TID; + } + else +#endif + if(((fc & IEEE80211_FCTL_DSTODS) == IEEE80211_FCTL_DSTODS)&&IEEE80211_QOS_HAS_SEQ(fc)) { + hdr_4addr_QoS = (struct ieee80211_hdr_QOS *)hdr; + tid = le16_to_cpu(hdr_4addr_QoS->QOS_ctl) & IEEE80211_QOS_TID; + tid = UP2AC(tid); + tid ++; + } else if (IEEE80211_QOS_HAS_SEQ(fc)) { + hdr_3addr_QoS = (struct ieee80211_hdr_3addr_QOS *)hdr; + tid = le16_to_cpu(hdr_3addr_QoS->QOS_ctl) & IEEE80211_QOS_TID; + tid = UP2AC(tid); + tid ++; + } else { + tid = 0; + } + + entry = ieee80211_frag_cache_find(ieee, seq, -1, tid,hdr->addr2, + hdr->addr1); + + if (entry == NULL) { + IEEE80211_DEBUG_FRAG( + "could not invalidate fragment cache " + "entry (seq=%u)\n", seq); + return -1; + } + + entry->skb = NULL; + return 0; +} + + + +/* ieee80211_rx_frame_mgtmt + * + * Responsible for handling management control frames + * + * Called by ieee80211_rx */ +static inline int +ieee80211_rx_frame_mgmt(struct ieee80211_device *ieee, struct sk_buff *skb, + struct ieee80211_rx_stats *rx_stats, u16 type, + u16 stype) +{ + /* On the struct stats definition there is written that + * this is not mandatory.... but seems that the probe + * response parser uses it + */ + struct ieee80211_hdr * hdr = (struct ieee80211_hdr*)skb->data; + rx_stats->len = skb->len; + ieee80211_rx_mgt(ieee,(struct ieee80211_hdr *)skb->data,rx_stats); + + if ((ieee->state == IEEE80211_LINKED) && (memcmp(hdr->addr3, ieee->current_network.bssid, ETH_ALEN))) + { + dev_kfree_skb_any(skb); + return 0; + } + + ieee80211_rx_frame_softmac(ieee, skb, rx_stats, type, stype); + + dev_kfree_skb_any(skb); + + return 0; + + #ifdef NOT_YET + if (ieee->iw_mode == IW_MODE_MASTER) { + printk(KERN_DEBUG "%s: Master mode not yet suppported.\n", + ieee->dev->name); + return 0; +/* + hostap_update_sta_ps(ieee, (struct hostap_ieee80211_hdr *) + skb->data);*/ + } + + if (ieee->hostapd && type == IEEE80211_TYPE_MGMT) { + if (stype == WLAN_FC_STYPE_BEACON && + ieee->iw_mode == IW_MODE_MASTER) { + struct sk_buff *skb2; + /* Process beacon frames also in kernel driver to + * update STA(AP) table statistics */ + skb2 = skb_clone(skb, GFP_ATOMIC); + if (skb2) + hostap_rx(skb2->dev, skb2, rx_stats); + } + + /* send management frames to the user space daemon for + * processing */ + ieee->apdevstats.rx_packets++; + ieee->apdevstats.rx_bytes += skb->len; + prism2_rx_80211(ieee->apdev, skb, rx_stats, PRISM2_RX_MGMT); + return 0; + } + + if (ieee->iw_mode == IW_MODE_MASTER) { + if (type != WLAN_FC_TYPE_MGMT && type != WLAN_FC_TYPE_CTRL) { + printk(KERN_DEBUG "%s: unknown management frame " + "(type=0x%02x, stype=0x%02x) dropped\n", + skb->dev->name, type, stype); + return -1; + } + + hostap_rx(skb->dev, skb, rx_stats); + return 0; + } + + printk(KERN_DEBUG "%s: hostap_rx_frame_mgmt: management frame " + "received in non-Host AP mode\n", skb->dev->name); + return -1; + #endif +} + + + +/* See IEEE 802.1H for LLC/SNAP encapsulation/decapsulation */ +/* Ethernet-II snap header (RFC1042 for most EtherTypes) */ +static unsigned char rfc1042_header[] = +{ 0xaa, 0xaa, 0x03, 0x00, 0x00, 0x00 }; +/* Bridge-Tunnel header (for EtherTypes ETH_P_AARP and ETH_P_IPX) */ +static unsigned char bridge_tunnel_header[] = +{ 0xaa, 0xaa, 0x03, 0x00, 0x00, 0xf8 }; +/* No encapsulation header if EtherType < 0x600 (=length) */ + +/* Called by ieee80211_rx_frame_decrypt */ +static int ieee80211_is_eapol_frame(struct ieee80211_device *ieee, + struct sk_buff *skb, size_t hdrlen) +{ + struct net_device *dev = ieee->dev; + u16 fc, ethertype; + struct ieee80211_hdr *hdr; + u8 *pos; + + if (skb->len < 24) + return 0; + + hdr = (struct ieee80211_hdr *) skb->data; + fc = le16_to_cpu(hdr->frame_ctl); + + /* check that the frame is unicast frame to us */ + if ((fc & (IEEE80211_FCTL_TODS | IEEE80211_FCTL_FROMDS)) == + IEEE80211_FCTL_TODS && + memcmp(hdr->addr1, dev->dev_addr, ETH_ALEN) == 0 && + memcmp(hdr->addr3, dev->dev_addr, ETH_ALEN) == 0) { + /* ToDS frame with own addr BSSID and DA */ + } else if ((fc & (IEEE80211_FCTL_TODS | IEEE80211_FCTL_FROMDS)) == + IEEE80211_FCTL_FROMDS && + memcmp(hdr->addr1, dev->dev_addr, ETH_ALEN) == 0) { + /* FromDS frame with own addr as DA */ + } else + return 0; + + if (skb->len < 24 + 8) + return 0; + + /* check for port access entity Ethernet type */ +// pos = skb->data + 24; + pos = skb->data + hdrlen; + ethertype = (pos[6] << 8) | pos[7]; + if (ethertype == ETH_P_PAE) + return 1; + + return 0; +} + +/* Called only as a tasklet (software IRQ), by ieee80211_rx */ +static inline int +ieee80211_rx_frame_decrypt(struct ieee80211_device* ieee, struct sk_buff *skb, + struct ieee80211_crypt_data *crypt) +{ + struct ieee80211_hdr *hdr; + int res, hdrlen; + + if (crypt == NULL || crypt->ops->decrypt_mpdu == NULL) + return 0; + + hdr = (struct ieee80211_hdr *) skb->data; +#ifdef _RTL8187_EXT_PATCH_ + if((ieee->iw_mode == ieee->iw_ext_mode) && (ieee->ext_patch_ieee80211_rx_frame_get_hdrlen)) + { + hdrlen = ieee->ext_patch_ieee80211_rx_frame_get_hdrlen(ieee, skb); + } + else +#endif + hdrlen = ieee80211_get_hdrlen(le16_to_cpu(hdr->frame_ctl)); + +#ifdef CONFIG_IEEE80211_CRYPT_TKIP + if (ieee->tkip_countermeasures && + strcmp(crypt->ops->name, "TKIP") == 0) { + if (net_ratelimit()) { + printk(KERN_DEBUG "%s: TKIP countermeasures: dropped " + "received packet from " MAC_FMT "\n", + ieee->dev->name, MAC_ARG(hdr->addr2)); + } + return -1; + } +#endif + + atomic_inc(&crypt->refcnt); + res = crypt->ops->decrypt_mpdu(skb, hdrlen, crypt->priv); + atomic_dec(&crypt->refcnt); + if (res < 0) { + IEEE80211_DEBUG_DROP( + "decryption failed (SA=" MAC_FMT + ") res=%d\n", MAC_ARG(hdr->addr2), res); + if (res == -2) + IEEE80211_DEBUG_DROP("Decryption failed ICV " + "mismatch (key %d)\n", + skb->data[hdrlen + 3] >> 6); + ieee->ieee_stats.rx_discards_undecryptable++; + return -1; + } + + return res; +} + + +/* Called only as a tasklet (software IRQ), by ieee80211_rx */ +static inline int +ieee80211_rx_frame_decrypt_msdu(struct ieee80211_device* ieee, struct sk_buff *skb, + int keyidx, struct ieee80211_crypt_data *crypt) +{ + struct ieee80211_hdr *hdr; + int res, hdrlen; + + if (crypt == NULL || crypt->ops->decrypt_msdu == NULL) + return 0; + + hdr = (struct ieee80211_hdr *) skb->data; +#ifdef _RTL8187_EXT_PATCH_ + if((ieee->iw_mode == ieee->iw_ext_mode) && (ieee->ext_patch_ieee80211_rx_frame_get_hdrlen)) + { + hdrlen = ieee->ext_patch_ieee80211_rx_frame_get_hdrlen(ieee, skb); + } + else +#endif + hdrlen = ieee80211_get_hdrlen(le16_to_cpu(hdr->frame_ctl)); + + atomic_inc(&crypt->refcnt); + res = crypt->ops->decrypt_msdu(skb, keyidx, hdrlen, crypt->priv); + atomic_dec(&crypt->refcnt); + if (res < 0) { + printk(KERN_DEBUG "%s: MSDU decryption/MIC verification failed" + " (SA=" MAC_FMT " keyidx=%d)\n", + ieee->dev->name, MAC_ARG(hdr->addr2), keyidx); + return -1; + } + + return 0; +} + + +/* this function is stolen from ipw2200 driver*/ +#define IEEE_PACKET_RETRY_TIME (5*HZ) +static int is_duplicate_packet(struct ieee80211_device *ieee, + struct ieee80211_hdr *header) +{ + u16 fc = le16_to_cpu(header->frame_ctl); + u16 sc = le16_to_cpu(header->seq_ctl); + u16 seq = WLAN_GET_SEQ_SEQ(sc); + u16 frag = WLAN_GET_SEQ_FRAG(sc); + u16 *last_seq, *last_frag; + unsigned long *last_time; + struct ieee80211_hdr_3addr_QOS *hdr_3addr_QoS; + struct ieee80211_hdr_QOS *hdr_4addr_QoS; + u8 tid; + +#ifdef _RTL8187_EXT_PATCH_ + if(ieee->iw_mode == ieee->iw_ext_mode) + { + tid = (header->addr2[ETH_ALEN-2] ^ header->addr2[ETH_ALEN-1]) & IEEE80211_QOS_TID; + } + else +#endif + //TO2DS and QoS + if(((fc & IEEE80211_FCTL_DSTODS) == IEEE80211_FCTL_DSTODS)&&IEEE80211_QOS_HAS_SEQ(fc)) { + hdr_4addr_QoS = (struct ieee80211_hdr_QOS *)header; + tid = le16_to_cpu(hdr_4addr_QoS->QOS_ctl) & IEEE80211_QOS_TID; + tid = UP2AC(tid); + tid ++; + } else if(IEEE80211_QOS_HAS_SEQ(fc)) { //QoS + hdr_3addr_QoS = (struct ieee80211_hdr_3addr_QOS*)header; + tid = le16_to_cpu(hdr_3addr_QoS->QOS_ctl) & IEEE80211_QOS_TID; + tid = UP2AC(tid); + tid ++; + } else { // no QoS + tid = 0; + } + + switch (ieee->iw_mode) { + case IW_MODE_ADHOC: + { + struct list_head *p; + struct ieee_ibss_seq *entry = NULL; + u8 *mac = header->addr2; + int index = mac[5] % IEEE_IBSS_MAC_HASH_SIZE; + //for (pos = (head)->next; pos != (head); pos = pos->next) + __list_for_each(p, &ieee->ibss_mac_hash[index]) { + entry = list_entry(p, struct ieee_ibss_seq, list); + if (!memcmp(entry->mac, mac, ETH_ALEN)) + break; + } + // if (memcmp(entry->mac, mac, ETH_ALEN)){ + if (p == &ieee->ibss_mac_hash[index]) { + entry = kmalloc(sizeof(struct ieee_ibss_seq), GFP_ATOMIC); + if (!entry) { + printk(KERN_WARNING "Cannot malloc new mac entry\n"); + return 0; + } + memcpy(entry->mac, mac, ETH_ALEN); + entry->seq_num[tid] = seq; + entry->frag_num[tid] = frag; + entry->packet_time[tid] = jiffies; + list_add(&entry->list, &ieee->ibss_mac_hash[index]); + return 0; + } + last_seq = &entry->seq_num[tid]; + last_frag = &entry->frag_num[tid]; + last_time = &entry->packet_time[tid]; + break; + } + + case IW_MODE_INFRA: + last_seq = &ieee->last_rxseq_num[tid]; + last_frag = &ieee->last_rxfrag_num[tid]; + last_time = &ieee->last_packet_time[tid]; + + break; + default: +#ifdef _RTL8187_EXT_PATCH_ + if(ieee->iw_mode == ieee->iw_ext_mode) + { +#if 0 + printk("==============> tid = %d\n", tid); + last_seq = &ieee->last_rxseq_num[tid]; + last_frag = &ieee->last_rxfrag_num[tid]; + last_time = &ieee->last_packet_time[tid]; +#else + struct list_head *p; + struct ieee_mesh_seq *entry = NULL; + u8 *mac = header->addr2; + int index = mac[5] % IEEE_IBSS_MAC_HASH_SIZE; + + __list_for_each(p, &ieee->mesh_mac_hash[index]) { + entry = list_entry(p, struct ieee_mesh_seq, list); + if (!memcmp(entry->mac, mac, ETH_ALEN)) + break; + } + if (p == &ieee->mesh_mac_hash[index]) { + entry = kmalloc(sizeof(struct ieee_mesh_seq), GFP_ATOMIC); + if (!entry) { + printk(KERN_WARNING "Cannot malloc new mac entry for mesh\n"); + return 0; + } + memcpy(entry->mac, mac, ETH_ALEN); + entry->seq_num = seq; + entry->frag_num = frag; + entry->packet_time = jiffies; + list_add(&entry->list, &ieee->mesh_mac_hash[index]); + return 0; + } + last_seq = &entry->seq_num; + last_frag = &entry->frag_num; + last_time = &entry->packet_time; +#endif + break; + } + else +#endif + return 0; + } + +// if(tid != 0) { +// printk(KERN_WARNING ":)))))))))))%x %x %x, fc(%x)\n", tid, *last_seq, seq, header->frame_ctl); +// } + if ((*last_seq == seq) && + time_after(*last_time + IEEE_PACKET_RETRY_TIME, jiffies)) { + if (*last_frag == frag){ + //printk(KERN_WARNING "[1] go drop!\n"); + goto drop; + + } + if (*last_frag + 1 != frag) + /* out-of-order fragment */ + //printk(KERN_WARNING "[2] go drop!\n"); + goto drop; + } else + *last_seq = seq; + + *last_frag = frag; + *last_time = jiffies; + return 0; + +drop: +// BUG_ON(!(fc & IEEE80211_FCTL_RETRY)); +// printk("DUP\n"); + + return 1; +} +#ifdef JUST_FOR_87SEMESH +#define ActionHeadLen 30 +#define WIFI_MESH_TYPE IEEE80211_FTYPE_DATA +#define WIFI_11S_MESH_ACTION 0x00A0 +#endif + +/* All received frames are sent to this function. @skb contains the frame in + * IEEE 802.11 format, i.e., in the format it was sent over air. + * This function is called only as a tasklet (software IRQ). */ +int ieee80211_rx(struct ieee80211_device *ieee, struct sk_buff *skb, + struct ieee80211_rx_stats *rx_stats) +{ + struct net_device *dev = ieee->dev; + struct ieee80211_hdr *hdr; + //struct ieee80211_hdr_3addr_QOS *hdr; + + size_t hdrlen; + u16 fc, type, stype, sc; + struct net_device_stats *stats; + unsigned int frag; + u8 *payload; + u16 ethertype; +#ifdef NOT_YET + struct net_device *wds = NULL; + struct sk_buff *skb2 = NULL; + struct net_device *wds = NULL; + int frame_authorized = 0; + int from_assoc_ap = 0; + void *sta = NULL; +#endif +// u16 QOS_ctl = 0; + u8 dst[ETH_ALEN]; + u8 src[ETH_ALEN]; + u8 bssid[ETH_ALEN]; + struct ieee80211_crypt_data *crypt = NULL; + int keyidx = 0; + + //Added for mesh by Lawrence. + //u8 status; + //u32 flags; + + // cheat the the hdr type + hdr = (struct ieee80211_hdr *)skb->data; + stats = &ieee->stats; + + if (skb->len < 10) { + printk(KERN_INFO "%s: SKB length < 10\n", + dev->name); + goto rx_dropped; + } +#if 0 +//{added by david for filter the packet listed in the filter table +#ifdef _RTL8187_EXT_PATCH_ + if((ieee->iw_mode == ieee->iw_ext_mode) && (ieee->ext_patch_ieee80211_acl_query)) + { + if(!ieee->ext_patch_ieee80211_acl_query(ieee, hdr->addr2)) + goto rx_dropped; + } +#endif +//} +#endif + fc = le16_to_cpu(hdr->frame_ctl); + type = WLAN_FC_GET_TYPE(fc); + stype = WLAN_FC_GET_STYPE(fc); + + //Because 87se's bad feature,do more handle. +#ifdef JUST_FOR_87SEMESH + +u8 tmphead[ActionHeadLen]; + if(type ==WIFI_MESH_TYPE && stype== WIFI_11S_MESH_ACTION ) + //head=sizeof(struct ieee80211_hdr)=30 + { + memset(tmphead,0,ActionHeadLen); + memcpy(tmphead,skb->data,ActionHeadLen); + + skb_pull(skb,ActionHeadLen+2); + memcpy(skb_push(skb,ActionHeadLen),tmphead,ActionHeadLen); + hdr = (struct ieee80211_hdr *)skb->data; + } + +#endif + sc = le16_to_cpu(hdr->seq_ctl); + + frag = WLAN_GET_SEQ_FRAG(sc); +#ifdef _RTL8187_EXT_PATCH_ + if((ieee->iw_mode == ieee->iw_ext_mode) && (ieee->ext_patch_ieee80211_rx_frame_get_hdrlen)) + { + hdrlen = ieee->ext_patch_ieee80211_rx_frame_get_hdrlen(ieee, skb); + if(skb->len < hdrlen) + goto rx_dropped; + } + else +#endif + hdrlen = ieee80211_get_hdrlen(fc); + +#ifdef NOT_YET +#if WIRELESS_EXT > 15 + /* Put this code here so that we avoid duplicating it in all + * Rx paths. - Jean II */ +#ifdef IW_WIRELESS_SPY /* defined in iw_handler.h */ + /* If spy monitoring on */ + if (iface->spy_data.spy_number > 0) { + struct iw_quality wstats; + wstats.level = rx_stats->signal; + wstats.noise = rx_stats->noise; + wstats.updated = 6; /* No qual value */ + /* Update spy records */ + wireless_spy_update(dev, hdr->addr2, &wstats); + } +#endif /* IW_WIRELESS_SPY */ +#endif /* WIRELESS_EXT > 15 */ + hostap_update_rx_stats(local->ap, hdr, rx_stats); +#endif + +#if WIRELESS_EXT > 15 + if (ieee->iw_mode == IW_MODE_MONITOR) { + ieee80211_monitor_rx(ieee, skb, rx_stats); + stats->rx_packets++; + stats->rx_bytes += skb->len; + return 1; + } +#endif + if (ieee->host_decrypt) { + int idx = 0; + if (skb->len >= hdrlen + 3) + idx = skb->data[hdrlen + 3] >> 6; +#ifdef _RTL8187_EXT_PATCH_ + + crypt = ieee->cryptlist[0]->crypt[idx]; +#if 0 + { + int i = ieee80211_find_MP(ieee, ((struct ieee80211_hdr*)skb->data)->addr2); + if (i == -1) + { + printk("error find entry in entry list\n"); + goto rx_dropped; + } + //printk("%s():"MAC_FMT", find in index:%d", __FUNCTION__, MAC_ARG(((struct ieee80211_hdr*)skb->data)->addr2), i); + crypt = ieee->cryptlist[i]->crypt[idx]; + } +#endif +#else + crypt = ieee->crypt[idx]; +#endif + +#ifdef NOT_YET + sta = NULL; + + /* Use station specific key to override default keys if the + * receiver address is a unicast address ("individual RA"). If + * bcrx_sta_key parameter is set, station specific key is used + * even with broad/multicast targets (this is against IEEE + * 802.11, but makes it easier to use different keys with + * stations that do not support WEP key mapping). */ + + if (!(hdr->addr1[0] & 0x01) || local->bcrx_sta_key) + (void) hostap_handle_sta_crypto(local, hdr, &crypt, + &sta); +#endif + + /* allow NULL decrypt to indicate an station specific override + * for default encryption */ + if (crypt && (crypt->ops == NULL || + crypt->ops->decrypt_mpdu == NULL)) + crypt = NULL; + + if (!crypt && (fc & IEEE80211_FCTL_WEP)) { + /* This seems to be triggered by some (multicast?) + * frames from other than current BSS, so just drop the + * frames silently instead of filling system log with + * these reports. */ + IEEE80211_DEBUG_DROP("Decryption failed (not set)" + " (SA=" MAC_FMT ")\n", + MAC_ARG(hdr->addr2)); + ieee->ieee_stats.rx_discards_undecryptable++; + goto rx_dropped; + } + } + + if (skb->len < IEEE80211_DATA_HDR3_LEN) + goto rx_dropped; + + // if QoS enabled, should check the sequence for each of the AC + if (is_duplicate_packet(ieee, hdr)) + goto rx_dropped; + +#ifdef _RTL8187_EXT_PATCH_ + if( ieee->iw_mode == ieee->iw_ext_mode && ieee->ext_patch_ieee80211_rx_mgt_update_expire ) + ieee->ext_patch_ieee80211_rx_mgt_update_expire( ieee, skb ); +#endif + + if (type == IEEE80211_FTYPE_MGMT) { + + #if 0 + if ( stype == IEEE80211_STYPE_AUTH && + fc & IEEE80211_FCTL_WEP && ieee->host_decrypt && + (keyidx = hostap_rx_frame_decrypt(ieee, skb, crypt)) < 0) + { + printk(KERN_DEBUG "%s: failed to decrypt mgmt::auth " + "from " MAC_FMT "\n", dev->name, + MAC_ARG(hdr->addr2)); + /* TODO: could inform hostapd about this so that it + * could send auth failure report */ + goto rx_dropped; + } + #endif + + + if (ieee80211_rx_frame_mgmt(ieee, skb, rx_stats, type, stype)) + goto rx_dropped; + else + goto rx_exit; + } + +#ifdef _RTL8187_EXT_PATCH_ + if((ieee->iw_mode == ieee->iw_ext_mode) && ieee->ext_patch_ieee80211_rx_on_rx) + { + if(ieee->ext_patch_ieee80211_rx_on_rx(ieee, skb, rx_stats, type, stype)==0) + { + goto rx_exit; + } + } +#endif + + /* Data frame - extract src/dst addresses */ + switch (fc & (IEEE80211_FCTL_FROMDS | IEEE80211_FCTL_TODS)) { + case IEEE80211_FCTL_FROMDS: + memcpy(dst, hdr->addr1, ETH_ALEN); + memcpy(src, hdr->addr3, ETH_ALEN); + memcpy(bssid, hdr->addr2, ETH_ALEN); + break; + case IEEE80211_FCTL_TODS: + memcpy(dst, hdr->addr3, ETH_ALEN); + memcpy(src, hdr->addr2, ETH_ALEN); + memcpy(bssid, hdr->addr1, ETH_ALEN); + break; + case IEEE80211_FCTL_FROMDS | IEEE80211_FCTL_TODS: + if (skb->len < IEEE80211_DATA_HDR4_LEN) + goto rx_dropped; + memcpy(dst, hdr->addr3, ETH_ALEN); + memcpy(src, hdr->addr4, ETH_ALEN); + memcpy(bssid, ieee->current_network.bssid, ETH_ALEN); + break; + case 0: + memcpy(dst, hdr->addr1, ETH_ALEN); + memcpy(src, hdr->addr2, ETH_ALEN); + memcpy(bssid, hdr->addr3, ETH_ALEN); + break; + } + +#ifdef NOT_YET + if (hostap_rx_frame_wds(ieee, hdr, fc, &wds)) + goto rx_dropped; + if (wds) { + skb->dev = dev = wds; + stats = hostap_get_stats(dev); + } + + if (ieee->iw_mode == IW_MODE_MASTER && !wds && + (fc & (IEEE80211_FCTL_TODS | IEEE80211_FCTL_FROMDS)) == IEEE80211_FCTL_FROMDS && + ieee->stadev && + memcmp(hdr->addr2, ieee->assoc_ap_addr, ETH_ALEN) == 0) { + /* Frame from BSSID of the AP for which we are a client */ + skb->dev = dev = ieee->stadev; + stats = hostap_get_stats(dev); + from_assoc_ap = 1; + } +#endif + + dev->last_rx = jiffies; + +#ifdef NOT_YET + if ((ieee->iw_mode == IW_MODE_MASTER || + ieee->iw_mode == IW_MODE_REPEAT) && + !from_assoc_ap) { + switch (hostap_handle_sta_rx(ieee, dev, skb, rx_stats, + wds != NULL)) { + case AP_RX_CONTINUE_NOT_AUTHORIZED: + frame_authorized = 0; + break; + case AP_RX_CONTINUE: + frame_authorized = 1; + break; + case AP_RX_DROP: + goto rx_dropped; + case AP_RX_EXIT: + goto rx_exit; + } + } +#endif + +#ifdef _RTL8187_EXT_PATCH_ + if((ieee->iw_mode == ieee->iw_ext_mode) && ieee->ext_patch_ieee80211_rx_is_valid_framectl) + { + if(ieee->ext_patch_ieee80211_rx_is_valid_framectl(ieee, fc, type, stype)==0) + goto rx_dropped; + } + else +#endif + /* Nullfunc frames may have PS-bit set, so they must be passed to + * hostap_handle_sta_rx() before being dropped here. */ + if (stype != IEEE80211_STYPE_DATA && + stype != IEEE80211_STYPE_DATA_CFACK && + stype != IEEE80211_STYPE_DATA_CFPOLL && + stype != IEEE80211_STYPE_DATA_CFACKPOLL&& + stype != IEEE80211_STYPE_QOS_DATA//add by David,2006.8.4 + ) { + if (stype != IEEE80211_STYPE_NULLFUNC) + IEEE80211_DEBUG_DROP( + "RX: dropped data frame " + "with no data (type=0x%02x, " + "subtype=0x%02x, len=%d)\n", + type, stype, skb->len); + goto rx_dropped; + } + + if (memcmp(bssid, ieee->current_network.bssid, ETH_ALEN)) + goto rx_dropped; + + /* skb: hdr + (possibly fragmented, possibly encrypted) payload */ +#ifdef _RTL8187_EXT_PATCH_ + if (ieee->host_decrypt && crypt) { + int idx = 0; + if (skb->len >= hdrlen + 3) + idx = skb->data[hdrlen + 3] >> 6; + if (ieee->iw_ext_mode == ieee->iw_mode) //if in mesh mode + { + int i = ieee80211_find_MP(ieee, ((struct ieee80211_hdr*)skb->data)->addr2, 0); + if (i == -1) + { + printk("error find entry in entry list\n"); + goto rx_dropped; + } + // printk("%s():"MAC_FMT", find in index:%d\n", __FUNCTION__, MAC_ARG(((struct ieee80211_hdr*)skb->data)->addr2), i); + if (ieee->cryptlist[i]&&ieee->cryptlist[i]->crypt[idx]) + crypt = ieee->cryptlist[i]->crypt[idx]; + + else + crypt = NULL; + } + else + crypt = ieee->cryptlist[0]->crypt[idx]; + } +#endif + + if (ieee->host_decrypt && (fc & IEEE80211_FCTL_WEP) && + (keyidx = ieee80211_rx_frame_decrypt(ieee, skb, crypt)) < 0) + goto rx_dropped; + + hdr = (struct ieee80211_hdr *) skb->data; + + /* skb: hdr + (possibly fragmented) plaintext payload */ + // PR: FIXME: hostap has additional conditions in the "if" below: + // ieee->host_decrypt && (fc & IEEE80211_FCTL_WEP) && + if ((frag != 0 || (fc & IEEE80211_FCTL_MOREFRAGS))) { + int flen; + struct sk_buff *frag_skb = ieee80211_frag_cache_get(ieee, hdr); + IEEE80211_DEBUG_FRAG("Rx Fragment received (%u)\n", frag); + + if (!frag_skb) { + IEEE80211_DEBUG(IEEE80211_DL_RX | IEEE80211_DL_FRAG, + "Rx cannot get skb from fragment " + "cache (morefrag=%d seq=%u frag=%u)\n", + (fc & IEEE80211_FCTL_MOREFRAGS) != 0, + WLAN_GET_SEQ_SEQ(sc), frag); + goto rx_dropped; + } + flen = skb->len; + if (frag != 0) + flen -= hdrlen; + + if (frag_skb->tail + flen > frag_skb->end) { + printk(KERN_WARNING "%s: host decrypted and " + "reassembled frame did not fit skb\n", + dev->name); + ieee80211_frag_cache_invalidate(ieee, hdr); + goto rx_dropped; + } + + if (frag == 0) { + /* copy first fragment (including full headers) into + * beginning of the fragment cache skb */ + memcpy(skb_put(frag_skb, flen), skb->data, flen); + } else { + /* append frame payload to the end of the fragment + * cache skb */ + memcpy(skb_put(frag_skb, flen), skb->data + hdrlen, + flen); + } + dev_kfree_skb_any(skb); + skb = NULL; + + if (fc & IEEE80211_FCTL_MOREFRAGS) { + /* more fragments expected - leave the skb in fragment + * cache for now; it will be delivered to upper layers + * after all fragments have been received */ + goto rx_exit; + } + + /* this was the last fragment and the frame will be + * delivered, so remove skb from fragment cache */ + skb = frag_skb; + hdr = (struct ieee80211_hdr *) skb->data; + ieee80211_frag_cache_invalidate(ieee, hdr); + } + + /* skb: hdr + (possible reassembled) full MSDU payload; possibly still + * encrypted/authenticated */ + if (ieee->host_decrypt && (fc & IEEE80211_FCTL_WEP) && + ieee80211_rx_frame_decrypt_msdu(ieee, skb, keyidx, crypt)) + goto rx_dropped; + + hdr = (struct ieee80211_hdr *) skb->data; + if (crypt && !(fc & IEEE80211_FCTL_WEP) && !ieee->open_wep) { + if (/*ieee->ieee802_1x &&*/ + ieee80211_is_eapol_frame(ieee, skb, hdrlen)) { + +#ifdef CONFIG_IEEE80211_DEBUG + /* pass unencrypted EAPOL frames even if encryption is + * configured */ + struct eapol *eap = (struct eapol *)(skb->data + + 24); + IEEE80211_DEBUG_EAP("RX: IEEE 802.1X EAPOL frame: %s\n", + eap_get_type(eap->type)); +#endif + } else { + IEEE80211_DEBUG_DROP( + "encryption configured, but RX " + "frame not encrypted (SA=" MAC_FMT ")\n", + MAC_ARG(hdr->addr2)); + goto rx_dropped; + } + } + +#ifdef CONFIG_IEEE80211_DEBUG + if (crypt && !(fc & IEEE80211_FCTL_WEP) && + ieee80211_is_eapol_frame(ieee, skb)) { + struct eapol *eap = (struct eapol *)(skb->data + + 24); + IEEE80211_DEBUG_EAP("RX: IEEE 802.1X EAPOL frame: %s\n", + eap_get_type(eap->type)); + } +#endif + + if (crypt && !(fc & IEEE80211_FCTL_WEP) && !ieee->open_wep && + !ieee80211_is_eapol_frame(ieee, skb, hdrlen)) { + IEEE80211_DEBUG_DROP( + "dropped unencrypted RX data " + "frame from " MAC_FMT + " (drop_unencrypted=1)\n", + MAC_ARG(hdr->addr2)); + goto rx_dropped; + } +/* + if(ieee80211_is_eapol_frame(ieee, skb, hdrlen)) { + printk(KERN_WARNING "RX: IEEE802.1X EPAOL frame!\n"); + } +*/ + /* skb: hdr + (possible reassembled) full plaintext payload */ + payload = skb->data + hdrlen; + ethertype = (payload[6] << 8) | payload[7]; + +#ifdef NOT_YET + /* If IEEE 802.1X is used, check whether the port is authorized to send + * the received frame. */ + if (ieee->ieee802_1x && ieee->iw_mode == IW_MODE_MASTER) { + if (ethertype == ETH_P_PAE) { + printk(KERN_DEBUG "%s: RX: IEEE 802.1X frame\n", + dev->name); + if (ieee->hostapd && ieee->apdev) { + /* Send IEEE 802.1X frames to the user + * space daemon for processing */ + prism2_rx_80211(ieee->apdev, skb, rx_stats, + PRISM2_RX_MGMT); + ieee->apdevstats.rx_packets++; + ieee->apdevstats.rx_bytes += skb->len; + goto rx_exit; + } + } else if (!frame_authorized) { + printk(KERN_DEBUG "%s: dropped frame from " + "unauthorized port (IEEE 802.1X): " + "ethertype=0x%04x\n", + dev->name, ethertype); + goto rx_dropped; + } + } +#endif + +#ifdef _RTL8187_EXT_PATCH_ + if((ieee->iw_mode == ieee->iw_ext_mode) && ieee->ext_patch_ieee80211_rx_process_dataframe) + { + if(ieee->ext_patch_ieee80211_rx_process_dataframe(ieee, skb, rx_stats)) + { + stats->rx_packets++; + stats->rx_bytes += skb->len; + goto rx_exit; + } + else + goto rx_dropped; + } +#endif + ieee->NumRxDataInPeriod++; +// ieee->NumRxOkTotal++; + /* convert hdr + possible LLC headers into Ethernet header */ + if (skb->len - hdrlen >= 8 && + ((memcmp(payload, rfc1042_header, SNAP_SIZE) == 0 && + ethertype != ETH_P_AARP && ethertype != ETH_P_IPX) || + memcmp(payload, bridge_tunnel_header, SNAP_SIZE) == 0)) { + /* remove RFC1042 or Bridge-Tunnel encapsulation and + * replace EtherType */ + skb_pull(skb, hdrlen + SNAP_SIZE); + memcpy(skb_push(skb, ETH_ALEN), src, ETH_ALEN); + memcpy(skb_push(skb, ETH_ALEN), dst, ETH_ALEN); + } else { + u16 len; + /* Leave Ethernet header part of hdr and full payload */ + skb_pull(skb, hdrlen); + len = htons(skb->len); + memcpy(skb_push(skb, 2), &len, 2); + memcpy(skb_push(skb, ETH_ALEN), src, ETH_ALEN); + memcpy(skb_push(skb, ETH_ALEN), dst, ETH_ALEN); + } + +#ifdef NOT_YET + if (wds && ((fc & (IEEE80211_FCTL_TODS | IEEE80211_FCTL_FROMDS)) == + IEEE80211_FCTL_TODS) && + skb->len >= ETH_HLEN + ETH_ALEN) { + /* Non-standard frame: get addr4 from its bogus location after + * the payload */ + memcpy(skb->data + ETH_ALEN, + skb->data + skb->len - ETH_ALEN, ETH_ALEN); + skb_trim(skb, skb->len - ETH_ALEN); + } +#endif + + stats->rx_packets++; + stats->rx_bytes += skb->len; + +#ifdef NOT_YET + if (ieee->iw_mode == IW_MODE_MASTER && !wds && + ieee->ap->bridge_packets) { + if (dst[0] & 0x01) { + /* copy multicast frame both to the higher layers and + * to the wireless media */ + ieee->ap->bridged_multicast++; + skb2 = skb_clone(skb, GFP_ATOMIC); + if (skb2 == NULL) + printk(KERN_DEBUG "%s: skb_clone failed for " + "multicast frame\n", dev->name); + } else if (hostap_is_sta_assoc(ieee->ap, dst)) { + /* send frame directly to the associated STA using + * wireless media and not passing to higher layers */ + ieee->ap->bridged_unicast++; + skb2 = skb; + skb = NULL; + } + } + + if (skb2 != NULL) { + /* send to wireless media */ + skb2->protocol = __constant_htons(ETH_P_802_3); + skb2->mac.raw = skb2->nh.raw = skb2->data; + /* skb2->nh.raw = skb2->data + ETH_HLEN; */ + skb2->dev = dev; + dev_queue_xmit(skb2); + } + +#endif + if (skb) { + //printk("0skb_len(%d)\n", skb->len); + skb->protocol = eth_type_trans(skb, dev); + memset(skb->cb, 0, sizeof(skb->cb)); + skb->dev = dev; + skb->ip_summed = CHECKSUM_NONE; /* 802.11 crc not sufficient */ + //skb->ip_summed = CHECKSUM_UNNECESSARY; /* 802.11 crc not sufficient */ + ieee->last_rx_ps_time = jiffies; + //printk("1skb_len(%d)\n", skb->len); + netif_rx(skb); + } + +//by lizhaoming for LED_RX 2008.6.23 +#ifdef LED_SHIN +// printk("==================>data rcvd\n"); + ieee->ieee80211_led_contorl(dev,LED_CTL_RX); +#endif + + rx_exit: +#ifdef NOT_YET + if (sta) + hostap_handle_sta_release(sta); +#endif + return 1; + + rx_dropped: + stats->rx_dropped++; +#if 0 + int i; + printk("======>dropped: %s():addr2:"MAC_FMT",addr1:"MAC_FMT",skb->len:%d, hdrlen:%d\n", __FUNCTION__, MAC_ARG(((struct ieee80211_hdr*)skb->data)->addr2), MAC_ARG(((struct ieee80211_hdr*)skb->data)->addr1), skb->len, hdrlen); + for (i = 0; i < skb->len; i++) { + if (i % 16 == 0) printk("\n\t"); + printk("%2x ", *(skb->data+i)); + } + + printk("\n"); +#endif + /* Returning 0 indicates to caller that we have not handled the SKB-- + * so it is still allocated and can be used again by underlying + * hardware as a DMA target */ + return 0; +} + +#ifdef _RTL8187_EXT_PATCH_ +int ieee_ext_skb_p80211_to_ether(struct sk_buff *skb, int hdrlen, u8 *dst, u8 *src) +{ + u8 *payload; + u16 ethertype; + + /* skb: hdr + (possible reassembled) full plaintext payload */ + payload = skb->data + hdrlen; + ethertype = (payload[6] << 8) | payload[7]; + + /* convert hdr + possible LLC headers into Ethernet header */ + if (skb->len - hdrlen >= 8 && + ((memcmp(payload, rfc1042_header, SNAP_SIZE) == 0 && + ethertype != ETH_P_AARP && ethertype != ETH_P_IPX) || + memcmp(payload, bridge_tunnel_header, SNAP_SIZE) == 0)) { + /* remove RFC1042 or Bridge-Tunnel encapsulation and + * replace EtherType */ + skb_pull(skb, hdrlen + SNAP_SIZE); + memcpy(skb_push(skb, ETH_ALEN), src, ETH_ALEN); + memcpy(skb_push(skb, ETH_ALEN), dst, ETH_ALEN); + } else { + u16 len; + /* Leave Ethernet header part of hdr and full payload */ + skb_pull(skb, hdrlen); + len = htons(skb->len); + memcpy(skb_push(skb, 2), &len, 2); + memcpy(skb_push(skb, ETH_ALEN), src, ETH_ALEN); + memcpy(skb_push(skb, ETH_ALEN), dst, ETH_ALEN); + } + + return 1; +} +#endif // _RTL8187_EXT_PATCH_ + + +#define MGMT_FRAME_FIXED_PART_LENGTH 0x24 + +static inline int ieee80211_is_ofdm_rate(u8 rate) +{ + switch (rate & ~IEEE80211_BASIC_RATE_MASK) { + case IEEE80211_OFDM_RATE_6MB: + case IEEE80211_OFDM_RATE_9MB: + case IEEE80211_OFDM_RATE_12MB: + case IEEE80211_OFDM_RATE_18MB: + case IEEE80211_OFDM_RATE_24MB: + case IEEE80211_OFDM_RATE_36MB: + case IEEE80211_OFDM_RATE_48MB: + case IEEE80211_OFDM_RATE_54MB: + return 1; + } + return 0; +} + + +// +// Description: +// Translate 0-100 signal strength index into dBm. +// +int +TranslateToDbm8187( + unsigned char SignalStrengthIndex // 0-100 index. + ) +{ + unsigned char SignalPower; // in dBm. + + // Translate to dBm (x=0.5y-95). + //SignalPower = (int)((SignalStrengthIndex + 1) >> 1); + SignalPower = (int)SignalStrengthIndex * 7 / 10; + SignalPower -= 95; +// printk("==>SignalPower:%d\n", SignalPower); + return SignalPower; +} + +static inline int ieee80211_SignalStrengthTranslate( + int CurrSS + ) +{ + int RetSS; + + // Step 1. Scale mapping. + if(CurrSS >= 71 && CurrSS <= 100) + { + RetSS = 95 + (((CurrSS - 70) / 6 == 5) ? 5 : ((CurrSS - 70) / 6 + 1)); + } + else if(CurrSS >= 41 && CurrSS <= 70) + { + RetSS = 83 + ((CurrSS - 40) / 3); + } + else if(CurrSS >= 31 && CurrSS <= 40) + { + RetSS = 71 + (CurrSS - 30); + } + else if(CurrSS >= 21 && CurrSS <= 30) + { + RetSS = 59 + (CurrSS - 20); + } + else if(CurrSS >= 5 && CurrSS <= 20) + { + RetSS = 47 + (((CurrSS - 5) * 2) / 3); + } + else if(CurrSS == 4) + { + RetSS = 37; + } + else if(CurrSS == 3) + { + RetSS = 27; + } + else if(CurrSS == 2) + { + RetSS = 18; + } + else if(CurrSS == 1) + { + RetSS = 9; + } + else + { + RetSS = CurrSS; + } + //RT_TRACE(COMP_DBG, DBG_LOUD, ("##### After Mapping: LastSS: %d, CurrSS: %d, RetSS: %d\n", LastSS, CurrSS, RetSS)); + + // Step 2. Smoothing. + + //RT_TRACE(COMP_DBG, DBG_LOUD, ("$$$$$ After Smoothing: LastSS: %d, CurrSS: %d, RetSS: %d\n", LastSS, CurrSS, RetSS)); + + return RetSS; +} + +#ifdef ENABLE_DOT11D +static inline void ieee80211_extract_country_ie( + struct ieee80211_device *ieee, + struct ieee80211_info_element *info_element, + struct ieee80211_network *network, + u8 * addr2 +) +{ +#if 0 + u32 i = 0; + u8 * p = (u8*)info_element->data; + printk("-----------------------\n"); + printk("%s Country IE:", network->ssid); + for(i=0; ilen; i++) + printk("\t%2.2x", *(p+i)); + printk("\n-----------------------\n"); +#endif + if(IS_DOT11D_ENABLE(ieee)) + { + if(info_element->len!= 0) + { + memcpy(network->CountryIeBuf, info_element->data, info_element->len); + network->CountryIeLen = info_element->len; + + if(!IS_COUNTRY_IE_VALID(ieee)) + { + Dot11d_UpdateCountryIe(ieee, addr2, info_element->len, info_element->data); + } + } + + // + // 070305, rcnjko: I update country IE watch dog here because + // some AP (e.g. Cisco 1242) don't include country IE in their + // probe response frame. + // + if(IS_EQUAL_CIE_SRC(ieee, addr2) ) + { + UPDATE_CIE_WATCHDOG(ieee); + } + } + +} +#endif + + + inline int ieee80211_network_init( + struct ieee80211_device *ieee, + struct ieee80211_probe_response *beacon, + struct ieee80211_network *network, + struct ieee80211_rx_stats *stats) +{ +#ifdef CONFIG_IEEE80211_DEBUG + char rates_str[64]; + char *p; +#endif + struct ieee80211_info_element *info_element; + u16 left; + u8 i; + short offset; + + /* Pull out fixed field data */ + memcpy(network->bssid, beacon->header.addr3, ETH_ALEN); + network->capability = beacon->capability; + network->last_scanned = jiffies; + network->time_stamp[0] = beacon->time_stamp[0]; + network->time_stamp[1] = beacon->time_stamp[1]; + network->beacon_interval = beacon->beacon_interval; + /* Where to pull this? beacon->listen_interval;*/ + network->listen_interval = 0x0A; + network->rates_len = network->rates_ex_len = 0; + network->last_associate = 0; + network->ssid_len = 0; + network->flags = 0; + network->atim_window = 0; + network->QoS_Enable = 0; +#ifdef THOMAS_TURBO + network->Turbo_Enable = 0; +#endif +#ifdef ENABLE_DOT11D + network->CountryIeLen = 0; + memset(network->CountryIeBuf, 0, MAX_IE_LEN); +#endif + + if (stats->freq == IEEE80211_52GHZ_BAND) { + /* for A band (No DS info) */ + network->channel = stats->received_channel; + } else + network->flags |= NETWORK_HAS_CCK; + + network->wpa_ie_len = 0; + network->rsn_ie_len = 0; + + info_element = &beacon->info_element; + left = stats->len - ((void *)info_element - (void *)beacon); + while (left >= sizeof(struct ieee80211_info_element_hdr)) { + if (sizeof(struct ieee80211_info_element_hdr) + info_element->len > left) { + IEEE80211_DEBUG_SCAN("SCAN: parse failed: info_element->len + 2 > left : info_element->len+2=%d left=%d.\n", + info_element->len + sizeof(struct ieee80211_info_element), + left); + return 1; + } + + switch (info_element->id) { + case MFIE_TYPE_SSID: + if (ieee80211_is_empty_essid(info_element->data, + info_element->len)) { + network->flags |= NETWORK_EMPTY_ESSID; + break; + } + + network->ssid_len = min(info_element->len, + (u8)IW_ESSID_MAX_SIZE); + memcpy(network->ssid, info_element->data, network->ssid_len); + if (network->ssid_len < IW_ESSID_MAX_SIZE) + memset(network->ssid + network->ssid_len, 0, + IW_ESSID_MAX_SIZE - network->ssid_len); + + IEEE80211_DEBUG_SCAN("MFIE_TYPE_SSID: '%s' len=%d.\n", + network->ssid, network->ssid_len); + break; + + case MFIE_TYPE_RATES: +#ifdef CONFIG_IEEE80211_DEBUG + p = rates_str; +#endif + network->rates_len = min(info_element->len, MAX_RATES_LENGTH); + for (i = 0; i < network->rates_len; i++) { + network->rates[i] = info_element->data[i]; +#ifdef CONFIG_IEEE80211_DEBUG + p += snprintf(p, sizeof(rates_str) - (p - rates_str), "%02X ", network->rates[i]); +#endif + if (ieee80211_is_ofdm_rate(info_element->data[i])) { + network->flags |= NETWORK_HAS_OFDM; + if (info_element->data[i] & + IEEE80211_BASIC_RATE_MASK) + network->flags &= + ~NETWORK_HAS_CCK; + } + } + + IEEE80211_DEBUG_SCAN("MFIE_TYPE_RATES: '%s' (%d)\n", + rates_str, network->rates_len); + break; + + case MFIE_TYPE_RATES_EX: +#ifdef CONFIG_IEEE80211_DEBUG + p = rates_str; +#endif + network->rates_ex_len = min(info_element->len, MAX_RATES_EX_LENGTH); + for (i = 0; i < network->rates_ex_len; i++) { + network->rates_ex[i] = info_element->data[i]; +#ifdef CONFIG_IEEE80211_DEBUG + p += snprintf(p, sizeof(rates_str) - (p - rates_str), "%02X ", network->rates[i]); +#endif + if (ieee80211_is_ofdm_rate(info_element->data[i])) { + network->flags |= NETWORK_HAS_OFDM; + if (info_element->data[i] & + IEEE80211_BASIC_RATE_MASK) + network->flags &= + ~NETWORK_HAS_CCK; + } + } + + IEEE80211_DEBUG_SCAN("MFIE_TYPE_RATES_EX: '%s' (%d)\n", + rates_str, network->rates_ex_len); + break; + + case MFIE_TYPE_DS_SET: + IEEE80211_DEBUG_SCAN("MFIE_TYPE_DS_SET: %d\n", + info_element->data[0]); + if (stats->freq == IEEE80211_24GHZ_BAND) + network->channel = info_element->data[0]; + break; + + case MFIE_TYPE_FH_SET: + IEEE80211_DEBUG_SCAN("MFIE_TYPE_FH_SET: ignored\n"); + break; + + case MFIE_TYPE_CF_SET: + IEEE80211_DEBUG_SCAN("MFIE_TYPE_CF_SET: ignored\n"); + break; + + case MFIE_TYPE_TIM: + + if(info_element->len < 4) + break; + + network->dtim_period = info_element->data[1]; + + if(ieee->state != IEEE80211_LINKED) + break; + + network->last_dtim_sta_time[0] = stats->mac_time[0]; + network->last_dtim_sta_time[1] = stats->mac_time[1]; + + network->dtim_data = IEEE80211_DTIM_VALID; + + if(info_element->data[0] != 0) + break; + + if(info_element->data[2] & 1) + network->dtim_data |= IEEE80211_DTIM_MBCAST; + + offset = (info_element->data[2] >> 1)*2; + + //printk("offset1:%x aid:%x\n",offset, ieee->assoc_id); + + if(ieee->assoc_id < offset || + ieee->assoc_id > 8*(offset + info_element->len -3)) + + break; + + + offset = offset + ieee->assoc_id / 8;// + ((aid % 8)? 0 : 1) ; + + // printk("offset:%x data:%x, ucast:%d\n", offset, + // info_element->data[3+offset] , + // info_element->data[3+offset] & (1<<(ieee->assoc_id%8))); + + if(info_element->data[3+offset] & (1<<(ieee->assoc_id%8))) + network->dtim_data |= IEEE80211_DTIM_UCAST; + + break; + + case MFIE_TYPE_IBSS_SET: + IEEE80211_DEBUG_SCAN("MFIE_TYPE_IBSS_SET: ignored\n"); + break; + + case MFIE_TYPE_CHALLENGE: + IEEE80211_DEBUG_SCAN("MFIE_TYPE_CHALLENGE: ignored\n"); + break; + + case MFIE_TYPE_GENERIC: + //nic is 87B + IEEE80211_DEBUG_SCAN("MFIE_TYPE_GENERIC: %d bytes\n", + info_element->len); + if (info_element->len >= 4 && + info_element->data[0] == 0x00 && + info_element->data[1] == 0x50 && + info_element->data[2] == 0xf2 && + info_element->data[3] == 0x01) { + network->wpa_ie_len = min(info_element->len + 2, + MAX_WPA_IE_LEN); + memcpy(network->wpa_ie, info_element, + network->wpa_ie_len); + } + +#ifdef THOMAS_TURBO + if (info_element->len == 7 && + info_element->data[0] == 0x00 && + info_element->data[1] == 0xe0 && + info_element->data[2] == 0x4c && + info_element->data[3] == 0x01 && + info_element->data[4] == 0x02) { + network->Turbo_Enable = 1; + } +#endif + if (1 == stats->nic_type) {//nic 87 + break; + } + + if (info_element->len >= 5 && + info_element->data[0] == 0x00 && + info_element->data[1] == 0x50 && + info_element->data[2] == 0xf2 && + info_element->data[3] == 0x02 && + info_element->data[4] == 0x00) { + //printk(KERN_WARNING "wmm info updated: %x\n", info_element->data[6]); + //WMM Information Element + network->wmm_info = info_element->data[6]; + network->QoS_Enable = 1; + } + + if (info_element->len >= 8 && + info_element->data[0] == 0x00 && + info_element->data[1] == 0x50 && + info_element->data[2] == 0xf2 && + info_element->data[3] == 0x02 && + info_element->data[4] == 0x01) { + // Not care about version at present. + //WMM Information Element + //printk(KERN_WARNING "wmm info¶m updated: %x\n", info_element->data[6]); + network->wmm_info = info_element->data[6]; + //WMM Parameter Element + memcpy(network->wmm_param, (u8 *)(info_element->data + 8),(info_element->len - 8)); + network->QoS_Enable = 1; + } + break; + + case MFIE_TYPE_RSN: + IEEE80211_DEBUG_SCAN("MFIE_TYPE_RSN: %d bytes\n", + info_element->len); + network->rsn_ie_len = min(info_element->len + 2, + MAX_WPA_IE_LEN); + memcpy(network->rsn_ie, info_element, + network->rsn_ie_len); + break; + +#ifdef ENABLE_DOT11D + case MFIE_TYPE_COUNTRY: + IEEE80211_DEBUG_SCAN("MFIE_TYPE_COUNTRY: %d bytes\n", + info_element->len); +// printk("=====>Receive <%s> Country IE\n",network->ssid); + ieee80211_extract_country_ie(ieee, info_element, network, beacon->header.addr2); + break; +#endif + + default: + IEEE80211_DEBUG_SCAN("unsupported IE %d\n", + info_element->id); + break; + } + + left -= sizeof(struct ieee80211_info_element_hdr) + + info_element->len; + info_element = (struct ieee80211_info_element *) + &info_element->data[info_element->len]; + } + + network->mode = 0; + if (stats->freq == IEEE80211_52GHZ_BAND) + network->mode = IEEE_A; + else { + if (network->flags & NETWORK_HAS_OFDM) + network->mode |= IEEE_G; + if (network->flags & NETWORK_HAS_CCK) + network->mode |= IEEE_B; + } + + if (network->mode == 0) { + IEEE80211_DEBUG_SCAN("Filtered out '%s (" MAC_FMT ")' " + "network.\n", + escape_essid(network->ssid, + network->ssid_len), + MAC_ARG(network->bssid)); + return 1; + } + + if (ieee80211_is_empty_essid(network->ssid, network->ssid_len)) + network->flags |= NETWORK_EMPTY_ESSID; + +#if 1 + //if(strcmp(network->ssid, "linksys_lzm000") == 0) + // printk("----signalstrength = %d ", stats->signalstrength); + stats->signal = TranslateToDbm8187(stats->signalstrength); + //stats->noise = stats->signal - stats->noise; + stats->noise = TranslateToDbm8187(100 - stats->signalstrength) - 25; +#endif + memcpy(&network->stats, stats, sizeof(network->stats)); + + //YJ,test,080611 + //if(strcmp(network->ssid, "ZyXEL") == 0) + // IEEE_NET_DUMP(network); + + return 0; +} + +static inline int is_same_network(struct ieee80211_network *src, + struct ieee80211_network *dst, + struct ieee80211_device * ieee) +{ + /* A network is only a duplicate if the channel, BSSID, ESSID + * and the capability field (in particular IBSS and BSS) all match. + * We treat all with the same BSSID and channel + * as one network */ + return (((src->ssid_len == dst->ssid_len) || (ieee->iw_mode == IW_MODE_INFRA)) && //YJ,mod,080819,for hidden ap + //((src->ssid_len == dst->ssid_len) && + (src->channel == dst->channel) && + !memcmp(src->bssid, dst->bssid, ETH_ALEN) && + (!memcmp(src->ssid, dst->ssid, src->ssid_len) || (ieee->iw_mode == IW_MODE_INFRA)) && //YJ,mod,080819,for hidden ap + //!memcmp(src->ssid, dst->ssid, src->ssid_len) && + ((src->capability & WLAN_CAPABILITY_IBSS) == + (dst->capability & WLAN_CAPABILITY_IBSS)) && + ((src->capability & WLAN_CAPABILITY_BSS) == + (dst->capability & WLAN_CAPABILITY_BSS))); +} + +inline void update_network(struct ieee80211_network *dst, + struct ieee80211_network *src) +{ + unsigned char quality = src->stats.signalstrength; + unsigned char signal = 0; + unsigned char noise = 0; + if(dst->stats.signalstrength > 0) { + quality = (dst->stats.signalstrength * 5 + src->stats.signalstrength + 5)/6; + } + signal = TranslateToDbm8187(quality); + //noise = signal - src->stats.noise; + if(dst->stats.noise > 0) + noise = (dst->stats.noise * 5 + src->stats.noise)/6; + //if(strcmp(dst->ssid, "linksys_lzm000") == 0) +// printk("ssid:%s, quality:%d, signal:%d\n", dst->ssid, quality, signal); + memcpy(&dst->stats, &src->stats, sizeof(struct ieee80211_rx_stats)); + dst->stats.signalstrength = quality; + dst->stats.signal = signal; + dst->stats.noise = noise; + dst->capability = src->capability; + memcpy(dst->rates, src->rates, src->rates_len); + dst->rates_len = src->rates_len; + memcpy(dst->rates_ex, src->rates_ex, src->rates_ex_len); + dst->rates_ex_len = src->rates_ex_len; + + //YJ,add,080819,for hidden ap + if(src->ssid_len > 0) + { + //if(src->ssid_len == 13) + // printk("=====================>>>>>>>> Dst ssid: %s Src ssid: %s\n", dst->ssid, src->ssid); + memset(dst->ssid, 0, dst->ssid_len); + dst->ssid_len = src->ssid_len; + memcpy(dst->ssid, src->ssid, src->ssid_len); + } + //YJ,add,080819,for hidden ap,end + dst->channel = src->channel; + dst->mode = src->mode; + dst->flags = src->flags; + dst->time_stamp[0] = src->time_stamp[0]; + dst->time_stamp[1] = src->time_stamp[1]; + + dst->beacon_interval = src->beacon_interval; + dst->listen_interval = src->listen_interval; + dst->atim_window = src->atim_window; + dst->dtim_period = src->dtim_period; + dst->dtim_data = src->dtim_data; + dst->last_dtim_sta_time[0] = src->last_dtim_sta_time[0]; + dst->last_dtim_sta_time[1] = src->last_dtim_sta_time[1]; + + memcpy(dst->wpa_ie, src->wpa_ie, src->wpa_ie_len); + dst->wpa_ie_len = src->wpa_ie_len; + memcpy(dst->rsn_ie, src->rsn_ie, src->rsn_ie_len); + dst->rsn_ie_len = src->rsn_ie_len; + + dst->last_scanned = jiffies; + /* dst->last_associate is not overwritten */ +#if 1 + dst->wmm_info = src->wmm_info; //sure to exist in beacon or probe response frame. +/* + if((dst->wmm_info^src->wmm_info)&0x0f) {//Param Set Count change, update Parameter + memcpy(dst->wmm_param, src->wmm_param, IEEE80211_AC_PRAM_LEN); + } +*/ + if(src->wmm_param[0].ac_aci_acm_aifsn|| \ + src->wmm_param[1].ac_aci_acm_aifsn|| \ + src->wmm_param[2].ac_aci_acm_aifsn|| \ + src->wmm_param[1].ac_aci_acm_aifsn) { + memcpy(dst->wmm_param, src->wmm_param, WME_AC_PRAM_LEN); + } + dst->QoS_Enable = src->QoS_Enable; +#else + dst->QoS_Enable = 1;//for Rtl8187 simulation +#endif + dst->SignalStrength = src->SignalStrength; +#ifdef THOMAS_TURBO + dst->Turbo_Enable = src->Turbo_Enable; +#endif +#ifdef ENABLE_DOT11D + dst->CountryIeLen = src->CountryIeLen; + memcpy(dst->CountryIeBuf, src->CountryIeBuf, src->CountryIeLen); +#endif + +} + +inline void ieee80211_process_probe_response( + struct ieee80211_device *ieee, + struct ieee80211_probe_response *beacon, + struct ieee80211_rx_stats *stats) +{ + struct ieee80211_network network; + struct ieee80211_network *target; + struct ieee80211_network *oldest = NULL; +#ifdef CONFIG_IEEE80211_DEBUG + struct ieee80211_info_element *info_element = &beacon->info_element; +#endif + unsigned long flags; + short renew; + u8 wmm_info; + u8 is_beacon = (WLAN_FC_GET_STYPE(beacon->header.frame_ctl) == IEEE80211_STYPE_BEACON)? 1:0; + + memset(&network, 0, sizeof(struct ieee80211_network)); +//rz +#ifdef _RTL8187_EXT_PATCH_ + if((ieee->iw_mode == ieee->iw_ext_mode) && ieee->ext_patch_ieee80211_process_probe_response_1) { + ieee->ext_patch_ieee80211_process_probe_response_1(ieee, beacon, stats); + return; + } +#endif + IEEE80211_DEBUG_SCAN( + "'%s' (" MAC_FMT "): %c%c%c%c %c%c%c%c-%c%c%c%c %c%c%c%c\n", + escape_essid(info_element->data, info_element->len), + MAC_ARG(beacon->header.addr3), + (beacon->capability & (1<<0xf)) ? '1' : '0', + (beacon->capability & (1<<0xe)) ? '1' : '0', + (beacon->capability & (1<<0xd)) ? '1' : '0', + (beacon->capability & (1<<0xc)) ? '1' : '0', + (beacon->capability & (1<<0xb)) ? '1' : '0', + (beacon->capability & (1<<0xa)) ? '1' : '0', + (beacon->capability & (1<<0x9)) ? '1' : '0', + (beacon->capability & (1<<0x8)) ? '1' : '0', + (beacon->capability & (1<<0x7)) ? '1' : '0', + (beacon->capability & (1<<0x6)) ? '1' : '0', + (beacon->capability & (1<<0x5)) ? '1' : '0', + (beacon->capability & (1<<0x4)) ? '1' : '0', + (beacon->capability & (1<<0x3)) ? '1' : '0', + (beacon->capability & (1<<0x2)) ? '1' : '0', + (beacon->capability & (1<<0x1)) ? '1' : '0', + (beacon->capability & (1<<0x0)) ? '1' : '0'); + + if (ieee80211_network_init(ieee, beacon, &network, stats)) { + IEEE80211_DEBUG_SCAN("Dropped '%s' (" MAC_FMT ") via %s.\n", + escape_essid(info_element->data, + info_element->len), + MAC_ARG(beacon->header.addr3), + WLAN_FC_GET_STYPE(beacon->header.frame_ctl) == + IEEE80211_STYPE_PROBE_RESP ? + "PROBE RESPONSE" : "BEACON"); + return; + } + +#ifdef ENABLE_DOT11D + // For Asus EeePc request, + // (1) if wireless adapter receive get any 802.11d country code in AP beacon, + // wireless adapter should follow the country code. + // (2) If there is no any country code in beacon, + // then wireless adapter should do active scan from ch1~11 and + // passive scan from ch12~14 + if(ieee->bGlobalDomain) + { + if (WLAN_FC_GET_STYPE(beacon->header.frame_ctl) == IEEE80211_STYPE_PROBE_RESP) + { + // Case 1: Country code + if(IS_COUNTRY_IE_VALID(ieee) ) + { + if( !IsLegalChannel(ieee, network.channel) ) + { + printk("GetScanInfo(): For Country code, filter probe response at channel(%d).\n", network.channel); + return; + } + } + // Case 2: No any country code. + else + { + // Filter over channel ch12~14 + if(network.channel > 11) + { + printk("GetScanInfo(): For Global Domain, filter probe response at channel(%d).\n", network.channel); + return; + } + } + } + else + { + // Case 1: Country code + if(IS_COUNTRY_IE_VALID(ieee) ) + { + if( !IsLegalChannel(ieee, network.channel) ) + { + printk("GetScanInfo(): For Country code, filter beacon at channel(%d).\n",network.channel); + return; + } + } + // Case 2: No any country code. + else + { + // Filter over channel ch12~14 + if(network.channel > 14) + { + printk("GetScanInfo(): For Global Domain, filter beacon at channel(%d).\n",network.channel); + return; + } + } + } + } + + //lzm add 081205 + // for Toshiba request, we use channel_plan COUNTRY_CODE_WORLD_WIDE_13_INDEX, + // For Liteon "World Wide 13" Domain name:ch1~11 active scan & ch12~13 passive scan + // So we shoud only rcv beacon in 12-13, and filter probe resp in 12-13. + if(ieee->MinPassiveChnlNum != MAX_CHANNEL_NUMBER+1) + { + if (WLAN_FC_GET_STYPE(beacon->header.frame_ctl) == IEEE80211_STYPE_PROBE_RESP) + { + // Filter over channel ch12~13 + if(network.channel >= ieee->MinPassiveChnlNum) + { + printk("GetScanInfo(): passive scan, filter probe resp at channel(%d).\n", network.channel); + return; + } + } + } +#endif + + + /* The network parsed correctly -- so now we scan our known networks + * to see if we can find it in our list. + * + * NOTE: This search is definitely not optimized. Once its doing + * the "right thing" we'll optimize it for efficiency if + * necessary */ + + /* Search for this entry in the list and update it if it is + * already there. */ + + spin_lock_irqsave(&ieee->lock, flags); + + if(is_same_network(&ieee->current_network, &network, ieee)) { + //YJ,add,080819,for hidden ap + if(is_beacon == 0) + network.flags = (~NETWORK_EMPTY_ESSID & network.flags)|(NETWORK_EMPTY_ESSID & ieee->current_network.flags); + if ((ieee->state == IEEE80211_LINKED) && is_beacon) + ieee->NumRxBcnInPeriod++; + wmm_info = ieee->current_network.wmm_info; + update_network(&ieee->current_network, &network); + } + + list_for_each_entry(target, &ieee->network_list, list) { + if (is_same_network(target, &network, ieee)) + break; + if ((oldest == NULL) || + (target->last_scanned < oldest->last_scanned)) + oldest = target; + } + + /* If we didn't find a match, then get a new network slot to initialize + * with this beacon's information */ + if (&target->list == &ieee->network_list) { + if (list_empty(&ieee->network_free_list)) { + /* If there are no more slots, expire the oldest */ + list_del(&oldest->list); + target = oldest; + IEEE80211_DEBUG_SCAN("Expired '%s' (" MAC_FMT ") from " + "network list.\n", + escape_essid(target->ssid, + target->ssid_len), + MAC_ARG(target->bssid)); + } else { + /* Otherwise just pull from the free list */ + target = list_entry(ieee->network_free_list.next, + struct ieee80211_network, list); + list_del(ieee->network_free_list.next); + } + + +#ifdef CONFIG_IEEE80211_DEBUG + IEEE80211_DEBUG_SCAN("Adding '%s' (" MAC_FMT ") via %s.\n", + escape_essid(network.ssid, + network.ssid_len), + MAC_ARG(network.bssid), + WLAN_FC_GET_STYPE(beacon->header.frame_ctl) == + IEEE80211_STYPE_PROBE_RESP ? + "PROBE RESPONSE" : "BEACON"); +#endif + +#ifdef _RTL8187_EXT_PATCH_ + network.ext_entry = target->ext_entry; +#endif + memcpy(target, &network, sizeof(*target)); + list_add_tail(&target->list, &ieee->network_list); + if(ieee->softmac_features & IEEE_SOFTMAC_ASSOCIATE) + ieee80211_softmac_new_net(ieee,&network); + } else { + IEEE80211_DEBUG_SCAN("Updating '%s' (" MAC_FMT ") via %s.\n", + escape_essid(target->ssid, + target->ssid_len), + MAC_ARG(target->bssid), + WLAN_FC_GET_STYPE(beacon->header.frame_ctl) == + IEEE80211_STYPE_PROBE_RESP ? + "PROBE RESPONSE" : "BEACON"); + + /* we have an entry and we are going to update it. But this entry may + * be already expired. In this case we do the same as we found a new + * net and call the new_net handler + */ + renew = !time_after(target->last_scanned + ieee->scan_age, jiffies); + //YJ,add,080819,for hidden ap + if(is_beacon == 0) + network.flags = (~NETWORK_EMPTY_ESSID & network.flags)|(NETWORK_EMPTY_ESSID & target->flags); + //if(strncmp(network.ssid, "linksys-c",9) == 0) + // printk("====>2 network.ssid=%s FLAG=%d target.ssid=%s FLAG=%d\n", network.ssid, network.flags, target->ssid, target->flags); + if(((network.flags & NETWORK_EMPTY_ESSID) == NETWORK_EMPTY_ESSID) \ + && (((network.ssid_len > 0) && (strncmp(target->ssid, network.ssid, network.ssid_len)))\ + ||((ieee->current_network.ssid_len == network.ssid_len)&&(strncmp(ieee->current_network.ssid, network.ssid, network.ssid_len) == 0)&&(ieee->state == IEEE80211_NOLINK)))) + renew = 1; + //YJ,add,080819,for hidden ap,end + update_network(target, &network); + if(renew && (ieee->softmac_features & IEEE_SOFTMAC_ASSOCIATE)) + ieee80211_softmac_new_net(ieee,&network); + } + + spin_unlock_irqrestore(&ieee->lock, flags); +} + +void ieee80211_rx_mgt(struct ieee80211_device *ieee, + struct ieee80211_hdr *header, + struct ieee80211_rx_stats *stats) +{ + switch (WLAN_FC_GET_STYPE(header->frame_ctl)) { + + case IEEE80211_STYPE_BEACON: + IEEE80211_DEBUG_MGMT("received BEACON (%d)\n", + WLAN_FC_GET_STYPE(header->frame_ctl)); + IEEE80211_DEBUG_SCAN("Beacon\n"); + ieee80211_process_probe_response( + ieee, (struct ieee80211_probe_response *)header, stats); + break; + + case IEEE80211_STYPE_PROBE_RESP: + IEEE80211_DEBUG_MGMT("received PROBE RESPONSE (%d)\n", + WLAN_FC_GET_STYPE(header->frame_ctl)); + IEEE80211_DEBUG_SCAN("Probe response\n"); + ieee80211_process_probe_response( + ieee, (struct ieee80211_probe_response *)header, stats); + break; +//rz +#ifdef _RTL8187_EXT_PATCH_ + case IEEE80211_STYPE_PROBE_REQ: + IEEE80211_DEBUG_MGMT("received PROBE REQUEST (%d)\n", + WLAN_FC_GET_STYPE(header->frame_ctl)); + IEEE80211_DEBUG_SCAN("Probe request\n"); + /// + //printk("Probe request\n"); + if( ieee->iw_mode == ieee->iw_ext_mode && ieee->ext_patch_ieee80211_rx_mgt_on_probe_req ) + ieee->ext_patch_ieee80211_rx_mgt_on_probe_req( ieee, (struct ieee80211_probe_request *)header, stats); + break; +#endif // _RTL8187_EXT_PATCH_ + + } +} + +#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)) +EXPORT_SYMBOL(ieee80211_rx_mgt); +EXPORT_SYMBOL(ieee80211_rx); +EXPORT_SYMBOL(ieee80211_network_init); +#ifdef _RTL8187_EXT_PATCH_ +EXPORT_SYMBOL(ieee_ext_skb_p80211_to_ether); +#endif +#else +EXPORT_SYMBOL_NOVERS(ieee80211_rx_mgt); +EXPORT_SYMBOL_NOVERS(ieee80211_rx); +EXPORT_SYMBOL_NOVERS(ieee80211_network_init); +#ifdef _RTL8187_EXT_PATCH_ +EXPORT_SYMBOL_NOVERS(ieee_ext_skb_p80211_to_ether); +#endif +#endif diff -Nur linux-2.6.30.5.orig/drivers/net/wireless/rtl8187b/ieee80211/ieee80211_softmac.c linux-2.6.30.5/drivers/net/wireless/rtl8187b/ieee80211/ieee80211_softmac.c --- linux-2.6.30.5.orig/drivers/net/wireless/rtl8187b/ieee80211/ieee80211_softmac.c 1970-01-01 01:00:00.000000000 +0100 +++ linux-2.6.30.5/drivers/net/wireless/rtl8187b/ieee80211/ieee80211_softmac.c 2009-08-23 19:01:04.000000000 +0200 @@ -0,0 +1,4083 @@ +/* IEEE 802.11 SoftMAC layer + * Copyright (c) 2005 Andrea Merello + * + * Mostly extracted from the rtl8180-sa2400 driver for the + * in-kernel generic ieee802.11 stack. + * + * Few lines might be stolen from other part of the ieee80211 + * stack. Copyright who own it's copyright + * + * WPA code stolen from the ipw2200 driver. + * Copyright who own it's copyright. + * + * released under the GPL + */ + + +#include "ieee80211.h" + +#include +#include +#include +#include + +#ifdef ENABLE_DOT11D +#include "dot11d.h" +#endif + + +u8 rsn_authen_cipher_suite[16][4] = { + {0x00,0x0F,0xAC,0x00}, //Use group key, //Reserved + {0x00,0x0F,0xAC,0x01}, //WEP-40 //RSNA default + {0x00,0x0F,0xAC,0x02}, //TKIP //NONE //{used just as default} + {0x00,0x0F,0xAC,0x03}, //WRAP-historical + {0x00,0x0F,0xAC,0x04}, //CCMP + {0x00,0x0F,0xAC,0x05}, //WEP-104 +}; + +short ieee80211_is_54g(struct ieee80211_network net) +{ + return ((net.rates_ex_len > 0) || (net.rates_len > 4)); +} + +short ieee80211_is_shortslot(struct ieee80211_network net) +{ + return (net.capability & WLAN_CAPABILITY_SHORT_SLOT); +} + +/* returns the total length needed for pleacing the RATE MFIE + * tag and the EXTENDED RATE MFIE tag if needed. + * It encludes two bytes per tag for the tag itself and its len + */ +unsigned int ieee80211_MFIE_rate_len(struct ieee80211_device *ieee) +{ + unsigned int rate_len = 0; + + if (ieee->modulation & IEEE80211_CCK_MODULATION) + rate_len = IEEE80211_CCK_RATE_LEN + 2; + + if (ieee->modulation & IEEE80211_OFDM_MODULATION) + + rate_len += IEEE80211_OFDM_RATE_LEN + 2; + + return rate_len; +} + +/* pleace the MFIE rate, tag to the memory (double) poined. + * Then it updates the pointer so that + * it points after the new MFIE tag added. + */ +void ieee80211_MFIE_Brate(struct ieee80211_device *ieee, u8 **tag_p) +{ + u8 *tag = *tag_p; + + if (ieee->modulation & IEEE80211_CCK_MODULATION){ + *tag++ = MFIE_TYPE_RATES; + *tag++ = 7; + *tag++ = IEEE80211_BASIC_RATE_MASK | IEEE80211_CCK_RATE_1MB; + *tag++ = IEEE80211_BASIC_RATE_MASK | IEEE80211_CCK_RATE_2MB; + *tag++ = IEEE80211_BASIC_RATE_MASK | IEEE80211_CCK_RATE_5MB; + *tag++ = IEEE80211_BASIC_RATE_MASK | IEEE80211_CCK_RATE_11MB; + //added for basic rate set + *tag++ = IEEE80211_BASIC_RATE_MASK | IEEE80211_OFDM_RATE_6MB; + *tag++ = IEEE80211_BASIC_RATE_MASK | IEEE80211_OFDM_RATE_12MB; + *tag++ = IEEE80211_BASIC_RATE_MASK | IEEE80211_OFDM_RATE_24MB; + } + + /* We may add an option for custom rates that specific HW might support */ + *tag_p = tag; +} + +void ieee80211_MFIE_Grate(struct ieee80211_device *ieee, u8 **tag_p) +{ + u8 *tag = *tag_p; + + if (ieee->modulation & IEEE80211_OFDM_MODULATION){ + + *tag++ = MFIE_TYPE_RATES_EX; + *tag++ = 5; + *tag++ = IEEE80211_OFDM_RATE_9MB; + *tag++ = IEEE80211_OFDM_RATE_18MB; + *tag++ = IEEE80211_OFDM_RATE_36MB; + *tag++ = IEEE80211_OFDM_RATE_48MB; + *tag++ = IEEE80211_OFDM_RATE_54MB; + + } + + /* We may add an option for custom rates that specific HW might support */ + *tag_p = tag; +} + + +void ieee80211_WMM_Info(struct ieee80211_device *ieee, u8 **tag_p) { + u8 *tag = *tag_p; + + *tag++ = MFIE_TYPE_GENERIC; //0 + *tag++ = 7; + *tag++ = 0x00; + *tag++ = 0x50; + *tag++ = 0xf2; + *tag++ = 0x02;//5 + *tag++ = 0x00; + *tag++ = 0x01; +#ifdef SUPPORT_USPD + if(ieee->current_network.wmm_info & 0x80) { + *tag++ = 0x0f|MAX_SP_Len; + } else { + *tag++ = MAX_SP_Len; + } +#else + *tag++ = MAX_SP_Len; +#endif + *tag_p = tag; +} + +#ifdef THOMAS_TURBO +void ieee80211_TURBO_Info(struct ieee80211_device *ieee, u8 **tag_p) { + u8 *tag = *tag_p; + + *tag++ = MFIE_TYPE_GENERIC; //0 + *tag++ = 7; + *tag++ = 0x00; + *tag++ = 0xe0; + *tag++ = 0x4c; + *tag++ = 0x01;//5 + *tag++ = 0x02; + *tag++ = 0x11; + *tag++ = 0x00; + + *tag_p = tag; + printk(KERN_ALERT "This is enable turbo mode IE process\n"); +} +#endif + +void enqueue_mgmt(struct ieee80211_device *ieee, struct sk_buff *skb) +{ + int nh; + nh = (ieee->mgmt_queue_head +1) % MGMT_QUEUE_NUM; + +/* + * if the queue is full but we have newer frames then + * just overwrites the oldest. + * + * if (nh == ieee->mgmt_queue_tail) + * return -1; + */ + ieee->mgmt_queue_head = nh; + ieee->mgmt_queue_ring[nh] = skb; + + //return 0; +} + +struct sk_buff *dequeue_mgmt(struct ieee80211_device *ieee) +{ + struct sk_buff *ret; + + if(ieee->mgmt_queue_tail == ieee->mgmt_queue_head) + return NULL; + + ret = ieee->mgmt_queue_ring[ieee->mgmt_queue_tail]; + + ieee->mgmt_queue_tail = + (ieee->mgmt_queue_tail+1) % MGMT_QUEUE_NUM; + + return ret; +} + +void init_mgmt_queue(struct ieee80211_device *ieee) +{ + ieee->mgmt_queue_tail = ieee->mgmt_queue_head = 0; +} + + +void ieee80211_sta_wakeup(struct ieee80211_device *ieee, short nl); + +inline void softmac_mgmt_xmit(struct sk_buff *skb, struct ieee80211_device *ieee) +{ + unsigned long flags; + short single = ieee->softmac_features & IEEE_SOFTMAC_SINGLE_QUEUE; + struct ieee80211_hdr_3addr *header= + (struct ieee80211_hdr_3addr *) skb->data; + + + spin_lock_irqsave(&ieee->lock, flags); + + /* called with 2nd param 0, no mgmt lock required */ + ieee80211_sta_wakeup(ieee,0); + + if(single){ + if(ieee->queue_stop){ + + enqueue_mgmt(ieee,skb); + }else{ + header->seq_ctl = cpu_to_le16(ieee->seq_ctrl[0]<<4); + + if (ieee->seq_ctrl[0] == 0xFFF) + ieee->seq_ctrl[0] = 0; + else + ieee->seq_ctrl[0]++; + + /* avoid watchdog triggers */ + ieee->dev->trans_start = jiffies; + ieee->softmac_data_hard_start_xmit(skb,ieee->dev,ieee->basic_rate); +#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,0) +// dev_kfree_skb_any(skb);//edit by thomas //'cause this function will cause Oops called in interrupt context in old version 101907 +#endif + } + + spin_unlock_irqrestore(&ieee->lock, flags); + }else{ + spin_unlock_irqrestore(&ieee->lock, flags); + spin_lock_irqsave(&ieee->mgmt_tx_lock, flags); + + header->seq_ctl = cpu_to_le16(ieee->seq_ctrl[0] << 4); + + if (ieee->seq_ctrl[0] == 0xFFF) + ieee->seq_ctrl[0] = 0; + else + ieee->seq_ctrl[0]++; + + ieee->softmac_hard_start_xmit(skb,ieee->dev); +#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,0) +// dev_kfree_skb_any(skb);//edit by thomas +#endif + spin_unlock_irqrestore(&ieee->mgmt_tx_lock, flags); + } +} + + +inline void softmac_ps_mgmt_xmit(struct sk_buff *skb, struct ieee80211_device *ieee) +{ + + short single = ieee->softmac_features & IEEE_SOFTMAC_SINGLE_QUEUE; + struct ieee80211_hdr_3addr *header = + (struct ieee80211_hdr_3addr *) skb->data; + + + if(single){ + + header->seq_ctl = cpu_to_le16(ieee->seq_ctrl[0] << 4); + + if (ieee->seq_ctrl[0] == 0xFFF) + ieee->seq_ctrl[0] = 0; + else + ieee->seq_ctrl[0]++; + + /* avoid watchdog triggers */ + ieee->dev->trans_start = jiffies; + ieee->softmac_data_hard_start_xmit(skb,ieee->dev,ieee->basic_rate); + + }else{ + + header->seq_ctl = cpu_to_le16(ieee->seq_ctrl[0] << 4); + + if (ieee->seq_ctrl[0] == 0xFFF) + ieee->seq_ctrl[0] = 0; + else + ieee->seq_ctrl[0]++; + + ieee->softmac_hard_start_xmit(skb,ieee->dev); + + } + dev_kfree_skb_any(skb);//edit by thomas +} + +inline struct sk_buff *ieee80211_probe_req(struct ieee80211_device *ieee) +{ + unsigned int len,rate_len; + u8 *tag; + struct sk_buff *skb; + struct ieee80211_probe_request *req; + +#ifdef _RTL8187_EXT_PATCH_ + short extMore = 0; + if(ieee->ext_patch_ieee80211_probe_req_1) + extMore = ieee->ext_patch_ieee80211_probe_req_1(ieee); +#endif + + len = ieee->current_network.ssid_len; + + rate_len = ieee80211_MFIE_rate_len(ieee); + +#ifdef _RTL8187_EXT_PATCH_ + if(!extMore) +#endif + skb = dev_alloc_skb(sizeof(struct ieee80211_probe_request) + + 2 + len + rate_len); +#ifdef _RTL8187_EXT_PATCH_ + else + skb = dev_alloc_skb(sizeof(struct ieee80211_probe_request) + + 2 + len + rate_len+128); // MESHID + CAP +#endif + + if (!skb) + return NULL; + + req = (struct ieee80211_probe_request *) skb_put(skb,sizeof(struct ieee80211_probe_request)); + req->header.frame_ctl = cpu_to_le16(IEEE80211_STYPE_PROBE_REQ); + req->header.duration_id = 0; //FIXME: is this OK ? + + memset(req->header.addr1, 0xff, ETH_ALEN); + memcpy(req->header.addr2, ieee->dev->dev_addr, ETH_ALEN); + memset(req->header.addr3, 0xff, ETH_ALEN); + + tag = (u8 *) skb_put(skb,len+2+rate_len); + + *tag++ = MFIE_TYPE_SSID; + *tag++ = len; + memcpy(tag, ieee->current_network.ssid, len); + tag += len; + + ieee80211_MFIE_Brate(ieee,&tag); + ieee80211_MFIE_Grate(ieee,&tag); + +#ifdef _RTL8187_EXT_PATCH_ + if(extMore) + ieee->ext_patch_ieee80211_probe_req_2(ieee, skb, tag); +#endif + return skb; +} + +struct sk_buff *ieee80211_get_beacon_(struct ieee80211_device *ieee); + +#ifdef _RTL8187_EXT_PATCH_ +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20) +void ext_ieee80211_send_beacon_wq(struct work_struct *work) +{ + struct ieee80211_device *ieee = container_of(work, struct ieee80211_device, ext_send_beacon_wq); +#else +void ext_ieee80211_send_beacon_wq(struct ieee80211_device *ieee) +{ +#endif + + struct sk_buff *skb; + + //unsigned long flags; +// printk("=========>%s()\n", __FUNCTION__); + skb = ieee80211_get_beacon_(ieee); + + if (skb){ + softmac_mgmt_xmit(skb, ieee); + ieee->softmac_stats.tx_beacons++; + dev_kfree_skb_any(skb);//edit by thomas + } + + + //printk(KERN_WARNING "[1] beacon sending!\n"); +// ieee->beacon_timer.expires = jiffies + +// (MSECS( ieee->current_network.beacon_interval -5)); + + //spin_lock_irqsave(&ieee->beacon_lock,flags); +// if(ieee->beacon_txing) +// add_timer(&ieee->beacon_timer); + //spin_unlock_irqrestore(&ieee->beacon_lock,flags); +} +#endif + +void ieee80211_send_beacon(struct ieee80211_device *ieee) +{ + struct sk_buff *skb; + + //unsigned long flags; +// printk("=========>%s()\n", __FUNCTION__); + skb = ieee80211_get_beacon_(ieee); + + if (skb){ + softmac_mgmt_xmit(skb, ieee); + ieee->softmac_stats.tx_beacons++; + dev_kfree_skb_any(skb);//edit by thomas + } + + + //printk(KERN_WARNING "[1] beacon sending!\n"); + ieee->beacon_timer.expires = jiffies + + (MSECS( ieee->current_network.beacon_interval -5)); + + //spin_lock_irqsave(&ieee->beacon_lock,flags); + if(ieee->beacon_txing) + add_timer(&ieee->beacon_timer); + //spin_unlock_irqrestore(&ieee->beacon_lock,flags); +} + + +void ieee80211_send_beacon_cb(unsigned long _ieee) +{ + struct ieee80211_device *ieee = + (struct ieee80211_device *) _ieee; + unsigned long flags; + + spin_lock_irqsave(&ieee->beacon_lock, flags); + ieee80211_send_beacon(ieee); + spin_unlock_irqrestore(&ieee->beacon_lock, flags); +} + +#ifdef _RTL8187_EXT_PATCH_ + +inline struct sk_buff *ieee80211_probe_req_with_SSID(struct ieee80211_device *ieee, char *ssid, int len_ssid) +{ + unsigned int len,rate_len; + u8 *tag; + struct sk_buff *skb; + struct ieee80211_probe_request *req; + +#ifdef _RTL8187_EXT_PATCH_ + short extMore = 0; + if(ieee->ext_patch_ieee80211_probe_req_1) + extMore = ieee->ext_patch_ieee80211_probe_req_1(ieee); +#endif + + len = len_ssid; + + rate_len = ieee80211_MFIE_rate_len(ieee); + +#ifdef _RTL8187_EXT_PATCH_ + if(!extMore) +#endif + skb = dev_alloc_skb(sizeof(struct ieee80211_probe_request) + + 2 + len + rate_len); +#ifdef _RTL8187_EXT_PATCH_ + else + skb = dev_alloc_skb(sizeof(struct ieee80211_probe_request) + + 2 + len + rate_len+128); // MESHID + CAP +#endif + + if (!skb) + return NULL; + + req = (struct ieee80211_probe_request *) skb_put(skb,sizeof(struct ieee80211_probe_request)); + req->header.frame_ctl = cpu_to_le16(IEEE80211_STYPE_PROBE_REQ); + req->header.duration_id = 0; //FIXME: is this OK ? + + memset(req->header.addr1, 0xff, ETH_ALEN); + memcpy(req->header.addr2, ieee->dev->dev_addr, ETH_ALEN); + memset(req->header.addr3, 0xff, ETH_ALEN); + + tag = (u8 *) skb_put(skb,len+2+rate_len); + + *tag++ = MFIE_TYPE_SSID; + *tag++ = len; + if(len) + { + memcpy(tag, ssid, len); + tag += len; + } + + ieee80211_MFIE_Brate(ieee,&tag); + ieee80211_MFIE_Grate(ieee,&tag); + +#ifdef _RTL8187_EXT_PATCH_ + if(extMore) + ieee->ext_patch_ieee80211_probe_req_2(ieee, skb, tag); +#endif + return skb; +} + +#endif // _RTL8187_EXT_PATCH_ + + +void ieee80211_send_probe(struct ieee80211_device *ieee) +{ + struct sk_buff *skb; + +#ifdef _RTL8187_EXT_PATCH_ + if(ieee->iw_mode == ieee->iw_ext_mode) + skb = ieee80211_probe_req_with_SSID(ieee, NULL, 0); + else +#endif + skb = ieee80211_probe_req(ieee); + if (skb){ + softmac_mgmt_xmit(skb, ieee); + ieee->softmac_stats.tx_probe_rq++; + dev_kfree_skb_any(skb);//edit by thomas + } +} + +void ieee80211_send_probe_requests(struct ieee80211_device *ieee) +{ + if (ieee->active_scan && (ieee->softmac_features & IEEE_SOFTMAC_PROBERQ)){ + ieee80211_send_probe(ieee); + ieee80211_send_probe(ieee); + } +} + +/* this performs syncro scan blocking the caller until all channels + * in the allowed channel map has been checked. + */ +void ieee80211_softmac_scan_syncro(struct ieee80211_device *ieee) +{ + short ch = 0; +#ifdef ENABLE_DOT11D + u8 channel_map[MAX_CHANNEL_NUMBER+1]; + memcpy(channel_map, GET_DOT11D_INFO(ieee)->channel_map, MAX_CHANNEL_NUMBER+1); +#endif + + + down(&ieee->scan_sem); + + while(1) + { + + do{ + ch++; + if (ch > MAX_CHANNEL_NUMBER) + goto out; /* scan completed */ + +#ifdef ENABLE_DOT11D + }while(!channel_map[ch]); +#else + }while(!ieee->channel_map[ch]); +#endif + + //printk("=>current channel is %d\n",ch); + + /* this fuction can be called in two situations + * 1- We have switched to ad-hoc mode and we are + * performing a complete syncro scan before conclude + * there are no interesting cell and to create a + * new one. In this case the link state is + * IEEE80211_NOLINK until we found an interesting cell. + * If so the ieee8021_new_net, called by the RX path + * will set the state to IEEE80211_LINKED, so we stop + * scanning + * 2- We are linked and the root uses run iwlist scan. + * So we switch to IEEE80211_LINKED_SCANNING to remember + * that we are still logically linked (not interested in + * new network events, despite for updating the net list, + * but we are temporarly 'unlinked' as the driver shall + * not filter RX frames and the channel is changing. + * So the only situation in witch are interested is to check + * if the state become LINKED because of the #1 situation + */ + + if (ieee->state == IEEE80211_LINKED) + goto out; + + //printk("---->%s: chan %d\n", __func__, ch); + ieee->set_chan(ieee->dev, ch); +#ifdef ENABLE_DOT11D + if(channel_map[ch] == 1) +#endif + { + ieee80211_send_probe_requests(ieee); + } + + /* this prevent excessive time wait when we + * need to wait for a syncro scan to end.. + */ + if (ieee->sync_scan_hurryup) + goto out; + + + msleep_interruptible_rtl(IEEE80211_SOFTMAC_SCAN_TIME); + + } +out: + ieee->sync_scan_hurryup = 0; + up(&ieee->scan_sem); +#ifdef ENABLE_DOT11D + if(IS_DOT11D_ENABLE(ieee)) + DOT11D_ScanComplete(ieee); +#endif + +} + +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) +/* called both by wq with ieee->lock held */ +void ieee80211_softmac_scan(struct ieee80211_device *ieee) +{ +#if 0 + short watchdog = 0; + do{ + ieee->current_network.channel = + (ieee->current_network.channel + 1) % MAX_CHANNEL_NUMBER; + if (watchdog++ > MAX_CHANNEL_NUMBER) + return; /* no good chans */ + + }while(!ieee->channel_map[ieee->current_network.channel]); +#endif + + schedule_task(&ieee->softmac_scan_wq); +} +#endif + +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)) +void ieee80211_softmac_scan_wq(struct work_struct *work) +{ + struct delayed_work *dwork = container_of(work, struct delayed_work, work); + struct ieee80211_device *ieee = container_of(dwork, struct ieee80211_device, softmac_scan_wq); +#else +void ieee80211_softmac_scan_wq(struct ieee80211_device *ieee) +{ +#endif + //static short watchdog = 0; + //short watchdog = 0;//lzm move into ieee->scan_watchdog 081215 for roaming + u8 channel_bak = ieee->current_network.channel;//lzm for channel+1 +#ifdef ENABLE_DOT11D + u8 channel_map[MAX_CHANNEL_NUMBER+1]; + memcpy(channel_map, GET_DOT11D_INFO(ieee)->channel_map, MAX_CHANNEL_NUMBER+1); +#endif + down(&ieee->scan_sem); + + do{ + ieee->current_network.channel = + (ieee->current_network.channel + 1) % MAX_CHANNEL_NUMBER; + if (ieee->scan_watchdog++ > MAX_CHANNEL_NUMBER) + goto out; /* no good chans */ +#ifdef ENABLE_DOT11D + }while(!channel_map[ieee->current_network.channel]); +#else + }while(!ieee->channel_map[ieee->current_network.channel]); +#endif + + if (ieee->scanning == 0 ) + goto out; + + //printk("current channel is %d\n",ieee->current_network.channel); + ieee->set_chan(ieee->dev, ieee->current_network.channel); +#ifdef ENABLE_DOT11D + if(channel_map[ieee->current_network.channel] == 1) +#endif + { + ieee80211_send_probe_requests(ieee); + } + + +#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0) + queue_delayed_work(ieee->wq, &ieee->softmac_scan_wq, IEEE80211_SOFTMAC_SCAN_TIME); +#else + ieee->scan_timer.expires = jiffies + (IEEE80211_SOFTMAC_SCAN_TIME); + if (ieee->scanning == 1) + add_timer(&ieee->scan_timer); +#endif + + up(&ieee->scan_sem); + return; +out: + //printk("%s():Stop scan now\n",__FUNCTION__); + ieee->actscanning = false; + ieee->scan_watchdog = 0; + ieee->scanning = 0; + ieee->current_network.channel = channel_bak; + up(&ieee->scan_sem); +#ifdef ENABLE_DOT11D + if(IS_DOT11D_ENABLE(ieee)) + DOT11D_ScanComplete(ieee); +#endif + + return; +} + +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) +void ieee80211_softmac_scan_cb(unsigned long _dev) +{ + unsigned long flags; + struct ieee80211_device *ieee = (struct ieee80211_device *)_dev; + + spin_lock_irqsave(&ieee->lock, flags); + ieee80211_softmac_scan(ieee); + spin_unlock_irqrestore(&ieee->lock, flags); +} +#endif + + +void ieee80211_beacons_start(struct ieee80211_device *ieee) +{ + unsigned long flags; + + spin_lock_irqsave(&ieee->beacon_lock,flags); + + ieee->beacon_txing = 1; + ieee80211_send_beacon(ieee); + + spin_unlock_irqrestore(&ieee->beacon_lock,flags); +} + +void ieee80211_beacons_stop(struct ieee80211_device *ieee) +{ + unsigned long flags; + + spin_lock_irqsave(&ieee->beacon_lock,flags); + + ieee->beacon_txing = 0; + del_timer_sync(&ieee->beacon_timer); + + spin_unlock_irqrestore(&ieee->beacon_lock,flags); + +} + + +void ieee80211_stop_send_beacons(struct ieee80211_device *ieee) +{ + if(ieee->stop_send_beacons) + ieee->stop_send_beacons(ieee->dev); + if (ieee->softmac_features & IEEE_SOFTMAC_BEACONS) + ieee80211_beacons_stop(ieee); +} + + +void ieee80211_start_send_beacons(struct ieee80211_device *ieee) +{ + if(ieee->start_send_beacons) + ieee->start_send_beacons(ieee->dev); + if(ieee->softmac_features & IEEE_SOFTMAC_BEACONS) + ieee80211_beacons_start(ieee); +} + + +void ieee80211_softmac_stop_scan(struct ieee80211_device *ieee) +{ +// unsigned long flags; + + ieee->sync_scan_hurryup = 1; + + down(&ieee->scan_sem); +// spin_lock_irqsave(&ieee->lock, flags); + + if (ieee->scanning == 1){ + //printk("%s():Stop scan now\n",__FUNCTION__); + ieee->scanning = 0; + //lzm add for softmac_scan_wq can't return from out + //example: rcv probe_response + ieee->scan_watchdog = 0;//lzm add 081215 for roaming + ieee->actscanning = false; + +#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0) + cancel_delayed_work(&ieee->softmac_scan_wq); +#else + del_timer_sync(&ieee->scan_timer); +#endif + } + +// spin_unlock_irqrestore(&ieee->lock, flags); + up(&ieee->scan_sem); +} + +void ieee80211_stop_scan(struct ieee80211_device *ieee) +{ + if (ieee->softmac_features & IEEE_SOFTMAC_SCAN) + ieee80211_softmac_stop_scan(ieee); + else + ieee->stop_scan(ieee->dev); +} + +/* called with ieee->lock held */ +void ieee80211_start_scan(struct ieee80211_device *ieee) +{ + ieee->actscanning = true; +#ifdef CONFIG_IPS + ieee->ieee80211_ips_leave(ieee->dev); +#endif + +#ifdef ENABLE_DOT11D + if(IS_DOT11D_ENABLE(ieee) ) + { + if(IS_COUNTRY_IE_VALID(ieee)) + { + RESET_CIE_WATCHDOG(ieee); + } + } +#endif + + if (ieee->softmac_features & IEEE_SOFTMAC_SCAN){ + if (ieee->scanning == 0){ + ieee->scanning = 1; +#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0) + queue_delayed_work(ieee->wq, &ieee->softmac_scan_wq,0); +#else + ieee80211_softmac_scan(ieee); +#endif + } + }else + ieee->start_scan(ieee->dev); + +} + +/* called with wx_sem held */ +void ieee80211_start_scan_syncro(struct ieee80211_device *ieee) +{ + //printk("====>%s()\n", __func__); +#ifdef CONFIG_IPS + ieee->ieee80211_ips_leave(ieee->dev); +#endif + ieee->actscanning = true; + +#ifdef ENABLE_DOT11D + if(IS_DOT11D_ENABLE(ieee) ) + { + if(IS_COUNTRY_IE_VALID(ieee)) + { + RESET_CIE_WATCHDOG(ieee); + } + } +#endif + + ieee->sync_scan_hurryup = 0; + + if (ieee->softmac_features & IEEE_SOFTMAC_SCAN) + ieee80211_softmac_scan_syncro(ieee); + else + ieee->scan_syncro(ieee->dev); + + ieee->actscanning = false; + //printk("<====%s()\n", __func__); +} + +inline struct sk_buff *ieee80211_authentication_req(struct ieee80211_network *beacon, + struct ieee80211_device *ieee, int challengelen) +{ + struct sk_buff *skb; + struct ieee80211_authentication *auth; + + skb = dev_alloc_skb(sizeof(struct ieee80211_authentication) + challengelen); + + if (!skb) return NULL; + + auth = (struct ieee80211_authentication *) + skb_put(skb, sizeof(struct ieee80211_authentication)); + + auth->header.frame_ctl = IEEE80211_STYPE_AUTH; + if (challengelen) auth->header.frame_ctl |= IEEE80211_FCTL_WEP; + + auth->header.duration_id = 0x013a; //FIXME + + memcpy(auth->header.addr1, beacon->bssid, ETH_ALEN); + memcpy(auth->header.addr2, ieee->dev->dev_addr, ETH_ALEN); + memcpy(auth->header.addr3, beacon->bssid, ETH_ALEN); + + auth->algorithm = ieee->open_wep ? WLAN_AUTH_OPEN : WLAN_AUTH_SHARED_KEY; + + auth->transaction = cpu_to_le16(ieee->associate_seq); + ieee->associate_seq++; + + auth->status = cpu_to_le16(WLAN_STATUS_SUCCESS); + + return skb; + +} + +u8 WPA_OUI[3] = {0x00, 0x50, 0xf2}; + +static struct sk_buff* ieee80211_probe_resp(struct ieee80211_device *ieee, u8 *dest) +{ + u8 *tag; + int beacon_size; + struct ieee80211_probe_response *beacon_buf; + struct sk_buff *skb; + int encrypt; + int atim_len,erp_len; + struct ieee80211_crypt_data* crypt; + + char *ssid = ieee->current_network.ssid; + int ssid_len = ieee->current_network.ssid_len; + int rate_len = ieee->current_network.rates_len+2; + int rate_ex_len = ieee->current_network.rates_ex_len; + + int wpa_ie_len = 0, wpa_type=0; + if(rate_ex_len > 0) rate_ex_len+=2; + + if(ieee->current_network.capability & WLAN_CAPABILITY_IBSS) + atim_len = 4; + else + atim_len = 0; + + if(ieee80211_is_54g(ieee->current_network)) + erp_len = 3; + else + erp_len = 0; + if (ieee->wpa_enabled) + { + // printk("hoho wpa_enalbe\n"); + wpa_ie_len = ieee->wpa_ie_len; //24-2 + } + beacon_size = sizeof(struct ieee80211_probe_response)+ + ssid_len + +3 //channel + +rate_len + +rate_ex_len + +atim_len + +erp_len + +wpa_ie_len; + + skb = dev_alloc_skb(beacon_size); + + if (!skb) + return NULL; + + beacon_buf = (struct ieee80211_probe_response*) skb_put(skb, beacon_size); + + memcpy (beacon_buf->header.addr1, dest,ETH_ALEN); + memcpy (beacon_buf->header.addr2, ieee->dev->dev_addr, ETH_ALEN); + memcpy (beacon_buf->header.addr3, ieee->current_network.bssid, ETH_ALEN); + + beacon_buf->header.duration_id = 0; //FIXME + beacon_buf->beacon_interval = + cpu_to_le16(ieee->current_network.beacon_interval); + beacon_buf->capability = + cpu_to_le16(ieee->current_network.capability & WLAN_CAPABILITY_IBSS); + + if(ieee->short_slot && (ieee->current_network.capability & WLAN_CAPABILITY_SHORT_SLOT)) + cpu_to_le16((beacon_buf->capability |= WLAN_CAPABILITY_SHORT_SLOT)); +#ifdef _RTL8187_EXT_PATCH_ +{ +/* struct ieee80211_crypt_data_list* cryptlist = ieee->cryptlist[1]; + u8 i = cryptlist->used; + crypt = cryptlist ->crypt[ieee->tx_keyidx]; +*/ + crypt = ieee->cryptlist[0]->crypt[ieee->tx_keyidx]; +} +#else + + crypt = ieee->crypt[ieee->tx_keyidx]; +#endif + if (crypt) + wpa_type = strcmp(crypt->ops->name, "TKIP"); + + + encrypt = ieee->host_encrypt && crypt && crypt->ops && + ((0 == strcmp(crypt->ops->name, "WEP")||wpa_ie_len)); + + if (encrypt) + beacon_buf->capability |= cpu_to_le16(WLAN_CAPABILITY_PRIVACY); + + + beacon_buf->header.frame_ctl = cpu_to_le16(IEEE80211_STYPE_PROBE_RESP); + + beacon_buf->info_element.id = MFIE_TYPE_SSID; + beacon_buf->info_element.len = ssid_len; + + tag = (u8*) beacon_buf->info_element.data; + + memcpy(tag, ssid, ssid_len); + + tag += ssid_len; + + *(tag++) = MFIE_TYPE_RATES; + *(tag++) = rate_len-2; + memcpy(tag,ieee->current_network.rates,rate_len-2); + tag+=rate_len-2; + + *(tag++) = MFIE_TYPE_DS_SET; + *(tag++) = 1; + *(tag++) = ieee->current_network.channel; + + if(atim_len){ + u16 val16; + *(tag++) = MFIE_TYPE_IBSS_SET; + *(tag++) = 2; + val16 = cpu_to_le16(ieee->current_network.atim_window); + //*((u16*)(tag)) = cpu_to_le16(ieee->current_network.atim_window); + memcpy((u8 *)tag,(u8 *)&val16,2); + tag+=2; + } + + if(erp_len){ + *(tag++) = MFIE_TYPE_ERP; + *(tag++) = 1; + *(tag++) = 0; + } + + if(rate_ex_len){ + *(tag++) = MFIE_TYPE_RATES_EX; + *(tag++) = rate_ex_len-2; + memcpy(tag,ieee->current_network.rates_ex,rate_ex_len-2); + tag+=rate_ex_len-2; + } + if (wpa_ie_len) + { +#if 0 + *(tag++) = 0xdd; + *(tag++) = wpa_ie_len-2; + memcpy(tag, WPA_OUI, 3); + tag += 3; + *(tag++) = 1; + *(tag++) = 1; + *(tag++) = 0; + + memcpy(tag, WPA_OUI, 3); + tag += 3; + *(tag++) = wpa_type ? 4:2; + *(tag++) = 1; + *(tag++) = 0; + + + memcpy(tag, WPA_OUI, 3); + tag += 3; + *(tag++) = wpa_type ? 4:0; + *(tag++) = 1; + *(tag++) = 0; + + memcpy(tag, WPA_OUI, 3); + tag += 3; + *(tag++) = 0; +#else + if (ieee->iw_mode == IW_MODE_ADHOC) + {//as Windows will set pairwise key same as the group key which is not allowed in Linux, so set this for IOT issue. WB 2008.07.07 + memcpy(&ieee->wpa_ie[14], &ieee->wpa_ie[8], 4); + } + + memcpy(tag, ieee->wpa_ie, ieee->wpa_ie_len); + +#endif + } + + + skb->dev = ieee->dev; + return skb; +} + + +#ifdef _RTL8187_EXT_PATCH_ +struct sk_buff* ieee80211_ext_probe_resp_by_net(struct ieee80211_device *ieee, u8 *dest, struct ieee80211_network *net) +{ + u8 *tag; + int beacon_size; + struct ieee80211_probe_response *beacon_buf; + struct sk_buff *skb; + int encrypt; + int atim_len,erp_len; + struct ieee80211_crypt_data* crypt; + u8 broadcast_addr[] = {0xff,0xff,0xff,0xff,0xff,0xff}; + + char *ssid = net->ssid; + int ssid_len = net->ssid_len; + + int rate_len = ieee->current_network.rates_len+2; + int rate_ex_len = ieee->current_network.rates_ex_len; + int wpa_ie_len = 0, wpa_type=0; + if(rate_ex_len > 0) rate_ex_len+=2; + + if( ieee->meshScanMode&4) + ieee->current_network.channel = ieee->ext_patch_ieee80211_ext_stop_scan_wq_set_channel(ieee); + if( ieee->meshScanMode&6) + { + +#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0) + queue_work(ieee->wq, &ieee->ext_stop_scan_wq); +#else + schedule_task(&ieee->ext_stop_scan_wq); +#endif + } + if(ieee->current_network.capability & WLAN_CAPABILITY_IBSS) // use current_network here + atim_len = 4; + else + atim_len = 0; + + if(ieee80211_is_54g(*net)) + erp_len = 3; + else + erp_len = 0; + + if (ieee->wpa_enabled &&(ieee->iw_ext_mode==ieee->iw_mode)) + { +// printk("hoho wpa_enalbe\n"); + wpa_ie_len = ieee->wpa_ie_len; //24-2 + } + + beacon_size = sizeof(struct ieee80211_probe_response)+ + ssid_len + +3 //channel + +rate_len + +rate_ex_len + +atim_len + +erp_len + +wpa_ie_len; +//b + skb = dev_alloc_skb(beacon_size+196); + + if (!skb) + return NULL; + + beacon_buf = (struct ieee80211_probe_response*) skb_put(skb, beacon_size); + + memcpy (beacon_buf->header.addr1, dest,ETH_ALEN); + memcpy (beacon_buf->header.addr2, ieee->dev->dev_addr, ETH_ALEN); + memcpy (beacon_buf->header.addr3, ieee->current_network.bssid, ETH_ALEN); + + beacon_buf->header.duration_id = 0; //FIXME + + beacon_buf->beacon_interval = + cpu_to_le16(ieee->current_network.beacon_interval); // use current_network here + beacon_buf->capability = + cpu_to_le16(ieee->current_network.capability & WLAN_CAPABILITY_IBSS); + + if(ieee->short_slot && (ieee->current_network.capability & WLAN_CAPABILITY_SHORT_SLOT)) + cpu_to_le16((beacon_buf->capability |= WLAN_CAPABILITY_SHORT_SLOT)); +#ifdef _RTL8187_EXT_PATCH_ + + crypt = ieee->cryptlist[0]->crypt[ieee->tx_keyidx]; +#else + + crypt = ieee->crypt[ieee->tx_keyidx]; +#endif + +// crypt = ieee->crypt[ieee->tx_keyidx]; + if (crypt) + wpa_type = strcmp(crypt->ops->name, "TKIP"); + + encrypt = ieee->host_encrypt && crypt && crypt->ops && + ((0 == strcmp(crypt->ops->name, "WEP")||wpa_ie_len)); + + if (encrypt) + beacon_buf->capability |= cpu_to_le16(WLAN_CAPABILITY_PRIVACY); + + + beacon_buf->header.frame_ctl = cpu_to_le16(IEEE80211_STYPE_PROBE_RESP); + + beacon_buf->info_element.id = MFIE_TYPE_SSID; + beacon_buf->info_element.len = ssid_len; + + tag = (u8*) beacon_buf->info_element.data; + + // brocad cast / probe rsp + if(memcmp(dest, broadcast_addr, ETH_ALEN )) + memcpy(tag, ssid, ssid_len); + else + ssid_len=0; + + tag += ssid_len; + +//get_bssrate_set(priv, _SUPPORTEDRATES_IE_, &pbssrate, &bssrate_len); +//pbuf = set_ie(pbuf, _SUPPORTEDRATES_IE_, bssrate_len, pbssrate, &frlen); + + *(tag++) = MFIE_TYPE_RATES; + *(tag++) = rate_len-2; + memcpy(tag,ieee->current_network.rates,rate_len-2); + tag+=rate_len-2; + + *(tag++) = MFIE_TYPE_DS_SET; + *(tag++) = 1; + *(tag++) = ieee->current_network.channel; // use current_network here + + + if(atim_len){ + *(tag++) = MFIE_TYPE_IBSS_SET; + *(tag++) = 2; + *((u16*)(tag)) = cpu_to_le16(ieee->current_network.atim_window); // use current_network here + tag+=2; + } + + if(erp_len){ + *(tag++) = MFIE_TYPE_ERP; + *(tag++) = 1; + *(tag++) = 0; + } + + if(rate_ex_len){ + *(tag++) = MFIE_TYPE_RATES_EX; + *(tag++) = rate_ex_len-2; + memcpy(tag,ieee->current_network.rates_ex,rate_ex_len-2); + tag+=rate_ex_len-2; + } + + if (wpa_ie_len) + { +#if 0 + *(tag++) = 0xdd; + *(tag++) = wpa_ie_len-2; + memcpy(tag, WPA_OUI, 3); + tag += 3; + *(tag++) = 1; + *(tag++) = 1; + *(tag++) = 0; + + memcpy(tag, WPA_OUI, 3); + tag += 3; + *(tag++) = wpa_type ? 4:2; + *(tag++) = 1; + *(tag++) = 0; + + + memcpy(tag, WPA_OUI, 3); + tag += 3; + *(tag++) = wpa_type ? 4:0; + *(tag++) = 1; + *(tag++) = 0; + + memcpy(tag, WPA_OUI, 3); + tag += 3; + *(tag++) = 0; +#else + memcpy(tag, ieee->wpa_ie, ieee->wpa_ie_len); +#endif + } + + + skb->dev = ieee->dev; + return skb; +} +#endif // _RTL8187_EXT_PATCH_ + + +struct sk_buff* ieee80211_assoc_resp(struct ieee80211_device *ieee, u8 *dest) +{ + struct sk_buff *skb; + u8* tag; + + struct ieee80211_crypt_data* crypt; + struct ieee80211_assoc_response_frame *assoc; + short encrypt; + + unsigned int rate_len = ieee80211_MFIE_rate_len(ieee); + int len = sizeof(struct ieee80211_assoc_response_frame) + rate_len; + + skb = dev_alloc_skb(len); + + if (!skb) + return NULL; + + assoc = (struct ieee80211_assoc_response_frame *) + skb_put(skb,sizeof(struct ieee80211_assoc_response_frame)); + + assoc->header.frame_ctl = cpu_to_le16(IEEE80211_STYPE_ASSOC_RESP); + memcpy(assoc->header.addr1, dest,ETH_ALEN); + memcpy(assoc->header.addr3, ieee->dev->dev_addr, ETH_ALEN); + memcpy(assoc->header.addr2, ieee->dev->dev_addr, ETH_ALEN); + assoc->capability = cpu_to_le16(ieee->iw_mode == IW_MODE_MASTER ? + WLAN_CAPABILITY_BSS : WLAN_CAPABILITY_IBSS); + + + if(ieee->short_slot) + assoc->capability |= cpu_to_le16(WLAN_CAPABILITY_SHORT_SLOT); + + if (ieee->host_encrypt){ +#ifdef _RTL8187_EXT_PATCH_ + crypt = ieee->cryptlist[0]->crypt[ieee->tx_keyidx]; +#else + crypt = ieee->crypt[ieee->tx_keyidx]; +#endif + } + else crypt = NULL; + + encrypt = ( crypt && crypt->ops); + + if (encrypt) + assoc->capability |= cpu_to_le16(WLAN_CAPABILITY_PRIVACY); + + assoc->status = 0; + assoc->aid = cpu_to_le16(ieee->assoc_id); + if (ieee->assoc_id == 0x2007) ieee->assoc_id=0; + else ieee->assoc_id++; + + tag = (u8*) skb_put(skb, rate_len); + + ieee80211_MFIE_Brate(ieee, &tag); + ieee80211_MFIE_Grate(ieee, &tag); + + return skb; +} + +struct sk_buff* ieee80211_auth_resp(struct ieee80211_device *ieee,int status, u8 *dest) +{ + struct sk_buff *skb; + struct ieee80211_authentication *auth; + + skb = dev_alloc_skb(sizeof(struct ieee80211_authentication)+1); + + if (!skb) + return NULL; + + skb->len = sizeof(struct ieee80211_authentication); + + auth = (struct ieee80211_authentication *)skb->data; + + auth->status = cpu_to_le16(status); + auth->transaction = cpu_to_le16(2); + auth->algorithm = cpu_to_le16(WLAN_AUTH_OPEN); + +#ifdef _RTL8187_EXT_PATCH_ + if(ieee->iw_mode == ieee->iw_ext_mode) + memcpy(auth->header.addr3, dest, ETH_ALEN); +#else + memcpy(auth->header.addr3, ieee->dev->dev_addr, ETH_ALEN); +#endif + memcpy(auth->header.addr2, ieee->dev->dev_addr, ETH_ALEN); + memcpy(auth->header.addr1, dest, ETH_ALEN); + auth->header.frame_ctl = cpu_to_le16(IEEE80211_STYPE_AUTH); + return skb; + + +} + +struct sk_buff* ieee80211_null_func(struct ieee80211_device *ieee,short pwr) +{ + struct sk_buff *skb; + struct ieee80211_hdr_3addr* hdr; + + skb = dev_alloc_skb(sizeof(struct ieee80211_hdr_3addr)); + + if (!skb) + return NULL; + + hdr = (struct ieee80211_hdr_3addr*)skb_put(skb,sizeof(struct ieee80211_hdr_3addr)); + + memcpy(hdr->addr1, ieee->current_network.bssid, ETH_ALEN); + memcpy(hdr->addr2, ieee->dev->dev_addr, ETH_ALEN); + memcpy(hdr->addr3, ieee->current_network.bssid, ETH_ALEN); + + hdr->frame_ctl = cpu_to_le16(IEEE80211_FTYPE_DATA | + IEEE80211_STYPE_NULLFUNC | IEEE80211_FCTL_TODS | + (pwr ? IEEE80211_FCTL_PM:0)); + + return skb; + + +} + + +void ieee80211_resp_to_assoc_rq(struct ieee80211_device *ieee, u8* dest) +{ + struct sk_buff *buf = ieee80211_assoc_resp(ieee, dest); + + if (buf){ + softmac_mgmt_xmit(buf, ieee); + dev_kfree_skb_any(buf);//edit by thomas + } +} + + +void ieee80211_resp_to_auth(struct ieee80211_device *ieee, int s, u8* dest) +{ + struct sk_buff *buf = ieee80211_auth_resp(ieee, s, dest); + + if (buf){ + softmac_mgmt_xmit(buf, ieee); + dev_kfree_skb_any(buf);//edit by thomas + } +} + + +void ieee80211_resp_to_probe(struct ieee80211_device *ieee, u8 *dest) +{ + + struct sk_buff *buf = ieee80211_probe_resp(ieee, dest); + + if (buf) { + softmac_mgmt_xmit(buf, ieee); + dev_kfree_skb_any(buf);//edit by thomas + } +} + + +inline struct sk_buff *ieee80211_association_req(struct ieee80211_network *beacon,struct ieee80211_device *ieee) +{ + struct sk_buff *skb; + + struct ieee80211_assoc_request_frame *hdr; + u8 *tag; + //int i; + unsigned int wpa_len = beacon->wpa_ie_len; +#if 1 + // for testing purpose + unsigned int rsn_len = beacon->rsn_ie_len; +#else + unsigned int rsn_len = beacon->rsn_ie_len - 4; +#endif + unsigned int rate_len = ieee80211_MFIE_rate_len(ieee); + unsigned int wmm_info_len = beacon->QoS_Enable?9:0; +#ifdef THOMAS_TURBO + unsigned int turbo_info_len = beacon->Turbo_Enable?9:0; +#endif + + u8 encry_proto = ieee->wpax_type_notify & 0xff; + + + int len = 0; + + //[0] Notify type of encryption: WPA/WPA2 + //[1] pair wise type + //[2] authen type + if(ieee->wpax_type_set) { + if (IEEE_PROTO_WPA == encry_proto) { + rsn_len = 0; + } else if (IEEE_PROTO_RSN == encry_proto) { + wpa_len = 0; + } + } +#ifdef THOMAS_TURBO + len = sizeof(struct ieee80211_assoc_request_frame)+ + + beacon->ssid_len//essid tagged val + + rate_len//rates tagged val + + wpa_len + + rsn_len + + wmm_info_len + + turbo_info_len; +#else + len = sizeof(struct ieee80211_assoc_request_frame)+ + + beacon->ssid_len//essid tagged val + + rate_len//rates tagged val + + wpa_len + + rsn_len + + wmm_info_len; +#endif + +#ifdef _RTL8187_EXT_PATCH_ + if(ieee->iw_mode == ieee->iw_ext_mode) + skb = dev_alloc_skb(len+256); // stanley + else +#endif + skb = dev_alloc_skb(len); + + if (!skb) + return NULL; + + hdr = (struct ieee80211_assoc_request_frame *) + skb_put(skb, sizeof(struct ieee80211_assoc_request_frame)); + + + hdr->header.frame_ctl = IEEE80211_STYPE_ASSOC_REQ; + hdr->header.duration_id= 37; //FIXME + memcpy(hdr->header.addr1, beacon->bssid, ETH_ALEN); + memcpy(hdr->header.addr2, ieee->dev->dev_addr, ETH_ALEN); + memcpy(hdr->header.addr3, beacon->bssid, ETH_ALEN); + memcpy(ieee->ap_mac_addr, beacon->bssid, ETH_ALEN);//for HW security, John + + hdr->capability = cpu_to_le16(WLAN_CAPABILITY_BSS); + if (beacon->capability & WLAN_CAPABILITY_PRIVACY ) + hdr->capability |= cpu_to_le16(WLAN_CAPABILITY_PRIVACY); + + if (beacon->capability & WLAN_CAPABILITY_SHORT_PREAMBLE ) + hdr->capability |= cpu_to_le16(WLAN_CAPABILITY_SHORT_PREAMBLE); + + if(ieee->short_slot) + hdr->capability |= cpu_to_le16(WLAN_CAPABILITY_SHORT_SLOT); + +#ifdef _RTL8187_EXT_PATCH_ + if((ieee->iw_mode == ieee->iw_ext_mode) && ieee->ext_patch_ieee80211_association_req_1) + ieee->ext_patch_ieee80211_association_req_1(hdr); +#endif + + hdr->listen_interval = 0xa; //FIXME + + hdr->info_element.id = MFIE_TYPE_SSID; + + hdr->info_element.len = beacon->ssid_len; + tag = skb_put(skb, beacon->ssid_len); + memcpy(tag, beacon->ssid, beacon->ssid_len); + + tag = skb_put(skb, rate_len); + + ieee80211_MFIE_Brate(ieee, &tag); + ieee80211_MFIE_Grate(ieee, &tag); + + //add rsn==0 condition for ap's mix security mode(wpa+wpa2), john2007.8.9 + //choose AES encryption as default algorithm while using mixed mode +#if 0 + if(rsn_len == 0){ + + tag = skb_put(skb,wpa_len); + + if(wpa_len) { + + + //{add by david. 2006.8.31 + //fix linksys compatibility bug + //} + if(wpa_len > 24) {//22+2, mean include the capability + beacon->wpa_ie[wpa_len - 2] = 0; + } + //multicast cipher OUI + if( beacon->wpa_ie[11]==0x2 ){ //0x0050f202 is the oui of tkip + ieee->broadcast_key_type = KEY_TYPE_TKIP; + } + else if( beacon->wpa_ie[11]==0x4 ){//0x0050f204 is the oui of ccmp + ieee->broadcast_key_type = KEY_TYPE_CCMP; + } + //unicast cipher OUI + if( beacon->wpa_ie[14]==0 + && beacon->wpa_ie[15]==0x50 + && beacon->wpa_ie[16]==0xf2 + && beacon->wpa_ie[17]==0x2 ){ //0x0050f202 is the oui of tkip + ieee->pairwise_key_type = KEY_TYPE_TKIP; + } + + else if( beacon->wpa_ie[14]==0 + && beacon->wpa_ie[15]==0x50 + && beacon->wpa_ie[16]==0xf2 + && beacon->wpa_ie[17]==0x4 ){//0x0050f204 is the oui of ccmp + ieee->pairwise_key_type = KEY_TYPE_CCMP; + } + //indicate the wpa_ie content to WPA_SUPPLICANT + buff = kmalloc(IW_CUSTOM_MAX, GFP_ATOMIC); + memset(buff, 0, IW_CUSTOM_MAX); + p=buff; + p += sprintf(p, "ASSOCINFO(ReqIEs="); + for(i=0;iwpa_ie[i]); + } + p += sprintf(p, ")"); + memset(&wrqu, 0, sizeof(wrqu) ); + wrqu.data.length = p - buff; + + wireless_send_event(dev, IWEVCUSTOM, &wrqu, buff); + memcpy(tag,beacon->wpa_ie,wpa_len); + } + + } + + if(rsn_len > 22) { + + if( beacon->rsn_ie[4]==0x0 && + beacon->rsn_ie[5]==0xf && + beacon->rsn_ie[6]==0xac){ + + switch(beacon->rsn_ie[7]){ + case 0x1: + ieee->broadcast_key_type = KEY_TYPE_WEP40; + break; + case 0x2: + ieee->broadcast_key_type = KEY_TYPE_TKIP; + break; + case 0x4: + ieee->broadcast_key_type = KEY_TYPE_CCMP; + break; + case 0x5: + ieee->broadcast_key_type = KEY_TYPE_WEP104; + break; + default: + printk("fault suite type in RSN broadcast key\n"); + break; + } + } + + if( beacon->rsn_ie[10]==0x0 && + beacon->rsn_ie[11]==0xf && + beacon->rsn_ie[12]==0xac){ + if(beacon->rsn_ie[8]==1){//not mixed mode + switch(beacon->rsn_ie[13]){ + case 0x2: + ieee->pairwise_key_type = KEY_TYPE_TKIP; + break; + case 0x4: + ieee->pairwise_key_type = KEY_TYPE_CCMP; + break; + default: + printk("fault suite type in RSN pairwise key\n"); + break; + } + } + else if(beacon->rsn_ie[8]==2){//mixed mode + ieee->pairwise_key_type = KEY_TYPE_CCMP; + } + } + + + + tag = skb_put(skb,22); + memcpy(tag,(beacon->rsn_ie + info_addr),8); + tag[1] = 20; + tag += 8; + info_addr += 8; + + spin_lock_irqsave(&ieee->wpax_suitlist_lock,flags); + for (i = 0; i < 2; i++) { + tag[0] = 1; + tag[1] = 0; + tag += 2; + suite_count = beacon->rsn_ie[info_addr] + \ + (beacon->rsn_ie[info_addr + 1] << 8); + info_addr += 2; + if(1 == suite_count) { + memcpy(tag,(beacon->rsn_ie + info_addr),4); + info_addr += 4; + } else { + // if the wpax_type_notify has been set by the application, + // just use it, otherwise just use the default one. + if(ieee->wpax_type_set) { + suit_select = ((0 == i) ? pairwise_type:authen_type)&0x0f ; + memcpy(tag,rsn_authen_cipher_suite[suit_select],4); + } else { + //default set as ccmp, or none authentication + if(i == 0) { + memcpy(tag,rsn_authen_cipher_suite[4],4); + } else { + memcpy(tag,rsn_authen_cipher_suite[2],4); + } + + } + + info_addr += (suite_count * 4); + } + tag += 4; + } + spin_unlock_irqrestore(&ieee->wpax_suitlist_lock,flags); + + tag[0] = 0; + tag[1] = beacon->rsn_ie[info_addr+1]; + + + + } else { + tag = skb_put(skb,rsn_len); + if(rsn_len) { + + + if( beacon->rsn_ie[4]==0x0 && + beacon->rsn_ie[5]==0xf && + beacon->rsn_ie[6]==0xac){ + switch(beacon->rsn_ie[7]){ + case 0x1: + ieee->broadcast_key_type = KEY_TYPE_WEP40; + break; + case 0x2: + ieee->broadcast_key_type = KEY_TYPE_TKIP; + break; + case 0x4: + ieee->broadcast_key_type = KEY_TYPE_CCMP; + break; + case 0x5: + ieee->broadcast_key_type = KEY_TYPE_WEP104; + break; + default: + printk("fault suite type in RSN broadcast key\n"); + break; + } + } + if( beacon->rsn_ie[10]==0x0 && + beacon->rsn_ie[11]==0xf && + beacon->rsn_ie[12]==0xac){ + if(beacon->rsn_ie[8]==1){//not mixed mode + switch(beacon->rsn_ie[13]){ + case 0x2: + ieee->pairwise_key_type = KEY_TYPE_TKIP; + break; + case 0x4: + ieee->pairwise_key_type = KEY_TYPE_CCMP; + break; + default: + printk("fault suite type in RSN pairwise key\n"); + break; + } + + } + else if(beacon->rsn_ie[8]==2){//mixed mode + ieee->pairwise_key_type = KEY_TYPE_CCMP; + } + } + + + beacon->rsn_ie[rsn_len - 2] = 0; + memcpy(tag,beacon->rsn_ie,rsn_len); + } + } +#else + if (ieee->wpa_ie){ + tag = skb_put(skb,ieee->wpa_ie_len); + memcpy(tag,ieee->wpa_ie,ieee->wpa_ie_len); + } +#endif + tag = skb_put(skb,wmm_info_len); + if(wmm_info_len) { + ieee80211_WMM_Info(ieee, &tag); + } +#ifdef THOMAS_TURBO + tag = skb_put(skb,turbo_info_len); + if(turbo_info_len) { + ieee80211_TURBO_Info(ieee, &tag); + } +#endif + +#ifdef _RTL8187_EXT_PATCH_ + if((ieee->iw_mode == ieee->iw_ext_mode) && ieee->ext_patch_ieee80211_association_req_2) + ieee->ext_patch_ieee80211_association_req_2(ieee, beacon, skb); +#endif + + return skb; +} + +void ieee80211_associate_abort(struct ieee80211_device *ieee) +{ + + unsigned long flags; + spin_lock_irqsave(&ieee->lock, flags); + + ieee->associate_seq++; + + /* don't scan, and avoid to have the RX path possibily + * try again to associate. Even do not react to AUTH or + * ASSOC response. Just wait for the retry wq to be scheduled. + * Here we will check if there are good nets to associate + * with, so we retry or just get back to NO_LINK and scanning + */ + if (ieee->state == IEEE80211_ASSOCIATING_AUTHENTICATING){ + IEEE80211_DEBUG_MGMT("Authentication failed\n"); + ieee->softmac_stats.no_auth_rs++; + }else{ + IEEE80211_DEBUG_MGMT("Association failed\n"); + ieee->softmac_stats.no_ass_rs++; + } + + ieee->state = IEEE80211_ASSOCIATING_RETRY; + +#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0) + queue_delayed_work(ieee->wq, &ieee->associate_retry_wq, \ + IEEE80211_SOFTMAC_ASSOC_RETRY_TIME); +#else + schedule_task(&ieee->associate_retry_wq); +#endif + + spin_unlock_irqrestore(&ieee->lock, flags); +} + +void ieee80211_associate_abort_cb(unsigned long dev) +{ + ieee80211_associate_abort((struct ieee80211_device *) dev); +} + + +void ieee80211_associate_step1(struct ieee80211_device *ieee) +{ + struct ieee80211_network *beacon = &ieee->current_network; + struct sk_buff *skb; + + IEEE80211_DEBUG_MGMT("Stopping scan\n"); + + ieee->softmac_stats.tx_auth_rq++; + skb=ieee80211_authentication_req(beacon, ieee, 0); + +#ifdef _RTL8187_EXT_PATCH_ + if(ieee->iw_mode == ieee->iw_ext_mode ) { + if(skb) + softmac_mgmt_xmit(skb, ieee); + return; + }else +#endif + if (!skb) + ieee80211_associate_abort(ieee); + else{ + ieee->state = IEEE80211_ASSOCIATING_AUTHENTICATING ; + IEEE80211_DEBUG_MGMT("Sending authentication request\n"); + //printk(KERN_WARNING "Sending authentication request\n"); + softmac_mgmt_xmit(skb, ieee); + //BUGON when you try to add_timer twice, using mod_timer may be better, john0709 + if(!timer_pending(&ieee->associate_timer)){ + ieee->associate_timer.expires = jiffies + (HZ / 2); + add_timer(&ieee->associate_timer); + } + dev_kfree_skb_any(skb);//edit by thomas + } +} + +void ieee80211_auth_challenge(struct ieee80211_device *ieee, u8 *challenge, int chlen) +{ + u8 *c; + struct sk_buff *skb; + struct ieee80211_network *beacon = &ieee->current_network; +// int hlen = sizeof(struct ieee80211_authentication); + + ieee->associate_seq++; + ieee->softmac_stats.tx_auth_rq++; + + skb = ieee80211_authentication_req(beacon, ieee, chlen+2); + if (!skb) + ieee80211_associate_abort(ieee); + else{ + c = skb_put(skb, chlen+2); + *(c++) = MFIE_TYPE_CHALLENGE; + *(c++) = chlen; + memcpy(c, challenge, chlen); + + IEEE80211_DEBUG_MGMT("Sending authentication challenge response\n"); + + ieee80211_encrypt_fragment(ieee, skb, sizeof(struct ieee80211_hdr_3addr )); + + softmac_mgmt_xmit(skb, ieee); + + if(!timer_pending(&ieee->associate_timer)){ + ieee->associate_timer.expires = jiffies + (HZ / 2); + add_timer(&ieee->associate_timer); + } + dev_kfree_skb_any(skb);//edit by thomas + } + kfree(challenge); +} + +#ifdef _RTL8187_EXT_PATCH_ + +// based on ieee80211_assoc_resp +struct sk_buff* ieee80211_assoc_resp_by_net(struct ieee80211_device *ieee, u8 *dest, unsigned short status, struct ieee80211_network *pstat, int pkt_type) +{ + struct sk_buff *skb; + u8* tag; + + struct ieee80211_crypt_data* crypt; + struct ieee80211_assoc_response_frame *assoc; + short encrypt; + + unsigned int rate_len = ieee80211_MFIE_rate_len(ieee); + int len = sizeof(struct ieee80211_assoc_response_frame) + rate_len; + + if(ieee->iw_mode == ieee->iw_ext_mode) + skb = dev_alloc_skb(len+256); // stanley + else + skb = dev_alloc_skb(len); + + if (!skb) + return NULL; + + assoc = (struct ieee80211_assoc_response_frame *) + skb_put(skb,sizeof(struct ieee80211_assoc_response_frame)); + + assoc->header.frame_ctl = cpu_to_le16(pkt_type); + + memcpy(assoc->header.addr1, dest,ETH_ALEN); + memcpy(assoc->header.addr3, ieee->dev->dev_addr, ETH_ALEN); + memcpy(assoc->header.addr2, ieee->dev->dev_addr, ETH_ALEN); + assoc->capability = cpu_to_le16(ieee->iw_mode == IW_MODE_MASTER ? + WLAN_CAPABILITY_BSS : WLAN_CAPABILITY_IBSS); + + if((ieee->iw_mode == ieee->iw_ext_mode) && ieee->ext_patch_ieee80211_assoc_resp_by_net_1) + ieee->ext_patch_ieee80211_assoc_resp_by_net_1(assoc); + + if(ieee->short_slot) + assoc->capability |= cpu_to_le16(WLAN_CAPABILITY_SHORT_SLOT); + + if (ieee->host_encrypt) +#ifdef _RTL8187_EXT_PATCH_ + crypt = ieee->cryptlist[0]->crypt[ieee->tx_keyidx]; +#else + crypt = ieee->crypt[ieee->tx_keyidx]; +#endif + + else crypt = NULL; + + encrypt = ( crypt && crypt->ops); + + if (encrypt) + assoc->capability |= cpu_to_le16(WLAN_CAPABILITY_PRIVACY); + + assoc->status = 0; + assoc->aid = cpu_to_le16(ieee->assoc_id); + if (ieee->assoc_id == 0x2007) ieee->assoc_id=0; + else ieee->assoc_id++; + + assoc->info_element.id = 230; // Stanley, an unused id (just a hot fix) + assoc->info_element.len = 0; + + tag = (u8*) skb_put(skb, rate_len); + + ieee80211_MFIE_Brate(ieee, &tag); + ieee80211_MFIE_Grate(ieee, &tag); + + if((ieee->iw_mode == ieee->iw_ext_mode) && ieee->ext_patch_ieee80211_assoc_resp_by_net_2) + ieee->ext_patch_ieee80211_assoc_resp_by_net_2(ieee, pstat, pkt_type, skb); + + return skb; +} + +// based on ieee80211_resp_to_assoc_rq +void ieee80211_ext_issue_assoc_rsp(struct ieee80211_device *ieee, u8 *dest, unsigned short status, struct ieee80211_network *pstat, int pkt_type) +{ + struct sk_buff *buf = ieee80211_assoc_resp_by_net(ieee, dest, status, pstat, pkt_type); + + if (buf) + softmac_mgmt_xmit(buf, ieee); +} + +// based on ieee80211_associate_step2 +void ieee80211_ext_issue_assoc_req(struct ieee80211_device *ieee, struct ieee80211_network *pstat) +{ + + struct sk_buff* skb; + + // printk("@@@@@ ieee80211_ext_issue_assoc_req on channel: %d\n", ieee->current_network.channel); + + ieee->softmac_stats.tx_ass_rq++; + skb=ieee80211_association_req(pstat, ieee); + if (skb) + softmac_mgmt_xmit(skb, ieee); +} + +void ieee80211_ext_issue_disassoc(struct ieee80211_device *ieee, struct ieee80211_network *pstat, int reason, unsigned char extReason) +{ + // do nothing + // printk("@@@@@ ieee80211_ext_issue_disassoc\n"); + return; +} +#endif // _RTL8187_EXT_PATCH_ + +void ieee80211_associate_step2(struct ieee80211_device *ieee) +{ + struct sk_buff* skb; + struct ieee80211_network *beacon = &ieee->current_network; + +// del_timer_sync(&ieee->associate_timer); + + IEEE80211_DEBUG_MGMT("Sending association request\n"); + + ieee->softmac_stats.tx_ass_rq++; + skb=ieee80211_association_req(beacon, ieee); + if (!skb) + ieee80211_associate_abort(ieee); + else{ + softmac_mgmt_xmit(skb, ieee); + if(!timer_pending(&ieee->associate_timer)){ + ieee->associate_timer.expires = jiffies + (HZ / 2); + add_timer(&ieee->associate_timer); + } + dev_kfree_skb_any(skb);//edit by thomas + } +} + +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)) +void ieee80211_associate_complete_wq(struct work_struct *work) +{ + struct ieee80211_device *ieee = container_of(work, struct ieee80211_device, associate_complete_wq); +#else +void ieee80211_associate_complete_wq(struct ieee80211_device *ieee) +{ +#endif + printk(KERN_INFO "Associated successfully\n"); + if(ieee80211_is_54g(ieee->current_network) && + (ieee->modulation & IEEE80211_OFDM_MODULATION)){ + + ieee->rate = 540; + printk(KERN_INFO"Using G rates\n"); + }else{ + ieee->rate = 110; + printk(KERN_INFO"Using B rates\n"); + } + +//by lizhaoming for LED LINK +#ifdef LED_SHIN + { + struct net_device *dev = ieee->dev; + ieee->ieee80211_led_contorl(dev, LED_CTL_LINK); + } +#endif + + ieee->link_change(ieee->dev); + notify_wx_assoc_event(ieee); + if (ieee->data_hard_resume) + ieee->data_hard_resume(ieee->dev); + netif_carrier_on(ieee->dev); +} + +void ieee80211_associate_complete(struct ieee80211_device *ieee) +{ + int i; +// struct net_device *dev = ieee->dev; + del_timer_sync(&ieee->associate_timer); + + for(i = 0; i < 6; i++) { +// ieee->seq_ctrl[i] = 0; + } + ieee->state = IEEE80211_LINKED; + IEEE80211_DEBUG_MGMT("Successfully associated\n"); + + //by lizhaoming for LED LINK + //ieee->ieee80211_led_contorl(dev, LED_CTL_LINK); + +#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0) + queue_work(ieee->wq, &ieee->associate_complete_wq); +#else + schedule_task(&ieee->associate_complete_wq); +#endif +} + +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)) +void ieee80211_associate_procedure_wq(struct work_struct *work) +{ + struct ieee80211_device *ieee = container_of(work, struct ieee80211_device, associate_procedure_wq); +#else +void ieee80211_associate_procedure_wq(struct ieee80211_device *ieee) +{ +#endif + ieee->sync_scan_hurryup = 1; + down(&ieee->wx_sem); + + if (ieee->data_hard_stop) + ieee->data_hard_stop(ieee->dev); + + ieee80211_stop_scan(ieee); + //printk("=======>%s set chan:%d\n", __func__, ieee->current_network.channel); + ieee->set_chan(ieee->dev, ieee->current_network.channel); + + ieee->associate_seq = 1; + ieee80211_associate_step1(ieee); + + up(&ieee->wx_sem); +} +#ifdef _RTL8187_EXT_PATCH_ +// based on ieee80211_associate_procedure_wq + +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20) +void ieee80211_ext_stop_scan_wq(struct work_struct *work) +{ + struct ieee80211_device *ieee = container_of(work, struct ieee80211_device, ext_stop_scan_wq); +#else +void ieee80211_ext_stop_scan_wq(struct ieee80211_device *ieee) +{ +#endif +/* + if (ieee->scanning == 0) + { + if((ieee->iw_mode == ieee->iw_ext_mode) && ieee->ext_patch_ieee80211_ext_stop_scan_wq_set_channel + && ( ieee->current_network.channel == ieee->ext_patch_ieee80211_ext_stop_scan_wq_set_channel(ieee) ) ) + return; + } +*/ + ieee->sync_scan_hurryup = 1; + + down(&ieee->wx_sem); + + // printk("@@@@@@@@@@ ieee80211_ext_stop_scan_wq\n"); + if (ieee->data_hard_stop) + ieee->data_hard_stop(ieee->dev); + + ieee80211_stop_scan(ieee); + + // set channel + if((ieee->iw_mode == ieee->iw_ext_mode) && ieee->ext_patch_ieee80211_ext_stop_scan_wq_set_channel) + { + int ch = ieee->ext_patch_ieee80211_ext_stop_scan_wq_set_channel(ieee); + ieee->current_network.channel = ch; + ieee->set_chan(ieee->dev, ch); + } + else + { + ieee->set_chan(ieee->dev, ieee->current_network.channel); + } + // + up(&ieee->wx_sem); +} + + +void ieee80211_ext_send_11s_beacon(struct ieee80211_device *ieee) +{ + #if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0) + queue_work(ieee->wq, &ieee->ext_send_beacon_wq); + #else + schedule_task(&ieee->ext_send_beacon_wq); + #endif + +} + +#endif // _RTL8187_EXT_PATCH_ + +inline void ieee80211_softmac_new_net(struct ieee80211_device *ieee, struct ieee80211_network *net) +{ + u8 tmp_ssid[IW_ESSID_MAX_SIZE+1]; + int tmp_ssid_len = 0; + + short apset,ssidset,ssidbroad,apmatch,ssidmatch; +// printk("===============>%s()\n",__FUNCTION__); + /* we are interested in new new only if we are not associated + * and we are not associating / authenticating + */ + if (ieee->state != IEEE80211_NOLINK) + return; + + if ((ieee->iw_mode == IW_MODE_INFRA) && !(net->capability & WLAN_CAPABILITY_BSS)) + return; + + if ((ieee->iw_mode == IW_MODE_ADHOC) && !(net->capability & WLAN_CAPABILITY_IBSS)) + return; + + + if (ieee->iw_mode == IW_MODE_INFRA || ieee->iw_mode == IW_MODE_ADHOC){ + /* if the user specified the AP MAC, we need also the essid + * This could be obtained by beacons or, if the network does not + * broadcast it, it can be put manually. + */ + apset = ieee->wap_set;//(memcmp(ieee->current_network.bssid, zero,ETH_ALEN)!=0 ); + ssidset = ieee->ssid_set;//ieee->current_network.ssid[0] != '\0'; + ssidbroad = !(net->ssid_len == 0 || net->ssid[0]== '\0'); + apmatch = (memcmp(ieee->current_network.bssid, net->bssid, ETH_ALEN)==0); + if(ieee->current_network.ssid_len != net->ssid_len) + ssidmatch = 0; + else + ssidmatch = (0==strncmp(ieee->current_network.ssid, net->ssid, net->ssid_len)); + + + + if ( /* if the user set the AP check if match. + * if the network does not broadcast essid we check the user supplyed ANY essid + * if the network does broadcast and the user does not set essid it is OK + * if the network does broadcast and the user did set essid chech if essid match + */ + ( apset && apmatch && + //((ssidset && ssidbroad && ssidmatch) || (ssidbroad && !ssidset) || (!ssidbroad && ssidset)) ) || + ((ssidset && ssidbroad && ssidmatch) || (!ssidbroad && ssidset)) ) || + /* if the ap is not set, check that the user set the bssid + * and the network does bradcast and that those two bssid matches + */ + (!apset && ssidset && ssidbroad && ssidmatch) + ){ + /* if the essid is hidden replace it with the + * essid provided by the user. + */ + if (!ssidbroad){ + strncpy(tmp_ssid, ieee->current_network.ssid, IW_ESSID_MAX_SIZE); + tmp_ssid_len = ieee->current_network.ssid_len; + } + memcpy(&ieee->current_network, net, sizeof(struct ieee80211_network)); + + if (!ssidbroad){ + strncpy(ieee->current_network.ssid, tmp_ssid, IW_ESSID_MAX_SIZE); + ieee->current_network.ssid_len = tmp_ssid_len; + } + printk(KERN_INFO"Linking with %s, channel:%d\n",ieee->current_network.ssid, ieee->current_network.channel); + +#ifdef CONFIG_IPS + ieee->ieee80211_ips_leave(ieee->dev); +#endif + + if (ieee->iw_mode == IW_MODE_INFRA){ + ieee->state = IEEE80211_ASSOCIATING; +#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0) + queue_work(ieee->wq, &ieee->associate_procedure_wq); +#else + schedule_task(&ieee->associate_procedure_wq); +#endif + }else{ + ieee->state = IEEE80211_LINKED; + if(ieee80211_is_54g(ieee->current_network) && + (ieee->modulation & IEEE80211_OFDM_MODULATION)){ + ieee->rate = 540; + printk(KERN_INFO"Using G rates\n"); + }else{ + ieee->rate = 110; + printk(KERN_INFO"Using B rates\n"); + } + } + + } + } + +} + +void ieee80211_softmac_check_all_nets(struct ieee80211_device *ieee) +{ + unsigned long flags; + struct ieee80211_network *target; + + spin_lock_irqsave(&ieee->lock, flags); +#if 0 + list_for_each_entry(target, &ieee->network_list, list) { + printk(KERN_INFO"check network list SSID: %s, channel: %d\n",target->ssid,target->channel); + } +#endif + list_for_each_entry(target, &ieee->network_list, list) { + + /* if the state become different that NOLINK means + * we had found what we are searching for + */ + + if (ieee->state != IEEE80211_NOLINK) + break; + + if (ieee->scan_age == 0 || time_after(target->last_scanned + ieee->scan_age, jiffies)) + ieee80211_softmac_new_net(ieee, target); + } + + spin_unlock_irqrestore(&ieee->lock, flags); + + //printk("<=====%s\n", __func__); +} + + +static inline u16 auth_parse(struct sk_buff *skb, u8** challenge, int *chlen) +{ + struct ieee80211_authentication *a; + u8 *t; + if (skb->len < (sizeof(struct ieee80211_authentication)-sizeof(struct ieee80211_info_element))){ + IEEE80211_DEBUG_MGMT("invalid len in auth resp: %d\n",skb->len); + return 0xcafe; + } + *challenge = NULL; + a = (struct ieee80211_authentication*) skb->data; + if(skb->len > (sizeof(struct ieee80211_authentication) +3)){ + t = skb->data + sizeof(struct ieee80211_authentication); + + if(*(t++) == MFIE_TYPE_CHALLENGE){ + *chlen = *(t++); + *challenge = (u8*)kmalloc(*chlen, GFP_ATOMIC); + memcpy(*challenge, t, *chlen); + } + } + + return cpu_to_le16(a->status); + +} + + +int auth_rq_parse(struct sk_buff *skb,u8* dest) +{ + struct ieee80211_authentication *a; + + if (skb->len < (sizeof(struct ieee80211_authentication)-sizeof(struct ieee80211_info_element))){ + IEEE80211_DEBUG_MGMT("invalid len in auth request: %d\n",skb->len); + return -1; + } + a = (struct ieee80211_authentication*) skb->data; + + memcpy(dest,a->header.addr2, ETH_ALEN); + + if (le16_to_cpu(a->algorithm) != WLAN_AUTH_OPEN) + return WLAN_STATUS_NOT_SUPPORTED_AUTH_ALG; + + return WLAN_STATUS_SUCCESS; +} + +static short probe_rq_parse(struct ieee80211_device *ieee, struct sk_buff *skb, u8 *src) +{ + u8 *tag; + u8 *skbend; + u8 *ssid=NULL; + u8 ssidlen = 0; + + struct ieee80211_hdr_3addr *header = + (struct ieee80211_hdr_3addr *) skb->data; + + if (skb->len < sizeof (struct ieee80211_hdr_3addr )) + return -1; /* corrupted */ + + memcpy(src,header->addr2, ETH_ALEN); + + skbend = (u8*)skb->data + skb->len; + + tag = skb->data + sizeof (struct ieee80211_hdr_3addr ); + + while (tag+1 < skbend){ + if (*tag == 0){ + ssid = tag+2; + ssidlen = *(tag+1); + break; + } + tag++; /* point to the len field */ + tag = tag + *(tag); /* point to the last data byte of the tag */ + tag++; /* point to the next tag */ + } + + //IEEE80211DMESG("Card MAC address is "MACSTR, MAC2STR(src)); + if (ssidlen == 0) return 1; + + if (!ssid) return 1; /* ssid not found in tagged param */ + return (!strncmp(ssid, ieee->current_network.ssid, ssidlen)); + +} + +int assoc_rq_parse(struct sk_buff *skb,u8* dest) +{ + struct ieee80211_assoc_request_frame *a; + + if (skb->len < (sizeof(struct ieee80211_assoc_request_frame) - + sizeof(struct ieee80211_info_element))) { + + IEEE80211_DEBUG_MGMT("invalid len in auth request:%d \n", skb->len); + return -1; + } + + a = (struct ieee80211_assoc_request_frame*) skb->data; + + memcpy(dest,a->header.addr2,ETH_ALEN); + + return 0; +} + +static inline u16 assoc_parse(struct sk_buff *skb, int *aid) +{ + struct ieee80211_assoc_response_frame *a; + if (skb->len < sizeof(struct ieee80211_assoc_response_frame)){ + IEEE80211_DEBUG_MGMT("invalid len in auth resp: %d\n", skb->len); + return 0xcafe; + } + + a = (struct ieee80211_assoc_response_frame*) skb->data; + *aid = le16_to_cpu(a->aid) & 0x3fff; + return le16_to_cpu(a->status); +} + +static inline void +ieee80211_rx_probe_rq(struct ieee80211_device *ieee, struct sk_buff *skb) +{ + u8 dest[ETH_ALEN]; + + //IEEE80211DMESG("Rx probe"); + ieee->softmac_stats.rx_probe_rq++; + //DMESG("Dest is "MACSTR, MAC2STR(dest)); + if (probe_rq_parse(ieee, skb, dest)){ + //IEEE80211DMESG("Was for me!"); + ieee->softmac_stats.tx_probe_rs++; + ieee80211_resp_to_probe(ieee, dest); + } +} + +//static inline void +inline void ieee80211_rx_auth_rq(struct ieee80211_device *ieee, struct sk_buff *skb) +{ + u8 dest[ETH_ALEN]; + int status; + //IEEE80211DMESG("Rx probe"); + ieee->softmac_stats.rx_auth_rq++; + + if ((status = auth_rq_parse(skb, dest))!= -1){ + ieee80211_resp_to_auth(ieee, status, dest); + } + //DMESG("Dest is "MACSTR, MAC2STR(dest)); + +} + +//static inline void +inline void +ieee80211_rx_assoc_rq(struct ieee80211_device *ieee, struct sk_buff *skb) +{ + + u8 dest[ETH_ALEN]; + //unsigned long flags; + + ieee->softmac_stats.rx_ass_rq++; + if (assoc_rq_parse(skb,dest) != -1){ + ieee80211_resp_to_assoc_rq(ieee, dest); + } + + printk(KERN_INFO"New client associated: "MAC_FMT"\n", MAC_ARG(dest)); + //FIXME + #if 0 + spin_lock_irqsave(&ieee->lock,flags); + add_associate(ieee,dest); + spin_unlock_irqrestore(&ieee->lock,flags); + #endif +} + + + +void ieee80211_sta_ps_send_null_frame(struct ieee80211_device *ieee, short pwr) +{ + + struct sk_buff *buf = ieee80211_null_func(ieee, pwr); + + printk(KERN_ALERT "ieee80211_sta_ps_send_null_frame \n"); + if (buf) + softmac_ps_mgmt_xmit(buf, ieee); + +} + + +short ieee80211_sta_ps_sleep(struct ieee80211_device *ieee, u32 *time_h, u32 *time_l) +{ + int timeout = ieee->ps_timeout; + u8 dtim; + /*if(ieee->ps == IEEE80211_PS_DISABLED || + ieee->iw_mode != IW_MODE_INFRA || + ieee->state != IEEE80211_LINKED) + + return 0; + */ + dtim = ieee->current_network.dtim_data; + //printk("DTIM\n"); + if(!(dtim & IEEE80211_DTIM_VALID)) + return 0; + //printk("VALID\n"); + ieee->current_network.dtim_data = IEEE80211_DTIM_INVALID; + + if(dtim & ((IEEE80211_DTIM_UCAST | IEEE80211_DTIM_MBCAST)& ieee->ps)) + return 2; + + if(!time_after(jiffies, ieee->dev->trans_start + MSECS(timeout))) + return 0; + + if(!time_after(jiffies, ieee->last_rx_ps_time + MSECS(timeout))) + return 0; + + if((ieee->softmac_features & IEEE_SOFTMAC_SINGLE_QUEUE ) && + (ieee->mgmt_queue_tail != ieee->mgmt_queue_head)) + return 0; + + if(time_l){ + *time_l = ieee->current_network.last_dtim_sta_time[0] + + (ieee->current_network.beacon_interval + * ieee->current_network.dtim_period) * 1000; + } + + if(time_h){ + *time_h = ieee->current_network.last_dtim_sta_time[1]; + if(time_l && *time_l < ieee->current_network.last_dtim_sta_time[0]) + *time_h += 1; + } + + return 1; + + +} + +inline void ieee80211_sta_ps(struct ieee80211_device *ieee) +{ + + u32 th,tl; + short sleep; + + unsigned long flags,flags2; + + spin_lock_irqsave(&ieee->lock, flags); + + if((ieee->ps == IEEE80211_PS_DISABLED || + ieee->iw_mode != IW_MODE_INFRA || + ieee->state != IEEE80211_LINKED)){ + + // #warning CHECK_LOCK_HERE + spin_lock_irqsave(&ieee->mgmt_tx_lock, flags2); + + ieee80211_sta_wakeup(ieee, 1); + + spin_unlock_irqrestore(&ieee->mgmt_tx_lock, flags2); + } + + sleep = ieee80211_sta_ps_sleep(ieee,&th, &tl); + /* 2 wake, 1 sleep, 0 do nothing */ + if(sleep == 0) + goto out; + + if(sleep == 1){ + + if(ieee->sta_sleep == 1) + ieee->enter_sleep_state(ieee->dev,th,tl); + + else if(ieee->sta_sleep == 0){ + // printk("send null 1\n"); + spin_lock_irqsave(&ieee->mgmt_tx_lock, flags2); + + if(ieee->ps_is_queue_empty(ieee->dev)){ + + + ieee->sta_sleep = 2; + + ieee->ps_request_tx_ack(ieee->dev); + + ieee80211_sta_ps_send_null_frame(ieee,1); + + ieee->ps_th = th; + ieee->ps_tl = tl; + } + spin_unlock_irqrestore(&ieee->mgmt_tx_lock, flags2); + + } + + + }else if(sleep == 2){ +//#warning CHECK_LOCK_HERE + spin_lock_irqsave(&ieee->mgmt_tx_lock, flags2); + + ieee80211_sta_wakeup(ieee,1); + + spin_unlock_irqrestore(&ieee->mgmt_tx_lock, flags2); + } + +out: + spin_unlock_irqrestore(&ieee->lock, flags); + +} + +void ieee80211_sta_wakeup(struct ieee80211_device *ieee, short nl) +{ + if(ieee->sta_sleep == 0){ + if(nl){ + printk("Warning: driver is probably failing to report TX ps error\n"); + ieee->ps_request_tx_ack(ieee->dev); + ieee80211_sta_ps_send_null_frame(ieee, 0); + } + return; + + } + + if(ieee->sta_sleep == 1) + ieee->sta_wake_up(ieee->dev); + + ieee->sta_sleep = 0; + + if(nl){ + ieee->ps_request_tx_ack(ieee->dev); + ieee80211_sta_ps_send_null_frame(ieee, 0); + } +} + +void ieee80211_ps_tx_ack(struct ieee80211_device *ieee, short success) +{ + unsigned long flags,flags2; + + spin_lock_irqsave(&ieee->lock, flags); + + if(ieee->sta_sleep == 2){ + /* Null frame with PS bit set */ + if(success){ + ieee->sta_sleep = 1; + ieee->enter_sleep_state(ieee->dev,ieee->ps_th,ieee->ps_tl); + } + /* if the card report not success we can't be sure the AP + * has not RXed so we can't assume the AP believe us awake + */ + } + /* 21112005 - tx again null without PS bit if lost */ + else { + + if((ieee->sta_sleep == 0) && !success){ + spin_lock_irqsave(&ieee->mgmt_tx_lock, flags2); + ieee80211_sta_ps_send_null_frame(ieee, 0); + spin_unlock_irqrestore(&ieee->mgmt_tx_lock, flags2); + } + } + spin_unlock_irqrestore(&ieee->lock, flags); +} + +inline int +ieee80211_rx_frame_softmac(struct ieee80211_device *ieee, struct sk_buff *skb, + struct ieee80211_rx_stats *rx_stats, u16 type, + u16 stype) +{ + struct ieee80211_hdr_3addr *header = (struct ieee80211_hdr_3addr *) skb->data; + u16 errcode; + u8* challenge=NULL; + int chlen=0; + int aid=0; + struct ieee80211_assoc_response_frame *assoc_resp; + struct ieee80211_info_element *info_element; + + if(!ieee->proto_started) + return 0; + + if(ieee->sta_sleep || (ieee->ps != IEEE80211_PS_DISABLED && + ieee->iw_mode == IW_MODE_INFRA && + ieee->state == IEEE80211_LINKED)) + + tasklet_schedule(&ieee->ps_task); + + if(WLAN_FC_GET_STYPE(header->frame_ctl) != IEEE80211_STYPE_PROBE_RESP && + WLAN_FC_GET_STYPE(header->frame_ctl) != IEEE80211_STYPE_BEACON) + ieee->last_rx_ps_time = jiffies; + + switch (WLAN_FC_GET_STYPE(header->frame_ctl)) { + case IEEE80211_STYPE_ASSOC_RESP: + case IEEE80211_STYPE_REASSOC_RESP: + + IEEE80211_DEBUG_MGMT("received [RE]ASSOCIATION RESPONSE (%d)\n", + WLAN_FC_GET_STYPE(header->frame_ctl)); + //printk(KERN_WARNING "Received association response\n"); + if ((ieee->softmac_features & IEEE_SOFTMAC_ASSOCIATE) && + ieee->state == IEEE80211_ASSOCIATING_AUTHENTICATED && + ieee->iw_mode == IW_MODE_INFRA){ + if (0 == (errcode=assoc_parse(skb, &aid))){ + u16 left; + + ieee->state=IEEE80211_LINKED; + ieee->assoc_id = aid; + ieee->softmac_stats.rx_ass_ok++; + + //printk(KERN_WARNING "nic_type = %s", (rx_stats->nic_type == 1)?"rtl8187":"rtl8187B"); + if(1 == rx_stats->nic_type) //card type is 8187 + { + goto associate_complete; + } + assoc_resp = (struct ieee80211_assoc_response_frame*)skb->data; + info_element = &assoc_resp->info_element; + left = skb->len - ((void*)info_element - (void*)assoc_resp); + + while (left >= sizeof(struct ieee80211_info_element_hdr)) { + if (sizeof(struct ieee80211_info_element_hdr) + info_element->len > left) { + printk(KERN_WARNING "[re]associate reeponse error!"); + return 1; + } + switch (info_element->id) { + case MFIE_TYPE_GENERIC: + IEEE80211_DEBUG_SCAN("MFIE_TYPE_GENERIC: %d bytes\n", info_element->len); + if (info_element->len >= 8 && + info_element->data[0] == 0x00 && + info_element->data[1] == 0x50 && + info_element->data[2] == 0xf2 && + info_element->data[3] == 0x02 && + info_element->data[4] == 0x01) { + // Not care about version at present. + //WMM Parameter Element + memcpy(ieee->current_network.wmm_param,(u8*)(info_element->data\ + + 8),(info_element->len - 8)); + + if (((ieee->current_network.wmm_info^info_element->data[6])& \ + 0x0f)||(!ieee->init_wmmparam_flag)) { + //refresh paramete element for current network + // update the register parameter for hardware + ieee->init_wmmparam_flag = 1; + //ieee->wmm_param_update(ieee); + //schedule_work(&ieee->wmm_param_update_wq); +#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0) + queue_work(ieee->wq, &ieee->wmm_param_update_wq); +#else + schedule_task(&ieee->wmm_param_update_wq); +#endif + + } + //update info_element for current network + ieee->current_network.wmm_info = info_element->data[6]; + } + break; + default: + //nothing to do at present!!! + break; + } + + left -= sizeof(struct ieee80211_info_element_hdr) + + info_element->len; + info_element = (struct ieee80211_info_element *) + &info_element->data[info_element->len]; + } + if(!ieee->init_wmmparam_flag) //legacy AP, reset the AC_xx_param register + { +#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0) + queue_work(ieee->wq,&ieee->wmm_param_update_wq); +#else + schedule_task(&ieee->wmm_param_update_wq); +#endif + ieee->init_wmmparam_flag = 1;//indicate AC_xx_param upated since last associate + } +associate_complete: + ieee80211_associate_complete(ieee); + }else{ + ieee->softmac_stats.rx_ass_err++; + IEEE80211_DEBUG_MGMT( + "Association response status code 0x%x\n", + errcode); + printk(KERN_WARNING "Association response status code 0x%x\n", + errcode); + ieee80211_associate_abort(ieee); + } + } +#ifdef _RTL8187_EXT_PATCH_ + else if ((ieee->iw_mode == ieee->iw_ext_mode) && ieee->ext_patch_ieee80211_rx_frame_softmac_on_assoc_rsp) + { + ieee->ext_patch_ieee80211_rx_frame_softmac_on_assoc_rsp(ieee, skb); + } +#endif + break; + + case IEEE80211_STYPE_ASSOC_REQ: + case IEEE80211_STYPE_REASSOC_REQ: + //printk("Received IEEE80211_STYPE_ASSOC_REQ\n"); + + if ((ieee->softmac_features & IEEE_SOFTMAC_ASSOCIATE) && + ieee->iw_mode == IW_MODE_MASTER) + + ieee80211_rx_assoc_rq(ieee, skb); +#ifdef _RTL8187_EXT_PATCH_ + else if ((ieee->iw_mode == ieee->iw_ext_mode) && ieee->ext_patch_ieee80211_rx_frame_softmac_on_assoc_req) + { + ieee->ext_patch_ieee80211_rx_frame_softmac_on_assoc_req(ieee, skb); + } +#endif + break; + + case IEEE80211_STYPE_AUTH: + //printk("Received authentication response\n"); + +#ifdef _RTL8187_EXT_PATCH_ +//printk("IEEE80211_STYPE_AUTH\n"); + if((ieee->iw_mode == ieee->iw_ext_mode) && ieee->ext_patch_ieee80211_rx_frame_softmac_on_auth) + if( ieee->ext_patch_ieee80211_rx_frame_softmac_on_auth(ieee, skb, rx_stats) ); +#endif + if (ieee->softmac_features & IEEE_SOFTMAC_ASSOCIATE){ + if (ieee->state == IEEE80211_ASSOCIATING_AUTHENTICATING && + ieee->iw_mode == IW_MODE_INFRA){ + + IEEE80211_DEBUG_MGMT("Received authentication response"); + + if (0 == (errcode=auth_parse(skb, &challenge, &chlen))){ + if(ieee->open_wep || !challenge){ + ieee->state = IEEE80211_ASSOCIATING_AUTHENTICATED; + ieee->softmac_stats.rx_auth_rs_ok++; + + ieee80211_associate_step2(ieee); + }else{ + ieee80211_auth_challenge(ieee, challenge, chlen); + } + }else{ + ieee->softmac_stats.rx_auth_rs_err++; + IEEE80211_DEBUG_MGMT("Authentication respose status code 0x%x",errcode); + ieee80211_associate_abort(ieee); + } + + }else if (ieee->iw_mode == IW_MODE_MASTER){ + ieee80211_rx_auth_rq(ieee, skb); + } + } + break; + + case IEEE80211_STYPE_PROBE_REQ: + //printk("Received IEEE80211_STYPE_PROBE_REQ\n"); + + if ((ieee->softmac_features & IEEE_SOFTMAC_PROBERS) && + ((ieee->iw_mode == IW_MODE_ADHOC || + ieee->iw_mode == IW_MODE_MASTER) && + ieee->state == IEEE80211_LINKED)) + + ieee80211_rx_probe_rq(ieee, skb); + break; + + case IEEE80211_STYPE_DISASSOC: + case IEEE80211_STYPE_DEAUTH: + //printk("Received IEEE80211_STYPE_DISASSOC\n"); +#ifdef _RTL8187_EXT_PATCH_ +//printk("IEEE80211_STYPE_DEAUTH\n"); + if((ieee->iw_mode == ieee->iw_ext_mode) && ieee->ext_patch_ieee80211_rx_frame_softmac_on_deauth) + if( ieee->ext_patch_ieee80211_rx_frame_softmac_on_deauth(ieee, skb, rx_stats) ) ; +#endif + /* FIXME for now repeat all the association procedure + * both for disassociation and deauthentication + */ + if ((ieee->softmac_features & IEEE_SOFTMAC_ASSOCIATE) && + ieee->state == IEEE80211_LINKED && + ieee->iw_mode == IW_MODE_INFRA){ + + ieee->state = IEEE80211_ASSOCIATING; + ieee->softmac_stats.reassoc++; + + notify_wx_assoc_event(ieee); +#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0) + queue_work(ieee->wq, &ieee->associate_procedure_wq); +#else + schedule_task(&ieee->associate_procedure_wq); +#endif + } + + break; + + default: + return -1; + break; + } + + //dev_kfree_skb_any(skb); + return 0; +} + + + +/* following are for a simplier TX queue management. + * Instead of using netif_[stop/wake]_queue the driver + * will uses these two function (plus a reset one), that + * will internally uses the kernel netif_* and takes + * care of the ieee802.11 fragmentation. + * So the driver receives a fragment per time and might + * call the stop function when it want without take care + * to have enought room to TX an entire packet. + * This might be useful if each fragment need it's own + * descriptor, thus just keep a total free memory > than + * the max fragmentation treshold is not enought.. If the + * ieee802.11 stack passed a TXB struct then you needed + * to keep N free descriptors where + * N = MAX_PACKET_SIZE / MIN_FRAG_TRESHOLD + * In this way you need just one and the 802.11 stack + * will take care of buffering fragments and pass them to + * to the driver later, when it wakes the queue. + */ + +void ieee80211_softmac_xmit(struct ieee80211_txb *txb, struct ieee80211_device *ieee) +{ + + + unsigned long flags; + int i; +#ifdef _RTL8187_EXT_PATCH_ + int rate = ieee->rate; +#endif + + spin_lock_irqsave(&ieee->lock,flags); + #if 0 + if(ieee->queue_stop){ + IEEE80211DMESG("EE: IEEE hard_start_xmit invoked when kernel queue should be stopped"); + netif_stop_queue(ieee->dev); + ieee->ieee_stats.swtxstop++; + //dev_kfree_skb_any(skb); + err = 1; + goto exit; + } + + ieee->stats.tx_bytes+=skb->len; + + + txb=ieee80211_skb_to_txb(ieee,skb); + + + if(txb==NULL){ + IEEE80211DMESG("WW: IEEE stack failed to provide txb"); + //dev_kfree_skb_any(skb); + err = 1; + goto exit; + } + #endif + +#ifdef _RTL8187_EXT_PATCH_ + if((ieee->iw_mode == ieee->iw_ext_mode) && ieee->ext_patch_ieee80211_softmac_xmit_get_rate && txb->nr_frags) + { + rate = ieee->ext_patch_ieee80211_softmac_xmit_get_rate(ieee, txb->fragments[0]); + } +#endif + /* called with 2nd parm 0, no tx mgmt lock required */ + ieee80211_sta_wakeup(ieee,0); + + for(i = 0; i < txb->nr_frags; i++) { + + if (ieee->queue_stop){ + ieee->tx_pending.txb = txb; + ieee->tx_pending.frag = i; + goto exit; + }else{ + ieee->softmac_data_hard_start_xmit( + txb->fragments[i], +#ifdef _RTL8187_EXT_PATCH_ + ieee->dev, rate); +#else + ieee->dev,ieee->rate); +#endif + //(i+1)nr_frags); + ieee->stats.tx_packets++; + ieee->stats.tx_bytes += txb->fragments[i]->len; + ieee->dev->trans_start = jiffies; + } + } + + ieee80211_txb_free(txb); + + exit: + spin_unlock_irqrestore(&ieee->lock,flags); + +} + +/* called with ieee->lock acquired */ +void ieee80211_resume_tx(struct ieee80211_device *ieee) +{ + int i; + for(i = ieee->tx_pending.frag; i < ieee->tx_pending.txb->nr_frags; i++) { + + if (ieee->queue_stop){ + ieee->tx_pending.frag = i; + return; + }else{ + + ieee->softmac_data_hard_start_xmit( + ieee->tx_pending.txb->fragments[i], + ieee->dev,ieee->rate); + //(i+1)tx_pending.txb->nr_frags); + ieee->stats.tx_packets++; + ieee->dev->trans_start = jiffies; + } + } + + + ieee80211_txb_free(ieee->tx_pending.txb); + ieee->tx_pending.txb = NULL; +} + + +void ieee80211_reset_queue(struct ieee80211_device *ieee) +{ + unsigned long flags; + + spin_lock_irqsave(&ieee->lock,flags); + init_mgmt_queue(ieee); + if (ieee->tx_pending.txb){ + ieee80211_txb_free(ieee->tx_pending.txb); + ieee->tx_pending.txb = NULL; + } + ieee->queue_stop = 0; + spin_unlock_irqrestore(&ieee->lock,flags); + +} + +void ieee80211_wake_queue(struct ieee80211_device *ieee) +{ + + unsigned long flags; + struct sk_buff *skb; + struct ieee80211_hdr_3addr *header; + + spin_lock_irqsave(&ieee->lock,flags); + if (! ieee->queue_stop) goto exit; + + ieee->queue_stop = 0; + + if(ieee->softmac_features & IEEE_SOFTMAC_SINGLE_QUEUE){ + while (!ieee->queue_stop && (skb = dequeue_mgmt(ieee))){ + + header = (struct ieee80211_hdr_3addr *) skb->data; + + header->seq_ctl = cpu_to_le16(ieee->seq_ctrl[0] << 4); + + if (ieee->seq_ctrl[0] == 0xFFF) + ieee->seq_ctrl[0] = 0; + else + ieee->seq_ctrl[0]++; + + printk(KERN_ALERT "ieee80211_wake_queue \n"); + ieee->softmac_data_hard_start_xmit(skb,ieee->dev,ieee->basic_rate); + dev_kfree_skb_any(skb);//edit by thomas + } + } + if (!ieee->queue_stop && ieee->tx_pending.txb) + ieee80211_resume_tx(ieee); + + if (!ieee->queue_stop && netif_queue_stopped(ieee->dev)){ + ieee->softmac_stats.swtxawake++; + netif_wake_queue(ieee->dev); + } + +exit : + spin_unlock_irqrestore(&ieee->lock,flags); +} + + +void ieee80211_stop_queue(struct ieee80211_device *ieee) +{ + //unsigned long flags; + //spin_lock_irqsave(&ieee->lock,flags); + + if (! netif_queue_stopped(ieee->dev)){ + netif_stop_queue(ieee->dev); + ieee->softmac_stats.swtxstop++; + } + ieee->queue_stop = 1; + //spin_unlock_irqrestore(&ieee->lock,flags); + +} + + +inline void ieee80211_randomize_cell(struct ieee80211_device *ieee) +{ + + get_random_bytes(ieee->current_network.bssid, ETH_ALEN); + + /* an IBSS cell address must have the two less significant + * bits of the first byte = 2 + */ + ieee->current_network.bssid[0] &= ~0x01; + ieee->current_network.bssid[0] |= 0x02; +} + +/* called in user context only */ +void ieee80211_start_master_bss(struct ieee80211_device *ieee) +{ + ieee->assoc_id = 1; + + if (ieee->current_network.ssid_len == 0){ + strncpy(ieee->current_network.ssid, + IEEE80211_DEFAULT_TX_ESSID, + IW_ESSID_MAX_SIZE); + + ieee->current_network.ssid_len = strlen(IEEE80211_DEFAULT_TX_ESSID); + ieee->ssid_set = 1; + } + + memcpy(ieee->current_network.bssid, ieee->dev->dev_addr, ETH_ALEN); + + ieee->set_chan(ieee->dev, ieee->current_network.channel); + ieee->state = IEEE80211_LINKED; + +//by lizhaoming for LED LINK +#ifdef LED_SHIN + { + struct net_device *dev = ieee->dev; + ieee->ieee80211_led_contorl(dev, LED_CTL_LINK); + } +#endif + ieee->link_change(ieee->dev); + notify_wx_assoc_event(ieee); + + if (ieee->data_hard_resume) + ieee->data_hard_resume(ieee->dev); + + netif_carrier_on(ieee->dev); +} + +void ieee80211_start_monitor_mode(struct ieee80211_device *ieee) +{ + if(ieee->raw_tx){ + + if (ieee->data_hard_resume) + ieee->data_hard_resume(ieee->dev); + + netif_carrier_on(ieee->dev); + } +} + +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)) +void ieee80211_start_ibss_wq(struct work_struct *work) +{ + struct delayed_work *dwork = container_of(work, struct delayed_work, work); + struct ieee80211_device *ieee = container_of(dwork, struct ieee80211_device, start_ibss_wq); +#else +void ieee80211_start_ibss_wq(struct ieee80211_device *ieee) +{ +#endif + + /* iwconfig mode ad-hoc will schedule this and return + * on the other hand this will block further iwconfig SET + * operations because of the wx_sem hold. + * Anyway some most set operations set a flag to speed-up + * (abort) this wq (when syncro scanning) before sleeping + * on the semaphore + */ + + down(&ieee->wx_sem); + + if (ieee->current_network.ssid_len == 0){ + strcpy(ieee->current_network.ssid,IEEE80211_DEFAULT_TX_ESSID); + ieee->current_network.ssid_len = strlen(IEEE80211_DEFAULT_TX_ESSID); + ieee->ssid_set = 1; + } + +//by lizhaoming for LED BLINK 2008.6.23 +#ifdef LED_SHIN + { + struct net_device *dev = ieee->dev; + ieee->ieee80211_led_contorl(dev, LED_CTL_SITE_SURVEY); + } +#endif + + /* check if we have this cell in our network list */ + ieee80211_softmac_check_all_nets(ieee); + +#ifdef ENABLE_DOT11D + //[World wide 13]: + // Adhoc: + // (1) active scan from ch1~11 and passive scan from ch12~13 + // (2) IBSS can join ch1~13 adhoc, but only start at ch10. + if(ieee->state == IEEE80211_NOLINK) + if(ieee->IbssStartChnl != 0) + ieee->current_network.channel = ieee->IbssStartChnl;//chan 10 +#endif + + /* if not then the state is not linked. Maybe the user swithced to + * ad-hoc mode just after being in monitor mode, or just after + * being very few time in managed mode (so the card have had no + * time to scan all the chans..) or we have just run up the iface + * after setting ad-hoc mode. So we have to give another try.. + * Here, in ibss mode, should be safe to do this without extra care + * (in bss mode we had to make sure no-one tryed to associate when + * we had just checked the ieee->state and we was going to start the + * scan) beacause in ibss mode the ieee80211_new_net function, when + * finds a good net, just set the ieee->state to IEEE80211_LINKED, + * so, at worst, we waste a bit of time to initiate an unneeded syncro + * scan, that will stop at the first round because it sees the state + * associated. + */ + if (ieee->state == IEEE80211_NOLINK){ + ieee80211_start_scan_syncro(ieee); + } + + /* the network definitively is not here.. create a new cell */ + if (ieee->state == IEEE80211_NOLINK){ + printk("creating new IBSS cell\n"); + ieee->state = IEEE80211_LINKED; + if(!ieee->wap_set) + ieee80211_randomize_cell(ieee); + + if(ieee->modulation & IEEE80211_CCK_MODULATION){ + + ieee->current_network.rates_len = 4; + + ieee->current_network.rates[0] = IEEE80211_BASIC_RATE_MASK | IEEE80211_CCK_RATE_1MB; + ieee->current_network.rates[1] = IEEE80211_BASIC_RATE_MASK | IEEE80211_CCK_RATE_2MB; + ieee->current_network.rates[2] = IEEE80211_BASIC_RATE_MASK | IEEE80211_CCK_RATE_5MB; + ieee->current_network.rates[3] = IEEE80211_BASIC_RATE_MASK | IEEE80211_CCK_RATE_11MB; + + }else + ieee->current_network.rates_len = 0; + + if(ieee->modulation & IEEE80211_OFDM_MODULATION){ + ieee->current_network.rates_ex_len = 8; + + ieee->current_network.rates_ex[0] = IEEE80211_BASIC_RATE_MASK | IEEE80211_OFDM_RATE_6MB; + ieee->current_network.rates_ex[1] = IEEE80211_BASIC_RATE_MASK | IEEE80211_OFDM_RATE_9MB; + ieee->current_network.rates_ex[2] = IEEE80211_BASIC_RATE_MASK | IEEE80211_OFDM_RATE_12MB; + ieee->current_network.rates_ex[3] = IEEE80211_BASIC_RATE_MASK | IEEE80211_OFDM_RATE_18MB; + ieee->current_network.rates_ex[4] = IEEE80211_BASIC_RATE_MASK | IEEE80211_OFDM_RATE_24MB; + ieee->current_network.rates_ex[5] = IEEE80211_BASIC_RATE_MASK | IEEE80211_OFDM_RATE_36MB; + ieee->current_network.rates_ex[6] = IEEE80211_BASIC_RATE_MASK | IEEE80211_OFDM_RATE_48MB; + ieee->current_network.rates_ex[7] = IEEE80211_BASIC_RATE_MASK | IEEE80211_OFDM_RATE_54MB; + + ieee->rate = 540; + }else{ + ieee->current_network.rates_ex_len = 0; + ieee->rate = 110; + } + + // By default, WMM function will be disabled in IBSS mode + ieee->current_network.QoS_Enable = 0; + + ieee->current_network.atim_window = 0; + ieee->current_network.capability = WLAN_CAPABILITY_IBSS; + if(ieee->short_slot) + ieee->current_network.capability |= WLAN_CAPABILITY_SHORT_SLOT; + + } + + ieee->state = IEEE80211_LINKED; + +//by lizhaoming for LED LINK +#ifdef LED_SHIN + { + struct net_device *dev = ieee->dev; + ieee->ieee80211_led_contorl(dev, LED_CTL_LINK); + } +#endif + + ieee->set_chan(ieee->dev, ieee->current_network.channel); + ieee->link_change(ieee->dev); + + notify_wx_assoc_event(ieee); + + ieee80211_start_send_beacons(ieee); + printk(KERN_WARNING "after sending beacon packet!\n"); + + if (ieee->data_hard_resume) + ieee->data_hard_resume(ieee->dev); + + netif_carrier_on(ieee->dev); + + up(&ieee->wx_sem); +} + +inline void ieee80211_start_ibss(struct ieee80211_device *ieee) +{ +#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0) + queue_delayed_work(ieee->wq, &ieee->start_ibss_wq, 150); //change to delayed work, delayed time is need to check +#else + schedule_task(&ieee->start_ibss_wq); +#endif +} + +/* this is called only in user context, with wx_sem held */ +void ieee80211_start_bss(struct ieee80211_device *ieee) +{ + unsigned long flags; + /* check if we have already found the net we + * are interested in (if any). + * if not (we are disassociated and we are not + * in associating / authenticating phase) start the background scanning. + */ + +//by lizhaoming for LED BLINK 2008.6.23 +#ifdef LED_SHIN + { + struct net_device *dev = ieee->dev; + ieee->ieee80211_led_contorl(dev, LED_CTL_SITE_SURVEY); + } +#endif + +#ifdef ENABLE_DOT11D + // + // Ref: 802.11d 11.1.3.3 + // STA shall not start a BSS unless properly formed Beacon frame including a Country IE. + // + if(IS_DOT11D_ENABLE(ieee) && !IS_COUNTRY_IE_VALID(ieee)) + { + if(! ieee->bGlobalDomain) + { + return; + } + } +#endif + //printk("======>%s()\n",__FUNCTION__); + ieee80211_softmac_check_all_nets(ieee); + + /* ensure no-one start an associating process (thus setting + * the ieee->state to ieee80211_ASSOCIATING) while we + * have just cheked it and we are going to enable scan. + * The ieee80211_new_net function is always called with + * lock held (from both ieee80211_softmac_check_all_nets and + * the rx path), so we cannot be in the middle of such function + */ + + spin_lock_irqsave(&ieee->lock, flags); + if (ieee->state == IEEE80211_NOLINK){ + //printk("Not find SSID in network list scan now\n"); + ieee80211_start_scan(ieee); + } + spin_unlock_irqrestore(&ieee->lock, flags); + +} + +/* called only in userspace context */ +void ieee80211_disassociate(struct ieee80211_device *ieee) +{ + netif_carrier_off(ieee->dev); + + if (ieee->softmac_features & IEEE_SOFTMAC_TX_QUEUE) + ieee80211_reset_queue(ieee); + + if (ieee->data_hard_stop) + ieee->data_hard_stop(ieee->dev); + +#ifdef ENABLE_DOT11D + if(IS_DOT11D_ENABLE(ieee)) + Dot11d_Reset(ieee); +#endif + + ieee->state = IEEE80211_NOLINK; + ieee->link_change(ieee->dev); + notify_wx_assoc_event(ieee); + +} +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)) +void ieee80211_associate_retry_wq(struct work_struct *work) +{ + struct delayed_work *dwork = container_of(work, struct delayed_work, work); + struct ieee80211_device *ieee = container_of(dwork, struct ieee80211_device, associate_retry_wq); +#else +void ieee80211_associate_retry_wq(struct ieee80211_device *ieee) +{ +#endif + unsigned long flags; + + down(&ieee->wx_sem); + if(!ieee->proto_started) + goto exit; + + if(ieee->state != IEEE80211_ASSOCIATING_RETRY) + goto exit; + + /* until we do not set the state to IEEE80211_NOLINK + * there are no possibility to have someone else trying + * to start an association procdure (we get here with + * ieee->state = IEEE80211_ASSOCIATING). + * When we set the state to IEEE80211_NOLINK it is possible + * that the RX path run an attempt to associate, but + * both ieee80211_softmac_check_all_nets and the + * RX path works with ieee->lock held so there are no + * problems. If we are still disassociated then start a scan. + * the lock here is necessary to ensure no one try to start + * an association procedure when we have just checked the + * state and we are going to start the scan. + */ + ieee->state = IEEE80211_NOLINK; + + ieee80211_softmac_check_all_nets(ieee); + + spin_lock_irqsave(&ieee->lock, flags); + if(ieee->state == IEEE80211_NOLINK) + { + printk("%s():Not find SSID:%s[ch=%d, mode=%s] in network list scan now\n", __FUNCTION__, + ieee->current_network.ssid,ieee->current_network.channel, + (ieee->iw_mode == IW_MODE_INFRA) ? "BSS" : "IBSS"); + + ieee80211_start_scan(ieee); + } + + spin_unlock_irqrestore(&ieee->lock, flags); + +exit: + up(&ieee->wx_sem); +} + +struct sk_buff *ieee80211_get_beacon_(struct ieee80211_device *ieee) +{ + u8 broadcast_addr[] = {0xff,0xff,0xff,0xff,0xff,0xff}; + + struct sk_buff *skb = NULL; + struct ieee80211_probe_response *b; + +//rz +#ifdef _RTL8187_EXT_PATCH_ + if((ieee->iw_mode == ieee->iw_ext_mode) && ieee->ext_patch_get_beacon_get_probersp ) + skb = ieee->ext_patch_get_beacon_get_probersp(ieee, broadcast_addr, &(ieee->current_network)); + else + skb = ieee80211_probe_resp(ieee, broadcast_addr); +#else + skb = ieee80211_probe_resp(ieee, broadcast_addr); +#endif +// + if (!skb) + return NULL; + + b = (struct ieee80211_probe_response *) skb->data; + b->header.frame_ctl = cpu_to_le16(IEEE80211_STYPE_BEACON); + + return skb; + +} + +struct sk_buff *ieee80211_get_beacon(struct ieee80211_device *ieee) +{ + struct sk_buff *skb; + struct ieee80211_probe_response *b; +// printk("=========>%s()\n", __FUNCTION__); + skb = ieee80211_get_beacon_(ieee); + if(!skb) + return NULL; + + b = (struct ieee80211_probe_response *) skb->data; + b->header.seq_ctrl = cpu_to_le16(ieee->seq_ctrl[0] << 4); + + if (ieee->seq_ctrl[0] == 0xFFF) + ieee->seq_ctrl[0] = 0; + else + ieee->seq_ctrl[0]++; + + return skb; +} + +void ieee80211_softmac_stop_protocol(struct ieee80211_device *ieee) +{ + ieee->sync_scan_hurryup = 1; + down(&ieee->wx_sem); + ieee80211_stop_protocol(ieee); + up(&ieee->wx_sem); +} + + +void ieee80211_stop_protocol(struct ieee80211_device *ieee) +{ + if (!ieee->proto_started) + return; + + ieee->proto_started = 0; + //printk("=====>%s\n", __func__); + +#ifdef _RTL8187_EXT_PATCH_ + if(ieee->ext_patch_ieee80211_stop_protocol) + ieee->ext_patch_ieee80211_stop_protocol(ieee); +//if call queue_delayed_work,can call this,or do nothing.. +//edit by lawrence,20071118 +#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0) +// cancel_delayed_work(&ieee->ext_stop_scan_wq); +// cancel_delayed_work(&ieee->ext_send_beacon_wq); +#endif +#endif // _RTL8187_EXT_PATCH_ + + ieee80211_stop_send_beacons(ieee); + + del_timer_sync(&ieee->associate_timer); +#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0) + cancel_delayed_work(&ieee->associate_retry_wq); + cancel_delayed_work(&ieee->start_ibss_wq); //cancel ibss start workqueue when stop protocol +#endif + ieee80211_stop_scan(ieee); + + ieee80211_disassociate(ieee); + //printk("<=====%s\n", __func__); + +} + +void ieee80211_softmac_start_protocol(struct ieee80211_device *ieee) +{ + ieee->sync_scan_hurryup = 0; + down(&ieee->wx_sem); + ieee80211_start_protocol(ieee); + up(&ieee->wx_sem); +} + +void ieee80211_start_protocol(struct ieee80211_device *ieee) +{ + short ch = 0; + int i = 0; + + if (ieee->proto_started) + return; + + //printk("=====>%s\n", __func__); + + ieee->proto_started = 1; + + if (ieee->current_network.channel == 0){ + do{ + ch++; + if (ch > MAX_CHANNEL_NUMBER) + return; /* no channel found */ +#ifdef ENABLE_DOT11D + }while(!GET_DOT11D_INFO(ieee)->channel_map[ch]); +#else + }while(!ieee->channel_map[ch]); +#endif + ieee->current_network.channel = ch; + } + + if (ieee->current_network.beacon_interval == 0) + ieee->current_network.beacon_interval = 100; + + ieee->set_chan(ieee->dev,ieee->current_network.channel); + mdelay(10);//must or link change will fail lzm + + for(i = 0; i < 17; i++) { + ieee->last_rxseq_num[i] = -1; + ieee->last_rxfrag_num[i] = -1; + ieee->last_packet_time[i] = 0; + } + + ieee->init_wmmparam_flag = 0;//reinitialize AC_xx_PARAM registers. + + + /* if the user set the MAC of the ad-hoc cell and then + * switch to managed mode, shall we make sure that association + * attempts does not fail just because the user provide the essid + * and the nic is still checking for the AP MAC ?? + */ + + if (ieee->iw_mode == IW_MODE_INFRA){ + ieee80211_start_bss(ieee); + // printk("==========> IW_MODE_INFRA\n"); + } + else if (ieee->iw_mode == IW_MODE_ADHOC){ + // printk("==========> IW_MODE_ADHOC\n"); + ieee80211_start_ibss(ieee); + } + else if (ieee->iw_mode == IW_MODE_MASTER){ + ieee80211_start_master_bss(ieee); +// printk("==========> IW_MODE_MASTER\n"); + } + else if(ieee->iw_mode == IW_MODE_MONITOR){ + ieee80211_start_monitor_mode(ieee); +// printk("==========> IW_MODE_MONITOR\n"); + } + +#ifdef _RTL8187_EXT_PATCH_ +// else if((ieee->iw_mode == ieee->iw_ext_mode) && ieee->ext_patch_ieee80211_start_protocol && ieee->ext_patch_ieee80211_start_protocol(ieee)) + else if((ieee->iw_mode == ieee->iw_ext_mode) && ieee->ext_patch_ieee80211_start_protocol) + { + ieee->ext_patch_ieee80211_start_mesh(ieee); + } +#endif +} + + +#define DRV_NAME "Ieee80211" +void ieee80211_softmac_init(struct ieee80211_device *ieee) +{ + int i; + memset(&ieee->current_network, 0, sizeof(struct ieee80211_network)); + + ieee->state = IEEE80211_NOLINK; + ieee->sync_scan_hurryup = 0; + for(i = 0; i < 5; i++) { + ieee->seq_ctrl[i] = 0; + } + + ieee->assoc_id = 0; + ieee->queue_stop = 0; + ieee->scanning = 0; + ieee->scan_watchdog = 0;//lzm add 081215 for roaming + ieee->softmac_features = 0; //so IEEE2100-like driver are happy + ieee->wap_set = 0; + ieee->ssid_set = 0; + ieee->proto_started = 0; + ieee->basic_rate = IEEE80211_DEFAULT_BASIC_RATE; + ieee->rate = 3; + ieee->ps = IEEE80211_PS_DISABLED; + ieee->sta_sleep = 0; +//by amy + ieee->bInactivePs = false; + ieee->actscanning = false; + ieee->ListenInterval = 2; + ieee->NumRxData = 0; + ieee->NumRxDataInPeriod = 0; //YJ,add,080828 + ieee->NumRxBcnInPeriod = 0; //YJ,add,080828 + ieee->bHwRadioOff = false;//by lizhaoming +//by amy +#ifdef _RTL8187_EXT_PATCH_ + ieee->iw_ext_mode = 999; +#endif + + init_mgmt_queue(ieee); + +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) + init_timer(&ieee->scan_timer); + ieee->scan_timer.data = (unsigned long)ieee; + ieee->scan_timer.function = ieee80211_softmac_scan_cb; +#endif + ieee->tx_pending.txb = NULL; + + init_timer(&ieee->associate_timer); + ieee->associate_timer.data = (unsigned long)ieee; + ieee->associate_timer.function = ieee80211_associate_abort_cb; + + init_timer(&ieee->beacon_timer); + ieee->beacon_timer.data = (unsigned long) ieee; + ieee->beacon_timer.function = ieee80211_send_beacon_cb; + +#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0) +#ifdef PF_SYNCTHREAD + ieee->wq = create_workqueue(DRV_NAME,0); +#else + ieee->wq = create_workqueue(DRV_NAME); +#endif +#endif +#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0) +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)//added by lawrence,070702 + INIT_DELAYED_WORK(&ieee->start_ibss_wq, ieee80211_start_ibss_wq); + INIT_WORK(&ieee->associate_complete_wq, ieee80211_associate_complete_wq); + INIT_WORK(&ieee->associate_procedure_wq, ieee80211_associate_procedure_wq); + INIT_DELAYED_WORK(&ieee->softmac_scan_wq, ieee80211_softmac_scan_wq); + INIT_DELAYED_WORK(&ieee->associate_retry_wq, ieee80211_associate_retry_wq); + INIT_WORK(&ieee->wx_sync_scan_wq, ieee80211_wx_sync_scan_wq); +//added by lawrence,20071118 +#ifdef _RTL8187_EXT_PATCH_ + INIT_WORK(&ieee->ext_stop_scan_wq, ieee80211_ext_stop_scan_wq); + //INIT_WORK(&ieee->ext_send_beacon_wq, ieee80211_beacons_start,ieee); + INIT_WORK(&ieee->ext_send_beacon_wq, ext_ieee80211_send_beacon_wq); +#endif //_RTL8187_EXT_PATCH_ +#else + INIT_WORK(&ieee->start_ibss_wq,(void(*)(void*)) ieee80211_start_ibss_wq,ieee); + INIT_WORK(&ieee->associate_retry_wq,(void(*)(void*)) ieee80211_associate_retry_wq,ieee); + INIT_WORK(&ieee->associate_complete_wq,(void(*)(void*)) ieee80211_associate_complete_wq,ieee); + INIT_WORK(&ieee->associate_procedure_wq,(void(*)(void*)) ieee80211_associate_procedure_wq,ieee); + INIT_WORK(&ieee->softmac_scan_wq,(void(*)(void*)) ieee80211_softmac_scan_wq,ieee); + INIT_WORK(&ieee->wx_sync_scan_wq,(void(*)(void*)) ieee80211_wx_sync_scan_wq,ieee); +#ifdef _RTL8187_EXT_PATCH_ + INIT_WORK(&ieee->ext_stop_scan_wq,(void(*)(void*)) ieee80211_ext_stop_scan_wq,ieee); + //INIT_WORK(&ieee->ext_send_beacon_wq,(void(*)(void*)) ieee80211_beacons_start,ieee); + INIT_WORK(&ieee->ext_send_beacon_wq,(void(*)(void*)) ext_ieee80211_send_beacon_wq,ieee); +#endif +#endif +#else + tq_init(&ieee->start_ibss_wq,(void(*)(void*)) ieee80211_start_ibss_wq,ieee); + tq_init(&ieee->associate_retry_wq,(void(*)(void*)) ieee80211_associate_retry_wq,ieee); + tq_init(&ieee->associate_complete_wq,(void(*)(void*)) ieee80211_associate_complete_wq,ieee); + tq_init(&ieee->associate_procedure_wq,(void(*)(void*)) ieee80211_associate_procedure_wq,ieee); + tq_init(&ieee->softmac_scan_wq,(void(*)(void*)) ieee80211_softmac_scan_wq,ieee); + tq_init(&ieee->wx_sync_scan_wq,(void(*)(void*)) ieee80211_wx_sync_scan_wq,ieee); +#ifdef _RTL8187_EXT_PATCH_ + tq_init(&ieee->ext_stop_scan_wq,(void(*)(void*)) ieee80211_ext_stop_scan_wq,ieee); + //tq_init(&ieee->ext_send_beacon_wq,(void(*)(void*)) ieee80211_beacons_start,ieee); + tq_init(&ieee->ext_send_beacon_wq,(void(*)(void*)) ext_ieee80211_send_beacon_wq,ieee); +#endif +#endif + sema_init(&ieee->wx_sem, 1); + sema_init(&ieee->scan_sem, 1); + sema_init(&ieee->ips_sem,1); + spin_lock_init(&ieee->mgmt_tx_lock); + spin_lock_init(&ieee->beacon_lock); + spin_lock_init(&ieee->beaconflag_lock); + tasklet_init(&ieee->ps_task, + (void(*)(unsigned long)) ieee80211_sta_ps, + (unsigned long)ieee); +#ifdef ENABLE_DOT11D + ieee->pDot11dInfo = kmalloc(sizeof(RT_DOT11D_INFO), GFP_ATOMIC); +#endif + +} + +void ieee80211_softmac_free(struct ieee80211_device *ieee) +{ + down(&ieee->wx_sem); + + del_timer_sync(&ieee->associate_timer); + +#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0) + cancel_delayed_work(&ieee->associate_retry_wq); + + + +#ifdef _RTL8187_EXT_PATCH_ + //When kernel>2.6.20,crash.... +// cancel_delayed_work(&ieee->ext_stop_scan_wq); +// cancel_delayed_work(&ieee->ext_send_beacon_wq); +#endif + destroy_workqueue(ieee->wq); +#endif + +#ifdef ENABLE_DOT11D + if(NULL != ieee->pDot11dInfo) + kfree(ieee->pDot11dInfo); +#endif + + up(&ieee->wx_sem); +} + +/******************************************************** + * Start of WPA code. * + * this is stolen from the ipw2200 driver * + ********************************************************/ + + +static int ieee80211_wpa_enable(struct ieee80211_device *ieee, int value) +{ + /* This is called when wpa_supplicant loads and closes the driver + * interface. */ + printk("%s WPA\n",value ? "enabling" : "disabling"); + ieee->wpa_enabled = value; + return 0; +} + + +void ieee80211_wpa_assoc_frame(struct ieee80211_device *ieee, char *wpa_ie, int wpa_ie_len) +{ + /* make sure WPA is enabled */ + ieee80211_wpa_enable(ieee, 1); + + ieee80211_disassociate(ieee); +} + + +static int ieee80211_wpa_mlme(struct ieee80211_device *ieee, int command, int reason) +{ + + int ret = 0; + + switch (command) { + case IEEE_MLME_STA_DEAUTH: + // silently ignore + break; + + case IEEE_MLME_STA_DISASSOC: + ieee80211_disassociate(ieee); + break; + + default: + printk("Unknown MLME request: %d\n", command); + ret = -EOPNOTSUPP; + } + + return ret; +} + + +static int ieee80211_wpa_set_wpa_ie(struct ieee80211_device *ieee, + struct ieee_param *param, int plen) +{ + u8 *buf; + + if (param->u.wpa_ie.len > MAX_WPA_IE_LEN || + (param->u.wpa_ie.len && param->u.wpa_ie.data == NULL)) + return -EINVAL; + + if (param->u.wpa_ie.len) { + buf = kmalloc(param->u.wpa_ie.len, GFP_KERNEL); + if (buf == NULL) + return -ENOMEM; + + memcpy(buf, param->u.wpa_ie.data, param->u.wpa_ie.len); + kfree(ieee->wpa_ie); + ieee->wpa_ie = buf; + ieee->wpa_ie_len = param->u.wpa_ie.len; + } else { + kfree(ieee->wpa_ie); + ieee->wpa_ie = NULL; + ieee->wpa_ie_len = 0; + } + + ieee80211_wpa_assoc_frame(ieee, ieee->wpa_ie, ieee->wpa_ie_len); + return 0; +} + +#define AUTH_ALG_OPEN_SYSTEM 0x1 +#define AUTH_ALG_SHARED_KEY 0x2 + +static int ieee80211_wpa_set_auth_algs(struct ieee80211_device *ieee, int value) +{ + + struct ieee80211_security sec = { + .flags = SEC_AUTH_MODE, + }; + int ret = 0; + + if (value & AUTH_ALG_SHARED_KEY) { + sec.auth_mode = WLAN_AUTH_SHARED_KEY; + ieee->open_wep = 0; + } else { + sec.auth_mode = WLAN_AUTH_OPEN; + ieee->open_wep = 1; + } + + if (ieee->set_security) + ieee->set_security(ieee->dev, &sec); + else + ret = -EOPNOTSUPP; + + return ret; +} + +static int ieee80211_wpa_set_param(struct ieee80211_device *ieee, u8 name, u32 value) +{ + int ret=0; + unsigned long flags; + + switch (name) { + case IEEE_PARAM_WPA_ENABLED: + ret = ieee80211_wpa_enable(ieee, value); + break; + + case IEEE_PARAM_TKIP_COUNTERMEASURES: + ieee->tkip_countermeasures=value; + break; + + case IEEE_PARAM_DROP_UNENCRYPTED: { + /* HACK: + * + * wpa_supplicant calls set_wpa_enabled when the driver + * is loaded and unloaded, regardless of if WPA is being + * used. No other calls are made which can be used to + * determine if encryption will be used or not prior to + * association being expected. If encryption is not being + * used, drop_unencrypted is set to false, else true -- we + * can use this to determine if the CAP_PRIVACY_ON bit should + * be set. + */ + struct ieee80211_security sec = { + .flags = SEC_ENABLED, + .enabled = value, + }; + ieee->drop_unencrypted = value; + /* We only change SEC_LEVEL for open mode. Others + * are set by ipw_wpa_set_encryption. + */ + if (!value) { + sec.flags |= SEC_LEVEL; + sec.level = SEC_LEVEL_0; + } + else { + sec.flags |= SEC_LEVEL; + sec.level = SEC_LEVEL_1; + } + if (ieee->set_security) + ieee->set_security(ieee->dev, &sec); + break; + } + + case IEEE_PARAM_PRIVACY_INVOKED: + ieee->privacy_invoked=value; + break; + + case IEEE_PARAM_AUTH_ALGS: + ret = ieee80211_wpa_set_auth_algs(ieee, value); + break; + + case IEEE_PARAM_IEEE_802_1X: + ieee->ieee802_1x=value; + break; + case IEEE_PARAM_WPAX_SELECT: + // added for WPA2 mixed mode + //printk(KERN_WARNING "------------------------>wpax value = %x\n", value); + spin_lock_irqsave(&ieee->wpax_suitlist_lock,flags); + ieee->wpax_type_set = 1; + ieee->wpax_type_notify = value; + spin_unlock_irqrestore(&ieee->wpax_suitlist_lock,flags); + break; + + default: + printk("Unknown WPA param: %d\n",name); + ret = -EOPNOTSUPP; + } + + return ret; +} + +/* implementation borrowed from hostap driver */ + +static int ieee80211_wpa_set_encryption(struct ieee80211_device *ieee, + struct ieee_param *param, int param_len) +{ + int ret = 0; + + struct ieee80211_crypto_ops *ops; + struct ieee80211_crypt_data **crypt; + + struct ieee80211_security sec = { + .flags = 0, + }; + + param->u.crypt.err = 0; + param->u.crypt.alg[IEEE_CRYPT_ALG_NAME_LEN - 1] = '\0'; + + if (param_len != + (int) ((char *) param->u.crypt.key - (char *) param) + + param->u.crypt.key_len) { + printk("Len mismatch %d, %d\n", param_len, + param->u.crypt.key_len); + return -EINVAL; + } + if (param->sta_addr[0] == 0xff && param->sta_addr[1] == 0xff && + param->sta_addr[2] == 0xff && param->sta_addr[3] == 0xff && + param->sta_addr[4] == 0xff && param->sta_addr[5] == 0xff) { + if (param->u.crypt.idx >= WEP_KEYS) + return -EINVAL; +#ifdef _RTL8187_EXT_PATCH_ + crypt = &ieee->cryptlist[0]->crypt[param->u.crypt.idx]; +#else + crypt = &ieee->crypt[param->u.crypt.idx]; +#endif + + } else { + return -EINVAL; + } + + if (strcmp(param->u.crypt.alg, "none") == 0) { + if (crypt) { + sec.enabled = 0; + // FIXME FIXME + //sec.encrypt = 0; + sec.level = SEC_LEVEL_0; + sec.flags |= SEC_ENABLED | SEC_LEVEL; + ieee80211_crypt_delayed_deinit(ieee, crypt); + } + goto done; + } + sec.enabled = 1; +// FIXME FIXME +// sec.encrypt = 1; + sec.flags |= SEC_ENABLED; + + /* IPW HW cannot build TKIP MIC, host decryption still needed. */ + if (!(ieee->host_encrypt || ieee->host_decrypt) && + strcmp(param->u.crypt.alg, "TKIP")) + goto skip_host_crypt; + + ops = ieee80211_get_crypto_ops(param->u.crypt.alg); + if (ops == NULL && strcmp(param->u.crypt.alg, "WEP") == 0) { + request_module("ieee80211_crypt_wep"); + ops = ieee80211_get_crypto_ops(param->u.crypt.alg); + } else if (ops == NULL && strcmp(param->u.crypt.alg, "TKIP") == 0) { + request_module("ieee80211_crypt_tkip"); + ops = ieee80211_get_crypto_ops(param->u.crypt.alg); + } else if (ops == NULL && strcmp(param->u.crypt.alg, "CCMP") == 0) { + request_module("ieee80211_crypt_ccmp"); + ops = ieee80211_get_crypto_ops(param->u.crypt.alg); + } + if (ops == NULL) { + printk("unknown crypto alg '%s'\n", param->u.crypt.alg); + param->u.crypt.err = IEEE_CRYPT_ERR_UNKNOWN_ALG; + ret = -EINVAL; + goto done; + } + +#ifdef _RTL8187_EXT_PATCH_ + u8 i; + for (i=0; icryptlist[i]->crypt[param->u.crypt.idx]; +// if (crypt != NULL) printk("crypt not null\n", crypt); + + *crypt = ieee->cryptlist[i]->crypt[param->u.crypt.idx]; +#endif + if (*crypt == NULL || (*crypt)->ops != ops) { + struct ieee80211_crypt_data *new_crypt; + + ieee80211_crypt_delayed_deinit(ieee, crypt); + + new_crypt = (struct ieee80211_crypt_data *) + kmalloc(sizeof(*new_crypt), GFP_KERNEL); + if (new_crypt == NULL) { + ret = -ENOMEM; + goto done; + } + memset(new_crypt, 0, sizeof(struct ieee80211_crypt_data)); + new_crypt->ops = ops; +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0) + if (new_crypt->ops && try_module_get(new_crypt->ops->owner)) +#else + if (new_crypt->ops && try_inc_mod_count(new_crypt->ops->owner)) +#endif + new_crypt->priv = + new_crypt->ops->init(param->u.crypt.idx); + + if (new_crypt->priv == NULL) { + kfree(new_crypt); + param->u.crypt.err = IEEE_CRYPT_ERR_CRYPT_INIT_FAILED; + ret = -EINVAL; + goto done; + } + + *crypt = new_crypt; + } + + if (param->u.crypt.key_len > 0 && (*crypt)->ops->set_key && + (*crypt)->ops->set_key(param->u.crypt.key, + param->u.crypt.key_len, param->u.crypt.seq, + (*crypt)->priv) < 0) { + printk("key setting failed\n"); + param->u.crypt.err = IEEE_CRYPT_ERR_KEY_SET_FAILED; + ret = -EINVAL; + goto done; + } +#ifdef _RTL8187_EXT_PATCH_ + } +#endif + skip_host_crypt: + if (param->u.crypt.set_tx) { + ieee->tx_keyidx = param->u.crypt.idx; + sec.active_key = param->u.crypt.idx; + sec.flags |= SEC_ACTIVE_KEY; + } else + sec.flags &= ~SEC_ACTIVE_KEY; + + if (param->u.crypt.alg != NULL) { + memcpy(sec.keys[param->u.crypt.idx], + param->u.crypt.key, + param->u.crypt.key_len); + sec.key_sizes[param->u.crypt.idx] = param->u.crypt.key_len; + sec.flags |= (1 << param->u.crypt.idx); + + if (strcmp(param->u.crypt.alg, "WEP") == 0) { + sec.flags |= SEC_LEVEL; + sec.level = SEC_LEVEL_1; + } else if (strcmp(param->u.crypt.alg, "TKIP") == 0) { + sec.flags |= SEC_LEVEL; + sec.level = SEC_LEVEL_2; + } else if (strcmp(param->u.crypt.alg, "CCMP") == 0) { + sec.flags |= SEC_LEVEL; + sec.level = SEC_LEVEL_3; + } + } + done: + if (ieee->set_security) + ieee->set_security(ieee->dev, &sec); +#if 1 +#ifdef _RTL8187_EXT_PATCH_ + if (ret != 0)//error out + { + for (i=0; icryptlist[i]->crypt[param->u.crypt.idx]==NULL){ + break; + } + else{ + //if (ieee->cryptlist[i]->crypt[param->u.crypt.idx] != NULL) + // { + kfree(ieee->cryptlist[i]->crypt[param->u.crypt.idx]); + ieee->cryptlist[i]->crypt[param->u.crypt.idx] = NULL; + // } + // kfree(ieee->cryptlist[i]); + // ieee->cryptlist[i] = NULL; + } + } + } +#endif +#endif + /* Do not reset port if card is in Managed mode since resetting will + * generate new IEEE 802.11 authentication which may end up in looping + * with IEEE 802.1X. If your hardware requires a reset after WEP + * configuration (for example... Prism2), implement the reset_port in + * the callbacks structures used to initialize the 802.11 stack. */ + if (ieee->reset_on_keychange && + ieee->iw_mode != IW_MODE_INFRA && + ieee->reset_port && + ieee->reset_port(ieee->dev)) { + printk("reset_port failed\n"); + param->u.crypt.err = IEEE_CRYPT_ERR_CARD_CONF_FAILED; + return -EINVAL; + } + + return ret; +} + +int ieee80211_wpa_supplicant_ioctl(struct ieee80211_device *ieee, struct iw_point *p) +{ + struct ieee_param *param; + int ret=0; + + down(&ieee->wx_sem); + //IEEE_DEBUG_INFO("wpa_supplicant: len=%d\n", p->length); + + if (p->length < sizeof(struct ieee_param) || !p->pointer){ + ret = -EINVAL; + goto out; + } + + param = (struct ieee_param *)kmalloc(p->length, GFP_KERNEL); + if (param == NULL){ + ret = -ENOMEM; + goto out; + } + if (copy_from_user(param, p->pointer, p->length)) { + kfree(param); + ret = -EFAULT; + goto out; + } + + switch (param->cmd) { + + case IEEE_CMD_SET_WPA_PARAM: + ret = ieee80211_wpa_set_param(ieee, param->u.wpa_param.name, + param->u.wpa_param.value); + break; + + case IEEE_CMD_SET_WPA_IE: + ret = ieee80211_wpa_set_wpa_ie(ieee, param, p->length); + break; + + case IEEE_CMD_SET_ENCRYPTION: + ret = ieee80211_wpa_set_encryption(ieee, param, p->length); + break; + + case IEEE_CMD_MLME: + ret = ieee80211_wpa_mlme(ieee, param->u.mlme.command, + param->u.mlme.reason_code); + break; + + default: + printk("Unknown WPA supplicant request: %d\n",param->cmd); + ret = -EOPNOTSUPP; + break; + } + + if (ret == 0 && copy_to_user(p->pointer, param, p->length)) + ret = -EFAULT; + + kfree(param); +out: + up(&ieee->wx_sem); + + return ret; +} + +void notify_wx_assoc_event(struct ieee80211_device *ieee) +{ + union iwreq_data wrqu; + wrqu.ap_addr.sa_family = ARPHRD_ETHER; + if (ieee->state == IEEE80211_LINKED) + memcpy(wrqu.ap_addr.sa_data, ieee->current_network.bssid, ETH_ALEN); + else + memset(wrqu.ap_addr.sa_data, 0, ETH_ALEN); + wireless_send_event(ieee->dev, SIOCGIWAP, &wrqu, NULL); +} + +#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)) +EXPORT_SYMBOL(ieee80211_get_beacon); +EXPORT_SYMBOL(ieee80211_wake_queue); +EXPORT_SYMBOL(ieee80211_stop_queue); +EXPORT_SYMBOL(ieee80211_reset_queue); +EXPORT_SYMBOL(ieee80211_softmac_stop_protocol); +EXPORT_SYMBOL(ieee80211_softmac_start_protocol); +EXPORT_SYMBOL(ieee80211_is_shortslot); +EXPORT_SYMBOL(ieee80211_is_54g); +EXPORT_SYMBOL(ieee80211_wpa_supplicant_ioctl); +EXPORT_SYMBOL(ieee80211_ps_tx_ack); +EXPORT_SYMBOL(notify_wx_assoc_event); +EXPORT_SYMBOL(ieee80211_stop_send_beacons); +EXPORT_SYMBOL(ieee80211_start_send_beacons); +EXPORT_SYMBOL(ieee80211_start_scan_syncro); +EXPORT_SYMBOL(ieee80211_start_protocol); +EXPORT_SYMBOL(ieee80211_stop_protocol); +EXPORT_SYMBOL(ieee80211_start_scan); +EXPORT_SYMBOL(ieee80211_stop_scan); +#ifdef _RTL8187_EXT_PATCH_ +EXPORT_SYMBOL(ieee80211_ext_issue_assoc_req); +EXPORT_SYMBOL(ieee80211_ext_issue_disassoc); +EXPORT_SYMBOL(ieee80211_ext_issue_assoc_rsp); +EXPORT_SYMBOL(softmac_mgmt_xmit); +EXPORT_SYMBOL(ieee80211_ext_probe_resp_by_net); +EXPORT_SYMBOL(ieee80211_stop_scan); +EXPORT_SYMBOL(ieee80211_ext_send_11s_beacon); +EXPORT_SYMBOL(ieee80211_rx_auth_rq); +EXPORT_SYMBOL(ieee80211_associate_step1); +#endif // _RTL8187_EXT_PATCH_ +#else +EXPORT_SYMBOL_NOVERS(ieee80211_get_beacon); +EXPORT_SYMBOL_NOVERS(ieee80211_wake_queue); +EXPORT_SYMBOL_NOVERS(ieee80211_stop_queue); +EXPORT_SYMBOL_NOVERS(ieee80211_reset_queue); +EXPORT_SYMBOL_NOVERS(ieee80211_softmac_stop_protocol); +EXPORT_SYMBOL_NOVERS(ieee80211_softmac_start_protocol); +EXPORT_SYMBOL_NOVERS(ieee80211_is_shortslot); +EXPORT_SYMBOL_NOVERS(ieee80211_is_54g); +EXPORT_SYMBOL_NOVERS(ieee80211_wpa_supplicant_ioctl); +EXPORT_SYMBOL_NOVERS(ieee80211_ps_tx_ack); +EXPORT_SYMBOL_NOVERS(ieee80211_start_scan); +EXPORT_SYMBOL_NOVERS(ieee80211_stop_scan); +#ifdef _RTL8187_EXT_PATCH_ +EXPORT_SYMBOL_NOVERS(ieee80211_ext_issue_assoc_req); +EXPORT_SYMBOL_NOVERS(ieee80211_ext_issue_disassoc); +EXPORT_SYMBOL_NOVERS(ieee80211_ext_issue_assoc_rsp); +EXPORT_SYMBOL_NOVERS(softmac_mgmt_xmit); +EXPORT_SYMBOL_NOVERS(ieee80211_ext_probe_resp_by_net); +EXPORT_SYMBOL_NOVERS(ieee80211_stop_scan); +EXPORT_SYMBOL_NOVERS(ieee80211_ext_send_11s_beacon); +EXPORT_SYMBOL_NOVERS(ieee80211_rx_auth_rq); +EXPORT_SYMBOL(ieee80211_associate_step1); +#endif // _RTL8187_EXT_PATCH_ + +#endif +//EXPORT_SYMBOL(ieee80211_sta_ps_send_null_frame); diff -Nur linux-2.6.30.5.orig/drivers/net/wireless/rtl8187b/ieee80211/ieee80211_softmac_wx.c linux-2.6.30.5/drivers/net/wireless/rtl8187b/ieee80211/ieee80211_softmac_wx.c --- linux-2.6.30.5.orig/drivers/net/wireless/rtl8187b/ieee80211/ieee80211_softmac_wx.c 1970-01-01 01:00:00.000000000 +0100 +++ linux-2.6.30.5/drivers/net/wireless/rtl8187b/ieee80211/ieee80211_softmac_wx.c 2009-08-23 19:01:04.000000000 +0200 @@ -0,0 +1,629 @@ +/* IEEE 802.11 SoftMAC layer + * Copyright (c) 2005 Andrea Merello + * + * Mostly extracted from the rtl8180-sa2400 driver for the + * in-kernel generic ieee802.11 stack. + * + * Some pieces of code might be stolen from ipw2100 driver + * copyright of who own it's copyright ;-) + * + * PS wx handler mostly stolen from hostap, copyright who + * own it's copyright ;-) + * + * released under the GPL + */ + + +#include "ieee80211.h" +#ifdef ENABLE_DOT11D +#include "dot11d.h" +#endif + +/* FIXME: add A freqs */ + +const long ieee80211_wlan_frequencies[] = { + 2412, 2417, 2422, 2427, + 2432, 2437, 2442, 2447, + 2452, 2457, 2462, 2467, + 2472, 2484 +}; + + +int ieee80211_wx_set_freq(struct ieee80211_device *ieee, struct iw_request_info *a, + union iwreq_data *wrqu, char *b) +{ + int ret; + struct iw_freq *fwrq = & wrqu->freq; + + down(&ieee->wx_sem); + + if(ieee->iw_mode == IW_MODE_INFRA){ + ret = -EOPNOTSUPP; + goto out; + } + + /* if setting by freq convert to channel */ + if (fwrq->e == 1) { + if ((fwrq->m >= (int) 2.412e8 && + fwrq->m <= (int) 2.487e8)) { + int f = fwrq->m / 100000; + int c = 0; + + while ((c < 14) && (f != ieee80211_wlan_frequencies[c])) + c++; + + /* hack to fall through */ + fwrq->e = 0; + fwrq->m = c + 1; + } + } + + if (fwrq->e > 0 || fwrq->m > 14 || fwrq->m < 1 ){ + ret = -EOPNOTSUPP; + goto out; + + }else { /* Set the channel */ + +#ifdef ENABLE_DOT11D + if(!IsLegalChannel(ieee, fwrq->m) ) + { + printk("channel(%d). is invalide\n", fwrq->m); + ret = -EOPNOTSUPP; + goto out; + } + else + { + if(ieee->iw_mode == IW_MODE_ADHOC) + { + if(ieee->MinPassiveChnlNum != MAX_CHANNEL_NUMBER+1) + { + if(fwrq->m >= ieee->MinPassiveChnlNum) + { + ret = -EOPNOTSUPP; + goto out; + } + } + } + } +#endif + ieee->current_network.channel = fwrq->m; + ieee->set_chan(ieee->dev, ieee->current_network.channel); + + if(ieee->iw_mode == IW_MODE_ADHOC || ieee->iw_mode == IW_MODE_MASTER) + if(ieee->state == IEEE80211_LINKED){ + + ieee80211_stop_send_beacons(ieee); + ieee80211_start_send_beacons(ieee); + } + } + + ret = 0; +out: + up(&ieee->wx_sem); + return ret; +} + + +int ieee80211_wx_get_freq(struct ieee80211_device *ieee, + struct iw_request_info *a, + union iwreq_data *wrqu, char *b) +{ + struct iw_freq *fwrq = & wrqu->freq; + + if (ieee->current_network.channel == 0) + return -1; + + fwrq->m = ieee->current_network.channel; + fwrq->e = 0; + + return 0; +} + +int ieee80211_wx_get_wap(struct ieee80211_device *ieee, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + unsigned long flags; + + wrqu->ap_addr.sa_family = ARPHRD_ETHER; + + if (ieee->iw_mode == IW_MODE_MONITOR) + return -1; + + /* We want avoid to give to the user inconsistent infos*/ + spin_lock_irqsave(&ieee->lock, flags); + + if (ieee->state != IEEE80211_LINKED && + ieee->state != IEEE80211_LINKED_SCANNING && + ieee->wap_set == 0) + + memset(wrqu->ap_addr.sa_data, 0, ETH_ALEN); + else + memcpy(wrqu->ap_addr.sa_data, + ieee->current_network.bssid, ETH_ALEN); + + spin_unlock_irqrestore(&ieee->lock, flags); + + return 0; +} + + +int ieee80211_wx_set_wap(struct ieee80211_device *ieee, + struct iw_request_info *info, + union iwreq_data *awrq, + char *extra) +{ + + int ret = 0; + u8 zero[] = {0,0,0,0,0,0}; + unsigned long flags; + + short ifup = ieee->proto_started;//dev->flags & IFF_UP; + struct sockaddr *temp = (struct sockaddr *)awrq; + + ieee->sync_scan_hurryup = 1; + + down(&ieee->wx_sem); + /* use ifconfig hw ether */ + if (ieee->iw_mode == IW_MODE_MASTER){ + ret = -1; + goto out; + } + + if (temp->sa_family != ARPHRD_ETHER){ + ret = -EINVAL; + goto out; + } + + if (ifup) + ieee80211_stop_protocol(ieee); + + /* just to avoid to give inconsistent infos in the + * get wx method. not really needed otherwise + */ + spin_lock_irqsave(&ieee->lock, flags); + + memcpy(ieee->current_network.bssid, temp->sa_data, ETH_ALEN); + ieee->wap_set = memcmp(temp->sa_data, zero,ETH_ALEN)!=0; + + spin_unlock_irqrestore(&ieee->lock, flags); + + if (ifup) + ieee80211_start_protocol(ieee); + +out: + up(&ieee->wx_sem); + return ret; +} + + int ieee80211_wx_get_essid(struct ieee80211_device *ieee, struct iw_request_info *a,union iwreq_data *wrqu,char *b) +{ + int len,ret = 0; + unsigned long flags; + + if (ieee->iw_mode == IW_MODE_MONITOR) + return -1; + + /* We want avoid to give to the user inconsistent infos*/ + spin_lock_irqsave(&ieee->lock, flags); + + if (ieee->current_network.ssid[0] == '\0' || + ieee->current_network.ssid_len == 0){ + ret = -1; + goto out; + } + + if (ieee->state != IEEE80211_LINKED && + ieee->state != IEEE80211_LINKED_SCANNING && + ieee->ssid_set == 0){ + ret = -1; + goto out; + } + len = ieee->current_network.ssid_len; + wrqu->essid.length = len; + strncpy(b,ieee->current_network.ssid,len); + wrqu->essid.flags = 1; + +out: + spin_unlock_irqrestore(&ieee->lock, flags); + + return ret; + +} + +int ieee80211_wx_set_rate(struct ieee80211_device *ieee, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + + u32 target_rate = wrqu->bitrate.value; + + ieee->rate = target_rate/100000; + //FIXME: we might want to limit rate also in management protocols. + return 0; +} + + + +int ieee80211_wx_get_rate(struct ieee80211_device *ieee, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + + wrqu->bitrate.value = ieee->rate * 100000; + + return 0; +} + +int ieee80211_wx_set_mode(struct ieee80211_device *ieee, struct iw_request_info *a, + union iwreq_data *wrqu, char *b) +{ + + ieee->sync_scan_hurryup = 1; + + down(&ieee->wx_sem); + //printk("=======>%s\n", __func__); + + if (wrqu->mode == ieee->iw_mode) + goto out; + + if (wrqu->mode == IW_MODE_MONITOR){ + + ieee->dev->type = ARPHRD_IEEE80211; + }else{ + ieee->dev->type = ARPHRD_ETHER; + } + + if (!ieee->proto_started){ + ieee->iw_mode = wrqu->mode; + }else{ + ieee80211_stop_protocol(ieee); + ieee->iw_mode = wrqu->mode; + ieee80211_start_protocol(ieee); + } + +out: + up(&ieee->wx_sem); + return 0; +} + +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20) +void ieee80211_wx_sync_scan_wq(struct work_struct *work) +{ + struct ieee80211_device *ieee = container_of(work, struct ieee80211_device, wx_sync_scan_wq); +#else +void ieee80211_wx_sync_scan_wq(struct ieee80211_device *ieee) +{ +#endif + short chan; + + chan = ieee->current_network.channel; + + netif_carrier_off(ieee->dev); + + if (ieee->data_hard_stop) + ieee->data_hard_stop(ieee->dev); + + ieee80211_stop_send_beacons(ieee); + + ieee->state = IEEE80211_LINKED_SCANNING; + ieee->link_change(ieee->dev); + + ieee80211_start_scan_syncro(ieee); + + ieee->set_chan(ieee->dev, chan); + + ieee->state = IEEE80211_LINKED; + ieee->link_change(ieee->dev); + + if (ieee->data_hard_resume) + ieee->data_hard_resume(ieee->dev); + + if(ieee->iw_mode == IW_MODE_ADHOC || ieee->iw_mode == IW_MODE_MASTER) + ieee80211_start_send_beacons(ieee); + + netif_carrier_on(ieee->dev); + + up(&ieee->wx_sem); + +} + +int ieee80211_wx_set_scan(struct ieee80211_device *ieee, struct iw_request_info *a, + union iwreq_data *wrqu, char *b) +{ + int ret = 0; + + down(&ieee->wx_sem); + + if (ieee->iw_mode == IW_MODE_MONITOR || !(ieee->proto_started)){ + ret = -1; + goto out; + } + + if ( ieee->state == IEEE80211_LINKED){ +#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0) + queue_work(ieee->wq, &ieee->wx_sync_scan_wq); +#else + schedule_task(&ieee->wx_sync_scan_wq); +#endif + /* intentionally forget to up sem */ + return 0; + } + +out: + up(&ieee->wx_sem); + return ret; +} + +int ieee80211_wx_set_essid(struct ieee80211_device *ieee, + struct iw_request_info *a, + union iwreq_data *wrqu, char *extra) +{ + + int ret=0,len; + short proto_started; + unsigned long flags; + + ieee->sync_scan_hurryup = 1; + + down(&ieee->wx_sem); + + //printk("=======>%s\n", __func__); + proto_started = ieee->proto_started; + + if (wrqu->essid.length > IW_ESSID_MAX_SIZE){ + ret= -E2BIG; + goto out; + } + + if (ieee->iw_mode == IW_MODE_MONITOR){ + ret= -1; + goto out; + } + + if(proto_started){ + ieee80211_stop_protocol(ieee); + } + + /* this is just to be sure that the GET wx callback + * has consisten infos. not needed otherwise + */ + spin_lock_irqsave(&ieee->lock, flags); + + if (wrqu->essid.flags && wrqu->essid.length) { + len = ((wrqu->essid.length-1) < IW_ESSID_MAX_SIZE) ? (wrqu->essid.length-1) : IW_ESSID_MAX_SIZE; +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20) + strncpy(ieee->current_network.ssid, extra, len); + ieee->current_network.ssid_len = len; +#else + strncpy(ieee->current_network.ssid, extra, len+1); + ieee->current_network.ssid_len = len+1; +#endif + ieee->ssid_set = 1; + //YJ,add,080819,for hidden ap + if(len == 0){ + memset(ieee->current_network.bssid, 0, ETH_ALEN); + ieee->current_network.capability = 0; + } + //YJ,add,080819,for hidden ap,end + } + else{ + ieee->ssid_set = 0; + ieee->current_network.ssid[0] = '\0'; + ieee->current_network.ssid_len = 0; + } + + spin_unlock_irqrestore(&ieee->lock, flags); + + if (proto_started){ + ieee80211_start_protocol(ieee); + } +out: + up(&ieee->wx_sem); + return ret; +} + + int ieee80211_wx_get_mode(struct ieee80211_device *ieee, struct iw_request_info *a, + union iwreq_data *wrqu, char *b) +{ + + wrqu->mode = ieee->iw_mode; + return 0; +} + + int ieee80211_wx_set_rawtx(struct ieee80211_device *ieee, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + + int *parms = (int *)extra; + int enable = (parms[0] > 0); + short prev = ieee->raw_tx; + + down(&ieee->wx_sem); + + if(enable) + ieee->raw_tx = 1; + else + ieee->raw_tx = 0; + + printk(KERN_INFO"raw TX is %s\n", + ieee->raw_tx ? "enabled" : "disabled"); + + if(ieee->iw_mode == IW_MODE_MONITOR) + { + if(prev == 0 && ieee->raw_tx){ + if (ieee->data_hard_resume) + ieee->data_hard_resume(ieee->dev); + + netif_carrier_on(ieee->dev); + } + + if(prev && ieee->raw_tx == 1) + netif_carrier_off(ieee->dev); + } + + up(&ieee->wx_sem); + + return 0; +} + +int ieee80211_wx_get_name(struct ieee80211_device *ieee, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + strcpy(wrqu->name, "802.11"); + if(ieee->modulation & IEEE80211_CCK_MODULATION){ + strcat(wrqu->name, "b"); + if(ieee->modulation & IEEE80211_OFDM_MODULATION) + strcat(wrqu->name, "/g"); + }else if(ieee->modulation & IEEE80211_OFDM_MODULATION) + strcat(wrqu->name, "g"); + + if((ieee->state == IEEE80211_LINKED) || + (ieee->state == IEEE80211_LINKED_SCANNING)) + strcat(wrqu->name," linked"); + else if(ieee->state != IEEE80211_NOLINK) + strcat(wrqu->name," link.."); + + + return 0; +} + + +/* this is mostly stolen from hostap */ +int ieee80211_wx_set_power(struct ieee80211_device *ieee, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + int ret = 0; + + if( + (!ieee->sta_wake_up) || + (!ieee->ps_request_tx_ack) || + (!ieee->enter_sleep_state) || + (!ieee->ps_is_queue_empty)){ + + printk("ERROR. PS mode is tryied to be use but\ +driver missed a callback\n\n"); + + return -1; + } + + down(&ieee->wx_sem); + + if (wrqu->power.disabled){ + ieee->ps = IEEE80211_PS_DISABLED; + + goto exit; + } + switch (wrqu->power.flags & IW_POWER_MODE) { + case IW_POWER_UNICAST_R: + ieee->ps = IEEE80211_PS_UNICAST; + + break; + case IW_POWER_ALL_R: + ieee->ps = IEEE80211_PS_UNICAST | IEEE80211_PS_MBCAST; + break; + + case IW_POWER_ON: + ieee->ps = IEEE80211_PS_DISABLED; + break; + + default: + ret = -EINVAL; + goto exit; + } + + if (wrqu->power.flags & IW_POWER_TIMEOUT) { + + ieee->ps_timeout = wrqu->power.value / 1000; + printk("Timeout %d\n",ieee->ps_timeout); + } + + if (wrqu->power.flags & IW_POWER_PERIOD) { + + ret = -EOPNOTSUPP; + goto exit; + //wrq->value / 1024; + + } +exit: + up(&ieee->wx_sem); + return ret; + +} + +/* this is stolen from hostap */ +int ieee80211_wx_get_power(struct ieee80211_device *ieee, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + int ret =0; + + down(&ieee->wx_sem); + + if(ieee->ps == IEEE80211_PS_DISABLED){ + wrqu->power.disabled = 1; + goto exit; + } + + wrqu->power.disabled = 0; + +// if ((wrqu->power.flags & IW_POWER_TYPE) == IW_POWER_TIMEOUT) { + wrqu->power.flags = IW_POWER_TIMEOUT; + wrqu->power.value = ieee->ps_timeout * 1000; +// } else { +// ret = -EOPNOTSUPP; +// goto exit; + //wrqu->power.flags = IW_POWER_PERIOD; + //wrqu->power.value = ieee->current_network.dtim_period * + // ieee->current_network.beacon_interval * 1024; +// } + + + if (ieee->ps & IEEE80211_PS_MBCAST) + wrqu->power.flags |= IW_POWER_ALL_R; + else + wrqu->power.flags |= IW_POWER_UNICAST_R; + +exit: + up(&ieee->wx_sem); + return ret; + +} +#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)) +EXPORT_SYMBOL(ieee80211_wx_get_essid); +EXPORT_SYMBOL(ieee80211_wx_set_essid); +EXPORT_SYMBOL(ieee80211_wx_set_rate); +EXPORT_SYMBOL(ieee80211_wx_get_rate); +EXPORT_SYMBOL(ieee80211_wx_set_wap); +EXPORT_SYMBOL(ieee80211_wx_get_wap); +EXPORT_SYMBOL(ieee80211_wx_set_mode); +EXPORT_SYMBOL(ieee80211_wx_get_mode); +EXPORT_SYMBOL(ieee80211_wx_set_scan); +EXPORT_SYMBOL(ieee80211_wx_get_freq); +EXPORT_SYMBOL(ieee80211_wx_set_freq); +EXPORT_SYMBOL(ieee80211_wx_set_rawtx); +EXPORT_SYMBOL(ieee80211_wx_get_name); +EXPORT_SYMBOL(ieee80211_wx_set_power); +EXPORT_SYMBOL(ieee80211_wx_get_power); +EXPORT_SYMBOL(ieee80211_wlan_frequencies); +#else +EXPORT_SYMBOL_NOVERS(ieee80211_wx_get_essid); +EXPORT_SYMBOL_NOVERS(ieee80211_wx_set_essid); +EXPORT_SYMBOL_NOVERS(ieee80211_wx_set_rate); +EXPORT_SYMBOL_NOVERS(ieee80211_wx_get_rate); +EXPORT_SYMBOL_NOVERS(ieee80211_wx_set_wap); +EXPORT_SYMBOL_NOVERS(ieee80211_wx_get_wap); +EXPORT_SYMBOL_NOVERS(ieee80211_wx_set_mode); +EXPORT_SYMBOL_NOVERS(ieee80211_wx_get_mode); +EXPORT_SYMBOL_NOVERS(ieee80211_wx_set_scan); +EXPORT_SYMBOL_NOVERS(ieee80211_wx_get_freq); +EXPORT_SYMBOL_NOVERS(ieee80211_wx_set_freq); +EXPORT_SYMBOL_NOVERS(ieee80211_wx_set_rawtx); +EXPORT_SYMBOL_NOVERS(ieee80211_wx_get_name); +EXPORT_SYMBOL_NOVERS(ieee80211_wx_set_power); +EXPORT_SYMBOL_NOVERS(ieee80211_wx_get_power); +EXPORT_SYMBOL_NOVERS(ieee80211_wlan_frequencies); +#endif diff -Nur linux-2.6.30.5.orig/drivers/net/wireless/rtl8187b/ieee80211/ieee80211_tx.c linux-2.6.30.5/drivers/net/wireless/rtl8187b/ieee80211/ieee80211_tx.c --- linux-2.6.30.5.orig/drivers/net/wireless/rtl8187b/ieee80211/ieee80211_tx.c 1970-01-01 01:00:00.000000000 +0100 +++ linux-2.6.30.5/drivers/net/wireless/rtl8187b/ieee80211/ieee80211_tx.c 2009-08-23 19:01:04.000000000 +0200 @@ -0,0 +1,876 @@ +/****************************************************************************** + + Copyright(c) 2003 - 2004 Intel Corporation. All rights reserved. + + This program is free software; you can redistribute it and/or modify it + under the terms of version 2 of the GNU General Public License as + published by the Free Software Foundation. + + 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. + + The full GNU General Public License is included in this distribution in the + file called LICENSE. + + Contact Information: + James P. Ketrenos + Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 + +****************************************************************************** + + Few modifications for Realtek's Wi-Fi drivers by + Andrea Merello + + A special thanks goes to Realtek for their support ! + +******************************************************************************/ + +#include +//#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "ieee80211.h" + + +/* + + +802.11 Data Frame + + +802.11 frame_contorl for data frames - 2 bytes + ,-----------------------------------------------------------------------------------------. +bits | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | a | b | c | d | e | + |----|-----|-----|-----|-----|-----|-----|-----|-----|-----|-----|-----|-----|-----|------| +val | 0 | 0 | 0 | 1 | x | 0 | 0 | 0 | 1 | 0 | x | x | x | x | x | + |----|-----|-----|-----|-----|-----|-----|-----|-----|-----|-----|-----|-----|-----|------| +desc | ^-ver-^ | ^type-^ | ^-----subtype-----^ | to |from |more |retry| pwr |more |wep | + | | | x=0 data,x=1 data+ack | DS | DS |frag | | mgm |data | | + '-----------------------------------------------------------------------------------------' + /\ + | +802.11 Data Frame | + ,--------- 'ctrl' expands to >-----------' + | + ,--'---,-------------------------------------------------------------. +Bytes | 2 | 2 | 6 | 6 | 6 | 2 | 0..2312 | 4 | + |------|------|---------|---------|---------|------|---------|------| +Desc. | ctrl | dura | DA/RA | TA | SA | Sequ | Frame | fcs | + | | tion | (BSSID) | | | ence | data | | + `--------------------------------------------------| |------' +Total: 28 non-data bytes `----.----' + | + .- 'Frame data' expands to <---------------------------' + | + V + ,---------------------------------------------------. +Bytes | 1 | 1 | 1 | 3 | 2 | 0-2304 | + |------|------|---------|----------|------|---------| +Desc. | SNAP | SNAP | Control |Eth Tunnel| Type | IP | + | DSAP | SSAP | | | | Packet | + | 0xAA | 0xAA |0x03 (UI)|0x00-00-F8| | | + `-----------------------------------------| | +Total: 8 non-data bytes `----.----' + | + .- 'IP Packet' expands, if WEP enabled, to <--' + | + V + ,-----------------------. +Bytes | 4 | 0-2296 | 4 | + |-----|-----------|-----| +Desc. | IV | Encrypted | ICV | + | | IP Packet | | + `-----------------------' +Total: 8 non-data bytes + + +802.3 Ethernet Data Frame + + ,-----------------------------------------. +Bytes | 6 | 6 | 2 | Variable | 4 | + |-------|-------|------|-----------|------| +Desc. | Dest. | Source| Type | IP Packet | fcs | + | MAC | MAC | | | | + `-----------------------------------------' +Total: 18 non-data bytes + +In the event that fragmentation is required, the incoming payload is split into +N parts of size ieee->fts. The first fragment contains the SNAP header and the +remaining packets are just data. + +If encryption is enabled, each fragment payload size is reduced by enough space +to add the prefix and postfix (IV and ICV totalling 8 bytes in the case of WEP) +So if you have 1500 bytes of payload with ieee->fts set to 500 without +encryption it will take 3 frames. With WEP it will take 4 frames as the +payload of each frame is reduced to 492 bytes. + +* SKB visualization +* +* ,- skb->data +* | +* | ETHERNET HEADER ,-<-- PAYLOAD +* | | 14 bytes from skb->data +* | 2 bytes for Type --> ,T. | (sizeof ethhdr) +* | | | | +* |,-Dest.--. ,--Src.---. | | | +* | 6 bytes| | 6 bytes | | | | +* v | | | | | | +* 0 | v 1 | v | v 2 +* 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 +* ^ | ^ | ^ | +* | | | | | | +* | | | | `T' <---- 2 bytes for Type +* | | | | +* | | '---SNAP--' <-------- 6 bytes for SNAP +* | | +* `-IV--' <-------------------- 4 bytes for IV (WEP) +* +* SNAP HEADER +* +*/ + +static u8 P802_1H_OUI[P80211_OUI_LEN] = { 0x00, 0x00, 0xf8 }; +static u8 RFC1042_OUI[P80211_OUI_LEN] = { 0x00, 0x00, 0x00 }; + +static inline int ieee80211_put_snap(u8 *data, u16 h_proto) +{ + struct ieee80211_snap_hdr *snap; + u8 *oui; + + snap = (struct ieee80211_snap_hdr *)data; + snap->dsap = 0xaa; + snap->ssap = 0xaa; + snap->ctrl = 0x03; + + if (h_proto == 0x8137 || h_proto == 0x80f3) + oui = P802_1H_OUI; + else + oui = RFC1042_OUI; + snap->oui[0] = oui[0]; + snap->oui[1] = oui[1]; + snap->oui[2] = oui[2]; + + *(u16 *)(data + SNAP_SIZE) = htons(h_proto); + + return SNAP_SIZE + sizeof(u16); +} + +int ieee80211_encrypt_fragment( + struct ieee80211_device *ieee, + struct sk_buff *frag, + int hdr_len) +{ + struct ieee80211_crypt_data* crypt = NULL;//ieee->crypt[ieee->tx_keyidx]; + int res;//, i; +// printk("====>wwwwww%s():ieee:%x, hdr_len:%d\n", __FUNCTION__, ieee, hdr_len); +/* printk("\n%s(), hdr_len:%d\n", __FUNCTION__, hdr_len); + for (i = 0; i < 48; i++) { + if (i % 16 == 0) printk("\n\t"); + printk("%2x ", *(frag->data+i)); + } +*/ + +#ifdef _RTL8187_EXT_PATCH_ +#if 0 + i = ieee80211_find_MP(ieee, ((struct ieee80211_hdr*) frag->data)->addr1); + if (i== -1){ + printk("error find MP entry in %s()\n", __FUNCTION__); + return i; + } + // printk("%s():"MAC_FMT", find in index:%d\n", __FUNCTION__, MAC_ARG(((struct ieee80211_hdr*)frag->data)->addr1), i); +#endif +// crypt = ieee->cryptlist[MAX_MP-1]->crypt[ieee->tx_keyidx]; + crypt = ieee->cryptlist[0]->crypt[ieee->tx_keyidx]; +#else + crypt = ieee->crypt[ieee->tx_keyidx]; +#endif + /*added to care about null crypt condition, to solve that system hangs when shared keys error*/ + if (!crypt || !crypt->ops) + return -1; + +#ifdef CONFIG_IEEE80211_CRYPT_TKIP + struct ieee80211_hdr *header; + + if (ieee->tkip_countermeasures && + crypt && crypt->ops && strcmp(crypt->ops->name, "TKIP") == 0) { + header = (struct ieee80211_hdr *) frag->data; + if (net_ratelimit()) { + printk(KERN_DEBUG "%s: TKIP countermeasures: dropped " + "TX packet to " MAC_FMT "\n", + ieee->dev->name, MAC_ARG(header->addr1)); + } + return -1; + } +#endif + /* To encrypt, frame format is: + * IV (4 bytes), clear payload (including SNAP), ICV (4 bytes) */ + + // PR: FIXME: Copied from hostap. Check fragmentation/MSDU/MPDU encryption. + /* Host-based IEEE 802.11 fragmentation for TX is not yet supported, so + * call both MSDU and MPDU encryption functions from here. */ + atomic_inc(&crypt->refcnt); + res = 0; + if (crypt->ops->encrypt_msdu) + res = crypt->ops->encrypt_msdu(frag, hdr_len, crypt->priv); + if (res == 0 && crypt->ops->encrypt_mpdu) + res = crypt->ops->encrypt_mpdu(frag, hdr_len, crypt->priv); + atomic_dec(&crypt->refcnt); + if (res < 0) { + printk(KERN_INFO "%s: Encryption failed: len=%d.\n", + ieee->dev->name, frag->len); + ieee->ieee_stats.tx_discards++; + return -1; + } + + return 0; +} + + +void ieee80211_txb_free(struct ieee80211_txb *txb) { + int i; + if (unlikely(!txb)) + return; + for (i = 0; i < txb->nr_frags; i++) + if (txb->fragments[i]) + dev_kfree_skb_any(txb->fragments[i]); + kfree(txb); +} + +struct ieee80211_txb *ieee80211_alloc_txb(int nr_frags, int txb_size, + int gfp_mask) +{ + struct ieee80211_txb *txb; + int i; + txb = kmalloc( + sizeof(struct ieee80211_txb) + (sizeof(u8*) * nr_frags), + gfp_mask); + if (!txb) + return NULL; + + memset(txb, 0, sizeof(struct ieee80211_txb)); + txb->nr_frags = nr_frags; + txb->frag_size = txb_size; + + for (i = 0; i < nr_frags; i++) { + txb->fragments[i] = dev_alloc_skb(txb_size); + if (unlikely(!txb->fragments[i])) { + i--; + break; + } + } + if (unlikely(i != nr_frags)) { + while (i >= 0) + dev_kfree_skb_any(txb->fragments[i--]); + kfree(txb); + return NULL; + } + return txb; +} + +// Classify the to-be send data packet +// Need to acquire the sent queue index. +static int +ieee80211_classify(struct sk_buff *skb, struct ieee80211_network *network) +{ + struct ether_header *eh = (struct ether_header*)skb->data; + unsigned int wme_UP = 0; + + if(!network->QoS_Enable) { + skb->priority = 0; + return(wme_UP); + } + + if(eh->ether_type == __constant_htons(ETHERTYPE_IP)) { + const struct iphdr *ih = (struct iphdr*)(skb->data + \ + sizeof(struct ether_header)); + wme_UP = (ih->tos >> 5)&0x07; + } else if (vlan_tx_tag_present(skb)) {//vtag packet +#ifndef VLAN_PRI_SHIFT +#define VLAN_PRI_SHIFT 13 /* Shift to find VLAN user priority */ +#define VLAN_PRI_MASK 7 /* Mask for user priority bits in VLAN */ +#endif + u32 tag = vlan_tx_tag_get(skb); + wme_UP = (tag >> VLAN_PRI_SHIFT) & VLAN_PRI_MASK; + } else if(ETH_P_PAE == ntohs(((struct ethhdr *)skb->data)->h_proto)) { + //printk(KERN_WARNING "type = normal packet\n"); + wme_UP = 7; + } + skb->priority = wme_UP; +/* + if (network->QoS_Enable) { + skb->priority = wme_UP; + }else { + skb->priority = 0; + } +*/ + return(wme_UP); +} + +#ifdef _RTL8187_EXT_PATCH_ +// based on part of ieee80211_xmit. Mainly allocate txb. ieee->lock is held +struct ieee80211_txb *ieee80211_ext_alloc_txb(struct sk_buff *skb, struct net_device *dev, struct ieee80211_hdr_3addr *header, int hdr_len, u8 isQoS, u16 *pQOS_ctl, int isEncrypt, struct ieee80211_crypt_data* crypt) +{ +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)) + struct ieee80211_device *ieee = netdev_priv(dev); +#else + struct ieee80211_device *ieee = (struct ieee80211_device *)dev->priv; +#endif + struct ieee80211_txb *txb = NULL; + struct ieee80211_hdr_3addr *frag_hdr; + int i, bytes_per_frag, nr_frags, bytes_last_frag, frag_size; + int ether_type; + int bytes, QOS_ctl; + struct sk_buff *skb_frag; + + ether_type = ntohs(((struct ethhdr *)skb->data)->h_proto); + + /* Advance the SKB to the start of the payload */ + skb_pull(skb, sizeof(struct ethhdr)); + + /* Determine total amount of storage required for TXB packets */ + bytes = skb->len + SNAP_SIZE + sizeof(u16); + + /* Determine fragmentation size based on destination (multicast + * and broadcast are not fragmented) */ + // if (is_multicast_ether_addr(dest) || + // is_broadcast_ether_addr(dest)) { + if (is_multicast_ether_addr(header->addr1) || + is_broadcast_ether_addr(header->addr1)) { + frag_size = MAX_FRAG_THRESHOLD; + QOS_ctl = QOS_CTL_NOTCONTAIN_ACK; + } + else { + //printk(KERN_WARNING "&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&frag_size = %d\n", frag_size); + frag_size = ieee->fts;//default:392 + QOS_ctl = 0; + } + + if(isQoS) { + QOS_ctl |= skb->priority; //set in the ieee80211_classify + *pQOS_ctl = cpu_to_le16(QOS_ctl); + } + //printk(KERN_WARNING "header size = %d, QOS_ctl = %x\n", hdr_len,QOS_ctl); + /* Determine amount of payload per fragment. Regardless of if + * this stack is providing the full 802.11 header, one will + * eventually be affixed to this fragment -- so we must account for + * it when determining the amount of payload space. */ + //bytes_per_frag = frag_size - (IEEE80211_3ADDR_LEN + (ieee->current_network->QoS_Enable ? 2:0)); + bytes_per_frag = frag_size - hdr_len; + if (ieee->config & + (CFG_IEEE80211_COMPUTE_FCS | CFG_IEEE80211_RESERVE_FCS)) + bytes_per_frag -= IEEE80211_FCS_LEN; + + /* Each fragment may need to have room for encryptiong pre/postfix */ + if (isEncrypt) + bytes_per_frag -= crypt->ops->extra_prefix_len + + crypt->ops->extra_postfix_len; + + /* Number of fragments is the total bytes_per_frag / + * payload_per_fragment */ + nr_frags = bytes / bytes_per_frag; + bytes_last_frag = bytes % bytes_per_frag; + if (bytes_last_frag) + nr_frags++; + else + bytes_last_frag = bytes_per_frag; + + /* When we allocate the TXB we allocate enough space for the reserve + * and full fragment bytes (bytes_per_frag doesn't include prefix, + * postfix, header, FCS, etc.) */ + txb = ieee80211_alloc_txb(nr_frags, frag_size, GFP_ATOMIC); + if (unlikely(!txb)) { + printk(KERN_WARNING "%s: Could not allocate TXB\n", + ieee->dev->name); + return NULL; + } + txb->encrypted = isEncrypt; + txb->payload_size = bytes; + + for (i = 0; i < nr_frags; i++) { + skb_frag = txb->fragments[i]; + skb_frag->priority = UP2AC(skb->priority); + if (isEncrypt) + skb_reserve(skb_frag, crypt->ops->extra_prefix_len); + + frag_hdr = (struct ieee80211_hdr_3addr *)skb_put(skb_frag, hdr_len); + memcpy(frag_hdr, (void *)header, hdr_len); + + /* If this is not the last fragment, then add the MOREFRAGS + * bit to the frame control */ + if (i != nr_frags - 1) { + frag_hdr->frame_ctl = cpu_to_le16( + header->frame_ctl | IEEE80211_FCTL_MOREFRAGS); + bytes = bytes_per_frag; + + } else { + /* The last fragment takes the remaining length */ + bytes = bytes_last_frag; + } + + frag_hdr->seq_ctl = cpu_to_le16(ieee->seq_ctrl[0]<<4 | i); + //frag_hdr->seq_ctl = cpu_to_le16(ieee->seq_ctrl<<4 | i); + // + + /* Put a SNAP header on the first fragment */ + if (i == 0) { + ieee80211_put_snap( + skb_put(skb_frag, SNAP_SIZE + sizeof(u16)), ether_type); + bytes -= SNAP_SIZE + sizeof(u16); + } + + memcpy(skb_put(skb_frag, bytes), skb->data, bytes); + + /* Advance the SKB... */ + skb_pull(skb, bytes); + + /* Encryption routine will move the header forward in order + * to insert the IV between the header and the payload */ + if (isEncrypt) + ieee80211_encrypt_fragment(ieee, skb_frag, hdr_len); + if (ieee->config & + (CFG_IEEE80211_COMPUTE_FCS | CFG_IEEE80211_RESERVE_FCS)) + skb_put(skb_frag, 4); + } + // Advance sequence number in data frame. + //printk(KERN_WARNING "QoS Enalbed? %s\n", ieee->current_network.QoS_Enable?"Y":"N"); + if (ieee->seq_ctrl[0] == 0xFFF) + ieee->seq_ctrl[0] = 0; + else + ieee->seq_ctrl[0]++; + // stanley, just for debug +/* +{ + int j=0; + for(j=0;jfragments[j]; + printk("send(%d): ", j); + for (i=0;ilen;i++) + printk("%02X ", skb->data[i]&0xff); + printk("\n"); + } +} +*/ + + return txb; +} + + +// based on part of ieee80211_xmit. Mainly allocate txb. ieee->lock is held +// Assume no encryption, no FCS computing +struct ieee80211_txb *ieee80211_ext_reuse_txb(struct sk_buff *skb, struct net_device *dev, struct ieee80211_hdr_3addr *header, int hdr_len, u8 isQoS, u16 *pQOS_ctl, int isEncrypt, struct ieee80211_crypt_data* crypt) +{ +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)) + struct ieee80211_device *ieee = netdev_priv(dev); +#else + struct ieee80211_device *ieee = (struct ieee80211_device *)dev->priv; +#endif + struct ieee80211_txb *txb = NULL; + struct ieee80211_hdr_3addr *frag_hdr; + int ether_type; + int bytes, QOS_ctl; + + ether_type = ntohs(((struct ethhdr *)skb->data)->h_proto); + + /* Advance the SKB to the start of the payload */ + skb_pull(skb, sizeof(struct ethhdr)); + + /* Determine total amount of storage required for TXB packets */ + bytes = skb->len + SNAP_SIZE + sizeof(u16); + + if (is_multicast_ether_addr(header->addr1) || + is_broadcast_ether_addr(header->addr1)) { + QOS_ctl = QOS_CTL_NOTCONTAIN_ACK; + } + else { + QOS_ctl = 0; + } + + if(isQoS) { + QOS_ctl |= skb->priority; //set in the ieee80211_classify + *pQOS_ctl = cpu_to_le16(QOS_ctl); + } + + txb = kmalloc( sizeof(struct ieee80211_txb) + sizeof(u8*), GFP_ATOMIC ); + if (unlikely(!txb)) { + printk(KERN_WARNING "%s: Could not allocate TXB\n", + ieee->dev->name); + return NULL; + } + + txb->nr_frags = 1; + txb->frag_size = bytes; + txb->encrypted = isEncrypt; + txb->payload_size = bytes; + + txb->fragments[0] = skb; + ieee80211_put_snap( + skb_push(skb, SNAP_SIZE + sizeof(u16)), ether_type); + frag_hdr = (struct ieee80211_hdr_3addr *)skb_push(skb, hdr_len); + memcpy(frag_hdr, (void *)header, hdr_len); + frag_hdr->seq_ctl = cpu_to_le16(ieee->seq_ctrl[0]<<4 | 0); + skb->priority = UP2AC(skb->priority); + if(isEncrypt) + ieee80211_encrypt_fragment(ieee,skb,hdr_len); + + // Advance sequence number in data frame. + //printk(KERN_WARNING "QoS Enalbed? %s\n", ieee->current_network.QoS_Enable?"Y":"N"); + if (ieee->seq_ctrl[0] == 0xFFF) + ieee->seq_ctrl[0] = 0; + else + ieee->seq_ctrl[0]++; + + return txb; +} + +#endif // _RTL8187_EXT_PATCH_ + +/* SKBs are added to the ieee->tx_queue. */ +int ieee80211_xmit(struct sk_buff *skb, + struct net_device *dev) +{ +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)) + struct ieee80211_device *ieee = netdev_priv(dev); +#else + struct ieee80211_device *ieee = (struct ieee80211_device *)dev->priv; +#endif + struct ieee80211_txb *txb = NULL; + struct ieee80211_hdr_3addr_QOS *frag_hdr; + int i, bytes_per_frag, nr_frags, bytes_last_frag, frag_size; + unsigned long flags; + struct net_device_stats *stats = &ieee->stats; + int ether_type, encrypt; + int bytes, fc, QOS_ctl, hdr_len; + struct sk_buff *skb_frag; + //struct ieee80211_hdr header = { /* Ensure zero initialized */ + // .duration_id = 0, + // .seq_ctl = 0 + //}; + struct ieee80211_hdr_3addr_QOS header = { /* Ensure zero initialized */ + .duration_id = 0, + .seq_ctl = 0, + .QOS_ctl = 0 + }; + u8 dest[ETH_ALEN], src[ETH_ALEN]; + + struct ieee80211_crypt_data* crypt; + + //printk(KERN_WARNING "upper layer packet!\n"); + spin_lock_irqsave(&ieee->lock, flags); + + /* If there is no driver handler to take the TXB, dont' bother + * creating it... */ + if ((!ieee->hard_start_xmit && !(ieee->softmac_features & IEEE_SOFTMAC_TX_QUEUE))|| + ((!ieee->softmac_data_hard_start_xmit && (ieee->softmac_features & IEEE_SOFTMAC_TX_QUEUE)))) { + printk(KERN_WARNING "%s: No xmit handler.\n", + ieee->dev->name); + goto success; + } + + ieee80211_classify(skb,&ieee->current_network); + if(likely(ieee->raw_tx == 0)){ + + if (unlikely(skb->len < SNAP_SIZE + sizeof(u16))) { + printk(KERN_WARNING "%s: skb too small (%d).\n", + ieee->dev->name, skb->len); + goto success; + } + + +#ifdef _RTL8187_EXT_PATCH_ + // note, skb->priority which was set by ieee80211_classify, and used by physical tx + if((ieee->iw_mode == ieee->iw_ext_mode) && (ieee->ext_patch_ieee80211_xmit)) + { + txb = ieee->ext_patch_ieee80211_xmit(skb, dev); + goto success; + } +#endif + + ether_type = ntohs(((struct ethhdr *)skb->data)->h_proto); +#ifdef _RTL8187_EXT_PATCH_ + crypt = ieee->cryptlist[0]->crypt[ieee->tx_keyidx]; +#else + crypt = ieee->crypt[ieee->tx_keyidx]; +#endif + encrypt = !(ether_type == ETH_P_PAE && ieee->ieee802_1x) && + ieee->host_encrypt && crypt && crypt->ops; + + if (!encrypt && ieee->ieee802_1x && + ieee->drop_unencrypted && ether_type != ETH_P_PAE) { + stats->tx_dropped++; + goto success; + } + + #ifdef CONFIG_IEEE80211_DEBUG + if (crypt && !encrypt && ether_type == ETH_P_PAE) { + struct eapol *eap = (struct eapol *)(skb->data + + sizeof(struct ethhdr) - SNAP_SIZE - sizeof(u16)); + IEEE80211_DEBUG_EAP("TX: IEEE 802.11 EAPOL frame: %s\n", + eap_get_type(eap->type)); + } + #endif + + /* Save source and destination addresses */ + memcpy(&dest, skb->data, ETH_ALEN); + memcpy(&src, skb->data+ETH_ALEN, ETH_ALEN); + + /* Advance the SKB to the start of the payload */ + skb_pull(skb, sizeof(struct ethhdr)); + + /* Determine total amount of storage required for TXB packets */ + bytes = skb->len + SNAP_SIZE + sizeof(u16); + + if(ieee->current_network.QoS_Enable) { + if (encrypt) + fc = IEEE80211_FTYPE_DATA | IEEE80211_STYPE_QOS_DATA | + IEEE80211_FCTL_WEP; + else + fc = IEEE80211_FTYPE_DATA | IEEE80211_STYPE_QOS_DATA; + + } else { + if (encrypt) + fc = IEEE80211_FTYPE_DATA | IEEE80211_STYPE_DATA | + IEEE80211_FCTL_WEP; + else + fc = IEEE80211_FTYPE_DATA | IEEE80211_STYPE_DATA; + } + + if (ieee->iw_mode == IW_MODE_INFRA) { + fc |= IEEE80211_FCTL_TODS; + /* To DS: Addr1 = BSSID, Addr2 = SA, + Addr3 = DA */ + memcpy(&header.addr1, ieee->current_network.bssid, ETH_ALEN); + memcpy(&header.addr2, &src, ETH_ALEN); + memcpy(&header.addr3, &dest, ETH_ALEN); + } else if (ieee->iw_mode == IW_MODE_ADHOC) { + /* not From/To DS: Addr1 = DA, Addr2 = SA, + Addr3 = BSSID */ + memcpy(&header.addr1, dest, ETH_ALEN); + memcpy(&header.addr2, src, ETH_ALEN); + memcpy(&header.addr3, ieee->current_network.bssid, ETH_ALEN); + } + // printk(KERN_WARNING "essid MAC address is "MAC_FMT, MAC_ARG(&header.addr1)); + header.frame_ctl = cpu_to_le16(fc); + //hdr_len = IEEE80211_3ADDR_LEN; + + /* Determine fragmentation size based on destination (multicast + * and broadcast are not fragmented) */ +// if (is_multicast_ether_addr(dest) || +// is_broadcast_ether_addr(dest)) { + if (is_multicast_ether_addr(header.addr1) || + is_broadcast_ether_addr(header.addr1)) { + frag_size = MAX_FRAG_THRESHOLD; + QOS_ctl = QOS_CTL_NOTCONTAIN_ACK; + } + else { + //printk(KERN_WARNING "&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&frag_size = %d\n", frag_size); + frag_size = ieee->fts;//default:392 + QOS_ctl = 0; + } + + if (ieee->current_network.QoS_Enable) { + hdr_len = IEEE80211_3ADDR_LEN + 2; + QOS_ctl |= skb->priority; //set in the ieee80211_classify + header.QOS_ctl = cpu_to_le16(QOS_ctl); + } else { + hdr_len = IEEE80211_3ADDR_LEN; + } + //printk(KERN_WARNING "header size = %d, QOS_ctl = %x\n", hdr_len,QOS_ctl); + /* Determine amount of payload per fragment. Regardless of if + * this stack is providing the full 802.11 header, one will + * eventually be affixed to this fragment -- so we must account for + * it when determining the amount of payload space. */ + //bytes_per_frag = frag_size - (IEEE80211_3ADDR_LEN + (ieee->current_network->QoS_Enable ? 2:0)); + bytes_per_frag = frag_size - hdr_len; + if (ieee->config & + (CFG_IEEE80211_COMPUTE_FCS | CFG_IEEE80211_RESERVE_FCS)) + bytes_per_frag -= IEEE80211_FCS_LEN; + + /* Each fragment may need to have room for encryptiong pre/postfix */ + if (encrypt) + bytes_per_frag -= crypt->ops->extra_prefix_len + + crypt->ops->extra_postfix_len; + + /* Number of fragments is the total bytes_per_frag / + * payload_per_fragment */ + nr_frags = bytes / bytes_per_frag; + bytes_last_frag = bytes % bytes_per_frag; + if (bytes_last_frag) + nr_frags++; + else + bytes_last_frag = bytes_per_frag; + + /* When we allocate the TXB we allocate enough space for the reserve + * and full fragment bytes (bytes_per_frag doesn't include prefix, + * postfix, header, FCS, etc.) */ + txb = ieee80211_alloc_txb(nr_frags, frag_size, GFP_ATOMIC); + if (unlikely(!txb)) { + printk(KERN_WARNING "%s: Could not allocate TXB\n", + ieee->dev->name); + goto failed; + } + txb->encrypted = encrypt; + txb->payload_size = bytes; + + for (i = 0; i < nr_frags; i++) { + skb_frag = txb->fragments[i]; + skb_frag->priority = UP2AC(skb->priority); + if (encrypt) + skb_reserve(skb_frag, crypt->ops->extra_prefix_len); + + frag_hdr = (struct ieee80211_hdr_3addr_QOS *)skb_put(skb_frag, hdr_len); + memcpy(frag_hdr, &header, hdr_len); + + /* If this is not the last fragment, then add the MOREFRAGS + * bit to the frame control */ + if (i != nr_frags - 1) { + frag_hdr->frame_ctl = cpu_to_le16( + fc | IEEE80211_FCTL_MOREFRAGS); + bytes = bytes_per_frag; + + } else { + /* The last fragment takes the remaining length */ + bytes = bytes_last_frag; + } + if(ieee->current_network.QoS_Enable) { + // add 1 only indicate to corresponding seq number control 2006/7/12 + frag_hdr->seq_ctl = cpu_to_le16(ieee->seq_ctrl[UP2AC(skb->priority)+1]<<4 | i); + //printk(KERN_WARNING "skb->priority = %d,", skb->priority); + //printk(KERN_WARNING "type:%d: seq = %d\n",UP2AC(skb->priority),ieee->seq_ctrl[UP2AC(skb->priority)+1]); + } else { + frag_hdr->seq_ctl = cpu_to_le16(ieee->seq_ctrl[0]<<4 | i); + } + //frag_hdr->seq_ctl = cpu_to_le16(ieee->seq_ctrl<<4 | i); + // + + /* Put a SNAP header on the first fragment */ + if (i == 0) { + ieee80211_put_snap( + skb_put(skb_frag, SNAP_SIZE + sizeof(u16)), + ether_type); + bytes -= SNAP_SIZE + sizeof(u16); + } + + memcpy(skb_put(skb_frag, bytes), skb->data, bytes); + + /* Advance the SKB... */ + skb_pull(skb, bytes); + + /* Encryption routine will move the header forward in order + * to insert the IV between the header and the payload */ + if (encrypt) + ieee80211_encrypt_fragment(ieee, skb_frag, hdr_len); + if (ieee->config & + (CFG_IEEE80211_COMPUTE_FCS | CFG_IEEE80211_RESERVE_FCS)) + skb_put(skb_frag, 4); + } + // Advance sequence number in data frame. + //printk(KERN_WARNING "QoS Enalbed? %s\n", ieee->current_network.QoS_Enable?"Y":"N"); + if (ieee->current_network.QoS_Enable) { + if (ieee->seq_ctrl[UP2AC(skb->priority) + 1] == 0xFFF) + ieee->seq_ctrl[UP2AC(skb->priority) + 1] = 0; + else + ieee->seq_ctrl[UP2AC(skb->priority) + 1]++; + } else { + if (ieee->seq_ctrl[0] == 0xFFF) + ieee->seq_ctrl[0] = 0; + else + ieee->seq_ctrl[0]++; + } + //--- + }else{ + if (unlikely(skb->len < sizeof(struct ieee80211_hdr_3addr))) { + printk(KERN_WARNING "%s: skb too small (%d).\n", + ieee->dev->name, skb->len); + goto success; + } + + txb = ieee80211_alloc_txb(1, skb->len, GFP_ATOMIC); + if(!txb){ + printk(KERN_WARNING "%s: Could not allocate TXB\n", + ieee->dev->name); + goto failed; + } + + txb->encrypted = 0; + txb->payload_size = skb->len; + memcpy(skb_put(txb->fragments[0],skb->len), skb->data, skb->len); + } + + success: + spin_unlock_irqrestore(&ieee->lock, flags); +#ifdef _RTL8187_EXT_PATCH_ + // Sometimes, extension mode can reuse skb (by txb->fragments[0]) + if( ! ((ieee->iw_mode == ieee->iw_ext_mode) && txb && (txb->fragments[0] == skb)) ) +#endif + dev_kfree_skb_any(skb); + if (txb) { + if (ieee->softmac_features & IEEE_SOFTMAC_TX_QUEUE){ + ieee80211_softmac_xmit(txb, ieee); + }else{ + if ((*ieee->hard_start_xmit)(txb, dev) == 0) { + stats->tx_packets++; + stats->tx_bytes += txb->payload_size; + return 0; + } + ieee80211_txb_free(txb); + } + } + + return 0; + + failed: + spin_unlock_irqrestore(&ieee->lock, flags); + netif_stop_queue(dev); + printk("netif_stop_queue in ieee80211_xmit \n"); + stats->tx_errors++; + return 1; + +} + + + +#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)) +EXPORT_SYMBOL(ieee80211_txb_free); +#ifdef _RTL8187_EXT_PATCH_ +EXPORT_SYMBOL(ieee80211_alloc_txb); +EXPORT_SYMBOL(ieee80211_ext_alloc_txb); +EXPORT_SYMBOL(ieee80211_ext_reuse_txb); + +EXPORT_SYMBOL(ieee80211_encrypt_fragment); +#endif // _RTL8187_EXT_PATCH_ +#else +EXPORT_SYMBOL_NOVERS(ieee80211_txb_free); +#ifdef _RTL8187_EXT_PATCH_ +EXPORT_SYMBOL_NOVERS(ieee80211_alloc_txb); +EXPORT_SYMBOL_NOVERS(ieee80211_ext_reuse_txb); + +EXPORT_SYMBOL_NOVERS(ieee80211_encrypt_fragment); +#endif // _RTL8187_EXT_PATCH_ +#endif + diff -Nur linux-2.6.30.5.orig/drivers/net/wireless/rtl8187b/ieee80211/ieee80211_wx.c linux-2.6.30.5/drivers/net/wireless/rtl8187b/ieee80211/ieee80211_wx.c --- linux-2.6.30.5.orig/drivers/net/wireless/rtl8187b/ieee80211/ieee80211_wx.c 1970-01-01 01:00:00.000000000 +0100 +++ linux-2.6.30.5/drivers/net/wireless/rtl8187b/ieee80211/ieee80211_wx.c 2009-08-23 19:01:04.000000000 +0200 @@ -0,0 +1,926 @@ +/****************************************************************************** + + Copyright(c) 2004 Intel Corporation. All rights reserved. + + Portions of this file are based on the WEP enablement code provided by the + Host AP project hostap-drivers v0.1.3 + Copyright (c) 2001-2002, SSH Communications Security Corp and Jouni Malinen + + Copyright (c) 2002-2003, Jouni Malinen + + This program is free software; you can redistribute it and/or modify it + under the terms of version 2 of the GNU General Public License as + published by the Free Software Foundation. + + 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. + + The full GNU General Public License is included in this distribution in the + file called LICENSE. + + Contact Information: + James P. Ketrenos + Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 + +******************************************************************************/ +#include +#include +#include +#include + +#include "ieee80211.h" +static const char *ieee80211_modes[] = { + "?", "a", "b", "ab", "g", "ag", "bg", "abg" +}; + +#define MAX_CUSTOM_LEN 64 +static inline char *rtl819x_translate_scan(struct ieee80211_device *ieee, + char *start, char *stop, + struct ieee80211_network *network, + struct iw_request_info *info) +{ + char custom[MAX_CUSTOM_LEN]; + char *p; + struct iw_event iwe; + int i, j; + u8 max_rate, rate; + + /* First entry *MUST* be the AP MAC address */ + iwe.cmd = SIOCGIWAP; + iwe.u.ap_addr.sa_family = ARPHRD_ETHER; + memcpy(iwe.u.ap_addr.sa_data, network->bssid, ETH_ALEN); +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,27) || defined (QMI_26_6)) + start = iwe_stream_add_event(info, start, stop, &iwe, IW_EV_ADDR_LEN); +#else + start = iwe_stream_add_event(start, stop, &iwe, IW_EV_ADDR_LEN); +#endif + /* Remaining entries will be displayed in the order we provide them */ + + /* Add the ESSID */ + iwe.cmd = SIOCGIWESSID; + iwe.u.data.flags = 1; + //YJ,modified,080903,for hidden ap + //if (network->flags & NETWORK_EMPTY_ESSID) { + if (network->ssid_len == 0) { + iwe.u.data.length = sizeof(""); +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,27) || defined (QMI_26_6)) + start = iwe_stream_add_point(info, start, stop, &iwe, ""); +#else + start = iwe_stream_add_point(start, stop, &iwe, ""); +#endif + } else { + iwe.u.data.length = min(network->ssid_len, (u8)32); +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,27) || defined (QMI_26_6)) + start = iwe_stream_add_point(info, start, stop, &iwe, network->ssid); +#else + start = iwe_stream_add_point(start, stop, &iwe, network->ssid); +#endif + } + + /* Add the protocol name */ + iwe.cmd = SIOCGIWNAME; + snprintf(iwe.u.name, IFNAMSIZ, "IEEE 802.11%s", ieee80211_modes[network->mode]); +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,27) || defined (QMI_26_6)) + start = iwe_stream_add_event(info, start, stop, &iwe, IW_EV_CHAR_LEN); +#else + start = iwe_stream_add_event(start, stop, &iwe, IW_EV_CHAR_LEN); +#endif + /* Add mode */ + iwe.cmd = SIOCGIWMODE; + if (network->capability & + (WLAN_CAPABILITY_BSS | WLAN_CAPABILITY_IBSS)) { + if (network->capability & WLAN_CAPABILITY_BSS) + iwe.u.mode = IW_MODE_MASTER; + else + iwe.u.mode = IW_MODE_ADHOC; + +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,27) || defined (QMI_26_6)) + start = iwe_stream_add_event(info, start, stop, &iwe, + IW_EV_UINT_LEN); +#else + start = iwe_stream_add_event(start, stop, &iwe, + IW_EV_UINT_LEN); +#endif + } + + /* Add frequency/channel */ + iwe.cmd = SIOCGIWFREQ; +/* iwe.u.freq.m = ieee80211_frequency(network->channel, network->mode); + iwe.u.freq.e = 3; */ + iwe.u.freq.m = network->channel; + iwe.u.freq.e = 0; + iwe.u.freq.i = 0; +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,27) || defined (QMI_26_6)) + start = iwe_stream_add_event(info, start, stop, &iwe, IW_EV_FREQ_LEN); +#else + start = iwe_stream_add_event(start, stop, &iwe, IW_EV_FREQ_LEN); +#endif + /* Add encryption capability */ + iwe.cmd = SIOCGIWENCODE; + if (network->capability & WLAN_CAPABILITY_PRIVACY) + iwe.u.data.flags = IW_ENCODE_ENABLED | IW_ENCODE_NOKEY; + else + iwe.u.data.flags = IW_ENCODE_DISABLED; + iwe.u.data.length = 0; +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,27) || defined (QMI_26_6)) + start = iwe_stream_add_point(info, start, stop, &iwe, network->ssid); +#else + start = iwe_stream_add_point(start, stop, &iwe, network->ssid); +#endif + /* Add basic and extended rates */ + max_rate = 0; + p = custom; + p += snprintf(p, MAX_CUSTOM_LEN - (p - custom), " Rates (Mb/s): "); + for (i = 0, j = 0; i < network->rates_len; ) { + if (j < network->rates_ex_len && + ((network->rates_ex[j] & 0x7F) < + (network->rates[i] & 0x7F))) + rate = network->rates_ex[j++] & 0x7F; + else + rate = network->rates[i++] & 0x7F; + if (rate > max_rate) + max_rate = rate; + p += snprintf(p, MAX_CUSTOM_LEN - (p - custom), + "%d%s ", rate >> 1, (rate & 1) ? ".5" : ""); + } + for (; j < network->rates_ex_len; j++) { + rate = network->rates_ex[j] & 0x7F; + p += snprintf(p, MAX_CUSTOM_LEN - (p - custom), + "%d%s ", rate >> 1, (rate & 1) ? ".5" : ""); + if (rate > max_rate) + max_rate = rate; + } + + iwe.cmd = SIOCGIWRATE; + iwe.u.bitrate.fixed = iwe.u.bitrate.disabled = 0; + iwe.u.bitrate.value = max_rate * 500000; +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,27) || defined (QMI_26_6)) + start = iwe_stream_add_event(info, start, stop, &iwe,IW_EV_PARAM_LEN); +#else + start = iwe_stream_add_event(start, stop, &iwe,IW_EV_PARAM_LEN); +#endif + iwe.cmd = IWEVCUSTOM; + iwe.u.data.length = p - custom; + if (iwe.u.data.length) +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,27) || defined (QMI_26_6)) + start = iwe_stream_add_point(info, start, stop, &iwe, custom); +#else + start = iwe_stream_add_point(start, stop, &iwe, custom); +#endif + /* Add quality statistics */ + /* TODO: Fix these values... */ + iwe.cmd = IWEVQUAL; + iwe.u.qual.qual = network->stats.signalstrength;//network->stats.signal; + iwe.u.qual.level = network->stats.signal;//network->stats.rssi; + iwe.u.qual.noise = network->stats.noise; +#if 0 + iwe.u.qual.updated = network->stats.mask & IEEE80211_STATMASK_WEMASK; + if (!(network->stats.mask & IEEE80211_STATMASK_RSSI)) + iwe.u.qual.updated |= IW_QUAL_LEVEL_INVALID; + if (!(network->stats.mask & IEEE80211_STATMASK_NOISE)) + iwe.u.qual.updated |= IW_QUAL_NOISE_INVALID; + if (!(network->stats.mask & IEEE80211_STATMASK_SIGNAL)) + iwe.u.qual.updated |= IW_QUAL_QUAL_INVALID; +#endif + + iwe.u.qual.updated = 0x7;//network->stats.mask & IEEE80211_STATMASK_WEMASK; +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,27) || defined (QMI_26_6)) + start = iwe_stream_add_event(info, start, stop, &iwe, IW_EV_QUAL_LEN); +#else + start = iwe_stream_add_event(start, stop, &iwe, IW_EV_QUAL_LEN); +#endif + iwe.cmd = IWEVCUSTOM; + p = custom; + + iwe.u.data.length = p - custom; + if (iwe.u.data.length) +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,27) || defined (QMI_26_6)) + start = iwe_stream_add_point(info, start, stop, &iwe, custom); +#else + start = iwe_stream_add_point(start, stop, &iwe, custom); +#endif +#if 0 + if (ieee->wpa_enabled && network->wpa_ie_len){ + char buf[MAX_WPA_IE_LEN * 2 + 30]; + // printk("WPA IE\n"); + u8 *p = buf; + p += sprintf(p, "wpa_ie="); + for (i = 0; i < network->wpa_ie_len; i++) { + p += sprintf(p, "%02x", network->wpa_ie[i]); + } + + memset(&iwe, 0, sizeof(iwe)); + iwe.cmd = IWEVCUSTOM; + iwe.u.data.length = strlen(buf); + start = iwe_stream_add_point(start, stop, &iwe, buf); + } + + if (ieee->wpa_enabled && network->rsn_ie_len){ + char buf[MAX_WPA_IE_LEN * 2 + 30]; + + u8 *p = buf; + p += sprintf(p, "rsn_ie="); + for (i = 0; i < network->rsn_ie_len; i++) { + p += sprintf(p, "%02x", network->rsn_ie[i]); + } + + +#else + memset(&iwe, 0, sizeof(iwe)); + if (network->wpa_ie_len) { + //printk("wpa_ie_len:%d\n", network->wpa_ie_len); + char buf[MAX_WPA_IE_LEN]; + memcpy(buf, network->wpa_ie, network->wpa_ie_len); + iwe.cmd = IWEVGENIE; + iwe.u.data.length = network->wpa_ie_len; +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,27) || defined (QMI_26_6)) + start = iwe_stream_add_point(info, start, stop, &iwe, buf); +#else + start = iwe_stream_add_point(start, stop, &iwe, buf); +#endif + } + + memset(&iwe, 0, sizeof(iwe)); + if (network->rsn_ie_len) { + //printk("=====>rsn_ie_len:\n", network->rsn_ie_len); + #if 0 + { + int i; + for (i=0; irsn_ie_len; i++); + printk("%2x ", network->rsn_ie[i]); + printk("\n"); + } + #endif + char buf[MAX_WPA_IE_LEN]; + memcpy(buf, network->rsn_ie, network->rsn_ie_len); + iwe.cmd = IWEVGENIE; + iwe.u.data.length = network->rsn_ie_len; +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,27) || defined (QMI_26_6)) + start = iwe_stream_add_point(info, start, stop, &iwe, buf); +#else + start = iwe_stream_add_point(start, stop, &iwe, buf); +#endif + } + +#endif + + /* Add EXTRA: Age to display seconds since last beacon/probe response + * for given network. */ + iwe.cmd = IWEVCUSTOM; + p = custom; + p += snprintf(p, MAX_CUSTOM_LEN - (p - custom), + " Last beacon: %lums ago", (jiffies - network->last_scanned) / (HZ / 100)); + iwe.u.data.length = p - custom; + if (iwe.u.data.length) +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,27) || defined (QMI_26_6)) + start = iwe_stream_add_point(info, start, stop, &iwe, custom); +#else + start = iwe_stream_add_point(start, stop, &iwe, custom); +#endif + + return start; +} + +int ieee80211_wx_get_scan(struct ieee80211_device *ieee, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + struct ieee80211_network *network; + unsigned long flags; + int err = 0; + char *ev = extra; + char *stop = ev + wrqu->data.length;//IW_SCAN_MAX_DATA; + //char *stop = ev + IW_SCAN_MAX_DATA; + int i = 0; + + IEEE80211_DEBUG_WX("Getting scan\n"); + down(&ieee->wx_sem); + spin_lock_irqsave(&ieee->lock, flags); + + if(!ieee->bHwRadioOff) + { + list_for_each_entry(network, &ieee->network_list, list) { + i++; + + if((stop-ev)<200) + { + err = -E2BIG; + break; + } + + if (ieee->scan_age == 0 || + time_after(network->last_scanned + ieee->scan_age, jiffies)) + { + ev = rtl819x_translate_scan(ieee, ev, stop, network, info); + } + else + IEEE80211_DEBUG_SCAN( + "Not showing network '%s (" + MAC_FMT ")' due to age (%lums).\n", + escape_essid(network->ssid, + network->ssid_len), + MAC_ARG(network->bssid), + (jiffies - network->last_scanned) / (HZ / 100)); + } + } + spin_unlock_irqrestore(&ieee->lock, flags); + up(&ieee->wx_sem); + wrqu->data.length = ev - extra; + wrqu->data.flags = 0; + + IEEE80211_DEBUG_WX("exit: %d networks returned.\n", i); + + return err; +} + +int ieee80211_wx_set_encode(struct ieee80211_device *ieee, + struct iw_request_info *info, + union iwreq_data *wrqu, char *keybuf) +{ + struct iw_point *erq = &(wrqu->encoding); + struct net_device *dev = ieee->dev; + struct ieee80211_security sec = { + .flags = 0 + }; + int i, key, key_provided, len; + struct ieee80211_crypt_data **crypt; + + IEEE80211_DEBUG_WX("SET_ENCODE\n"); + + key = erq->flags & IW_ENCODE_INDEX; + if (key) { + if (key > WEP_KEYS) + return -EINVAL; + key--; + key_provided = 1; + } else { + key_provided = 0; + key = ieee->tx_keyidx; + } + + IEEE80211_DEBUG_WX("Key: %d [%s]\n", key, key_provided ? + "provided" : "default"); +#ifdef _RTL8187_EXT_PATCH_ +#if 0 +{ + int j; + for(j=0; jcryptlist[j]->crypt[key]; +#else + crypt = &ieee->cryptlist[0]->crypt[key]; +#endif +#else + crypt = &ieee->crypt[key]; +#endif + if (erq->flags & IW_ENCODE_DISABLED) { + if (key_provided && *crypt) { + IEEE80211_DEBUG_WX("Disabling encryption on key %d.\n", + key); + ieee80211_crypt_delayed_deinit(ieee, crypt); + } else + IEEE80211_DEBUG_WX("Disabling encryption.\n"); + + /* Check all the keys to see if any are still configured, + * and if no key index was provided, de-init them all */ + for (i = 0; i < WEP_KEYS; i++) { +#ifdef _RTL8187_EXT_PATCH_ + + if (ieee->cryptlist[0]->crypt[i] != NULL){ +#else + + if (ieee->crypt[i] != NULL) { +#endif + if (key_provided) + break; + ieee80211_crypt_delayed_deinit( +#ifdef _RTL8187_EXT_PATCH_ + ieee, &ieee->cryptlist[0]->crypt[i]); +#else + ieee, &ieee->crypt[i]); +#endif + } + } + + if (i == WEP_KEYS) { + sec.enabled = 0; + sec.level = SEC_LEVEL_0; + sec.flags |= SEC_ENABLED | SEC_LEVEL; + } + + goto done; + } + + + + sec.enabled = 1; + sec.flags |= SEC_ENABLED; + + if (*crypt != NULL && (*crypt)->ops != NULL && + strcmp((*crypt)->ops->name, "WEP") != 0) { + /* changing to use WEP; deinit previously used algorithm + * on this key */ + ieee80211_crypt_delayed_deinit(ieee, crypt); + } + + if (*crypt == NULL) { + struct ieee80211_crypt_data *new_crypt; + + /* take WEP into use */ + new_crypt = kmalloc(sizeof(struct ieee80211_crypt_data), + GFP_KERNEL); + if (new_crypt == NULL) + return -ENOMEM; + memset(new_crypt, 0, sizeof(struct ieee80211_crypt_data)); + new_crypt->ops = ieee80211_get_crypto_ops("WEP"); + if (!new_crypt->ops) { + request_module("ieee80211_crypt_wep"); + new_crypt->ops = ieee80211_get_crypto_ops("WEP"); + } +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0) + if (new_crypt->ops && try_module_get(new_crypt->ops->owner)) +#else + if (new_crypt->ops && try_inc_mod_count(new_crypt->ops->owner)) +#endif + new_crypt->priv = new_crypt->ops->init(key); + + if (!new_crypt->ops || !new_crypt->priv) { + kfree(new_crypt); + new_crypt = NULL; + + printk(KERN_WARNING "%s: could not initialize WEP: " + "load module ieee80211_crypt_wep\n", + dev->name); + return -EOPNOTSUPP; + } + *crypt = new_crypt; + } + + /* If a new key was provided, set it up */ + if (erq->length > 0) { + len = erq->length <= 5 ? 5 : 13; + memcpy(sec.keys[key], keybuf, erq->length); + if (len > erq->length) + memset(sec.keys[key] + erq->length, 0, + len - erq->length); + IEEE80211_DEBUG_WX("Setting key %d to '%s' (%d:%d bytes)\n", + key, escape_essid(sec.keys[key], len), + erq->length, len); + sec.key_sizes[key] = len; + (*crypt)->ops->set_key(sec.keys[key], len, NULL, + (*crypt)->priv); + sec.flags |= (1 << key); + /* This ensures a key will be activated if no key is + * explicitely set */ + if (key == sec.active_key) + sec.flags |= SEC_ACTIVE_KEY; + + ieee->tx_keyidx = key; //we need it to support multi_key setting. added by wb 2008_2_22 + } else { + len = (*crypt)->ops->get_key(sec.keys[key], WEP_KEY_LEN, + NULL, (*crypt)->priv); + if (len == 0) { + /* Set a default key of all 0 */ + IEEE80211_DEBUG_WX("Setting key %d to all zero.\n", + key); + memset(sec.keys[key], 0, 13); + (*crypt)->ops->set_key(sec.keys[key], 13, NULL, + (*crypt)->priv); + sec.key_sizes[key] = 13; + sec.flags |= (1 << key); + } + + /* No key data - just set the default TX key index */ + if (key_provided) { + IEEE80211_DEBUG_WX( + "Setting key %d to default Tx key.\n", key); + ieee->tx_keyidx = key; + sec.active_key = key; + sec.flags |= SEC_ACTIVE_KEY; + } + } +#ifdef _RTL8187_EXT_PATCH_ +#if 0 +} +} +#endif +#endif + done: + ieee->open_wep = !(erq->flags & IW_ENCODE_RESTRICTED); + sec.auth_mode = ieee->open_wep ? WLAN_AUTH_OPEN : WLAN_AUTH_SHARED_KEY; + sec.flags |= SEC_AUTH_MODE; + IEEE80211_DEBUG_WX("Auth: %s\n", sec.auth_mode == WLAN_AUTH_OPEN ? + "OPEN" : "SHARED KEY"); + + /* For now we just support WEP, so only set that security level... + * TODO: When WPA is added this is one place that needs to change */ + sec.flags |= SEC_LEVEL; + sec.level = SEC_LEVEL_1; /* 40 and 104 bit WEP */ + + if (ieee->set_security) + ieee->set_security(dev, &sec); + + /* Do not reset port if card is in Managed mode since resetting will + * generate new IEEE 802.11 authentication which may end up in looping + * with IEEE 802.1X. If your hardware requires a reset after WEP + * configuration (for example... Prism2), implement the reset_port in + * the callbacks structures used to initialize the 802.11 stack. */ + if (ieee->reset_on_keychange && + ieee->iw_mode != IW_MODE_INFRA && + ieee->reset_port && ieee->reset_port(dev)) { + printk(KERN_DEBUG "%s: reset_port failed\n", dev->name); + return -EINVAL; + } + return 0; +} + +int ieee80211_wx_get_encode(struct ieee80211_device *ieee, + struct iw_request_info *info, + union iwreq_data *wrqu, char *keybuf) +{ + struct iw_point *erq = &(wrqu->encoding); + int len, key; + struct ieee80211_crypt_data *crypt; + + IEEE80211_DEBUG_WX("GET_ENCODE\n"); + + if(ieee->iw_mode == IW_MODE_MONITOR) + return -1; + + key = erq->flags & IW_ENCODE_INDEX; + if (key) { + if (key > WEP_KEYS) + return -EINVAL; + key--; + } else + key = ieee->tx_keyidx; +#ifdef _RTL8187_EXT_PATCH_ + crypt = ieee->cryptlist[0]->crypt[key]; +#else + crypt = ieee->crypt[key]; +#endif + erq->flags = key + 1; + + if (crypt == NULL || crypt->ops == NULL) { + erq->length = 0; + erq->flags |= IW_ENCODE_DISABLED; + return 0; + } + + if (strcmp(crypt->ops->name, "WEP") != 0) { + /* only WEP is supported with wireless extensions, so just + * report that encryption is used */ + erq->length = 0; + erq->flags |= IW_ENCODE_ENABLED; + return 0; + } + + len = crypt->ops->get_key(keybuf, WEP_KEY_LEN, NULL, crypt->priv); + erq->length = (len >= 0 ? len : 0); + + erq->flags |= IW_ENCODE_ENABLED; + + if (ieee->open_wep) + erq->flags |= IW_ENCODE_OPEN; + else + erq->flags |= IW_ENCODE_RESTRICTED; + + return 0; +} + +int ieee80211_wx_set_encode_ext(struct ieee80211_device *ieee, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + struct net_device *dev = ieee->dev; + struct iw_point *encoding = &wrqu->encoding; + struct iw_encode_ext *ext = (struct iw_encode_ext *)extra; + int i, idx, ret = 0; + int group_key = 0; + const char *alg, *module; + struct ieee80211_crypto_ops *ops; + struct ieee80211_crypt_data **crypt; + + struct ieee80211_security sec = { + .flags = 0, + }; + //printk("======>encoding flag:%x,ext flag:%x, ext alg:%d\n", encoding->flags,ext->ext_flags, ext->alg); + idx = encoding->flags & IW_ENCODE_INDEX; + if (idx) { + if (idx < 1 || idx > WEP_KEYS) + return -EINVAL; + idx--; + } else + idx = ieee->tx_keyidx; + + if (ext->ext_flags & IW_ENCODE_EXT_GROUP_KEY) { +#ifdef _RTL8187_EXT_PATCH_ + crypt = &ieee->cryptlist[0]->crypt[idx]; +#else + crypt = &ieee->crypt[idx]; +#endif + group_key = 1; + } else { + /* some Cisco APs use idx>0 for unicast in dynamic WEP */ + //printk("not group key, flags:%x, ext->alg:%d\n", ext->ext_flags, ext->alg); + if (idx != 0 && ext->alg != IW_ENCODE_ALG_WEP) + return -EINVAL; + if (ieee->iw_mode == IW_MODE_INFRA) +#ifdef _RTL8187_EXT_PATCH_ + crypt = &ieee->cryptlist[0]->crypt[idx]; +#else + crypt = &ieee->crypt[idx]; +#endif + else + return -EINVAL; + } + + sec.flags |= SEC_ENABLED;// | SEC_ENCRYPT; + if ((encoding->flags & IW_ENCODE_DISABLED) || + ext->alg == IW_ENCODE_ALG_NONE) { + if (*crypt) + ieee80211_crypt_delayed_deinit(ieee, crypt); + + for (i = 0; i < WEP_KEYS; i++) +#ifdef _RTL8187_EXT_PATCH_ + if (ieee->cryptlist[0]->crypt[i] != NULL) +#else + if (ieee->crypt[i] != NULL) +#endif + break; + + if (i == WEP_KEYS) { + sec.enabled = 0; + // sec.encrypt = 0; + sec.level = SEC_LEVEL_0; + sec.flags |= SEC_LEVEL; + } + //printk("disabled: flag:%x\n", encoding->flags); + goto done; + } + + sec.enabled = 1; + // sec.encrypt = 1; +#if 0 + if (group_key ? !ieee->host_mc_decrypt : + !(ieee->host_encrypt || ieee->host_decrypt || + ieee->host_encrypt_msdu)) + goto skip_host_crypt; +#endif + switch (ext->alg) { + case IW_ENCODE_ALG_WEP: + alg = "WEP"; + module = "ieee80211_crypt_wep"; + break; + case IW_ENCODE_ALG_TKIP: + alg = "TKIP"; + module = "ieee80211_crypt_tkip"; + break; + case IW_ENCODE_ALG_CCMP: + alg = "CCMP"; + module = "ieee80211_crypt_ccmp"; + break; + default: + IEEE80211_DEBUG_WX("%s: unknown crypto alg %d\n", + dev->name, ext->alg); + ret = -EINVAL; + goto done; + } + printk("alg name:%s\n",alg); + + ops = ieee80211_get_crypto_ops(alg); + if (ops == NULL) { + request_module(module); + ops = ieee80211_get_crypto_ops(alg); + } + if (ops == NULL) { + IEEE80211_DEBUG_WX("%s: unknown crypto alg %d\n", + dev->name, ext->alg); + printk("========>unknown crypto alg %d\n", ext->alg); + ret = -EINVAL; + goto done; + } + + if (*crypt == NULL || (*crypt)->ops != ops) { + struct ieee80211_crypt_data *new_crypt; + + ieee80211_crypt_delayed_deinit(ieee, crypt); + + new_crypt = kzalloc(sizeof(*new_crypt), GFP_KERNEL); + if (new_crypt == NULL) { + ret = -ENOMEM; + goto done; + } + new_crypt->ops = ops; + if (new_crypt->ops && try_module_get(new_crypt->ops->owner)) + new_crypt->priv = new_crypt->ops->init(idx); + if (new_crypt->priv == NULL) { + kfree(new_crypt); + ret = -EINVAL; + goto done; + } + *crypt = new_crypt; + + } + //I need to deinit other crypt here in mesh mode instead deinit them while use them to tx&rx. +#ifdef _RTL8187_EXT_PATCH_ + if (ieee->iw_mode == ieee->iw_ext_mode) + { + int j; + for (j=1; jcryptlist[j]->crypt[idx]; + if (*crypttmp == NULL) + break; + if (*crypttmp && (*crypttmp)->ops != ops) + ieee80211_crypt_delayed_deinit(ieee, crypttmp); + } + } +#endif + if (ext->key_len > 0 && (*crypt)->ops->set_key && + (*crypt)->ops->set_key(ext->key, ext->key_len, ext->rx_seq, + (*crypt)->priv) < 0) { + IEEE80211_DEBUG_WX("%s: key setting failed\n", dev->name); + printk("key setting failed\n"); + ret = -EINVAL; + goto done; + } +#if 1 +// skip_host_crypt: + //printk("skip_host_crypt:ext_flags:%x\n", ext->ext_flags); + if (ext->ext_flags & IW_ENCODE_EXT_SET_TX_KEY) { + ieee->tx_keyidx = idx; + sec.active_key = idx; + sec.flags |= SEC_ACTIVE_KEY; + } + + if (ext->alg != IW_ENCODE_ALG_NONE) { + memcpy(sec.keys[idx], ext->key, ext->key_len); + sec.key_sizes[idx] = ext->key_len; + sec.flags |= (1 << idx); + if (ext->alg == IW_ENCODE_ALG_WEP) { + // sec.encode_alg[idx] = SEC_ALG_WEP; + sec.flags |= SEC_LEVEL; + sec.level = SEC_LEVEL_1; + } else if (ext->alg == IW_ENCODE_ALG_TKIP) { + // sec.encode_alg[idx] = SEC_ALG_TKIP; + sec.flags |= SEC_LEVEL; + sec.level = SEC_LEVEL_2; + } else if (ext->alg == IW_ENCODE_ALG_CCMP) { + // sec.encode_alg[idx] = SEC_ALG_CCMP; + sec.flags |= SEC_LEVEL; + sec.level = SEC_LEVEL_3; + } + /* Don't set sec level for group keys. */ + if (group_key) + sec.flags &= ~SEC_LEVEL; + } +#endif +done: + if (ieee->set_security) + ieee->set_security(ieee->dev, &sec); + + if (ieee->reset_on_keychange && + ieee->iw_mode != IW_MODE_INFRA && + ieee->reset_port && ieee->reset_port(dev)) { + IEEE80211_DEBUG_WX("%s: reset_port failed\n", dev->name); + return -EINVAL; + } + + return ret; +} +int ieee80211_wx_set_mlme(struct ieee80211_device *ieee, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + struct iw_mlme *mlme = (struct iw_mlme *) extra; +// printk("\ndkgadfslkdjgalskdf===============>%s(), cmd:%x\n", __FUNCTION__, mlme->cmd); +#if 1 + switch (mlme->cmd) { + case IW_MLME_DEAUTH: + case IW_MLME_DISASSOC: + // printk("disassoc now\n"); + ieee80211_disassociate(ieee); + break; + default: + return -EOPNOTSUPP; + } +#endif + return 0; +} + +int ieee80211_wx_set_auth(struct ieee80211_device *ieee, + struct iw_request_info *info, + struct iw_param *data, char *extra) +{ +/* + struct ieee80211_security sec = { + .flags = SEC_AUTH_MODE, + } +*/ + //printk("set auth:flag:%x, data value:%x\n", data->flags, data->value); + switch (data->flags & IW_AUTH_INDEX) { + case IW_AUTH_WPA_VERSION: + /*need to support wpa2 here*/ + //printk("wpa version:%x\n", data->value); + break; + case IW_AUTH_CIPHER_PAIRWISE: + case IW_AUTH_CIPHER_GROUP: + case IW_AUTH_KEY_MGMT: + /* + * * Host AP driver does not use these parameters and allows + * * wpa_supplicant to control them internally. + * */ + break; + case IW_AUTH_TKIP_COUNTERMEASURES: + ieee->tkip_countermeasures = data->value; + break; + case IW_AUTH_DROP_UNENCRYPTED: + ieee->drop_unencrypted = data->value; + break; + + case IW_AUTH_80211_AUTH_ALG: + ieee->open_wep = (data->value&IW_AUTH_ALG_OPEN_SYSTEM)?1:0; + //printk("open_wep:%d\n", ieee->open_wep); + break; + +#if 1 + case IW_AUTH_WPA_ENABLED: + ieee->wpa_enabled = (data->value)?1:0; + //printk("enalbe wpa:%d\n", ieee->wpa_enabled); + break; + +#endif + case IW_AUTH_RX_UNENCRYPTED_EAPOL: + ieee->ieee802_1x = data->value; + break; + case IW_AUTH_PRIVACY_INVOKED: + ieee->privacy_invoked = data->value; + break; + default: + return -EOPNOTSUPP; + } + return 0; +} + +#if 1 +int ieee80211_wx_set_gen_ie(struct ieee80211_device *ieee, u8 *ie, size_t len) +{ +#if 0 + printk("====>%s()\n", __FUNCTION__); + { + int i; + for (i=0; iMAX_WPA_IE_LEN || (len && ie == NULL)) + { + // printk("return error out, len:%d\n", len); + return -EINVAL; + } + if (len) + { + + if (len != ie[1]+2) printk("len:%d, ie:%d\n", (int)len, ie[1]); + buf = kmalloc(len, GFP_KERNEL); + if (buf == NULL) + return -ENOMEM; + memcpy(buf, ie, len); + kfree(ieee->wpa_ie); + ieee->wpa_ie = buf; + ieee->wpa_ie_len = len; + } + else{ + if (ieee->wpa_ie) + kfree(ieee->wpa_ie); + ieee->wpa_ie = NULL; + ieee->wpa_ie_len = 0; + } +// printk("<=====out %s()\n", __FUNCTION__); + + return 0; + +} +#endif + +EXPORT_SYMBOL(ieee80211_wx_set_gen_ie); +EXPORT_SYMBOL(ieee80211_wx_set_mlme); +EXPORT_SYMBOL(ieee80211_wx_set_auth); +EXPORT_SYMBOL(ieee80211_wx_set_encode_ext); +EXPORT_SYMBOL(ieee80211_wx_get_scan); +EXPORT_SYMBOL(ieee80211_wx_set_encode); +EXPORT_SYMBOL(ieee80211_wx_get_encode); +#if 0 +EXPORT_SYMBOL_NOVERS(ieee80211_wx_get_scan); +EXPORT_SYMBOL_NOVERS(ieee80211_wx_set_encode); +EXPORT_SYMBOL_NOVERS(ieee80211_wx_get_encode); +#endif diff -Nur linux-2.6.30.5.orig/drivers/net/wireless/rtl8187b/ieee80211/internal.h linux-2.6.30.5/drivers/net/wireless/rtl8187b/ieee80211/internal.h --- linux-2.6.30.5.orig/drivers/net/wireless/rtl8187b/ieee80211/internal.h 1970-01-01 01:00:00.000000000 +0100 +++ linux-2.6.30.5/drivers/net/wireless/rtl8187b/ieee80211/internal.h 2009-08-23 19:01:04.000000000 +0200 @@ -0,0 +1,115 @@ +/* + * Cryptographic API. + * + * Copyright (c) 2002 James Morris + * + * 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. + * + */ +#ifndef _CRYPTO_INTERNAL_H +#define _CRYPTO_INTERNAL_H + + +//#include +#include "rtl_crypto.h" +#include +#include +#include +#include +#include +#include + +#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,4,20)) +#define list_for_each_entry(pos, head, member) \ + for (pos = list_entry((head)->next, typeof(*pos), member), \ + prefetch(pos->member.next); \ + &pos->member != (head); \ + pos = list_entry(pos->member.next, typeof(*pos), member), \ + prefetch(pos->member.next)) + +static inline void cond_resched(void) +{ + if (need_resched()) { + set_current_state(TASK_RUNNING); + schedule(); + } +} +#endif + +extern enum km_type crypto_km_types[]; + +static inline enum km_type crypto_kmap_type(int out) +{ + return crypto_km_types[(in_softirq() ? 2 : 0) + out]; +} + +static inline void *crypto_kmap(struct page *page, int out) +{ + return kmap_atomic(page, crypto_kmap_type(out)); +} + +static inline void crypto_kunmap(void *vaddr, int out) +{ + kunmap_atomic(vaddr, crypto_kmap_type(out)); +} + +static inline void crypto_yield(struct crypto_tfm *tfm) +{ + if (!in_softirq()) + cond_resched(); +} + +static inline void *crypto_tfm_ctx(struct crypto_tfm *tfm) +{ + return (void *)&tfm[1]; +} + +struct crypto_alg *crypto_alg_lookup(const char *name); + +#ifdef CONFIG_KMOD +void crypto_alg_autoload(const char *name); +struct crypto_alg *crypto_alg_mod_lookup(const char *name); +#else +static inline struct crypto_alg *crypto_alg_mod_lookup(const char *name) +{ + return crypto_alg_lookup(name); +} +#endif + +#ifdef CONFIG_CRYPTO_HMAC +int crypto_alloc_hmac_block(struct crypto_tfm *tfm); +void crypto_free_hmac_block(struct crypto_tfm *tfm); +#else +static inline int crypto_alloc_hmac_block(struct crypto_tfm *tfm) +{ + return 0; +} + +static inline void crypto_free_hmac_block(struct crypto_tfm *tfm) +{ } +#endif + +#ifdef CONFIG_PROC_FS +void __init crypto_init_proc(void); +#else +static inline void crypto_init_proc(void) +{ } +#endif + +int crypto_init_digest_flags(struct crypto_tfm *tfm, u32 flags); +int crypto_init_cipher_flags(struct crypto_tfm *tfm, u32 flags); +int crypto_init_compress_flags(struct crypto_tfm *tfm, u32 flags); + +int crypto_init_digest_ops(struct crypto_tfm *tfm); +int crypto_init_cipher_ops(struct crypto_tfm *tfm); +int crypto_init_compress_ops(struct crypto_tfm *tfm); + +void crypto_exit_digest_ops(struct crypto_tfm *tfm); +void crypto_exit_cipher_ops(struct crypto_tfm *tfm); +void crypto_exit_compress_ops(struct crypto_tfm *tfm); + +#endif /* _CRYPTO_INTERNAL_H */ + diff -Nur linux-2.6.30.5.orig/drivers/net/wireless/rtl8187b/ieee80211/kmap_types.h linux-2.6.30.5/drivers/net/wireless/rtl8187b/ieee80211/kmap_types.h --- linux-2.6.30.5.orig/drivers/net/wireless/rtl8187b/ieee80211/kmap_types.h 1970-01-01 01:00:00.000000000 +0100 +++ linux-2.6.30.5/drivers/net/wireless/rtl8187b/ieee80211/kmap_types.h 2009-08-23 19:01:04.000000000 +0200 @@ -0,0 +1,20 @@ +#ifndef __KMAP_TYPES_H + +#define __KMAP_TYPES_H + + +enum km_type { + KM_BOUNCE_READ, + KM_SKB_SUNRPC_DATA, + KM_SKB_DATA_SOFTIRQ, + KM_USER0, + KM_USER1, + KM_BH_IRQ, + KM_SOFTIRQ0, + KM_SOFTIRQ1, + KM_TYPE_NR +}; + +#define _ASM_KMAP_TYPES_H + +#endif diff -Nur linux-2.6.30.5.orig/drivers/net/wireless/rtl8187b/ieee80211/readme linux-2.6.30.5/drivers/net/wireless/rtl8187b/ieee80211/readme --- linux-2.6.30.5.orig/drivers/net/wireless/rtl8187b/ieee80211/readme 1970-01-01 01:00:00.000000000 +0100 +++ linux-2.6.30.5/drivers/net/wireless/rtl8187b/ieee80211/readme 2009-08-23 19:01:04.000000000 +0200 @@ -0,0 +1,162 @@ +What this layer should do + +- It mantain the old mechanism as alternative, so the + ipw2100 driver works with really few changes. +- Encapsulate / Decapsulate ieee80211 packet +- Handle fragmentation +- Optionally provide an alterantive mechanism for netif queue stop/wake, + so that the ieee80211 layer will pass one fragment per time instead of + one txb struct per time. so the driver can stop the queue in the middle + of a packet. +- Provide two different TX interfaces for cards that can handle management + frames on one HW queue, and data on another, and for cards that have only + one HW queue (the latter untested and very, very rough). +- Optionally provide the logic for handling IBSS/MASTER/MONITOR/BSS modes + and for the channel, essid and wap get/set wireless extension requests. + so that the driver has only to change channel when the ieee stack tell it. +- Optionally provide a scanning mechanism so that the driver has not to + worry about this, just implement the set channel calback and pass + frames to the upper layer +- Optionally provide the bss client protocol handshaking (just with open + authentication) +- Optionally provide the probe request send mechanism +- Optionally provide the bss master mode logic to handle association + protocol (only open authentication) and probe responses. +- SW wep encryption (with open authentication) +- It collects some stats +- It provides beacons to the card when it ask for them + +What this layer doesn't do (yet) +- Perform shared authentication +- Have full support for master mode (the AP should loop back in the air + frames from an associated client to another. This could be done easily + with few lines of code, and it is done in my previous version of the + stach, but a table of association must be keept and a disassociation + policy must be decided and implemented. +- Handle cleanly the full ieee 802.11 protocol. In AP mode it never + disassociate clients, and it is really prone to always allow access. + In bss client mode it is a bit rough with AP deauth and disassoc requests. +- It has not any entry point to view the collected stats. +- Altought it takes care of the card supported rates in the management frame + it sends, support for rate changing on TXed packet is not complete. +- Give up once associated in bss client mode (it never detect a + signal loss condition to disassociate and restart scanning) +- Provide a mechanism for enabling the TX in monitor mode, so + userspace programs can TX raw packets. +- Provide a mechanism for cards that need that the SW take care of beacon + TX completely, in sense that the SW has to enqueue by itself beacons + to the card so it TX them (if any...) +APIs + +Callback functions in the original stack has been mantained. +following has been added (from ieee80211.h) + + /* Softmac-generated frames (mamagement) are TXed via this + * callback if the flag IEEE_SOFTMAC_SINGLE_QUEUE is + * not set. As some cards may have different HW queues that + * one might want to use for data and management frames + * the option to have two callbacks might be useful. + * This fucntion can't sleep. + */ + int (*softmac_hard_start_xmit)(struct sk_buff *skb, + struct net_device *dev); + + /* used instead of hard_start_xmit (not softmac_hard_start_xmit) + * if the IEEE_SOFTMAC_TX_QUEUE feature is used to TX data + * frames. I the option IEEE_SOFTMAC_SINGLE_QUEUE is also set + * then also management frames are sent via this callback. + * This function can't sleep. + */ + void (*softmac_data_hard_start_xmit)(struct sk_buff *skb, + struct net_device *dev); + + /* stops the HW queue for DATA frames. Useful to avoid + * waste time to TX data frame when we are reassociating + * This function can sleep. + */ + void (*data_hard_stop)(struct net_device *dev); + + /* OK this is complementar to data_poll_hard_stop */ + void (*data_hard_resume)(struct net_device *dev); + + /* ask to the driver to retune the radio . + * This function can sleep. the driver should ensure + * the radio has been swithced before return. + */ + void (*set_chan)(struct net_device *dev,short ch); + + /* These are not used if the ieee stack takes care of + * scanning (IEEE_SOFTMAC_SCAN feature set). + * In this case only the set_chan is used. + * + * The syncro version is similar to the start_scan but + * does not return until all channels has been scanned. + * this is called in user context and should sleep, + * it is called in a work_queue when swithcing to ad-hoc mode + * or in behalf of iwlist scan when the card is associated + * and root user ask for a scan. + * the fucntion stop_scan should stop both the syncro and + * background scanning and can sleep. + * The fucntion start_scan should initiate the background + * scanning and can't sleep. + */ + void (*scan_syncro)(struct net_device *dev); + void (*start_scan)(struct net_device *dev); + void (*stop_scan)(struct net_device *dev); + + /* indicate the driver that the link state is changed + * for example it may indicate the card is associated now. + * Driver might be interested in this to apply RX filter + * rules or simply light the LINK led + */ + void (*link_change)(struct net_device *dev); + +Functions hard_data_[resume/stop] are optional and should not be used +if the driver decides to uses data+management frames enqueue in a +single HQ queue (thus using just the softmac_hard_data_start_xmit +callback). + +Function that the driver can use are: + +ieee80211_get_beacon - this is called by the driver when + the HW needs a beacon. +ieee80211_softmac_start_protocol - this should normally be called in the + driver open function +ieee80211_softmac_stop_protocol - the opposite of the above +ieee80211_wake_queue - this is similar to netif_wake_queue +ieee80211_reset_queue - this throw away fragments pending(if any) +ieee80211_stop_queue - this is similar to netif_stop_queue + + +known BUGS: +- When performing syncro scan (possiblily when swithcing to ad-hoc mode + and when running iwlist scan when associated) there is still an odd + behaviour.. I have not looked in this more accurately (yet). + +locking: +locking is done by means of three structures. +1- ieee->lock (by means of spin_[un]lock_irq[save/restore] +2- ieee->wx_sem +3- ieee->scan_sem + +the lock 1 is what protect most of the critical sections in the ieee stack. +the lock 2 is used to avoid that more than one of the SET wireless extension +handlers (as well as start/stop protocol function) are running at the same time. +the lock 1 is used when we need to modify or read the shared data in the wx handlers. +In other words the lock 2 will prevent one SET action will run across another SET +action (by make sleep the 2nd one) but allow GET actions, while the lock 1 +make atomic those little shared data access in both GET and SET operation. +So get operation will be never be delayed really: they will never sleep.. +Furthermore in the top of some SET operations a flag is set before acquiring +the lock. This is an help to make the previous running SET operation to +finish faster if needed (just in case the second one will totally undo the +first, so there is not need to complete the 1st really.. ). +The background scanning mechaninsm is protected by the lock 1 except for the +workqueue. this wq is here just to let the set_chan callback sleep (I thinked it +might be appreciated by USB network card driver developer). In this case the lock 3 +take its turn. +Thus the stop function needs both the locks. +Funny in the syncro scan the lock 2 play its role (as both the syncro_scan +function and the stop scan function are called with this semaphore held). + + diff -Nur linux-2.6.30.5.orig/drivers/net/wireless/rtl8187b/ieee80211/rtl8187_mesh.h linux-2.6.30.5/drivers/net/wireless/rtl8187b/ieee80211/rtl8187_mesh.h --- linux-2.6.30.5.orig/drivers/net/wireless/rtl8187b/ieee80211/rtl8187_mesh.h 1970-01-01 01:00:00.000000000 +0100 +++ linux-2.6.30.5/drivers/net/wireless/rtl8187b/ieee80211/rtl8187_mesh.h 2009-08-23 19:01:04.000000000 +0200 @@ -0,0 +1,282 @@ +#ifndef _RTL8187_MESH_H_ +#define _RTL8187_MESH_H_ + +#include "msh_class.h" // struct mshclass +#include "mesh.h" // struct MESH-Neighbor-Entry +#include "ieee80211.h" // struct ieee80211-network +#include "mesh_8185_util.h" // DOT11-QUEUE +#include "hash_table.h" // hash-table +#include "8185s_pathsel.h" +#include + +#define GET_MESH_PRIV(x) ((struct mshclass_priv *)(x->priv)) + +struct ieee80211_hdr_mesh { + u16 frame_ctl; + u16 duration_id; + u8 addr1[ETH_ALEN]; + u8 addr2[ETH_ALEN]; + u8 addr3[ETH_ALEN]; + u16 seq_ctl; + u8 addr4[ETH_ALEN]; + unsigned char mesh_flag; + INT8 TTL; + UINT16 segNum; + unsigned char DestMACAddr[ETH_ALEN]; // modify for 6 address + unsigned char SrcMACAddr[ETH_ALEN]; +} __attribute__ ((packed)); + +struct myMeshIDNode { + struct list_head list; + char id[MESH_ID_LEN+1]; + short popEN; + char tried; + unsigned long expire; + struct ieee80211_network mesh_network; +}; + +struct ieee80211_hdr_mesh_QOS { + u16 frame_ctl; + u16 duration_id; + u8 addr1[ETH_ALEN]; + u8 addr2[ETH_ALEN]; + u8 addr3[ETH_ALEN]; + u16 seq_ctl; + u8 addr4[ETH_ALEN]; + u16 QOS_ctl; + unsigned char mesh_flag; + INT8 TTL; + UINT16 segNum; + unsigned char DestMACAddr[ETH_ALEN]; // modify for 6 address + unsigned char SrcMACAddr[ETH_ALEN]; +} __attribute__ ((packed)); + + +struct mesh_PeerEntry { + // based on 8185ag.h + struct list_head hash_list; + unsigned int used; ///< used == TRUE => has been allocated, \n used == FALSE => can be allocated + unsigned char hwaddr[MACADDRLEN]; ///< hardware address + + // struct list_head mesh_unEstablish_ptr; // ©|¥¼(©Î±q¤w³s½u -> ¥¼³s½u) ¤§ MP list + struct list_head mesh_mp_ptr; // MP list + + /*mesh_neighbor: + * Inited by "Neighbor Discovering" + * cleaned by "Disassociation" or "Expired" + */ + struct MESH_Neighbor_Entry mesh_neighbor_TBL; + + struct ieee80211_network * pstat; // a backward pointer + + // 802.11 seq checking + u16 last_rxseq; /* rx seq previous per-tid */ + u16 last_rxfrag;/* tx frag previous per-tid */ + unsigned long last_time; + // +}; + + +struct mshclass_priv { + + struct mesh_PeerEntry *meshEntries; // 1-to-1 for priv->ieee80211->networks + + spinlock_t lock_stainfo; // lock for accessing the data structure of stat info + spinlock_t lock_queue; // lock for DOT11_EnQueue2/DOT11_DeQueue2/enque/dequeue + spinlock_t lock_Rreq; // lock for rreq_retry. Some function like aodv_expire/tx use lock_queue simultaneously +// spinlock_t lock_meshlist; + + // struct _DOT11_QUEUE *pevent_queue; ///< 802.11 QUEUEµ²ºc + // struct hash_table *pathsel_table; // GANTOE + //tsananiu + struct _DOT11_QUEUE *pathsel_queue; ///< 802.11 QUEUEµ²ºc + + //tsananiu end + + //add by shlu 20070518 + unsigned char RreqMAC[AODV_RREQ_TABLE_SIZE][6]; + unsigned int RreqBegin; + unsigned int RreqEnd; + +#if defined(MESH_ROLE_ROOT) || defined(MESH_ROLE_PORTAL) +#define MAX_SZ_BAD_MAC 3 + unsigned char BadMac[MAX_SZ_BAD_MAC][MACADDRLEN]; + int idx_BadMac; +#endif // MESH_ROLE_ROOT || MESH_ROLE_PORTAL + + //------------- + unsigned char root_mac[MACADDRLEN]; + struct mesh_info dot11MeshInfo; // extrated from wifi_mib (ieee802_mib.h) + struct hash_table *proxy_table, *mesh_rreq_retry_queue; //GANTOE //GANTOE + struct hash_table *pathsel_table; // add by chuangch 2007.09.13 + // add by Jason + struct mpp_tb *pann_mpp_tb; + + struct timer_list expire_timer; // 1sec timer + + struct timer_list beacon_timer; // 1sec timer + struct list_head stat_hash[MAX_NETWORK_COUNT]; // sta_info hash table (aid_obj) + + struct list_head meshList[MAX_CHANNEL_NUMBER]; + int scanMode; + + struct { + struct ieee80211_network *pstat; + unsigned char hwaddr[MACADDRLEN]; + } stainfo_cache; + + // The following elements are used by 802.11s. + // For copyright-pretection, we use an independent (binary) module. + // Note that it can also be put either under r8180_priv or ieee80211_device. The adv of put under + // r8180_priv is to get "higher encapsulation". On the other hand, r8180_priv was originally designed + // for "hardward specific." + char mesh_mac_filter_allow[8][13]; + char mesh_mac_filter_deny[8][13]; + + struct MESH_Share meshare; // mesh share data + + struct { + + int prev_iw_mode; // Save this->iw_mode for r8180_wx->r8180_wx_enable_mesh. No init requirement + + struct MESH_Profile mesh_profile; // contains MESHID + + struct mesh_info dot11MeshInfo; // contains meshMaxAssocNum + + struct net_device_stats mesh_stats; + + UINT8 mesh_Version; // ¨Ï¥Îªºª©¥» + // WLAN Mesh Capability + INT16 mesh_PeerCAP_cap; // peer capability-Cap number (¦³¸¹¼Æ) + UINT8 mesh_PeerCAP_flags; // peer capability-flags + UINT8 mesh_PowerSaveCAP; // Power Save capability + UINT8 mesh_SyncCAP; // Synchronization capability + UINT8 mesh_MDA_CAP; // MDA capability + UINT32 mesh_ChannelPrecedence; // Channel Precedence + + // neighbor -> candidate neighbor, if mesh_available_peerlink > 0, page 56, D0.02 + UINT8 mesh_AvailablePeerLink; // ¦¹¬O§_¦³»Ý­n?(¦]¥¦µ¥¦P©ó mesh_PeerCAP)=>¼È ®É«O ¯d + + UINT8 mesh_HeaderFlags; // mesh header ¤ºªº mesh flags field + + // MKD domain element [MKDDIE] + UINT8 mesh_MKD_DomainID[6]; + UINT8 mesh_MKDDIE_SecurityConfiguration; + + // EMSA Handshake element [EMSAIE] + UINT8 mesh_EMSAIE_ANonce[32]; + UINT8 mesh_EMSAIE_SNonce[32]; + UINT8 mesh_EMSAIE_MA_ID[6]; + UINT16 mesh_EMSAIE_MIC_Control; + UINT8 mesh_EMSAIE_MIC[16]; + + struct timer_list mesh_peer_link_timer; ///< ¹ï©|¥¼³s ½u(»P³s½u°h¦Ü¥¼³s½u) MP mesh_unEstablish_hdr §@ peer link time out + +// struct timer_list mesh_beacon_timer; + // mesh_unEstablish_hdr: + // It is a list structure, only stores unEstablish (or Establish -> unEstablish [MP_HOLDING])MP entry + // Each entry is a pointer pointing to an entry in "stat_info->mesh_mp_ptr" + // and removed by successful "Peer link setup" or "Expired" + struct list_head mesh_unEstablish_hdr; + + // mesh_mp_hdr: + // It is a list of MP/MAP/MPP who has already passed "Peer link setup" + // Each entry is a pointer pointing to an entry in "stat_info->mesh_mp_ptr" + // Every entry is inserted by "successful peer link setup" + // and removed by "Expired" + struct list_head mesh_mp_hdr; + + } mesh; + + int iCurChannel; // remember the working channel +}; + +// Stanley, 04/23/07 +// The following mode is used by ieee80211_device->iw_mode +// Although it is better to put the definition under linux/wireless.h (or wireless_copy.h), it is a system file +// that we shouldn't modify directly. +#define IW_MODE_MESH 11 /* 802.11s mesh mode */ + +// Default MESHID +#define IEEE80211S_DEFAULT_MESHID "802.11s" + +// callback for 802.11s +extern short rtl8187_patch_ieee80211_probe_req_1 (struct ieee80211_device *ieee); +extern u8* rtl8187_patch_ieee80211_probe_req_2 (struct ieee80211_device *ieee, struct sk_buff *skb, u8 *tag); + +// wx +extern int rtl8187_patch_r8180_wx_get_meshinfo(struct net_device *dev, struct iw_request_info *info, union iwreq_data *wrqu, char *extra); +extern int rtl8187_patch_r8180_wx_enable_mesh(struct net_device *dev); +extern int rtl8187_patch_r8180_wx_disable_mesh(struct net_device *dev); +extern int rtl8187_patch_r8180_wx_wx_set_meshID(struct net_device *dev, char *ext,unsigned char channel); +extern void rtl8187_patch_r8180_wx_set_channel (struct ieee80211_device *ieee, int ch); +extern int rtl8187_patch_r8180_wx_set_add_mac_allow(struct net_device *dev, struct iw_request_info *info, union iwreq_data *wrqu, char *extra); +extern int rtl8187_patch_r8180_wx_set_del_mac_allow(struct net_device *dev, struct iw_request_info *info, union iwreq_data *wrqu, char *extra); +extern int rtl8187_patch_r8180_wx_set_add_mac_deny(struct net_device *dev, struct iw_request_info *info, union iwreq_data *wrqu, char *extra); +extern int rtl8187_patch_r8180_wx_set_del_mac_deny(struct net_device *dev, struct iw_request_info *info, union iwreq_data *wrqu, char *extra); +extern int rtl8187_patch_r8180_wx_get_mac_allow(struct net_device *dev, struct iw_request_info *info, union iwreq_data *wrqu, char *extra); +extern int rtl8187_patch_r8180_wx_get_mac_deny(struct net_device *dev, struct iw_request_info *info, union iwreq_data *wrqu, char *extra); + +extern int rtl8187_patch_r8180_wx_get_mesh_list(struct net_device *dev, struct iw_request_info *info, union iwreq_data *wrqu, char *extra); +extern int rtl8187_patch_r8180_wx_mesh_scan(struct net_device *dev, struct iw_request_info *info, union iwreq_data *wrqu, char *extra); +extern int rtl8187_patch_r8180_wx_get_selected_mesh(struct net_device *dev, int en, char *cho, char* id); +//by amy for networkmanager UI +extern int rtl8187_patch_r8180_wx_get_selected_mesh_channel(struct net_device *dev, char *extmeshid, char *cho); +//by amy for networkmanager UI +// osdep +extern int rtl8187_patch_ieee80211_start_protocol (struct ieee80211_device *ieee); +extern u8 rtl8187_patch_rtl8180_up(struct mshclass *priv); +extern void rtl8187_patch_ieee80211_stop_protocol(struct ieee80211_device *ieee); + +// issue_assocreq_MP +extern void rtl8187_patch_ieee80211_association_req_1 (struct ieee80211_assoc_request_frame *hdr); +extern u8* rtl8187_patch_ieee80211_association_req_2 (struct ieee80211_device *ieee, struct ieee80211_network *pstat, struct sk_buff *skb); + +// OnAssocReq_MP +extern int rtl8187_patch_ieee80211_rx_frame_softmac_on_assoc_req (struct ieee80211_device *ieee, struct sk_buff *skb); + +// issue_assocrsp_MP +extern void rtl8187_patch_ieee80211_assoc_resp_by_net_1 (struct ieee80211_assoc_response_frame *assoc); +u8* rtl8187_patch_ieee80211_assoc_resp_by_net_2 (struct ieee80211_device *ieee, struct ieee80211_network *pstat, int pkt_type, struct sk_buff *skb); + +// OnAssocRsp_MP +extern int rtl8187_patch_ieee80211_rx_frame_softmac_on_assoc_rsp (struct ieee80211_device *ieee, struct sk_buff *skb); + + +extern int rtl8187_patch_ieee80211_rx_frame_softmac_on_auth(struct ieee80211_device *ieee, struct sk_buff *skb, struct ieee80211_rx_stats *rx_stats); +extern int rtl8187_patch_ieee80211_rx_frame_softmac_on_deauth(struct ieee80211_device *ieee, struct sk_buff *skb, struct ieee80211_rx_stats *rx_stats); +extern unsigned int rtl8187_patch_ieee80211_process_probe_response_1( struct ieee80211_device *ieee, struct ieee80211_probe_response *beacon, struct ieee80211_rx_stats *stats); +extern void rtl8187_patch_ieee80211_rx_mgt_on_probe_req( struct ieee80211_device *ieee, struct ieee80211_probe_request *beacon, struct ieee80211_rx_stats *stats); +extern void rtl8187_patch_ieee80211_rx_mgt_update_expire ( struct ieee80211_device *ieee, struct sk_buff *skb); + +// set channel +extern int rtl8187_patch_ieee80211_ext_stop_scan_wq_set_channel (struct ieee80211_device *ieee); + +// on rx (rx isr) +extern int rtl8187_patch_ieee80211_rx_on_rx (struct ieee80211_device *ieee, struct sk_buff *skb, struct ieee80211_rx_stats *rx_stats, u16 type, u16 stype); + +// r8187_core +// handle ioctl +extern int rtl8187_patch_rtl8180_ioctl(struct net_device *dev, struct ifreq *rq, int cmd); +// create proc +extern void rtl8187_patch_create_proc(struct r8180_priv *priv); +extern void rtl8187_patch_remove_proc(struct r8180_priv *priv); + +// tx, xmit +// locked by ieee->lock. Call ieee80211_softmac_xmit afterward +extern struct ieee80211_txb* rtl8187_patch_ieee80211_xmit (struct sk_buff *skb, struct net_device *dev); + +// given a skb, output header's length +extern int rtl8187_patch_ieee80211_rx_frame_get_hdrlen (struct ieee80211_device *ieee, struct sk_buff *skb); + +// check the frame control field, return 0: not accept, 1: accept +extern int rtl8187_patch_ieee80211_rx_is_valid_framectl (struct ieee80211_device *ieee, u16 fc, u16 type, u16 stype); + +// process_dataframe +extern int rtl8187_patch_ieee80211_rx_process_dataframe (struct ieee80211_device *ieee, struct sk_buff *skb, struct ieee80211_rx_stats *rx_stats); + +extern int rtl8187_patch_is_duplicate_packet (struct ieee80211_device *ieee, struct ieee80211_hdr *header, u16 type, u16 stype); + +extern int rtl8187_patch_ieee80211_softmac_xmit_get_rate (struct ieee80211_device *ieee, struct sk_buff *skb); +extern void ieee80211_start_mesh(struct ieee80211_device *ieee); +#endif // _RTL8187_MESH_H_ diff -Nur linux-2.6.30.5.orig/drivers/net/wireless/rtl8187b/ieee80211/rtl_crypto.h linux-2.6.30.5/drivers/net/wireless/rtl8187b/ieee80211/rtl_crypto.h --- linux-2.6.30.5.orig/drivers/net/wireless/rtl8187b/ieee80211/rtl_crypto.h 1970-01-01 01:00:00.000000000 +0100 +++ linux-2.6.30.5/drivers/net/wireless/rtl8187b/ieee80211/rtl_crypto.h 2009-08-23 19:01:04.000000000 +0200 @@ -0,0 +1,399 @@ +/* + * Scatterlist Cryptographic API. + * + * Copyright (c) 2002 James Morris + * Copyright (c) 2002 David S. Miller (davem@redhat.com) + * + * Portions derived from Cryptoapi, by Alexander Kjeldaas + * and Nettle, by Niels Mé°ˆler. + * + * 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. + * + */ +#ifndef _LINUX_CRYPTO_H +#define _LINUX_CRYPTO_H + +#include +#include +#include +#include +#include +#include +#include + +#define crypto_register_alg crypto_register_alg_rtl +#define crypto_unregister_alg crypto_unregister_alg_rtl +#define crypto_alloc_tfm crypto_alloc_tfm_rtl +#define crypto_free_tfm crypto_free_tfm_rtl +#define crypto_alg_available crypto_alg_available_rtl + +/* + * Algorithm masks and types. + */ +#define CRYPTO_ALG_TYPE_MASK 0x000000ff +#define CRYPTO_ALG_TYPE_CIPHER 0x00000001 +#define CRYPTO_ALG_TYPE_DIGEST 0x00000002 +#define CRYPTO_ALG_TYPE_COMPRESS 0x00000004 + +/* + * Transform masks and values (for crt_flags). + */ +#define CRYPTO_TFM_MODE_MASK 0x000000ff +#define CRYPTO_TFM_REQ_MASK 0x000fff00 +#define CRYPTO_TFM_RES_MASK 0xfff00000 + +#define CRYPTO_TFM_MODE_ECB 0x00000001 +#define CRYPTO_TFM_MODE_CBC 0x00000002 +#define CRYPTO_TFM_MODE_CFB 0x00000004 +#define CRYPTO_TFM_MODE_CTR 0x00000008 + +#define CRYPTO_TFM_REQ_WEAK_KEY 0x00000100 +#define CRYPTO_TFM_RES_WEAK_KEY 0x00100000 +#define CRYPTO_TFM_RES_BAD_KEY_LEN 0x00200000 +#define CRYPTO_TFM_RES_BAD_KEY_SCHED 0x00400000 +#define CRYPTO_TFM_RES_BAD_BLOCK_LEN 0x00800000 +#define CRYPTO_TFM_RES_BAD_FLAGS 0x01000000 + +/* + * Miscellaneous stuff. + */ +#define CRYPTO_UNSPEC 0 +#define CRYPTO_MAX_ALG_NAME 64 + +struct scatterlist; + +/* + * Algorithms: modular crypto algorithm implementations, managed + * via crypto_register_alg() and crypto_unregister_alg(). + */ +struct cipher_alg { + unsigned int cia_min_keysize; + unsigned int cia_max_keysize; + int (*cia_setkey)(void *ctx, const u8 *key, + unsigned int keylen, u32 *flags); + void (*cia_encrypt)(void *ctx, u8 *dst, const u8 *src); + void (*cia_decrypt)(void *ctx, u8 *dst, const u8 *src); +}; + +struct digest_alg { + unsigned int dia_digestsize; + void (*dia_init)(void *ctx); + void (*dia_update)(void *ctx, const u8 *data, unsigned int len); + void (*dia_final)(void *ctx, u8 *out); + int (*dia_setkey)(void *ctx, const u8 *key, + unsigned int keylen, u32 *flags); +}; + +struct compress_alg { + int (*coa_init)(void *ctx); + void (*coa_exit)(void *ctx); + int (*coa_compress)(void *ctx, const u8 *src, unsigned int slen, + u8 *dst, unsigned int *dlen); + int (*coa_decompress)(void *ctx, const u8 *src, unsigned int slen, + u8 *dst, unsigned int *dlen); +}; + +#define cra_cipher cra_u.cipher +#define cra_digest cra_u.digest +#define cra_compress cra_u.compress + +struct crypto_alg { + struct list_head cra_list; + u32 cra_flags; + unsigned int cra_blocksize; + unsigned int cra_ctxsize; + const char cra_name[CRYPTO_MAX_ALG_NAME]; + + union { + struct cipher_alg cipher; + struct digest_alg digest; + struct compress_alg compress; + } cra_u; + + struct module *cra_module; +}; + +/* + * Algorithm registration interface. + */ +int crypto_register_alg(struct crypto_alg *alg); +int crypto_unregister_alg(struct crypto_alg *alg); + +/* + * Algorithm query interface. + */ +int crypto_alg_available(const char *name, u32 flags); + +/* + * Transforms: user-instantiated objects which encapsulate algorithms + * and core processing logic. Managed via crypto_alloc_tfm() and + * crypto_free_tfm(), as well as the various helpers below. + */ +struct crypto_tfm; + +struct cipher_tfm { + void *cit_iv; + unsigned int cit_ivsize; + u32 cit_mode; + int (*cit_setkey)(struct crypto_tfm *tfm, + const u8 *key, unsigned int keylen); + int (*cit_encrypt)(struct crypto_tfm *tfm, + struct scatterlist *dst, + struct scatterlist *src, + unsigned int nbytes); + int (*cit_encrypt_iv)(struct crypto_tfm *tfm, + struct scatterlist *dst, + struct scatterlist *src, + unsigned int nbytes, u8 *iv); + int (*cit_decrypt)(struct crypto_tfm *tfm, + struct scatterlist *dst, + struct scatterlist *src, + unsigned int nbytes); + int (*cit_decrypt_iv)(struct crypto_tfm *tfm, + struct scatterlist *dst, + struct scatterlist *src, + unsigned int nbytes, u8 *iv); + void (*cit_xor_block)(u8 *dst, const u8 *src); +}; + +struct digest_tfm { + void (*dit_init)(struct crypto_tfm *tfm); + void (*dit_update)(struct crypto_tfm *tfm, + struct scatterlist *sg, unsigned int nsg); + void (*dit_final)(struct crypto_tfm *tfm, u8 *out); + void (*dit_digest)(struct crypto_tfm *tfm, struct scatterlist *sg, + unsigned int nsg, u8 *out); + int (*dit_setkey)(struct crypto_tfm *tfm, + const u8 *key, unsigned int keylen); +#ifdef CONFIG_CRYPTO_HMAC + void *dit_hmac_block; +#endif +}; + +struct compress_tfm { + int (*cot_compress)(struct crypto_tfm *tfm, + const u8 *src, unsigned int slen, + u8 *dst, unsigned int *dlen); + int (*cot_decompress)(struct crypto_tfm *tfm, + const u8 *src, unsigned int slen, + u8 *dst, unsigned int *dlen); +}; + +#define crt_cipher crt_u.cipher +#define crt_digest crt_u.digest +#define crt_compress crt_u.compress + +struct crypto_tfm { + + u32 crt_flags; + + union { + struct cipher_tfm cipher; + struct digest_tfm digest; + struct compress_tfm compress; + } crt_u; + + struct crypto_alg *__crt_alg; +}; + +/* + * Transform user interface. + */ + +/* + * crypto_alloc_tfm() will first attempt to locate an already loaded algorithm. + * If that fails and the kernel supports dynamically loadable modules, it + * will then attempt to load a module of the same name or alias. A refcount + * is grabbed on the algorithm which is then associated with the new transform. + * + * crypto_free_tfm() frees up the transform and any associated resources, + * then drops the refcount on the associated algorithm. + */ +struct crypto_tfm *crypto_alloc_tfm(const char *alg_name, u32 tfm_flags); +void crypto_free_tfm(struct crypto_tfm *tfm); + +/* + * Transform helpers which query the underlying algorithm. + */ +static inline const char *crypto_tfm_alg_name(struct crypto_tfm *tfm) +{ + return tfm->__crt_alg->cra_name; +} + +static inline const char *crypto_tfm_alg_modname(struct crypto_tfm *tfm) +{ + struct crypto_alg *alg = tfm->__crt_alg; + + if (alg->cra_module) + return alg->cra_module->name; + else + return NULL; +} + +static inline u32 crypto_tfm_alg_type(struct crypto_tfm *tfm) +{ + return tfm->__crt_alg->cra_flags & CRYPTO_ALG_TYPE_MASK; +} + +static inline unsigned int crypto_tfm_alg_min_keysize(struct crypto_tfm *tfm) +{ + BUG_ON(crypto_tfm_alg_type(tfm) != CRYPTO_ALG_TYPE_CIPHER); + return tfm->__crt_alg->cra_cipher.cia_min_keysize; +} + +static inline unsigned int crypto_tfm_alg_max_keysize(struct crypto_tfm *tfm) +{ + BUG_ON(crypto_tfm_alg_type(tfm) != CRYPTO_ALG_TYPE_CIPHER); + return tfm->__crt_alg->cra_cipher.cia_max_keysize; +} + +static inline unsigned int crypto_tfm_alg_ivsize(struct crypto_tfm *tfm) +{ + BUG_ON(crypto_tfm_alg_type(tfm) != CRYPTO_ALG_TYPE_CIPHER); + return tfm->crt_cipher.cit_ivsize; +} + +static inline unsigned int crypto_tfm_alg_blocksize(struct crypto_tfm *tfm) +{ + return tfm->__crt_alg->cra_blocksize; +} + +static inline unsigned int crypto_tfm_alg_digestsize(struct crypto_tfm *tfm) +{ + BUG_ON(crypto_tfm_alg_type(tfm) != CRYPTO_ALG_TYPE_DIGEST); + return tfm->__crt_alg->cra_digest.dia_digestsize; +} + +/* + * API wrappers. + */ +static inline void crypto_digest_init(struct crypto_tfm *tfm) +{ + BUG_ON(crypto_tfm_alg_type(tfm) != CRYPTO_ALG_TYPE_DIGEST); + tfm->crt_digest.dit_init(tfm); +} + +static inline void crypto_digest_update(struct crypto_tfm *tfm, + struct scatterlist *sg, + unsigned int nsg) +{ + BUG_ON(crypto_tfm_alg_type(tfm) != CRYPTO_ALG_TYPE_DIGEST); + tfm->crt_digest.dit_update(tfm, sg, nsg); +} + +static inline void crypto_digest_final(struct crypto_tfm *tfm, u8 *out) +{ + BUG_ON(crypto_tfm_alg_type(tfm) != CRYPTO_ALG_TYPE_DIGEST); + tfm->crt_digest.dit_final(tfm, out); +} + +static inline void crypto_digest_digest(struct crypto_tfm *tfm, + struct scatterlist *sg, + unsigned int nsg, u8 *out) +{ + BUG_ON(crypto_tfm_alg_type(tfm) != CRYPTO_ALG_TYPE_DIGEST); + tfm->crt_digest.dit_digest(tfm, sg, nsg, out); +} + +static inline int crypto_digest_setkey(struct crypto_tfm *tfm, + const u8 *key, unsigned int keylen) +{ + BUG_ON(crypto_tfm_alg_type(tfm) != CRYPTO_ALG_TYPE_DIGEST); + if (tfm->crt_digest.dit_setkey == NULL) + return -ENOSYS; + return tfm->crt_digest.dit_setkey(tfm, key, keylen); +} + +static inline int crypto_cipher_setkey(struct crypto_tfm *tfm, + const u8 *key, unsigned int keylen) +{ + BUG_ON(crypto_tfm_alg_type(tfm) != CRYPTO_ALG_TYPE_CIPHER); + return tfm->crt_cipher.cit_setkey(tfm, key, keylen); +} + +static inline int crypto_cipher_encrypt(struct crypto_tfm *tfm, + struct scatterlist *dst, + struct scatterlist *src, + unsigned int nbytes) +{ + BUG_ON(crypto_tfm_alg_type(tfm) != CRYPTO_ALG_TYPE_CIPHER); + return tfm->crt_cipher.cit_encrypt(tfm, dst, src, nbytes); +} + +static inline int crypto_cipher_encrypt_iv(struct crypto_tfm *tfm, + struct scatterlist *dst, + struct scatterlist *src, + unsigned int nbytes, u8 *iv) +{ + BUG_ON(crypto_tfm_alg_type(tfm) != CRYPTO_ALG_TYPE_CIPHER); + BUG_ON(tfm->crt_cipher.cit_mode == CRYPTO_TFM_MODE_ECB); + return tfm->crt_cipher.cit_encrypt_iv(tfm, dst, src, nbytes, iv); +} + +static inline int crypto_cipher_decrypt(struct crypto_tfm *tfm, + struct scatterlist *dst, + struct scatterlist *src, + unsigned int nbytes) +{ + BUG_ON(crypto_tfm_alg_type(tfm) != CRYPTO_ALG_TYPE_CIPHER); + return tfm->crt_cipher.cit_decrypt(tfm, dst, src, nbytes); +} + +static inline int crypto_cipher_decrypt_iv(struct crypto_tfm *tfm, + struct scatterlist *dst, + struct scatterlist *src, + unsigned int nbytes, u8 *iv) +{ + BUG_ON(crypto_tfm_alg_type(tfm) != CRYPTO_ALG_TYPE_CIPHER); + BUG_ON(tfm->crt_cipher.cit_mode == CRYPTO_TFM_MODE_ECB); + return tfm->crt_cipher.cit_decrypt_iv(tfm, dst, src, nbytes, iv); +} + +static inline void crypto_cipher_set_iv(struct crypto_tfm *tfm, + const u8 *src, unsigned int len) +{ + BUG_ON(crypto_tfm_alg_type(tfm) != CRYPTO_ALG_TYPE_CIPHER); + memcpy(tfm->crt_cipher.cit_iv, src, len); +} + +static inline void crypto_cipher_get_iv(struct crypto_tfm *tfm, + u8 *dst, unsigned int len) +{ + BUG_ON(crypto_tfm_alg_type(tfm) != CRYPTO_ALG_TYPE_CIPHER); + memcpy(dst, tfm->crt_cipher.cit_iv, len); +} + +static inline int crypto_comp_compress(struct crypto_tfm *tfm, + const u8 *src, unsigned int slen, + u8 *dst, unsigned int *dlen) +{ + BUG_ON(crypto_tfm_alg_type(tfm) != CRYPTO_ALG_TYPE_COMPRESS); + return tfm->crt_compress.cot_compress(tfm, src, slen, dst, dlen); +} + +static inline int crypto_comp_decompress(struct crypto_tfm *tfm, + const u8 *src, unsigned int slen, + u8 *dst, unsigned int *dlen) +{ + BUG_ON(crypto_tfm_alg_type(tfm) != CRYPTO_ALG_TYPE_COMPRESS); + return tfm->crt_compress.cot_decompress(tfm, src, slen, dst, dlen); +} + +/* + * HMAC support. + */ +#ifdef CONFIG_CRYPTO_HMAC +void crypto_hmac_init(struct crypto_tfm *tfm, u8 *key, unsigned int *keylen); +void crypto_hmac_update(struct crypto_tfm *tfm, + struct scatterlist *sg, unsigned int nsg); +void crypto_hmac_final(struct crypto_tfm *tfm, u8 *key, + unsigned int *keylen, u8 *out); +void crypto_hmac(struct crypto_tfm *tfm, u8 *key, unsigned int *keylen, + struct scatterlist *sg, unsigned int nsg, u8 *out); +#endif /* CONFIG_CRYPTO_HMAC */ + +#endif /* _LINUX_CRYPTO_H */ + diff -Nur linux-2.6.30.5.orig/drivers/net/wireless/rtl8187b/ieee80211/scatterwalk.h linux-2.6.30.5/drivers/net/wireless/rtl8187b/ieee80211/scatterwalk.h --- linux-2.6.30.5.orig/drivers/net/wireless/rtl8187b/ieee80211/scatterwalk.h 1970-01-01 01:00:00.000000000 +0100 +++ linux-2.6.30.5/drivers/net/wireless/rtl8187b/ieee80211/scatterwalk.h 2009-08-23 19:01:04.000000000 +0200 @@ -0,0 +1,51 @@ +/* + * Cryptographic API. + * + * Copyright (c) 2002 James Morris + * Copyright (c) 2002 Adam J. Richter + * Copyright (c) 2004 Jean-Luc Cooke + * + * 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. + * + */ + +#ifndef _CRYPTO_SCATTERWALK_H +#define _CRYPTO_SCATTERWALK_H +#include +#include + +struct scatter_walk { + struct scatterlist *sg; + struct page *page; + void *data; + unsigned int len_this_page; + unsigned int len_this_segment; + unsigned int offset; +}; + +/* Define sg_next is an inline routine now in case we want to change + scatterlist to a linked list later. */ +static inline struct scatterlist *sg_next(struct scatterlist *sg) +{ + return sg + 1; +} + +static inline int scatterwalk_samebuf(struct scatter_walk *walk_in, + struct scatter_walk *walk_out, + void *src_p, void *dst_p) +{ + return walk_in->page == walk_out->page && + walk_in->offset == walk_out->offset && + walk_in->data == src_p && walk_out->data == dst_p; +} + +void *scatterwalk_whichbuf(struct scatter_walk *walk, unsigned int nbytes, void *scratch); +void scatterwalk_start(struct scatter_walk *walk, struct scatterlist *sg); +int scatterwalk_copychunks(void *buf, struct scatter_walk *walk, size_t nbytes, int out); +void scatterwalk_map(struct scatter_walk *walk, int out); +void scatterwalk_done(struct scatter_walk *walk, int out, int more); + +#endif /* _CRYPTO_SCATTERWALK_H */ diff -Nur linux-2.6.30.5.orig/drivers/net/wireless/rtl8187b/Makefile linux-2.6.30.5/drivers/net/wireless/rtl8187b/Makefile --- linux-2.6.30.5.orig/drivers/net/wireless/rtl8187b/Makefile 1970-01-01 01:00:00.000000000 +0100 +++ linux-2.6.30.5/drivers/net/wireless/rtl8187b/Makefile 2009-08-23 19:01:04.000000000 +0200 @@ -0,0 +1,41 @@ +obj-$(CONFIG_RTL8187B) += rtl8187b.o + +rtl8187b-objs := r8187_core.o \ + r8180_93cx6.o \ + r8180_wx.o \ + r8180_rtl8225.o \ + r8180_rtl8225z2.o \ + r8180_pm.o \ + r8180_dm.o \ + r8187_led.o \ + ieee80211/dot11d.o \ + ieee80211/ieee80211_softmac.o \ + ieee80211/ieee80211_rx.o \ + ieee80211/ieee80211_tx.o \ + ieee80211/ieee80211_wx.o \ + ieee80211/ieee80211_module.o \ + ieee80211/ieee80211_softmac_wx.o \ + ieee80211/ieee80211_crypt.o \ + ieee80211/ieee80211_crypt_tkip.o \ + ieee80211/ieee80211_crypt_ccmp.o \ + ieee80211/ieee80211_crypt_wep.o + +EXTRA_CFLAGS += -DCONFIG_RTL8180_PM +EXTRA_CFLAGS += -DJACKSON_NEW_8187 -DJACKSON_NEW_RX +EXTRA_CFLAGS += -DTHOMAS_BEACON -DTHOMAS_TASKLET -DTHOMAS_SKB -DTHOMAS_TURBO +EXTRA_CFLAGS += -DJOHN_IOCTL +EXTRA_CFLAGS += -DLED +#EXTRA_CFLAGS += -DLED_SHIN +EXTRA_CFLAGS += -DPOLLING_METHOD_FOR_RADIO +#EXTRA_CFLAGS += -DSW_ANTE_DIVERSITY +EXTRA_CFLAGS += -DCPU_64BIT +EXTRA_CFLAGS += -DCONFIG_IPS +#CFLAGS += -DJOHN_HWSEC -DJOHN_TKIP +#CFLAGS += -DJOHN_DUMP_TX +#EXTRA_CFLAGS += -DJOHN_DUMP_TXPKT + +#Radio On/Off debug +EXTRA_CFLAGS += -DCONFIG_RADIO_DEBUG + +#for dot11d +EXTRA_CFLAGS += -DENABLE_DOT11D diff -Nur linux-2.6.30.5.orig/drivers/net/wireless/rtl8187b/msh_class.h linux-2.6.30.5/drivers/net/wireless/rtl8187b/msh_class.h --- linux-2.6.30.5.orig/drivers/net/wireless/rtl8187b/msh_class.h 1970-01-01 01:00:00.000000000 +0100 +++ linux-2.6.30.5/drivers/net/wireless/rtl8187b/msh_class.h 2009-08-23 19:01:04.000000000 +0200 @@ -0,0 +1,117 @@ +/*! \file msh_class.h + \brief msh CLASS extension + + \date 2007/5/2 + \author Stanley Chang +*/ + +#ifndef _MESH_CLASS_HDR_H_ +#define _MESH_CLASS_HDR_H_ + +#include /* ETH_ALEN */ +#include /* ARRAY_SIZE */ +#include +#include +#include +#include + +#include "ieee80211/ieee80211.h" // for struct ieee80211-xxxx +#include "r8187.h" // for struct r8180-priv + +#define MAC_TABLE_SIZE 8 + +struct mshclass { + struct r8180_priv * p8187; + + // callback functions + // ieee80211_softmac.c + int (*ext_patch_ieee80211_start_protocol) (struct ieee80211_device *ieee); // start special mode + + short (*ext_patch_ieee80211_probe_req_1) (struct ieee80211_device *ieee); // return = 0: no more phases, >0: another phase + u8* (*ext_patch_ieee80211_probe_req_2) (struct ieee80211_device *ieee, struct sk_buff *skb, u8 *tag); // return tag + + void (*ext_patch_ieee80211_association_req_1) (struct ieee80211_assoc_request_frame *hdr); + u8* (*ext_patch_ieee80211_association_req_2) (struct ieee80211_device *ieee, struct ieee80211_network *pstat, struct sk_buff *skb); + + int (*ext_patch_ieee80211_rx_frame_softmac_on_assoc_req) (struct ieee80211_device *ieee, struct sk_buff *skb); + int (*ext_patch_ieee80211_rx_frame_softmac_on_assoc_rsp) (struct ieee80211_device *ieee, struct sk_buff *skb); + + void (*ext_patch_ieee80211_stop_protocol) (struct ieee80211_device *ieee); // stop timer + + void (*ext_patch_ieee80211_assoc_resp_by_net_1) (struct ieee80211_assoc_response_frame *assoc); + u8* (*ext_patch_ieee80211_assoc_resp_by_net_2) (struct ieee80211_device *ieee, struct ieee80211_network *pstat, int pkt_type, struct sk_buff *skb); + + int (*ext_patch_ieee80211_ext_stop_scan_wq_set_channel) (struct ieee80211_device *ieee); + + struct sk_buff* (*ext_patch_get_beacon_get_probersp)(struct ieee80211_device *ieee, u8 *dest, struct ieee80211_network *net); + + int (*ext_patch_ieee80211_softmac_xmit_get_rate) (struct ieee80211_device *ieee, struct sk_buff *skb); + int (*ext_patch_ieee80211_rx_frame_softmac_on_auth)(struct ieee80211_device *ieee, struct sk_buff *skb, struct ieee80211_rx_stats *rx_stats); + int (*ext_patch_ieee80211_rx_frame_softmac_on_deauth)(struct ieee80211_device *ieee, struct sk_buff *skb, struct ieee80211_rx_stats *rx_stats); +//by amy for mesh + void (*ext_patch_ieee80211_start_mesh)(struct ieee80211_device *ieee); +//by amy for mesh + /// r8180_wx.c + int (*ext_patch_r8180_wx_get_meshinfo) (struct net_device *dev, struct iw_request_info *info, union iwreq_data *wrqu, char *extra); + int (*ext_patch_r8180_wx_enable_mesh) (struct net_device *dev); + int (*ext_patch_r8180_wx_disable_mesh) (struct net_device *dev); + int (*ext_patch_r8180_wx_set_meshID) ( struct net_device *dev, char *ext); +//by amy for mesh + int (*ext_patch_r8180_wx_set_mesh_chan)(struct net_device *dev, unsigned char channel); +//by amy for mesh + void (*ext_patch_r8180_wx_set_channel) (struct ieee80211_device *ieee, int ch); + + int (*ext_patch_r8180_wx_set_add_mac_allow) (struct net_device *dev, struct iw_request_info *info, union iwreq_data *wrqu, char *extra); + int (*ext_patch_r8180_wx_set_del_mac_allow) (struct net_device *dev, struct iw_request_info *info, union iwreq_data *wrqu, char *extra); + int (*ext_patch_r8180_wx_set_add_mac_deny) (struct net_device *dev, struct iw_request_info *info, union iwreq_data *wrqu, char *extra); + int (*ext_patch_r8180_wx_set_del_mac_deny) (struct net_device *dev, struct iw_request_info *info, union iwreq_data *wrqu, char *extra); + int (*ext_patch_r8180_wx_get_mac_allow) (struct net_device *dev, struct iw_request_info *info, union iwreq_data *wrqu, char *extra); + int (*ext_patch_r8180_wx_get_mac_deny) (struct net_device *dev, struct iw_request_info *info, union iwreq_data *wrqu, char *extra); + + int (*ext_patch_r8180_wx_get_mesh_list) (struct net_device *dev, struct iw_request_info *info, union iwreq_data *wrqu, char *extra); + int (*ext_patch_r8180_wx_mesh_scan) (struct net_device *dev, struct iw_request_info *info, union iwreq_data *wrqu, char *extra); + int (*ext_patch_r8180_wx_get_selected_mesh)(struct net_device *dev, int en, char *cho, char* id); +//by amy for networkmanager UI + int (*ext_patch_r8180_wx_get_selected_mesh_channel)(struct net_device *dev, char* extmeshid, char *cho); +//by amy for networkmanager UI + /// r8187_core.c + u8 (*ext_patch_rtl8180_up) (struct mshclass *priv); + + // ieee80211_rx.c + unsigned int (*ext_patch_ieee80211_process_probe_response_1) ( struct ieee80211_device *ieee, struct ieee80211_probe_response *beacon, struct ieee80211_rx_stats *stats); + void (*ext_patch_ieee80211_rx_mgt_on_probe_req) ( struct ieee80211_device *ieee, struct ieee80211_probe_request *beacon, struct ieee80211_rx_stats *stats); + + void (*ext_patch_ieee80211_rx_mgt_update_expire) ( struct ieee80211_device *ieee, struct sk_buff *skb); + + int (*ext_patch_ieee80211_rx_on_rx) (struct ieee80211_device *ieee, struct sk_buff *skb, struct ieee80211_rx_stats *rx_stats, u16 type, u16 stype); + + int (*ext_patch_ieee80211_rx_frame_get_hdrlen) (struct ieee80211_device *ieee, struct sk_buff *skb); + + int (*ext_patch_ieee80211_rx_is_valid_framectl) (struct ieee80211_device *ieee, u16 fc, u16 type, u16 stype); + + // return > 0 is success. 0 when failed + int (*ext_patch_ieee80211_rx_process_dataframe) (struct ieee80211_device *ieee, struct sk_buff *skb, struct ieee80211_rx_stats *rx_stats); + + int (*ext_patch_is_duplicate_packet) (struct ieee80211_device *ieee, struct ieee80211_hdr *header, u16 type, u16 stype); + /* added by david for setting acl dynamically */ + u8 (*ext_patch_ieee80211_acl_query) (struct ieee80211_device *ieee, u8 *sa); + + // r8187_core.c + int (*ext_patch_rtl8180_ioctl) (struct net_device *dev, struct ifreq *rq, int cmd); + void (*ext_patch_create_proc) (struct r8180_priv *priv); + void (*ext_patch_remove_proc) (struct r8180_priv *priv); + + // ieee80211_tx.c + + // locked by ieee->lock. Call ieee80211_softmac_xmit afterward + struct ieee80211_txb* (*ext_patch_ieee80211_xmit) (struct sk_buff *skb, struct net_device *dev); + + // DO NOT MODIFY ANY STRUCTURE BELOW THIS LINE + u8 priv[0]; // mshclass_priv; +}; + +extern void free_mshobj(struct mshclass **pObj); +extern struct mshclass *alloc_mshobj(struct r8180_priv *caller_priv); + + +#endif // _MESH_CLASS_HDR_H_ diff -Nur linux-2.6.30.5.orig/drivers/net/wireless/rtl8187b/r8180_93cx6.c linux-2.6.30.5/drivers/net/wireless/rtl8187b/r8180_93cx6.c --- linux-2.6.30.5.orig/drivers/net/wireless/rtl8187b/r8180_93cx6.c 1970-01-01 01:00:00.000000000 +0100 +++ linux-2.6.30.5/drivers/net/wireless/rtl8187b/r8180_93cx6.c 2009-08-23 19:01:04.000000000 +0200 @@ -0,0 +1,146 @@ +/* + This files contains card eeprom (93c46 or 93c56) programming routines, + memory is addressed by 16 bits words. + + This is part of rtl8180 OpenSource driver. + Copyright (C) Andrea Merello 2004 + Released under the terms of GPL (General Public Licence) + + Parts of this driver are based on the GPL part of the + official realtek driver. + + Parts of this driver are based on the rtl8180 driver skeleton + from Patric Schenke & Andres Salomon. + + Parts of this driver are based on the Intel Pro Wireless 2100 GPL driver. + + We want to tanks the Authors of those projects and the Ndiswrapper + project Authors. +*/ + +#include "r8180_93cx6.h" + +void eprom_cs(struct net_device *dev, short bit) +{ + if(bit) + write_nic_byte(dev, EPROM_CMD, + (1<epromtype==EPROM_93c56){ + addr_str[7]=addr & 1; + addr_str[6]=addr & (1<<1); + addr_str[5]=addr & (1<<2); + addr_str[4]=addr & (1<<3); + addr_str[3]=addr & (1<<4); + addr_str[2]=addr & (1<<5); + addr_str[1]=addr & (1<<6); + addr_str[0]=addr & (1<<7); + addr_len=8; + }else{ + addr_str[5]=addr & 1; + addr_str[4]=addr & (1<<1); + addr_str[3]=addr & (1<<2); + addr_str[2]=addr & (1<<3); + addr_str[1]=addr & (1<<4); + addr_str[0]=addr & (1<<5); + addr_len=6; + } + eprom_cs(dev, 1); + eprom_ck_cycle(dev); + eprom_send_bits_string(dev, read_cmd, 3); + eprom_send_bits_string(dev, addr_str, addr_len); + + //keep chip pin D to low state while reading. + //I'm unsure if it is necessary, but anyway shouldn't hurt + eprom_w(dev, 0); + + for(i=0;i<16;i++){ + //eeprom needs a clk cycle between writing opcode&adr + //and reading data. (eeprom outs a dummy 0) + eprom_ck_cycle(dev); + ret |= (eprom_r(dev)<<(15-i)); + } + + eprom_cs(dev, 0); + eprom_ck_cycle(dev); + + //disable EPROM programming + write_nic_byte(dev, EPROM_CMD, + (EPROM_CMD_NORMAL< + Released under the terms of GPL (General Public Licence) + + Parts of this driver are based on the GPL part of the official realtek driver + Parts of this driver are based on the rtl8180 driver skeleton from Patric Schenke & Andres Salomon + Parts of this driver are based on the Intel Pro Wireless 2100 GPL driver + + We want to tanks the Authors of such projects and the Ndiswrapper project Authors. +*/ + +/*This files contains card eeprom (93c46 or 93c56) programming routines*/ +/*memory is addressed by WORDS*/ + +#include "r8187.h" +#include "r8180_hw.h" + +#define EPROM_DELAY 10 + +#define EPROM_ANAPARAM_ADDRLWORD 0xd +#define EPROM_ANAPARAM_ADDRHWORD 0xe + +#define EPROM_CHANNEL_PLAN 0x3 //0x6>>1 +//0x77 BIT[0]0:use gpio 1 bit 1, 1:use gpio 1 bit 2. +#define EPROM_SELECT_GPIO (0x77 >> 1) +//#define EEPROM_COUNTRY_CODE 0x2E//87se channel plan is here + +#define EPROM_RFCHIPID 0x6 +#define EPROM_TXPW_BASE 0x05 +#define EPROM_RFCHIPID_RTL8225U 5 +#define EPROM_RFCHIPID_RTL8225U_VF 6 +#define EPROM_RF_PARAM 0x4 +#define EPROM_CONFIG2 0xc + +#define EPROM_VERSION 0x1E +#define MAC_ADR 0x7 + +#define CIS 0x18 + +#define EPROM_TXPW0 0x16 +#define EPROM_TXPW2 0x1b +#define EPROM_TXPW1 0x3d + + +u32 eprom_read(struct net_device *dev,u32 addr); //reads a 16 bits word diff -Nur linux-2.6.30.5.orig/drivers/net/wireless/rtl8187b/r8180_dm.c linux-2.6.30.5/drivers/net/wireless/rtl8187b/r8180_dm.c --- linux-2.6.30.5.orig/drivers/net/wireless/rtl8187b/r8180_dm.c 1970-01-01 01:00:00.000000000 +0100 +++ linux-2.6.30.5/drivers/net/wireless/rtl8187b/r8180_dm.c 2009-08-23 19:01:04.000000000 +0200 @@ -0,0 +1,882 @@ +/*++ +Copyright (c) Realtek Semiconductor Corp. All rights reserved. + +Module Name: + r8180_dig.c + +Abstract: + Hardware dynamic mechanism for RTL8187B + +Major Change History: + When Who What + ---------- --------------- ------------------------------- + 2006-11-15 david Created + +Notes: + This file is ported from RTL8187B Windows driver. + + +--*/ +#include "r8180_dm.h" +#include "r8180_hw.h" +#include "r8180_rtl8225.h" + +//================================================================================ +// Local Constant. +//================================================================================ +#define Z1_HIPWR_UPPER_TH 99 +#define Z1_HIPWR_LOWER_TH 70 +#define Z2_HIPWR_UPPER_TH 99 +#define Z2_HIPWR_LOWER_TH 90 + +bool CheckDig(struct net_device *dev) +{ + struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev); + struct ieee80211_device *ieee = priv->ieee80211; + + if(ieee->state != IEEE80211_LINKED) + return false; + + if(priv->card_8187 == NIC_8187B) { + // + // We need to schedule dig workitem on either of the below mechanisms. + // By Bruce, 2007-06-01. + // + if(!priv->bDigMechanism && !priv->bCCKThMechanism) + return false; + + if(priv->CurrentOperaRate < 36) // Schedule Dig under all OFDM rates. By Bruce, 2007-06-01. + return false; + } else { + if(!priv->bDigMechanism) + return false; + + if(priv->CurrentOperaRate < 48) + return false; + } + return true; +} + + +// +// Description: +// Implementation of DIG for Zebra and Zebra2. +// +void DIG_Zebra(struct net_device *dev) +{ + struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev); + //PHAL_DATA_8187 pHalData = GetHalData8187(Adapter); + u16 CCKFalseAlarm, OFDMFalseAlarm; + u16 OfdmFA1, OfdmFA2; + int InitialGainStep = 7; // The number of initial gain stages. + int LowestGainStage = 4; // The capable lowest stage of performing dig workitem. + +// printk("---------> DIG_Zebra()\n"); + + //Read only 1 byte because of HW bug. This is a temporal modification. Joseph + // Modify by Isaiah 2006-06-27 + if(priv->card_8187_Bversion == VERSION_8187B_B) + { + CCKFalseAlarm = 0; + OFDMFalseAlarm = (u16)(priv->FalseAlarmRegValue); + OfdmFA1 = 0x01; + OfdmFA2 = priv->RegDigOfdmFaUpTh; + } + else + { + CCKFalseAlarm = (u16)(priv->FalseAlarmRegValue & 0x0000ffff); + OFDMFalseAlarm = (u16)((priv->FalseAlarmRegValue >> 16) & 0x0000ffff); + OfdmFA1 = 0x15; + //OfdmFA2 = 0xC00; + OfdmFA2 = ((u16)(priv->RegDigOfdmFaUpTh)) << 8; + } + +// printk("DIG**********CCK False Alarm: %#X \n",CCKFalseAlarm); +// printk("DIG**********OFDM False Alarm: %#X \n",OFDMFalseAlarm); + + + + // The number of initial gain steps is different, by Bruce, 2007-04-13. + if(priv->card_8187 == NIC_8187) { + if (priv->InitialGain == 0 ) //autoDIG + { + switch( priv->rf_chip) + { + case RF_ZEBRA: + priv->InitialGain = 5; // m74dBm; + break; + case RF_ZEBRA2: + priv->InitialGain = 4; // m78dBm; + break; + default: + priv->InitialGain = 5; // m74dBm; + break; + } + } + InitialGainStep = 7; + if(priv->InitialGain > 7) + priv->InitialGain = 5; + LowestGainStage = 4; + } else { + if (priv->InitialGain == 0 ) //autoDIG + { // Advised from SD3 DZ, by Bruce, 2007-06-05. + priv->InitialGain = 4; // In 87B, m74dBm means State 4 (m82dBm) + } + if(priv->card_8187_Bversion != VERSION_8187B_B) + { // Advised from SD3 DZ, by Bruce, 2007-06-05. + OfdmFA1 = 0x20; + } + InitialGainStep = 8; + LowestGainStage = priv->RegBModeGainStage; // Lowest gain stage. + } + + if (OFDMFalseAlarm > OfdmFA1) + { + if (OFDMFalseAlarm > OfdmFA2) + { + priv->DIG_NumberFallbackVote++; + if (priv->DIG_NumberFallbackVote >1) + { + //serious OFDM False Alarm, need fallback + // By Bruce, 2007-03-29. + // if (pHalData->InitialGain < 7) // In 87B, m66dBm means State 7 (m74dBm) + if (priv->InitialGain < InitialGainStep) + { + priv->InitialGain = (priv->InitialGain + 1); + //printk("DIG**********OFDM False Alarm: %#X, OfdmFA1: %#X, OfdmFA2: %#X\n", OFDMFalseAlarm, OfdmFA1, OfdmFA2); + //printk("DIG+++++++ fallback OFDM:%d \n", priv->InitialGain); + UpdateInitialGain(dev); // 2005.01.06, by rcnjko. + } + priv->DIG_NumberFallbackVote = 0; + priv->DIG_NumberUpgradeVote=0; + } + } + else + { + if (priv->DIG_NumberFallbackVote) + priv->DIG_NumberFallbackVote--; + } + priv->DIG_NumberUpgradeVote=0; + } + else //OFDM False Alarm < 0x15 + { + if (priv->DIG_NumberFallbackVote) + priv->DIG_NumberFallbackVote--; + priv->DIG_NumberUpgradeVote++; + + if (priv->DIG_NumberUpgradeVote>9) + { + if (priv->InitialGain > LowestGainStage) // In 87B, m78dBm means State 4 (m864dBm) + { + priv->InitialGain = (priv->InitialGain - 1); + //printk("DIG**********OFDM False Alarm: %#X, OfdmFA1: %#X, OfdmFA2: %#X\n", OFDMFalseAlarm, OfdmFA1, OfdmFA2); + //printk("DIG--------- Upgrade OFDM:%d \n", priv->InitialGain); + UpdateInitialGain(dev); // 2005.01.06, by rcnjko. + } + priv->DIG_NumberFallbackVote = 0; + priv->DIG_NumberUpgradeVote=0; + } + } + +// printk("DIG+++++++ OFDM:%d\n", priv->InitialGain); +// printk("<--------- DIG_Zebra()\n"); +} + +// +// Description: +// Dispatch DIG implementation according to RF. +// +void DynamicInitGain(struct net_device *dev) +{ + struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev); + + switch(priv->rf_chip) + { + case RF_ZEBRA: + case RF_ZEBRA2: // [AnnieWorkaround] For Zebra2, 2005-08-01. + //case RF_ZEBRA4: + DIG_Zebra(dev); + break; + + default: + printk("DynamicInitGain(): unknown RFChipID(%d) !!!\n", priv->rf_chip); + break; + } +} + +// By Bruce, 2007-03-29. +// +// Description: +// Dispatch CCK Power Detection implementation according to RF. +// +void DynamicCCKThreshold(struct net_device *dev) +{ + struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev); + u16 CCK_Up_Th; + u16 CCK_Lw_Th; + u16 CCKFalseAlarm; + + printk("=====>DynamicCCKThreshold()\n"); + + CCK_Up_Th = priv->CCKUpperTh; + CCK_Lw_Th = priv->CCKLowerTh; + CCKFalseAlarm = (u16)((priv->FalseAlarmRegValue & 0x0000ffff) >> 8); // We only care about the higher byte. + printk("DynamicCCKThreshold(): CCK Upper Threshold: 0x%02X, Lower Threshold: 0x%02X, CCKFalseAlarmHighByte: 0x%02X\n", CCK_Up_Th, CCK_Lw_Th, CCKFalseAlarm); + + if(priv->StageCCKTh < 3 && CCKFalseAlarm >= CCK_Up_Th) + { + priv->StageCCKTh ++; + UpdateCCKThreshold(dev); + } + else if(priv->StageCCKTh > 0 && CCKFalseAlarm <= CCK_Lw_Th) + { + priv->StageCCKTh --; + UpdateCCKThreshold(dev); + } + + printk("<=====DynamicCCKThreshold()\n"); +} + +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)) +void rtl8180_hw_dig_wq (struct work_struct *work) +{ + struct delayed_work *dwork = container_of(work,struct delayed_work,work); + struct ieee80211_device *ieee = container_of(dwork,struct ieee80211_device,hw_dig_wq); + struct net_device *dev = ieee->dev; +#else +void rtl8180_hw_dig_wq(struct net_device *dev) +{ + // struct r8180_priv *priv = ieee80211_priv(dev); +#endif + struct r8180_priv *priv = ieee80211_priv(dev); + + // Read CCK and OFDM False Alarm. + if(priv->card_8187_Bversion == VERSION_8187B_B) { + // Read only 1 byte because of HW bug. This is a temporal modification. Joseph + // Modify by Isaiah 2006-06-27 + priv->FalseAlarmRegValue = (u32)read_nic_byte(dev, (OFDM_FALSE_ALARM+1)); + } else { + priv->FalseAlarmRegValue = read_nic_dword(dev, CCK_FALSE_ALARM); + } + + // Adjust Initial Gain dynamically. + if(priv->bDigMechanism) { + DynamicInitGain(dev); + } + + // + // Move from DynamicInitGain to be independent of the OFDM DIG mechanism, by Bruce, 2007-06-01. + // + if(priv->card_8187 == NIC_8187B) { + // By Bruce, 2007-03-29. + // Dynamically update CCK Power Detection Threshold. + if(priv->bCCKThMechanism) + { + DynamicCCKThreshold(dev); + } + } +} + +void SetTxPowerLevel8187(struct net_device *dev, short chan) +{ + struct r8180_priv *priv = ieee80211_priv(dev); + + switch(priv->rf_chip) + { + case RF_ZEBRA: + rtl8225_SetTXPowerLevel(dev,chan); + break; + + case RF_ZEBRA2: + //case RF_ZEBRA4: + rtl8225z2_SetTXPowerLevel(dev,chan); + break; + } +} + +// +// Description: +// Check if input power signal strength exceeds maximum input power threshold +// of current HW. +// If yes, we set our HW to high input power state: +// RX: always force TR switch to SW Tx mode to reduce input power. +// TX: turn off smaller Tx output power (see RtUsbCheckForHang). +// +// If no, we restore our HW to normal input power state: +/// RX: restore TR switch to HW controled mode. +// TX: restore TX output power (see RtUsbCheckForHang). +// +// TODO: +// 1. Tx power control shall not be done in Platform-dependent timer (e.g. RtUsbCheckForHang). +// 2. Allow these threshold adjustable by RF SD. +// +void DoRxHighPower(struct net_device *dev) +{ + struct r8180_priv *priv = ieee80211_priv(dev); + TR_SWITCH_STATE TrSwState; + u16 HiPwrUpperTh = 0; + u16 HiPwrLowerTh = 0; + u16 RSSIHiPwrUpperTh = 0; + u16 RSSIHiPwrLowerTh = 0; + + //87S remove TrSwitch mechanism + if((priv->card_8187 == NIC_8187B)||(priv->card_8187 == NIC_8187)) { + + //printk("----> DoRxHighPower()\n"); + + // + // Get current TR switch setting. + // + //Adapter->HalFunc.GetHwRegHandler(Adapter, HW_VAR_TR_SWITCH, (pu1Byte)(&TrSwState)); + TrSwState = priv->TrSwitchState; + + // + // Determine threshold according to RF type. + // + switch(priv->rf_chip) + { + case RF_ZEBRA: + HiPwrUpperTh = Z1_HIPWR_UPPER_TH; + HiPwrLowerTh = Z1_HIPWR_LOWER_TH; + printk("DoRxHighPower(): RF_ZEBRA, Upper Threshold: %d LOWER Threshold: %d\n", + HiPwrUpperTh, HiPwrLowerTh); + break; + + case RF_ZEBRA2: + if((priv->card_8187 == NIC_8187)) { + HiPwrUpperTh = Z2_HIPWR_UPPER_TH; + HiPwrLowerTh = Z2_HIPWR_LOWER_TH; + } else { + // By Bruce, 2007-04-11. + // HiPwrUpperTh = Z2_HIPWR_UPPER_TH; + // HiPwrLowerTh = Z2_HIPWR_LOWER_TH; + + HiPwrUpperTh = priv->Z2HiPwrUpperTh; + HiPwrLowerTh = priv->Z2HiPwrLowerTh; + HiPwrUpperTh = HiPwrUpperTh * 10; + HiPwrLowerTh = HiPwrLowerTh * 10; + + RSSIHiPwrUpperTh = priv->Z2RSSIHiPwrUpperTh; + RSSIHiPwrLowerTh = priv->Z2RSSIHiPwrLowerTh; + //printk("DoRxHighPower(): RF_ZEBRA2, Upper Threshold: %d LOWER Threshold: %d, RSSI Upper Th: %d, RSSI Lower Th: %d\n",HiPwrUpperTh, HiPwrLowerTh, RSSIHiPwrUpperTh, RSSIHiPwrLowerTh); + } + break; + + default: + printk("DoRxHighPower(): Unknown RFChipID(%d), UndecoratedSmoothedSS(%d), TrSwState(%d)!!!\n", + priv->rf_chip, priv->UndecoratedSmoothedSS, TrSwState); + return; + break; + } + + /*printk(">>>>>>>>>>Set TR switch to software control, UndecoratedSmoothedSS:%d, CurCCKRSSI = %d\n",\ + priv->UndecoratedSmoothedSS, priv->CurCCKRSSI); + */ + if((priv->card_8187 == NIC_8187)) { + // + // Perform Rx part High Power Mechanism by UndecoratedSmoothedSS. + // + if (priv->UndecoratedSmoothedSS > HiPwrUpperTh) + { // High input power state. + if( priv->TrSwitchState == TR_HW_CONTROLLED ) + { + /* printk(">>>>>>>>>>Set TR switch to software control, UndecoratedSmoothedSS:%d \n", \ + priv->UndecoratedSmoothedSS); + // printk(">>>>>>>>>> TR_SW_TX\n"); + */ + write_nic_byte(dev, RFPinsSelect, + (u8)(priv->wMacRegRfPinsSelect | TR_SW_MASK_8187 )); + write_nic_byte(dev, RFPinsOutput, + (u8)((priv->wMacRegRfPinsOutput&(~TR_SW_MASK_8187))|TR_SW_MASK_TX_8187)); + priv->TrSwitchState = TR_SW_TX; + priv->bToUpdateTxPwr = true; + } + } + else if (priv->UndecoratedSmoothedSS < HiPwrLowerTh) + { // Normal input power state. + if( priv->TrSwitchState == TR_SW_TX) + { + /* printk("<<<<<<<<<<UndecoratedSmoothedSS); + // printk("<<<<<<<<<< TR_HW_CONTROLLED\n"); + */ + write_nic_byte(dev, RFPinsOutput, (u8)(priv->wMacRegRfPinsOutput)); + write_nic_byte(dev, RFPinsSelect, (u8)(priv->wMacRegRfPinsSelect)); + priv->TrSwitchState = TR_HW_CONTROLLED; + priv->bToUpdateTxPwr = true; + } + } + }else { + /*printk("=====>TrSwState = %s\n", (TrSwState==TR_HW_CONTROLLED)?"TR_HW_CONTROLLED":"TR_SW_TX"); + //printk("UndecoratedSmoothedSS:%d, CurCCKRSSI = %d\n",priv->UndecoratedSmoothedSS, priv->CurCCKRSSI); */ + // Asked by SD3 DZ, by Bruce, 2007-04-12. + if(TrSwState == TR_HW_CONTROLLED) + { + if((priv->UndecoratedSmoothedSS > HiPwrUpperTh) || + (priv->bCurCCKPkt && (priv->CurCCKRSSI > RSSIHiPwrUpperTh))) + { + //printk("===============================> high power!\n"); + write_nic_byte(dev, RFPinsSelect, (u8)(priv->wMacRegRfPinsSelect|TR_SW_MASK_8187 )); + write_nic_byte(dev, RFPinsOutput, + (u8)((priv->wMacRegRfPinsOutput&(~TR_SW_MASK_8187))|TR_SW_MASK_TX_8187)); + priv->TrSwitchState = TR_SW_TX; + priv->bToUpdateTxPwr = true; + } + } + else + { + if((priv->UndecoratedSmoothedSS < HiPwrLowerTh) && + (!priv->bCurCCKPkt || priv->CurCCKRSSI < RSSIHiPwrLowerTh)) + { + write_nic_byte(dev, RFPinsOutput, (u8)(priv->wMacRegRfPinsOutput)); + write_nic_byte(dev, RFPinsSelect, (u8)(priv->wMacRegRfPinsSelect)); + priv->TrSwitchState = TR_HW_CONTROLLED; + priv->bToUpdateTxPwr = true; + } + } + //printk("<=======TrSwState = %s\n", (TrSwState==TR_HW_CONTROLLED)?"TR_HW_CONTROLLED":"TR_SW_TX"); + } + //printk("<---- DoRxHighPower()\n"); + } +} + + +// +// Description: +// Callback function of UpdateTxPowerWorkItem. +// Because of some event happend, e.g. CCX TPC, High Power Mechanism, +// We update Tx power of current channel again. +// +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)) +void rtl8180_tx_pw_wq (struct work_struct *work) +{ + struct delayed_work *dwork = container_of(work,struct delayed_work,work); + struct ieee80211_device *ieee = container_of(dwork,struct ieee80211_device,tx_pw_wq); + struct net_device *dev = ieee->dev; +#else +void rtl8180_tx_pw_wq(struct net_device *dev) +{ + // struct r8180_priv *priv = ieee80211_priv(dev); +#endif + + struct r8180_priv *priv = ieee80211_priv(dev); + + //printk("----> UpdateTxPowerWorkItemCallback()\n"); + + if(priv->bToUpdateTxPwr) + { + //printk("DoTxHighPower(): schedule UpdateTxPowerWorkItem......\n"); + priv->bToUpdateTxPwr = false; + SetTxPowerLevel8187(dev, priv->chan); + } + + DoRxHighPower(dev); + //printk("<---- UpdateTxPowerWorkItemCallback()\n"); +} + +// +// Description: +// Return TRUE if we shall perform High Power Mecahnism, FALSE otherwise. +// +bool CheckHighPower(struct net_device *dev) +{ + struct r8180_priv *priv = ieee80211_priv(dev); + struct ieee80211_device *ieee = priv->ieee80211; + + if(!priv->bRegHighPowerMechanism) + { + return false; + } + + if((ieee->state == IEEE80211_LINKED_SCANNING)||(ieee->state == IEEE80211_MESH_SCANNING)) + { + return false; + } + + return true; +} + +#ifdef SW_ANTE_DIVERSITY + +#define ANTENNA_DIVERSITY_TIMER_PERIOD 1000 // 1000 m + +void +SwAntennaDiversityRxOk8185( + struct net_device *dev, + u8 SignalStrength + ) +{ + struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev); + + //printk("+SwAntennaDiversityRxOk8185: RxSs: %d\n", SignalStrength); + + priv->AdRxOkCnt++; + + if( priv->AdRxSignalStrength != -1) + { + priv->AdRxSignalStrength = ((priv->AdRxSignalStrength*7) + (SignalStrength*3)) / 10; + } + else + { // Initialization case. + priv->AdRxSignalStrength = SignalStrength; + } + + //printk("====>pkt rcvd by %d\n", priv->LastRxPktAntenna); + if( priv->LastRxPktAntenna ) //Main antenna. + priv->AdMainAntennaRxOkCnt++; + else // Aux antenna. + priv->AdAuxAntennaRxOkCnt++; + //printk("-SwAntennaDiversityRxOk8185: AdRxOkCnt: %d AdRxSignalStrength: %d\n", priv->AdRxOkCnt, priv->AdRxSignalStrength); +} + +// +// Description: Change Antenna Switch. +// +bool +SetAntenna8185( + struct net_device *dev, + u8 u1bAntennaIndex + ) +{ + struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev); + bool bAntennaSwitched = false; + +// printk("+SetAntenna8185(): Antenna is switching to: %d \n", u1bAntennaIndex); + + switch(u1bAntennaIndex) + { + case 0://main antenna + switch(priv->rf_chip) + { + case RF_ZEBRA: + case RF_ZEBRA2: + //case RF_ZEBRA4: + // Tx Antenna. + write_nic_byte(dev, ANTSEL, 0x03); // Config TX antenna. + + //PlatformEFIOWrite4Byte(Adapter, BBAddr, 0x01009b90); // Config CCK RX antenna. + //PlatformEFIOWrite4Byte(Adapter, BBAddr, 0x5c8D); // Config OFDM RX antenna. + + // Rx CCK . + write_nic_byte(dev, 0x7f, ((0x01009b90 & 0xff000000) >> 24)); + write_nic_byte(dev, 0x7e, ((0x01009b90 & 0x00ff0000) >> 16)); + write_nic_byte(dev, 0x7d, ((0x01009b90 & 0x0000ff00) >> 8)); + write_nic_byte(dev, 0x7c, ((0x01009b90 & 0x000000ff) >> 0)); + + // Rx OFDM. + write_nic_byte(dev, 0x7f, ((0x00005c8D & 0xff000000) >> 24)); + write_nic_byte(dev, 0x7e, ((0x00005c8D & 0x00ff0000) >> 16)); + write_nic_byte(dev, 0x7d, ((0x00005c8D & 0x0000ff00) >> 8)); + write_nic_byte(dev, 0x7c, ((0x00005c8D & 0x000000ff) >> 0)); + + bAntennaSwitched = true; + break; + + default: + printk("SetAntenna8185: unkown RFChipID(%d)\n", priv->rf_chip); + break; + } + break; + + case 1: + switch(priv->rf_chip) + { + case RF_ZEBRA: + case RF_ZEBRA2: + //case RF_ZEBRA4: + // Tx Antenna. + write_nic_byte(dev, ANTSEL, 0x00); // Config TX antenna. + + //PlatformEFIOWrite4Byte(Adapter, BBAddr, 0x0100bb90); // Config CCK RX antenna. + //PlatformEFIOWrite4Byte(Adapter, BBAddr, 0x548D); // Config OFDM RX antenna. + + // Rx CCK. + write_nic_byte(dev, 0x7f, ((0x0100bb90 & 0xff000000) >> 24)); + write_nic_byte(dev, 0x7e, ((0x0100bb90 & 0x00ff0000) >> 16)); + write_nic_byte(dev, 0x7d, ((0x0100bb90 & 0x0000ff00) >> 8)); + write_nic_byte(dev, 0x7c, ((0x0100bb90 & 0x000000ff) >> 0)); + + // Rx OFDM. + write_nic_byte(dev, 0x7f, ((0x0000548D & 0xff000000) >> 24)); + write_nic_byte(dev, 0x7e, ((0x0000548D & 0x00ff0000) >> 16)); + write_nic_byte(dev, 0x7d, ((0x0000548D & 0x0000ff00) >> 8)); + write_nic_byte(dev, 0x7c, ((0x0000548D & 0x000000ff) >> 0)); + + bAntennaSwitched = true; + break; + + default: + printk("SetAntenna8185: unkown RFChipID(%d)\n", priv->rf_chip); + break; + } + break; + + default: + printk("SetAntenna8185: unkown u1bAntennaIndex(%d)\n", u1bAntennaIndex); + break; + } + + if(bAntennaSwitched) + { + priv->CurrAntennaIndex = u1bAntennaIndex; + } + +// printk("-SetAntenna8185(): return (%#X)\n", bAntennaSwitched); + + return bAntennaSwitched; +} + +// +// Description: Toggle Antenna switch. +// +bool SwitchAntenna(struct net_device *dev) +{ + struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev); + + bool bResult = false; + + if(priv->CurrAntennaIndex == 0) + { + bResult = SetAntenna8185(dev, 1); + if(priv->ieee80211->state == IEEE80211_LINKED) + printk("Switching to Aux antenna 1 \n"); + } + else + { + bResult = SetAntenna8185(dev, 0); + if(priv->ieee80211->state == IEEE80211_LINKED) + printk("Switching to Main antenna 0 \n"); + } + + return bResult; +} + +// +// Description: +// Engine of SW Antenna Diversity mechanism. +// Since 8187 has no Tx part information, +// this implementation is only dependend on Rx part information. +// +// 2006.04.17, by rcnjko. +// +void SwAntennaDiversity(struct net_device *dev) +{ + struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev); + //bool bSwCheckSS=false; + bool bSwCheckSS=true;//open the SignalStrength check if not switched by rx ok pkt. + +// printk("+SwAntennaDiversity(): CurrAntennaIndex: %d\n", priv->CurrAntennaIndex); + +//by amy 080312 + if(bSwCheckSS){ + priv->AdTickCount++; + + //printk("(1) AdTickCount: %d, AdCheckPeriod: %d\n", priv->AdTickCount, priv->AdCheckPeriod); + //printk("(2) AdRxSignalStrength: %ld, AdRxSsThreshold: %ld\n", priv->AdRxSignalStrength, priv->AdRxSsThreshold); + } +// priv->AdTickCount++;//-by amy 080312 + + // Case 1. No Link. + if(priv->ieee80211->state != IEEE80211_LINKED){ + //printk("SwAntennaDiversity(): Case 1. No Link.\n"); + + priv->bAdSwitchedChecking = false; + // I switch antenna here to prevent any one of antenna is broken before link established, 2006.04.18, by rcnjko.. + SwitchAntenna(dev); + } + // Case 2. Linked but no packet received. + else if(priv->AdRxOkCnt == 0){ + printk("SwAntennaDiversity(): Case 2. Linked but no packet received.\n"); + + priv->bAdSwitchedChecking = false; + SwitchAntenna(dev); + } + // Case 3. Evaluate last antenna switch action in case4. and undo it if necessary. + else if(priv->bAdSwitchedChecking == true){ + //printk("SwAntennaDiversity(): Case 3. Evaluate last antenna switch action.\n"); + + priv->bAdSwitchedChecking = false; + + // Adjust Rx signal strength threashold. + priv->AdRxSsThreshold = (priv->AdRxSignalStrength + priv->AdRxSsBeforeSwitched) / 2; + + priv->AdRxSsThreshold = (priv->AdRxSsThreshold > priv->AdMaxRxSsThreshold) ? + priv->AdMaxRxSsThreshold: priv->AdRxSsThreshold; + if(priv->AdRxSignalStrength < priv->AdRxSsBeforeSwitched){ + // Rx signal strength is not improved after we swtiched antenna. => Swich back. + printk("SwAntennaDiversity(): Rx Signal Strength is not improved, CurrRxSs: %ld, LastRxSs: %ld\n", priv->AdRxSignalStrength, priv->AdRxSsBeforeSwitched); + + //by amy 080312 + // Increase Antenna Diversity checking period due to bad decision. + priv->AdCheckPeriod *= 2; + //by amy 080312 + // + // Increase Antenna Diversity checking period. + if(priv->AdCheckPeriod > priv->AdMaxCheckPeriod) + priv->AdCheckPeriod = priv->AdMaxCheckPeriod; + + // Wrong deceision => switch back. + SwitchAntenna(dev); + }else{ // Rx Signal Strength is improved. + printk("SwAntennaDiversity(): Rx Signal Strength is improved, CurrRxSs: %ld, LastRxSs: %ld\n", priv->AdRxSignalStrength, priv->AdRxSsBeforeSwitched); + + // Reset Antenna Diversity checking period to its min value. + priv->AdCheckPeriod = priv->AdMinCheckPeriod; + } + + //printk("SwAntennaDiversity(): AdRxSsThreshold: %ld, AdCheckPeriod: %d\n", + // priv->AdRxSsThreshold, priv->AdCheckPeriod); + } + // Case 4. Evaluate if we shall switch antenna now. + // Cause Table Speed is very fast in TRC Dell Lab, we check it every time. + else// if(priv->AdTickCount >= priv->AdCheckPeriod)//-by amy 080312 + { + //printk("SwAntennaDiversity(): Case 4. Evaluate if we shall switch antenna now.\n"); + + priv->AdTickCount = 0; + + // + // We evaluate RxOk counts for each antenna first and than + // evaluate signal strength. + // The following operation can overcome the disability of CCA on both two antennas + // When signal strength was extremely low or high. + // 2008.01.30. + // + + // + // Evaluate RxOk count from each antenna if we shall switch default antenna now. + // Added by Roger, 2008.02.21. + + //{by amy 080312 + if((priv->AdMainAntennaRxOkCnt < priv->AdAuxAntennaRxOkCnt) && (priv->CurrAntennaIndex == 0)){ + // We set Main antenna as default but RxOk count was less than Aux ones. + + printk("SwAntennaDiversity(): Main antenna %d RxOK is poor, AdMainAntennaRxOkCnt: %d, AdAuxAntennaRxOkCnt: %d\n",priv->CurrAntennaIndex, priv->AdMainAntennaRxOkCnt, priv->AdAuxAntennaRxOkCnt); + + // Switch to Aux antenna. + SwitchAntenna(dev); + priv->bHWAdSwitched = true; + }else if((priv->AdAuxAntennaRxOkCnt < priv->AdMainAntennaRxOkCnt) && (priv->CurrAntennaIndex == 1)){ + // We set Aux antenna as default but RxOk count was less than Main ones. + + printk("SwAntennaDiversity(): Aux antenna %d RxOK is poor, AdMainAntennaRxOkCnt: %d, AdAuxAntennaRxOkCnt: %d\n",priv->CurrAntennaIndex, priv->AdMainAntennaRxOkCnt, priv->AdAuxAntennaRxOkCnt); + + // Switch to Main antenna. + SwitchAntenna(dev); + priv->bHWAdSwitched = true; + }else{// Default antenna is better. + + printk("SwAntennaDiversity(): Current Antenna %d is better., AdMainAntennaRxOkCnt: %d, AdAuxAntennaRxOkCnt: %d\n",priv->CurrAntennaIndex, priv->AdMainAntennaRxOkCnt, priv->AdAuxAntennaRxOkCnt); + + // Still need to check current signal strength. + priv->bHWAdSwitched = false; + } + // + // We evaluate Rx signal strength ONLY when default antenna + // didn't changed by HW evaluation. + // 2008.02.27. + // + // [TRC Dell Lab] SignalStrength is inaccuracy. Isaiah 2008-03-05 + // For example, Throughput of aux is better than main antenna(about 10M v.s 2M), + // but AdRxSignalStrength is less than main. + // Our guess is that main antenna have lower throughput and get many change + // to receive more CCK packets(ex.Beacon) which have stronger SignalStrength. + // + if( (!priv->bHWAdSwitched) && (bSwCheckSS)){ + //by amy 080312} + + // Evaluate Rx signal strength if we shall switch antenna now. + if(priv->AdRxSignalStrength < priv->AdRxSsThreshold){ + // Rx signal strength is weak => Switch Antenna. + printk("SwAntennaDiversity(): Rx Signal Strength is weak, CurrRxSs: %ld, RxSsThreshold: %ld\n", priv->AdRxSignalStrength, priv->AdRxSsThreshold); + + priv->AdRxSsBeforeSwitched = priv->AdRxSignalStrength; + priv->bAdSwitchedChecking = true; + + SwitchAntenna(dev); + }else{ // Rx signal strength is OK. + printk("SwAntennaDiversity(): Rx Signal Strength is OK, CurrRxSs: %ld, RxSsThreshold: %ld\n", priv->AdRxSignalStrength, priv->AdRxSsThreshold); + + priv->bAdSwitchedChecking = false; + // Increase Rx signal strength threashold if necessary. + if( (priv->AdRxSignalStrength > (priv->AdRxSsThreshold + 10)) && // Signal is much stronger than current threshold + priv->AdRxSsThreshold <= priv->AdMaxRxSsThreshold) // Current threhold is not yet reach upper limit. + { + priv->AdRxSsThreshold = (priv->AdRxSsThreshold + priv->AdRxSignalStrength) / 2; + priv->AdRxSsThreshold = (priv->AdRxSsThreshold > priv->AdMaxRxSsThreshold) ? + priv->AdMaxRxSsThreshold: priv->AdRxSsThreshold;//+by amy 080312 + } + + // Reduce Antenna Diversity checking period if possible. + if( priv->AdCheckPeriod > priv->AdMinCheckPeriod ) + { + priv->AdCheckPeriod /= 2; + } + } + } + } +//by amy 080312 + // Reset antenna diversity Rx related statistics. + priv->AdRxOkCnt = 0; + priv->AdMainAntennaRxOkCnt = 0; + priv->AdAuxAntennaRxOkCnt = 0; +//by amy 080312 + +// priv->AdRxOkCnt = 0;//-by amy 080312 + + //printk("-SwAntennaDiversity()\n"); +} + +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)) +void SwAntennaWorkItemCallback(struct work_struct *work) +{ + struct ieee80211_device *ieee = container_of(work, struct ieee80211_device, SwAntennaWorkItem.work); + struct net_device *dev = ieee->dev; +#else +void SwAntennaWorkItemCallback(struct net_device *dev) +{ +#endif + //printk("==>%s \n", __func__); + SwAntennaDiversity(dev); +} + +// +// Description: Timer callback function of SW Antenna Diversity. +// +void SwAntennaDiversityTimerCallback(struct net_device *dev) +{ + struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev); + RT_RF_POWER_STATE rtState; + + //printk("+SwAntennaDiversityTimerCallback()\n"); + + // + // We do NOT need to switch antenna while RF is off. + // 2007.05.09, added by Roger. + // + rtState = priv->eRFPowerState; + do{ + if (rtState == eRfOff){ +// printk("SwAntennaDiversityTimer - RF is OFF.\n"); + break; + }else if (rtState == eRfSleep){ + // Don't access BB/RF under Disable PLL situation. + //RT_TRACE((COMP_RF|COMP_ANTENNA), DBG_LOUD, ("SwAntennaDiversityTimerCallback(): RF is Sleep => skip it\n")); + break; + } + + queue_work(priv->ieee80211->wq,(void *)&priv->ieee80211->SwAntennaWorkItem); + + }while(false); + + if(priv->up){ + //priv->SwAntennaDiversityTimer.expires = jiffies + MSECS(ANTENNA_DIVERSITY_TIMER_PERIOD); + //add_timer(&priv->SwAntennaDiversityTimer); + mod_timer(&priv->SwAntennaDiversityTimer, jiffies + MSECS(ANTENNA_DIVERSITY_TIMER_PERIOD)); + } + +} +#endif + + + diff -Nur linux-2.6.30.5.orig/drivers/net/wireless/rtl8187b/r8180_dm.h linux-2.6.30.5/drivers/net/wireless/rtl8187b/r8180_dm.h --- linux-2.6.30.5.orig/drivers/net/wireless/rtl8187b/r8180_dm.h 1970-01-01 01:00:00.000000000 +0100 +++ linux-2.6.30.5/drivers/net/wireless/rtl8187b/r8180_dm.h 2009-08-23 19:01:04.000000000 +0200 @@ -0,0 +1,38 @@ +/* + Hardware dynamic mechanism for RTL8187B. +Notes: + This file is ported from RTL8187B Windows driver +*/ + +#ifndef R8180_DM_H +#define R8180_DM_H + +#include "r8187.h" + +bool CheckDig(struct net_device *dev); +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)) +void rtl8180_hw_dig_wq (struct work_struct *work); +#else +void rtl8180_hw_dig_wq(struct net_device *dev); +#endif + +bool CheckHighPower(struct net_device *dev); +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)) +void rtl8180_tx_pw_wq (struct work_struct *work); +#else +void rtl8180_tx_pw_wq(struct net_device *dev); +#endif + +//by lzm for antenna +#ifdef SW_ANTE_DIVERSITY +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)) +void SwAntennaWorkItemCallback(struct work_struct *work); +#else +void SwAntennaWorkItemCallback(struct net_device *dev); +#endif +void SwAntennaDiversityRxOk8185(struct net_device *dev, u8 SignalStrength); +void SwAntennaDiversityTimerCallback(struct net_device *dev); +#endif +//by lzm for antenna + +#endif //R8180_PM_H diff -Nur linux-2.6.30.5.orig/drivers/net/wireless/rtl8187b/r8180_hw.h linux-2.6.30.5/drivers/net/wireless/rtl8187b/r8180_hw.h --- linux-2.6.30.5.orig/drivers/net/wireless/rtl8187b/r8180_hw.h 1970-01-01 01:00:00.000000000 +0100 +++ linux-2.6.30.5/drivers/net/wireless/rtl8187b/r8180_hw.h 2009-08-23 19:01:04.000000000 +0200 @@ -0,0 +1,788 @@ +/* + This is part of rtl8187 OpenSource driver. + Copyright (C) Andrea Merello 2004-2005 + Released under the terms of GPL (General Public Licence) + + Parts of this driver are based on the GPL part of the + official Realtek driver. + Parts of this driver are based on the rtl8180 driver skeleton + from Patric Schenke & Andres Salomon. + Parts of this driver are based on the Intel Pro Wireless + 2100 GPL driver. + + We want to tanks the Authors of those projects + and the Ndiswrapper project Authors. +*/ + +/* Mariusz Matuszek added full registers definition with Realtek's name */ + +/* this file contains register definitions for the rtl8187 MAC controller */ +#ifndef R8180_HW +#define R8180_HW + +typedef enum _RF_TYPE_8187{ + RF_TYPE_MIN, + RF_ZEBRA = 5, + RF_ZEBRA2, // added by Annie, 2005-08-01. + RF_TYPE_MAX, +}RF_TYPE_8187,*PRF_TYPE_8187; + +typedef enum _VERSION_8187{ + // RTL8187 + VERSION_8187_B, // B-cut + VERSION_8187_D, // D-cut + // RTL8187B + VERSION_8187B_B, // B-cut + VERSION_8187B_D, //D-cut //added 2007-9-14 + VERSION_8187B_E, //E-cut //added 2007-9-14 +}VERSION_8187,*PVERSION_8187; + +//by lzm for antenna +#ifdef SW_ANTE_DIVERSITY +#define RF_PARAM 0x19 +#define RF_PARAM_DIGPHY_SHIFT 0 +#define RF_PARAM_ANTBDEFAULT_SHIFT 1 +#define EEPROM_VERSION 0x3c +#define EEPROM_CONFIG2 0x18 +#define EEPROM_CS_THRESHOLD 0x2F +#define EEPROM_RF_PARAM 0x08 +//// BIT[8-9] is for SW Antenna Diversity. Only the value EEPROM_SW_AD_ENABLE means enable, other values are diable. +#define EEPROM_SW_AD_MASK 0x0300 +#define EEPROM_SW_AD_ENABLE 0x0100 +//// BIT[10-11] determine if Antenna 1 is the Default Antenna. Only the value EEPROM_DEF_ANT_1 means TRUE, other values are FALSE. +#define EEPROM_DEF_ANT_MASK 0x0C00 +#define EEPROM_DEF_ANT_1 0x0400 + +#define RCR_EnCS1 BIT29 // enable carrier sense method 1 +#define RCR_EnCS2 BIT30 // enable carrier sense method 2 +#endif +//by lzm for antenna + +#define RTL8187_RF_INDEX 0x8225 +#define RTL8187_REQT_READ 0xc0 +#define RTL8187_REQT_WRITE 0x40 +#define RTL8187_REQ_GET_REGS 0x05 +#define RTL8187_REQ_SET_REGS 0x05 + + + +#define MAX_TX_URB 5 +#define MAX_RX_URB 16 +#define RX_URB_SIZE 0x9C4 + + + + + +#define BB_ANTATTEN_CHAN14 0x0c +#define BB_ANTENNA_B 0x40 + +#define BB_HOST_BANG (1<<30) +#define BB_HOST_BANG_EN (1<<2) +#define BB_HOST_BANG_CLK (1<<1) +#define BB_HOST_BANG_RW (1<<3) +#define BB_HOST_BANG_DATA 1 + +#define ANAPARAM_TXDACOFF_SHIFT 27 +#define ANAPARAM_PWR0_MASK ((1<<30)|(1<<29)|(1<<28)) +#define ANAPARAM_PWR0_SHIFT 28 +#define ANAPARAM_PWR1_MASK ((1<<26)|(1<<25)|(1<<24)|(1<<23)|(1<<22)|(1<<21)|(1<<20)) +#define ANAPARAM_PWR1_SHIFT 20 + +#define MAC0 0 +#define MAC1 1 +#define MAC2 2 +#define MAC3 3 +#define MAC4 4 +#define MAC5 5 + +#define RXFIFOCOUNT 0x10 +#define TXFIFOCOUNT 0x12 +#define BcnIntTime 0x74 +#define TALLY_SEL 0xfc +#define BQREQ 0x13 + +#define CMD 0x37 +#define CMD_RST_SHIFT 4 +#define CMD_RESERVED_MASK ((1<<1) | (1<<5) | (1<<6) | (1<<7)) +#define CMD_RX_ENABLE_SHIFT 3 +#define CMD_TX_ENABLE_SHIFT 2 + +#define EPROM_CMD 0x50 +#define EPROM_CMD_RESERVED_MASK ((1<<5)|(1<<4)) +#define EPROM_CMD_OPERATING_MODE_SHIFT 6 +#define EPROM_CMD_OPERATING_MODE_MASK ((1<<7)|(1<<6)) +#define EPROM_CMD_CONFIG 0x3 +#define EPROM_CMD_NORMAL 0 +#define EPROM_CMD_LOAD 1 +#define EPROM_CMD_PROGRAM 2 +#define EPROM_CS_SHIFT 3 +#define EPROM_CK_SHIFT 2 +#define EPROM_W_SHIFT 1 +#define EPROM_R_SHIFT 0 +#define CONFIG2_DMA_POLLING_MODE_SHIFT 3 +#define INTA 0x3e +#define INTA_TXOVERFLOW (1<<15) +#define INTA_TIMEOUT (1<<14) +#define INTA_BEACONTIMEOUT (1<<13) +#define INTA_ATIM (1<<12) +#define INTA_BEACONDESCERR (1<<11) +#define INTA_BEACONDESCOK (1<<10) +#define INTA_HIPRIORITYDESCERR (1<<9) +#define INTA_HIPRIORITYDESCOK (1<<8) +#define INTA_NORMPRIORITYDESCERR (1<<7) +#define INTA_NORMPRIORITYDESCOK (1<<6) +#define INTA_RXOVERFLOW (1<<5) +#define INTA_RXDESCERR (1<<4) +#define INTA_LOWPRIORITYDESCERR (1<<3) +#define INTA_LOWPRIORITYDESCOK (1<<2) +#define INTA_RXCRCERR (1<<1) +#define INTA_RXOK (1) +#define INTA_MASK 0x3c +#define RXRING_ADDR 0xe4 // page 0 +#define PGSELECT 0x5e +#define PGSELECT_PG_SHIFT 0 +#define RX_CONF 0x44 +#define MAC_FILTER_MASK ((1<<0) | (1<<1) | (1<<2) | (1<<3) | (1<<5) | \ +(1<<12) | (1<<18) | (1<<19) | (1<<20) | (1<<21) | (1<<22) | (1<<23)) +#define RX_CHECK_BSSID_SHIFT 23 +#define ACCEPT_PWR_FRAME_SHIFT 22 +#define ACCEPT_MNG_FRAME_SHIFT 20 +#define ACCEPT_CTL_FRAME_SHIFT 19 +#define ACCEPT_DATA_FRAME_SHIFT 18 +#define ACCEPT_ICVERR_FRAME_SHIFT 12 +#define ACCEPT_CRCERR_FRAME_SHIFT 5 +#define ACCEPT_BCAST_FRAME_SHIFT 3 +#define ACCEPT_MCAST_FRAME_SHIFT 2 +#define ACCEPT_ALLMAC_FRAME_SHIFT 0 +#define ACCEPT_NICMAC_FRAME_SHIFT 1 +#define RX_FIFO_THRESHOLD_MASK ((1<<13) | (1<<14) | (1<<15)) +#define RX_FIFO_THRESHOLD_SHIFT 13 +#define RX_FIFO_THRESHOLD_128 3 +#define RX_FIFO_THRESHOLD_256 4 +#define RX_FIFO_THRESHOLD_512 5 +#define RX_FIFO_THRESHOLD_1024 6 +#define RX_FIFO_THRESHOLD_NONE 7 +#define RX_AUTORESETPHY_SHIFT 28 +#define EPROM_TYPE_SHIFT 6 +#define TX_CONF 0x40 +#define TX_CONF_HEADER_AUTOICREMENT_SHIFT 30 +#define TX_LOOPBACK_SHIFT 17 +#define TX_LOOPBACK_MAC 1 +#define TX_LOOPBACK_BASEBAND 2 +#define TX_LOOPBACK_NONE 0 +#define TX_LOOPBACK_CONTINUE 3 +#define TX_LOOPBACK_MASK ((1<<17)|(1<<18)) +#define TX_LRLRETRY_SHIFT 0 +#define R8180_MAX_RETRY 255 +#define TX_SRLRETRY_SHIFT 8 +#define TX_NOICV_SHIFT 19 +#define TX_NOCRC_SHIFT 16 +#define TX_DMA_POLLING 0xd9 +#define TX_DMA_POLLING_BEACON_SHIFT 7 +#define TX_DMA_POLLING_HIPRIORITY_SHIFT 6 +#define TX_DMA_POLLING_NORMPRIORITY_SHIFT 5 +#define TX_DMA_POLLING_LOWPRIORITY_SHIFT 4 +#define TX_DMA_STOP_BEACON_SHIFT 3 +#define TX_DMA_STOP_HIPRIORITY_SHIFT 2 +#define TX_DMA_STOP_NORMPRIORITY_SHIFT 1 +#define TX_DMA_STOP_LOWPRIORITY_SHIFT 0 +#define TX_NORMPRIORITY_RING_ADDR 0x24 +#define TX_HIGHPRIORITY_RING_ADDR 0x28 +#define TX_LOWPRIORITY_RING_ADDR 0x20 +#define MAX_RX_DMA_MASK ((1<<8) | (1<<9) | (1<<10)) +#define MAX_RX_DMA_2048 7 +#define MAX_RX_DMA_1024 6 +#define MAX_RX_DMA_SHIFT 10 +#define INT_TIMEOUT 0x48 +#define CONFIG3_CLKRUN_SHIFT 2 +#define CONFIG3_ANAPARAM_W_SHIFT 6 +#define ANAPARAM 0x54 +#define BEACON_INTERVAL 0x70 +#define BEACON_INTERVAL_MASK ((1<<0)|(1<<1)|(1<<2)|(1<<3)|(1<<4)|(1<<5)| \ +(1<<6)|(1<<7)|(1<<8)|(1<<9)) +#define ATIM_MASK ((1<<0)|(1<<1)|(1<<2)|(1<<3)|(1<<4)|(1<<5)|(1<<6)|(1<<7)| \ +(1<<8)|(1<<9)) +#define ATIM 0x72 +#define EPROM_CS_SHIFT 3 +#define EPROM_CK_SHIFT 2 +#define PHY_DELAY 0x78 +#define PHY_CONFIG 0x80 +#define PHY_ADR 0x7c +#define PHY_READ 0x7e +#define CARRIER_SENSE_COUNTER 0x79 //byte +#define SECURITY 0x5f +#define SECURITY_WEP_TX_ENABLE_SHIFT 1 +#define SECURITY_WEP_RX_ENABLE_SHIFT 0 +#define SECURITY_ENCRYP_104 1 +#define SECURITY_ENCRYP_SHIFT 4 +#define SECURITY_ENCRYP_MASK ((1<<4)|(1<<5)) +#define KEY0 0x90 +#define CONFIG2_ANTENNA_SHIFT 6 +#define TX_BEACON_RING_ADDR 0x4c +#define CONFIG0_WEP40_SHIFT 7 +#define CONFIG0_WEP104_SHIFT 6 +#define AGCRESET_SHIFT 5 + + + +/* + * Operational registers offsets in PCI (I/O) space. + * RealTek names are used. + */ + +#define IDR0 0x0000 +#define IDR1 0x0001 +#define IDR2 0x0002 +#define IDR3 0x0003 +#define IDR4 0x0004 +#define IDR5 0x0005 + +/* 0x0006 - 0x0007 - reserved */ + +#define MAR0 0x0008 +#define MAR1 0x0009 +#define MAR2 0x000A +#define MAR3 0x000B +#define MAR4 0x000C +#define MAR5 0x000D +#define MAR6 0x000E +#define MAR7 0x000F + +/* 0x0010 - 0x0017 - reserved */ + +#define TSFTR 0x0018 +#define TSFTR_END 0x001F + +#define TLPDA 0x0020 +#define TLPDA_END 0x0023 +#define TNPDA 0x0024 +#define TNPDA_END 0x0027 +#define THPDA 0x0028 +#define THPDA_END 0x002B + +#define BRSR_8187 0x002C +#define BRSR_8187_END 0x002D +#define BRSR_8187B 0x0034 +#define BRSR_8187B_END 0x0035 + +#define BSSID 0x002E +#define BSSID_END 0x0033 + +/* 0x0034 - 0x0034 - reserved */ + +/* 0x0038 - 0x003B - reserved */ + +#define IMR 0x003C +#define IMR_END 0x003D + +#define ISR 0x003E +#define ISR_END 0x003F + +#define TCR 0x0040 +#define TCR_END 0x0043 + +#define RCR 0x0044 +#define RCR_END 0x0047 + +#define TimerInt 0x0048 +#define TimerInt_END 0x004B + +#define TBDA 0x004C +#define TBDA_END 0x004F + +#define CR9346 0x0050 + +#define CONFIG0 0x0051 +#define CONFIG1 0x0052 +#define CONFIG2 0x0053 + +#define ANA_PARAM 0x0054 +#define ANA_PARAM_END 0x0x0057 + +#define MSR 0x0058 + +#define CONFIG3 0x0059 +#define CONFIG4 0x005A + +#define TESTR 0x005B + +/* 0x005C - 0x005D - reserved */ +#define TFPC_AC 0x005C +#define PSR 0x005E + +#define SCR 0x005F + +/* 0x0060 - 0x006F - reserved */ +#define ANA_PARAM2 0x0060 +#define ANA_PARAM2_END 0x0063 + +#define BcnIntv 0x0070 +#define BcnItv_END 0x0071 + +#define AtimWnd 0x0072 +#define AtimWnd_END 0x0073 + +#define BintrItv 0x0074 +#define BintrItv_END 0x0075 + +#define AtimtrItv 0x0076 +#define AtimtrItv_END 0x0077 + +#define PhyDelay 0x0078 + +//#define CRCount 0x0079 + +#define AckTimeOutReg 0x79 // ACK timeout register, in unit of 4 us. +/* 0x007A - 0x007B - reserved */ +#define BBAddr 0x007C + + +#define PhyAddr 0x007C +#define PhyDataW 0x007D +#define PhyDataR 0x007E +#define RF_Ready 0x007F + +#define PhyCFG 0x0080 +#define PhyCFG_END 0x0083 + +/* following are for rtl8185 */ +#define RFPinsOutput 0x80 +#define RFPinsEnable 0x82 +#define RF_TIMING 0x8c +#define RFPinsSelect 0x84 +#define ANAPARAM2 0x60 +#define RF_PARA 0x88 +#define RFPinsInput 0x86 +#define GP_ENABLE 0x90 +#define GPIO 0x91 +#define HSSI_PARA 0x94 // HSS Parameter +#define SW_CONTROL_GPIO 0x400 +#define CCK_TXAGC 0x9d +#define OFDM_TXAGC 0x9e +#define ANTSEL 0x9f +#define TXAGC_CTL_PER_PACKET_ANT_SEL 0x02 +#define WPA_CONFIG 0xb0 +#define TX_AGC_CTL 0x9c +#define TX_AGC_CTL_PER_PACKET_TXAGC 0x01 +#define TX_AGC_CTL_PERPACKET_GAIN_SHIFT 0 +#define TX_AGC_CTL_PERPACKET_ANTSEL_SHIFT 1 +#define TX_AGC_CTL_FEEDBACK_ANT 2 +#define RESP_RATE 0x34 +#define SIFS 0xb4 +#define DIFS 0xb5 +#define EIFS_8187 0x35 +#define EIFS_8187B 0x2D +#define SLOT 0xb6 +#define CW_VAL 0xbd +#define CW_CONF 0xbc +#define CW_CONF_PERPACKET_RETRY_LIMIT 0x02 +#define CW_CONF_PERPACKET_CW 0x01 +#define CW_CONF_PERPACKET_RETRY_SHIFT 1 +#define CW_CONF_PERPACKET_CW_SHIFT 0 +#define MAX_RESP_RATE_SHIFT 4 +#define MIN_RESP_RATE_SHIFT 0 +#define RATE_FALLBACK 0xbe +#define RATE_FALLBACK_CTL_ENABLE 0x80 +#define RATE_FALLBACK_CTL_AUTO_STEP0 0x00 + +#define ARFR 0x1E0 // Auto Rate Fallback Register (0x1e0 ~ 0x1e2) +#define RMS 0x1EC // Rx Max Pacetk Size (0x1ec[0:12]) + +/* + * 0x0084 - 0x00D3 is selected to page 1 when PSEn bit (bit0, PSR) + * is set to 1 + */ + +#define Wakeup0 0x0084 +#define Wakeup0_END 0x008B + +#define Wakeup1 0x008C +#define Wakeup1_END 0x0093 + +#define Wakeup2LD 0x0094 +#define Wakeup2LD_END 0x009B +#define Wakeup2HD 0x009C +#define Wakeup2HD_END 0x00A3 + +#define Wakeup3LD 0x00A4 +#define Wakeup3LD_END 0x00AB +#define Wakeup3HD 0x00AC +#define Wakeup3HD_END 0x00B3 + +#define Wakeup4LD 0x00B4 +#define Wakeup4LD_END 0x00BB +#define Wakeup4HD 0x00BC +#define Wakeup4HD_END 0x00C3 + +#define CRC0 0x00C4 +#define CRC0_END 0x00C5 +#define CRC1 0x00C6 +#define CRC1_END 0x00C7 +#define CRC2 0x00C8 +#define CRC2_END 0x00C9 +#define CRC3 0x00CA +#define CRC3_END 0x00CB +#define CRC4 0x00CC +#define CRC4_END 0x00CD + +/* 0x00CE - 0x00D3 - reserved */ + + + +/* + * 0x0084 - 0x00D3 is selected to page 0 when PSEn bit (bit0, PSR) + * is set to 0 + */ + +/* 0x0084 - 0x008F - reserved */ + +#define DK0 0x0090 +#define DK0_END 0x009F +#define DK1 0x00A0 +#define DK1_END 0x00AF +#define DK2 0x00B0 +#define DK2_END 0x00BF +#define DK3 0x00C0 +#define DK3_END 0x00CF + +#define GPO 0x90 +#define GPE 0x91 +#define GPI 0x92 + +#define RFTiming 0x008C +#define ACM_CONTROL 0x00BF // ACM Control Registe +#define INT_MIG 0x00E2 // Interrupt Migration (0xE2 ~ 0xE3) +#define TID_AC_MAP 0x00E8 // TID to AC Mapping Register + +#define AC_VO_PARAM 0x00F0 // AC_VO Parameters Record +#define AC_VI_PARAM 0x00F4 // AC_VI Parameters Record +#define AC_BE_PARAM 0x00F8 // AC_BE Parameters Record +#define AC_BK_PARAM 0x00FC // AC_BK Parameters Record + +/* 0x00D0 - 0x00D3 - reserved */ +#define CCK_FALSE_ALARM 0x00D0 +#define OFDM_FALSE_ALARM 0x00D2 + + +/* 0x00D4 - 0x00D7 - reserved */ + +#define CONFIG5 0x00D8 + +#define TPPoll 0x00D9 + +/* 0x00DA - 0x00DB - reserved */ + +#define CWR 0x00DC +#define CWR_END 0x00DD + +#define RetryCTR 0x00DE + +/* 0x00DF - 0x00E3 - reserved */ + +#define RDSAR 0x00E4 +#define RDSAR_END 0x00E7 + +/* 0x00E8 - 0x00EF - reserved */ +#define ANA_PARAM3 0x00EE + +#define FER 0x00F0 +#define FER_END 0x00F3 + +#define FEMR 0x1D4 // Function Event Mask register (0xf4 ~ 0xf7) +//#define FEMR 0x00F4 +#define FEMR_END 0x00F7 + +#define FPSR 0x00F8 +#define FPSR_END 0x00FB + +#define FFER 0x00FC +#define FFER_END 0x00FF + +/* + * 0x0000 - 0x00ff is selected to page 0 when PSEn bit (bit0, PSR) + * is set to 2 + */ +#define RFSW_CTRL 0x272 // 0x272-0x273. + + + +//---------------------------------------------------------------------------- +// 8187B AC_XX_PARAM bits +//---------------------------------------------------------------------------- +#define AC_PARAM_TXOP_LIMIT_OFFSET 16 +#define AC_PARAM_ECW_MAX_OFFSET 12 +#define AC_PARAM_ECW_MIN_OFFSET 8 +#define AC_PARAM_AIFS_OFFSET 0 + +//---------------------------------------------------------------------------- +// 8187B ACM_CONTROL bits (Offset 0xBF, 1 Byte) +//---------------------------------------------------------------------------- +#define VOQ_ACM_EN (0x01 << 7) //BIT7 +#define VIQ_ACM_EN (0x01 << 6) //BIT6 +#define BEQ_ACM_EN (0x01 << 5) //BIT5 +#define ACM_HW_EN (0x01 << 4) //BIT4 +#define TXOPSEL (0x01 << 3) //BIT3 +#define VOQ_ACM_CTL (0x01 << 2) //BIT2 // Set to 1 when AC_VO used time reaches or exceeds the admitted time +#define VIQ_ACM_CTL (0x01 << 1) //BIT1 // Set to 1 when AC_VI used time reaches or exceeds the admitted time +#define BEQ_ACM_CTL (0x01 << 0) //BIT0 // Set to 1 when AC_BE used time reaches or exceeds the admitted time + +//---------------------------------------------------------------------------- +// 8187B RF pins related setting (offset 0xFF80-0xFF87,) +//---------------------------------------------------------------------------- +#define TR_SW_MASK_TX_8187 BIT5 +#define TR_SW_MASK_RX_8187 BIT6 +#define TR_SW_MASK_8187 (TR_SW_MASK_TX_8187 | TR_SW_MASK_RX_8187) + +/* + * Bitmasks for specific register functions. + * Names are derived from the register name and function name. + * + * _[] + * + * this leads to some awkward names... + */ + +#define BRSR_BPLCP ((1<< 8)) +#define BRSR_MBR ((1<< 1)|(1<< 0)) +#define BRSR_MBR_8185 ((1<< 11)|(1<< 10)|(1<< 9)|(1<< 8)|(1<< 7)|(1<< 6)|(1<< 5)|(1<< 4)|(1<< 3)|(1<< 2)|(1<< 1)|(1<< 0)) +#define BRSR_MBR0 ((1<< 0)) +#define BRSR_MBR1 ((1<< 1)) + +#define CR_RST ((1<< 4)) +#define CR_RE ((1<< 3)) +#define CR_TE ((1<< 2)) +#define CR_MulRW ((1<< 0)) + +#define IMR_TXFOVW ((1<<15)) +#define IMR_TimeOut ((1<<14)) +#define IMR_BcnInt ((1<<13)) +#define IMR_ATIMInt ((1<<12)) +#define IMR_TBDER ((1<<11)) +#define IMR_TBDOK ((1<<10)) +#define IMR_THPDER ((1<< 9)) +#define IMR_THPDOK ((1<< 8)) +#define IMR_TNPDER ((1<< 7)) +#define IMR_TNPDOK ((1<< 6)) +#define IMR_RXFOVW ((1<< 5)) +#define IMR_RDU ((1<< 4)) +#define IMR_TLPDER ((1<< 3)) +#define IMR_TLPDOK ((1<< 2)) +#define IMR_RER ((1<< 1)) +#define IMR_ROK ((1<< 0)) + +#define ISR_TXFOVW ((1<<15)) +#define ISR_TimeOut ((1<<14)) +#define ISR_BcnInt ((1<<13)) +#define ISR_ATIMInt ((1<<12)) +#define ISR_TBDER ((1<<11)) +#define ISR_TBDOK ((1<<10)) +#define ISR_THPDER ((1<< 9)) +#define ISR_THPDOK ((1<< 8)) +#define ISR_TNPDER ((1<< 7)) +#define ISR_TNPDOK ((1<< 6)) +#define ISR_RXFOVW ((1<< 5)) +#define ISR_RDU ((1<< 4)) +#define ISR_TLPDER ((1<< 3)) +#define ISR_TLPDOK ((1<< 2)) +#define ISR_RER ((1<< 1)) +#define ISR_ROK ((1<< 0)) + +#define HW_VERID_R8180_F 3 +#define HW_VERID_R8180_ABCD 2 +#define HW_VERID_R8185_ABC 4 +#define HW_VERID_R8185_D 5 + +#define TCR_DurProcMode ((1<<30)) +#define TCR_DISReqQsize ((1<<28)) +#define TCR_HWVERID_MASK ((1<<27)|(1<<26)|(1<<25)) +#define TCR_HWVERID_SHIFT 25 +#define TCR_SWPLCPLEN ((1<<24)) +#define TCR_PLCP_LEN TCR_SAT // rtl8180 +#define TCR_MXDMA_MASK ((1<<23)|(1<<22)|(1<<21)) +#define TCR_MXDMA_1024 6 +#define TCR_MXDMA_2048 7 +#define TCR_MXDMA_SHIFT 21 +#define TCR_DISCW ((1<<20)) +#define TCR_ICV ((1<<19)) +#define TCR_LBK ((1<<18)|(1<<17)) +#define TCR_LBK1 ((1<<18)) +#define TCR_LBK0 ((1<<17)) +#define TCR_CRC ((1<<16)) +#define TCR_SRL_MASK ((1<<15)|(1<<14)|(1<<13)|(1<<12)|(1<<11)|(1<<10)|(1<<9)|(1<<8)) +#define TCR_LRL_MASK ((1<<0)|(1<<1)|(1<<2)|(1<<3)|(1<<4)|(1<<5)|(1<<6)|(1<<7)) +#define TCR_PROBE_NOTIMESTAMP_SHIFT 29 //rtl8185 + +#define RCR_ONLYERLPKT ((1<<31)) +#define RCR_CS_SHIFT 29 +#define RCR_CS_MASK ((1<<30) | (1<<29)) +#define RCR_ENMARP ((1<<28)) +#define RCR_CBSSID ((1<<23)) +#define RCR_APWRMGT ((1<<22)) +#define RCR_ADD3 ((1<<21)) +#define RCR_AMF ((1<<20)) +#define RCR_ACF ((1<<19)) +#define RCR_ADF ((1<<18)) +#define RCR_RXFTH ((1<<15)|(1<<14)|(1<<13)) +#define RCR_RXFTH2 ((1<<15)) +#define RCR_RXFTH1 ((1<<14)) +#define RCR_RXFTH0 ((1<<13)) +#define RCR_AICV ((1<<12)) +#define RCR_MXDMA ((1<<10)|(1<< 9)|(1<< 8)) +#define RCR_MXDMA2 ((1<<10)) +#define RCR_MXDMA1 ((1<< 9)) +#define RCR_MXDMA0 ((1<< 8)) +#define RCR_9356SEL ((1<< 6)) +#define RCR_ACRC32 ((1<< 5)) +#define RCR_AB ((1<< 3)) +#define RCR_AM ((1<< 2)) +#define RCR_APM ((1<< 1)) +#define RCR_AAP ((1<< 0)) + +#define CR9346_EEM ((1<<7)|(1<<6)) +#define CR9346_EEM1 ((1<<7)) +#define CR9346_EEM0 ((1<<6)) +#define CR9346_EECS ((1<<3)) +#define CR9346_EESK ((1<<2)) +#define CR9346_EED1 ((1<<1)) +#define CR9346_EED0 ((1<<0)) + +#define CONFIG0_WEP104 ((1<<6)) +#define CONFIG0_LEDGPO_En ((1<<4)) +#define CONFIG0_Aux_Status ((1<<3)) +#define CONFIG0_GL ((1<<1)|(1<<0)) +#define CONFIG0_GL1 ((1<<1)) +#define CONFIG0_GL0 ((1<<0)) + +#define CONFIG1_LEDS ((1<<7)|(1<<6)) +#define CONFIG1_LEDS1 ((1<<7)) +#define CONFIG1_LEDS0 ((1<<6)) +#define CONFIG1_LWACT ((1<<4)) +#define CONFIG1_MEMMAP ((1<<3)) +#define CONFIG1_IOMAP ((1<<2)) +#define CONFIG1_VPD ((1<<1)) +#define CONFIG1_PMEn ((1<<0)) + +#define CONFIG2_LCK ((1<<7)) +#define CONFIG2_ANT ((1<<6)) +#define CONFIG2_DPS ((1<<3)) +#define CONFIG2_PAPE_sign ((1<<2)) +#define CONFIG2_PAPE_time ((1<<1)|(1<<0)) +#define CONFIG2_PAPE_time1 ((1<<1)) +#define CONFIG2_PAPE_time0 ((1<<0)) + +#define CONFIG3_GNTSel ((1<<7)) +#define CONFIG3_PARM_En ((1<<6)) +#define CONFIG3_Magic ((1<<5)) +#define CONFIG3_CardB_En ((1<<3)) +#define CONFIG3_CLKRUN_En ((1<<2)) +#define CONFIG3_FuncRegEn ((1<<1)) +#define CONFIG3_FBtbEn ((1<<0)) + +#define CONFIG4_VCOPDN ((1<<7)) +#define CONFIG4_PWROFF ((1<<6)) +#define CONFIG4_PWRMGT ((1<<5)) +#define CONFIG4_LWPME ((1<<4)) +#define CONFIG4_LWPTN ((1<<2)) +#define CONFIG4_RFTYPE ((1<<1)|(1<<0)) +#define CONFIG4_RFTYPE1 ((1<<1)) +#define CONFIG4_RFTYPE0 ((1<<0)) + +#define CONFIG5_TX_FIFO_OK ((1<<7)) +#define CONFIG5_RX_FIFO_OK ((1<<6)) +#define CONFIG5_CALON ((1<<5)) +#define CONFIG5_EACPI ((1<<2)) +#define CONFIG5_LANWake ((1<<1)) +#define CONFIG5_PME_STS ((1<<0)) + +#define MSR_LINK_MASK ((1<<2)|(1<<3)) +#define MSR_LINK_MANAGED 2 +#define MSR_LINK_NONE 0 +#define MSR_LINK_SHIFT 2 +#define MSR_LINK_ADHOC 1 +#define MSR_LINK_MASTER 3 +#define MSR_LINK_ENEDCA (1<<4) + +#define PSR_GPO ((1<<7)) +#define PSR_GPI ((1<<6)) +#define PSR_LEDGPO1 ((1<<5)) +#define PSR_LEDGPO0 ((1<<4)) +#define PSR_UWF ((1<<1)) +#define PSR_PSEn ((1<<0)) + +#define SCR_KM ((1<<5)|(1<<4)) +#define SCR_KM1 ((1<<5)) +#define SCR_KM0 ((1<<4)) +#define SCR_TXSECON ((1<<1)) +#define SCR_RXSECON ((1<<0)) + +#define BcnItv_BcnItv (0x01FF) + +#define AtimWnd_AtimWnd (0x01FF) + +#define BintrItv_BintrItv (0x01FF) + +#define AtimtrItv_AtimtrItv (0x01FF) + +#define PhyDelay_PhyDelay ((1<<2)|(1<<1)|(1<<0)) + +#define TPPoll_BQ ((1<<7)) +#define TPPoll_HPQ ((1<<6)) +#define TPPoll_NPQ ((1<<5)) +#define TPPoll_LPQ ((1<<4)) +#define TPPoll_SBQ ((1<<3)) +#define TPPoll_SHPQ ((1<<2)) +#define TPPoll_SNPQ ((1<<1)) +#define TPPoll_SLPQ ((1<<0)) + +#define CWR_CW (0x01FF) + +#define FER_INTR ((1<<15)) +#define FER_GWAKE ((1<< 4)) + +#define FEMR_INTR ((1<<15)) +#define FEMR_WKUP ((1<<14)) +#define FEMR_GWAKE ((1<< 4)) + +#define FPSR_INTR ((1<<15)) +#define FPSR_GWAKE ((1<< 4)) + +#define FFER_INTR ((1<<15)) +#define FFER_GWAKE ((1<< 4)) + + +//---------------------------------------------------------------------------- +// 818xB AnaParm & AnaParm2 Register +//---------------------------------------------------------------------------- +/* +#ifdef RTL8185B_FPGA +#define ANAPARM_FPGA_ON 0xa0000b59 +//#define ANAPARM_FPGA_OFF +#define ANAPARM2_FPGA_ON 0x860dec11 +//#define ANAPARM2_FPGA_OFF +#else //ASIC +*/ +#define ANAPARM_ASIC_ON 0x45090658 +//#define ANAPARM_ASIC_OFF +#define ANAPARM2_ASIC_ON 0x727f3f52 +//#define ANAPARM2_ASIC_OFF +//#endif +//by amy for power save +#define RF_CHANGE_BY_SW BIT31 +#define RF_CHANGE_BY_HW BIT30 +#define RF_CHANGE_BY_PS BIT29 +#define RF_CHANGE_BY_IPS BIT28 +#define ANAPARM_ASIC_ON 0x45090658 +#define ANAPARM2_ASIC_ON 0x727f3f52 + +#define ANAPARM_ON ANAPARM_ASIC_ON +#define ANAPARM2_ON ANAPARM2_ASIC_ON +#define TFPC 0x5C // Tx FIFO Packet Count for BK, BE, VI, VO queues (2 bytes) +#define Config4_PowerOff BIT6 // Turn ON/Off RF Power(RFMD) +#define ANAPARM_OFF 0x51480658 +#define ANAPARM2_OFF 0x72003f70 +//by amy for power save + +#define MAX_DOZE_WAITING_TIMES_87B 500 + +#endif diff -Nur linux-2.6.30.5.orig/drivers/net/wireless/rtl8187b/r8180_pm.c linux-2.6.30.5/drivers/net/wireless/rtl8187b/r8180_pm.c --- linux-2.6.30.5.orig/drivers/net/wireless/rtl8187b/r8180_pm.c 1970-01-01 01:00:00.000000000 +0100 +++ linux-2.6.30.5/drivers/net/wireless/rtl8187b/r8180_pm.c 2009-08-23 19:01:04.000000000 +0200 @@ -0,0 +1,99 @@ +/* + Power management interface routines. + Written by Mariusz Matuszek. + This code is currently just a placeholder for later work and + does not do anything useful. + + This is part of rtl8180 OpenSource driver. + Copyright (C) Andrea Merello 2004 + Released under the terms of GPL (General Public Licence) +*/ + +#ifdef CONFIG_RTL8180_PM + + +#include "r8180_hw.h" +#include "r8180_pm.h" +#include "r8187.h" +int rtl8180_save_state (struct pci_dev *dev, u32 state) +{ + printk(KERN_NOTICE "r8180 save state call (state %u).\n", state); + return(-EAGAIN); +} + +//netif_running is set to 0 before system call rtl8180_close, +//netif_running is set to 1 before system call rtl8180_open, +//if open success it will not change, or it change to 0; +int rtl8187_suspend (struct usb_interface *intf, pm_message_t state) +{ + struct r8180_priv *priv; +#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0) + struct net_device *dev = usb_get_intfdata(intf); +#else + //struct net_device *dev = (struct net_device *)ptr; +#endif + + printk("====>%s \n", __func__); + priv=ieee80211_priv(dev); + + if(dev) { +#ifdef POLLING_METHOD_FOR_RADIO + del_timer_sync(&priv->gpio_polling_timer); + cancel_delayed_work(&priv->ieee80211->GPIOChangeRFWorkItem); + priv->polling_timer_on = 0; +#endif + if (!netif_running(dev)) { + //printk(KERN_WARNING "UI or other close dev before suspend, go out suspend function\n"); + return 0; + } + + dev->netdev_ops->ndo_stop(dev); + netif_device_detach(dev); + } + return 0; +} + + +int rtl8187_resume (struct usb_interface *intf) +{ + struct r8180_priv *priv; +#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0) + struct net_device *dev = usb_get_intfdata(intf); +#else + //struct net_device *dev = (struct net_device *)ptr; +#endif + + printk("====>%s \n", __func__); + priv=ieee80211_priv(dev); + + if(dev) { +#ifdef POLLING_METHOD_FOR_RADIO + if(priv->polling_timer_on == 0){//add for S3/S4 + gpio_change_polling((unsigned long)dev); + } +#endif + if (!netif_running(dev)){ + //printk(KERN_WARNING "UI or other close dev before suspend, go out resume function\n"); + return 0; + } + + netif_device_attach(dev); + dev->netdev_ops->ndo_open(dev); + } + + return 0; +} + + +int rtl8180_enable_wake (struct pci_dev *dev, u32 state, int enable) +{ + + //printk(KERN_NOTICE "r8180 enable wake call (state %u, enable %d).\n", + // state, enable); + return 0; + //return(-EAGAIN); +} + + + +#endif //CONFIG_RTL8180_PM diff -Nur linux-2.6.30.5.orig/drivers/net/wireless/rtl8187b/r8180_pm.h linux-2.6.30.5/drivers/net/wireless/rtl8187b/r8180_pm.h --- linux-2.6.30.5.orig/drivers/net/wireless/rtl8187b/r8180_pm.h 1970-01-01 01:00:00.000000000 +0100 +++ linux-2.6.30.5/drivers/net/wireless/rtl8187b/r8180_pm.h 2009-08-23 19:01:04.000000000 +0200 @@ -0,0 +1,28 @@ +/* + Power management interface routines. + Written by Mariusz Matuszek. + This code is currently just a placeholder for later work and + does not do anything useful. + + This is part of rtl8180 OpenSource driver. + Copyright (C) Andrea Merello 2004 + Released under the terms of GPL (General Public Licence) + +*/ + +#ifdef CONFIG_RTL8180_PM + +#ifndef R8180_PM_H +#define R8180_PM_H + +#include +#include + +int rtl8180_save_state (struct pci_dev *dev, u32 state); +int rtl8187_suspend (struct usb_interface *intf,pm_message_t state); +int rtl8187_resume (struct usb_interface *intf); +int rtl8180_enable_wake (struct pci_dev *dev, u32 state, int enable); + +#endif //R8180_PM_H + +#endif // CONFIG_RTL8180_PM diff -Nur linux-2.6.30.5.orig/drivers/net/wireless/rtl8187b/r8180_rtl8225.c linux-2.6.30.5/drivers/net/wireless/rtl8187b/r8180_rtl8225.c --- linux-2.6.30.5.orig/drivers/net/wireless/rtl8187b/r8180_rtl8225.c 1970-01-01 01:00:00.000000000 +0100 +++ linux-2.6.30.5/drivers/net/wireless/rtl8187b/r8180_rtl8225.c 2009-08-23 19:01:04.000000000 +0200 @@ -0,0 +1,1007 @@ +/* + This is part of the rtl8180-sa2400 driver + released under the GPL (See file COPYING for details). + Copyright (c) 2005 Andrea Merello + + This files contains programming code for the rtl8225 + radio frontend. + + *Many* thanks to Realtek Corp. for their great support! + +*/ + + + +#include "r8180_hw.h" +#include "r8180_rtl8225.h" +#ifdef ENABLE_DOT11D +#include "dot11d.h" +#endif + +#define USE_8051_3WIRE 1 + +u8 rtl8225_threshold[]={ + 0x8d, 0x8d, 0x8d, 0x8d, 0x9d, 0xad, 0xbd, +}; + +u8 rtl8225_gain[]={ + 0x23,0x88,0x7c,0xa5,// -82dbm + 0x23,0x88,0x7c,0xb5,// -82dbm + 0x23,0x88,0x7c,0xc5,// -82dbm + 0x33,0x80,0x79,0xc5,// -78dbm + 0x43,0x78,0x76,0xc5,// -74dbm + 0x53,0x60,0x73,0xc5,// -70dbm + 0x63,0x58,0x70,0xc5,// -66dbm +}; + +u16 rtl8225bcd_rxgain[]={ + 0x0400, 0x0401, 0x0402, 0x0403, 0x0404, 0x0405, 0x0408, 0x0409, + 0x040a, 0x040b, 0x0502, 0x0503, 0x0504, 0x0505, 0x0540, 0x0541, + 0x0542, 0x0543, 0x0544, 0x0545, 0x0580, 0x0581, 0x0582, 0x0583, + 0x0584, 0x0585, 0x0588, 0x0589, 0x058a, 0x058b, 0x0643, 0x0644, + 0x0645, 0x0680, 0x0681, 0x0682, 0x0683, 0x0684, 0x0685, 0x0688, + 0x0689, 0x068a, 0x068b, 0x068c, 0x0742, 0x0743, 0x0744, 0x0745, + 0x0780, 0x0781, 0x0782, 0x0783, 0x0784, 0x0785, 0x0788, 0x0789, + 0x078a, 0x078b, 0x078c, 0x078d, 0x0790, 0x0791, 0x0792, 0x0793, + 0x0794, 0x0795, 0x0798, 0x0799, 0x079a, 0x079b, 0x079c, 0x079d, + 0x07a0, 0x07a1, 0x07a2, 0x07a3, 0x07a4, 0x07a5, 0x07a8, 0x07a9, + 0x07aa, 0x07ab, 0x07ac, 0x07ad, 0x07b0, 0x07b1, 0x07b2, 0x07b3, + 0x07b4, 0x07b5, 0x07b8, 0x07b9, 0x07ba, 0x07bb, 0x07bb + +}; + + + +u8 rtl8225_tx_gain_cck_ofdm[]={ + 0x02,0x06,0x0e,0x1e,0x3e,0x7e +}; + + +u8 rtl8225_tx_power_ofdm[]={ + 0x80,0x90,0xa2,0xb5,0xcb,0xe4 +}; + + +u8 rtl8225_tx_power_cck_ch14[]={ + 0x18,0x17,0x15,0x0c,0x00,0x00,0x00,0x00, + 0x1b,0x1a,0x17,0x0e,0x00,0x00,0x00,0x00, + 0x1f,0x1e,0x1a,0x0f,0x00,0x00,0x00,0x00, + 0x22,0x21,0x1d,0x11,0x00,0x00,0x00,0x00, + 0x26,0x25,0x21,0x13,0x00,0x00,0x00,0x00, + 0x2b,0x2a,0x25,0x15,0x00,0x00,0x00,0x00 +}; + + +u8 rtl8225_tx_power_cck[]={ + 0x18,0x17,0x15,0x11,0x0c,0x08,0x04,0x02, + 0x1b,0x1a,0x17,0x13,0x0e,0x09,0x04,0x02, + 0x1f,0x1e,0x1a,0x15,0x10,0x0a,0x05,0x02, + 0x22,0x21,0x1d,0x18,0x11,0x0b,0x06,0x02, + 0x26,0x25,0x21,0x1b,0x14,0x0d,0x06,0x03, + 0x2b,0x2a,0x25,0x1e,0x16,0x0e,0x07,0x03 +}; + +u8 rtl8225_agc[]={ + 0x9e,0x9e,0x9e,0x9e,0x9e,0x9e,0x9e,0x9e,0x9d,0x9c,0x9b,0x9a,0x99,0x98,0x97,0x96, + 0x95,0x94,0x93,0x92,0x91,0x90,0x8f,0x8e,0x8d,0x8c,0x8b,0x8a,0x89,0x88,0x87,0x86, + 0x85,0x84,0x83,0x82,0x81,0x80,0x3f,0x3e,0x3d,0x3c,0x3b,0x3a,0x39,0x38,0x37,0x36, + 0x35,0x34,0x33,0x32,0x31,0x30,0x2f,0x2e,0x2d,0x2c,0x2b,0x2a,0x29,0x28,0x27,0x26, + 0x25,0x24,0x23,0x22,0x21,0x20,0x1f,0x1e,0x1d,0x1c,0x1b,0x1a,0x19,0x18,0x17,0x16, + 0x15,0x14,0x13,0x12,0x11,0x10,0x0f,0x0e,0x0d,0x0c,0x0b,0x0a,0x09,0x08,0x07,0x06, + 0x05,0x04,0x03,0x02,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01, + 0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01, +}; + +u32 rtl8225_chan[] = { + 0, //dummy channel 0 + 0x085c, //1 + 0x08dc, //2 + 0x095c, //3 + 0x09dc, //4 + 0x0a5c, //5 + 0x0adc, //6 + 0x0b5c, //7 + 0x0bdc, //8 + 0x0c5c, //9 + 0x0cdc, //10 + 0x0d5c, //11 + 0x0ddc, //12 + 0x0e5c, //13 + //0x0f5c, //14 + 0x0f72, // 14 +}; + +void rtl8225_set_gain(struct net_device *dev, short gain) +{ + write_phy_ofdm(dev, 0x0d, rtl8225_gain[gain * 4]); + write_phy_ofdm(dev, 0x1b, rtl8225_gain[gain * 4 + 2]); + write_phy_ofdm(dev, 0x1d, rtl8225_gain[gain * 4 + 3]); + write_phy_ofdm(dev, 0x23, rtl8225_gain[gain * 4 + 1]); + +} + + +void write_rtl8225(struct net_device *dev, u8 adr, u16 data) +{ +//in windows the delays in this function was del from 85 to 87, +//here we mod to sleep, or The CPU occupany is too hight. LZM 31/10/2008 + +#ifdef USE_8051_3WIRE + + struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev); + struct usb_device *udev = priv->udev; + //u8 bit; + //u16 wReg80, wReg82, wReg84; + u16 wReg80, wReg84; + + wReg80 = read_nic_word(dev, RFPinsOutput); + wReg80 &= 0xfff3; +// wReg82 = read_nic_word(dev, RFPinsEnable); + wReg84 = read_nic_word(dev, RFPinsSelect); + // 3-wire should be controled by HW when we finish SW 3-wire programming. 2005.08.10, by rcnjko. + //wReg84 &= 0xfff0; + wReg84 &= 0xfff8; //modified by david according to windows segment code. + + // We must set SW enabled before terminating HW 3-wire, 2005.07.29, by rcnjko. +// write_nic_word(dev, RFPinsEnable, (wReg82|0x0007)); // Set To Output Enable + write_nic_word(dev, RFPinsSelect, (wReg84|0x0007)); // Set To SW Switch +// force_pci_posting(dev); +// udelay(10); // + + write_nic_word(dev, 0x80, (BB_HOST_BANG_EN|wReg80)); // Set SI_EN (RFLE) +// force_pci_posting(dev); +// udelay(2); + //twreg.struc.enableB = 0; + write_nic_word(dev, 0x80, (wReg80)); // Clear SI_EN (RFLE) +// force_pci_posting(dev); +// udelay(10); + + usb_control_msg(udev, usb_sndctrlpipe(udev, 0), + RTL8187_REQ_SET_REGS, RTL8187_REQT_WRITE, + adr, 0x8225, &data, 2, HZ / 2); + + // write_nic_word(dev, 0x80, (BB_HOST_BANG_EN|wReg80)); +// force_pci_posting(dev); +// udelay(10); + + write_nic_word(dev, 0x80, (wReg80|0x0004)); + write_nic_word(dev, 0x84, (wReg84|0x0000));// Set To SW Switch + + if(priv->card_type == USB) + ;// msleep(2); + else + ; // rtl8185_rf_pins_enable(dev); + +#else + int i; + u16 out,select; + u8 bit; + u32 bangdata = (data << 4) | (adr & 0xf); + struct r8180_priv *priv = ieee80211_priv(dev); + + out = read_nic_word(dev, RFPinsOutput) & 0xfff3; + + write_nic_word(dev,RFPinsEnable, + (read_nic_word(dev,RFPinsEnable) | 0x7)); + + select = read_nic_word(dev, RFPinsSelect); + + write_nic_word(dev, RFPinsSelect, select | 0x7 | + ((priv->card_type == USB) ? 0 : SW_CONTROL_GPIO)); + +// force_pci_posting(dev); +// udelay(10); + + write_nic_word(dev, RFPinsOutput, out | BB_HOST_BANG_EN );//| 0x1fff); + +// force_pci_posting(dev); +// udelay(2); + + write_nic_word(dev, RFPinsOutput, out); + +// force_pci_posting(dev); +// udelay(10); + + + for(i=15; i>=0;i--){ + + bit = (bangdata & (1<> i; + + write_nic_word(dev, RFPinsOutput, bit | out); + + write_nic_word(dev, RFPinsOutput, bit | out | BB_HOST_BANG_CLK); + write_nic_word(dev, RFPinsOutput, bit | out | BB_HOST_BANG_CLK); + + i--; + bit = (bangdata & (1<> i; + + write_nic_word(dev, RFPinsOutput, bit | out | BB_HOST_BANG_CLK); + write_nic_word(dev, RFPinsOutput, bit | out | BB_HOST_BANG_CLK); + + write_nic_word(dev, RFPinsOutput, bit | out); + + } + + write_nic_word(dev, RFPinsOutput, out | BB_HOST_BANG_EN); + +// force_pci_posting(dev); +// udelay(10); + + write_nic_word(dev, RFPinsOutput, out | + ((priv->card_type == USB) ? 4 : BB_HOST_BANG_EN)); + + write_nic_word(dev, RFPinsSelect, select | + ((priv->card_type == USB) ? 0 : SW_CONTROL_GPIO)); + + if(priv->card_type == USB) + ;// msleep(2); + else +// rtl8185_rf_pins_enable(dev); +#endif +} + + +void write_rtl8225_patch(struct net_device *dev, u8 adr, u16 data) +{ + + int i; + u16 out,select; + u8 bit; + u32 bangdata = (data << 4) | (adr & 0xf); + struct r8180_priv *priv = ieee80211_priv(dev); + + out = read_nic_word(dev, RFPinsOutput) & 0xfff3; + + write_nic_word(dev,RFPinsEnable, + (read_nic_word(dev,RFPinsEnable) | 0x7)); + + select = read_nic_word(dev, RFPinsSelect); + + write_nic_word(dev, RFPinsSelect, select | 0x7 | + ((priv->card_type == USB) ? 0 : SW_CONTROL_GPIO)); + + force_pci_posting(dev); + udelay(10); + + write_nic_word(dev, RFPinsOutput, out | BB_HOST_BANG_EN );//| 0x1fff); + + force_pci_posting(dev); + udelay(2); + + write_nic_word(dev, RFPinsOutput, out); + + force_pci_posting(dev); + udelay(10); + + for(i=15; i>=0;i--){ + + bit = (bangdata & (1<> i; + + write_nic_word(dev, RFPinsOutput, bit | out); + + write_nic_word(dev, RFPinsOutput, bit | out | BB_HOST_BANG_CLK); + write_nic_word(dev, RFPinsOutput, bit | out | BB_HOST_BANG_CLK); + + i--; + bit = (bangdata & (1<> i; + + write_nic_word(dev, RFPinsOutput, bit | out | BB_HOST_BANG_CLK); + write_nic_word(dev, RFPinsOutput, bit | out | BB_HOST_BANG_CLK); + + write_nic_word(dev, RFPinsOutput, bit | out); + + } + + write_nic_word(dev, RFPinsOutput, out | BB_HOST_BANG_EN); + + force_pci_posting(dev); + udelay(10); + + write_nic_word(dev, RFPinsOutput, out | + ((priv->card_type == USB) ? 4 : BB_HOST_BANG_EN)); + + write_nic_word(dev, RFPinsSelect, select | + ((priv->card_type == USB) ? 0 : SW_CONTROL_GPIO)); + + if(priv->card_type == USB) + mdelay(2); + else + rtl8185_rf_pins_enable(dev); + +} + +void rtl8225_rf_close(struct net_device *dev) +{ + write_rtl8225(dev, 0x4, 0x1f); + + force_pci_posting(dev); + mdelay(1); + + rtl8180_set_anaparam(dev, RTL8225_ANAPARAM_OFF); + rtl8185_set_anaparam2(dev, RTL8225_ANAPARAM2_OFF); +} + +#ifdef ENABLE_DOT11D +// +// Description: +// Map dBm into Tx power index according to +// current HW model, for example, RF and PA, and +// current wireless mode. +// +s8 +DbmToTxPwrIdx( + struct r8180_priv *priv, + WIRELESS_MODE WirelessMode, + s32 PowerInDbm + ) +{ + bool bUseDefault = true; + s8 TxPwrIdx = 0; + +#ifdef CONFIG_RTL818X_S + // + // 071011, SD3 SY: + // OFDM Power in dBm = Index * 0.5 + 0 + // CCK Power in dBm = Index * 0.25 + 13 + // + if(priv->card_8185 >= VERSION_8187S_B) + { + s32 tmp = 0; + + if(WirelessMode == WIRELESS_MODE_G) + { + bUseDefault = false; + tmp = (2 * PowerInDbm); + + if(tmp < 0) + TxPwrIdx = 0; + else if(tmp > 40) // 40 means 20 dBm. + TxPwrIdx = 40; + else + TxPwrIdx = (s8)tmp; + } + else if(WirelessMode == WIRELESS_MODE_B) + { + bUseDefault = false; + tmp = (4 * PowerInDbm) - 52; + + if(tmp < 0) + TxPwrIdx = 0; + else if(tmp > 28) // 28 means 20 dBm. + TxPwrIdx = 28; + else + TxPwrIdx = (s8)tmp; + } + } +#endif + + // + // TRUE if we want to use a default implementation. + // We shall set it to FALSE when we have exact translation formular + // for target IC. 070622, by rcnjko. + // + if(bUseDefault) + { + if(PowerInDbm < 0) + TxPwrIdx = 0; + else if(PowerInDbm > 35) + TxPwrIdx = 35; + else + TxPwrIdx = (u8)PowerInDbm; + } + + return TxPwrIdx; +} +#endif + + +short rtl8225_rf_set_sens(struct net_device *dev, short sens) +{ + if (sens <0 || sens > 6) return -1; + + if(sens > 4) + write_rtl8225(dev, 0x0c, 0x850); + else + write_rtl8225(dev, 0x0c, 0x50); + + sens= 6-sens; + rtl8225_set_gain(dev, sens); + + write_phy_cck(dev, 0x41, rtl8225_threshold[sens]); + return 0; + +} + +void rtl8225_SetTXPowerLevel(struct net_device *dev, short ch) +{ + struct r8180_priv *priv = ieee80211_priv(dev); + + int GainIdx; + int GainSetting; + int i; + u8 power; + u8 *cck_power_table; + u8 max_cck_power_level; + u8 max_ofdm_power_level; + u8 min_ofdm_power_level; + u8 cck_power_level = 0xff & priv->chtxpwr[ch]; + u8 ofdm_power_level = 0xff & priv->chtxpwr_ofdm[ch]; + +#ifdef ENABLE_DOT11D + if(IS_DOT11D_ENABLE(priv->ieee80211) && + IS_DOT11D_STATE_DONE(priv->ieee80211) ) + { + //PRT_DOT11D_INFO pDot11dInfo = GET_DOT11D_INFO(priv->ieee80211); + u8 MaxTxPwrInDbm = DOT11D_GetMaxTxPwrInDbm(priv->ieee80211, ch); + u8 CckMaxPwrIdx = DbmToTxPwrIdx(priv, WIRELESS_MODE_B, MaxTxPwrInDbm); + u8 OfdmMaxPwrIdx = DbmToTxPwrIdx(priv, WIRELESS_MODE_G, MaxTxPwrInDbm); + + //printk("Max Tx Power dBm (%d) => CCK Tx power index : %d, OFDM Tx power index: %d\n", MaxTxPwrInDbm, CckMaxPwrIdx, OfdmMaxPwrIdx); + + //printk("EEPROM channel(%d) => CCK Tx power index: %d, OFDM Tx power index: %d\n", + // ch, cck_power_level, ofdm_power_level); + + if(cck_power_level > CckMaxPwrIdx) + cck_power_level = CckMaxPwrIdx; + if(ofdm_power_level > OfdmMaxPwrIdx) + ofdm_power_level = OfdmMaxPwrIdx; + } + + //priv->CurrentCckTxPwrIdx = cck_power_level; + //priv->CurrentOfdmTxPwrIdx = ofdm_power_level; +#endif + + + if(priv->card_type == USB){ + max_cck_power_level = 11; + max_ofdm_power_level = 25; // 12 -> 25 + min_ofdm_power_level = 10; + }else{ + max_cck_power_level = 35; + max_ofdm_power_level = 35; + min_ofdm_power_level = 0; + } + if( priv->TrSwitchState == TR_SW_TX ) + { + printk("SetTxPowerLevel8187(): Origianl OFDM Tx power level %d\n", ofdm_power_level); + ofdm_power_level -= GetTxOfdmHighPowerBias(dev); + cck_power_level -= GetTxCckHighPowerBias(dev); + printk("SetTxPowerLevel8187(): Adjusted OFDM Tx power level %d for we are in High Power state\n", + ofdm_power_level); + printk("SetTxPowerLevel8187(): Adjusted CCK Tx power level %d for we are in High Power state\n", + cck_power_level); + } + + + + /* CCK power setting */ + if(cck_power_level > max_cck_power_level) + cck_power_level = max_cck_power_level; + GainIdx=cck_power_level % 6; + GainSetting=cck_power_level / 6; + + if(ch == 14) + cck_power_table = rtl8225_tx_power_cck_ch14; + else + cck_power_table = rtl8225_tx_power_cck; + +// if(priv->card_8185 == 1 && priv->card_8185_Bversion ){ + /*Ver B*/ +// write_nic_byte(dev, TX_GAIN_CCK, rtl8225_tx_gain_cck_ofdm[GainSetting]); +// }else{ + /*Ver C - D */ + write_nic_byte(dev, CCK_TXAGC, rtl8225_tx_gain_cck_ofdm[GainSetting]>>1); +// } + + for(i=0;i<8;i++){ + + power = cck_power_table[GainIdx * 8 + i]; + write_phy_cck(dev, 0x44 + i, power); + } + + /* FIXME Is this delay really needeed ? */ + force_pci_posting(dev); + mdelay(1); + + /* OFDM power setting */ +// Old: +// if(ofdm_power_level > max_ofdm_power_level) +// ofdm_power_level = 35; +// ofdm_power_level += min_ofdm_power_level; +// Latest: + if(ofdm_power_level > (max_ofdm_power_level - min_ofdm_power_level)) + ofdm_power_level = max_ofdm_power_level; + else + ofdm_power_level += min_ofdm_power_level; + if(ofdm_power_level > 35) + ofdm_power_level = 35; +// + + GainIdx=ofdm_power_level % 6; + GainSetting=ofdm_power_level / 6; +#if 1 +// if(priv->card_type == USB){ + rtl8185_set_anaparam2(dev,RTL8225_ANAPARAM2_ON); + + write_phy_ofdm(dev,2,0x42); + write_phy_ofdm(dev,6,0); + write_phy_ofdm(dev,8,0); +// } +#endif +// if(priv->card_8185 == 1 && priv->card_8185_Bversion){ +// /*Ver B*/ +// write_nic_byte(dev, TX_GAIN_OFDM, rtl8225_tx_gain_cck_ofdm[GainSetting]); +// }else{ + /*Ver C - D */ + write_nic_byte(dev, OFDM_TXAGC, rtl8225_tx_gain_cck_ofdm[GainSetting]>>1); +// } + + + power = rtl8225_tx_power_ofdm[GainIdx]; + + write_phy_ofdm(dev, 0x5, power); + write_phy_ofdm(dev, 0x7, power); + + force_pci_posting(dev); + mdelay(1); + //write_nic_byte(dev, TX_AGC_CONTROL,4); +} + +void rtl8225_rf_set_chan(struct net_device *dev, short ch) +{ + struct r8180_priv *priv = ieee80211_priv(dev); + short gset = (priv->ieee80211->state == IEEE80211_LINKED && + ieee80211_is_54g(priv->ieee80211->current_network)) || + priv->ieee80211->iw_mode == IW_MODE_MONITOR; + int eifs_addr; + + if(NIC_8187 == priv->card_8187) { + eifs_addr = EIFS_8187; + } else { + eifs_addr = EIFS_8187B; + } + +#ifdef ENABLE_DOT11D + if(!IsLegalChannel(priv->ieee80211, ch) ) + { + printk("channel(%d). is invalide\n", ch); + return; + } +#endif + + rtl8225_SetTXPowerLevel(dev, ch); + + write_rtl8225(dev, 0x7, rtl8225_chan[ch]); + + force_pci_posting(dev); + mdelay(10); + + write_nic_byte(dev,SIFS,0x22);// SIFS: 0x22 + + if(gset) + write_nic_byte(dev,DIFS,20); //DIFS: 20 + else + write_nic_byte(dev,DIFS,0x24); //DIFS: 36 + + if(priv->ieee80211->state == IEEE80211_LINKED && + ieee80211_is_shortslot(priv->ieee80211->current_network)) + write_nic_byte(dev,SLOT,0x9); //SLOT: 9 + + else + write_nic_byte(dev,SLOT,0x14); //SLOT: 20 (0x14) + + + if(gset){ + write_nic_byte(dev,eifs_addr,91 - 20); // EIFS: 91 (0x5B) + write_nic_byte(dev,CW_VAL,0x73); //CW VALUE: 0x37 + //DMESG("using G net params"); + }else{ + write_nic_byte(dev,eifs_addr,91 - 0x24); // EIFS: 91 (0x5B) + write_nic_byte(dev,CW_VAL,0xa5); //CW VALUE: 0x37 + //DMESG("using B net params"); + } + + +} + +void rtl8225_host_pci_init(struct net_device *dev) +{ + write_nic_word(dev, RFPinsOutput, 0x480); + + rtl8185_rf_pins_enable(dev); + + //if(priv->card_8185 == 2 && priv->enable_gpio0 ) /* version D */ + //write_nic_word(dev, RFPinsSelect, 0x88); + //else + write_nic_word(dev, RFPinsSelect, 0x88 | SW_CONTROL_GPIO); /* 0x488 | SW_CONTROL_GPIO */ + + write_nic_byte(dev, GP_ENABLE, 0); + + force_pci_posting(dev); + mdelay(200); + + write_nic_word(dev, GP_ENABLE, 0xff & (~(1<<6))); /* bit 6 is for RF on/off detection */ + + +} + +void rtl8225_host_usb_init(struct net_device *dev) +{ + write_nic_byte(dev,RFPinsSelect+1,0); + + write_nic_byte(dev,GPIO,0); + + write_nic_byte_E(dev,0x53,read_nic_byte_E(dev,0x53) | (1<<7)); + + write_nic_byte(dev,RFPinsSelect+1,4); + + write_nic_byte(dev,GPIO,0x20); + + write_nic_byte(dev,GP_ENABLE,0); + + + /* Config BB & RF */ + write_nic_word(dev, RFPinsOutput, 0x80); + + write_nic_word(dev, RFPinsSelect, 0x80); + + write_nic_word(dev, RFPinsEnable, 0x80); + + + mdelay(100); + + mdelay(1000); + +} + +void rtl8225_rf_init(struct net_device *dev) +{ + struct r8180_priv *priv = ieee80211_priv(dev); + int i; + short channel = 1; + u16 brsr; + int brsr_addr; + + if(NIC_8187 == priv->card_8187) { + brsr_addr = BRSR_8187; + } else { + brsr_addr = BRSR_8187B; + } + + + priv->chan = channel; + + rtl8180_set_anaparam(dev, RTL8225_ANAPARAM_ON); + + + if(priv->card_type == USB) + rtl8225_host_usb_init(dev); + else + rtl8225_host_pci_init(dev); + + write_nic_dword(dev, RF_TIMING, 0x000a8008); + + //brsr = read_nic_word(dev, BRSR); + brsr = read_nic_word(dev, brsr_addr); + + //write_nic_word(dev, BRSR, 0xffff); + write_nic_word(dev, brsr_addr, 0xffff); + + write_nic_dword(dev, RF_PARA, 0x100044); + + #if 1 //0->1 + rtl8180_set_mode(dev, EPROM_CMD_CONFIG); + write_nic_byte(dev, CONFIG3, 0x44); + rtl8180_set_mode(dev, EPROM_CMD_NORMAL); + #endif + + if(priv->card_type == USB){ + rtl8185_rf_pins_enable(dev); + + mdelay(1000); + } + + write_rtl8225(dev, 0x0, 0x67); mdelay(1); + + + write_rtl8225(dev, 0x1, 0xfe0); mdelay(1); + + write_rtl8225(dev, 0x2, 0x44d); mdelay(1); + + write_rtl8225(dev, 0x3, 0x441); mdelay(1); + + if(priv->card_type == USB) + write_rtl8225(dev, 0x4, 0x486); + else + write_rtl8225(dev, 0x4, 0x8be); + + mdelay(1); + + + /* version B & C */ + + if(priv->card_type == USB) + write_rtl8225(dev, 0x5, 0xbc0); + else if(priv->card_type == MINIPCI) + write_rtl8225(dev, 0x5, 0xbc0 + 3 +(6<<3)); + else + write_rtl8225(dev, 0x5, 0xbc0 + (6<<3)); + + mdelay(1); +// } + + write_rtl8225(dev, 0x6, 0xae6); mdelay(1); + + write_rtl8225(dev, 0x7, ((priv->card_type == USB)? 0x82a : rtl8225_chan[channel])); mdelay(1); + + write_rtl8225(dev, 0x8, 0x1f); mdelay(1); + + write_rtl8225(dev, 0x9, 0x334); mdelay(1); + + write_rtl8225(dev, 0xa, 0xfd4); mdelay(1); + + write_rtl8225(dev, 0xb, 0x391); mdelay(1); + + write_rtl8225(dev, 0xc, 0x50); mdelay(1); + + + write_rtl8225(dev, 0xd, 0x6db); mdelay(1); + + write_rtl8225(dev, 0xe, 0x29); mdelay(1); + + write_rtl8225(dev, 0xf, 0x914); + + if(priv->card_type == USB){ + //force_pci_posting(dev); + mdelay(100); + } + + write_rtl8225(dev, 0x2, 0xc4d); + + if(priv->card_type == USB){ + // force_pci_posting(dev); + mdelay(200); + + write_rtl8225(dev, 0x2, 0x44d); + + // force_pci_posting(dev); + mdelay(100); + + }//End of if(priv->card_type == USB) + /* FIXME!! rtl8187 we have to check if calibrarion + * is successful and eventually cal. again (repeat + * the two write on reg 2) + */ + force_pci_posting(dev); + + mdelay(100); //200 for 8187 + + //if(priv->card_type != USB) /* maybe not needed even for 8185 */ +// write_rtl8225(dev, 0x7, rtl8225_chan[channel]); + + write_rtl8225(dev, 0x0, 0x127); + + for(i=0;i<95;i++){ + write_rtl8225(dev, 0x1, (u8)(i+1)); + + /* version B & C & D*/ + + write_rtl8225(dev, 0x2, rtl8225bcd_rxgain[i]); + } + + write_rtl8225(dev, 0x0, 0x27); + + +// //if(priv->card_type != USB){ +// write_rtl8225(dev, 0x2, 0x44d); +// write_rtl8225(dev, 0x7, rtl8225_chan[channel]); +// write_rtl8225(dev, 0x2, 0x47d); +// +// force_pci_posting(dev); +// mdelay(100); +// +// write_rtl8225(dev, 0x2, 0x44d); +// //} + + write_rtl8225(dev, 0x0, 0x22f); + + if(priv->card_type != USB) + rtl8185_rf_pins_enable(dev); + + for(i=0;i<128;i++){ + write_phy_ofdm(dev, 0xb, rtl8225_agc[i]); + + mdelay(1); + write_phy_ofdm(dev, 0xa, (u8)i+ 0x80); + + mdelay(1); + } + + force_pci_posting(dev); + mdelay(1); + + write_phy_ofdm(dev, 0x0, 0x1); mdelay(1); + write_phy_ofdm(dev, 0x1, 0x2); mdelay(1); + write_phy_ofdm(dev, 0x2, ((priv->card_type == USB)? 0x42 : 0x62)); mdelay(1); + write_phy_ofdm(dev, 0x3, 0x0); mdelay(1); + write_phy_ofdm(dev, 0x4, 0x0); mdelay(1); + write_phy_ofdm(dev, 0x5, 0x0); mdelay(1); + write_phy_ofdm(dev, 0x6, 0x40); mdelay(1); + write_phy_ofdm(dev, 0x7, 0x0); mdelay(1); + write_phy_ofdm(dev, 0x8, 0x40); mdelay(1); + write_phy_ofdm(dev, 0x9, 0xfe); mdelay(1); + + /* ver C & D */ + write_phy_ofdm(dev, 0xa, 0x9); mdelay(1); + + //write_phy_ofdm(dev, 0x18, 0xef); + // } + //} + write_phy_ofdm(dev, 0xb, 0x80); mdelay(1); + + write_phy_ofdm(dev, 0xc, 0x1);mdelay(1); + + + //if(priv->card_type != USB) + //write_phy_ofdm(dev, 0xd, 0x33); // <> + + write_phy_ofdm(dev, 0xe, 0xd3);mdelay(1); + + write_phy_ofdm(dev, 0xf, 0x38);mdelay(1); +/*ver D & 8187*/ +// } + +// if(priv->card_8185 == 1 && priv->card_8185_Bversion) +// write_phy_ofdm(dev, 0x10, 0x04);/*ver B*/ +// else + write_phy_ofdm(dev, 0x10, 0x84);mdelay(1); +/*ver C & D & 8187*/ + + write_phy_ofdm(dev, 0x11, 0x06);mdelay(1); +/*agc resp time 700*/ + + +// if(priv->card_8185 == 2){ + /* Ver D & 8187*/ + write_phy_ofdm(dev, 0x12, 0x20);mdelay(1); + + write_phy_ofdm(dev, 0x13, 0x20);mdelay(1); + + write_phy_ofdm(dev, 0x14, 0x0); mdelay(1); + write_phy_ofdm(dev, 0x15, 0x40); mdelay(1); + write_phy_ofdm(dev, 0x16, 0x0); mdelay(1); + write_phy_ofdm(dev, 0x17, 0x40); mdelay(1); + +// if (priv->card_type == USB) +// write_phy_ofdm(dev, 0x18, 0xef); + + write_phy_ofdm(dev, 0x18, 0xef);mdelay(1); + + + write_phy_ofdm(dev, 0x19, 0x19); mdelay(1); + write_phy_ofdm(dev, 0x1a, 0x20); mdelay(1); + +// if (priv->card_type != USB){ +// if(priv->card_8185 == 1 && priv->card_8185_Bversion) +// write_phy_ofdm(dev, 0x1b, 0x66); /* Ver B */ +// else + write_phy_ofdm(dev, 0x1b, 0x76);mdelay(1); + /* Ver C & D */ //FIXME:MAYBE not needed +// } + + write_phy_ofdm(dev, 0x1c, 0x4);mdelay(1); + + /*ver D & 8187*/ + write_phy_ofdm(dev, 0x1e, 0x95);mdelay(1); + + write_phy_ofdm(dev, 0x1f, 0x75); mdelay(1); + +// } + + write_phy_ofdm(dev, 0x20, 0x1f);mdelay(1); + + write_phy_ofdm(dev, 0x21, 0x27);mdelay(1); + + write_phy_ofdm(dev, 0x22, 0x16);mdelay(1); + +// if(priv->card_type != USB) + //write_phy_ofdm(dev, 0x23, 0x43); //FIXME maybe not needed // <> + + write_phy_ofdm(dev, 0x24, 0x46); mdelay(1); + write_phy_ofdm(dev, 0x25, 0x20); mdelay(1); + write_phy_ofdm(dev, 0x26, 0x90); mdelay(1); + write_phy_ofdm(dev, 0x27, 0x88); mdelay(1); +/* Ver C & D & 8187*/ + + // <> Set init. gain to m74dBm. + + rtl8225_set_gain(dev,4); + /*write_phy_ofdm(dev, 0x0d, 0x43); mdelay(1); + write_phy_ofdm(dev, 0x1b, 0x76); mdelay(1); + write_phy_ofdm(dev, 0x1d, 0xc5); mdelay(1); + write_phy_ofdm(dev, 0x23, 0x78); mdelay(1); +*/ + //if(priv->card_type == USB); + // rtl8225_set_gain_usb(dev, 1); /* FIXME this '2' is random */ + + write_phy_cck(dev, 0x0, 0x98); mdelay(1); + write_phy_cck(dev, 0x3, 0x20); mdelay(1); + write_phy_cck(dev, 0x4, 0x7e); mdelay(1); + write_phy_cck(dev, 0x5, 0x12); mdelay(1); + write_phy_cck(dev, 0x6, 0xfc); mdelay(1); + write_phy_cck(dev, 0x7, 0x78);mdelay(1); + /* Ver C & D & 8187*/ + + write_phy_cck(dev, 0x8, 0x2e);mdelay(1); + + write_phy_cck(dev, 0x10, ((priv->card_type == USB) ? 0x9b: 0x93)); mdelay(1); + write_phy_cck(dev, 0x11, 0x88); mdelay(1); + write_phy_cck(dev, 0x12, 0x47); mdelay(1); + write_phy_cck(dev, 0x13, 0xd0); /* Ver C & D & 8187*/ + + write_phy_cck(dev, 0x19, 0x0); + write_phy_cck(dev, 0x1a, 0xa0); + write_phy_cck(dev, 0x1b, 0x8); + write_phy_cck(dev, 0x40, 0x86); /* CCK Carrier Sense Threshold */ + + write_phy_cck(dev, 0x41, 0x8d);mdelay(1); + + + write_phy_cck(dev, 0x42, 0x15); mdelay(1); + write_phy_cck(dev, 0x43, 0x18); mdelay(1); + write_phy_cck(dev, 0x44, 0x1f); mdelay(1); + write_phy_cck(dev, 0x45, 0x1e); mdelay(1); + write_phy_cck(dev, 0x46, 0x1a); mdelay(1); + write_phy_cck(dev, 0x47, 0x15); mdelay(1); + write_phy_cck(dev, 0x48, 0x10); mdelay(1); + write_phy_cck(dev, 0x49, 0xa); mdelay(1); + write_phy_cck(dev, 0x4a, 0x5); mdelay(1); + write_phy_cck(dev, 0x4b, 0x2); mdelay(1); + write_phy_cck(dev, 0x4c, 0x5);mdelay(1); + + + write_nic_byte(dev, 0x5b, 0x0d); mdelay(1); + + + +// <> +// // TESTR 0xb 8187 +// write_phy_cck(dev, 0x10, 0x93);// & 0xfb); +// +// //if(priv->card_type != USB){ +// write_phy_ofdm(dev, 0x2, 0x62); +// write_phy_ofdm(dev, 0x6, 0x0); +// write_phy_ofdm(dev, 0x8, 0x0); +// //} + + rtl8225_SetTXPowerLevel(dev, channel); + + write_phy_cck(dev, 0x10, 0x9b); mdelay(1); /* Rx ant A, 0xdb for B */ + write_phy_ofdm(dev, 0x26, 0x90); mdelay(1); /* Rx ant A, 0x10 for B */ + + rtl8185_tx_antenna(dev, 0x3); /* TX ant A, 0x0 for B */ + + /* switch to high-speed 3-wire + * last digit. 2 for both cck and ofdm + */ + if(priv->card_type == USB) + write_nic_dword(dev, 0x94, 0x3dc00002); + else{ + write_nic_dword(dev, 0x94, 0x15c00002); + rtl8185_rf_pins_enable(dev); + } + +// if(priv->card_type != USB) +// rtl8225_set_gain(dev, 4); /* FIXME this '1' is random */ // <> +// rtl8225_set_mode(dev, 1); /* FIXME start in B mode */ // <> +// +// /* make sure is waken up! */ +// write_rtl8225(dev,0x4, 0x9ff); +// rtl8180_set_anaparam(dev, RTL8225_ANAPARAM_ON); +// rtl8185_set_anaparam2(dev, RTL8225_ANAPARAM2_ON); + + rtl8225_rf_set_chan(dev, priv->chan); + + //write_nic_word(dev,BRSR,brsr); + +} diff -Nur linux-2.6.30.5.orig/drivers/net/wireless/rtl8187b/r8180_rtl8225.h linux-2.6.30.5/drivers/net/wireless/rtl8187b/r8180_rtl8225.h --- linux-2.6.30.5.orig/drivers/net/wireless/rtl8187b/r8180_rtl8225.h 1970-01-01 01:00:00.000000000 +0100 +++ linux-2.6.30.5/drivers/net/wireless/rtl8187b/r8180_rtl8225.h 2009-08-23 19:01:04.000000000 +0200 @@ -0,0 +1,77 @@ +/* + This is part of the rtl8180-sa2400 driver + released under the GPL (See file COPYING for details). + Copyright (c) 2005 Andrea Merello + + This files contains programming code for the rtl8225 + radio frontend. + + *Many* thanks to Realtek Corp. for their great support! + +*/ + +#ifndef RTL8225H +#define RTL8225H + +#include "r8187.h" + +#define RTL8225_ANAPARAM_ON 0xa0000a59 + +// FIXME: OFF ANAPARAM MIGHT BE WRONG! +#define RTL8225_ANAPARAM_OFF 0xa00beb59 +#define RTL8225_ANAPARAM2_OFF 0x840dec11 + +#define RTL8225_ANAPARAM2_ON 0x860c7312 + +void rtl8225_rf_init(struct net_device *dev); +void rtl8225z2_rf_init(struct net_device *dev); +void rtl8225z2_rf_set_chan(struct net_device *dev, short ch); +short rtl8225_is_V_z2(struct net_device *dev); +void rtl8225_rf_set_chan(struct net_device *dev,short ch); +void rtl8225_rf_close(struct net_device *dev); +short rtl8225_rf_set_sens(struct net_device *dev, short sens); +void rtl8225_host_pci_init(struct net_device *dev); +void rtl8225_host_usb_init(struct net_device *dev); +void write_rtl8225(struct net_device *dev, u8 adr, u16 data); +void rtl8225z2_rf_set_mode(struct net_device *dev) ; +void rtl8185_rf_pins_enable(struct net_device *dev); +void rtl8180_set_mode(struct net_device *dev,int mode); +void UpdateInitialGain(struct net_device *dev); +void UpdateCCKThreshold(struct net_device *dev); +void rtl8225_SetTXPowerLevel(struct net_device *dev, short ch); +void rtl8225z2_SetTXPowerLevel(struct net_device *dev, short ch); + +#define RTL8225_RF_MAX_SENS 6 +#define RTL8225_RF_DEF_SENS 4 + +extern inline char GetTxOfdmHighPowerBias(struct net_device *dev) +{ + // + // We should always adjust our Tx Power for 8187 and 8187B. + // It was ever recommended not to adjust Tx Power of 8187B with Atheros AP + // for throughput by David, but now we found it is not the issue to impact + // the Atheros's problem and also no adjustion for Tx Power will cause "low" + // throughput. By Bruce, 2007-07-03. + // + return 10; +} + +// +// Description: +// Return Tx power level to minus if we are in high power state. +// +// Note: +// Adjust it according to RF if required. +// +extern inline char GetTxCckHighPowerBias(struct net_device *dev) +{ + return 7; +} + + + +extern u8 rtl8225_agc[]; + +extern u32 rtl8225_chan[]; + +#endif diff -Nur linux-2.6.30.5.orig/drivers/net/wireless/rtl8187b/r8180_rtl8225z2.c linux-2.6.30.5/drivers/net/wireless/rtl8187b/r8180_rtl8225z2.c --- linux-2.6.30.5.orig/drivers/net/wireless/rtl8187b/r8180_rtl8225z2.c 1970-01-01 01:00:00.000000000 +0100 +++ linux-2.6.30.5/drivers/net/wireless/rtl8187b/r8180_rtl8225z2.c 2009-08-23 19:01:04.000000000 +0200 @@ -0,0 +1,2090 @@ +/* + This is part of the rtl8180-sa2400 driver + released under the GPL (See file COPYING for details). + Copyright (c) 2005 Andrea Merello + + This files contains programming code for the rtl8225 + radio frontend. + + *Many* thanks to Realtek Corp. for their great support! + +*/ + + + +#include "r8180_hw.h" +#include "r8180_rtl8225.h" +#ifdef ENABLE_DOT11D +#include "dot11d.h" +#endif + +//2005.11.16 +u8 rtl8225z2_threshold[]={ + 0x8d, 0x8d, 0x8d, 0x8d, 0x9d, 0xad, 0xbd, +}; + +// 0xd 0x19 0x1b 0x21 +u8 rtl8225z2_gain_bg[]={ + 0x23, 0x15, 0xa5, // -82-1dbm + 0x23, 0x15, 0xb5, // -82-2dbm + 0x23, 0x15, 0xc5, // -82-3dbm + 0x33, 0x15, 0xc5, // -78dbm + 0x43, 0x15, 0xc5, // -74dbm + 0x53, 0x15, 0xc5, // -70dbm + 0x63, 0x15, 0xc5, // -66dbm +}; + +u8 rtl8225z2_gain_a[]={ + 0x13,0x27,0x5a,//,0x37,// -82dbm + 0x23,0x23,0x58,//,0x37,// -82dbm + 0x33,0x1f,0x56,//,0x37,// -82dbm + 0x43,0x1b,0x54,//,0x37,// -78dbm + 0x53,0x17,0x51,//,0x37,// -74dbm + 0x63,0x24,0x4f,//,0x37,// -70dbm + 0x73,0x0f,0x4c,//,0x37,// -66dbm +}; +static u32 MAC_REG_TABLE[][3]={ + {0xf0, 0x32, 0000}, {0xf1, 0x32, 0000}, {0xf2, 0x00, 0000}, {0xf3, 0x00, 0000}, + {0xf4, 0x32, 0000}, {0xf5, 0x43, 0000}, {0xf6, 0x00, 0000}, {0xf7, 0x00, 0000}, + {0xf8, 0x46, 0000}, {0xf9, 0xa4, 0000}, {0xfa, 0x00, 0000}, {0xfb, 0x00, 0000}, + {0xfc, 0x96, 0000}, {0xfd, 0xa4, 0000}, {0xfe, 0x00, 0000}, {0xff, 0x00, 0000}, + + {0x58, 0x4b, 0001}, {0x59, 0x00, 0001}, {0x5a, 0x4b, 0001}, {0x5b, 0x00, 0001}, + {0x60, 0x4b, 0001}, {0x61, 0x09, 0001}, {0x62, 0x4b, 0001}, {0x63, 0x09, 0001}, + {0xce, 0x0f, 0001}, {0xcf, 0x00, 0001}, {0xe0, 0xff, 0001}, {0xe1, 0x0f, 0001}, + {0xe2, 0x00, 0001}, {0xf0, 0x4e, 0001}, {0xf1, 0x01, 0001}, {0xf2, 0x02, 0001}, + {0xf3, 0x03, 0001}, {0xf4, 0x04, 0001}, {0xf5, 0x05, 0001}, {0xf6, 0x06, 0001}, + {0xf7, 0x07, 0001}, {0xf8, 0x08, 0001}, + + {0x4e, 0x00, 0002}, {0x0c, 0x04, 0002}, {0x21, 0x61, 0002}, {0x22, 0x68, 0002}, + {0x23, 0x6f, 0002}, {0x24, 0x76, 0002}, {0x25, 0x7d, 0002}, {0x26, 0x84, 0002}, + {0x27, 0x8d, 0002}, {0x4d, 0x08, 0002}, {0x50, 0x05, 0002}, {0x51, 0xf5, 0002}, + {0x52, 0x04, 0002}, {0x53, 0xa0, 0002}, {0x54, 0x1f, 0002}, {0x55, 0x23, 0002}, + {0x56, 0x45, 0002}, {0x57, 0x67, 0002}, {0x58, 0x08, 0002}, {0x59, 0x08, 0002}, + {0x5a, 0x08, 0002}, {0x5b, 0x08, 0002}, {0x60, 0x08, 0002}, {0x61, 0x08, 0002}, + {0x62, 0x08, 0002}, {0x63, 0x08, 0002}, {0x64, 0xcf, 0002}, {0x72, 0x56, 0002}, + {0x73, 0x9a, 0002}, + + {0x34, 0xf0, 0000}, {0x35, 0x0f, 0000}, {0x5b, 0x40, 0000}, {0x84, 0x88, 0000}, + {0x85, 0x24, 0000}, {0x88, 0x54, 0000}, {0x8b, 0xb8, 0000}, {0x8c, 0x07, 0000}, + {0x8d, 0x00, 0000}, {0x94, 0x1b, 0000}, {0x95, 0x12, 0000}, {0x96, 0x00, 0000}, + {0x97, 0x06, 0000}, {0x9d, 0x1a, 0000}, {0x9f, 0x10, 0000}, {0xb4, 0x22, 0000}, + {0xbe, 0x80, 0000}, {0xdb, 0x00, 0000}, {0xee, 0x00, 0000}, {0x91, 0x01, 0000}, + //lzm mode 0x91 form 0x03->0x01 open GPIO BIT1, + //because Polling methord will rurn off Radio + //the first time when read GPI(0x92). + //because after 0x91:bit1 form 1->0, there will + //be time for 0x92:bit1 form 0->1 + + {0x4c, 0x00, 0002}, {0x9f, 0x00, 0003}, {0x8c, 0x01, 0000}, {0x8d, 0x10, 0000}, + {0x8e, 0x08, 0000}, {0x8f, 0x00, 0000} +}; + +static u8 ZEBRA_AGC[]={ + 0, + 0x5e,0x5e,0x5e,0x5e,0x5d,0x5b,0x59,0x57,0x55,0x53,0x51,0x4f,0x4d,0x4b,0x49,0x47, + 0x45,0x43,0x41,0x3f,0x3d,0x3b,0x39,0x37,0x35,0x33,0x31,0x2f,0x2d,0x2b,0x29,0x27, + 0x25,0x23,0x21,0x1f,0x1d,0x1b,0x19,0x17,0x15,0x13,0x11,0x0f,0x0d,0x0b,0x09,0x07, + 0x05,0x03,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01, + 0x19,0x19,0x19,0x019,0x19,0x19,0x19,0x19,0x19,0x20,0x21,0x22,0x23,0x24,0x25,0x26, + 0x26,0x27,0x27,0x28,0x28,0x29,0x2a,0x2a,0x2a,0x2b,0x2b,0x2b,0x2c,0x2c,0x2c,0x2d, + 0x2d,0x2d,0x2d,0x2e,0x2e,0x2e,0x2e,0x2f,0x2f,0x2f,0x30,0x30,0x31,0x31,0x31,0x31, + 0x31,0x31,0x31,0x31,0x31,0x31,0x31,0x31,0x31,0x31,0x31,0x31,0x31,0x31,0x31,0x31 +}; + +static u32 ZEBRA_RF_RX_GAIN_TABLE[]={ + 0, + 0x0400,0x0401,0x0402,0x0403,0x0404,0x0405,0x0408,0x0409, + 0x040a,0x040b,0x0502,0x0503,0x0504,0x0505,0x0540,0x0541, + 0x0542,0x0543,0x0544,0x0545,0x0580,0x0581,0x0582,0x0583, + 0x0584,0x0585,0x0588,0x0589,0x058a,0x058b,0x0643,0x0644, + 0x0645,0x0680,0x0681,0x0682,0x0683,0x0684,0x0685,0x0688, + 0x0689,0x068a,0x068b,0x068c,0x0742,0x0743,0x0744,0x0745, + 0x0780,0x0781,0x0782,0x0783,0x0784,0x0785,0x0788,0x0789, + 0x078a,0x078b,0x078c,0x078d,0x0790,0x0791,0x0792,0x0793, + 0x0794,0x0795,0x0798,0x0799,0x079a,0x079b,0x079c,0x079d, + 0x07a0,0x07a1,0x07a2,0x07a3,0x07a4,0x07a5,0x07a8,0x07a9, + 0x03aa,0x03ab,0x03ac,0x03ad,0x03b0,0x03b1,0x03b2,0x03b3, + 0x03b4,0x03b5,0x03b8,0x03b9,0x03ba,0x03bb,0x03bb +}; + +// Use the new SD3 given param, by shien chang, 2006.07.14 + +static u8 OFDM_CONFIG[]={ + // 0x00 + 0x10, 0x0d, 0x01, 0x00, 0x14, 0xfb, 0xfb, 0x60, + 0x00, 0x60, 0x00, 0x00, 0x00, 0x5c, 0x00, 0x00, + + // 0x10 + 0x40, 0x00, 0x40, 0x00, 0x00, 0x00, 0xa8, 0x26, + 0x32, 0x33, 0x07, 0xa5, 0x6f, 0x55, 0xc8, 0xb3, + + // 0x20 + 0x0a, 0xe1, 0x2C, 0x8a, 0x86, 0x83, 0x34, 0x0f, + 0x4f, 0x24, 0x6f, 0xc2, 0x6b, 0x40, 0x80, 0x00, + + // 0x30 + 0xc0, 0xc1, 0x58, 0xf1, 0x00, 0xe4, 0x90, 0x3e, + 0x6d, 0x3c, 0xfb, 0x07//0xc7 + }; + +//2005.11.16, +u8 ZEBRA2_CCK_OFDM_GAIN_SETTING[]={ + 0x00,0x01,0x02,0x03,0x04,0x05, + 0x06,0x07,0x08,0x09,0x0a,0x0b, + 0x0c,0x0d,0x0e,0x0f,0x10,0x11, + 0x12,0x13,0x14,0x15,0x16,0x17, + 0x18,0x19,0x1a,0x1b,0x1c,0x1d, + 0x1e,0x1f,0x20,0x21,0x22,0x23, +}; +//- +u16 rtl8225z2_rxgain[]={ + 0x0400, 0x0401, 0x0402, 0x0403, 0x0404, 0x0405, 0x0408, 0x0409, + 0x040a, 0x040b, 0x0502, 0x0503, 0x0504, 0x0505, 0x0540, 0x0541, + 0x0542, 0x0543, 0x0544, 0x0545, 0x0580, 0x0581, 0x0582, 0x0583, + 0x0584, 0x0585, 0x0588, 0x0589, 0x058a, 0x058b, 0x0643, 0x0644, + 0x0645, 0x0680, 0x0681, 0x0682, 0x0683, 0x0684, 0x0685, 0x0688, + 0x0689, 0x068a, 0x068b, 0x068c, 0x0742, 0x0743, 0x0744, 0x0745, + 0x0780, 0x0781, 0x0782, 0x0783, 0x0784, 0x0785, 0x0788, 0x0789, + 0x078a, 0x078b, 0x078c, 0x078d, 0x0790, 0x0791, 0x0792, 0x0793, + 0x0794, 0x0795, 0x0798, 0x0799, 0x079a, 0x079b, 0x079c, 0x079d, + 0x07a0, 0x07a1, 0x07a2, 0x07a3, 0x07a4, 0x07a5, 0x07a8, 0x07a9, + 0x03aa, 0x03ab, 0x03ac, 0x03ad, 0x03b0, 0x03b1, 0x03b2, 0x03b3, + 0x03b4, 0x03b5, 0x03b8, 0x03b9, 0x03ba, 0x03bb, 0x03bb + +}; + + +/* + from 0 to 0x23 +u8 rtl8225_tx_gain_cck_ofdm[]={ + 0x02,0x06,0x0e,0x1e,0x3e,0x7e +}; +*/ + +//- +u8 rtl8225z2_tx_power_ofdm[]={ + 0x42,0x00,0x40,0x00,0x40 +}; + + +//- +u8 rtl8225z2_tx_power_cck_ch14[]={ + 0x36,0x35,0x2e,0x1b,0x00,0x00,0x00,0x00, + 0x30, 0x2f, 0x29, 0x15, 0x00, 0x00, 0x00, 0x00, + 0x30, 0x2f, 0x29, 0x15, 0x00, 0x00, 0x00, 0x00, + 0x30, 0x2f, 0x29, 0x15, 0x00, 0x00, 0x00, 0x00, +}; + + +//- +u8 rtl8225z2_tx_power_cck[]={ + 0x36,0x35,0x2e,0x25,0x1c,0x12,0x09,0x04, + 0x30, 0x2f, 0x29, 0x21, 0x19, 0x10, 0x08, 0x03, + 0x2b, 0x2a, 0x25, 0x1e, 0x16, 0x0e, 0x07, 0x03, + 0x26, 0x25, 0x21, 0x1b, 0x14, 0x0d, 0x06, 0x03 +}; + +#ifdef ENABLE_DOT11D +// +// Description: +// Map dBm into Tx power index according to +// current HW model, for example, RF and PA, and +// current wireless mode. +// +s8 +rtl8187B_DbmToTxPwrIdx( + struct r8180_priv *priv, + WIRELESS_MODE WirelessMode, + s32 PowerInDbm + ) +{ + bool bUseDefault = true; + s8 TxPwrIdx = 0; + +#ifdef CONFIG_RTL818X_S + // + // 071011, SD3 SY: + // OFDM Power in dBm = Index * 0.5 + 0 + // CCK Power in dBm = Index * 0.25 + 13 + // + if(priv->card_8185 >= VERSION_8187S_B) + { + s32 tmp = 0; + + if(WirelessMode == WIRELESS_MODE_G) + { + bUseDefault = false; + tmp = (2 * PowerInDbm); + + if(tmp < 0) + TxPwrIdx = 0; + else if(tmp > 40) // 40 means 20 dBm. + TxPwrIdx = 40; + else + TxPwrIdx = (s8)tmp; + } + else if(WirelessMode == WIRELESS_MODE_B) + { + bUseDefault = false; + tmp = (4 * PowerInDbm) - 52; + + if(tmp < 0) + TxPwrIdx = 0; + else if(tmp > 28) // 28 means 20 dBm. + TxPwrIdx = 28; + else + TxPwrIdx = (s8)tmp; + } + } +#endif + + // + // TRUE if we want to use a default implementation. + // We shall set it to FALSE when we have exact translation formular + // for target IC. 070622, by rcnjko. + // + if(bUseDefault) + { + if(PowerInDbm < 0) + TxPwrIdx = 0; + else if(PowerInDbm > 35) + TxPwrIdx = 35; + else + TxPwrIdx = (u8)PowerInDbm; + } + + return TxPwrIdx; +} +#endif + + +void rtl8225z2_set_gain(struct net_device *dev, short gain) +{ + u8* rtl8225_gain; + struct r8180_priv *priv = ieee80211_priv(dev); + + u8 mode = priv->ieee80211->mode; + + if(mode == IEEE_B || mode == IEEE_G) + rtl8225_gain = rtl8225z2_gain_bg; + else + rtl8225_gain = rtl8225z2_gain_a; + + //write_phy_ofdm(dev, 0x0d, rtl8225_gain[gain * 3]); + //write_phy_ofdm(dev, 0x19, rtl8225_gain[gain * 3 + 1]); + //write_phy_ofdm(dev, 0x1b, rtl8225_gain[gain * 3 + 2]); + //2005.11.17, by ch-hsu + write_phy_ofdm(dev, 0x0b, rtl8225_gain[gain * 3]); + write_phy_ofdm(dev, 0x1b, rtl8225_gain[gain * 3 + 1]); + write_phy_ofdm(dev, 0x1d, rtl8225_gain[gain * 3 + 2]); + write_phy_ofdm(dev, 0x21, 0x37); + +} + +u32 read_rtl8225(struct net_device *dev, u8 adr) +{ + u32 data2Write = ((u32)(adr & 0x1f)) << 27; + u32 dataRead; + u32 mask; + u16 oval,oval2,oval3,tmp; +// ThreeWireReg twreg; +// ThreeWireReg tdata; + int i; + short bit, rw; + + u8 wLength = 6; + u8 rLength = 12; + u8 low2high = 0; + + oval = read_nic_word(dev, RFPinsOutput); + oval2 = read_nic_word(dev, RFPinsEnable); + oval3 = read_nic_word(dev, RFPinsSelect); + write_nic_word(dev, RFPinsEnable, (oval2|0xf)); + write_nic_word(dev, RFPinsSelect, (oval3|0xf)); + + dataRead = 0; + + oval &= ~0xf; + + write_nic_word(dev, RFPinsOutput, oval | BB_HOST_BANG_EN ); udelay(4); + + write_nic_word(dev, RFPinsOutput, oval ); udelay(5); + + rw = 0; + + mask = (low2high) ? 0x01 : (((u32)0x01)<<(32-1)); + for(i = 0; i < wLength/2; i++) + { + bit = ((data2Write&mask) != 0) ? 1 : 0; + write_nic_word(dev, RFPinsOutput, bit|oval | rw); udelay(1); + + write_nic_word(dev, RFPinsOutput, bit|oval | BB_HOST_BANG_CLK | rw); udelay(2); + write_nic_word(dev, RFPinsOutput, bit|oval | BB_HOST_BANG_CLK | rw); udelay(2); + + mask = (low2high) ? (mask<<1): (mask>>1); + + if(i == 2) + { + rw = BB_HOST_BANG_RW; + write_nic_word(dev, RFPinsOutput, bit|oval | BB_HOST_BANG_CLK | rw); udelay(2); + write_nic_word(dev, RFPinsOutput, bit|oval | rw); udelay(2); + break; + } + + bit = ((data2Write&mask) != 0) ? 1: 0; + + write_nic_word(dev, RFPinsOutput, oval|bit|rw| BB_HOST_BANG_CLK); udelay(2); + write_nic_word(dev, RFPinsOutput, oval|bit|rw| BB_HOST_BANG_CLK); udelay(2); + + write_nic_word(dev, RFPinsOutput, oval| bit |rw); udelay(1); + + mask = (low2high) ? (mask<<1) : (mask>>1); + } + + //twreg.struc.clk = 0; + //twreg.struc.data = 0; + write_nic_word(dev, RFPinsOutput, rw|oval); udelay(2); + mask = (low2high) ? 0x01 : (((u32)0x01) << (12-1)); + + // We must set data pin to HW controled, otherwise RF can't driver it and + // value RF register won't be able to read back properly. 2006.06.13, by rcnjko. + write_nic_word(dev, RFPinsEnable,((oval2|0xe) & (~0x01))); + + for(i = 0; i < rLength; i++) + { + write_nic_word(dev, RFPinsOutput, rw|oval); udelay(1); + + write_nic_word(dev, RFPinsOutput, rw|oval|BB_HOST_BANG_CLK); udelay(2); + write_nic_word(dev, RFPinsOutput, rw|oval|BB_HOST_BANG_CLK); udelay(2); + write_nic_word(dev, RFPinsOutput, rw|oval|BB_HOST_BANG_CLK); udelay(2); + tmp = read_nic_word(dev, RFPinsInput); + + dataRead |= (tmp & BB_HOST_BANG_CLK ? mask : 0); + + write_nic_word(dev, RFPinsOutput, (rw|oval)); udelay(2); + + mask = (low2high) ? (mask<<1) : (mask>>1); + } + + write_nic_word(dev, RFPinsOutput, BB_HOST_BANG_EN|BB_HOST_BANG_RW|oval); udelay(2); + + write_nic_word(dev, RFPinsEnable, oval2); + write_nic_word(dev, RFPinsSelect, oval3); // Set To SW Switch + write_nic_word(dev, RFPinsOutput, 0x3a0); + + return dataRead; + +} +short rtl8225_is_V_z2(struct net_device *dev) +{ + short vz2 = 1; + //set VCO-PDN pin +// printk("%s()\n", __FUNCTION__); + write_nic_word(dev, RFPinsOutput, 0x0080); + write_nic_word(dev, RFPinsSelect, 0x0080); + write_nic_word(dev, RFPinsEnable, 0x0080); + + //lzm mod for up take too long time 20081201 + //mdelay(100); + //mdelay(1000); + + /* sw to reg pg 1 */ + write_rtl8225(dev, 0, 0x1b7); + /* reg 8 pg 1 = 23*/ + if( read_rtl8225(dev, 8) != 0x588) + vz2 = 0; + + else /* reg 9 pg 1 = 24 */ + if( read_rtl8225(dev, 9) != 0x700) + vz2 = 0; + + /* sw back to pg 0 */ + write_rtl8225(dev, 0, 0xb7); + + return vz2; + +} + +void rtl8225z2_SetTXPowerLevel(struct net_device *dev, short ch) +{ + struct r8180_priv *priv = ieee80211_priv(dev); + +// int GainIdx; +// int GainSetting; + int i; + u8 power; + u8 *cck_power_table; + u8 max_cck_power_level; + u8 min_cck_power_level; + u8 max_ofdm_power_level; + u8 min_ofdm_power_level; + s8 cck_power_level = 0xff & priv->chtxpwr[ch]; + s8 ofdm_power_level = 0xff & priv->chtxpwr_ofdm[ch]; + u8 hw_version = priv->card_8187_Bversion; + +#ifdef ENABLE_DOT11D + if(IS_DOT11D_ENABLE(priv->ieee80211) && + IS_DOT11D_STATE_DONE(priv->ieee80211) ) + { + //PRT_DOT11D_INFO pDot11dInfo = GET_DOT11D_INFO(priv->ieee80211); + u8 MaxTxPwrInDbm = DOT11D_GetMaxTxPwrInDbm(priv->ieee80211, ch); + u8 CckMaxPwrIdx = rtl8187B_DbmToTxPwrIdx(priv, WIRELESS_MODE_B, MaxTxPwrInDbm); + u8 OfdmMaxPwrIdx = rtl8187B_DbmToTxPwrIdx(priv, WIRELESS_MODE_G, MaxTxPwrInDbm); + + //printk("Max Tx Power dBm (%d) => CCK Tx power index : %d, OFDM Tx power index: %d\n", MaxTxPwrInDbm, CckMaxPwrIdx, OfdmMaxPwrIdx); + + //printk("EEPROM channel(%d) => CCK Tx power index: %d, OFDM Tx power index: %d\n", + // ch, cck_power_level, ofdm_power_level); + + if(cck_power_level > CckMaxPwrIdx) + cck_power_level = CckMaxPwrIdx; + if(ofdm_power_level > OfdmMaxPwrIdx) + ofdm_power_level = OfdmMaxPwrIdx; + } + + //priv->CurrentCckTxPwrIdx = cck_power_level; + //priv->CurrentOfdmTxPwrIdx = ofdm_power_level; +#endif + + if (NIC_8187B == priv->card_8187) + { + if (hw_version == VERSION_8187B_B) + { + min_cck_power_level = 0; + max_cck_power_level = 15; + min_ofdm_power_level = 2; + max_ofdm_power_level = 17; + }else + { + min_cck_power_level = 7; + max_cck_power_level = 22; + min_ofdm_power_level = 10; + max_ofdm_power_level = 25; + } + + if( priv->TrSwitchState == TR_SW_TX ) + { + //printk("SetTxPowerLevel8187(): Origianl OFDM Tx power level %d, adjust value = %d\n", ofdm_power_level,GetTxOfdmHighPowerBias(dev)); + ofdm_power_level -= GetTxOfdmHighPowerBias(dev); + cck_power_level -= GetTxCckHighPowerBias(dev); + //printk("SetTxPowerLevel8187(): Adjusted OFDM Tx power level %d for we are in High Power state\n", + // ofdm_power_level); + //printk("SetTxPowerLevel8187(): Adjusted CCK Tx power level %d for we are in High Power state\n", + // cck_power_level); + } + /* CCK power setting */ + if(cck_power_level > (max_cck_power_level -min_cck_power_level)) + cck_power_level = max_cck_power_level; + else + cck_power_level += min_cck_power_level; + cck_power_level += priv->cck_txpwr_base; + + if(cck_power_level > 35) + cck_power_level = 35; + if(cck_power_level < 0) + cck_power_level = 0; + + if(ch == 14) + cck_power_table = rtl8225z2_tx_power_cck_ch14; + else + cck_power_table = rtl8225z2_tx_power_cck; + if (hw_version == VERSION_8187B_B) + { + if (cck_power_level <= 6){ + } + else if (cck_power_level <=11){ + cck_power_table += 8; + } + else{ + cck_power_table += (8*2); + } + }else{ + if (cck_power_level<=5){ + }else if(cck_power_level<=11){ + cck_power_table += 8; + }else if(cck_power_level <= 17){ + cck_power_table += 8*2; + }else{ + cck_power_table += 8*3; + } + } + + + + for(i=0;i<8;i++){ + + power = cck_power_table[i]; + write_phy_cck(dev, 0x44 + i, power); + } + + //write_nic_byte(dev, TX_GAIN_CCK, power); + //2005.11.17, + write_nic_byte(dev, CCK_TXAGC, (ZEBRA2_CCK_OFDM_GAIN_SETTING[cck_power_level]*2)); + +// force_pci_posting(dev); +// msleep(1); +//in windows the delay was del from 85 to 87, +//here we mod to sleep, or The CPU occupany is too hight. LZM 31/10/2008 + + /* OFDM power setting */ + // Old: + // if(ofdm_power_level > max_ofdm_power_level) + // ofdm_power_level = 35; + // ofdm_power_level += min_ofdm_power_level; + // Latest: + if(ofdm_power_level > (max_ofdm_power_level - min_ofdm_power_level)) + ofdm_power_level = max_ofdm_power_level; + else + ofdm_power_level += min_ofdm_power_level; + + ofdm_power_level += priv->ofdm_txpwr_base; + + if(ofdm_power_level > 35) + ofdm_power_level = 35; + + if(ofdm_power_level < 0) + ofdm_power_level = 0; + write_nic_byte(dev, OFDM_TXAGC, ZEBRA2_CCK_OFDM_GAIN_SETTING[ofdm_power_level]*2); + + if (hw_version == VERSION_8187B_B) + { + if(ofdm_power_level<=11){ + write_phy_ofdm(dev, 0x87, 0x60); + write_phy_ofdm(dev, 0x89, 0x60); + } + else{ + write_phy_ofdm(dev, 0x87, 0x5c); + write_phy_ofdm(dev, 0x89, 0x5c); + } + }else{ + if(ofdm_power_level<=11){ + write_phy_ofdm(dev, 0x87, 0x5c); + write_phy_ofdm(dev, 0x89, 0x5c); + } + if(ofdm_power_level<=17){ + write_phy_ofdm(dev, 0x87, 0x54); + write_phy_ofdm(dev, 0x89, 0x54); + } + else{ + write_phy_ofdm(dev, 0x87, 0x50); + write_phy_ofdm(dev, 0x89, 0x50); + } + } +// force_pci_posting(dev); +// msleep(1); +//in windows the delay was del from 85 to 87, +//and here we mod to sleep, or The CPU occupany is too hight. LZM 31/10/2008 + }else if(NIC_8187 == priv->card_8187) { + min_cck_power_level = 0; + max_cck_power_level = 15; + min_ofdm_power_level = 10; + max_ofdm_power_level = 25; + if(cck_power_level > (max_cck_power_level -min_cck_power_level)) + cck_power_level = max_cck_power_level; + else + cck_power_level += min_cck_power_level; + cck_power_level += priv->cck_txpwr_base; + + if(cck_power_level > 35) + cck_power_level = 35; + + if(ch == 14) + cck_power_table = rtl8225z2_tx_power_cck_ch14; + else + cck_power_table = rtl8225z2_tx_power_cck; + for(i=0;i<8;i++){ + power = cck_power_table[i]; + write_phy_cck(dev, 0x44 + i, power); + } + + //write_nic_byte(dev, TX_GAIN_CCK, power); + //2005.11.17, + write_nic_byte(dev, CCK_TXAGC, ZEBRA2_CCK_OFDM_GAIN_SETTING[cck_power_level]); + +// force_pci_posting(dev); +// msleep(1); +//in windows the delay was del from 85 to 87, +//and here we mod to sleep, or The CPU occupany is too hight. LZM 31/10/2008 + if(ofdm_power_level > (max_ofdm_power_level - min_ofdm_power_level)) + ofdm_power_level = max_ofdm_power_level; + else + ofdm_power_level += min_ofdm_power_level; + + ofdm_power_level += priv->ofdm_txpwr_base; + + if(ofdm_power_level > 35) + ofdm_power_level = 35; + write_nic_byte(dev, OFDM_TXAGC, ZEBRA2_CCK_OFDM_GAIN_SETTING[ofdm_power_level]); + + rtl8185_set_anaparam2(dev,RTL8225_ANAPARAM2_ON); + + write_phy_ofdm(dev,2,0x42); + write_phy_ofdm(dev,5,0); + write_phy_ofdm(dev,6,0x40); + write_phy_ofdm(dev,7,0); + write_phy_ofdm(dev,8,0x40); + } + +} + +void rtl8225z2_rf_set_chan(struct net_device *dev, short ch) +{ + struct r8180_priv *priv = ieee80211_priv(dev); + short gset = (priv->ieee80211->state == IEEE80211_LINKED && + ieee80211_is_54g(priv->ieee80211->current_network)) || + priv->ieee80211->iw_mode == IW_MODE_MONITOR; + int eifs_addr; + + down(&priv->set_chan_sem); + + if(NIC_8187 == priv->card_8187) { + eifs_addr = EIFS_8187; + } else { + eifs_addr = EIFS_8187B; + } + +#ifdef ENABLE_DOT11D + if(!IsLegalChannel(priv->ieee80211, ch) ) + { + printk("channel(%d). is invalide\n", ch); + up(&priv->set_chan_sem); + return; + } +#endif + //87B not do it FIXME + rtl8225z2_SetTXPowerLevel(dev, ch); + + //write_nic_byte(dev,0x7,(u8)rtl8225_chan[ch]); + write_rtl8225(dev, 0x7, rtl8225_chan[ch]); + + force_pci_posting(dev); + //mdelay(10); +//in windows the delay was del from 85 to 87, +//and here we mod to sleep, or The CPU occupany is too hight. LZM 31/10/2008 + if(NIC_8187 == priv->card_8187){ + write_nic_byte(dev,SIFS,0x22);// SIFS: 0x22 + + if(gset) + write_nic_byte(dev,DIFS,20); //DIFS: 20 + else + write_nic_byte(dev,DIFS,0x24); //DIFS: 36 + + if(priv->ieee80211->state == IEEE80211_LINKED && + ieee80211_is_shortslot(priv->ieee80211->current_network)) + write_nic_byte(dev,SLOT,0x9); //SLOT: 9 + + else + write_nic_byte(dev,SLOT,0x14); //SLOT: 20 (0x14) + + + if(gset){ + write_nic_byte(dev,eifs_addr,91 - 20); // EIFS: 91 (0x5B) + write_nic_byte(dev,CW_VAL,0x73); //CW VALUE: 0x37 + //DMESG("using G net params"); + }else{ + write_nic_byte(dev,eifs_addr,91 - 0x24); // EIFS: 91 (0x5B) + write_nic_byte(dev,CW_VAL,0xa5); //CW VALUE: 0x37 + //DMESG("using B net params"); + } + } + + else { +#ifdef THOMAS_TURBO + if(priv->ieee80211->current_network.Turbo_Enable && priv->ieee80211->iw_mode == IW_MODE_INFRA){ + write_nic_word(dev,AC_VO_PARAM,0x5114); + write_nic_word(dev,AC_VI_PARAM,0x5114); + write_nic_word(dev,AC_BE_PARAM,0x5114); + write_nic_word(dev,AC_BK_PARAM,0x5114); + } else { + write_nic_word(dev,AC_VO_PARAM,0x731c); + write_nic_word(dev,AC_VI_PARAM,0x731c); + write_nic_word(dev,AC_BE_PARAM,0x731c); + write_nic_word(dev,AC_BK_PARAM,0x731c); + } +#endif + } + + up(&priv->set_chan_sem); +} +void +MacConfig_87BASIC_HardCode(struct net_device *dev) +{ + //============================================================================ + // MACREG.TXT + //============================================================================ + int nLinesRead = 0; + u32 u4bRegOffset, u4bRegValue, u4bPageIndex; + int i; + + nLinesRead=(sizeof(MAC_REG_TABLE)/3)/4; + + for(i = 0; i < nLinesRead; i++) + { + u4bRegOffset=MAC_REG_TABLE[i][0]; + u4bRegValue=MAC_REG_TABLE[i][1]; + u4bPageIndex=MAC_REG_TABLE[i][2]; + + u4bRegOffset|= (u4bPageIndex << 8); + + write_nic_byte(dev, u4bRegOffset, (u8)u4bRegValue); + } + //============================================================================ +} + +static void MacConfig_87BASIC(struct net_device *dev) +{ + MacConfig_87BASIC_HardCode(dev); + + //============================================================================ + + // Follow TID_AC_MAP of WMac. + //PlatformEFIOWrite2Byte(dev, TID_AC_MAP, 0xfa50); + write_nic_word(dev, TID_AC_MAP, 0xfa50); + + // Interrupt Migration, Jong suggested we use set 0x0000 first, 2005.12.14, by rcnjko. + write_nic_word(dev, INT_MIG, 0x0000); + + // Prevent TPC to cause CRC error. Added by Annie, 2006-06-10. + write_nic_dword(dev, 0x1F0, 0x00000000); + write_nic_dword(dev, 0x1F4, 0x00000000); + write_nic_byte(dev, 0x1F8, 0x00); + + // For WiFi 5.2.2.5 Atheros AP performance. Added by Annie, 2006-06-12. + // PlatformIOWrite4Byte(dev, RFTiming, 0x0008e00f); + // Asked for by SD3 CM Lin, 2006.06.27, by rcnjko. + write_nic_dword(dev, RFTiming, 0x00004001); + +#ifdef TODO + // Asked for by Victor, for 87B B-cut Rx FIFO overflow bug, 2006.06.27, by rcnjko. + if(dev->NdisUsbDev.CardInfo.USBIsHigh == FALSE) + { + PlatformEFIOWrite1Byte(dev, 0x24E, 0x01); + } +#endif +} + + +// +// Description: +// Initialize RFE and read Zebra2 version code. +// +// 2005-08-01, by Annie. +// +void +SetupRFEInitialTiming(struct net_device* dev) +{ + //u32 data8, data9; + struct r8180_priv *priv = ieee80211_priv(dev); + + // setup initial timing for RFE + // Set VCO-PDN pin. + write_nic_word(dev, RFPinsOutput, 0x0480); + write_nic_word(dev, RFPinsSelect, 0x2488); + write_nic_word(dev, RFPinsEnable, 0x1FFF); + + mdelay(100); + // Steven recommends: delay 1 sec for setting RF 1.8V. by Annie, 2005-04-28. + mdelay(1000); + + // + // TODO: Read Zebra version code if necessary. + // + priv->rf_chip = RF_ZEBRA2; +} + + +void ZEBRA_Config_87BASIC_HardCode(struct net_device* dev) +{ + u32 i; + u32 addr,data; + u32 u4bRegOffset, u4bRegValue; + + + //============================================================================= + // RADIOCFG.TXT + //============================================================================= + write_rtl8225(dev, 0x00, 0x00b7); mdelay(1); + write_rtl8225(dev, 0x01, 0x0ee0); mdelay(1); + write_rtl8225(dev, 0x02, 0x044d); mdelay(1); + write_rtl8225(dev, 0x03, 0x0441); mdelay(1); + write_rtl8225(dev, 0x04, 0x08c3); mdelay(1); + write_rtl8225(dev, 0x05, 0x0c72); mdelay(1); + write_rtl8225(dev, 0x06, 0x00e6); mdelay(1); + write_rtl8225(dev, 0x07, 0x082a); mdelay(1); + write_rtl8225(dev, 0x08, 0x003f); mdelay(1); + write_rtl8225(dev, 0x09, 0x0335); mdelay(1); + write_rtl8225(dev, 0x0a, 0x09d4); mdelay(1); + write_rtl8225(dev, 0x0b, 0x07bb); mdelay(1); + write_rtl8225(dev, 0x0c, 0x0850); mdelay(1); + write_rtl8225(dev, 0x0d, 0x0cdf); mdelay(1); + write_rtl8225(dev, 0x0e, 0x002b); mdelay(1); + write_rtl8225(dev, 0x0f, 0x0114); mdelay(1); + + write_rtl8225(dev, 0x00, 0x01b7); mdelay(1); + + + for(i=1;i<=95;i++) + { + write_rtl8225(dev, 0x01, i);mdelay(1); + write_rtl8225(dev, 0x02, ZEBRA_RF_RX_GAIN_TABLE[i]); mdelay(1); + //DbgPrint("RF - 0x%x = 0x%x\n", i, ZEBRA_RF_RX_GAIN_TABLE[i]); + } + + write_rtl8225(dev, 0x03, 0x0080); mdelay(1); // write reg 18 + write_rtl8225(dev, 0x05, 0x0004); mdelay(1); // write reg 20 + write_rtl8225(dev, 0x00, 0x00b7); mdelay(1); // switch to reg0-reg15 + //lzm mod for up take too long time 20081201 +#ifdef THOMAS_BEACON + msleep(1000);// Deay 1 sec. //0xfd + //msleep(1000);// Deay 1 sec. //0xfd + //msleep(1000);// Deay 1 sec. //0xfd + msleep(400);// Deay 1 sec. //0xfd +#else + + mdelay(1000); + //mdelay(1000); + //mdelay(1000); + mdelay(400); +#endif + write_rtl8225(dev, 0x02, 0x0c4d); mdelay(1); + //lzm mod for up take too long time 20081201 + //mdelay(1000); + //mdelay(1000); + msleep(100);// Deay 100 ms. //0xfe + msleep(100);// Deay 100 ms. //0xfe + write_rtl8225(dev, 0x02, 0x044d); mdelay(1); + write_rtl8225(dev, 0x00, 0x02bf); mdelay(1); //0x002f disable 6us corner change, 06f--> enable + + //============================================================================= + + //============================================================================= + // CCKCONF.TXT + //============================================================================= + /* + u4bRegOffset=0x41; + u4bRegValue=0xc8; + + //DbgPrint("\nCCK- 0x%x = 0x%x\n", u4bRegOffset, u4bRegValue); + WriteBB(dev, (0x01000080 | (u4bRegOffset & 0x7f) | ((u4bRegValue & 0xff) << 8))); + */ + + + //============================================================================= + + //============================================================================= + // Follow WMAC RTL8225_Config() + //============================================================================= +// // +// // enable EEM0 and EEM1 in 9346CR +// PlatformEFIOWrite1Byte(dev, CR9346, PlatformEFIORead1Byte(dev, CR9346)|0xc0); +// // enable PARM_En in Config3 +// PlatformEFIOWrite1Byte(dev, CONFIG3, PlatformEFIORead1Byte(dev, CONFIG3)|0x40); +// +// PlatformEFIOWrite4Byte(dev, AnaParm2, ANAPARM2_ASIC_ON); //0x727f3f52 +// PlatformEFIOWrite4Byte(dev, AnaParm, ANAPARM_ASIC_ON); //0x45090658 + + // power control + write_nic_byte(dev, CCK_TXAGC, 0x03); + write_nic_byte(dev, OFDM_TXAGC, 0x07); + write_nic_byte(dev, ANTSEL, 0x03); + +// // disable PARM_En in Config3 +// PlatformEFIOWrite1Byte(dev, CONFIG3, PlatformEFIORead1Byte(dev, CONFIG3)&0xbf); +// // disable EEM0 and EEM1 in 9346CR +// PlatformEFIOWrite1Byte(dev, CR9346, PlatformEFIORead1Byte(dev, CR9346)&0x3f); + //============================================================================= + + //============================================================================= + // AGC.txt + //============================================================================= + //write_nic_dword( dev, PhyAddr, 0x00001280); // Annie, 2006-05-05 + //write_phy_ofdm( dev, 0x00, 0x12); // David, 2006-08-01 + write_phy_ofdm( dev, 0x80, 0x12); // David, 2006-08-09 + + for (i=0; i<128; i++) + { + //DbgPrint("AGC - [%x+1] = 0x%x\n", i, ZEBRA_AGC[i+1]); + + data = ZEBRA_AGC[i+1]; + data = data << 8; + data = data | 0x0000008F; + + addr = i + 0x80; //enable writing AGC table + addr = addr << 8; + addr = addr | 0x0000008E; + + write_phy_ofdm(dev,data&0x7f,(data>>8)&0xff); + write_phy_ofdm(dev,addr&0x7f,(addr>>8)&0xff); + write_phy_ofdm(dev,0x0E,0x00); + } + + //write_nic_dword(dev, PhyAddr, 0x00001080); // Annie, 2006-05-05 + //write_phy_ofdm( dev, 0x00, 0x10); // David, 2006-08-01 + write_phy_ofdm( dev, 0x80, 0x10); // David, 2006-08-09 + + //============================================================================= + + //============================================================================= + // OFDMCONF.TXT + //============================================================================= + + for(i=0; i<60; i++) + { + u4bRegOffset=i; + u4bRegValue=OFDM_CONFIG[i]; + //u4bRegValue=OFDM_CONFIG3m82[i]; + + // write_nic_dword(dev,PhyAddr,(0x00000080 | (u4bRegOffset & 0x7f) | ((u4bRegValue & 0xff) << 8))); + write_phy_ofdm(dev,i,u4bRegValue); + } + + + //============================================================================= +} + +void ZEBRA_Config_87BASIC(struct net_device *dev) +{ + ZEBRA_Config_87BASIC_HardCode(dev); +} +//by amy for DIG +// +// Description: +// Update initial gain into PHY. +// +void +UpdateCCKThreshold( + struct net_device *dev + ) +{ + struct r8180_priv *priv = ieee80211_priv(dev); + // Update CCK Power Detection(0x41) value. + switch(priv->StageCCKTh) + { + case 0: +// printk("Update CCK Stage 0: 88 \n"); + write_phy_cck(dev, 0xc1, 0x88);mdelay(1); + break; + + case 1: +// printk("Update CCK Stage 1: 98 \n"); + write_phy_cck(dev, 0xc1, 0x98);mdelay(1); + break; + + case 2: +// printk("Update CCK Stage 2: C8 \n"); + write_phy_cck(dev, 0xc1, 0xC8);mdelay(1); + break; + + case 3: +// printk("Update CCK Stage 3: D8 \n"); + write_phy_cck(dev, 0xc1, 0xD8);mdelay(1); + break; + + default: +// printk("Update CCK Stage %d ERROR!\n", pHalData->StageCCKTh); + break; + } +} +// +// Description: +// Update initial gain into PHY. +// +void +UpdateInitialGain( + struct net_device *dev + ) +{ + struct r8180_priv *priv = ieee80211_priv(dev); + //u8 u1Tmp=0; + + //printk("UpdateInitialGain(): InitialGain: %d RFChipID: %d\n", priv->InitialGain, priv->rf_chip); + + switch(priv->rf_chip) + { + case RF_ZEBRA: + case RF_ZEBRA2: + + // + // Note: + // Whenever we update this gain table, we should be careful about those who call it. + // Functions which call UpdateInitialGain as follows are important: + // (1)StaRateAdaptive87B + // (2)DIG_Zebra + // (3)ActSetWirelessMode8187 (when the wireless mode is "B" mode, we set the + // OFDM[0x17] = 0x26 to improve the Rx sensitivity). + // By Bruce, 2007-06-01. + // + + // + // SD3 C.M. Lin Initial Gain Table, by Bruce, 2007-06-01. + // + switch(priv->InitialGain) + { + case 1: //m861dBm + DMESG("RTL8187 + 8225 Initial Gain State 1: -82 dBm "); + write_phy_ofdm(dev, 0x97, 0x26); mdelay(1); + write_phy_ofdm(dev, 0xa4, 0x86); mdelay(1); + write_phy_ofdm(dev, 0x85, 0xfa); mdelay(1); + break; + + case 2: //m862dBm + DMESG("RTL8187 + 8225 Initial Gain State 2: -78 dBm "); + write_phy_ofdm(dev, 0x97, 0x36); mdelay(1);// Revise 0x26 to 0x36, by Roger, 2007.05.03. + write_phy_ofdm(dev, 0xa4, 0x86); mdelay(1); + write_phy_ofdm(dev, 0x85, 0xfa); mdelay(1); + break; + + case 3: //m863dBm + DMESG("RTL8187 + 8225 Initial Gain State 3: -78 dBm "); + write_phy_ofdm(dev, 0x97, 0x36); mdelay(1);// Revise 0x26 to 0x36, by Roger, 2007.05.03. + write_phy_ofdm(dev, 0xa4, 0x86); mdelay(1); + write_phy_ofdm(dev, 0x85, 0xfb); mdelay(1); + break; + + case 4: //m864dBm + DMESG("RTL8187 + 8225 Initial Gain State 4: -74 dBm "); + write_phy_ofdm(dev, 0x97, 0x46); mdelay(1);// Revise 0x26 to 0x36, by Roger, 2007.05.03. + write_phy_ofdm(dev, 0xa4, 0x86); mdelay(1); + write_phy_ofdm(dev, 0x85, 0xfb); mdelay(1); + break; + + case 5: //m82dBm + DMESG("RTL8187 + 8225 Initial Gain State 5: -74 dBm "); + write_phy_ofdm(dev, 0x97, 0x46); mdelay(1); + write_phy_ofdm(dev, 0xa4, 0x96); mdelay(1); + write_phy_ofdm(dev, 0x85, 0xfb); mdelay(1); + break; + + case 6: //m78dBm + DMESG("RTL8187 + 8225 Initial Gain State 6: -70 dBm "); + write_phy_ofdm(dev, 0x97, 0x56); mdelay(1); + write_phy_ofdm(dev, 0xa4, 0x96); mdelay(1); + write_phy_ofdm(dev, 0x85, 0xfc); mdelay(1); + break; + + case 7: //m74dBm + DMESG("RTL8187 + 8225 Initial Gain State 7: -70 dBm "); + write_phy_ofdm(dev, 0x97, 0x56); mdelay(1); + write_phy_ofdm(dev, 0xa4, 0xa6); mdelay(1); + write_phy_ofdm(dev, 0x85, 0xfc); mdelay(1); + break; + + // By Bruce, 2007-03-29. + case 8: + write_phy_ofdm(dev, 0x97, 0x66); mdelay(1); + write_phy_ofdm(dev, 0xa4, 0xb6); mdelay(1); + write_phy_ofdm(dev, 0x85, 0xfc); mdelay(1); + break; + + default: //MP + DMESG("RTL8187 + 8225 Initial Gain State: -82 dBm (default), InitialGain(%d)", priv->InitialGain); + write_phy_ofdm(dev, 0x97, 0x26); mdelay(1); + write_phy_ofdm(dev, 0xa4, 0x86); mdelay(1); + write_phy_ofdm(dev, 0x85, 0xfa); mdelay(1); + break; + } + break; + + default: + break; + } +} +//by amy for DIG +void PhyConfig8187(struct net_device *dev) +{ + struct r8180_priv *priv = ieee80211_priv(dev); + u8 btConfig4; + + btConfig4 = read_nic_byte(dev, CONFIG4); + priv->RFProgType = (btConfig4 & 0x03); + + + + switch(priv->rf_chip) + { + case RF_ZEBRA2: + ZEBRA_Config_87BASIC(dev); + break; + } + if(priv->bDigMechanism) + { + if(priv->InitialGain == 0) + priv->InitialGain = 4; + DMESG("DIG is enabled, set default initial gain index to %d", priv->InitialGain); + } + + // By Bruce, 2007-03-29. + UpdateCCKThreshold(dev); + // Update initial gain after PhyConfig comleted, asked for by SD3 CMLin. + UpdateInitialGain(dev); + return ; +} + +u8 GetSupportedWirelessMode8187(struct net_device* dev) +{ + u8 btSupportedWirelessMode; + struct r8180_priv *priv = ieee80211_priv(dev); + + btSupportedWirelessMode = 0; + + switch(priv->rf_chip) + { + case RF_ZEBRA: + case RF_ZEBRA2: + btSupportedWirelessMode = (WIRELESS_MODE_B | WIRELESS_MODE_G); + break; + default: + btSupportedWirelessMode = WIRELESS_MODE_B; + break; + } + return btSupportedWirelessMode; +} + +void ActUpdateChannelAccessSetting(struct net_device *dev, + int WirelessMode, + PCHANNEL_ACCESS_SETTING ChnlAccessSetting) +{ + AC_CODING eACI; + AC_PARAM AcParam; +#ifdef TODO + PSTA_QOS pStaQos = Adapter->MgntInfo.pStaQos; +#endif + //bool bFollowLegacySetting = false; + + + switch( WirelessMode ) + { + case WIRELESS_MODE_A: + ChnlAccessSetting->SIFS_Timer = 0x22; + ChnlAccessSetting->DIFS_Timer = 34; // 34 = 16 + 2*9. 2006.06.07, by rcnjko. + ChnlAccessSetting->SlotTimeTimer = 9; + ChnlAccessSetting->EIFS_Timer = 23; + ChnlAccessSetting->CWminIndex = 4; + ChnlAccessSetting->CWmaxIndex = 10; + break; + + case WIRELESS_MODE_B: + ChnlAccessSetting->SIFS_Timer = 0x22; + ChnlAccessSetting->DIFS_Timer = 50; // 50 = 10 + 2*20. 2006.06.07, by rcnjko. + ChnlAccessSetting->SlotTimeTimer = 20; + ChnlAccessSetting->EIFS_Timer = 91; + ChnlAccessSetting->CWminIndex = 5; + ChnlAccessSetting->CWmaxIndex = 10; + break; + + case WIRELESS_MODE_G: + // + // + // TODO: We still don't know how to set up these registers, just follow WMAC to + // verify 8185B FPAG. + // + // + // Jong said CWmin/CWmax register are not functional in 8185B, + // so we shall fill channel access realted register into AC parameter registers, + // even in nQBss. + // + ChnlAccessSetting->SIFS_Timer = 0x22; // Suggested by Jong, 2005.12.08. + ChnlAccessSetting->SlotTimeTimer = 9; // 2006.06.07, by rcnjko. + ChnlAccessSetting->DIFS_Timer = 28; // 28 = 10 + 2*9. 2006.06.07, by rcnjko. + ChnlAccessSetting->EIFS_Timer = 0x5B; // Suggested by wcchu, it is the default value of EIFS register, 2005.12.08. +#ifdef TODO + switch (Adapter->NdisUsbDev.CWinMaxMin) +#else + switch (2) +#endif + { + case 0:// 0: [max:7 min:1 ] + ChnlAccessSetting->CWminIndex = 1; + ChnlAccessSetting->CWmaxIndex = 7; + break; + case 1:// 1: [max:7 min:2 ] + ChnlAccessSetting->CWminIndex = 2; + ChnlAccessSetting->CWmaxIndex = 7; + break; + case 2:// 2: [max:7 min:3 ] + ChnlAccessSetting->CWminIndex = 3; + ChnlAccessSetting->CWmaxIndex = 7; + break; + case 3:// 3: [max:9 min:1 ] + ChnlAccessSetting->CWminIndex = 1; + ChnlAccessSetting->CWmaxIndex = 9; + break; + case 4:// 4: [max:9 min:2 ] + ChnlAccessSetting->CWminIndex = 2; + ChnlAccessSetting->CWmaxIndex = 9; + break; + case 5:// 5: [max:9 min:3 ] + ChnlAccessSetting->CWminIndex = 3; + ChnlAccessSetting->CWmaxIndex = 9; + break; + case 6:// 6: [max:A min:5 ] + ChnlAccessSetting->CWminIndex = 5; + ChnlAccessSetting->CWmaxIndex = 10; + break; + case 7:// 7: [max:A min:4 ] + ChnlAccessSetting->CWminIndex = 4; + ChnlAccessSetting->CWmaxIndex = 10; + break; + + default: + ChnlAccessSetting->CWminIndex = 1; + ChnlAccessSetting->CWmaxIndex = 7; + break; + } +#ifdef TODO + if( Adapter->MgntInfo.OpMode == RT_OP_MODE_IBSS) + { + ChnlAccessSetting->CWminIndex= 4; + ChnlAccessSetting->CWmaxIndex= 10; + } +#endif + break; + } + + + write_nic_byte(dev, SIFS, ChnlAccessSetting->SIFS_Timer); +//{ update slot time related by david, 2006-7-21 + write_nic_byte(dev, SLOT, ChnlAccessSetting->SlotTimeTimer); // Rewrited from directly use PlatformEFIOWrite1Byte(), by Annie, 2006-03-29. +#ifdef TODO + if(pStaQos->CurrentQosMode > QOS_DISABLE) + { + for(eACI = 0; eACI < AC_MAX; eACI++) + { + Adapter->HalFunc.SetHwRegHandler(Adapter, HW_VAR_AC_PARAM, \ + (pu1Byte)(&(pStaQos->WMMParamEle.AcParam[eACI])) ); + } + } + else +#endif + { + u8 u1bAIFS = aSifsTime + (2 * ChnlAccessSetting->SlotTimeTimer ); + + write_nic_byte(dev, AC_VO_PARAM, u1bAIFS); + write_nic_byte(dev, AC_VI_PARAM, u1bAIFS); + write_nic_byte(dev, AC_BE_PARAM, u1bAIFS); + write_nic_byte(dev, AC_BK_PARAM, u1bAIFS); + } +//} + + write_nic_byte(dev, EIFS_8187B, ChnlAccessSetting->EIFS_Timer); + write_nic_byte(dev, AckTimeOutReg, 0x5B); // Suggested by wcchu, it is the default value of EIFS register, 2005.12.08. +#ifdef TODO + // Update ECWmin/ECWmax, AIFS, TXOP Limit of each AC to the value defined by SPEC. + if( pStaQos->CurrentQosMode > QOS_DISABLE ) + { // QoS mode. + if(pStaQos->QBssWirelessMode == WirelessMode) + { + // Follow AC Parameters of the QBSS. + for(eACI = 0; eACI < AC_MAX; eACI++) + { + Adapter->HalFunc.SetHwRegHandler(Adapter, HW_VAR_AC_PARAM, (pu1Byte)(&(pStaQos->WMMParamEle.AcParam[eACI])) ); + } + } + else + { + // Follow Default WMM AC Parameters. + bFollowLegacySetting = TRUE; + } + } + else + { // Legacy 802.11. + bFollowLegacySetting = TRUE; + } + + if(bFollowLegacySetting) +#endif + if(true) + { + // + // Follow 802.11 seeting to AC parameter, all AC shall use the same parameter. + // 2005.12.01, by rcnjko. + // + AcParam.longData = 0; + AcParam.f.AciAifsn.f.AIFSN = 2; // Follow 802.11 DIFS. + AcParam.f.AciAifsn.f.ACM = 0; + AcParam.f.Ecw.f.ECWmin = ChnlAccessSetting->CWminIndex; // Follow 802.11 CWmin. + AcParam.f.Ecw.f.ECWmax = ChnlAccessSetting->CWmaxIndex; // Follow 802.11 CWmax. + AcParam.f.TXOPLimit = 0; + for(eACI = 0; eACI < AC_MAX; eACI++) + { + AcParam.f.AciAifsn.f.ACI = (u8)eACI; + { + PAC_PARAM pAcParam = (PAC_PARAM)(&AcParam); + AC_CODING eACI; + u8 u1bAIFS; + u32 u4bAcParam; + + // Retrive paramters to udpate. + eACI = pAcParam->f.AciAifsn.f.ACI; + u1bAIFS = pAcParam->f.AciAifsn.f.AIFSN * ChnlAccessSetting->SlotTimeTimer + aSifsTime; + u4bAcParam = ( (((u32)(pAcParam->f.TXOPLimit)) << AC_PARAM_TXOP_LIMIT_OFFSET) | + (((u32)(pAcParam->f.Ecw.f.ECWmax)) << AC_PARAM_ECW_MAX_OFFSET) | + (((u32)(pAcParam->f.Ecw.f.ECWmin)) << AC_PARAM_ECW_MIN_OFFSET) | + (((u32)u1bAIFS) << AC_PARAM_AIFS_OFFSET)); + + switch(eACI) + { + case AC1_BK: + write_nic_dword(dev, AC_BK_PARAM, u4bAcParam); + break; + + case AC0_BE: + write_nic_dword(dev, AC_BE_PARAM, u4bAcParam); + break; + + case AC2_VI: + write_nic_dword(dev, AC_VI_PARAM, u4bAcParam); + break; + + case AC3_VO: + write_nic_dword(dev, AC_VO_PARAM, u4bAcParam); + break; + + default: + printk(KERN_WARNING "SetHwReg8185(): invalid ACI: %d !\n", eACI); + break; + } + + // Cehck ACM bit. + // If it is set, immediately set ACM control bit to downgrading AC for passing WMM testplan. Annie, 2005-12-13. + //write_nic_byte(dev, ACM_CONTROL, pAcParam->f.AciAifsn); + { + PACI_AIFSN pAciAifsn = (PACI_AIFSN)(&pAcParam->f.AciAifsn); + AC_CODING eACI = pAciAifsn->f.ACI; + + //modified Joseph + //for 8187B AsynIORead issue +#ifdef TODO + u8 AcmCtrl = pHalData->AcmControl; +#else + u8 AcmCtrl = 0; +#endif + if( pAciAifsn->f.ACM ) + { // ACM bit is 1. + switch(eACI) + { + case AC0_BE: + AcmCtrl |= (BEQ_ACM_EN|BEQ_ACM_CTL|ACM_HW_EN); // or 0x21 + break; + + case AC2_VI: + AcmCtrl |= (VIQ_ACM_EN|VIQ_ACM_CTL|ACM_HW_EN); // or 0x42 + break; + + case AC3_VO: + AcmCtrl |= (VOQ_ACM_EN|VOQ_ACM_CTL|ACM_HW_EN); // or 0x84 + break; + + default: + printk(KERN_WARNING "SetHwReg8185(): [HW_VAR_ACM_CTRL] ACM set\ + failed: eACI is %d\n", eACI ); + break; + } + } + else + { // ACM bit is 0. + switch(eACI) + { + case AC0_BE: + AcmCtrl &= ( (~BEQ_ACM_EN) & (~BEQ_ACM_CTL) & (~ACM_HW_EN) ); // and 0xDE + break; + + case AC2_VI: + AcmCtrl &= ( (~VIQ_ACM_EN) & (~VIQ_ACM_CTL) & (~ACM_HW_EN) ); // and 0xBD + break; + + case AC3_VO: + AcmCtrl &= ( (~VOQ_ACM_EN) & (~VOQ_ACM_CTL) & (~ACM_HW_EN) ); // and 0x7B + break; + + default: + break; + } + } + + //printk(KERN_WARNING "SetHwReg8185(): [HW_VAR_ACM_CTRL] Write 0x%X\n", AcmCtrl); + +#ifdef TO_DO + pHalData->AcmControl = AcmCtrl; +#endif + write_nic_byte(dev, ACM_CONTROL, AcmCtrl); + } + } + } + } +} + +void ActSetWirelessMode8187(struct net_device* dev, u8 btWirelessMode) +{ + struct r8180_priv *priv = ieee80211_priv(dev); + struct ieee80211_device *ieee = priv->ieee80211; + //PMGNT_INFO pMgntInfo = &(pAdapter->MgntInfo); + u8 btSupportedWirelessMode = GetSupportedWirelessMode8187(dev); + + if( (btWirelessMode & btSupportedWirelessMode) == 0 ) + { // Don't switch to unsupported wireless mode, 2006.02.15, by rcnjko. + printk(KERN_WARNING "ActSetWirelessMode8187(): WirelessMode(%d) is not supported (%d)!\n", + btWirelessMode, btSupportedWirelessMode); + return; + } + + // 1. Assign wireless mode to swtich if necessary. + if( (btWirelessMode == WIRELESS_MODE_AUTO) || + (btWirelessMode & btSupportedWirelessMode) == 0 ) + { + if((btSupportedWirelessMode & WIRELESS_MODE_A)) + { + btWirelessMode = WIRELESS_MODE_A; + } + else if((btSupportedWirelessMode & WIRELESS_MODE_G)) + { + btWirelessMode = WIRELESS_MODE_G; + } + else if((btSupportedWirelessMode & WIRELESS_MODE_B)) + { + btWirelessMode = WIRELESS_MODE_B; + } + else + { + printk(KERN_WARNING "MptActSetWirelessMode8187(): No valid wireless mode supported, \ + btSupportedWirelessMode(%x)!!!\n", btSupportedWirelessMode); + btWirelessMode = WIRELESS_MODE_B; + } + } + + // 2. Swtich band. + switch(priv->rf_chip) + { + case RF_ZEBRA: + case RF_ZEBRA2: + { + // Update current wireless mode if we swtich to specified band successfully. + ieee->mode = (WIRELESS_MODE)btWirelessMode; + } + break; + + default: + printk(KERN_WARNING "MptActSetWirelessMode8187(): unsupported RF: 0x%X !!!\n", priv->rf_chip); + break; + } + + // 4. Change related setting. + if( ieee->mode == WIRELESS_MODE_A ){ + DMESG("WIRELESS_MODE_A"); + } + else if(ieee->mode == WIRELESS_MODE_B ){ + DMESG("WIRELESS_MODE_B"); + } + else if( ieee->mode == WIRELESS_MODE_G ){ + DMESG("WIRELESS_MODE_G"); + } + ActUpdateChannelAccessSetting(dev, ieee->mode, &priv->ChannelAccessSetting ); +//by amy 0305 +#ifdef TODO + if(ieee->mode == WIRELESS_MODE_B && priv->InitialGain > pHalData->RegBModeGainStage) + { + pHalData->InitialGain = pHalData->RegBModeGainStage; // B mode, OFDM[0x17] = 26. + RT_TRACE(COMP_INIT | COMP_DIG, DBG_LOUD, ("ActSetWirelessMode8187(): update init_gain to index %d for B mode\n",pHalData->InitialGain)); + PlatformScheduleWorkItem( &(pHalData->UpdateDigWorkItem) ); + } +// pAdapter->MgntInfo.dot11CurrentWirelessMode = pHalData->CurrentWirelessMode; +// MgntSetRegdot11OperationalRateSet( pAdapter ); +#endif +//by amy 0305 +} + + +void +InitializeExtraRegsOn8185(struct net_device *dev) +{ + struct r8180_priv *priv = ieee80211_priv(dev); + struct ieee80211_device *ieee = priv->ieee80211; + //RTL8185_TODO: Determine Retrylimit, TxAGC, AutoRateFallback control. + bool bUNIVERSAL_CONTROL_RL = false; // Enable per-packet tx retry, 2005.03.31, by rcnjko. + bool bUNIVERSAL_CONTROL_AGC = true;//false; + bool bUNIVERSAL_CONTROL_ANT = true;//false; + bool bAUTO_RATE_FALLBACK_CTL = true; + u8 val8; + + // Set up ACK rate. + // Suggested by wcchu, 2005.08.25, by rcnjko. + // 1. Initialize (MinRR, MaxRR) to (6,24) for A/G. + // 2. MUST Set RR before BRSR. + // 3. CCK must be basic rate. + if((ieee->mode == IEEE_G)||(ieee->mode == IEEE_A)) + { + write_nic_word(dev, BRSR_8187B, 0x0fff); + } + else + { + write_nic_word(dev, BRSR_8187B, 0x000f); + } + + + // Retry limit + val8 = read_nic_byte(dev, CW_CONF); + if(bUNIVERSAL_CONTROL_RL) + { + val8 &= (~CW_CONF_PERPACKET_RETRY_LIMIT); + } + else + { + val8 |= CW_CONF_PERPACKET_RETRY_LIMIT; + } + + write_nic_byte(dev, CW_CONF, val8); + + // Tx AGC + val8 = read_nic_byte(dev, TX_AGC_CTL); + if(bUNIVERSAL_CONTROL_AGC) + { + val8 &= (~TX_AGC_CTL_PER_PACKET_TXAGC); + write_nic_byte(dev, CCK_TXAGC, 128); + write_nic_byte(dev, OFDM_TXAGC, 128); + } + else + { + val8 |= TX_AGC_CTL_PER_PACKET_TXAGC; + } + write_nic_byte(dev, TX_AGC_CTL, val8); + + // Tx Antenna including Feedback control + val8 = read_nic_byte(dev, TX_AGC_CTL); + + if(bUNIVERSAL_CONTROL_ANT) + { + write_nic_byte(dev, ANTSEL, 0x00); + val8 &= (~TXAGC_CTL_PER_PACKET_ANT_SEL); + } + else + { + val8 |= TXAGC_CTL_PER_PACKET_ANT_SEL; + } + write_nic_byte(dev, TX_AGC_CTL, val8); + + // Auto Rate fallback control + val8 = read_nic_byte(dev, RATE_FALLBACK); + if( bAUTO_RATE_FALLBACK_CTL ) + { + val8 |= RATE_FALLBACK_CTL_ENABLE | RATE_FALLBACK_CTL_AUTO_STEP0; + + // We shall set up the ARFR according to user's setting. + write_nic_word(dev, ARFR, 0x0fff); // set 1M ~ 54M + } + else + { + val8 &= (~RATE_FALLBACK_CTL_ENABLE); + } + write_nic_byte(dev, RATE_FALLBACK, val8); + +} +/////////////////////////// +void rtl8225z2_rf_init(struct net_device *dev) +{ + + struct r8180_priv *priv = ieee80211_priv(dev); + if (NIC_8187B == priv->card_8187){ + struct ieee80211_device *ieee = priv->ieee80211; + u8 InitWirelessMode; + u8 SupportedWirelessMode; + bool bInvalidWirelessMode = false; + InitializeExtraRegsOn8185(dev); + + write_nic_byte(dev, MSR, read_nic_byte(dev,MSR) & 0xf3); // default network type to 'No Link' + //{to avoid tx stall + write_nic_byte(dev, MSR, read_nic_byte(dev, MSR)|MSR_LINK_ENEDCA);//should always set ENDCA bit + write_nic_byte(dev, ACM_CONTROL, priv->AcmControl); + + write_nic_word(dev, BcnIntv, 100); + write_nic_word(dev, AtimWnd, 2); + write_nic_word(dev, FEMR, 0xFFFF); + //LED TYPE + { + write_nic_byte(dev, CONFIG1,((read_nic_byte(dev, CONFIG1)&0x3f)|0x80)); //turn on bit 5:Clkrun_mode + } + write_nic_byte(dev, CR9346, 0x0); // disable config register write + + //{ add some info here + write_nic_dword(dev, MAC0, ((u32*)dev->dev_addr)[0]); + write_nic_word(dev, MAC4, ((u32*)dev->dev_addr)[1] & 0xffff ); + + write_nic_byte(dev, WPA_CONFIG, 0); + //} + + MacConfig_87BASIC(dev); + + // Override the RFSW_CTRL (MAC offset 0x272-0x273), 2006.06.07, by rcnjko. + write_nic_word(dev, RFSW_CTRL, 0x569a); +#ifdef JOHN_TKIP + { + void CamResetAllEntry(struct net_device *dev); + void EnableHWSecurityConfig8187(struct net_device *dev); + CamResetAllEntry(dev); + EnableHWSecurityConfig8187(dev); + write_nic_word(dev, AESMSK_FC, AESMSK_FC_DEFAULT); mdelay(1); + write_nic_word(dev, AESMSK_SC, AESMSK_SC_DEFAULT); mdelay(1); + write_nic_word(dev, AESMSK_QC, AESMSK_QC_DEFAULT); mdelay(1); + } +#endif + //----------------------------------------------------------------------------- + // Set up PHY related. + //----------------------------------------------------------------------------- + // Enable Config3.PARAM_En to revise AnaaParm. + write_nic_byte(dev, CR9346, 0xC0); + write_nic_byte(dev, CONFIG3, read_nic_byte(dev,CONFIG3)|CONFIG3_PARM_En); + write_nic_byte(dev, CR9346, 0x0); + + // Initialize RFE and read Zebra2 version code. Added by Annie, 2005-08-01. + SetupRFEInitialTiming(dev); + // PHY config. + PhyConfig8187(dev); + + // We assume RegWirelessMode has already been initialized before, + // however, we has to validate the wireless mode here and provide a reasonble + // initialized value if necessary. 2005.01.13, by rcnjko. + SupportedWirelessMode = GetSupportedWirelessMode8187(dev); + + if((ieee->mode != WIRELESS_MODE_B) && + (ieee->mode != WIRELESS_MODE_G) && + (ieee->mode != WIRELESS_MODE_A) && + (ieee->mode != WIRELESS_MODE_AUTO)) + { // It should be one of B, G, A, or AUTO. + bInvalidWirelessMode = true; + } + else + { // One of B, G, A, or AUTO. + // Check if the wireless mode is supported by RF. + if( (ieee->mode != WIRELESS_MODE_AUTO) && + (ieee->mode & SupportedWirelessMode) == 0 ) + { + bInvalidWirelessMode = true; + } + } + + if(bInvalidWirelessMode || ieee->mode==WIRELESS_MODE_AUTO) + { // Auto or other invalid value. + // Assigne a wireless mode to initialize. + if((SupportedWirelessMode & WIRELESS_MODE_A)) + { + InitWirelessMode = WIRELESS_MODE_A; + } + else if((SupportedWirelessMode & WIRELESS_MODE_G)) + { + + InitWirelessMode = WIRELESS_MODE_G; + } + else if((SupportedWirelessMode & WIRELESS_MODE_B)) + { + + InitWirelessMode = WIRELESS_MODE_B; + } + else + { + printk(KERN_WARNING + "InitializeAdapter8187(): No valid wireless mode supported, SupportedWirelessMode(%x)!!!\n", + SupportedWirelessMode); + InitWirelessMode = WIRELESS_MODE_B; + } + + // Initialize RegWirelessMode if it is not a valid one. + if(bInvalidWirelessMode) + { + ieee->mode = (WIRELESS_MODE)InitWirelessMode; + } + } + else + { // One of B, G, A. + InitWirelessMode = ieee->mode; + } + ActSetWirelessMode8187(dev, (u8)(InitWirelessMode)); + {//added for init gain + write_phy_ofdm(dev, 0x97, 0x46); mdelay(1); + write_phy_ofdm(dev, 0xa4, 0xb6); mdelay(1); + write_phy_ofdm(dev, 0x85, 0xfc); mdelay(1); + write_phy_cck(dev, 0xc1, 0x88); mdelay(1); + } + + } + else{ + int i; + short channel = 1; + u16 brsr; + u32 data,addr; + + priv->chan = channel; + + rtl8180_set_anaparam(dev, RTL8225_ANAPARAM_ON); + + if(priv->card_type == USB) + rtl8225_host_usb_init(dev); + else + rtl8225_host_pci_init(dev); + + write_nic_dword(dev, RF_TIMING, 0x000a8008); + + brsr = read_nic_word(dev, BRSR_8187); + + write_nic_word(dev, BRSR_8187, 0xffff); + + + write_nic_dword(dev, RF_PARA, 0x100044); + + #if 1 //0->1 + rtl8180_set_mode(dev, EPROM_CMD_CONFIG); + write_nic_byte(dev, CONFIG3, 0x44); + rtl8180_set_mode(dev, EPROM_CMD_NORMAL); + #endif + + + rtl8185_rf_pins_enable(dev); + + // mdelay(1000); + + write_rtl8225(dev, 0x0, 0x2bf); mdelay(1); + + + write_rtl8225(dev, 0x1, 0xee0); mdelay(1); + + write_rtl8225(dev, 0x2, 0x44d); mdelay(1); + + write_rtl8225(dev, 0x3, 0x441); mdelay(1); + + + write_rtl8225(dev, 0x4, 0x8c3);mdelay(1); + + + + write_rtl8225(dev, 0x5, 0xc72);mdelay(1); + // } + + write_rtl8225(dev, 0x6, 0xe6); mdelay(1); + + write_rtl8225(dev, 0x7, ((priv->card_type == USB)? 0x82a : rtl8225_chan[channel])); mdelay(1); + + write_rtl8225(dev, 0x8, 0x3f); mdelay(1); + + write_rtl8225(dev, 0x9, 0x335); mdelay(1); + + write_rtl8225(dev, 0xa, 0x9d4); mdelay(1); + + write_rtl8225(dev, 0xb, 0x7bb); mdelay(1); + + write_rtl8225(dev, 0xc, 0x850); mdelay(1); + + + write_rtl8225(dev, 0xd, 0xcdf); mdelay(1); + + write_rtl8225(dev, 0xe, 0x2b); mdelay(1); + + write_rtl8225(dev, 0xf, 0x114); + + + mdelay(100); + + + //if(priv->card_type != USB) /* maybe not needed even for 8185 */ + // write_rtl8225(dev, 0x7, rtl8225_chan[channel]); + + write_rtl8225(dev, 0x0, 0x1b7); + + for(i=0;i<95;i++){ + write_rtl8225(dev, 0x1, (u8)(i+1)); + /* version B & C & D*/ + write_rtl8225(dev, 0x2, rtl8225z2_rxgain[i]); + } + //write_rtl8225(dev, 0x3, 0x80); + write_rtl8225(dev, 0x3, 0x2); + write_rtl8225(dev, 0x5, 0x4); + + write_rtl8225(dev, 0x0, 0xb7); + + write_rtl8225(dev, 0x2, 0xc4d); + + if(priv->card_type == USB){ + // force_pci_posting(dev); + mdelay(200); + + write_rtl8225(dev, 0x2, 0x44d); + + // force_pci_posting(dev); + mdelay(200); + + }//End of if(priv->card_type == USB) + /* FIXME!! rtl8187 we have to check if calibrarion + * is successful and eventually cal. again (repeat + * the two write on reg 2) + */ + // Check for calibration status, 2005.11.17, + data = read_rtl8225(dev, 6); + if (!(data&0x00000080)) + { + write_rtl8225(dev, 0x02, 0x0c4d); + force_pci_posting(dev); mdelay(200); + write_rtl8225(dev, 0x02, 0x044d); + force_pci_posting(dev); mdelay(100); + data = read_rtl8225(dev, 6); + if (!(data&0x00000080)) + { + DMESGW("RF Calibration Failed!!!!\n"); + } + } + //force_pci_posting(dev); + + mdelay(200); //200 for 8187 + + + // //if(priv->card_type != USB){ + // write_rtl8225(dev, 0x2, 0x44d); + // write_rtl8225(dev, 0x7, rtl8225_chan[channel]); + // write_rtl8225(dev, 0x2, 0x47d); + // + // force_pci_posting(dev); + // mdelay(100); + // + // write_rtl8225(dev, 0x2, 0x44d); + // //} + + write_rtl8225(dev, 0x0, 0x2bf); + + if(priv->card_type != USB) + rtl8185_rf_pins_enable(dev); + //set up ZEBRA AGC table, 2005.11.17, + for(i=0;i<128;i++){ + data = rtl8225_agc[i]; + + addr = i + 0x80; //enable writing AGC table + write_phy_ofdm(dev, 0xb, data); + + mdelay(1); + write_phy_ofdm(dev, 0xa, addr); + + mdelay(1); + } + + force_pci_posting(dev); + mdelay(1); + + write_phy_ofdm(dev, 0x0, 0x1); mdelay(1); + write_phy_ofdm(dev, 0x1, 0x2); mdelay(1); + write_phy_ofdm(dev, 0x2, ((priv->card_type == USB)? 0x42 : 0x62)); mdelay(1); + write_phy_ofdm(dev, 0x3, 0x0); mdelay(1); + write_phy_ofdm(dev, 0x4, 0x0); mdelay(1); + write_phy_ofdm(dev, 0x5, 0x0); mdelay(1); + write_phy_ofdm(dev, 0x6, 0x40); mdelay(1); + write_phy_ofdm(dev, 0x7, 0x0); mdelay(1); + write_phy_ofdm(dev, 0x8, 0x40); mdelay(1); + write_phy_ofdm(dev, 0x9, 0xfe); mdelay(1); + + write_phy_ofdm(dev, 0xa, 0x8); mdelay(1); + + //write_phy_ofdm(dev, 0x18, 0xef); + // } + //} + write_phy_ofdm(dev, 0xb, 0x80); mdelay(1); + + write_phy_ofdm(dev, 0xc, 0x1);mdelay(1); + + + //if(priv->card_type != USB) + write_phy_ofdm(dev, 0xd, 0x43); + + write_phy_ofdm(dev, 0xe, 0xd3);mdelay(1); + + write_phy_ofdm(dev, 0xf, 0x38);mdelay(1); + /*ver D & 8187*/ + // } + + // if(priv->card_8185 == 1 && priv->card_8185_Bversion) + // write_phy_ofdm(dev, 0x10, 0x04);/*ver B*/ + // else + write_phy_ofdm(dev, 0x10, 0x84);mdelay(1); + /*ver C & D & 8187*/ + + write_phy_ofdm(dev, 0x11, 0x07);mdelay(1); + /*agc resp time 700*/ + + + // if(priv->card_8185 == 2){ + /* Ver D & 8187*/ + write_phy_ofdm(dev, 0x12, 0x20);mdelay(1); + + write_phy_ofdm(dev, 0x13, 0x20);mdelay(1); + + write_phy_ofdm(dev, 0x14, 0x0); mdelay(1); + write_phy_ofdm(dev, 0x15, 0x40); mdelay(1); + write_phy_ofdm(dev, 0x16, 0x0); mdelay(1); + write_phy_ofdm(dev, 0x17, 0x40); mdelay(1); + + // if (priv->card_type == USB) + // write_phy_ofdm(dev, 0x18, 0xef); + + write_phy_ofdm(dev, 0x18, 0xef);mdelay(1); + + + write_phy_ofdm(dev, 0x19, 0x19); mdelay(1); + write_phy_ofdm(dev, 0x1a, 0x20); mdelay(1); + write_phy_ofdm(dev, 0x1b, 0x15);mdelay(1); + + write_phy_ofdm(dev, 0x1c, 0x4);mdelay(1); + + write_phy_ofdm(dev, 0x1d, 0xc5);mdelay(1); //2005.11.17, + + write_phy_ofdm(dev, 0x1e, 0x95);mdelay(1); + + write_phy_ofdm(dev, 0x1f, 0x75); mdelay(1); + + // } + + write_phy_ofdm(dev, 0x20, 0x1f);mdelay(1); + + write_phy_ofdm(dev, 0x21, 0x17);mdelay(1); + + write_phy_ofdm(dev, 0x22, 0x16);mdelay(1); + + // if(priv->card_type != USB) + write_phy_ofdm(dev, 0x23, 0x80);mdelay(1); //FIXME maybe not needed // <> + + write_phy_ofdm(dev, 0x24, 0x46); mdelay(1); + write_phy_ofdm(dev, 0x25, 0x00); mdelay(1); + write_phy_ofdm(dev, 0x26, 0x90); mdelay(1); + + write_phy_ofdm(dev, 0x27, 0x88); mdelay(1); + + + // <> Set init. gain to m74dBm. + + rtl8225z2_set_gain(dev,4); + //rtl8225z2_set_gain(dev,2); + + write_phy_cck(dev, 0x0, 0x98); mdelay(1); + write_phy_cck(dev, 0x3, 0x20); mdelay(1); + write_phy_cck(dev, 0x4, 0x7e); mdelay(1); + write_phy_cck(dev, 0x5, 0x12); mdelay(1); + write_phy_cck(dev, 0x6, 0xfc); mdelay(1); + write_phy_cck(dev, 0x7, 0x78);mdelay(1); + /* Ver C & D & 8187*/ + write_phy_cck(dev, 0x8, 0x2e);mdelay(1); + + write_phy_cck(dev, 0x9, 0x11);mdelay(1); + write_phy_cck(dev, 0xa, 0x17);mdelay(1); + write_phy_cck(dev, 0xb, 0x11);mdelay(1); + + write_phy_cck(dev, 0x10, ((priv->card_type == USB) ? 0x9b: 0x93)); mdelay(1); + write_phy_cck(dev, 0x11, 0x88); mdelay(1); + write_phy_cck(dev, 0x12, 0x47); mdelay(1); + write_phy_cck(dev, 0x13, 0xd0); /* Ver C & D & 8187*/ + + write_phy_cck(dev, 0x19, 0x0); mdelay(1); + write_phy_cck(dev, 0x1a, 0xa0); mdelay(1); + write_phy_cck(dev, 0x1b, 0x8); mdelay(1); + write_phy_cck(dev, 0x1d, 0x0); mdelay(1); + + write_phy_cck(dev, 0x40, 0x86); /* CCK Carrier Sense Threshold */ mdelay(1); + + write_phy_cck(dev, 0x41, 0x9d);mdelay(1); + + + write_phy_cck(dev, 0x42, 0x15); mdelay(1); + write_phy_cck(dev, 0x43, 0x18); mdelay(1); + + + write_phy_cck(dev, 0x44, 0x36); mdelay(1); + write_phy_cck(dev, 0x45, 0x35); mdelay(1); + write_phy_cck(dev, 0x46, 0x2e); mdelay(1); + write_phy_cck(dev, 0x47, 0x25); mdelay(1); + write_phy_cck(dev, 0x48, 0x1c); mdelay(1); + write_phy_cck(dev, 0x49, 0x12); mdelay(1); + write_phy_cck(dev, 0x4a, 0x09); mdelay(1); + write_phy_cck(dev, 0x4b, 0x04); mdelay(1); + write_phy_cck(dev, 0x4c, 0x5);mdelay(1); + + + write_nic_byte(dev, 0x5b, 0x0d); mdelay(1); + + + + // <> + // // TESTR 0xb 8187 + // write_phy_cck(dev, 0x10, 0x93);// & 0xfb); + // + // //if(priv->card_type != USB){ + // write_phy_ofdm(dev, 0x2, 0x62); + // write_phy_ofdm(dev, 0x6, 0x0); + // write_phy_ofdm(dev, 0x8, 0x0); + // //} + + rtl8225z2_SetTXPowerLevel(dev, channel); + + write_phy_cck(dev, 0x10, 0x9b); mdelay(1); /* Rx ant A, 0xdb for B */ + write_phy_ofdm(dev, 0x26, 0x90); mdelay(1); /* Rx ant A, 0x10 for B */ + + rtl8185_tx_antenna(dev, 0x3); /* TX ant A, 0x0 for B */ + + /* switch to high-speed 3-wire + * last digit. 2 for both cck and ofdm + */ + if(priv->card_type == USB) + write_nic_dword(dev, 0x94, 0x3dc00002); + else{ + write_nic_dword(dev, 0x94, 0x15c00002); + rtl8185_rf_pins_enable(dev); + } + + // if(priv->card_type != USB) + // rtl8225_set_gain(dev, 4); /* FIXME this '1' is random */ // <> + // rtl8225_set_mode(dev, 1); /* FIXME start in B mode */ // <> + // + // /* make sure is waken up! */ + // write_rtl8225(dev,0x4, 0x9ff); + // rtl8180_set_anaparam(dev, RTL8225_ANAPARAM_ON); + // rtl8185_set_anaparam2(dev, RTL8225_ANAPARAM2_ON); + + rtl8225_rf_set_chan(dev, priv->chan); + + //write_nic_word(dev,BRSR,brsr); + + //rtl8225z2_rf_set_mode(dev); + } +} + +void rtl8225z2_rf_set_mode(struct net_device *dev) +{ + struct r8180_priv *priv = ieee80211_priv(dev); + + if(priv->ieee80211->mode == IEEE_A) + { + write_rtl8225(dev, 0x5, 0x1865); + write_nic_dword(dev, RF_PARA, 0x10084); + write_nic_dword(dev, RF_TIMING, 0xa8008); + write_phy_ofdm(dev, 0x0, 0x0); + write_phy_ofdm(dev, 0xa, 0x6); + write_phy_ofdm(dev, 0xb, 0x99); + write_phy_ofdm(dev, 0xf, 0x20); + write_phy_ofdm(dev, 0x11, 0x7); + + rtl8225z2_set_gain(dev,4); + + write_phy_ofdm(dev,0x15, 0x40); + write_phy_ofdm(dev,0x17, 0x40); + + write_nic_dword(dev, 0x94,0x10000000); + }else{ + + write_rtl8225(dev, 0x5, 0x1864); + write_nic_dword(dev, RF_PARA, 0x10044); + write_nic_dword(dev, RF_TIMING, 0xa8008); + write_phy_ofdm(dev, 0x0, 0x1); + write_phy_ofdm(dev, 0xa, 0x6); + write_phy_ofdm(dev, 0xb, 0x99); + write_phy_ofdm(dev, 0xf, 0x20); + write_phy_ofdm(dev, 0x11, 0x7); + + rtl8225z2_set_gain(dev,4); + + write_phy_ofdm(dev,0x15, 0x40); + write_phy_ofdm(dev,0x17, 0x40); + + write_nic_dword(dev, 0x94,0x04000002); + } +} diff -Nur linux-2.6.30.5.orig/drivers/net/wireless/rtl8187b/r8180_wx.c linux-2.6.30.5/drivers/net/wireless/rtl8187b/r8180_wx.c --- linux-2.6.30.5.orig/drivers/net/wireless/rtl8187b/r8180_wx.c 1970-01-01 01:00:00.000000000 +0100 +++ linux-2.6.30.5/drivers/net/wireless/rtl8187b/r8180_wx.c 2009-08-23 19:01:04.000000000 +0200 @@ -0,0 +1,2067 @@ +/* + This file contains wireless extension handlers. + + This is part of rtl8180 OpenSource driver. + Copyright (C) Andrea Merello 2004-2005 + Released under the terms of GPL (General Public Licence) + + Parts of this driver are based on the GPL part + of the official realtek driver. + + Parts of this driver are based on the rtl8180 driver skeleton + from Patric Schenke & Andres Salomon. + + Parts of this driver are based on the Intel Pro Wireless 2100 GPL driver. + + We want to tanks the Authors of those projects and the Ndiswrapper + project Authors. +*/ + + + +#include "r8187.h" +#include "r8180_hw.h" +//added 1117 +#include "ieee80211/ieee80211.h" +#ifdef ENABLE_DOT11D +#include "dot11d.h" +#endif + + +//#define RATE_COUNT 4 +u32 rtl8180_rates[] = {1000000,2000000,5500000,11000000, + 6000000,9000000,12000000,18000000,24000000,36000000,48000000,54000000}; +#define RATE_COUNT sizeof(rtl8180_rates)/(sizeof(rtl8180_rates[0])) + +#ifdef _RTL8187_EXT_PATCH_ +#define IW_MODE_MESH 11 +static int r8180_wx_join_mesh(struct net_device *dev, struct iw_request_info *info, union iwreq_data *wrqu, char *extra); +int r8180_wx_set_channel(struct net_device *dev, struct iw_request_info *info, union iwreq_data *wrqu, char *extra); +static int r8180_wx_mesh_scan(struct net_device *dev, struct iw_request_info *info, union iwreq_data *wrqu, char *extra); +static int r8180_wx_get_mesh_list(struct net_device *dev, struct iw_request_info *info, union iwreq_data *wrqu, char *extra); +#endif + +static int r8180_wx_get_freq(struct net_device *dev, + struct iw_request_info *a, + union iwreq_data *wrqu, char *b) +{ + struct r8180_priv *priv = ieee80211_priv(dev); + + return ieee80211_wx_get_freq(priv->ieee80211,a,wrqu,b); +} + + +#if 0 + +static int r8180_wx_set_beaconinterval(struct net_device *dev, struct iw_request_info *aa, + union iwreq_data *wrqu, char *b) +{ + int *parms = (int *)b; + int bi = parms[0]; + + struct r8180_priv *priv = ieee80211_priv(dev); + if(priv->ieee80211->bHwRadioOff) + return 0; + down(&priv->wx_sem); + DMESG("setting beacon interval to %x",bi); + + priv->ieee80211->beacon_interval=bi; + rtl8180_commit(dev); + up(&priv->wx_sem); + + return 0; +} + + +static int r8180_wx_set_forceassociate(struct net_device *dev, struct iw_request_info *aa, + union iwreq_data *wrqu, char *extra) +{ + struct r8180_priv *priv=ieee80211_priv(dev); + int *parms = (int *)extra; + if(priv->ieee80211->bHwRadioOff) + return 0; + + priv->ieee80211->force_associate = (parms[0] > 0); + + + return 0; +} + +#endif +static int r8180_wx_get_mode(struct net_device *dev, struct iw_request_info *a, + union iwreq_data *wrqu, char *b) +{ + struct r8180_priv *priv=ieee80211_priv(dev); + + return ieee80211_wx_get_mode(priv->ieee80211,a,wrqu,b); +} + + + +static int r8180_wx_get_rate(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + struct r8180_priv *priv = ieee80211_priv(dev); + return ieee80211_wx_get_rate(priv->ieee80211,info,wrqu,extra); +} + + + +static int r8180_wx_set_rate(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + int ret; + struct r8180_priv *priv = ieee80211_priv(dev); + if(priv->ieee80211->bHwRadioOff) + return 0; + + down(&priv->wx_sem); + + ret = ieee80211_wx_set_rate(priv->ieee80211,info,wrqu,extra); + + up(&priv->wx_sem); + + return ret; +} +#ifdef JOHN_IOCTL +u16 read_rtl8225(struct net_device *dev, u8 addr); +void write_rtl8225(struct net_device *dev, u8 adr, u16 data); +u32 john_read_rtl8225(struct net_device *dev, u8 adr); +void _write_rtl8225(struct net_device *dev, u8 adr, u16 data); + +static int r8180_wx_read_regs(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + struct r8180_priv *priv = ieee80211_priv(dev); + u8 addr = 0; + u16 data1; + + down(&priv->wx_sem); + + + get_user(addr,(u8*)wrqu->data.pointer); + data1 = read_rtl8225(dev, addr); + wrqu->data.length = data1; + + up(&priv->wx_sem); + return 0; + +} + +static int r8180_wx_write_regs(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + struct r8180_priv *priv = ieee80211_priv(dev); + u8 addr = 0; + + down(&priv->wx_sem); + + get_user(addr, (u8*)wrqu->data.pointer); + write_rtl8225(dev, addr, wrqu->data.length); + + up(&priv->wx_sem); + return 0; + +} + +void rtl8187_write_phy(struct net_device *dev, u8 adr, u32 data); +u8 rtl8187_read_phy(struct net_device *dev,u8 adr, u32 data); + +static int r8180_wx_read_bb(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + struct r8180_priv *priv = ieee80211_priv(dev); + u8 databb; +#if 0 + int i; + for(i=0;i<12;i++) printk("%8x\n", read_cam(dev, i) ); +#endif + + down(&priv->wx_sem); + + databb = rtl8187_read_phy(dev, (u8)wrqu->data.length, 0x00000000); + wrqu->data.length = databb; + + up(&priv->wx_sem); + return 0; +} + +void rtl8187_write_phy(struct net_device *dev, u8 adr, u32 data); +static int r8180_wx_write_bb(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + struct r8180_priv *priv = ieee80211_priv(dev); + u8 databb = 0; + + down(&priv->wx_sem); + + get_user(databb, (u8*)wrqu->data.pointer); + rtl8187_write_phy(dev, wrqu->data.length, databb); + + up(&priv->wx_sem); + return 0; + +} + + +static int r8180_wx_write_nicb(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + struct r8180_priv *priv = ieee80211_priv(dev); + u32 addr = 0; + + down(&priv->wx_sem); + + get_user(addr, (u32*)wrqu->data.pointer); + write_nic_byte(dev, addr, wrqu->data.length); + + up(&priv->wx_sem); + return 0; + +} +static int r8180_wx_read_nicb(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + struct r8180_priv *priv = ieee80211_priv(dev); + u32 addr = 0; + u16 data1; + + down(&priv->wx_sem); + + get_user(addr,(u32*)wrqu->data.pointer); + data1 = read_nic_byte(dev, addr); + wrqu->data.length = data1; + + up(&priv->wx_sem); + return 0; +} + +static inline int is_same_network(struct ieee80211_network *src, + struct ieee80211_network *dst, + struct ieee80211_device *ieee) +{ + /* A network is only a duplicate if the channel, BSSID, ESSID + * and the capability field (in particular IBSS and BSS) all match. + * We treat all with the same BSSID and channel + * as one network */ + return (((src->ssid_len == dst->ssid_len)||(ieee->iw_mode == IW_MODE_INFRA)) && //YJ,mod, 080819,for hidden ap + //((src->ssid_len == dst->ssid_len) && + (src->channel == dst->channel) && + !memcmp(src->bssid, dst->bssid, ETH_ALEN) && + (!memcmp(src->ssid, dst->ssid, src->ssid_len)||(ieee->iw_mode == IW_MODE_INFRA)) && //YJ,mod, 080819,for hidden ap + //!memcmp(src->ssid, dst->ssid, src->ssid_len) && + ((src->capability & WLAN_CAPABILITY_IBSS) == + (dst->capability & WLAN_CAPABILITY_IBSS)) && + ((src->capability & WLAN_CAPABILITY_BSS) == + (dst->capability & WLAN_CAPABILITY_BSS))); +} + +static int r8180_wx_get_ap_status(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + struct r8180_priv *priv = ieee80211_priv(dev); + struct ieee80211_device *ieee = priv->ieee80211; + struct ieee80211_network *target; + int name_len; + + down(&priv->wx_sem); + + //count the length of input ssid + for(name_len=0 ; ((char*)wrqu->data.pointer)[name_len]!='\0' ; name_len++); + + //search for the correspoding info which is received + list_for_each_entry(target, &ieee->network_list, list) { + if ( (target->ssid_len == name_len) && + (strncmp(target->ssid, (char*)wrqu->data.pointer, name_len)==0)){ + if( ((jiffies-target->last_scanned)/HZ > 1) && (ieee->state == IEEE80211_LINKED) && (is_same_network(&ieee->current_network,target, ieee)) ) + wrqu->data.length = 999; + else + wrqu->data.length = target->SignalStrength; + if(target->wpa_ie_len>0 || target->rsn_ie_len>0 ) + //set flags=1 to indicate this ap is WPA + wrqu->data.flags = 1; + else wrqu->data.flags = 0; + + + break; + } + } + + if (&target->list == &ieee->network_list){ + wrqu->data.flags = 3; + } + up(&priv->wx_sem); + return 0; +} + + + +#endif + +static int r8180_wx_set_rawtx(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + struct r8180_priv *priv = ieee80211_priv(dev); + int ret; + + if(priv->ieee80211->bHwRadioOff) + return 0; + + down(&priv->wx_sem); + + ret = ieee80211_wx_set_rawtx(priv->ieee80211, info, wrqu, extra); + + up(&priv->wx_sem); + + return ret; + +} + +static int r8180_wx_set_crcmon(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + struct r8180_priv *priv = ieee80211_priv(dev); + int *parms = (int *)extra; + int enable = (parms[0] > 0); + short prev = priv->crcmon; + + if(priv->ieee80211->bHwRadioOff) + return 0; + + down(&priv->wx_sem); + + if(enable) + priv->crcmon=1; + else + priv->crcmon=0; + + DMESG("bad CRC in monitor mode are %s", + priv->crcmon ? "accepted" : "rejected"); + + if(prev != priv->crcmon && priv->up){ + rtl8180_down(dev); + rtl8180_up(dev); + } + + up(&priv->wx_sem); + + return 0; +} + +static int r8180_wx_set_mode(struct net_device *dev, struct iw_request_info *a, + union iwreq_data *wrqu, char *b) +{ + struct r8180_priv *priv = ieee80211_priv(dev); + int ret; + if(priv->ieee80211->bHwRadioOff) + return 0; + +#ifdef _RTL8187_EXT_PATCH_ + if (priv->mshobj && (priv->ieee80211->iw_ext_mode==11)) return 0; +#endif + down(&priv->wx_sem); + +#ifdef CONFIG_IPS + if(priv->bInactivePs){ + if(wrqu->mode != IW_MODE_INFRA){ + down(&priv->ieee80211->ips_sem); + IPSLeave(dev); + up(&priv->ieee80211->ips_sem); + } + } +#endif + ret = ieee80211_wx_set_mode(priv->ieee80211,a,wrqu,b); + + rtl8187_set_rxconf(dev); + + up(&priv->wx_sem); + return ret; +} + + +//YJ,add,080819,for hidden ap +struct iw_range_with_scan_capa +{ + /* Informative stuff (to choose between different interface) */ + __u32 throughput; /* To give an idea... */ + /* In theory this value should be the maximum benchmarked + * TCP/IP throughput, because with most of these devices the + * bit rate is meaningless (overhead an co) to estimate how + * fast the connection will go and pick the fastest one. + * I suggest people to play with Netperf or any benchmark... + */ + + /* NWID (or domain id) */ + __u32 min_nwid; /* Minimal NWID we are able to set */ + __u32 max_nwid; /* Maximal NWID we are able to set */ + + /* Old Frequency (backward compat - moved lower ) */ + __u16 old_num_channels; + __u8 old_num_frequency; + + /* Scan capabilities */ + __u8 scan_capa; +}; +//YJ,add,080819,for hidden ap + +static int rtl8180_wx_get_range(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + struct iw_range *range = (struct iw_range *)extra; + struct r8180_priv *priv = ieee80211_priv(dev); + u16 val; + int i; + struct iw_range_with_scan_capa* tmp = (struct iw_range_with_scan_capa*)range; //YJ,add,080819,for hidden ap + + wrqu->data.length = sizeof(*range); + memset(range, 0, sizeof(*range)); + + /* Let's try to keep this struct in the same order as in + * linux/include/wireless.h + */ + + /* TODO: See what values we can set, and remove the ones we can't + * set, or fill them with some default data. + */ + + /* ~5 Mb/s real (802.11b) */ + range->throughput = 5 * 1000 * 1000; + + // TODO: Not used in 802.11b? +// range->min_nwid; /* Minimal NWID we are able to set */ + // TODO: Not used in 802.11b? +// range->max_nwid; /* Maximal NWID we are able to set */ + + /* Old Frequency (backward compat - moved lower ) */ +// range->old_num_channels; +// range->old_num_frequency; +// range->old_freq[6]; /* Filler to keep "version" at the same offset */ + if(priv->rf_set_sens != NULL) + range->sensitivity = priv->max_sens; /* signal level threshold range */ + + range->max_qual.qual = 100; + /* TODO: Find real max RSSI and stick here */ + range->max_qual.level = 0; + range->max_qual.noise = -98; + range->max_qual.updated = 7; /* Updated all three */ + + range->avg_qual.qual = 92; /* > 8% missed beacons is 'bad' */ + /* TODO: Find real 'good' to 'bad' threshol value for RSSI */ + range->avg_qual.level = 20 + -98; + range->avg_qual.noise = 0; + range->avg_qual.updated = 7; /* Updated all three */ + + range->num_bitrates = RATE_COUNT; + + for (i = 0; i < RATE_COUNT && i < IW_MAX_BITRATES; i++) { + range->bitrate[i] = rtl8180_rates[i]; + } + + range->min_frag = MIN_FRAG_THRESHOLD; + range->max_frag = MAX_FRAG_THRESHOLD; + + range->pm_capa = 0; + + range->we_version_compiled = WIRELESS_EXT; + range->we_version_source = 16; + +// range->retry_capa; /* What retry options are supported */ +// range->retry_flags; /* How to decode max/min retry limit */ +// range->r_time_flags; /* How to decode max/min retry life */ +// range->min_retry; /* Minimal number of retries */ +// range->max_retry; /* Maximal number of retries */ +// range->min_r_time; /* Minimal retry lifetime */ +// range->max_r_time; /* Maximal retry lifetime */ + + range->num_channels = 14; + + for (i = 0, val = 0; i < 14; i++) { + + // Include only legal frequencies for some countries +#ifdef ENABLE_DOT11D + if ((GET_DOT11D_INFO(priv->ieee80211)->channel_map)[i+1]) { +#else + if ((priv->ieee80211->channel_map)[i+1]) { +#endif + range->freq[val].i = i + 1; + range->freq[val].m = ieee80211_wlan_frequencies[i] * 100000; + range->freq[val].e = 1; + val++; + } else { + // FIXME: do we need to set anything for channels + // we don't use ? + } + + if (val == IW_MAX_FREQUENCIES) + break; + } + + range->num_frequency = val; + range->enc_capa = IW_ENC_CAPA_WPA | IW_ENC_CAPA_WPA2 | + IW_ENC_CAPA_CIPHER_TKIP | IW_ENC_CAPA_CIPHER_CCMP; + + tmp->scan_capa = 0x01; //YJ,add,080819,for hidden ap + + return 0; +} + + +static int r8180_wx_set_scan(struct net_device *dev, struct iw_request_info *a, + union iwreq_data *wrqu, char *b) +{ + struct r8180_priv *priv = ieee80211_priv(dev); + struct ieee80211_device* ieee = priv->ieee80211; + int ret; + + if(priv->ieee80211->bHwRadioOff) + return 0; + //printk("==============>%s()\n",__FUNCTION__); + if(!priv->up) + return -1; + + if (wrqu->data.flags & IW_SCAN_THIS_ESSID) + { + struct iw_scan_req* req = (struct iw_scan_req*)b; + if (req->essid_len) + { + ieee->current_network.ssid_len = req->essid_len; + memcpy(ieee->current_network.ssid, req->essid, req->essid_len); + } + } + + //set Tr switch to hardware control to scan more bss + if(priv->TrSwitchState == TR_SW_TX) { + //YJ,add,080611 + write_nic_byte(dev, RFPinsSelect, (u8)(priv->wMacRegRfPinsSelect)); + write_nic_byte(dev, RFPinsOutput, (u8)(priv->wMacRegRfPinsOutput)); + //YJ,add,080611,end + priv->TrSwitchState = TR_HW_CONTROLLED; + } +#ifdef _RTL8187_EXT_PATCH_ + if((priv->ieee80211->iw_mode == IW_MODE_MESH) && (priv->ieee80211->iw_ext_mode == IW_MODE_MESH)){ + r8180_wx_mesh_scan(dev,a,wrqu,b); + ret = 0; + } + else +#endif + { + down(&priv->wx_sem); + if(priv->ieee80211->state != IEEE80211_LINKED){ + //printk("===>start no link scan\n"); + //ieee80211_start_scan(priv->ieee80211); + //lzm mod 090115 because wq can't scan complete once + //because after start protocal wq scan is in doing + //so we should stop it first. + ieee80211_stop_scan(priv->ieee80211); + ieee80211_start_scan_syncro(priv->ieee80211); + ret = 0; + } else { + ret = ieee80211_wx_set_scan(priv->ieee80211,a,wrqu,b); + } + up(&priv->wx_sem); + } + return ret; +} + + +static int r8180_wx_get_scan(struct net_device *dev, struct iw_request_info *a, + union iwreq_data *wrqu, char *b) +{ + + int ret; + struct r8180_priv *priv = ieee80211_priv(dev); + + if(!priv->up) return -1; +#ifdef _RTL8187_EXT_PATCH_ + if((priv->ieee80211->iw_mode == IW_MODE_MESH) && (priv->ieee80211->iw_ext_mode == IW_MODE_MESH)){ + ret = r8180_wx_get_mesh_list(dev, a, wrqu, b); + } + else +#endif + { + down(&priv->wx_sem); + + ret = ieee80211_wx_get_scan(priv->ieee80211,a,wrqu,b); + + up(&priv->wx_sem); + } + return ret; +} + + +static int r8180_wx_set_essid(struct net_device *dev, + struct iw_request_info *a, + union iwreq_data *wrqu, char *b) +{ + struct r8180_priv *priv = ieee80211_priv(dev); + int ret; +#ifdef _RTL8187_EXT_PATCH_ + struct ieee80211_device *ieee = priv->ieee80211; + char ch = 0; + char tmpmeshid[32]; + char *p; + int tmpmeshid_len=0; + int i; + short proto_started; +#endif + if(priv->ieee80211->bHwRadioOff) + return 0; + //printk("==========>%s()\n",__FUNCTION__); + down(&priv->wx_sem); + +#ifdef _RTL8187_EXT_PATCH_ + if((priv->ieee80211->iw_mode == IW_MODE_MESH) && (priv->ieee80211->iw_ext_mode == IW_MODE_MESH)){ + if (wrqu->essid.length > IW_ESSID_MAX_SIZE){ + ret= -E2BIG; + goto out; + } + if (wrqu->essid.flags && (wrqu->essid.length > 1)) { + memset(tmpmeshid,0,32); +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20) + tmpmeshid_len=wrqu->essid.length; +#else + tmpmeshid_len=wrqu->essid.length + 1; +#endif + p=b+tmpmeshid_len-2; + for(i=tmpmeshid_len-1;i>0;i--) + { + if((*p)=='@') + break; + p--; + } + if((i == 0) || (i == 1)){ + printk("error:wrong meshid\n"); + ret = -1; + goto out; + } + + memcpy(tmpmeshid,b,(i-1)); + p++; + if((tmpmeshid_len-1-i)==1) + { + if(*p > '9'|| *p <= '0'){ + goto out; + } else { + ch = *p - '0'; + } + } + else if((tmpmeshid_len-1-i)==2) + { + if((*p == '1') && (*(p+1) >= '0') && (*(p+1) <= '9')) + ch = (*p - '0') * 10 + (*(p+1) - '0'); + else + goto out; + } + else { + ret = 0; + goto out; + } + if(ch > 14) + { + ret = 0; + printk("channel is invalid: %d\n",ch); + goto out; + } + ieee->sync_scan_hurryup = 1; + + proto_started = ieee->proto_started; + if(proto_started) + ieee80211_stop_protocol(ieee); + + printk("==============>tmpmeshid is %s\n",tmpmeshid); + priv->mshobj->ext_patch_r8180_wx_set_meshID(dev, tmpmeshid); + priv->mshobj->ext_patch_r8180_wx_set_mesh_chan(dev,ch); + r8180_wx_set_channel(dev, NULL, NULL, &ch); + if (proto_started) + ieee80211_start_protocol(ieee); + } + else{ + printk("BUG:meshid is null\n"); + ret=0; + goto out; + } + + ret = 0; + } + else +#endif + { + ret = ieee80211_wx_set_essid(priv->ieee80211,a,wrqu,b); + } + +#ifdef _RTL8187_EXT_PATCH_ +out: +#endif + up(&priv->wx_sem); + return ret; +} + + +static int r8180_wx_get_essid(struct net_device *dev, + struct iw_request_info *a, + union iwreq_data *wrqu, char *b) +{ + int ret; + struct r8180_priv *priv = ieee80211_priv(dev); + + down(&priv->wx_sem); + + ret = ieee80211_wx_get_essid(priv->ieee80211, a, wrqu, b); + + up(&priv->wx_sem); + + return ret; +} + + +static int r8180_wx_set_freq(struct net_device *dev, struct iw_request_info *a, + union iwreq_data *wrqu, char *b) +{ + int ret; + struct r8180_priv *priv = ieee80211_priv(dev); + + if(priv->ieee80211->bHwRadioOff) + return 0; + + down(&priv->wx_sem); + + ret = ieee80211_wx_set_freq(priv->ieee80211, a, wrqu, b); + + up(&priv->wx_sem); + return ret; +} + +static int r8180_wx_get_name(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + struct r8180_priv *priv = ieee80211_priv(dev); + return ieee80211_wx_get_name(priv->ieee80211, info, wrqu, extra); +} + + +static int r8180_wx_set_frag(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + struct r8180_priv *priv = ieee80211_priv(dev); + + if(priv->ieee80211->bHwRadioOff) + return 0; + + if (wrqu->frag.disabled) + priv->ieee80211->fts = DEFAULT_FRAG_THRESHOLD; + else { + if (wrqu->frag.value < MIN_FRAG_THRESHOLD || + wrqu->frag.value > MAX_FRAG_THRESHOLD) + return -EINVAL; + + priv->ieee80211->fts = wrqu->frag.value & ~0x1; + } + + return 0; +} + + +static int r8180_wx_get_frag(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + struct r8180_priv *priv = ieee80211_priv(dev); + + wrqu->frag.value = priv->ieee80211->fts; + wrqu->frag.fixed = 0; /* no auto select */ + wrqu->frag.disabled = (wrqu->frag.value == DEFAULT_FRAG_THRESHOLD); + + return 0; +} + + +static int r8180_wx_set_wap(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *awrq, + char *extra) +{ + int ret; + struct r8180_priv *priv = ieee80211_priv(dev); + if(priv->ieee80211->bHwRadioOff) + return 0; + + //printk("in function %s\n",__FUNCTION__); +#ifdef _RTL8187_EXT_PATCH_ + if (priv->mshobj && (priv->ieee80211->iw_ext_mode==11)){ + return 0; + } +#endif + down(&priv->wx_sem); + + ret = ieee80211_wx_set_wap(priv->ieee80211,info,awrq,extra); + + up(&priv->wx_sem); + return ret; + +} + + +static int r8180_wx_get_wap(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + struct r8180_priv *priv = ieee80211_priv(dev); + + return ieee80211_wx_get_wap(priv->ieee80211,info,wrqu,extra); +} + + +static int r8180_wx_get_enc(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *key) +{ + struct r8180_priv *priv = ieee80211_priv(dev); + + return ieee80211_wx_get_encode(priv->ieee80211, info, wrqu, key); +} + +static int r8180_wx_set_enc(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *key) +{ + struct r8180_priv *priv = ieee80211_priv(dev); + int ret; +#ifdef JOHN_HWSEC +// struct ieee80211_device *ieee = priv->ieee80211; +// u32 TargetContent; + u32 hwkey[4]={0,0,0,0}; + u8 mask=0xff; + u32 key_idx=0; + u8 broadcast_addr[6] ={ 0xff,0xff,0xff,0xff,0xff,0xff}; + u8 zero_addr[4][6] ={ {0x00,0x00,0x00,0x00,0x00,0x00}, + {0x00,0x00,0x00,0x00,0x00,0x01}, + {0x00,0x00,0x00,0x00,0x00,0x02}, + {0x00,0x00,0x00,0x00,0x00,0x03} }; + int i; + +#endif + + if(priv->ieee80211->bHwRadioOff) + return 0; + + down(&priv->wx_sem); + + DMESG("Setting SW wep key"); + ret = ieee80211_wx_set_encode(priv->ieee80211,info,wrqu,key); + + up(&priv->wx_sem); + +#ifdef JOHN_HWSEC + + //sometimes, the length is zero while we do not type key value + if(wrqu->encoding.length!=0){ + + for(i=0 ; i<4 ; i++){ + hwkey[i] |= key[4*i+0]&mask; + if(i==1&&(4*i+1)==wrqu->encoding.length) mask=0x00; + if(i==3&&(4*i+1)==wrqu->encoding.length) mask=0x00; + hwkey[i] |= (key[4*i+1]&mask)<<8; + hwkey[i] |= (key[4*i+2]&mask)<<16; + hwkey[i] |= (key[4*i+3]&mask)<<24; + } + + #define CONF_WEP40 0x4 + #define CONF_WEP104 0x14 + + switch(wrqu->encoding.flags){ + case 0: + case 1: key_idx = 0; break; + case 2: key_idx = 1; break; + case 3: key_idx = 2; break; + case 4: key_idx = 3; break; + default: break; + } + + if(wrqu->encoding.length==0x5){ + setKey( dev, + key_idx, //EntryNo + key_idx, //KeyIndex + KEY_TYPE_WEP40, //KeyType + zero_addr[key_idx], + 0, //DefaultKey + hwkey); //KeyContent + + if(key_idx == 0){ + + write_nic_byte(dev, WPA_CONFIG, 7); + + setKey( dev, + 4, //EntryNo + key_idx, //KeyIndex + KEY_TYPE_WEP40, //KeyType + broadcast_addr, //addr + 0, //DefaultKey + hwkey); //KeyContent + } + } + + else if(wrqu->encoding.length==0xd){ + setKey( dev, + key_idx, //EntryNo + key_idx, //KeyIndex + KEY_TYPE_WEP104, //KeyType + zero_addr[key_idx], + 0, //DefaultKey + hwkey); //KeyContent + + if(key_idx == 0){ + + write_nic_byte(dev, WPA_CONFIG, 7); + + setKey( dev, + 4, //EntryNo + key_idx, //KeyIndex + KEY_TYPE_WEP104, //KeyType + broadcast_addr, //addr + 0, //DefaultKey + hwkey); //KeyContent + } + } + else printk("wrong type in WEP, not WEP40 and WEP104\n"); + + } + + //consider the setting different key index situation + //wrqu->encoding.flags = 801 means that we set key with index "1" + if(wrqu->encoding.length==0 && (wrqu->encoding.flags >>8) == 0x8 ){ + + write_nic_byte(dev, WPA_CONFIG, 7); + + //copy wpa config from default key(key0~key3) to broadcast key(key5) + // + key_idx = (wrqu->encoding.flags & 0xf)-1 ; + write_cam(dev, (4*6), 0xffff0000|read_cam(dev, key_idx*6) ); + write_cam(dev, (4*6)+1, 0xffffffff); + write_cam(dev, (4*6)+2, read_cam(dev, (key_idx*6)+2) ); + write_cam(dev, (4*6)+3, read_cam(dev, (key_idx*6)+3) ); + write_cam(dev, (4*6)+4, read_cam(dev, (key_idx*6)+4) ); + write_cam(dev, (4*6)+5, read_cam(dev, (key_idx*6)+5) ); + } + +#endif /*JOHN_HWSEC*/ + return ret; +} + + +static int r8180_wx_set_scan_type(struct net_device *dev, struct iw_request_info *aa, union + iwreq_data *wrqu, char *p){ + + struct r8180_priv *priv = ieee80211_priv(dev); + int *parms=(int*)p; + int mode=parms[0]; + + if(priv->ieee80211->bHwRadioOff) + return 0; + + priv->ieee80211->active_scan = mode; + + return 1; +} + + + +static int r8180_wx_set_retry(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + struct r8180_priv *priv = ieee80211_priv(dev); + int err = 0; + + if(priv->ieee80211->bHwRadioOff) + return 0; + + down(&priv->wx_sem); + + if (wrqu->retry.flags & IW_RETRY_LIFETIME || + wrqu->retry.disabled){ + err = -EINVAL; + goto exit; + } + if (!(wrqu->retry.flags & IW_RETRY_LIMIT)){ + err = -EINVAL; + goto exit; + } + + if(wrqu->retry.value > R8180_MAX_RETRY){ + err= -EINVAL; + goto exit; + } + if (wrqu->retry.flags & IW_RETRY_MAX) { + priv->retry_rts = wrqu->retry.value; + DMESG("Setting retry for RTS/CTS data to %d", wrqu->retry.value); + + }else { + priv->retry_data = wrqu->retry.value; + DMESG("Setting retry for non RTS/CTS data to %d", wrqu->retry.value); + } + + /* FIXME ! + * We might try to write directly the TX config register + * or to restart just the (R)TX process. + * I'm unsure if whole reset is really needed + */ + + rtl8180_commit(dev); + /* + if(priv->up){ + rtl8180_rtx_disable(dev); + rtl8180_rx_enable(dev); + rtl8180_tx_enable(dev); + + } + */ +exit: + up(&priv->wx_sem); + + return err; +} + +static int r8180_wx_get_retry(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + struct r8180_priv *priv = ieee80211_priv(dev); + + + wrqu->retry.disabled = 0; /* can't be disabled */ + + if ((wrqu->retry.flags & IW_RETRY_TYPE) == + IW_RETRY_LIFETIME) + return -EINVAL; + + if (wrqu->retry.flags & IW_RETRY_MAX) { + wrqu->retry.flags = IW_RETRY_LIMIT & IW_RETRY_MAX; + wrqu->retry.value = priv->retry_rts; + } else { + wrqu->retry.flags = IW_RETRY_LIMIT & IW_RETRY_MIN; + wrqu->retry.value = priv->retry_data; + } + //DMESG("returning %d",wrqu->retry.value); + + + return 0; +} + +static int r8180_wx_get_sens(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + struct r8180_priv *priv = ieee80211_priv(dev); + if(priv->rf_set_sens == NULL) + return -1; /* we have not this support for this radio */ + wrqu->sens.value = priv->sens; + return 0; +} + + +static int r8180_wx_set_sens(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + + struct r8180_priv *priv = ieee80211_priv(dev); + + short err = 0; + + if(priv->ieee80211->bHwRadioOff) + return 0; + + down(&priv->wx_sem); + //DMESG("attempt to set sensivity to %ddb",wrqu->sens.value); + if(priv->rf_set_sens == NULL) { + err= -1; /* we have not this support for this radio */ + goto exit; + } + if(priv->rf_set_sens(dev, wrqu->sens.value) == 0) + priv->sens = wrqu->sens.value; + else + err= -EINVAL; + +exit: + up(&priv->wx_sem); + + return err; +} + + +static int dummy(struct net_device *dev, struct iw_request_info *a, + union iwreq_data *wrqu,char *b) +{ + return -1; +} +static int r8180_wx_set_enc_ext(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + + struct r8180_priv *priv = ieee80211_priv(dev); + //printk("===>%s()\n", __FUNCTION__); + + int ret=0; + + if(priv->ieee80211->bHwRadioOff) + return 0; + + down(&priv->wx_sem); + ret = ieee80211_wx_set_encode_ext(priv->ieee80211, info, wrqu, extra); + up(&priv->wx_sem); + return ret; + +} +static int r8180_wx_set_auth(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data* data, char *extra) +{ + //printk("====>%s()\n", __FUNCTION__); + struct r8180_priv *priv = ieee80211_priv(dev); + int ret=0; + + if(priv->ieee80211->bHwRadioOff) + return 0; + + down(&priv->wx_sem); + ret = ieee80211_wx_set_auth(priv->ieee80211, info, &(data->param), extra); + up(&priv->wx_sem); + return ret; +} + +static int r8180_wx_set_mlme(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + //printk("====>%s()\n", __FUNCTION__); + + int ret=0; + struct r8180_priv *priv = ieee80211_priv(dev); + + if(priv->ieee80211->bHwRadioOff) + return 0; + + down(&priv->wx_sem); +#if 1 + ret = ieee80211_wx_set_mlme(priv->ieee80211, info, wrqu, extra); +#endif + up(&priv->wx_sem); + return ret; +} + +static int r8180_wx_set_gen_ie(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data* data, char *extra) +{ + //printk("====>%s(), len:%d\n", __FUNCTION__, data->length); + int ret=0; + struct r8180_priv *priv = ieee80211_priv(dev); + + if(priv->ieee80211->bHwRadioOff) + return 0; + + down(&priv->wx_sem); +#if 1 + ret = ieee80211_wx_set_gen_ie(priv->ieee80211, extra, data->data.length); +#endif + up(&priv->wx_sem); + //printk("<======%s(), ret:%d\n", __FUNCTION__, ret); + return ret; + + +} + +#ifdef _RTL8187_EXT_PATCH_ +/* + Output: + (case 1) Mesh: Enable. MESHID=[%s] (max length of %s is 32 bytes). + (case 2) Mesh: Disable. +*/ +static int r8180_wx_get_meshinfo(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + struct r8180_priv *priv = ieee80211_priv(dev); + + if( ! priv->mshobj || !priv->mshobj->ext_patch_r8180_wx_get_meshinfo ) + return 0; + return priv->mshobj->ext_patch_r8180_wx_get_meshinfo(dev, info, wrqu, extra); +} + + +static int r8180_wx_enable_mesh(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + struct r8180_priv *priv = ieee80211_priv(dev); + struct ieee80211_device *ieee = priv->ieee80211; + + int ret = 0; + + if( ! priv->mshobj || !priv->mshobj->ext_patch_r8180_wx_enable_mesh ) + return 0; + + down(&priv->wx_sem); + if(priv->mshobj->ext_patch_r8180_wx_enable_mesh(dev)) + { + union iwreq_data tmprqu; + tmprqu.mode = ieee->iw_mode; + ieee->iw_mode = 0; + ret = ieee80211_wx_set_mode(ieee, info, &tmprqu, extra); + rtl8187_set_rxconf(dev); + } + + up(&priv->wx_sem); + + return ret; + +} + +static int r8180_wx_disable_mesh(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + struct r8180_priv *priv = ieee80211_priv(dev); + struct ieee80211_device *ieee = priv->ieee80211; + + int ret = 0; + + if( ! priv->mshobj || !priv->mshobj->ext_patch_r8180_wx_disable_mesh ) + return 0; + + down(&priv->wx_sem); + if(priv->mshobj->ext_patch_r8180_wx_disable_mesh(dev)) + { + union iwreq_data tmprqu; + tmprqu.mode = ieee->iw_mode; + ieee->iw_mode = 999; + ret = ieee80211_wx_set_mode(ieee, info, &tmprqu, extra); + rtl8187_set_rxconf(dev); + } + + up(&priv->wx_sem); + + return ret; +} + + +int r8180_wx_set_channel(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + int ch = *extra; + struct r8180_priv *priv = ieee80211_priv(dev); + struct ieee80211_device *ieee = priv->ieee80211; + + if(priv->ieee80211->bHwRadioOff) + return 0; + + // is 11s ? + if (!priv->mshobj || (ieee->iw_mode != ieee->iw_ext_mode) || !priv->mshobj->ext_patch_r8180_wx_set_channel ) + return 0; + + printk("set channel = %d\n", ch); + if ( ch < 0 ) + { + ieee80211_start_scan(ieee); // auto + ieee->meshScanMode =2; + } + else + { +//#ifdef NETWORKMANAGER_UI + if((priv->ieee80211->iw_mode == IW_MODE_MESH) && (priv->ieee80211->iw_ext_mode == IW_MODE_MESH)){ + } +//#else + else{ + down(&priv->wx_sem);} +//#endif + ieee->meshScanMode =0; + // ieee->set_chan(dev, ch); +//#ifdef _RTL8187_EXT_PATCH_ + if(priv->mshobj->ext_patch_r8180_wx_set_channel) + { + priv->mshobj->ext_patch_r8180_wx_set_channel(ieee, ch); + priv->mshobj->ext_patch_r8180_wx_set_mesh_chan(dev,ch); + } +//#endif + ieee->set_chan(ieee->dev, ch); + ieee->current_network.channel = ch; + queue_work(ieee->wq, &ieee->ext_stop_scan_wq); + ieee80211_ext_send_11s_beacon(ieee); +//#ifdef NETWORKMANAGER_UI + if((priv->ieee80211->iw_mode == IW_MODE_MESH) && (priv->ieee80211->iw_ext_mode == IW_MODE_MESH)){ + } +//#else + else{ + up(&priv->wx_sem);} +//#endif + //up(&ieee->wx_sem); + + // ieee80211_stop_scan(ieee); // user set + // + + /* + netif_carrier_off(ieee->dev); + + if (ieee->data_hard_stop) + ieee->data_hard_stop(ieee->dev); + + ieee->state = IEEE80211_NOLINK; + ieee->link_change(ieee->dev); + + ieee->current_network.channel = fwrq->m; + ieee->set_chan(ieee->dev, ieee->current_network.channel); + + + if (ieee->data_hard_resume) + ieee->data_hard_resume(ieee->dev); + + netif_carrier_on(ieee->dev); + */ + + } + + return 0; +} + +static int r8180_wx_set_meshID(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + struct r8180_priv *priv = ieee80211_priv(dev); + + if(priv->ieee80211->bHwRadioOff) + return 0; + + if( ! priv->mshobj || !priv->mshobj->ext_patch_r8180_wx_set_meshID ) + return 0; + + //printk("len=%d\n", wrqu->data.length); + //printk("\nCall setMeshid."); + return priv->mshobj->ext_patch_r8180_wx_set_meshID(dev, wrqu->data.pointer); +} + + +/* reserved for future +static int r8180_wx_add_mac_allow(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + struct r8180_priv *priv = ieee80211_priv(dev); + + if( ! priv->mshobj || !priv->mshobj->ext_patch_r8180_wx_set_add_mac_allow ) + return 0; + + return priv->mshobj->ext_patch_r8180_wx_set_add_mac_allow(dev, info, wrqu, extra); +} + +static int r8180_wx_del_mac_allow(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + struct r8180_priv *priv = ieee80211_priv(dev); + + if( ! priv->mshobj || !priv->mshobj->ext_patch_r8180_wx_set_del_mac_allow ) + return 0; + + return priv->mshobj->ext_patch_r8180_wx_set_del_mac_allow(dev, info, wrqu, extra); +} +*/ +static int r8180_wx_add_mac_deny(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + struct r8180_priv *priv = ieee80211_priv(dev); + + if( ! priv->mshobj || !priv->mshobj->ext_patch_r8180_wx_set_add_mac_deny ) + return 0; + + return priv->mshobj->ext_patch_r8180_wx_set_add_mac_deny(dev, info, wrqu, extra); +} + +static int r8180_wx_del_mac_deny(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + struct r8180_priv *priv = ieee80211_priv(dev); + + if( ! priv->mshobj || !priv->mshobj->ext_patch_r8180_wx_set_del_mac_deny ) + return 0; + + return priv->mshobj->ext_patch_r8180_wx_set_del_mac_deny(dev, info, wrqu, extra); +} + +/* reserved for future +static int r8180_wx_get_mac_allow(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + struct r8180_priv *priv = ieee80211_priv(dev); + + if( ! priv->mshobj || !priv->mshobj->ext_patch_r8180_wx_get_mac_allow ) + return 0; + + return priv->mshobj->ext_patch_r8180_wx_get_mac_allow(dev, info, wrqu, extra); +} +*/ + +static int r8180_wx_get_mac_deny(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + struct r8180_priv *priv = ieee80211_priv(dev); + + if( ! priv->mshobj || !priv->mshobj->ext_patch_r8180_wx_get_mac_deny ) + return 0; + + return priv->mshobj->ext_patch_r8180_wx_get_mac_deny(dev, info, wrqu, extra); +} + + +static int r8180_wx_get_mesh_list(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + struct r8180_priv *priv = ieee80211_priv(dev); + + if( ! priv->mshobj || !priv->mshobj->ext_patch_r8180_wx_get_mesh_list ) + return 0; + + return priv->mshobj->ext_patch_r8180_wx_get_mesh_list(dev, info, wrqu, extra); +} + +static int r8180_wx_mesh_scan(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + struct r8180_priv *priv = ieee80211_priv(dev); + + if( ! priv->mshobj || !priv->mshobj->ext_patch_r8180_wx_mesh_scan ) + return 0; + + return priv->mshobj->ext_patch_r8180_wx_mesh_scan(dev, info, wrqu, extra); +} + +static int r8180_wx_join_mesh(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + struct r8180_priv *priv = ieee80211_priv(dev); + int index; + int ret=0; + char extmeshid[32]; + int len=0; + char id[50], ch; +//#ifdef NETWORKMANAGER_UI + + if((priv->ieee80211->iw_mode == IW_MODE_MESH) && (priv->ieee80211->iw_ext_mode == IW_MODE_MESH)){ + printk("join mesh %s\n",extra); + if (wrqu->essid.length > IW_ESSID_MAX_SIZE){ + ret= -E2BIG; + goto out; + } + //printk("wrqu->essid.length is %d\n",wrqu->essid.length); + //printk("wrqu->essid.flags is %d\n",wrqu->essid.flags); + if((wrqu->essid.length == 1) && (wrqu->essid.flags == 1)){ + ret = 0; + goto out; + } + if (wrqu->essid.flags && wrqu->essid.length) { + if(priv->mshobj->ext_patch_r8180_wx_get_selected_mesh_channel(dev, extra, &ch)) + { + priv->mshobj->ext_patch_r8180_wx_set_meshID(dev, extra); + priv->mshobj->ext_patch_r8180_wx_set_mesh_chan(dev,ch); + r8180_wx_set_channel(dev, NULL, NULL, &ch); + } + else + printk("invalid mesh #\n"); + + } +#if 0 + else{ + if(priv->mshobj->ext_patch_r8180_wx_get_selected_mesh_channel(dev, 0, &ch)) + { + priv->mshobj->ext_patch_r8180_wx_set_meshID(dev, extra); + priv->mshobj->ext_patch_r8180_wx_set_mesh_chan(dev,ch); + r8180_wx_set_channel(dev, NULL, NULL, &ch); + } + else + printk("invalid mesh #\n"); + + } +#endif + } + else{ +//#else + index = *(extra); +// printk("index=%d\n", index); + + if( ! priv->mshobj + || !priv->mshobj->ext_patch_r8180_wx_set_meshID + || !priv->mshobj->ext_patch_r8180_wx_get_selected_mesh ) + return 0; + + if( priv->mshobj->ext_patch_r8180_wx_get_selected_mesh(dev, index, &ch, id) ) + { + // printk("ch=%d, id=%s\n", ch, id); + priv->mshobj->ext_patch_r8180_wx_set_meshID(dev, id); + priv->mshobj->ext_patch_r8180_wx_set_mesh_chan(dev,ch); + r8180_wx_set_channel(dev, NULL, NULL, &ch); + } + else + printk("invalid mesh #\n"); + } +//#endif +out: + return ret; +} + +#endif // _RTL8187_EXT_PATCH_ + + +static int r8180_wx_get_radion(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + struct r8180_priv *priv = ieee80211_priv(dev); +// u8 addr; + + down(&priv->wx_sem); + if(priv->radion == 1) { + *(int *)extra = 1; + } else { + + *(int *)extra = 0; + } + up(&priv->wx_sem); + return 0; + +} + +static int r8180_wx_set_radion(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + int radion = *extra; + struct r8180_priv *priv = ieee80211_priv(dev); +// struct ieee80211_device *ieee = priv->ieee80211; + u8 btCR9346, btConfig3; + int i; + u16 u2bTFPC = 0; + u8 u1bTmp; + + if(priv->ieee80211->bHwRadioOff) + return 0; + + down(&priv->wx_sem); + printk("set radion = %d\n", radion); + +#ifdef _RTL8187_EXT_PATCH_ + if(ieee->iw_mode == ieee->iw_ext_mode) { + printk("mesh mode:: could not set radi on/off = %d\n", radion); + up(&priv->wx_sem); + return 0; + } +#endif + // Set EEM0 and EEM1 in 9346CR. + btCR9346 = read_nic_byte(dev, CR9346); + write_nic_byte(dev, CR9346, (btCR9346|0xC0) ); + // Set PARM_En in Config3. + btConfig3 = read_nic_byte(dev, CONFIG3); + write_nic_byte(dev, CONFIG3, (btConfig3|CONFIG3_PARM_En) ); + + if ( radion == 1) //radion off + { + printk("==================>RF on\n"); + write_nic_dword(dev, ANAPARAM, ANAPARM_ON); + write_nic_dword(dev, ANAPARAM2, ANAPARM2_ON); + write_nic_byte(dev, CONFIG4, (priv->RFProgType)); + + write_nic_byte(dev, 0x085, 0x24); // 061219, SD3 ED: for minicard CCK power leakage issue. + write_rtl8225(dev, 0x4, 0x9FF); + + u1bTmp = read_nic_byte(dev, 0x24E); + write_nic_byte(dev, 0x24E, (u1bTmp & (~(BIT5|BIT6))) );// 070124 SD1 Alex: turn on CCK and OFDM. + priv->radion = 1; //radion on + } + else + { + printk("==================>RF off\n"); + for(i = 0; i < MAX_DOZE_WAITING_TIMES_87B; i++) + { // Make sure TX FIFO is empty befor turn off RFE pwoer. + u2bTFPC = read_nic_word(dev, TFPC); + if(u2bTFPC == 0) + { + break; + } + else + { + printk("%d times TFPC: %d != 0 before doze!\n", (i+1), u2bTFPC); + udelay(10); + } + } + if( i == MAX_DOZE_WAITING_TIMES_87B ) + { + printk("\n\n\n SetZebraRFPowerState8187B(): %d times TFPC: %d != 0 !!!\n\n\n",\ + MAX_DOZE_WAITING_TIMES_87B, u2bTFPC); + } + + u1bTmp = read_nic_byte(dev, 0x24E); + write_nic_byte(dev, 0x24E, (u1bTmp|BIT5|BIT6));// 070124 SD1 Alex: turn off CCK and OFDM. + + write_rtl8225(dev, 0x4,0x1FF); // Turn off RF first to prevent BB lock up, suggested by PJ, 2006.03.03. + write_nic_byte(dev, 0x085, 0x04); // 061219, SD3 ED: for minicard CCK power leakage issue. + + write_nic_byte(dev, CONFIG4, (priv->RFProgType|Config4_PowerOff)); + + write_nic_dword(dev, ANAPARAM, ANAPARM_OFF); + write_nic_dword(dev, ANAPARAM2, ANAPARM2_OFF); // 070301, SD1 William: to reduce RF off power consumption to 80 mA. + priv->radion = 0; //radion off + } + // Clear PARM_En in Config3. + btConfig3 &= ~(CONFIG3_PARM_En); + write_nic_byte(dev, CONFIG3, btConfig3); + // Clear EEM0 and EEM1 in 9346CR. + btCR9346 &= ~(0xC0); + write_nic_byte(dev, CR9346, btCR9346); + + up(&priv->wx_sem); + + return 0; +} + +static int r8180_wx_set_ratadpt (struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + int ratadapt = *extra; + struct r8180_priv *priv = ieee80211_priv(dev); + struct ieee80211_device *ieee = priv->ieee80211; + + if(priv->ieee80211->bHwRadioOff) + return 0; + + down(&priv->wx_sem); + printk("Set rate adaptive %s\n", (ratadapt==0)?"on":"off"); + if(ratadapt == 0) { + del_timer_sync(&priv->rateadapter_timer); + cancel_delayed_work(&priv->ieee80211->rate_adapter_wq); + priv->rateadapter_timer.function((unsigned long)dev); + } else { + del_timer_sync(&priv->rateadapter_timer); + cancel_delayed_work(&priv->ieee80211->rate_adapter_wq); + printk("force rate to %d\n", ratadapt); + ieee->rate = ratadapt; + } + up(&priv->wx_sem); + return 0; +} + +#ifdef ENABLE_TOSHIBA_CONFIG +static int r8180_wx_get_tblidx(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + struct r8180_priv *priv = ieee80211_priv(dev); + //extern u8 chan_plan_index; + //printk("=========>%s(), %x\n", __FUNCTION__, priv->channel_plan); + down(&priv->wx_sem); + put_user(priv->channel_plan, (u8*)wrqu->data.pointer); + up(&priv->wx_sem); + return 0; + +} + +//This func will be called after probe auto +static int r8180_wx_set_tbl (struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + struct r8180_priv *priv = ieee80211_priv(dev); + u8 len = 0; + s8 err = -1; + extern CHANNEL_LIST Current_tbl; + down(&priv->wx_sem); + if (!wrqu->data.pointer) + { + printk("user data pointer is null\n"); + goto exit; + } + len = wrqu->data.length; + //printk("=========>%s(), len:%d\n", __FUNCTION__, len); + //memset(&Current_tbl, 0, sizeof(CHANNEL_LIST)); + if (copy_from_user((u8*)&Current_tbl, (void*)wrqu->data.pointer, len)) + { + printk("error copy from user\n"); + goto exit; + } + { + int i; + Current_tbl.Len = len; + //printk("%d\n", Current_tbl.Len); + + Dot11d_Init(priv->ieee80211); + priv->ieee80211->bGlobalDomain = false; + priv->ieee80211->bWorldWide13 = false; + + //lzm add 081205 + priv->ieee80211->MinPassiveChnlNum=12; + priv->ieee80211->IbssStartChnl= 10; + + for (i=0; ichannel_plan == COUNTRY_CODE_ETSI) + { + if(Current_tbl.Channel[i] <= 11) + { +#ifdef ENABLE_DOT11D + GET_DOT11D_INFO(priv->ieee80211)->channel_map[Current_tbl.Channel[i]] = 1; +#else + priv->ieee80211->channel_map[Current_tbl.Channel[i]] = 1; +#endif + } + else if((Current_tbl.Channel[i] >= 11) && (Current_tbl.Channel[i] <= 13)) + { +#ifdef ENABLE_DOT11D + GET_DOT11D_INFO(priv->ieee80211)->channel_map[Current_tbl.Channel[i]] = 2; +#else + priv->ieee80211->channel_map[Current_tbl.Channel[i]] = 2; +#endif + } + } + else + { + if(Current_tbl.Channel[i] <= 14) + { +#ifdef ENABLE_DOT11D + GET_DOT11D_INFO(priv->ieee80211)->channel_map[Current_tbl.Channel[i]] = 1; +#else + priv->ieee80211->channel_map[Current_tbl.Channel[i]] = 1; +#endif + } + } + } +#if 0 + printk("\n"); + for(i=1; iieee80211)->channel_map[i]); +#else + printk("%2d ", priv->ieee80211->channel_map[i]); +#endif + } + printk("\n"); + +#endif + if(priv->ieee80211->proto_started) + {//we need to restart protocol now if it was start before channel map + ieee80211_softmac_stop_protocol(priv->ieee80211); + //mdelay(1); + ieee80211_softmac_start_protocol(priv->ieee80211); + } + } + err = 0; +exit: + up(&priv->wx_sem); + return err; + + +} + +#endif + + +static iw_handler r8180_wx_handlers[] = +{ + NULL, /* SIOCSIWCOMMIT */ + r8180_wx_get_name, /* SIOCGIWNAME */ + dummy, /* SIOCSIWNWID */ + dummy, /* SIOCGIWNWID */ + r8180_wx_set_freq, /* SIOCSIWFREQ */ + r8180_wx_get_freq, /* SIOCGIWFREQ */ + r8180_wx_set_mode, /* SIOCSIWMODE */ + r8180_wx_get_mode, /* SIOCGIWMODE */ + r8180_wx_set_sens, /* SIOCSIWSENS */ + r8180_wx_get_sens, /* SIOCGIWSENS */ + NULL, /* SIOCSIWRANGE */ + rtl8180_wx_get_range, /* SIOCGIWRANGE */ + NULL, /* SIOCSIWPRIV */ + NULL, /* SIOCGIWPRIV */ + NULL, /* SIOCSIWSTATS */ + NULL, /* SIOCGIWSTATS */ + dummy, /* SIOCSIWSPY */ + dummy, /* SIOCGIWSPY */ + NULL, /* SIOCGIWTHRSPY */ + NULL, /* SIOCWIWTHRSPY */ + r8180_wx_set_wap, /* SIOCSIWAP */ + r8180_wx_get_wap, /* SIOCGIWAP */ + r8180_wx_set_mlme, //NULL, /* SIOCSIWMLME*/ /* -- hole -- */ + dummy, /* SIOCGIWAPLIST -- depricated */ + r8180_wx_set_scan, /* SIOCSIWSCAN */ + r8180_wx_get_scan, /* SIOCGIWSCAN */ + r8180_wx_set_essid, /* SIOCSIWESSID */ + r8180_wx_get_essid, /* SIOCGIWESSID */ + dummy, /* SIOCSIWNICKN */ + dummy, /* SIOCGIWNICKN */ + NULL, /* -- hole -- */ + NULL, /* -- hole -- */ + r8180_wx_set_rate, /* SIOCSIWRATE */ + r8180_wx_get_rate, /* SIOCGIWRATE */ + dummy, /* SIOCSIWRTS */ + dummy, /* SIOCGIWRTS */ + r8180_wx_set_frag, /* SIOCSIWFRAG */ + r8180_wx_get_frag, /* SIOCGIWFRAG */ + dummy, /* SIOCSIWTXPOW */ + dummy, /* SIOCGIWTXPOW */ + r8180_wx_set_retry, /* SIOCSIWRETRY */ + r8180_wx_get_retry, /* SIOCGIWRETRY */ + r8180_wx_set_enc, /* SIOCSIWENCODE */ + r8180_wx_get_enc, /* SIOCGIWENCODE */ + dummy, /* SIOCSIWPOWER */ + dummy, /* SIOCGIWPOWER */ + NULL, /*---hole---*/ + NULL, /*---hole---*/ + r8180_wx_set_gen_ie,//NULL, /* SIOCSIWGENIE */ + NULL, /* SIOCSIWGENIE */ + r8180_wx_set_auth,//NULL, /* SIOCSIWAUTH */ + NULL,//r8180_wx_get_auth,//NULL, /* SIOCSIWAUTH */ + r8180_wx_set_enc_ext, /* SIOCSIWENCODEEXT */ + NULL,//r8180_wx_get_enc_ext,//NULL, /* SIOCSIWENCODEEXT */ + NULL, /* SIOCSIWPMKSA */ + NULL, /*---hole---*/ +}; + + +static const struct iw_priv_args r8180_private_args[] = { + { + SIOCIWFIRSTPRIV + 0x0, + IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "badcrc" + }, + + { + SIOCIWFIRSTPRIV + 0x1, + IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "activescan" + + }, + { + SIOCIWFIRSTPRIV + 0x2, + IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "rawtx" + }, +#ifdef JOHN_IOCTL + { + SIOCIWFIRSTPRIV + 0x3, + IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "readRF" + } + , + { + SIOCIWFIRSTPRIV + 0x4, + IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "writeRF" + } + , + { + SIOCIWFIRSTPRIV + 0x5, + IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "readBB" + } + , + { + SIOCIWFIRSTPRIV + 0x6, + IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "writeBB" + } + , + { + SIOCIWFIRSTPRIV + 0x7, + IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "readnicb" + } + , + { + SIOCIWFIRSTPRIV + 0x8, + IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "writenicb" + } + , + { + SIOCIWFIRSTPRIV + 0x9, + IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "apinfo" + }, +#endif + { + SIOCIWFIRSTPRIV + 0xA, + 0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED |1, "getradion" + }, + { + SIOCIWFIRSTPRIV + 0xB, + IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "setradion" + }, + { + SIOCIWFIRSTPRIV + 0xC, + IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "ratadpt" + }, +#ifdef ENABLE_TOSHIBA_CONFIG + { + SIOCIWFIRSTPRIV + 0xD, + 0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "gettblidx" + }, + { + SIOCIWFIRSTPRIV + 0xE, + IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,0, "settblidx" + }, + +#endif + +}; + +/* + * Private ioctl interface information + +struct iw_priv_args +{ +// __u32 cmd; +// __u16 set_args; +// __u16 get_args; +// char name[IFNAMSIZ]; +//}; +*/ +//If get cmd's number is big,there may cause some problemes. +//So modified by Lawrence,071120 + +static iw_handler r8180_private_handler[] = { +// r8180_wx_set_monitor, /* SIOCIWFIRSTPRIV */ + r8180_wx_set_crcmon, /*SIOCIWSECONDPRIV*/ +// r8180_wx_set_forceassociate, +// r8180_wx_set_beaconinterval, +// r8180_wx_set_monitor_type, + r8180_wx_set_scan_type, + r8180_wx_set_rawtx, + +#if 0 +#ifdef _RTL8187_EXT_PATCH_ + r8180_wx_get_meshinfo, + r8180_wx_enable_mesh, + r8180_wx_disable_mesh, + r8180_wx_set_channel, + r8180_wx_set_meshID, + +// r8180_wx_add_mac_allow, +// r8180_wx_get_mac_allow, +// r8180_wx_del_mac_allow, + r8180_wx_add_mac_deny, + r8180_wx_get_mac_deny, + r8180_wx_del_mac_deny, + r8180_wx_get_mesh_list, + r8180_wx_mesh_scan, + r8180_wx_join_mesh, +#endif +#endif + +#ifdef JOHN_IOCTL + r8180_wx_read_regs, + r8180_wx_write_regs, + r8180_wx_read_bb, + r8180_wx_write_bb, + r8180_wx_read_nicb, + r8180_wx_write_nicb, + r8180_wx_get_ap_status, +#endif + r8180_wx_get_radion, + r8180_wx_set_radion, + r8180_wx_set_ratadpt, +#ifdef ENABLE_TOSHIBA_CONFIG + r8180_wx_get_tblidx, + r8180_wx_set_tbl, +#endif +}; + +#if WIRELESS_EXT >= 17 +//WB modefied to show signal to GUI on 18-01-2008 +static struct iw_statistics *r8180_get_wireless_stats(struct net_device *dev) +{ + struct r8180_priv *priv = ieee80211_priv(dev); + struct ieee80211_device* ieee = priv->ieee80211; + struct iw_statistics* wstats = &priv->wstats; +// struct ieee80211_network* target = NULL; + int tmp_level = 0; + int tmp_qual = 0; + int tmp_noise = 0; +// unsigned long flag; + + if (ieee->state < IEEE80211_LINKED) + { + wstats->qual.qual = 0; + wstats->qual.level = 0; + wstats->qual.noise = 0; + wstats->qual.updated = IW_QUAL_ALL_UPDATED | IW_QUAL_DBM; + return wstats; + } +#if 0 + spin_lock_irqsave(&ieee->lock, flag); + list_for_each_entry(target, &ieee->network_list, list) + { + if (is_same_network(target, &ieee->current_network)) + { + printk("it's same network:%s\n", target->ssid); +#if 0 + if (!tmp_level) + { + tmp_level = target->stats.signalstrength; + tmp_qual = target->stats.signal; + } + else + { + + tmp_level = (15*tmp_level + target->stats.signalstrength)/16; + tmp_qual = (15*tmp_qual + target->stats.signal)/16; + } +#else + tmp_level = target->stats.signal; + tmp_qual = target->stats.signalstrength; + tmp_noise = target->stats.noise; + printk("level:%d, qual:%d, noise:%d\n", tmp_level, tmp_qual, tmp_noise); +#endif + break; + } + } + spin_unlock_irqrestore(&ieee->lock, flag); +#endif + tmp_level = (&ieee->current_network)->stats.signal; + tmp_qual = (&ieee->current_network)->stats.signalstrength; + tmp_noise = (&ieee->current_network)->stats.noise; + //printk("level:%d, qual:%d, noise:%d\n", tmp_level, tmp_qual, tmp_noise); + + wstats->qual.level = tmp_level; + wstats->qual.qual = tmp_qual; + wstats->qual.noise = tmp_noise; + wstats->qual.updated = IW_QUAL_ALL_UPDATED| IW_QUAL_DBM; + return wstats; +} +#endif + + +struct iw_handler_def r8180_wx_handlers_def={ + .standard = r8180_wx_handlers, + .num_standard = sizeof(r8180_wx_handlers) / sizeof(iw_handler), + .private = r8180_private_handler, + .num_private = sizeof(r8180_private_handler) / sizeof(iw_handler), + .num_private_args = sizeof(r8180_private_args) / sizeof(struct iw_priv_args), +#if WIRELESS_EXT >= 17 + .get_wireless_stats = r8180_get_wireless_stats, +#endif + .private_args = (struct iw_priv_args *)r8180_private_args, +}; +#ifdef _RTL8187_EXT_PATCH_ +EXPORT_SYMBOL(r8180_wx_set_channel); +#endif diff -Nur linux-2.6.30.5.orig/drivers/net/wireless/rtl8187b/r8180_wx.h linux-2.6.30.5/drivers/net/wireless/rtl8187b/r8180_wx.h --- linux-2.6.30.5.orig/drivers/net/wireless/rtl8187b/r8180_wx.h 1970-01-01 01:00:00.000000000 +0100 +++ linux-2.6.30.5/drivers/net/wireless/rtl8187b/r8180_wx.h 2009-08-23 19:01:04.000000000 +0200 @@ -0,0 +1,21 @@ +/* + This is part of rtl8180 OpenSource driver - v 0.3 + Copyright (C) Andrea Merello 2004 + Released under the terms of GPL (General Public Licence) + + Parts of this driver are based on the GPL part of the official realtek driver + Parts of this driver are based on the rtl8180 driver skeleton from Patric Schenke & Andres Salomon + Parts of this driver are based on the Intel Pro Wireless 2100 GPL driver + + We want to tanks the Authors of such projects and the Ndiswrapper project Authors. +*/ + +/* this file (will) contains wireless extension handlers*/ + +#ifndef R8180_WX_H +#define R8180_WX_H +#include +#include "ieee80211/ieee80211.h" +extern struct iw_handler_def r8180_wx_handlers_def; + +#endif diff -Nur linux-2.6.30.5.orig/drivers/net/wireless/rtl8187b/r8187_core.c linux-2.6.30.5/drivers/net/wireless/rtl8187b/r8187_core.c --- linux-2.6.30.5.orig/drivers/net/wireless/rtl8187b/r8187_core.c 1970-01-01 01:00:00.000000000 +0100 +++ linux-2.6.30.5/drivers/net/wireless/rtl8187b/r8187_core.c 2009-08-23 19:01:04.000000000 +0200 @@ -0,0 +1,7194 @@ +/* + This is part of rtl8187 OpenSource driver - v 0.1 + Copyright (C) Andrea Merello 2005 + Released under the terms of GPL (General Public License) + + + Parts of this driver are based on the rtl8180 driver skeleton + from Patric Schenke & Andres Salomon. + + Parts of this driver are based on the Intel Pro Wireless 2*00 GPL drivers. + + some ideas might be derived from David Young rtl8180 netbsd driver. + + Parts of the usb code are from the r8150.c driver in linux kernel + + Some ideas borrowed from the 8139too.c driver included in linux kernel. + + We (I?) want to thanks the Authors of those projecs and also the + Ndiswrapper's project Authors. + + A special big thanks goes also to Realtek corp. for their help in my + attempt to add RTL8187 and RTL8225 support, and to David Young also. + + - Please note that this file is a modified version from rtl8180-sa2400 + drv. So some other people have contributed to this project, and they are + thanked in the rtl8180-sa2400 CHANGELOG. +*/ + +#undef LOOP_TEST +#undef DUMP_RX +#undef DUMP_TX +#undef DEBUG_TX_DESC2 +#undef RX_DONT_PASS_UL +#undef DEBUG_EPROM +#undef DEBUG_RX_VERBOSE +#undef DUMMY_RX +#undef DEBUG_ZERO_RX +#undef DEBUG_RX_SKB +#undef DEBUG_TX_FRAG +#undef DEBUG_RX_FRAG +#undef DEBUG_TX_FILLDESC +#undef DEBUG_TX +#undef DEBUG_IRQ +#undef DEBUG_RX +#undef DEBUG_RXALLOC +#undef DEBUG_REGISTERS +#undef DEBUG_RING +#undef DEBUG_IRQ_TASKLET +#undef DEBUG_TX_ALLOC +#undef DEBUG_TX_DESC +#undef CONFIG_SOFT_BEACON +#undef DEBUG_RW_REGISTER + +#define CONFIG_RTL8180_IO_MAP +//#define CONFIG_SOFT_BEACON +//#define DEBUG_RW_REGISTER + +#include + +#include "r8180_hw.h" +#include "r8187.h" +#include "r8180_rtl8225.h" /* RTL8225 Radio frontend */ +#include "r8180_93cx6.h" /* Card EEPROM */ +#include "r8180_wx.h" +#include "r8180_dm.h" + +#include +// FIXME: check if 2.6.7 is ok +#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,7)) +#define usb_kill_urb usb_unlink_urb +#endif + +#ifdef CONFIG_RTL8180_PM +#include "r8180_pm.h" +#endif + +#ifdef ENABLE_DOT11D +#include "dot11d.h" +#endif + +#ifndef USB_VENDOR_ID_REALTEK +#define USB_VENDOR_ID_REALTEK 0x0bda +#endif +#ifndef USB_VENDOR_ID_NETGEAR +#define USB_VENDOR_ID_NETGEAR 0x0846 +#endif + +#define TXISR_SELECT(priority) ((priority == MANAGE_PRIORITY)?rtl8187_managetx_isr:\ + (priority == BEACON_PRIORITY)?rtl8187_beacontx_isr: \ + (priority == VO_PRIORITY)?rtl8187_votx_isr: \ + (priority == VI_PRIORITY)?rtl8187_vitx_isr:\ + (priority == BE_PRIORITY)?rtl8187_betx_isr:rtl8187_bktx_isr) + +static struct usb_device_id rtl8187_usb_id_tbl[] = { + {USB_DEVICE(USB_VENDOR_ID_REALTEK, 0x8187)}, + {USB_DEVICE(USB_VENDOR_ID_REALTEK, 0x8189)}, +// {USB_DEVICE_VER(USB_VENDOR_ID_REALTEK, 0x8187,0x0200,0x0200)}, + {USB_DEVICE(USB_VENDOR_ID_NETGEAR, 0x6100)}, + {USB_DEVICE(USB_VENDOR_ID_NETGEAR, 0x6a00)}, + {USB_DEVICE(USB_VENDOR_ID_REALTEK, 0x8197)}, + {USB_DEVICE(USB_VENDOR_ID_REALTEK, 0x8198)}, + {} +}; + +static char* ifname = "wlan%d"; +#if 0 +static int hwseqnum = 0; +static int hwwep = 0; +#endif +static int channels = 0x3fff; +//static int channels = 0x7ff;// change by thomas, use 1 - 11 channel 0907-2007 +#define eqMacAddr(a,b) ( ((a)[0]==(b)[0] && (a)[1]==(b)[1] && (a)[2]==(b)[2] && (a)[3]==(b)[3] && (a)[4]==(b)[4] && (a)[5]==(b)[5]) ? 1:0 ) +//by amy for rate adaptive +#define DEFAULT_RATE_ADAPTIVE_TIMER_PERIOD 300 +//by amy for rate adaptive +//by amy for ps +#define IEEE80211_WATCH_DOG_TIME 2000 +//by amy for ps +MODULE_LICENSE("GPL"); +#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)) +MODULE_VERSION("V 1.1"); +#endif +MODULE_DEVICE_TABLE(usb, rtl8187_usb_id_tbl); +MODULE_AUTHOR("Realsil Wlan"); +MODULE_DESCRIPTION("Linux driver for Realtek RTL8187 WiFi cards"); + +#if 0 +MODULE_PARM(ifname,"s"); +MODULE_PARM_DESC(devname," Net interface name, wlan%d=default"); + +MODULE_PARM(hwseqnum,"i"); +MODULE_PARM_DESC(hwseqnum," Try to use hardware 802.11 header sequence numbers. Zero=default"); + +MODULE_PARM(hwwep,"i"); +MODULE_PARM_DESC(hwwep," Try to use hardware WEP support. Still broken and not available on all cards"); + +MODULE_PARM(channels,"i"); +MODULE_PARM_DESC(channels," Channel bitmask for specific locales. NYI"); +#endif + +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 9) +module_param(ifname, charp, S_IRUGO|S_IWUSR ); +//module_param(hwseqnum,int, S_IRUGO|S_IWUSR); +//module_param(hwwep,int, S_IRUGO|S_IWUSR); +module_param(channels,int, S_IRUGO|S_IWUSR); +#else +MODULE_PARM(ifname, "s"); +//MODULE_PARM(hwseqnum,"i"); +//MODULE_PARM(hwwep,"i"); +MODULE_PARM(channels,"i"); +#endif + +MODULE_PARM_DESC(devname," Net interface name, wlan%d=default"); +//MODULE_PARM_DESC(hwseqnum," Try to use hardware 802.11 header sequence numbers. Zero=default"); +//MODULE_PARM_DESC(hwwep," Try to use hardware WEP support. Still broken and not available on all cards"); +MODULE_PARM_DESC(channels," Channel bitmask for specific locales. NYI"); + +#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0) +static int __devinit rtl8187_usb_probe(struct usb_interface *intf, + const struct usb_device_id *id); +static void __devexit rtl8187_usb_disconnect(struct usb_interface *intf); +#else +static void *__devinit rtl8187_usb_probe(struct usb_device *udev,unsigned int ifnum, + const struct usb_device_id *id); +static void __devexit rtl8187_usb_disconnect(struct usb_device *udev, void *ptr); +#endif + + +static struct usb_driver rtl8187_usb_driver = { +#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 15) + .owner = THIS_MODULE, +#endif + .name = RTL8187_MODULE_NAME, /* Driver name */ + .id_table = rtl8187_usb_id_tbl, /* PCI_ID table */ + .probe = rtl8187_usb_probe, /* probe fn */ + .disconnect = rtl8187_usb_disconnect, /* remove fn */ +#if LINUX_VERSION_CODE > KERNEL_VERSION(2, 5, 0) +#ifdef CONFIG_RTL8180_PM + .suspend = rtl8187_suspend, /* PM suspend fn */ + .resume = rtl8187_resume, /* PM resume fn */ +#else + .suspend = NULL, /* PM suspend fn */ + .resume = NULL, /* PM resume fn */ +#endif +#endif +}; + +#ifdef JOHN_HWSEC +void CAM_mark_invalid(struct net_device *dev, u8 ucIndex) +{ + u32 ulContent=0; + u32 ulCommand=0; + u32 ulEncAlgo=CAM_AES; + + // keyid must be set in config field + ulContent |= (ucIndex&3) | ((u16)(ulEncAlgo)<<2); + + ulContent |= BIT15; + // polling bit, and No Write enable, and address + ulCommand= CAM_CONTENT_COUNT*ucIndex; + ulCommand= ulCommand | BIT31|BIT16; + // write content 0 is equall to mark invalid + + write_nic_dword(dev, WCAMI, ulContent); //delay_ms(40); + //RT_TRACE(COMP_SEC, DBG_LOUD, ("CAM_mark_invalid(): WRITE A4: %x \n",ulContent)); + write_nic_dword(dev, RWCAM, ulCommand); //delay_ms(40); + //RT_TRACE(COMP_SEC, DBG_LOUD, ("CAM_mark_invalid(): WRITE A0: %x \n",ulCommand)); +} + +void CAM_empty_entry(struct net_device *dev, u8 ucIndex) +{ + u32 ulCommand=0; + u32 ulContent=0; + u8 i; + u32 ulEncAlgo=CAM_AES; + + for(i=0;i<6;i++) + { + + // filled id in CAM config 2 byte + if( i == 0) + { + ulContent |=(ucIndex & 0x03) | (ulEncAlgo<<2); + ulContent |= BIT15; + + } + else + { + ulContent = 0; + } + // polling bit, and No Write enable, and address + ulCommand= CAM_CONTENT_COUNT*ucIndex+i; + ulCommand= ulCommand | BIT31|BIT16; + // write content 0 is equall to mark invalid + write_nic_dword(dev, WCAMI, ulContent); //delay_ms(40); + //RT_TRACE(COMP_SEC, DBG_LOUD, ("CAM_empty_entry(): WRITE A4: %x \n",ulContent)); + write_nic_dword(dev, RWCAM, ulCommand); //delay_ms(40); + //RT_TRACE(COMP_SEC, DBG_LOUD, ("CAM_empty_entry(): WRITE A0: %x \n",ulCommand)); + } +} + +void CamResetAllEntry(struct net_device *dev) +{ + u8 ucIndex; + + //2004/02/11 In static WEP, OID_ADD_KEY or OID_ADD_WEP are set before STA associate to AP. + // However, ResetKey is called on OID_802_11_INFRASTRUCTURE_MODE and MlmeAssociateRequest + // In this condition, Cam can not be reset because upper layer will not set this static key again. + //if(Adapter->EncAlgorithm == WEP_Encryption) + // return; + //debug + //DbgPrint("========================================\n"); + //DbgPrint(" Call ResetAllEntry \n"); + //DbgPrint("========================================\n\n"); + + for(ucIndex=0;ucIndexwrite_read_register_index % 200) ; + + priv->write_read_registers[reg_index].address = 0; + priv->write_read_registers[reg_index].content = 0; + priv->write_read_registers[reg_index].flag = 0; + + priv->write_read_registers[reg_index].address = addr; + priv->write_read_registers[reg_index].content = cont; + priv->write_read_registers[reg_index].flag = flag; + + priv->write_read_register_index = (priv->write_read_register_index + 1) % 200; +} + +bool print_once = 0; + +void print_rw_registers(struct net_device *dev) +{ + struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev); + int reg_index = 0; + int watchdog = 0; + if(print_once == false) + { + print_once = true; + for(reg_index = ((priv->write_read_register_index + 1) % 200); watchdog <= 199; reg_index++) + { + watchdog++; + printk("====>reg_addr:0x%x, reg_cont:0x%x, read_or_write:0x%d\n", + priv->write_read_registers[reg_index].address, + priv->write_read_registers[reg_index].content, + priv->write_read_registers[reg_index].flag); + } + } +} +//lzm add for write time out test +#endif + +#ifdef CPU_64BIT +void write_nic_byte_E(struct net_device *dev, int indx, u8 data) +{ + int status; + struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev); + struct usb_device *udev = priv->udev; + + status = usb_control_msg(udev, usb_sndctrlpipe(udev, 0), + RTL8187_REQ_SET_REGS, RTL8187_REQT_WRITE, + indx|0xfe00, 0, &data, 1, HZ / 2); + +//lzm add for write time out test +#ifdef DEBUG_RW_REGISTER + add_into_rw_registers(dev, indx, data, 2); +#endif + + if (status < 0) + { + printk("write_nic_byte_E TimeOut!addr:%x, status:%x\n", indx, status); +#ifdef DEBUG_RW_REGISTER + print_rw_registers(dev); +#endif + } +} + +u8 read_nic_byte_E(struct net_device *dev, int indx) +{ + int status; + u8 data, *buf; + dma_addr_t dma_handle; + struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev); + struct usb_device *udev = priv->udev; + + buf = dma_pool_alloc(priv->usb_pool, GFP_ATOMIC, &dma_handle); + if (!buf) { + printk("read_nic_byte_E out of memory\n"); + return -ENOMEM; + } + status = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0), + RTL8187_REQ_GET_REGS, RTL8187_REQT_READ, + indx|0xfe00, 0, buf, 1, HZ / 2); +//lzm add for write time out test +#ifdef DEBUG_RW_REGISTER + add_into_rw_registers(dev, indx, buf[0], 1); +#endif + + if (status < 0) + { + printk("read_nic_byte_E TimeOut!addr:%x, status:%x\n",indx, status); +#ifdef DEBUG_RW_REGISTER + print_rw_registers(dev); +#endif + } + + data = buf[0]; + dma_pool_free(priv->usb_pool, buf, dma_handle); + return data; +} + +void write_nic_byte(struct net_device *dev, int indx, u8 data) +{ + int status; + + struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev); + struct usb_device *udev = priv->udev; + + status = usb_control_msg(udev, usb_sndctrlpipe(udev, 0), + RTL8187_REQ_SET_REGS, RTL8187_REQT_WRITE, + (indx&0xff)|0xff00, (indx>>8)&0x03, &data, 1, HZ / 2); + +//lzm add for write time out test +#ifdef DEBUG_RW_REGISTER + add_into_rw_registers(dev, indx, data, 2); +#endif + if (status < 0) + { + printk("write_nic_byte TimeOut!addr:%x, status:%x\n",indx, status); +#ifdef DEBUG_RW_REGISTER + print_rw_registers(dev); +#endif + } + + +} + +void write_nic_word(struct net_device *dev, int indx, u16 data) +{ + + int status; + + struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev); + struct usb_device *udev = priv->udev; + + status = usb_control_msg(udev, usb_sndctrlpipe(udev, 0), + RTL8187_REQ_SET_REGS, RTL8187_REQT_WRITE, + (indx&0xff)|0xff00, (indx>>8)&0x03, &data, 2, HZ / 2); + +//lzm add for write time out test +#ifdef DEBUG_RW_REGISTER + add_into_rw_registers(dev, indx, data, 2); + + if(priv->write_read_register_index == 199) + { + //print_rw_registers(dev); + } +#endif + if (status < 0) + { + printk("write_nic_word TimeOut!addr:%x, status:%x\n",indx, status); +#ifdef DEBUG_RW_REGISTER + print_rw_registers(dev); +#endif + } + +} + +void write_nic_dword(struct net_device *dev, int indx, u32 data) +{ + + int status; + + struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev); + struct usb_device *udev = priv->udev; + + status = usb_control_msg(udev, usb_sndctrlpipe(udev, 0), + RTL8187_REQ_SET_REGS, RTL8187_REQT_WRITE, + (indx&0xff)|0xff00, (indx>>8)&0x03, &data, 4, HZ / 2); +//lzm add for write time out test +#ifdef DEBUG_RW_REGISTER + add_into_rw_registers(dev, indx, data, 2); +#endif + + + if (status < 0) + { + printk("write_nic_dword TimeOut!addr:%x, status:%x\n",indx, status); +#ifdef DEBUG_RW_REGISTER + print_rw_registers(dev); +#endif + } + +} + + u8 read_nic_byte(struct net_device *dev, int indx) +{ + u8 data, *buf; + int status; + struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev); + struct usb_device *udev = priv->udev; + dma_addr_t dma_handle; + + buf = dma_pool_alloc(priv->usb_pool, GFP_ATOMIC, &dma_handle); + if (!buf) { + printk("read_nic_byte: out of memory\n"); + return -ENOMEM; + } + status = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0), + RTL8187_REQ_GET_REGS, RTL8187_REQT_READ, + (indx&0xff)|0xff00, (indx>>8)&0x03, buf, 1, HZ / 2); +//lzm add for write time out test +#ifdef DEBUG_RW_REGISTER + add_into_rw_registers(dev, indx, buf[0], 1); +#endif + + if (status < 0) + { + printk("read_nic_byte TimeOut!addr:%x, status:%x\n",indx, status); +#ifdef DEBUG_RW_REGISTER + print_rw_registers(dev); +#endif + } + + data = buf[0]; + dma_pool_free(priv->usb_pool, buf, dma_handle); + return data; +} + +u16 read_nic_word(struct net_device *dev, int indx) +{ + u16 data, *buf; + int status; + struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev); + struct usb_device *udev = priv->udev; + dma_addr_t dma_handle; + + buf = dma_pool_alloc(priv->usb_pool, GFP_ATOMIC, &dma_handle); + if (!buf) { + printk("read_nic_word: out of memory\n"); + return -ENOMEM; + } + status = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0), + RTL8187_REQ_GET_REGS, RTL8187_REQT_READ, + (indx&0xff)|0xff00, (indx>>8)&0x03, buf, 2, HZ / 2); +//lzm add for write time out test +#ifdef DEBUG_RW_REGISTER + add_into_rw_registers(dev, indx, buf[0], 1); +#endif + + if (status < 0) + { + printk("read_nic_word TimeOut!addr:%x, status:%x\n",indx, status); +#ifdef DEBUG_RW_REGISTER + print_rw_registers(dev); +#endif + } + + + data = buf[0]; + dma_pool_free(priv->usb_pool, buf, dma_handle); + return data; +} + +u32 read_nic_dword(struct net_device *dev, int indx) +{ + u32 data, *buf; + int status; + dma_addr_t dma_handle; +// int result; + + struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev); + struct usb_device *udev = priv->udev; + + buf = dma_pool_alloc(priv->usb_pool, GFP_ATOMIC, &dma_handle); + if (!buf){ + printk("read_nic_dword: out of memory\n"); + return -ENOMEM; + } + status = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0), + RTL8187_REQ_GET_REGS, RTL8187_REQT_READ, + (indx&0xff)|0xff00, (indx>>8)&0x03, buf, 4, HZ / 2); +//lzm add for write time out test +#ifdef DEBUG_RW_REGISTER + add_into_rw_registers(dev, indx, buf[0], 1); +#endif + + if (status < 0) + { + printk("read_nic_dword TimeOut!addr:%x, status:%x\n",indx, status); +#ifdef DEBUG_RW_REGISTER + print_rw_registers(dev); +#endif + } + + + + data = buf[0]; + dma_pool_free(priv->usb_pool, buf, dma_handle); + return data; +} +#else +void write_nic_byte_E(struct net_device *dev, int indx, u8 data) +{ + int status; + struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev); + struct usb_device *udev = priv->udev; + + status = usb_control_msg(udev, usb_sndctrlpipe(udev, 0), + RTL8187_REQ_SET_REGS, RTL8187_REQT_WRITE, + indx|0xfe00, 0, &data, 1, HZ / 2); + + if (status < 0) + { + printk("write_nic_byte_E TimeOut!addr:0x%x,val:0x%x, status:%x\n", indx,data,status); + } +} + +u8 read_nic_byte_E(struct net_device *dev, int indx) +{ + int status; + u8 data = 0; + u8 buf[64]; + struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev); + struct usb_device *udev = priv->udev; + + status = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0), + RTL8187_REQ_GET_REGS, RTL8187_REQT_READ, + indx|0xfe00, 0, buf, 1, HZ / 2); + + if (status < 0) + { + printk("read_nic_byte_E TimeOut!addr:0x%x, status:%x\n", indx, status); + } + + data = *(u8*)buf; + return data; +} + +void write_nic_byte(struct net_device *dev, int indx, u8 data) +{ + int status; + + struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev); + struct usb_device *udev = priv->udev; + + status = usb_control_msg(udev, usb_sndctrlpipe(udev, 0), + RTL8187_REQ_SET_REGS, RTL8187_REQT_WRITE, + (indx&0xff)|0xff00, (indx>>8)&0x03, &data, 1, HZ / 2); + + if (status < 0) + { + printk("write_nic_byte TimeOut!addr:0x%x,val:0x%x, status:%x\n", indx,data, status); + } + + +} + +void write_nic_word(struct net_device *dev, int indx, u16 data) +{ + + int status; + + struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev); + struct usb_device *udev = priv->udev; + + status = usb_control_msg(udev, usb_sndctrlpipe(udev, 0), + RTL8187_REQ_SET_REGS, RTL8187_REQT_WRITE, + (indx&0xff)|0xff00, (indx>>8)&0x03, &data, 2, HZ / 2); + + if (status < 0) + { + printk("write_nic_word TimeOut!addr:0x%x,val:0x%x, status:%x\n", indx,data, status); + } + +} + +void write_nic_dword(struct net_device *dev, int indx, u32 data) +{ + + int status; + + struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev); + struct usb_device *udev = priv->udev; + + status = usb_control_msg(udev, usb_sndctrlpipe(udev, 0), + RTL8187_REQ_SET_REGS, RTL8187_REQT_WRITE, + (indx&0xff)|0xff00, (indx>>8)&0x03, &data, 4, HZ / 2); + + + if (status < 0) + { + printk("write_nic_dword TimeOut!addr:0x%x,val:0x%x, status:%x\n", indx,data, status); + } + +} + +u8 read_nic_byte(struct net_device *dev, int indx) +{ + u8 data = 0; + u8 buf[64]; + int status; + struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev); + struct usb_device *udev = priv->udev; + + status = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0), + RTL8187_REQ_GET_REGS, RTL8187_REQT_READ, + (indx&0xff)|0xff00, (indx>>8)&0x03, buf, 1, HZ / 2); + + if (status < 0) + { + printk("read_nic_byte TimeOut!addr:0x%x,status:%x\n", indx,status); + } + + + data = *(u8*)buf; + return data; +} + +u16 read_nic_word(struct net_device *dev, int indx) +{ + u16 data = 0; + u8 buf[64]; + int status; + struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev); + struct usb_device *udev = priv->udev; + + status = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0), + RTL8187_REQ_GET_REGS, RTL8187_REQT_READ, + (indx&0xff)|0xff00, (indx>>8)&0x03, buf, 2, HZ / 2); + + if (status < 0) + { + printk("read_nic_word TimeOut!addr:0x%x,status:%x\n", indx,status); + } + + data = *(u16*)buf; + return data; +} + +u32 read_nic_dword(struct net_device *dev, int indx) +{ + u32 data = 0; + u8 buf[64]; + int status; + + struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev); + struct usb_device *udev = priv->udev; + + status = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0), + RTL8187_REQ_GET_REGS, RTL8187_REQT_READ, + (indx&0xff)|0xff00, (indx>>8)&0x03, buf, 4, HZ / 2); + + if (status < 0) + { + printk("read_nic_dword TimeOut!addr:0x%x,status:%x\n", indx, status); + } + + + data = *(u32*)buf; + return data; +} +#endif + + +u8 read_phy_cck(struct net_device *dev, u8 adr); +u8 read_phy_ofdm(struct net_device *dev, u8 adr); +/* this might still called in what was the PHY rtl8185/rtl8187 common code + * plans are to possibilty turn it again in one common code... + */ +inline void force_pci_posting(struct net_device *dev) +{ +} + + +static struct net_device_stats *rtl8180_stats(struct net_device *dev); +void rtl8180_commit(struct net_device *dev); +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)) +void rtl8180_restart(struct work_struct *work); +#else +void rtl8180_restart(struct net_device *dev); +#endif +/**************************************************************************** + -----------------------------PROCFS STUFF------------------------- +*****************************************************************************/ + +static struct proc_dir_entry *rtl8180_proc = NULL; +static int proc_get_stats_ap(char *page, char **start, + off_t offset, int count, + int *eof, void *data) +{ + struct net_device *dev = data; + struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev); + struct ieee80211_device *ieee = priv->ieee80211; + struct ieee80211_network *target; + + int len = 0; + + list_for_each_entry(target, &ieee->network_list, list) { + + len += snprintf(page + len, count - len, + "%s ", target->ssid); + len += snprintf(page + len, count - len, + "%ld ", (jiffies-target->last_scanned)/HZ); + + + + if(target->wpa_ie_len>0 || target->rsn_ie_len>0){ + len += snprintf(page + len, count - len, + "WPA\n"); + } + else{ + len += snprintf(page + len, count - len, + "non_WPA\n"); + } + + } + + *eof = 1; + return len; +} + +static int proc_get_registers(char *page, char **start, + off_t offset, int count, + int *eof, void *data) +{ + struct net_device *dev = data; + + int len = 0; + int i,n; + + int max=0xff; + + /* This dump the current register page */ +len += snprintf(page + len, count - len, + "\n####################page 0##################\n "); + + for(n=0;n<=max;) + { + //printk( "\nD: %2x> ", n); + len += snprintf(page + len, count - len, + "\nD: %2x > ",n); + + for(i=0;i<16 && n<=max;i++,n++) + len += snprintf(page + len, count - len, + "%2x ",read_nic_byte(dev,n)); + + // printk("%2x ",read_nic_byte(dev,n)); + } + len += snprintf(page + len, count - len,"\n"); +len += snprintf(page + len, count - len, + "\n####################page 1##################\n "); + for(n=0;n<=max;) + { + //printk( "\nD: %2x> ", n); + len += snprintf(page + len, count - len, + "\nD: %2x > ",n); + + for(i=0;i<16 && n<=max;i++,n++) + len += snprintf(page + len, count - len, + "%2x ",read_nic_byte(dev,0x100|n)); + + // printk("%2x ",read_nic_byte(dev,n)); + } +len += snprintf(page + len, count - len, + "\n####################page 2##################\n "); + for(n=0;n<=max;) + { + //printk( "\nD: %2x> ", n); + len += snprintf(page + len, count - len, + "\nD: %2x > ",n); + + for(i=0;i<16 && n<=max;i++,n++) + len += snprintf(page + len, count - len, + "%2x ",read_nic_byte(dev,0x200|n)); + + // printk("%2x ",read_nic_byte(dev,n)); + } + + + + *eof = 1; + return len; + +} + + +static int proc_get_cck_reg(char *page, char **start, + off_t offset, int count, + int *eof, void *data) +{ + struct net_device *dev = data; + + int len = 0; + int i,n; + + int max = 0x5F; + + /* This dump the current register page */ + for(n=0;n<=max;) + { + //printk( "\nD: %2x> ", n); + len += snprintf(page + len, count - len, + "\nD: %2x > ",n); + + for(i=0;i<16 && n<=max;i++,n++) + len += snprintf(page + len, count - len, + "%2x ",read_phy_cck(dev,n)); + + // printk("%2x ",read_nic_byte(dev,n)); + } + len += snprintf(page + len, count - len,"\n"); + + + *eof = 1; + return len; + +} + + +static int proc_get_ofdm_reg(char *page, char **start, + off_t offset, int count, + int *eof, void *data) +{ + struct net_device *dev = data; + + int len = 0; + int i,n; + + //int max=0xff; + int max = 0x40; + + /* This dump the current register page */ + for(n=0;n<=max;) + { + //printk( "\nD: %2x> ", n); + len += snprintf(page + len, count - len, + "\nD: %2x > ",n); + + for(i=0;i<16 && n<=max;i++,n++) + len += snprintf(page + len, count - len, + "%2x ",read_phy_ofdm(dev,n)); + + // printk("%2x ",read_nic_byte(dev,n)); + } + len += snprintf(page + len, count - len,"\n"); + + + + *eof = 1; + return len; + +} + + +#if 0 +static int proc_get_stats_hw(char *page, char **start, + off_t offset, int count, + int *eof, void *data) +{ + struct net_device *dev = data; + struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev); + + int len = 0; + + len += snprintf(page + len, count - len, + "NIC int: %lu\n" + "Total int: %lu\n", + priv->stats.ints, + priv->stats.shints); + + *eof = 1; + return len; +} +#endif + +static int proc_get_stats_tx(char *page, char **start, + off_t offset, int count, + int *eof, void *data) +{ + struct net_device *dev = data; + struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev); + + int len = 0; + + len += snprintf(page + len, count - len, + "TX VI priority ok int: %lu\n" + "TX VI priority error int: %lu\n" + "TX VO priority ok int: %lu\n" + "TX VO priority error int: %lu\n" + "TX BE priority ok int: %lu\n" + "TX BE priority error int: %lu\n" + "TX BK priority ok int: %lu\n" + "TX BK priority error int: %lu\n" + "TX MANAGE priority ok int: %lu\n" + "TX MANAGE priority error int: %lu\n" + "TX BEACON priority ok int: %lu\n" + "TX BEACON priority error int: %lu\n" +// "TX high priority ok int: %lu\n" +// "TX high priority failed error int: %lu\n" + "TX queue resume: %lu\n" + "TX queue stopped?: %d\n" + "TX fifo overflow: %lu\n" +// "TX beacon: %lu\n" + "TX VI queue: %d\n" + "TX VO queue: %d\n" + "TX BE queue: %d\n" + "TX BK queue: %d\n" + "TX BEACON queue: %d\n" + "TX MANAGE queue: %d\n" +// "TX HW queue: %d\n" + "TX VI dropped: %lu\n" + "TX VO dropped: %lu\n" + "TX BE dropped: %lu\n" + "TX BK dropped: %lu\n" + "TX total data packets %lu\n", +// "TX beacon aborted: %lu\n", + priv->stats.txviokint, + priv->stats.txvierr, + priv->stats.txvookint, + priv->stats.txvoerr, + priv->stats.txbeokint, + priv->stats.txbeerr, + priv->stats.txbkokint, + priv->stats.txbkerr, + priv->stats.txmanageokint, + priv->stats.txmanageerr, + priv->stats.txbeaconokint, + priv->stats.txbeaconerr, +// priv->stats.txhpokint, +// priv->stats.txhperr, + priv->stats.txresumed, + netif_queue_stopped(dev), + priv->stats.txoverflow, +// priv->stats.txbeacon, + atomic_read(&(priv->tx_pending[VI_PRIORITY])), + atomic_read(&(priv->tx_pending[VO_PRIORITY])), + atomic_read(&(priv->tx_pending[BE_PRIORITY])), + atomic_read(&(priv->tx_pending[BK_PRIORITY])), + atomic_read(&(priv->tx_pending[BEACON_PRIORITY])), + atomic_read(&(priv->tx_pending[MANAGE_PRIORITY])), +// read_nic_byte(dev, TXFIFOCOUNT), + priv->stats.txvidrop, + priv->stats.txvodrop, + priv->stats.txbedrop, + priv->stats.txbkdrop, + priv->stats.txdatapkt +// priv->stats.txbeaconerr + ); + + *eof = 1; + return len; +} + + + +static int proc_get_stats_rx(char *page, char **start, + off_t offset, int count, + int *eof, void *data) +{ + struct net_device *dev = data; + struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev); + + int len = 0; + + len += snprintf(page + len, count - len, + "RX packets: %lu\n" + "RX urb status error: %lu\n" + "RX invalid urb error: %lu\n", + priv->stats.rxok, + priv->stats.rxstaterr, + priv->stats.rxurberr); + + *eof = 1; + return len; +} + +#if WIRELESS_EXT < 17 +static struct iw_statistics *r8180_get_wireless_stats(struct net_device *dev) +{ + struct r8180_priv *priv = ieee80211_priv(dev); + + return &priv->wstats; +} +#endif + +void rtl8180_proc_module_init(void) +{ + DMESG("Initializing proc filesystem"); +#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,24)) + rtl8180_proc=create_proc_entry(RTL8187_MODULE_NAME, S_IFDIR, proc_net); +#else + rtl8180_proc=create_proc_entry(RTL8187_MODULE_NAME, S_IFDIR, init_net.proc_net); +#endif +} + + +void rtl8180_proc_module_remove(void) +{ +#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,24)) + remove_proc_entry(RTL8187_MODULE_NAME, proc_net); +#else + remove_proc_entry(RTL8187_MODULE_NAME, init_net.proc_net); +#endif +} + + +void rtl8180_proc_remove_one(struct net_device *dev) +{ + struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev); + if (priv->dir_dev) { + // remove_proc_entry("stats-hw", priv->dir_dev); + remove_proc_entry("stats-tx", priv->dir_dev); + remove_proc_entry("stats-rx", priv->dir_dev); + // remove_proc_entry("stats-ieee", priv->dir_dev); + remove_proc_entry("stats-ap", priv->dir_dev); + remove_proc_entry("registers", priv->dir_dev); + remove_proc_entry("cck-registers",priv->dir_dev); + remove_proc_entry("ofdm-registers",priv->dir_dev); + remove_proc_entry(dev->name, rtl8180_proc); + priv->dir_dev = NULL; + } +} + + +void rtl8180_proc_init_one(struct net_device *dev) +{ + struct proc_dir_entry *e; + struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev); + priv->dir_dev = create_proc_entry(dev->name, + S_IFDIR | S_IRUGO | S_IXUGO, + rtl8180_proc); + if (!priv->dir_dev) { + DMESGE("Unable to initialize /proc/net/rtl8187/%s\n", + dev->name); + return; + } + #if 0 + e = create_proc_read_entry("stats-hw", S_IFREG | S_IRUGO, + priv->dir_dev, proc_get_stats_hw, dev); + + if (!e) { + DMESGE("Unable to initialize " + "/proc/net/rtl8187/%s/stats-hw\n", + dev->name); + } + #endif + e = create_proc_read_entry("stats-rx", S_IFREG | S_IRUGO, + priv->dir_dev, proc_get_stats_rx, dev); + + if (!e) { + DMESGE("Unable to initialize " + "/proc/net/rtl8187/%s/stats-rx\n", + dev->name); + } + + + e = create_proc_read_entry("stats-tx", S_IFREG | S_IRUGO, + priv->dir_dev, proc_get_stats_tx, dev); + + if (!e) { + DMESGE("Unable to initialize " + "/proc/net/rtl8187/%s/stats-tx\n", + dev->name); + } + #if 0 + e = create_proc_read_entry("stats-ieee", S_IFREG | S_IRUGO, + priv->dir_dev, proc_get_stats_ieee, dev); + + if (!e) { + DMESGE("Unable to initialize " + "/proc/net/rtl8187/%s/stats-ieee\n", + dev->name); + } + + #endif + + e = create_proc_read_entry("stats-ap", S_IFREG | S_IRUGO, + priv->dir_dev, proc_get_stats_ap, dev); + + if (!e) { + DMESGE("Unable to initialize " + "/proc/net/rtl8187/%s/stats-ap\n", + dev->name); + } + + e = create_proc_read_entry("registers", S_IFREG | S_IRUGO, + priv->dir_dev, proc_get_registers, dev); + if (!e) { + DMESGE("Unable to initialize " + "/proc/net/rtl8187/%s/registers\n", + dev->name); + } + + e = create_proc_read_entry("cck-registers", S_IFREG | S_IRUGO, + priv->dir_dev, proc_get_cck_reg, dev); + if (!e) { + DMESGE("Unable to initialize " + "/proc/net/rtl8187/%s/cck-registers\n", + dev->name); + } + + e = create_proc_read_entry("ofdm-registers", S_IFREG | S_IRUGO, + priv->dir_dev, proc_get_ofdm_reg, dev); + if (!e) { + DMESGE("Unable to initialize " + "/proc/net/rtl8187/%s/ofdm-registers\n", + dev->name); + } + +#ifdef _RTL8187_EXT_PATCH_ + if( priv->mshobj && priv->mshobj->ext_patch_create_proc ) + priv->mshobj->ext_patch_create_proc(priv); +#endif + +} +/**************************************************************************** + -----------------------------MISC STUFF------------------------- +*****************************************************************************/ + +/* this is only for debugging */ +void print_buffer(u32 *buffer, int len) +{ + int i; + u8 *buf =(u8*)buffer; + + printk("ASCII BUFFER DUMP (len: %x):\n",len); + + for(i=0;itx_np_pending : &priv->tx_lp_pending); + int used = atomic_read(&priv->tx_pending[priority]); + + return (used < MAX_TX_URB); +} + +void tx_timeout(struct net_device *dev) +{ + struct r8180_priv *priv = ieee80211_priv(dev); + //rtl8180_commit(dev); + printk("@@@@ Transmit timeout at %ld, latency %ld\n", jiffies, + jiffies - dev->trans_start); + + printk("@@@@ netif_queue_stopped = %d\n", netif_queue_stopped(dev)); + +#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)) + schedule_work(&priv->reset_wq); +#else + schedule_task(&priv->reset_wq); +#endif + //DMESG("TXTIMEOUT"); +} + + +/* this is only for debug */ +void dump_eprom(struct net_device *dev) +{ + int i; + for(i=0; i<63; i++) + DMESG("EEPROM addr %x : %x", i, eprom_read(dev,i)); +} + +/* this is only for debug */ +void rtl8180_dump_reg(struct net_device *dev) +{ + int i; + int n; + int max=0xff; + + DMESG("Dumping NIC register map"); + + for(n=0;n<=max;) + { + printk( "\nD: %2x> ", n); + for(i=0;i<16 && n<=max;i++,n++) + printk("%2x ",read_nic_byte(dev,n)); + } + printk("\n"); +} + +/**************************************************************************** + ------------------------------HW STUFF--------------------------- +*****************************************************************************/ + + +void rtl8180_irq_enable(struct net_device *dev) +{ + struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev); + //priv->irq_enabled = 1; + + //write_nic_word(dev,INTA_MASK,INTA_RXOK | INTA_RXDESCERR | INTA_RXOVERFLOW | + // INTA_TXOVERFLOW | INTA_HIPRIORITYDESCERR | INTA_HIPRIORITYDESCOK | + // INTA_NORMPRIORITYDESCERR | INTA_NORMPRIORITYDESCOK | + // INTA_LOWPRIORITYDESCERR | INTA_LOWPRIORITYDESCOK | INTA_TIMEOUT); + + write_nic_word(dev,INTA_MASK, priv->irq_mask); +} + + +void rtl8180_irq_disable(struct net_device *dev) +{ + write_nic_word(dev,INTA_MASK,0); + force_pci_posting(dev); +// priv->irq_enabled = 0; +} + + +void rtl8180_set_mode(struct net_device *dev,int mode) +{ + u8 ecmd; + ecmd=read_nic_byte(dev, EPROM_CMD); + ecmd=ecmd &~ EPROM_CMD_OPERATING_MODE_MASK; + ecmd=ecmd | (mode<ieee80211->state == IEEE80211_LINKED){ + + if (priv->ieee80211->iw_mode == IW_MODE_INFRA) + msr |= (MSR_LINK_MANAGED<ieee80211->iw_mode == IW_MODE_ADHOC) + msr |= (MSR_LINK_ADHOC<ieee80211->iw_mode == IW_MODE_MASTER) + msr |= (MSR_LINK_MASTER<chan=ch; + #if 0 + if(priv->ieee80211->iw_mode == IW_MODE_ADHOC || + priv->ieee80211->iw_mode == IW_MODE_MASTER){ + + priv->ieee80211->link_state = WLAN_LINK_ASSOCIATED; + priv->ieee80211->master_chan = ch; + rtl8180_update_beacon_ch(dev); + } + #endif + + /* this hack should avoid frame TX during channel setting*/ + tx = read_nic_dword(dev,TX_CONF); + tx &= ~TX_LOOPBACK_MASK; + +#ifndef LOOP_TEST + write_nic_dword(dev,TX_CONF, tx |( TX_LOOPBACK_MAC<rf_set_chan(dev,priv->chan); + //mdelay(10); //CPU occupany is too high. LZM 31/10/2008 + write_nic_dword(dev,TX_CONF,tx | (TX_LOOPBACK_NONE<udev, + usb_rcvbulkpipe(priv->udev,(NIC_8187 == priv->card_8187)?0x81:0x83), + rx_urb->transfer_buffer, + RX_URB_SIZE, + rtl8187_rx_isr, + dev); +#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0) + err = usb_submit_urb(rx_urb, GFP_ATOMIC); +#else + err = usb_submit_urb(rx_urb); +#endif + if(err && err != -EPERM){ + DMESGE("cannot submit RX command. URB_STATUS %x",rx_urb->status); + } +} + + +void rtl8187_rx_manage_urbsubmit(struct net_device *dev, struct urb* rx_urb) +{ + struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev); + int err; +#ifdef THOMAS_BEACON + usb_fill_bulk_urb(rx_urb,priv->udev, + usb_rcvbulkpipe(priv->udev,0x09), + rx_urb->transfer_buffer, + rx_urb->transfer_buffer_length, + rtl8187_rx_manage_isr, dev); +#endif + +#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0) + err = usb_submit_urb(rx_urb, GFP_ATOMIC); +#else + err = usb_submit_urb(rx_urb); +#endif + if(err && err != -EPERM){ + DMESGE("cannot submit RX command. URB_STATUS %x",rx_urb->status); + } +} + + + +void rtl8187_rx_initiate(struct net_device *dev) +{ + int i; + unsigned long flags; + struct urb *purb; + + struct sk_buff *pskb; + + struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev); + + priv->tx_urb_index = 0; + + if ((!priv->rx_urb) || (!priv->pp_rxskb)) { + + DMESGE("Cannot intiate RX urb mechanism"); + return; + + } + + priv->rx_inx = 0; +#ifdef THOMAS_TASKLET + atomic_set(&priv->irt_counter,0); +#endif + for(i = 0;i < MAX_RX_URB; i++){ + + purb = priv->rx_urb[i] = usb_alloc_urb(0,GFP_KERNEL); + + if(!priv->rx_urb[i]) + goto destroy; + + pskb = priv->pp_rxskb[i] = dev_alloc_skb (RX_URB_SIZE); + + if (pskb == NULL) + goto destroy; + + purb->transfer_buffer_length = RX_URB_SIZE; + purb->transfer_buffer = pskb->data; + } + + spin_lock_irqsave(&priv->irq_lock,flags);//added by thomas + + for(i=0;irx_urb[i]); + + spin_unlock_irqrestore(&priv->irq_lock,flags);//added by thomas + + return; + +destroy: + + for(i = 0; i < MAX_RX_URB; i++) { + + purb = priv->rx_urb[i]; + + if (purb) + usb_free_urb(purb); + + pskb = priv->pp_rxskb[i]; + + if (pskb) + dev_kfree_skb_any(pskb); + + } + + return; +} + + +void rtl8187_rx_manage_initiate(struct net_device *dev) +{ + struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev); + if(!priv->rx_urb) + DMESGE("Cannot intiate RX urb mechanism"); + + rtl8187_rx_manage_urbsubmit(dev,priv->rx_urb[MAX_RX_URB]); + +} + + +void rtl8187_set_rxconf(struct net_device *dev) +{ + struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev); + u32 rxconf; + + rxconf=read_nic_dword(dev,RX_CONF); + rxconf = rxconf &~ MAC_FILTER_MASK; + rxconf = rxconf | (1<EEPROMCSMethod;//for antenna +#endif + + if (dev->flags & IFF_PROMISC) DMESG ("NIC in promisc mode"); + + if(priv->ieee80211->iw_mode == IW_MODE_MONITOR || \ + dev->flags & IFF_PROMISC){ + rxconf = rxconf | (1<ieee80211->iw_mode == IW_MODE_MASTER){ + rxconf = rxconf | (1<ieee80211->iw_mode == IW_MODE_MONITOR){ + rxconf = rxconf | (1<crcmon == 1 && priv->ieee80211->iw_mode == IW_MODE_MONITOR) + rxconf = rxconf | (1<card_8187) { + cmd=read_nic_byte(dev,CMD); + write_nic_byte(dev,CMD,cmd | (1<ReceiveConfig); + } +} + + +void rtl8180_tx_enable(struct net_device *dev) +{ + u8 cmd; + u8 byte; + u32 txconf = 0; + struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev); + + if(NIC_8187B == priv->card_8187){ + write_nic_dword(dev, TCR, priv->TransmitConfig); + byte = read_nic_byte(dev, MSR); + byte |= MSR_LINK_ENEDCA; + write_nic_byte(dev, MSR, byte); +#ifdef LOOP_TEST + txconf= read_nic_dword(dev,TX_CONF); + txconf = txconf | (TX_LOOPBACK_MAC<retry_data<retry_rts<dma_poll_mask &=~(1<dma_poll_mask); + rtl8180_set_mode(dev,EPROM_CMD_NORMAL); +} + + +void rtl8180_ +_disable(struct net_device *dev) +{ + struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev); + priv->dma_poll_mask |= (1<dma_poll_mask); + rtl8180_set_mode(dev,EPROM_CMD_NORMAL); +} + +#endif + + +void rtl8180_rtx_disable(struct net_device *dev) +{ + u8 cmd; + int i; + struct r8180_priv *priv = ieee80211_priv(dev); + + cmd=read_nic_byte(dev,CMD); + write_nic_byte(dev, CMD, cmd &~ \ + ((1<rx_inx;//0 + i=0; + if(priv->rx_urb){ + while(irx_urb[index]){ + usb_kill_urb(priv->rx_urb[index]); + } + if( index == (MAX_RX_URB-1) ) + index=0; + else + index=index+1; + i++; + } + if(priv->rx_urb[MAX_RX_URB]) + usb_kill_urb(priv->rx_urb[MAX_RX_URB]); + } + } +#endif +} + + +int alloc_tx_beacon_desc_ring(struct net_device *dev, int count) +{ + #if 0 + int i; + u32 *tmp; + struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev); + + priv->txbeaconring = (u32*)pci_alloc_consistent(priv->pdev, + sizeof(u32)*8*count, + &priv->txbeaconringdma); + if (!priv->txbeaconring) return -1; + for (tmp=priv->txbeaconring,i=0;itxbeaconringdma+((i+1)*8*4); + else + *(tmp+4) = (u32)priv->txbeaconringdma; + + tmp=tmp+8; + } + #endif + return 0; +} + +long NetgearSignalStrengthTranslate(long LastSS,long CurrSS) +{ + long RetSS; + + // Step 1. Scale mapping. + if(CurrSS >= 71 && CurrSS <= 100){ + RetSS = 90 + ((CurrSS - 70) / 3); + }else if(CurrSS >= 41 && CurrSS <= 70){ + RetSS = 78 + ((CurrSS - 40) / 3); + }else if(CurrSS >= 31 && CurrSS <= 40){ + RetSS = 66 + (CurrSS - 30); + }else if(CurrSS >= 21 && CurrSS <= 30){ + RetSS = 54 + (CurrSS - 20); + }else if(CurrSS >= 5 && CurrSS <= 20){ + RetSS = 42 + (((CurrSS - 5) * 2) / 3); + }else if(CurrSS == 4){ + RetSS = 36; + }else if(CurrSS == 3){ + RetSS = 27; + }else if(CurrSS == 2){ + RetSS = 18; + }else if(CurrSS == 1){ + RetSS = 9; + }else{ + RetSS = CurrSS; + } + //RT_TRACE(COMP_DBG, DBG_LOUD, ("##### After Mapping: LastSS: %d, CurrSS: %d, RetSS: %d\n", LastSS, CurrSS, RetSS)); + + // Step 2. Smoothing. + if(LastSS > 0){ + RetSS = ((LastSS * 5) + (RetSS)+ 5) / 6; + } + //RT_TRACE(COMP_DBG, DBG_LOUD, ("$$$$$ After Smoothing: LastSS: %d, CurrSS: %d, RetSS: %d\n", LastSS, CurrSS, RetSS)); + + return RetSS; +} + +extern long TranslateToDbm8187(u8 SignalStrengthIndex); // 0-100 index. +//long TranslateToDbm8187(u8 SignalStrengthIndex) // 0-100 index. +//{ + // long SignalPower; // in dBm. + + // Translate to dBm (x=0.5y-95). + // SignalPower = (long)((SignalStrengthIndex + 1) >> 1); + // SignalPower -= 95; + + // return SignalPower; +//} + + +void rtl8180_reset(struct net_device *dev) +{ + + struct r8180_priv *priv = ieee80211_priv(dev); + u8 cr; + int i; + + + /* make sure the analog power is on before + * reset, otherwise reset may fail + */ + if(NIC_8187 == priv->card_8187) { + rtl8180_set_anaparam(dev, RTL8225_ANAPARAM_ON); + rtl8185_set_anaparam2(dev, RTL8225_ANAPARAM2_ON); + rtl8180_irq_disable(dev); + mdelay(200); + write_nic_byte_E(dev,0x18,0x10); + write_nic_byte_E(dev,0x18,0x11); + write_nic_byte_E(dev,0x18,0x00); + mdelay(200); + } + + + cr=read_nic_byte(dev,CMD); + cr = cr & 2; + cr = cr | (1<card_8187) { + + //printk("This is RTL8187 Reset procedure\n"); + rtl8180_set_mode(dev,EPROM_CMD_LOAD); + force_pci_posting(dev); + mdelay(200); + + /* after the eeprom load cycle, make sure we have + * correct anaparams + */ + rtl8180_set_anaparam(dev, RTL8225_ANAPARAM_ON); + rtl8185_set_anaparam2(dev, RTL8225_ANAPARAM2_ON); + } + else { + //printk("This is RTL8187B Reset procedure\n"); + //test pending bug, john 20070815 + //initialize tx_pending + for(i=0;i<0x10;i++) atomic_set(&(priv->tx_pending[i]), 0); + + } + +} + +inline u16 ieeerate2rtlrate(int rate) +{ + switch(rate){ + case 10: + return 0; + case 20: + return 1; + case 55: + return 2; + case 110: + return 3; + case 60: + return 4; + case 90: + return 5; + case 120: + return 6; + case 180: + return 7; + case 240: + return 8; + case 360: + return 9; + case 480: + return 10; + case 540: + return 11; + default: + return 3; + + } +} +static u16 rtl_rate[] = {10,20,55,110,60,90,120,180,240,360,480,540,720}; +inline u16 rtl8180_rate2rate(short rate) +{ + if (rate >12) return 10; + return rtl_rate[rate]; +} + +void rtl8180_irq_rx_tasklet(struct r8180_priv *priv); +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20) +void rtl8187_rx_isr(struct urb *rx_urb, struct pt_regs *regs) +#else +void rtl8187_rx_isr(struct urb* rx_urb) +#endif +{ + struct net_device *dev = (struct net_device*)rx_urb->context; + struct r8180_priv *priv = ieee80211_priv(dev); + priv->rxurb_task = rx_urb; + + + //DMESGW("David: Rx tasklet start!"); + +#ifdef THOMAS_TASKLET + atomic_inc( &priv->irt_counter ); + + //if( likely(priv->irt_counter_head+1 != priv->irt_counter_tail) ){ + // priv->irt_counter_head = (priv->irt_counter_head+1)&0xffff ; + tasklet_schedule(&priv->irq_rx_tasklet); + //} else{ + //DMESG("error: priv->irt_counter_head is going to pass through priv->irt_counter_tail\n"); + /* + skb = priv->pp_rxskb[priv->rx_inx]; + dev_kfree_skb_any(skb); + + skb = dev_alloc_skb(RX_URB_SIZE); + if (skb == NULL) + panic("No Skb For RX!/n"); + + rx_urb->transfer_buffer = skb->data; + + priv->pp_rxskb[priv->rx_inx] = skb; + if(status == 0) + rtl8187_rx_urbsubmit(dev,rx_urb); + else { + priv->pp_rxskb[priv->rx_inx] = NULL; + dev_kfree_skb_any(skb); + printk("RX process aborted due to explicit shutdown (%x) ", status); + } + + if (*prx_inx == (MAX_RX_URB -1)) + *prx_inx = 0; + else + *prx_inx = *prx_inx + 1; + + */ + //} +#endif + +} + +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20) +void rtl8187_rx_manage_isr(struct urb *rx_urb, struct pt_regs *regs) +#else +void rtl8187_rx_manage_isr(struct urb* rx_urb) +#endif +{ + struct net_device *dev = (struct net_device*)rx_urb->context; + struct r8180_priv *priv = ieee80211_priv(dev); + int status,cmd; + struct sk_buff *skb; + u32 *desc; + int ret; + unsigned long flag; + + //DMESG("RX %d ",rx_urb->status); + status = rx_urb->status; + if(status == 0){ + + desc = (u32*)(rx_urb->transfer_buffer); + cmd = (desc[0] >> 30) & 0x03; + //printk(KERN_ALERT "buffersize = %d, length = %d, pipe = %p\n", + //rx_urb->transfer_buffer_length, rx_urb->actual_length, rx_urb->pipe>>15); + + if(cmd == 0x00) {//beacon interrupt + //send beacon packet + + spin_lock_irqsave(&priv->ieee80211->beaconflag_lock,flag); + if(priv->flag_beacon == true){ + //printk("rtl8187_rx_manage_isr(): CMD_TYPE0_BCN_INTR\n"); + + skb = ieee80211_get_beacon(priv->ieee80211); + if(!skb){ + DMESG("not enought memory for allocating beacon"); + return; + } + //printk(KERN_WARNING "to send beacon packet through beacon endpoint!\n"); + ret = rtl8180_tx(dev, (u32*)skb->data, skb->len, BEACON_PRIORITY, + 0, ieeerate2rtlrate(priv->ieee80211->basic_rate)); + + if( ret != 0 ){ + printk(KERN_ALERT "tx beacon packet error : %d !\n", ret); + } + dev_kfree_skb_any(skb); + + //} else {//0x00 + //{ log the device information + // At present, It is not implemented just now. + //} + //} + + } + spin_unlock_irqrestore(&priv->ieee80211->beaconflag_lock,flag); + } + else if(cmd == 0x01){ + //printk("rtl8187_rx_manage_isr(): CMD_TYPE1_TX_CLOSE\n"); + priv->CurrRetryCnt += (u16)desc[0]&0x000000ff; + //printk("priv->CurrRetryCnt is %d\n",priv->CurrRetryCnt); + } + else + printk("HalUsbInCommandComplete8187B(): unknown Type(%#X) !!!\n", cmd); + + }else{ + priv->stats.rxstaterr++; + priv->ieee80211->stats.rx_errors++; + } + + + if( status == 0 ) + //if(status != -ENOENT) + rtl8187_rx_manage_urbsubmit(dev, rx_urb); + else + ;//DMESG("Mangement RX process aborted due to explicit shutdown"); +} + +#if 0 +void rtl8180_tx_queues_stop(struct net_device *dev) +{ + //struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev); + u8 dma_poll_mask = (1<dma_poll_mask |= (1<dma_poll_mask); + rtl8180_set_mode(dev,EPROM_CMD_NORMAL); + #endif +} + + +void rtl8180_data_hard_resume(struct net_device *dev) +{ + // FIXME !! + #if 0 + struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev); + priv->dma_poll_mask &= ~(1<dma_poll_mask); + rtl8180_set_mode(dev,EPROM_CMD_NORMAL); + #endif +} + +unsigned int PRI2EP[4] = {0x06,0x07,0x05,0x04}; +// this function TX data frames when the ieee80211 stack requires this. +// It checks also if we need to stop the ieee tx queue, eventually do it +void rtl8180_hard_data_xmit(struct sk_buff *skb, struct net_device *dev, int rate) +{ + struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev); + + short morefrag = 0; + unsigned long flags; + struct ieee80211_hdr *h = (struct ieee80211_hdr *) skb->data; + + unsigned char ep; + short ret; //john + + if (le16_to_cpu(h->frame_ctl) & IEEE80211_FCTL_MOREFRAGS) + morefrag = 1; + //DMESG("%x %x", h->frame_ctl, h->seq_ctl); + /* + * This function doesn't require lock because we make + * sure it's called with the tx_lock already acquired. + * this come from the kernel's hard_xmit callback (trought + * the ieee stack, or from the try_wake_queue (again trought + * the ieee stack. + */ + spin_lock_irqsave(&priv->tx_lock,flags); + + //lzm mod 20081128 for sometimes wlan down but it still have some pkt to tx + if((priv->ieee80211->bHwRadioOff)||(!priv->up)) + { + spin_unlock_irqrestore(&priv->tx_lock,flags); + + return; + } + + if(NIC_8187B == priv->card_8187){ + ep = PRI2EP[skb->priority]; + } else { + ep = LOW_PRIORITY; + } + //if (!check_nic_enought_desc(dev, PRI2EP[skb->priority])){ + if (!check_nic_enought_desc(dev, ep)){ + DMESG("Error: no TX slot "); + ieee80211_stop_queue(priv->ieee80211); + } + +#ifdef LED_SHIN + priv->ieee80211->ieee80211_led_contorl(dev,LED_CTL_TX); +#endif + + ret = rtl8180_tx(dev, (u32*)skb->data, skb->len, ep, morefrag,ieeerate2rtlrate(rate)); + if(ret!=0) DMESG("Error: rtl8180_tx failed in rtl8180_hard_data_xmit\n");//john + + priv->stats.txdatapkt++; + + //if (!check_nic_enought_desc(dev, PRI2EP[skb->priority])){ + if (!check_nic_enought_desc(dev, ep)){ + ieee80211_stop_queue(priv->ieee80211); + } + + spin_unlock_irqrestore(&priv->tx_lock,flags); + +} + +//This is a rough attempt to TX a frame +//This is called by the ieee 80211 stack to TX management frames. +//If the ring is full packet are dropped (for data frame the queue +//is stopped before this can happen). + +int rtl8180_hard_start_xmit(struct sk_buff *skb,struct net_device *dev) +{ + struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev); + struct ieee80211_device *ieee = priv->ieee80211; + int ret; + unsigned long flags; + spin_lock_irqsave(&priv->tx_lock,flags); + + //lzm mod 20081128 for sometimes wlan down but it still have some pkt to tx + if((priv->ieee80211->bHwRadioOff)||(!priv->up)) + { + spin_unlock_irqrestore(&priv->tx_lock,flags); + return 0; + } + + ret = rtl8180_tx(dev, (u32*)skb->data, skb->len, MANAGE_PRIORITY, 0, ieeerate2rtlrate(ieee->basic_rate)); + + priv->ieee80211->stats.tx_bytes+=skb->len; + priv->ieee80211->stats.tx_packets++; + + spin_unlock_irqrestore(&priv->tx_lock,flags); + + return ret; +} + + +#if 0 +// longpre 144+48 shortpre 72+24 +u16 rtl8180_len2duration(u32 len, short rate,short* ext) +{ + u16 duration; + u16 drift; + *ext=0; + + switch(rate){ + case 0://1mbps + *ext=0; + duration = ((len+4)<<4) /0x2; + drift = ((len+4)<<4) % 0x2; + if(drift ==0 ) break; + duration++; + break; + + case 1://2mbps + *ext=0; + duration = ((len+4)<<4) /0x4; + drift = ((len+4)<<4) % 0x4; + if(drift ==0 ) break; + duration++; + break; + + case 2: //5.5mbps + *ext=0; + duration = ((len+4)<<4) /0xb; + drift = ((len+4)<<4) % 0xb; + if(drift ==0 ) + break; + duration++; + break; + + default: + case 3://11mbps + *ext=0; + duration = ((len+4)<<4) /0x16; + drift = ((len+4)<<4) % 0x16; + if(drift ==0 ) + break; + duration++; + if(drift > 6) + break; + *ext=1; + break; + } + + return duration; +} +#endif + +void rtl8180_try_wake_queue(struct net_device *dev, int pri); + +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20) +void rtl8187_lptx_isr(struct urb *tx_urb, struct pt_regs *regs) +#else +void rtl8187_lptx_isr(struct urb* tx_urb) +#endif +{ + struct net_device *dev = (struct net_device*)tx_urb->context; + struct r8180_priv *priv = ieee80211_priv(dev); + + if(tx_urb->status == 0){ + dev->trans_start = jiffies; //john + priv->stats.txlpokint++; + priv->txokbytestotal+=tx_urb->actual_length; + }else{ + priv->stats.txlperr++; + } + + kfree(tx_urb->transfer_buffer); + usb_free_urb(tx_urb); + + if(atomic_read(&priv->tx_pending[LOW_PRIORITY]) >= 1) + atomic_dec(&priv->tx_pending[LOW_PRIORITY]); + + rtl8180_try_wake_queue(dev,LOW_PRIORITY); +} + +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20) +void rtl8187_nptx_isr(struct urb *tx_urb, struct pt_regs *regs) +#else +void rtl8187_nptx_isr(struct urb* tx_urb) +#endif +{ + struct net_device *dev = (struct net_device*)tx_urb->context; + struct r8180_priv *priv = ieee80211_priv(dev); + + if(tx_urb->status == 0){ + dev->trans_start = jiffies; //john + priv->stats.txnpokint++; + }else{ + priv->stats.txnperr++; + } + + kfree(tx_urb->transfer_buffer); + usb_free_urb(tx_urb); + + if(atomic_read(&priv->tx_pending[NORM_PRIORITY]) >= 1) + atomic_dec(&priv->tx_pending[NORM_PRIORITY]); + //rtl8180_try_wake_queue(dev,NORM_PRIORITY); +} + +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20) +void rtl8187_votx_isr(struct urb *tx_urb, struct pt_regs *regs) +#else +void rtl8187_votx_isr(struct urb* tx_urb) +#endif +{ + struct net_device *dev = (struct net_device*)tx_urb->context; + struct r8180_priv *priv = ieee80211_priv(dev); + + if(tx_urb->status == 0){ + dev->trans_start = jiffies; //john + priv->stats.txvookint++; + priv->txokbytestotal+=tx_urb->actual_length; + }else{ + priv->stats.txvoerr++; + } + + kfree(tx_urb->transfer_buffer); + usb_free_urb(tx_urb); + + if(atomic_read(&priv->tx_pending[VO_PRIORITY]) >= 1) + atomic_dec(&priv->tx_pending[VO_PRIORITY]); + rtl8180_try_wake_queue(dev,VO_PRIORITY); +} + +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20) +void rtl8187_vitx_isr(struct urb *tx_urb, struct pt_regs *regs) +#else +void rtl8187_vitx_isr(struct urb* tx_urb) +#endif +{ + struct net_device *dev = (struct net_device*)tx_urb->context; + struct r8180_priv *priv = ieee80211_priv(dev); + + if(tx_urb->status == 0){ + dev->trans_start = jiffies; //john + priv->stats.txviokint++; + priv->txokbytestotal+=tx_urb->actual_length; + }else{ + priv->stats.txvierr++; + } + + kfree(tx_urb->transfer_buffer); + usb_free_urb(tx_urb); + + if(atomic_read(&priv->tx_pending[VI_PRIORITY]) >= 1) + atomic_dec(&priv->tx_pending[VI_PRIORITY]); + rtl8180_try_wake_queue(dev,VI_PRIORITY); +} + +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20) +void rtl8187_betx_isr(struct urb *tx_urb, struct pt_regs *regs) +#else +void rtl8187_betx_isr(struct urb* tx_urb) +#endif +{ + struct net_device *dev = (struct net_device*)tx_urb->context; + struct r8180_priv *priv = ieee80211_priv(dev); + + if(tx_urb->status == 0){ + dev->trans_start = jiffies; //john + priv->stats.txbeokint++; + priv->txokbytestotal+=tx_urb->actual_length; + }else{ + priv->stats.txbeerr++; + } + + kfree(tx_urb->transfer_buffer); + usb_free_urb(tx_urb); + + if(atomic_read(&priv->tx_pending[BE_PRIORITY]) >= 1) + atomic_dec(&priv->tx_pending[BE_PRIORITY]); + rtl8180_try_wake_queue(dev, BE_PRIORITY); +} + +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20) +void rtl8187_bktx_isr(struct urb *tx_urb, struct pt_regs *regs) +#else +void rtl8187_bktx_isr(struct urb* tx_urb) +#endif +{ + struct net_device *dev = (struct net_device*)tx_urb->context; + struct r8180_priv *priv = ieee80211_priv(dev); + + if(tx_urb->status == 0){ + dev->trans_start = jiffies; //john + priv->stats.txbkokint++; + }else{ + priv->stats.txbkerr++; + } + + kfree(tx_urb->transfer_buffer); + usb_free_urb(tx_urb); + + if(atomic_read(&priv->tx_pending[BK_PRIORITY]) >= 1) + atomic_dec(&priv->tx_pending[BK_PRIORITY]); + rtl8180_try_wake_queue(dev,BK_PRIORITY); +} + +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20) +void rtl8187_beacontx_isr(struct urb *tx_urb, struct pt_regs *regs) +#else +void rtl8187_beacontx_isr(struct urb* tx_urb) +#endif +{ + struct net_device *dev = (struct net_device*)tx_urb->context; + struct r8180_priv *priv = ieee80211_priv(dev); + + if(tx_urb->status == 0){ + dev->trans_start = jiffies; //john + priv->stats.txbeaconokint++; + priv->txokbytestotal+=tx_urb->actual_length; + }else{ + priv->stats.txbeaconerr++; + } + + kfree(tx_urb->transfer_buffer); + usb_free_urb(tx_urb); + + if(atomic_read(&priv->tx_pending[BEACON_PRIORITY]) >= 1) + atomic_dec(&priv->tx_pending[BEACON_PRIORITY]); + //rtl8180_try_wake_queue(dev,BEACON_PRIORITY); +} + +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20) +void rtl8187_managetx_isr(struct urb *tx_urb, struct pt_regs *regs) +#else +void rtl8187_managetx_isr(struct urb* tx_urb) +#endif +{ + struct net_device *dev = (struct net_device*)tx_urb->context; + struct r8180_priv *priv = ieee80211_priv(dev); + + if(tx_urb->status == 0){ + dev->trans_start = jiffies; //john + priv->stats.txmanageokint++; + priv->txokbytestotal+=tx_urb->actual_length; + }else{ + priv->stats.txmanageerr++; + } + + kfree(tx_urb->transfer_buffer); + usb_free_urb(tx_urb); + + if(atomic_read(&priv->tx_pending[MANAGE_PRIORITY]) >= 1) + atomic_dec(&priv->tx_pending[MANAGE_PRIORITY]); +// rtl8180_try_wake_queue(dev,MANAGE_PRIORITY); +} + +void rtl8187_beacon_stop(struct net_device *dev) +{ + u8 msr, msrm, msr2; + struct r8180_priv *priv = ieee80211_priv(dev); + unsigned long flag; + msr = read_nic_byte(dev, MSR); + msrm = msr & MSR_LINK_MASK; + msr2 = msr & ~MSR_LINK_MASK; + if(NIC_8187B == priv->card_8187) { + spin_lock_irqsave(&priv->ieee80211->beaconflag_lock,flag); + priv->flag_beacon = false; + spin_unlock_irqrestore(&priv->ieee80211->beaconflag_lock,flag); + } + if ((msrm == (MSR_LINK_ADHOC<ieee80211->current_network; + + + write_nic_dword(dev,BSSID,((u32*)net->bssid)[0]); + write_nic_word(dev,BSSID+4,((u16*)net->bssid)[2]); + + rtl8180_update_msr(dev); + + //rtl8180_set_mode(dev,EPROM_CMD_CONFIG); + write_nic_word(dev, AtimWnd, 2); + write_nic_word(dev, AtimtrItv, 100); + write_nic_word(dev, BEACON_INTERVAL, net->beacon_interval); + //write_nic_word(dev, BcnIntTime, 100); + write_nic_word(dev, BcnIntTime, 0x3FF); + + +} + +void rtl8187_beacon_tx(struct net_device *dev) +{ + struct r8180_priv *priv = ieee80211_priv(dev); + struct sk_buff *skb; + int i = 0; + u8 cr; + unsigned long flag; + rtl8187_net_update(dev); + + if(NIC_8187B == priv->card_8187) { + //Cause TSF timer of MAC reset to 0 + cr=read_nic_byte(dev,CMD); + cr = cr | (1<ieee80211->beaconflag_lock,flag); + priv->flag_beacon = true; + spin_unlock_irqrestore(&priv->ieee80211->beaconflag_lock,flag); + + //rtl8187_rx_manage_initiate(dev); + } else { + printk(KERN_WARNING "get the beacon!\n"); + skb = ieee80211_get_beacon(priv->ieee80211); + if(!skb){ + DMESG("not enought memory for allocating beacon"); + return; + } + + write_nic_byte(dev, BQREQ, read_nic_byte(dev, BQREQ) | (1<<7)); + + i=0; + //while(!read_nic_byte(dev,BQREQ & (1<<7))) + while( (read_nic_byte(dev, BQREQ) & (1<<7)) == 0 ) + { + msleep_interruptible_rtl(HZ/2); + if(i++ > 10){ + DMESGW("get stuck to wait HW beacon to be ready"); + return ; + } + } + //tx + rtl8180_tx(dev, (u32*)skb->data, skb->len, NORM_PRIORITY, + 0, ieeerate2rtlrate(priv->ieee80211->basic_rate)); + if(skb) + dev_kfree_skb_any(skb); + } +} + +#if 0 +void rtl8187_nptx_isr(struct urb *tx_urb, struct pt_regs *regs) +{ + struct net_device *dev = (struct net_device*)tx_urb->context; + struct r8180_priv *priv = ieee80211_priv(dev); + + if(tx_urb->status == 0) + priv->stats.txnpokint++; + else + priv->stats.txnperr++; + kfree(tx_urb->transfer_buffer); + usb_free_urb(tx_urb); + atomic_dec(&priv->tx_np_pending); + //rtl8180_try_wake_queue(dev,NORM_PRIORITY); +} +#endif +inline u8 rtl8180_IsWirelessBMode(u16 rate) +{ + if( ((rate <= 110) && (rate != 60) && (rate != 90)) || (rate == 220) ) + return 1; + else return 0; +} + +u16 N_DBPSOfRate(u16 DataRate); + +u16 ComputeTxTime( + u16 FrameLength, + u16 DataRate, + u8 bManagementFrame, + u8 bShortPreamble + ) +{ + u16 FrameTime; + u16 N_DBPS; + u16 Ceiling; + + if( rtl8180_IsWirelessBMode(DataRate) ) + { + if( bManagementFrame || !bShortPreamble || DataRate == 10 ){ // long preamble + FrameTime = (u16)(144+48+(FrameLength*8/(DataRate/10))); + }else{ // Short preamble + FrameTime = (u16)(72+24+(FrameLength*8/(DataRate/10))); + } + if( ( FrameLength*8 % (DataRate/10) ) != 0 ) //Get the Ceilling + FrameTime ++; + } else { //802.11g DSSS-OFDM PLCP length field calculation. + N_DBPS = N_DBPSOfRate(DataRate); + Ceiling = (16 + 8*FrameLength + 6) / N_DBPS + + (((16 + 8*FrameLength + 6) % N_DBPS) ? 1 : 0); + FrameTime = (u16)(16 + 4 + 4*Ceiling + 6); + } + return FrameTime; +} + +u16 N_DBPSOfRate(u16 DataRate) +{ + u16 N_DBPS = 24; + + switch(DataRate) + { + case 60: + N_DBPS = 24; + break; + + case 90: + N_DBPS = 36; + break; + + case 120: + N_DBPS = 48; + break; + + case 180: + N_DBPS = 72; + break; + + case 240: + N_DBPS = 96; + break; + + case 360: + N_DBPS = 144; + break; + + case 480: + N_DBPS = 192; + break; + + case 540: + N_DBPS = 216; + break; + + default: + break; + } + + return N_DBPS; +} +// NOte!!! +// the rate filled in is the rtl_rate. +// while the priv->ieee80211->basic_rate,used in the following code is ieee80211 rate. + +#ifdef JUST_FOR_87SEMESH +#define ActionHeadLen 30 +#endif +#define sCrcLng 4 +#define sAckCtsLng 112 // bits in ACK and CTS frames +short rtl8180_tx(struct net_device *dev, u32* txbuf, int len, priority_t priority, + short morefrag, short rate) +{ + u32 *tx; + int pend ; + int status; + struct urb *tx_urb; + int urb_len; + struct r8180_priv *priv = ieee80211_priv(dev); + struct ieee80211_hdr_3addr_QOS *frag_hdr = (struct ieee80211_hdr_3addr_QOS *)txbuf; + struct ieee80211_device *ieee;//added for descriptor + u8 dest[ETH_ALEN]; + + bool bUseShortPreamble = false; + bool bCTSEnable = false; + bool bRTSEnable = false; + u16 Duration = 0; + u16 RtsDur = 0; + u16 ThisFrameTime = 0; + u16 TxDescDuration = 0; + + ieee = priv->ieee80211; +#if 0 +//{added by david for filter the packet listed in the filter table +#ifdef _RTL8187_EXT_PATCH_ + if((ieee->iw_mode == ieee->iw_ext_mode) && (ieee->ext_patch_ieee80211_acl_query)) + { + if(!ieee->ext_patch_ieee80211_acl_query(ieee, frag_hdr->addr1)) { + return 0; + } + } +#endif +//} +#endif + +#ifdef JUST_FOR_87SEMESH +//#ifdef Lawrence_Mesh + u8* meshtype = (u8*)txbuf; + if(*meshtype == 0xA8) + { + //overflow?? + //memcpy(meshtype+ActionHeadLen+2,meshtype+ActionHeadLen,Len-ActionHeadLen); + //memcpy(meshtype+ActionHeadLen,0,2); + u8 actionframe[256]; + memset(actionframe,0,256); + memcpy(actionframe,meshtype,ActionHeadLen); + memcpy(actionframe+ActionHeadLen+2,meshtype+ActionHeadLen,len-ActionHeadLen); + txbuf = (u32*)actionframe; + len=len+2; + frag_hdr = (struct ieee80211_hdr_3addr_QOS *)txbuf; + } +#endif + + //pend = atomic_read((priority == NORM_PRIORITY)? &priv->tx_np_pending : &priv->tx_lp_pending); + pend = atomic_read(&priv->tx_pending[priority]); + /* we are locked here so the two atomic_read and inc are executed without interleaves */ + if( pend > MAX_TX_URB){ + if(NIC_8187 == priv->card_8187) { + if(priority == NORM_PRIORITY) + priv->stats.txnpdrop++; + else + priv->stats.txlpdrop++; + + } else { + switch (priority) { + case VO_PRIORITY: + priv->stats.txvodrop++; + break; + case VI_PRIORITY: + priv->stats.txvidrop++; + break; + case BE_PRIORITY: + priv->stats.txbedrop++; + break; + case MANAGE_PRIORITY: //lzm for MANAGE_PRIORITY pending + if(priv->commit == 0) + { + priv->commit = 1; + printk(KERN_INFO "manage pkt pending will commit now....\n"); +#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)) + schedule_work(&priv->reset_wq); +#else + schedule_task(&priv->reset_wq); +#endif + } + break; + default://BK_PRIORITY + priv->stats.txbkdrop++; + break; + } + } + //printk(KERN_INFO "tx_pending: %d > MAX_TX_URB\n", priority); + return -1; + } + + urb_len = len + ((NIC_8187 == priv->card_8187)?(4*3):(4*8)); + if((0 == (urb_len&63))||(0 == (urb_len&511))) { + urb_len += 1; + } + + tx = kmalloc(urb_len, GFP_ATOMIC); + if(!tx) return -ENOMEM; + memset(tx, 0, sizeof(u32) * 8); + +#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0) + tx_urb = usb_alloc_urb(0,GFP_ATOMIC); +#else + tx_urb = usb_alloc_urb(0); +#endif + + if(!tx_urb){ + kfree(tx); + return -ENOMEM; + } + + // Check multicast/broadcast + if (ieee->iw_mode == IW_MODE_INFRA) { + /* To DS: Addr1 = BSSID, Addr2 = SA, + Addr3 = DA */ + //memcpy(&dest, frag_hdr->addr3, ETH_ALEN); + memcpy(&dest, frag_hdr->addr1, ETH_ALEN); + } else if (ieee->iw_mode == IW_MODE_ADHOC) { + /* not From/To DS: Addr1 = DA, Addr2 = SA, + Addr3 = BSSID */ + memcpy(&dest, frag_hdr->addr1, ETH_ALEN); + } + + if (is_multicast_ether_addr(dest) ||is_broadcast_ether_addr(dest)) + { + Duration = 0; + RtsDur = 0; + bRTSEnable = false; + bCTSEnable = false; + + ThisFrameTime = ComputeTxTime(len + sCrcLng, rtl8180_rate2rate(rate), false, bUseShortPreamble); + TxDescDuration = ThisFrameTime; + } else {// Unicast packet + //u8 AckRate; + u16 AckTime; + + // Figure out ACK rate according to BSS basic rate and Tx rate, 2006.03.08 by rcnjko. + //AckRate = ComputeAckRate( pMgntInfo->mBrates, (u1Byte)(pTcb->DataRate) ); + // Figure out ACK time according to the AckRate and assume long preamble is used on receiver, 2006.03.08, by rcnjko. + //AckTime = ComputeTxTime( sAckCtsLng/8, AckRate, FALSE, FALSE); + //For simplicity, just use the 1M basic rate + AckTime = ComputeTxTime(14, 10,false, false); // AckCTSLng = 14 use 1M bps send + //AckTime = ComputeTxTime(14, 2,false, false); // AckCTSLng = 14 use 1M bps send + + if ( ((len + sCrcLng) > priv->rts) && priv->rts ){ // RTS/CTS. + u16 RtsTime, CtsTime; + //u16 CtsRate; + bRTSEnable = true; + bCTSEnable = false; + + // Rate and time required for RTS. + RtsTime = ComputeTxTime( sAckCtsLng/8,priv->ieee80211->basic_rate, false, false); + // Rate and time required for CTS. + CtsTime = ComputeTxTime(14, 10,false, false); // AckCTSLng = 14 use 1M bps send + + // Figure out time required to transmit this frame. + ThisFrameTime = ComputeTxTime(len + sCrcLng, + rtl8180_rate2rate(rate), + false, + bUseShortPreamble); + + // RTS-CTS-ThisFrame-ACK. + RtsDur = CtsTime + ThisFrameTime + AckTime + 3*aSifsTime; + + TxDescDuration = RtsTime + RtsDur; + }else {// Normal case. + bCTSEnable = false; + bRTSEnable = false; + RtsDur = 0; + + ThisFrameTime = ComputeTxTime(len + sCrcLng, rtl8180_rate2rate(rate), false, bUseShortPreamble); + TxDescDuration = ThisFrameTime + aSifsTime + AckTime; + } + + if(!(frag_hdr->frame_ctl & IEEE80211_FCTL_MOREFRAGS)) { //no more fragment + // ThisFrame-ACK. + Duration = aSifsTime + AckTime; + } else { // One or more fragments remained. + u16 NextFragTime; + NextFragTime = ComputeTxTime( len + sCrcLng, //pretend following packet length equal current packet + rtl8180_rate2rate(rate), + false, bUseShortPreamble ); + + //ThisFrag-ACk-NextFrag-ACK. + Duration = NextFragTime + 3*aSifsTime + 2*AckTime; + } + + } // End of Unicast packet + + + //fill the tx desriptor + tx[0] |= len & 0xfff; +#ifdef JOHN_HWSEC + if(frag_hdr->frame_ctl & IEEE80211_FCTL_WEP ){ + tx[0] &= 0xffff7fff; + //group key may be different from pairwise key + if( frag_hdr->addr1[0]==0xff && + frag_hdr->addr1[0]==0xff && + frag_hdr->addr1[0]==0xff && + frag_hdr->addr1[0]==0xff && + frag_hdr->addr1[0]==0xff && + frag_hdr->addr1[0]==0xff ){ + if(ieee->broadcast_key_type == KEY_TYPE_CCMP) tx[7] |= 0x2;//ccmp + else tx[7] |= 0x1;//wep and tkip + } + else { + if(ieee->pairwise_key_type == KEY_TYPE_CCMP) tx[7] |= 0x2;//CCMP + else tx[7] |= 0x1;//WEP and TKIP + } + } + else +#endif /*JOHN_HWSEC*/ + + tx[0] |= (1<<15); + + if (priv->ieee80211->current_network.capability&WLAN_CAPABILITY_SHORT_PREAMBLE){ + if (priv->plcp_preamble_mode==1 && rate!=0) { // short mode now, not long! + tx[0] |= (1<<16); + } // enable short preamble mode. + } + + if(morefrag) tx[0] |= (1<<17); + //printk(KERN_WARNING "rtl_rate = %d\n", rate); + tx[0] |= (rate << 24); //TX rate + frag_hdr->duration_id = Duration; + + if(NIC_8187B == priv->card_8187) { + if(bCTSEnable) { + tx[0] |= (1<<18); + } + + if(bRTSEnable) //rts enable + { + tx[0] |= ((ieeerate2rtlrate(priv->ieee80211->basic_rate))<<19);//RTS RATE + tx[0] |= (1<<23);//rts enable + tx[1] |= RtsDur;//RTS Duration + } + tx[3] |= (TxDescDuration<<16); //DURATION + if( WLAN_FC_GET_STYPE(le16_to_cpu(frag_hdr->frame_ctl)) == IEEE80211_STYPE_PROBE_RESP ) + tx[5] |= (1<<8);//(priv->retry_data<<8); //retry lim ; + else + tx[5] |= (11<<8);//(priv->retry_data<<8); //retry lim ; + + //frag_hdr->duration_id = Duration; + memcpy(tx+8,txbuf,len); + } else { + if ( (len>priv->rts) && priv->rts && priority==LOW_PRIORITY){ + tx[0] |= (1<<23); //enalbe RTS function + tx[1] |= RtsDur; //Need to edit here! ----hikaru + } + else { + tx[1]=0; + } + tx[0] |= (ieeerate2rtlrate(priv->ieee80211->basic_rate) << 19); /* RTS RATE - should be basic rate */ + + tx[2] = 3; // CW min + tx[2] |= (7<<4); //CW max + tx[2] |= (11<<8);//(priv->retry_data<<8); //retry lim + + // printk("%x\n%x\n",tx[0],tx[1]); + +#ifdef DUMP_TX + int i; + printk("--rate %x---",rate); + for (i = 0; i < (len + 3); i++) + printk("%2x", ((u8*)tx)[i]); + printk("---------------\n"); +#endif + memcpy(tx+3,txbuf,len); + } + +#ifdef JOHN_DUMP_TXDESC + int i; + printk("--rate %x---",rate); + for (i = 0; i < 8; i++) + printk("%8x ", tx[i]); + printk("\n"); +#endif +#ifdef JOHN_DUMP_TXPKT + { + int j; + printk("\n---------------------------------------------------------------------\n"); + printk("--rate %x--urb_len in decimal %d",rate, urb_len); + for (j = 32; j < (urb_len); j++){ + if( ( (j-32)%24 )==0 ) printk("\n"); + printk("%2x ", ((u8*)tx)[j]); + } + printk("\n---------------------------------------------------------------------\n"); + + } +#endif + + if(NIC_8187 == priv->card_8187) { + usb_fill_bulk_urb(tx_urb,priv->udev, + usb_sndbulkpipe(priv->udev,priority), tx, + urb_len, (priority == LOW_PRIORITY)?rtl8187_lptx_isr:rtl8187_nptx_isr, dev); + + } else { + //printk(KERN_WARNING "Tx packet use by submit urb!\n"); + /* FIXME check what EP is for low/norm PRI */ + usb_fill_bulk_urb(tx_urb,priv->udev, + usb_sndbulkpipe(priv->udev,priority), tx, + urb_len, TXISR_SELECT(priority), dev); + } + +#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0) + status = usb_submit_urb(tx_urb, GFP_ATOMIC); +#else + status = usb_submit_urb(tx_urb); +#endif + + if (!status){ + //atomic_inc((priority == NORM_PRIORITY)? &priv->tx_np_pending : &priv->tx_lp_pending); + atomic_inc(&priv->tx_pending[priority]); + dev->trans_start = jiffies; + //printk("=====> tx_pending[%d]=%d\n", priority, atomic_read(&priv->tx_pending[priority])); + return 0; + }else{ + DMESGE("Error TX URB %d, error pending %d", + //atomic_read((priority == NORM_PRIORITY)? &priv->tx_np_pending : &priv->tx_lp_pending), + atomic_read(&priv->tx_pending[priority]), + status); + return -1; + } +} + + short rtl8187_usb_initendpoints(struct net_device *dev) +{ + struct r8180_priv *priv = ieee80211_priv(dev); + + priv->rx_urb = (struct urb**) kmalloc (sizeof(struct urb*) * (MAX_RX_URB+1), GFP_KERNEL); + + memset(priv->rx_urb, 0, sizeof(struct urb*) * MAX_RX_URB); + +#ifdef JACKSON_NEW_RX + priv->pp_rxskb = (struct sk_buff **)kmalloc(sizeof(struct sk_buff *) * MAX_RX_URB, GFP_KERNEL); + if (priv->pp_rxskb == NULL) + goto destroy; + + memset(priv->pp_rxskb, 0, sizeof(struct sk_buff*) * MAX_RX_URB); +#endif +#ifdef THOMAS_BEACON + { + int align; + unsigned long oldaddr,newaddr; //lzm mod for 64bit cpu crash 20081107 + priv->rx_urb[MAX_RX_URB] = usb_alloc_urb(0, GFP_KERNEL); + priv->oldaddr = kmalloc(16, GFP_KERNEL); + oldaddr = (unsigned long)priv->oldaddr; + align = oldaddr&3; + if(align != 0 ){ + newaddr = oldaddr + 4 - align; + priv->rx_urb[MAX_RX_URB]->transfer_buffer_length = 16-4+align; + } + else{ + newaddr = oldaddr; + priv->rx_urb[MAX_RX_URB]->transfer_buffer_length = 16; + } + priv->rx_urb[MAX_RX_URB]->transfer_buffer = (u32*)newaddr; + } +#endif + + + goto _middle; + + +destroy: + +#ifdef JACKSON_NEW_RX + if (priv->pp_rxskb) { + kfree(priv->pp_rxskb); + priv->pp_rxskb = NULL; + + } +#endif + if (priv->rx_urb) { + kfree(priv->rx_urb); + } + priv->rx_urb = NULL; + + DMESGE("Endpoint Alloc Failure"); + return -ENOMEM; + + +_middle: + + return 0; + +} +#ifdef THOMAS_BEACON +void rtl8187_usb_deleteendpoints(struct net_device *dev) +{ + int i; + struct r8180_priv *priv = ieee80211_priv(dev); + + if( in_interrupt() ) + printk(KERN_ALERT " %ld in interrupt \n",in_interrupt() ); + if(priv->rx_urb){ + for(i=0;i<(MAX_RX_URB+1);i++){ + if(priv->rx_urb[i]) { + usb_kill_urb(priv->rx_urb[i]); + usb_free_urb(priv->rx_urb[i]); + } + } + kfree(priv->rx_urb); + priv->rx_urb = NULL; + } + if(priv->oldaddr){ + kfree(priv->oldaddr); + priv->oldaddr = NULL; + } + if (priv->pp_rxskb) { + kfree(priv->pp_rxskb); + priv->pp_rxskb = 0; + } +} +#endif + +void rtl8187_set_rate(struct net_device *dev) +{ + int i; + u16 word; + int basic_rate,min_rr_rate,max_rr_rate; + + //if (ieee80211_is_54g(priv->ieee80211->current_network) && + // priv->ieee80211->state == IEEE80211_LINKED){ + basic_rate = ieeerate2rtlrate(240); + min_rr_rate = ieeerate2rtlrate(60); + max_rr_rate = ieeerate2rtlrate(240); + + /* + }else{ + basic_rate = ieeerate2rtlrate(20); + min_rr_rate = ieeerate2rtlrate(10); + max_rr_rate = ieeerate2rtlrate(110); + } + */ + + write_nic_byte(dev, RESP_RATE, + max_rr_rate<beacon_interval); + rtl8187_net_update(dev); + /*update timing params*/ + rtl8180_set_chan(dev, priv->chan); + rtl8187_set_rxconf(dev); +} + +#if LINUX_VERSION_CODE >=KERNEL_VERSION(2,6,20) +void rtl8180_wmm_param_update(struct work_struct* work) +{ + struct ieee80211_device * ieee = container_of(work, struct ieee80211_device,wmm_param_update_wq); + struct net_device *dev = ieee->dev; + struct r8180_priv *priv = ieee80211_priv(dev); +#else +void rtl8180_wmm_param_update(struct ieee80211_device *ieee) +{ + struct net_device *dev = ieee->dev; + struct r8180_priv *priv = ieee80211_priv(dev); +#endif + u8 *ac_param = (u8 *)(ieee->current_network.wmm_param); + u8 mode = ieee->current_network.mode; + AC_CODING eACI; + AC_PARAM AcParam; + PAC_PARAM pAcParam; + u8 i; + + //8187 need not to update wmm param, added by David, 2006.9.8 + if(NIC_8187 == priv->card_8187) { + return; + } + + if(!ieee->current_network.QoS_Enable) + { + //legacy ac_xx_param update + + AcParam.longData = 0; + AcParam.f.AciAifsn.f.AIFSN = 2; // Follow 802.11 DIFS. + AcParam.f.AciAifsn.f.ACM = 0; + AcParam.f.Ecw.f.ECWmin = 3; // Follow 802.11 CWmin. + AcParam.f.Ecw.f.ECWmax = 7; // Follow 802.11 CWmax. + AcParam.f.TXOPLimit = 0; + for(eACI = 0; eACI < AC_MAX; eACI++) + { + AcParam.f.AciAifsn.f.ACI = (u8)eACI; + { + u8 u1bAIFS; + u32 u4bAcParam; + + + pAcParam = (PAC_PARAM)(&AcParam); + // Retrive paramters to udpate. + u1bAIFS = pAcParam->f.AciAifsn.f.AIFSN *(((mode&IEEE_G) == IEEE_G)?9:20) + aSifsTime; + u4bAcParam = ((((u32)(pAcParam->f.TXOPLimit)) << AC_PARAM_TXOP_LIMIT_OFFSET) | + (((u32)(pAcParam->f.Ecw.f.ECWmax)) << AC_PARAM_ECW_MAX_OFFSET) | + (((u32)(pAcParam->f.Ecw.f.ECWmin)) << AC_PARAM_ECW_MIN_OFFSET) | + (((u32)u1bAIFS) << AC_PARAM_AIFS_OFFSET)); + + switch(eACI) + { + case AC1_BK: + write_nic_dword(dev, AC_BK_PARAM, u4bAcParam); + break; + + case AC0_BE: + write_nic_dword(dev, AC_BE_PARAM, u4bAcParam); + break; + + case AC2_VI: + write_nic_dword(dev, AC_VI_PARAM, u4bAcParam); + break; + + case AC3_VO: + write_nic_dword(dev, AC_VO_PARAM, u4bAcParam); + break; + + default: + printk(KERN_WARNING "SetHwReg8185(): invalid ACI: %d !\n", eACI); + break; + } + } + } + + return; + } + // + for(i = 0; i < AC_MAX; i++){ + pAcParam = (AC_PARAM * )ac_param; + { + AC_CODING eACI; + u8 u1bAIFS; + u32 u4bAcParam; + + // Retrive paramters to udpate. + eACI = pAcParam->f.AciAifsn.f.ACI; + //Mode G/A: slotTimeTimer = 9; Mode B: 20 + u1bAIFS = pAcParam->f.AciAifsn.f.AIFSN * (((mode&IEEE_G) == IEEE_G)?9:20) + aSifsTime; + u4bAcParam = ((((u32)(pAcParam->f.TXOPLimit)) << AC_PARAM_TXOP_LIMIT_OFFSET) | + (((u32)(pAcParam->f.Ecw.f.ECWmax)) << AC_PARAM_ECW_MAX_OFFSET) | + (((u32)(pAcParam->f.Ecw.f.ECWmin)) << AC_PARAM_ECW_MIN_OFFSET) | + (((u32)u1bAIFS) << AC_PARAM_AIFS_OFFSET)); + + switch(eACI) + { + case AC1_BK: + write_nic_dword(dev, AC_BK_PARAM, u4bAcParam); + //printk(KERN_WARNING "[%04x]:0x%08x\n",AC_BK_PARAM,read_nic_dword(dev, AC_BK_PARAM)); + break; + + case AC0_BE: + write_nic_dword(dev, AC_BE_PARAM, u4bAcParam); + //printk(KERN_WARNING "[%04x]:0x%08x\n",AC_BE_PARAM,read_nic_dword(dev, AC_BE_PARAM)); + break; + + case AC2_VI: + write_nic_dword(dev, AC_VI_PARAM, u4bAcParam); + //printk(KERN_WARNING "[%04x]:0x%08x\n",AC_VI_PARAM,read_nic_dword(dev, AC_VI_PARAM)); + break; + + case AC3_VO: + write_nic_dword(dev, AC_VO_PARAM, u4bAcParam); + //printk(KERN_WARNING "[%04x]:0x%08x\n",AC_VO_PARAM,read_nic_dword(dev, AC_VO_PARAM)); + break; + + default: + printk(KERN_WARNING "SetHwReg8185(): invalid ACI: %d !\n", eACI); + break; + } + } + ac_param += (sizeof(AC_PARAM)); + } +} + +int IncludedInSupportedRates(struct r8180_priv *priv, u8 TxRate ) +{ + u8 rate_len; + u8 rate_ex_len; + u8 RateMask = 0x7F; + u8 idx; + unsigned short Found = 0; + u8 NaiveTxRate = TxRate&RateMask; + + rate_len = priv->ieee80211->current_network.rates_len; + rate_ex_len = priv->ieee80211->current_network.rates_ex_len; + + for( idx=0; idx< rate_len; idx++ ){ + if( (priv->ieee80211->current_network.rates[idx] & RateMask) == NaiveTxRate ) { + Found = 1; + goto found_rate; + } + } + + for( idx=0; idx< rate_ex_len; idx++ ) { + if( (priv->ieee80211->current_network.rates_ex[idx] & RateMask) == NaiveTxRate ) { + Found = 1; + goto found_rate; + } + } + + return Found; + found_rate: + return Found; +} +// +// Description: +// Get the Tx rate one degree up form the input rate in the supported rates. +// Return the upgrade rate if it is successed, otherwise return the input rate. +// By Bruce, 2007-06-05. +// +u8 GetUpgradeTxRate(struct net_device *dev, u8 rate) +{ + struct r8180_priv *priv = ieee80211_priv(dev); + u8 UpRate; + + // Upgrade 1 degree. + switch(rate) + { + case 108: // Up to 54Mbps. + UpRate = 108; + break; + + case 96: // Up to 54Mbps. + UpRate = 108; + break; + + case 72: // Up to 48Mbps. + UpRate = 96; + break; + + case 48: // Up to 36Mbps. + UpRate = 72; + break; + + case 36: // Up to 24Mbps. + UpRate = 48; + break; + + case 22: // Up to 18Mbps. + UpRate = 36; + break; + + case 11: // Up to 11Mbps. + UpRate = 22; + break; + + case 4: // Up to 5.5Mbps. + UpRate = 11; + break; + + case 2: // Up to 2Mbps. + UpRate = 4; + break; + + default: + printk("GetUpgradeTxRate(): Input Tx Rate(%d) is undefined!\n", rate); + return rate; + } + // Check if the rate is valid. + if(IncludedInSupportedRates(priv, UpRate)) + { +// printk("GetUpgradeTxRate(): GetUpgrade Tx rate(%d) from %d !\n", UpRate, priv->CurrentOperaRate); + return UpRate; + } + else + { + printk("GetUpgradeTxRate(): Tx rate (%d) is not in supported rates\n", UpRate); + return rate; + } + return rate; +} +// +// Description: +// Get the Tx rate one degree down form the input rate in the supported rates. +// Return the degrade rate if it is successed, otherwise return the input rate. +// By Bruce, 2007-06-05. +// +u8 GetDegradeTxRate( struct net_device *dev, u8 rate) +{ + struct r8180_priv *priv = ieee80211_priv(dev); + u8 DownRate; + + // Upgrade 1 degree. + switch(rate) + { + case 108: // Down to 48Mbps. + DownRate = 96; + break; + + case 96: // Down to 36Mbps. + DownRate = 72; + break; + + case 72: // Down to 24Mbps. + DownRate = 48; + break; + + case 48: // Down to 18Mbps. + DownRate = 36; + break; + + case 36: // Down to 11Mbps. + DownRate = 22; + break; + + case 22: // Down to 5.5Mbps. + DownRate = 11; + break; + + case 11: // Down to 2Mbps. + DownRate = 4; + break; + + case 4: // Down to 1Mbps. + DownRate = 2; + break; + + case 2: // Down to 1Mbps. + DownRate = 2; + break; + + default: + printk("GetDegradeTxRate(): Input Tx Rate(%d) is undefined!\n", rate); + return rate; + } + // Check if the rate is valid. + if(IncludedInSupportedRates(priv, DownRate)){ +// printk("GetDegradeTxRate(): GetDegrade Tx rate(%d) from %d!\n", DownRate, priv->CurrentOperaRate); + return DownRate; + }else{ + printk("GetDegradeTxRate(): Tx rate (%d) is not in supported rates\n", DownRate); + return rate; + } + return rate; +} + +// +// Helper function to determine if specified data rate is +// CCK rate. +// 2005.01.25, by rcnjko. +// +bool MgntIsCckRate(u16 rate ) +{ + bool bReturn = false; + + if((rate <= 22) && (rate != 12) && (rate != 18)){ + bReturn = true; + } + + return bReturn; +} +//by amy for rate adaptive +// +// Description: +// Core logic to adjust Tx data rate in STA mode according to +// OFDM retry count ratio. +// +// Note: +// RTL8187 : pHalData->CurrRetryCnt = TallyCnt +// RTL8187B : pHalData->CurrRetryCnt = PktRetryCnt in TxClosedCommand +// +void sta_rateadaptive8187B(struct net_device *dev) +{ + struct r8180_priv *priv = ieee80211_priv(dev); + unsigned long CurrTxokCnt; + u16 CurrRetryCnt; + u16 CurrRetryRate; + unsigned long CurrRxokCnt; + bool bTryUp = false; + bool bTryDown = false; + u8 TryUpTh = 1; + u8 TryDownTh = 2; + u32 TxThroughput; + long CurrSignalStrength; + bool bUpdateInitialGain = false; + CurrRetryCnt = priv->CurrRetryCnt; + CurrTxokCnt = (priv->stats.txbeaconokint + priv->stats.txmanageokint + + priv->stats.txvookint + priv->stats.txviokint + priv->stats.txbeokint)- priv->LastTxokCnt; + CurrRxokCnt = priv->stats.rxok - priv->LastRxokCnt; + CurrSignalStrength = priv->RecvSignalPower; + TxThroughput = (u32)(priv->txokbytestotal - priv->LastTxOKBytes); + priv->LastTxOKBytes = priv->txokbytestotal; + priv->CurrentOperaRate = priv->ieee80211->rate / 5; + //printk("priv->CurrentOperaRate is %d\n",priv->CurrentOperaRate); + +#if 1 + //2 Compute retry ratio. + if (CurrTxokCnt>0) + { + CurrRetryRate = (u16)(CurrRetryCnt*100/CurrTxokCnt); + } + else + { // It may be serious retry. To distinguish serious retry or no packets modified by Bruce + CurrRetryRate = (u16)(CurrRetryCnt*100/1); + } +#endif + + + //printk("\n(1) priv->LastRetryRate: %d \n",priv->LastRetryRate); + //printk("(2) CurrRetryCnt = %d \n", CurrRetryCnt); + //printk("(3) TxokCnt = %d \n", CurrTxokCnt); + //printk("(4) CurrRetryRate = %d \n", CurrRetryRate); + //printk("(5) SignalStrength = %d \n",priv->RecvSignalPower); + + priv->LastRetryCnt = priv->CurrRetryCnt; + priv->LastTxokCnt = (priv->stats.txbeaconokint + priv->stats.txmanageokint + + priv->stats.txvookint + priv->stats.txviokint + priv->stats.txbeokint); + priv->LastRxokCnt = priv->stats.rxok; + priv->CurrRetryCnt = 0; + //2No Tx packets, return to init_rate or not? + if (CurrRetryRate==0 && CurrTxokCnt == 0) + { + // + // 2007.04.09, by Roger. after 4.5 seconds in this condition, we try to raise rate. + // + priv->TryupingCountNoData++; + + //printk("No Tx packets, TryupingCountNoData(%d)\n", priv->TryupingCountNoData); + //printk("(6) priv->CurrentOperaRate =%d\n", priv->CurrentOperaRate); + + if (priv->TryupingCountNoData>15) + { + priv->TryupingCountNoData = 0; + priv->CurrentOperaRate = GetUpgradeTxRate(dev, priv->CurrentOperaRate); + // Reset Fail Record + priv->LastFailTxRate = 0; + priv->LastFailTxRateSS = -200; + priv->FailTxRateCount = 0; + } + goto SetInitialGain; + } + else + { + priv->TryupingCountNoData=0; //Reset trying up times. + } + + // + // For Netgear case, I comment out the following signal strength estimation, + // which can results in lower rate to transmit when sample is NOT enough (e.g. PING request). + // 2007.04.09, by Roger. + // +#if 1 + // If sample is not enough, we use signalstrength. + if ( CurrTxokCnt<10|| CurrRetryCnt<10) + { + //printk("Sample is not enough, we use signalstrength for rate adaptive\n"); + //After 3 sec, and trying up. + priv->TryupingCountNoData++; + if (priv->TryupingCountNoData>10) + { + //printk("Sample is not enough and After 3 sec try up\n"); + priv->TryupingCountNoData=0; + + // + // Added by Roger, 2007.01.04. + // Signal strength plus 3 for air link. + // + + if ( CurrSignalStrength>-68 )//&& IncludedInSupportedRates(Adapter, 108) ) + { + priv->ieee80211->rate = 540; + //pMgntInfo->CurrentOperaRate = 108; + } + else if (CurrSignalStrength>-70)// && IncludedInSupportedRates(Adapter, 96) ) + { + priv->ieee80211->rate = 480; + //pMgntInfo->CurrentOperaRate = 96; + } + else if (CurrSignalStrength>-73)// && IncludedInSupportedRates(Adapter, 72) ) + { + priv->ieee80211->rate = 360; + //pMgntInfo->CurrentOperaRate = 72; + } + else if (CurrSignalStrength>-79)// && IncludedInSupportedRates(Adapter, 48) ) + { + priv->ieee80211->rate = 240; + //pMgntInfo->CurrentOperaRate = 48; + } + else if (CurrSignalStrength>-81)// && IncludedInSupportedRates(Adapter, 36) ) + { + priv->ieee80211->rate = 180; + //pMgntInfo->CurrentOperaRate = 36; + } + else if (CurrSignalStrength>-83)// && IncludedInSupportedRates(Adapter, 22) ) + { + priv->ieee80211->rate = 110; + //pMgntInfo->CurrentOperaRate = 22; + } + else if (CurrSignalStrength>-85)// && IncludedInSupportedRates(Adapter, 11) ) + { + priv->ieee80211->rate = 55; + //pMgntInfo->CurrentOperaRate = 11; + } + else if (CurrSignalStrength>-89)// && IncludedInSupportedRates(Adapter, 4) ) + { + priv->ieee80211->rate = 20; + //pMgntInfo->CurrentOperaRate = 4; + } + + + } + + //2004.12.23 skip record for 0 + //pHalData->LastRetryRate = CurrRetryRate; + //printk("pMgntInfo->CurrentOperaRate =%d\n",priv->ieee80211->rate); + return; + } + else + { + priv->TryupingCountNoData=0; + } +#endif + // + // Restructure rate adaptive as the following main stages: + // (1) Add retry threshold in 54M upgrading condition with signal strength. + // (2) Add the mechanism to degrade to CCK rate according to signal strength + // and retry rate. + // (3) Remove all Initial Gain Updates over OFDM rate. To avoid the complicated + // situation, Initial Gain Update is upon on DIG mechanism except CCK rate. + // (4) Add the mehanism of trying to upgrade tx rate. + // (5) Record the information of upping tx rate to avoid trying upping tx rate constantly. + // By Bruce, 2007-06-05. + // + // + + // 11Mbps or 36Mbps + // Check more times in these rate(key rates). + // + if(priv->CurrentOperaRate == 22 || priv->CurrentOperaRate == 72) + { + TryUpTh += 9; + } + // + // Let these rates down more difficult. + // + if(MgntIsCckRate(priv->CurrentOperaRate) || priv->CurrentOperaRate == 36) + { + TryDownTh += 1; + } + + //1 Adjust Rate. + if (priv->bTryuping == true) + { + //2 For Test Upgrading mechanism + // Note: + // Sometimes the throughput is upon on the capability bwtween the AP and NIC, + // thus the low data rate does not improve the performance. + // We randomly upgrade the data rate and check if the retry rate is improved. + + // Upgrading rate did not improve the retry rate, fallback to the original rate. + if ( (CurrRetryRate > 25) && TxThroughput < priv->LastTxThroughput) + { + //Not necessary raising rate, fall back rate. + bTryDown = true; + //printk("Not necessary raising rate, fall back rate....\n"); + //printk("(7) priv->CurrentOperaRate =%d, TxThroughput = %d, LastThroughput = %d\n", + // priv->CurrentOperaRate, TxThroughput, priv->LastTxThroughput); + } + else + { + priv->bTryuping = false; + } + } + else if (CurrSignalStrength > -51 && (CurrRetryRate < 100)) + { + //2For High Power + // + // Added by Roger, 2007.04.09. + // Return to highest data rate, if signal strength is good enough. + // SignalStrength threshold(-50dbm) is for RTL8186. + // Revise SignalStrength threshold to -51dbm. + // + // Also need to check retry rate for safety, by Bruce, 2007-06-05. + if(priv->CurrentOperaRate != 108) + { + bTryUp = true; + // Upgrade Tx Rate directly. + priv->TryupingCount += TryUpTh; + //printk("StaRateAdaptive87B: Power(%d) is high enough!!. \n", CurrSignalStrength); + } + } + // To avoid unstable rate jumping, comment out this condition, by Bruce, 2007-06-26. + /* + else if(CurrSignalStrength < -86 && CurrRetryRate >= 100) + { + //2 For Low Power + // + // Low signal strength and high current tx rate may cause Tx rate to degrade too slowly. + // Update Tx rate to CCK rate directly. + // By Bruce, 2007-06-05. + // + if(!MgntIsCckRate(pMgntInfo->CurrentOperaRate)) + { + if(CurrSignalStrength > -88 && IncludedInSupportedRates(Adapter, 22)) // 11M + pMgntInfo->CurrentOperaRate = 22; + else if(CurrSignalStrength > -90 && IncludedInSupportedRates(Adapter, 11)) // 5.5M + pMgntInfo->CurrentOperaRate = 11; + else if(CurrSignalStrength > -92 && IncludedInSupportedRates(Adapter, 4)) // 2M + pMgntInfo->CurrentOperaRate = 4; + else // 1M + pMgntInfo->CurrentOperaRate = 2; + } + else if(CurrRetryRate >= 200) + { + pMgntInfo->CurrentOperaRate = GetDegradeTxRate(Adapter, pMgntInfo->CurrentOperaRate); + } + RT_TRACE(COMP_RATE, DBG_LOUD, ("RA: Low Power(%d), or High Retry Rate(%d), set rate to CCK rate (%d). \n", + CurrSignalStrength, CurrRetryRate, pMgntInfo->CurrentOperaRate)); + bUpdateInitialGain = TRUE; + // Reset Fail Record + pHalData->LastFailTxRate = 0; + pHalData->LastFailTxRateSS = -200; + pHalData->FailTxRateCount = 0; + goto SetInitialGain; + } + */ + else if(CurrTxokCnt< 100 && CurrRetryRate >= 600) + { + //2 For Serious Retry + // + // Traffic is not busy but our Tx retry is serious. + // + bTryDown = true; + // Let Rate Mechanism to degrade tx rate directly. + priv->TryDownCountLowData += TryDownTh; + //printk("RA: Tx Retry is serious. Degrade Tx Rate to %d directly...\n", priv->CurrentOperaRate); + } + else if ( priv->CurrentOperaRate == 108 ) + { + //2For 54Mbps + // if ( (CurrRetryRate>38)&&(pHalData->LastRetryRate>35)) + if ( (CurrRetryRate>33)&&(priv->LastRetryRate>32)) + { + //(30,25) for cable link threshold. (38,35) for air link. + //Down to rate 48Mbps. + bTryDown = true; + } + } + else if ( priv->CurrentOperaRate == 96 ) + { + //2For 48Mbps + // if ( ((CurrRetryRate>73) && (pHalData->LastRetryRate>72)) && IncludedInSupportedRates(Adapter, 72) ) + if ( ((CurrRetryRate>48) && (priv->LastRetryRate>47))) + { + //(73, 72) for temp used. + //(25, 23) for cable link, (60,59) for air link. + //CurrRetryRate plus 25 and 26 respectively for air link. + //Down to rate 36Mbps. + bTryDown = true; + } + else if ( (CurrRetryRate<8) && (priv->LastRetryRate<8) ) //TO DO: need to consider (RSSI) + { + bTryUp = true; + } + } + else if ( priv->CurrentOperaRate == 72 ) + { + //2For 36Mbps + //if ( (CurrRetryRate>97) && (pHalData->LastRetryRate>97)) + if ( (CurrRetryRate>55) && (priv->LastRetryRate>54)) + { + //(30,25) for cable link threshold respectively. (103,10) for air link respectively. + //CurrRetryRate plus 65 and 69 respectively for air link threshold. + //Down to rate 24Mbps. + bTryDown = true; + } + // else if ( (CurrRetryRate<20) && (pHalData->LastRetryRate<20) && IncludedInSupportedRates(Adapter, 96) )//&& (device->LastRetryRate<15) ) //TO DO: need to consider (RSSI) + else if ( (CurrRetryRate<15) && (priv->LastRetryRate<16))//&& (device->LastRetryRate<15) ) //TO DO: need to consider (RSSI) + { + bTryUp = true; + } + } + else if ( priv->CurrentOperaRate == 48 ) + { + //2For 24Mbps + // if ( ((CurrRetryRate>119) && (pHalData->LastRetryRate>119) && IncludedInSupportedRates(Adapter, 36))) + if ( ((CurrRetryRate>63) && (priv->LastRetryRate>62))) + { + //(15,15) for cable link threshold respectively. (119, 119) for air link threshold. + //Plus 84 for air link threshold. + //Down to rate 18Mbps. + bTryDown = true; + } + // else if ( (CurrRetryRate<14) && (pHalData->LastRetryRate<15) && IncludedInSupportedRates(Adapter, 72)) //TO DO: need to consider (RSSI) + else if ( (CurrRetryRate<20) && (priv->LastRetryRate<21)) //TO DO: need to consider (RSSI) + { + bTryUp = true; + } + } + else if ( priv->CurrentOperaRate == 36 ) + { + //2For 18Mbps + if ( ((CurrRetryRate>109) && (priv->LastRetryRate>109))) + { + //(99,99) for cable link, (109,109) for air link. + //Down to rate 11Mbps. + bTryDown = true; + } + // else if ( (CurrRetryRate<15) && (pHalData->LastRetryRate<16) && IncludedInSupportedRates(Adapter, 48)) //TO DO: need to consider (RSSI) + else if ( (CurrRetryRate<25) && (priv->LastRetryRate<26)) //TO DO: need to consider (RSSI) + { + bTryUp = true; + } + } + else if ( priv->CurrentOperaRate == 22 ) + { + //2For 11Mbps + // if (CurrRetryRate>299 && IncludedInSupportedRates(Adapter, 11)) + if (CurrRetryRate>95) + { + bTryDown = true; + } + else if (CurrRetryRate<55)//&& (device->LastRetryRate<55) ) //TO DO: need to consider (RSSI) + { + bTryUp = true; + } + } + else if ( priv->CurrentOperaRate == 11 ) + { + //2For 5.5Mbps + // if (CurrRetryRate>159 && IncludedInSupportedRates(Adapter, 4) ) + if (CurrRetryRate>149) + { + bTryDown = true; + } + // else if ( (CurrRetryRate<30) && (pHalData->LastRetryRate<30) && IncludedInSupportedRates(Adapter, 22) ) + else if ( (CurrRetryRate<60) && (priv->LastRetryRate < 65)) + { + bTryUp = true; + } + } + else if ( priv->CurrentOperaRate == 4 ) + { + //2For 2 Mbps + if((CurrRetryRate>99) && (priv->LastRetryRate>99)) + { + bTryDown = true; + } + // else if ( (CurrRetryRate<50) && (pHalData->LastRetryRate<65) && IncludedInSupportedRates(Adapter, 11) ) + else if ( (CurrRetryRate < 65) && (priv->LastRetryRate < 70)) + { + bTryUp = true; + } + } + else if ( priv->CurrentOperaRate == 2 ) + { + //2For 1 Mbps + // if ( (CurrRetryRate<50) && (pHalData->LastRetryRate<65) && IncludedInSupportedRates(Adapter, 4)) + if ( (CurrRetryRate<70) && (priv->LastRetryRate<75)) + { + bTryUp = true; + } + } + if(bTryUp && bTryDown) + printk("StaRateAdaptive87B(): Tx Rate tried upping and downing simultaneously!\n"); + + //1 Test Upgrading Tx Rate + // Sometimes the cause of the low throughput (high retry rate) is the compatibility between the AP and NIC. + // To test if the upper rate may cause lower retry rate, this mechanism randomly occurs to test upgrading tx rate. + if(!bTryUp && !bTryDown && (priv->TryupingCount == 0) && (priv->TryDownCountLowData == 0) + && priv->CurrentOperaRate != 108 && priv->FailTxRateCount < 2) + { +#if 1 + if(jiffies% (CurrRetryRate + 101) == 0) + { + bTryUp = true; + priv->bTryuping = true; + printk("======================================================>StaRateAdaptive87B(): Randomly try upgrading...\n"); + } +#endif + } + //1 Rate Mechanism + if(bTryUp) + { + priv->TryupingCount++; + priv->TryDownCountLowData = 0; + + // + // Check more times if we need to upgrade indeed. + // Because the largest value of pHalData->TryupingCount is 0xFFFF and + // the largest value of pHalData->FailTxRateCount is 0x14, + // this condition will be satisfied at most every 2 min. + // + if((priv->TryupingCount > (TryUpTh + priv->FailTxRateCount * priv->FailTxRateCount)) || + (CurrSignalStrength > priv->LastFailTxRateSS) || priv->bTryuping) + { + priv->TryupingCount = 0; + // + // When transfering from CCK to OFDM, DIG is an important issue. + // + if(priv->CurrentOperaRate == 22) + bUpdateInitialGain = true; + // (1)To avoid upgrade frequently to the fail tx rate, add the FailTxRateCount into the threshold. + // (2)If the signal strength is increased, it may be able to upgrade. + priv->CurrentOperaRate = GetUpgradeTxRate(dev, priv->CurrentOperaRate); + //printk("StaRateAdaptive87B(): Upgrade Tx Rate to %d\n", priv->CurrentOperaRate); + + // Update Fail Tx rate and count. + if(priv->LastFailTxRate != priv->CurrentOperaRate) + { + priv->LastFailTxRate = priv->CurrentOperaRate; + priv->FailTxRateCount = 0; + priv->LastFailTxRateSS = -200; // Set lowest power. + } + } + } + else + { + if(priv->TryupingCount > 0) + priv->TryupingCount --; + } + + if(bTryDown) + { + priv->TryDownCountLowData++; + priv->TryupingCount = 0; + + + //Check if Tx rate can be degraded or Test trying upgrading should fallback. + if(priv->TryDownCountLowData > TryDownTh || priv->bTryuping) + { + priv->TryDownCountLowData = 0; + priv->bTryuping = false; + // Update fail information. + if(priv->LastFailTxRate == priv->CurrentOperaRate) + { + priv->FailTxRateCount ++; + // Record the Tx fail rate signal strength. + if(CurrSignalStrength > priv->LastFailTxRateSS) + { + priv->LastFailTxRateSS = CurrSignalStrength; + } + } + else + { + priv->LastFailTxRate = priv->CurrentOperaRate; + priv->FailTxRateCount = 1; + priv->LastFailTxRateSS = CurrSignalStrength; + } + priv->CurrentOperaRate = GetDegradeTxRate(dev, priv->CurrentOperaRate); + // + // When it is CCK rate, it may need to update initial gain to receive lower power packets. + // + if(MgntIsCckRate(priv->CurrentOperaRate)) + { + bUpdateInitialGain = true; + } + //printk("StaRateAdaptive87B(): Degrade Tx Rate to %d\n", priv->CurrentOperaRate); + } + } + else + { + if(priv->TryDownCountLowData > 0) + priv->TryDownCountLowData --; + } + // Keep the Tx fail rate count to equal to 0x15 at most. + // Reduce the fail count at least to 10 sec if tx rate is tending stable. + if(priv->FailTxRateCount >= 0x15 || + (!bTryUp && !bTryDown && priv->TryDownCountLowData == 0 && priv->TryupingCount && priv->FailTxRateCount > 0x6)) + { + priv->FailTxRateCount --; + } + + // + // We need update initial gain when we set tx rate "from OFDM to CCK" or + // "from CCK to OFDM". + // +SetInitialGain: +#if 1 //to be done + if(bUpdateInitialGain) + { + if(MgntIsCckRate(priv->CurrentOperaRate)) // CCK + { + if(priv->InitialGain > priv->RegBModeGainStage) + { + if(CurrSignalStrength < -85) // Low power, OFDM [0x17] = 26. + { + priv->InitialGain = priv->RegBModeGainStage; + } + else if(priv->InitialGain > priv->RegBModeGainStage + 1) + { + priv->InitialGain -= 2; + } + else + { + priv->InitialGain --; + } + UpdateInitialGain(dev); + } + } + else // OFDM + { + if(priv->InitialGain < 4) + { + priv->InitialGain ++; + UpdateInitialGain(dev); + } + } + } +#endif + //Record the related info + priv->LastRetryRate = CurrRetryRate; + priv->LastTxThroughput = TxThroughput; + priv->ieee80211->rate = priv->CurrentOperaRate * 5; +} + +#if LINUX_VERSION_CODE >=KERNEL_VERSION(2,6,20) +void rtl8180_rate_adapter(struct work_struct * work) +{ + struct delayed_work *dwork = container_of(work,struct delayed_work,work); + struct ieee80211_device *ieee = container_of(dwork,struct ieee80211_device,rate_adapter_wq); + struct net_device *dev = ieee->dev; +#else +void rtl8180_rate_adapter(struct net_device *dev) +{ + +#endif + sta_rateadaptive8187B(dev); +} + +void timer_rate_adaptive(unsigned long data) +{ + struct r8180_priv* priv = ieee80211_priv((struct net_device *)data); + //DMESG("---->timer_rate_adaptive()\n"); + if(!priv->up) + { + //DMESG("<----timer_rate_adaptive():driver is not up!\n"); + return; + } + if( (priv->ieee80211->mode != IEEE_B) && + (priv->ieee80211->iw_mode != IW_MODE_MASTER) + && ((priv->ieee80211->state == IEEE80211_LINKED)||(priv->ieee80211->state == IEEE80211_MESH_LINKED))) + { + //DMESG("timer_rate_adaptive():schedule rate_adapter_wq\n"); +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20) + queue_delayed_work(priv->ieee80211->wq,&priv->ieee80211->rate_adapter_wq, 0); +#else + queue_work(priv->ieee80211->wq,&priv->ieee80211->rate_adapter_wq); +#endif + } + + mod_timer(&priv->rateadapter_timer, jiffies + MSECS(DEFAULT_RATE_ADAPTIVE_TIMER_PERIOD)); + //DMESG("<----timer_rate_adaptive()\n"); +} +//by amy for rate adaptive + + +void rtl8180_irq_rx_tasklet_new(struct r8180_priv *priv); +void rtl8180_irq_rx_tasklet(struct r8180_priv *priv); + +//YJ,add,080828,for KeepAlive +#if 0 +static void MgntLinkKeepAlive(struct r8180_priv *priv ) +{ + if (priv->keepAliveLevel == 0) + return; + + if(priv->ieee80211->state == IEEE80211_LINKED) + { + // + // Keep-Alive. + // + //printk("LastTx:%d Tx:%d LastRx:%d Rx:%ld Idle:%d\n",priv->link_detect.LastNumTxUnicast,priv->NumTxUnicast, priv->link_detect.LastNumRxUnicast, priv->ieee80211->NumRxUnicast, priv->link_detect.IdleCount); + + if ( (priv->keepAliveLevel== 2) || + (priv->link_detect.LastNumTxUnicast == priv->NumTxUnicast && + priv->link_detect.LastNumRxUnicast == priv->ieee80211->NumRxUnicast ) + ) + { + priv->link_detect.IdleCount++; + + // + // Send a Keep-Alive packet packet to AP if we had been idle for a while. + // + if(priv->link_detect.IdleCount >= ((KEEP_ALIVE_INTERVAL / CHECK_FOR_HANG_PERIOD)-1) ) + { + priv->link_detect.IdleCount = 0; + ieee80211_sta_ps_send_null_frame(priv->ieee80211, false); + } + } + else + { + priv->link_detect.IdleCount = 0; + } + priv->link_detect.LastNumTxUnicast = priv->NumTxUnicast; + priv->link_detect.LastNumRxUnicast = priv->ieee80211->NumRxUnicast; + } +} +//YJ,add,080828,for KeepAlive,end +#endif +void InactivePowerSave(struct net_device *dev) +{ + struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev); + + // + // This flag "bSwRfProcessing", indicates the status of IPS procedure, should be set if the IPS workitem + // is really scheduled. + // The old code, sets this flag before scheduling the IPS workitem and however, at the same time the + // previous IPS workitem did not end yet, fails to schedule the current workitem. Thus, bSwRfProcessing + // blocks the IPS procedure of switching RF. + // By Bruce, 2007-12-25. + // + priv->bSwRfProcessing = true; + MgntActSet_RF_State(dev, priv->eInactivePowerState, RF_CHANGE_BY_IPS); + + // + // To solve CAM values miss in RF OFF, rewrite CAM values after RF ON. By Bruce, 2007-09-20. + // +#if 0 + while( index < 4 ) + { + if( ( pMgntInfo->SecurityInfo.PairwiseEncAlgorithm == WEP104_Encryption ) || + (pMgntInfo->SecurityInfo.PairwiseEncAlgorithm == WEP40_Encryption) ) + { + if( pMgntInfo->SecurityInfo.KeyLen[index] != 0) + pAdapter->HalFunc.SetKeyHandler(pAdapter, index, 0, FALSE, pMgntInfo->SecurityInfo.PairwiseEncAlgorithm, TRUE, FALSE); + + } + index++; + } +#endif + priv->bSwRfProcessing = false; +} + +// +// Description: +// Enter the inactive power save mode. RF will be off +// 2007.08.17, by shien chang. +// +void IPSEnter(struct net_device *dev) +{ + struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev); + RT_RF_POWER_STATE rtState; + + if (priv->bInactivePs) + { + rtState = priv->eRFPowerState; + + // + // Added by Bruce, 2007-12-25. + // Do not enter IPS in the following conditions: + // (1) RF is already OFF or Sleep + // (2) bSwRfProcessing (indicates the IPS is still under going) + // (3) Connectted (only disconnected can trigger IPS) + // (4) IBSS (send Beacon) + // (5) AP mode (send Beacon) + // + if (rtState == eRfOn && !priv->bSwRfProcessing && (priv->ieee80211->iw_mode != IW_MODE_ADHOC) + && (priv->ieee80211->state != IEEE80211_LINKED )) + { +#ifdef CONFIG_RADIO_DEBUG + DMESG("IPSEnter(): Turn off RF."); +#endif + priv->eInactivePowerState = eRfOff; + InactivePowerSave(dev); + //SetRFPowerState(dev, priv->eInactivePowerState); + //MgntActSet_RF_State(dev, priv->eInactivePowerState, RF_CHANGE_BY_IPS); + } + } + //printk("priv->eRFPowerState is %d\n",priv->eRFPowerState); +} + +void IPSLeave(struct net_device *dev) +{ + struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev); + RT_RF_POWER_STATE rtState; + if (priv->bInactivePs) + { + rtState = priv->eRFPowerState; + if (rtState == eRfOff && (!priv->bSwRfProcessing) && priv->RfOffReason <= RF_CHANGE_BY_IPS) + { +#ifdef CONFIG_RADIO_DEBUG + DMESG("ISLeave(): Turn on RF."); +#endif + priv->eInactivePowerState = eRfOn; + InactivePowerSave(dev); + } + } +// printk("priv->eRFPowerState is %d\n",priv->eRFPowerState); +} +//by amy for power save + +//YJ,add,081230 +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)) +void IPSLeave_wq (struct work_struct *work) +{ + struct ieee80211_device *ieee = container_of(work,struct ieee80211_device,ips_leave_wq); + struct net_device *dev = ieee->dev; +#else +void IPSLeave_wq(struct net_device *dev) +{ +#endif + struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev); + down(&priv->ieee80211->ips_sem); + IPSLeave(dev); + up(&priv->ieee80211->ips_sem); +} + +void ieee80211_ips_leave(struct net_device *dev) +{ + struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev); + if(priv->bInactivePs){ + if(priv->eRFPowerState == eRfOff) + { + //DMESG("%s", __FUNCTION__); + queue_work(priv->ieee80211->wq,&priv->ieee80211->ips_leave_wq); + } + } +} +//YJ,add,081230,end + +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)) +void rtl8180_watch_dog_wq (struct work_struct *work) +{ + struct delayed_work *dwork = container_of(work,struct delayed_work,work); + struct ieee80211_device *ieee = container_of(dwork,struct ieee80211_device,watch_dog_wq); + struct net_device *dev = ieee->dev; +#else +void rtl8180_watch_dog_wq(struct net_device *dev) +{ +#endif + struct r8180_priv *priv = ieee80211_priv(dev); + //bool bEnterPS = false; + //bool bBusyTraffic = false; + u32 TotalRxNum = 0; + u16 SlotIndex = 0, i=0; + //YJ,add,080828,for link state check + if((priv->ieee80211->state == IEEE80211_LINKED) && (priv->ieee80211->iw_mode == IW_MODE_INFRA)){ + SlotIndex = (priv->link_detect.SlotIndex++) % priv->link_detect.SlotNum; + priv->link_detect.RxFrameNum[SlotIndex] = priv->ieee80211->NumRxDataInPeriod + priv->ieee80211->NumRxBcnInPeriod; + for( i=0; ilink_detect.SlotNum; i++ ) + TotalRxNum+= priv->link_detect.RxFrameNum[i]; +#if 0 //for roaming temp del + if(TotalRxNum == 0){ + priv->ieee80211->state = IEEE80211_ASSOCIATING; + printk("=========>turn to another AP\n"); + queue_work(priv->ieee80211->wq, &priv->ieee80211->associate_procedure_wq); + } +#endif + } + priv->link_detect.NumRxOkInPeriod = 0; + priv->link_detect.NumTxOkInPeriod = 0; + priv->ieee80211->NumRxDataInPeriod = 0; + priv->ieee80211->NumRxBcnInPeriod = 0; + +#ifdef CONFIG_IPS + if(priv->ieee80211->actscanning == false){ + if((priv->ieee80211->iw_mode == IW_MODE_INFRA) && + (priv->ieee80211->state == IEEE80211_NOLINK) && + (priv->eRFPowerState == eRfOn)) + { + //printk("actscanning:%d, state:%d, eRFPowerState:%d\n", + // priv->ieee80211->actscanning, + // priv->ieee80211->state, + // priv->eRFPowerState); + + down(&priv->ieee80211->ips_sem); + IPSEnter(dev); + up(&priv->ieee80211->ips_sem); + } + } + //queue_delayed_work(priv->ieee80211->wq,&priv->ieee80211->watch_dog_wq,IEEE80211_WATCH_DOG_TIME); +#endif + + //printk("========================>leave rtl8180_watch_dog_wq()\n"); +} + +void watch_dog_adaptive(unsigned long data) +{ + struct net_device* dev = (struct net_device*)data; + struct r8180_priv* priv = ieee80211_priv(dev); + //DMESG("---->watch_dog_adaptive()\n"); + if(!priv->up){ + //DMESG("<----watch_dog_adaptive():driver is not up!\n"); + return; + } + // Tx and Rx High Power Mechanism. + if(CheckHighPower(dev)){ + //printk("===============================> high power!\n"); +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20) + queue_delayed_work(priv->ieee80211->wq,&priv->ieee80211->tx_pw_wq, 0); +#else + queue_work(priv->ieee80211->wq,&priv->ieee80211->tx_pw_wq); +#endif + } + + // Schedule an workitem to perform DIG + if(CheckDig(dev) == true){ + +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20) + queue_delayed_work(priv->ieee80211->wq,&priv->ieee80211->hw_dig_wq,0); +#else + queue_work(priv->ieee80211->wq,&priv->ieee80211->hw_dig_wq); +#endif + } + +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20) + queue_delayed_work(priv->ieee80211->wq,&priv->ieee80211->watch_dog_wq,0); +#else + queue_work(priv->ieee80211->wq,&priv->ieee80211->watch_dog_wq); +#endif + + mod_timer(&priv->watch_dog_timer, jiffies + MSECS(IEEE80211_WATCH_DOG_TIME)); + //DMESG("<----watch_dog_adaptive()\n"); +} + +#ifdef ENABLE_DOT11D + +CHANNEL_LIST Current_tbl; + +static CHANNEL_LIST ChannelPlan[] = { + {{1,2,3,4,5,6,7,8,9,10,11,36,40,44,48,52,56,60,64},19}, //FCC + {{1,2,3,4,5,6,7,8,9,10,11},11}, //IC + {{1,2,3,4,5,6,7,8,9,10,11,12,13,36,40,44,48,52,56,60,64},21}, //ETSI + {{1,2,3,4,5,6,7,8,9,10,11,12,13,36,40,44,48,52,56,60,64},21}, //Spain. Change to ETSI. + {{1,2,3,4,5,6,7,8,9,10,11,12,13,36,40,44,48,52,56,60,64},21}, //France. Change to ETSI. + {{14,36,40,44,48,52,56,60,64},9}, //MKK + {{1,2,3,4,5,6,7,8,9,10,11,12,13,14, 36,40,44,48,52,56,60,64},22},//MKK1 + {{1,2,3,4,5,6,7,8,9,10,11,12,13,36,40,44,48,52,56,60,64},21}, //Israel. + {{1,2,3,4,5,6,7,8,9,10,11,12,13,34,38,42,46},17}, // For 11a , TELEC + {{1,2,3,4,5,6,7,8,9,10,11,12,13,14},14}, //For Global Domain. 1-11:active scan, 12-14 passive scan. //+YJ, 080626 + {{1,2,3,4,5,6,7,8,9,10,11,12,13},13} //world wide 13: ch1~ch11 active scan, ch12~13 passive //lzm add 081205 +}; + +static void rtl8180_set_channel_map(u8 channel_plan, struct ieee80211_device *ieee) +{ + int i; + + //lzm add 081205 + ieee->MinPassiveChnlNum=MAX_CHANNEL_NUMBER+1; + ieee->IbssStartChnl=0; + + switch (channel_plan) + { + case COUNTRY_CODE_FCC: + case COUNTRY_CODE_IC: + case COUNTRY_CODE_ETSI: + case COUNTRY_CODE_SPAIN: + case COUNTRY_CODE_FRANCE: + case COUNTRY_CODE_MKK: + case COUNTRY_CODE_MKK1: + case COUNTRY_CODE_ISRAEL: + case COUNTRY_CODE_TELEC: + { + Dot11d_Init(ieee); + ieee->bGlobalDomain = false; + ieee->bWorldWide13 = false; + if (ChannelPlan[channel_plan].Len != 0){ + // Clear old channel map + memset(GET_DOT11D_INFO(ieee)->channel_map, 0, sizeof(GET_DOT11D_INFO(ieee)->channel_map)); + // Set new channel map + for (i=0;ichannel_map[ChannelPlan[channel_plan].Channel[i]] = 1; + } + } + break; + } + case COUNTRY_CODE_GLOBAL_DOMAIN: + { + GET_DOT11D_INFO(ieee)->bEnabled = 0; + Dot11d_Reset(ieee); + ieee->bGlobalDomain = true; + ieee->bWorldWide13 = false; + + //lzm add 081205 + ieee->MinPassiveChnlNum=12; + ieee->IbssStartChnl= 10; + + break; + } + case COUNTRY_CODE_WORLD_WIDE_13_INDEX://lzm add 081205 + { + Dot11d_Init(ieee); + ieee->bGlobalDomain = false; + ieee->bWorldWide13 = true; + + //lzm add 081205 + ieee->MinPassiveChnlNum=12; + ieee->IbssStartChnl= 10; + + if (ChannelPlan[channel_plan].Len != 0){ + // Clear old channel map + memset(GET_DOT11D_INFO(ieee)->channel_map, 0, sizeof(GET_DOT11D_INFO(ieee)->channel_map)); + // Set new channel map + for (i=0;ichannel_map[ChannelPlan[channel_plan].Channel[i]] = 1; + else//ch12~13 passive scan + GET_DOT11D_INFO(ieee)->channel_map[ChannelPlan[channel_plan].Channel[i]] = 2; + } + } + + break; + } + default: + { + Dot11d_Init(ieee); + ieee->bGlobalDomain = false; + ieee->bWorldWide13 = false; + memset(GET_DOT11D_INFO(ieee)->channel_map, 0, sizeof(GET_DOT11D_INFO(ieee)->channel_map)); + for (i=1;i<=14;i++) + { + GET_DOT11D_INFO(ieee)->channel_map[i] = 1; + } + break; + } + } +} +#endif + + +//Add for RF power on power off by lizhaoming 080512 +#ifdef POLLING_METHOD_FOR_RADIO +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)) +void GPIOChangeRFWorkItemCallBack(struct work_struct *work); +#else +void GPIOChangeRFWorkItemCallBack(struct ieee80211_device *ieee); +#endif +void gpio_change_polling(unsigned long data); +#endif + + +static void rtl8180_link_detect_init(plink_detect_t plink_detect) +{ + memset(plink_detect, 0, sizeof(link_detect_t)); + plink_detect->SlotNum = DEFAULT_SLOT_NUM; +} + +#ifdef SW_ANTE_DIVERSITY +static void rtl8187_antenna_diversity_read(struct net_device *dev) +{ + struct r8180_priv *priv = ieee80211_priv(dev); + u16 usValue; + + //2 Read CustomerID + usValue = eprom_read(dev, EEPROM_SW_REVD_OFFSET>>1); + priv->EEPROMCustomerID = (u8)( usValue & EEPROM_CID_MASK ); + //DMESG("EEPROM Customer ID: %02X\n", priv->EEPROMCustomerID); + + //2 Read AntennaDiversity + // SW Antenna Diversity. + if( (usValue & EEPROM_SW_AD_MASK) != EEPROM_SW_AD_ENABLE ){ + priv->EEPROMSwAntennaDiversity = false; + DMESG("EEPROM Disable SW Antenna Diversity"); + }else{ + priv->EEPROMSwAntennaDiversity = true; + DMESG("EEPROM Enable SW Antenna Diversity"); + } + // Default Antenna to use. + if( (usValue & EEPROM_DEF_ANT_MASK) != EEPROM_DEF_ANT_1 ) { + priv->EEPROMDefaultAntenna1 = false; + DMESG("EEPROM Default Main Antenna 0"); + }else{ + priv->EEPROMDefaultAntenna1 = false; + DMESG( "EEPROM Default Aux Antenna 1"); + } + + // + // Antenna diversity mechanism. Added by Roger, 2007.11.05. + // + if( priv->RegSwAntennaDiversityMechanism == 0 ) // Auto //set it to 0 when init + {// 0: default from EEPROM. + priv->bSwAntennaDiverity = priv->EEPROMSwAntennaDiversity; + }else{// 1:disable antenna diversity, 2: enable antenna diversity. + priv->bSwAntennaDiverity = ((priv->RegSwAntennaDiversityMechanism == 1)? false : true); + } + //DMESG("bSwAntennaDiverity = %d\n", priv->bSwAntennaDiverity); + + + // + // Default antenna settings. Added by Roger, 2007.11.05. + // + if( priv->RegDefaultAntenna == 0)//set it to 0 when init + { // 0: default from EEPROM. + priv->bDefaultAntenna1 = priv->EEPROMDefaultAntenna1; + }else{// 1: main, 2: aux. + priv->bDefaultAntenna1 = ((priv->RegDefaultAntenna== 2) ? true : false); + } + //DMESG("bDefaultAntenna1 = %d\n", priv->bDefaultAntenna1); + +//by amy for antenna +} +#endif + +short rtl8180_init(struct net_device *dev) +{ + struct r8180_priv *priv = ieee80211_priv(dev); + int i, j; + u16 word; + //int ch; + //u16 version; + u8 hw_version; + //u8 config3; + struct usb_device *udev; + u16 idProduct; + u16 bcdDevice; + //u8 chan_plan_index; + + //FIXME: these constants are placed in a bad pleace. + + //priv->txbuffsize = 1024; + //priv->txringcount = 32; + //priv->rxbuffersize = 1024; + //priv->rxringcount = 32; + //priv->txbeaconcount = 3; + //priv->rx_skb_complete = 1; + //priv->txnp_pending.ispending=0; + /* ^^ the SKB does not containt a partial RXed packet (is empty) */ + + //memcpy(priv->stats,0,sizeof(struct Stats)); + + //priv->irq_enabled=0; + priv->driver_upping = 0; + priv->commit = 0; + + //priv->stats.rxdmafail=0; + priv->stats.txrdu=0; + //priv->stats.rxrdu=0; + //priv->stats.rxnolast=0; + //priv->stats.rxnodata=0; + //priv->stats.rxreset=0; + //priv->stats.rxwrkaround=0; + //priv->stats.rxnopointer=0; + priv->stats.txbeerr=0; + priv->stats.txbkerr=0; + priv->stats.txvierr=0; + priv->stats.txvoerr=0; + priv->stats.txmanageerr=0; + priv->stats.txbeaconerr=0; + priv->stats.txresumed=0; + //priv->stats.rxerr=0; + //priv->stats.rxoverflow=0; + //priv->stats.rxint=0; + priv->stats.txbeokint=0; + priv->stats.txbkokint=0; + priv->stats.txviokint=0; + priv->stats.txvookint=0; + priv->stats.txmanageokint=0; + priv->stats.txbeaconokint=0; + /*priv->stats.txhpokint=0; + priv->stats.txhperr=0;*/ + priv->stats.rxurberr=0; + priv->stats.rxstaterr=0; + priv->stats.txoverflow=0; + priv->stats.rxok=0; + //priv->stats.txbeaconerr=0; + //priv->stats.txlperr=0; + //priv->stats.txlpokint=0; +//john + priv->stats.txnpdrop=0; + priv->stats.txlpdrop =0; + priv->stats.txbedrop =0; + priv->stats.txbkdrop =0; + priv->stats.txvidrop =0; + priv->stats.txvodrop =0; + priv->stats.txbeacondrop =0; + priv->stats.txmanagedrop =0; + + // priv->stats.txokbytestotal =0; +//by amy + priv->LastSignalStrengthInPercent=0; + priv->SignalStrength=0; + priv->SignalQuality=0; + priv->antenna_flag=0; + priv->flag_beacon = false; +//by amy +//david + //radion on defaultly + priv->radion = 1; +//david +//by amy for rate adaptive + priv->CurrRetryCnt=0; + priv->LastRetryCnt=0; + priv->LastTxokCnt=0; + priv->LastRxokCnt=0; + priv->LastRetryRate=0; + priv->bTryuping=0; + priv->CurrTxRate=0; + priv->CurrRetryRate=0; + priv->TryupingCount=0; + priv->TryupingCountNoData=0; + priv->TryDownCountLowData=0; + priv->RecvSignalPower=0; + priv->LastTxOKBytes=0; + priv->LastFailTxRate=0; + priv->LastFailTxRateSS=0; + priv->FailTxRateCount=0; + priv->LastTxThroughput=0; + priv->txokbytestotal=0; +//by amy for rate adaptive +//by amy for ps + priv->RFChangeInProgress = false; + priv->SetRFPowerStateInProgress = false; + priv->RFProgType = 0; + priv->bInHctTest = false; + priv->bInactivePs = true;//false; + priv->ieee80211->bInactivePs = priv->bInactivePs; + priv->eInactivePowerState = eRfOn;//lzm add for IPS and Polling methord + priv->bSwRfProcessing = false; + priv->eRFPowerState = eRfOff; + priv->RfOffReason = 0; + priv->NumRxOkInPeriod = 0; + priv->NumTxOkInPeriod = 0; + priv->bLeisurePs = true; + priv->dot11PowerSaveMode = eActive; + priv->RegThreeWireMode=HW_THREE_WIRE_BY_8051; + priv->ps_mode = false; +//by amy for ps +//by amy for DIG + priv->bDigMechanism = 1; + priv->bCCKThMechanism = 0; + priv->InitialGain = 0; + priv->StageCCKTh = 0; + priv->RegBModeGainStage = 2; +//by amy for DIG +// {by david for DIG, 2008.3.6 + priv->RegDigOfdmFaUpTh = 0x0c; + priv->RegBModeGainStage = 0x02; + priv->DIG_NumberFallbackVote = 0; + priv->DIG_NumberUpgradeVote = 0; + priv->CCKUpperTh = 0x100; + priv->CCKLowerTh = 0x20; +//} +//{added by david for High tx power, 2008.3.11 + priv->bRegHighPowerMechanism = true; + priv->bToUpdateTxPwr = false; + + priv->Z2HiPwrUpperTh = 77; + priv->Z2HiPwrLowerTh = 75; + priv->Z2RSSIHiPwrUpperTh = 70; + priv->Z2RSSIHiPwrLowerTh = 20; + //specify for rtl8187B + priv->wMacRegRfPinsOutput = 0x0480; + priv->wMacRegRfPinsSelect = 0x2488; + // + // Note that, we just set TrSwState to TR_HW_CONTROLLED here instead of changing + // HW setting because we assume it should be inialized as HW controlled. 061010, by rcnjko. + // + priv->TrSwitchState = TR_HW_CONTROLLED; +//} + priv->ieee80211->iw_mode = IW_MODE_INFRA; +//test pending bug, john 20070815 + for(i=0;i<0x10;i++) atomic_set(&(priv->tx_pending[i]), 0); +//by lizhaoming +#ifdef POLLING_METHOD_FOR_RADIO + priv->wlan_first_up_flag1 = 0; + priv->polling_timer_on = 0;//add for S3/S4 +#endif +//by lizhaoming for LED +#ifdef LED + priv->ieee80211->ieee80211_led_contorl = LedControl8187; +#endif +#ifdef CONFIG_IPS + priv->ieee80211->ieee80211_ips_leave = ieee80211_ips_leave;//IPSLeave; +#endif + +#ifdef SW_ANTE_DIVERSITY + priv->antb=0; + priv->diversity=1; + priv->LastRxPktAntenna = 0; + priv->AdMinCheckPeriod = 5; + priv->AdMaxCheckPeriod = 10; + // Lower signal strength threshold to fit the HW participation in antenna diversity. +by amy 080312 + priv->AdMaxRxSsThreshold = 30;//60->30 + priv->AdRxSsThreshold = 20;//50->20 + priv->AdCheckPeriod = priv->AdMinCheckPeriod; + priv->AdTickCount = 0; + priv->AdRxSignalStrength = -1; + priv->RegSwAntennaDiversityMechanism = 0; + priv->RegDefaultAntenna = 0; + priv->SignalStrength = 0; + priv->AdRxOkCnt = 0; + priv->CurrAntennaIndex = 0; + priv->AdRxSsBeforeSwitched = 0; + init_timer(&priv->SwAntennaDiversityTimer); + priv->SwAntennaDiversityTimer.data = (unsigned long)dev; + priv->SwAntennaDiversityTimer.function = (void *)SwAntennaDiversityTimerCallback; +#endif + + priv->retry_rts = DEFAULT_RETRY_RTS; + priv->retry_data = DEFAULT_RETRY_DATA; + priv->ieee80211->rate = 110; //11 mbps + priv->CurrentOperaRate=priv->ieee80211->rate/5; + priv->ieee80211->short_slot = 1; + priv->ieee80211->mode = IEEE_G; + priv->promisc = (dev->flags & IFF_PROMISC) ? 1:0; + + rtl8180_link_detect_init(&priv->link_detect); + + spin_lock_init(&priv->tx_lock); + spin_lock_init(&priv->irq_lock);//added by thomas + spin_lock_init(&priv->rf_ps_lock); +#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)) +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)) + INIT_WORK(&priv->reset_wq, (void*)rtl8180_restart); + INIT_WORK(&priv->ieee80211->ips_leave_wq, (void*)IPSLeave_wq); //YJ,add,081230,for IPS + INIT_DELAYED_WORK(&priv->ieee80211->rate_adapter_wq,(void*)rtl8180_rate_adapter); + INIT_DELAYED_WORK(&priv->ieee80211->hw_dig_wq,(void*)rtl8180_hw_dig_wq); + INIT_DELAYED_WORK(&priv->ieee80211->watch_dog_wq,(void*)rtl8180_watch_dog_wq); + INIT_DELAYED_WORK(&priv->ieee80211->tx_pw_wq,(void*)rtl8180_tx_pw_wq); + +//add for RF power on power off by lizhaoming 080512 +#ifdef POLLING_METHOD_FOR_RADIO + INIT_DELAYED_WORK(&priv->ieee80211->GPIOChangeRFWorkItem, (void*)GPIOChangeRFWorkItemCallBack); +#endif + +#ifdef SW_ANTE_DIVERSITY + INIT_DELAYED_WORK(&priv->ieee80211->SwAntennaWorkItem,(void*) SwAntennaWorkItemCallback); +#endif + +#else + INIT_WORK(&priv->reset_wq,(void*) rtl8180_restart,dev); + INIT_WORK(&priv->ieee80211->ips_leave_wq, (void*)IPSLeave_wq,dev); //YJ,add,081230,for IPS + INIT_WORK(&priv->ieee80211->rate_adapter_wq,(void*)rtl8180_rate_adapter,dev); + INIT_WORK(&priv->ieee80211->hw_dig_wq,(void*)rtl8180_hw_dig_wq,dev); + INIT_WORK(&priv->ieee80211->watch_dog_wq,(void*)rtl8180_watch_dog_wq,dev); + INIT_WORK(&priv->ieee80211->tx_pw_wq,(void*)rtl8180_tx_pw_wq,dev); + +//add for RF power on power off by lizhaoming 080512 +#ifdef POLLING_METHOD_FOR_RADIO + INIT_WORK(&priv->ieee80211->GPIOChangeRFWorkItem,(void*) GPIOChangeRFWorkItemCallBack, priv->ieee80211); +#endif + +#ifdef SW_ANTE_DIVERSITY + INIT_WORK(&priv->ieee80211->SwAntennaWorkItem,(void*) SwAntennaWorkItemCallback, dev); +#endif + +#endif +#else + tq_init(&priv->reset_wq,(void*) rtl8180_restart,dev); +#endif + sema_init(&priv->wx_sem,1); + sema_init(&priv->set_chan_sem,1); +#ifdef THOMAS_TASKLET + tasklet_init(&priv->irq_rx_tasklet, + (void(*)(unsigned long))rtl8180_irq_rx_tasklet_new, + (unsigned long)priv); +#else + tasklet_init(&priv->irq_rx_tasklet, + (void(*)(unsigned long))rtl8180_irq_rx_tasklet, + (unsigned long)priv); +#endif +//by lizhaoming for Radio on/off +#ifdef POLLING_METHOD_FOR_RADIO + init_timer(&priv->gpio_polling_timer); + priv->gpio_polling_timer.data = (unsigned long)dev; + priv->gpio_polling_timer.function = gpio_change_polling; +#endif +//by amy for rate adaptive + init_timer(&priv->rateadapter_timer); + priv->rateadapter_timer.data = (unsigned long)dev; + priv->rateadapter_timer.function = timer_rate_adaptive; +//by amy for rate adaptive +//by amy for ps + init_timer(&priv->watch_dog_timer); + priv->watch_dog_timer.data = (unsigned long)dev; + priv->watch_dog_timer.function = watch_dog_adaptive; +//by amy +//by amy for ps + priv->ieee80211->current_network.beacon_interval = DEFAULT_BEACONINTERVAL; + priv->ieee80211->iw_mode = IW_MODE_INFRA; + priv->ieee80211->softmac_features = IEEE_SOFTMAC_SCAN | + IEEE_SOFTMAC_ASSOCIATE | IEEE_SOFTMAC_PROBERQ | +#ifdef CONFIG_SOFT_BEACON + IEEE_SOFTMAC_BEACONS | //IEEE_SOFTMAC_SINGLE_QUEUE; +#endif + IEEE_SOFTMAC_PROBERS | IEEE_SOFTMAC_TX_QUEUE; + + priv->ieee80211->active_scan = 1; + //priv->ieee80211->ch_lock = 0; + priv->ieee80211->rate = 110; //11 mbps + priv->ieee80211->modulation = IEEE80211_CCK_MODULATION | IEEE80211_OFDM_MODULATION; + priv->ieee80211->host_encrypt = 1; + priv->ieee80211->host_decrypt = 1; +#ifdef CONFIG_SOFT_BEACON + priv->ieee80211->start_send_beacons = NULL; + priv->ieee80211->stop_send_beacons = NULL; +#else + priv->ieee80211->start_send_beacons = rtl8187_beacon_tx; + priv->ieee80211->stop_send_beacons = rtl8187_beacon_stop; +#endif + priv->ieee80211->softmac_hard_start_xmit = rtl8180_hard_start_xmit; + priv->ieee80211->set_chan = rtl8180_set_chan; + priv->ieee80211->link_change = rtl8187_link_change; + priv->ieee80211->softmac_data_hard_start_xmit = rtl8180_hard_data_xmit; + priv->ieee80211->data_hard_stop = rtl8180_data_hard_stop; + priv->ieee80211->data_hard_resume = rtl8180_data_hard_resume; + +#ifdef _RTL8187_EXT_PATCH_ + priv->ieee80211->meshScanMode = 0; + priv->mshobj = alloc_mshobj(priv); + if(priv->mshobj) + { + priv->ieee80211->ext_patch_ieee80211_start_protocol = priv->mshobj->ext_patch_ieee80211_start_protocol; + priv->ieee80211->ext_patch_ieee80211_stop_protocol = priv->mshobj->ext_patch_ieee80211_stop_protocol; +//by amy for mesh + priv->ieee80211->ext_patch_ieee80211_start_mesh = priv->mshobj->ext_patch_ieee80211_start_mesh; +//by amy for mesh + priv->ieee80211->ext_patch_ieee80211_probe_req_1 = priv->mshobj->ext_patch_ieee80211_probe_req_1; + priv->ieee80211->ext_patch_ieee80211_probe_req_2 = priv->mshobj->ext_patch_ieee80211_probe_req_2; + priv->ieee80211->ext_patch_ieee80211_association_req_1 = priv->mshobj->ext_patch_ieee80211_association_req_1; + priv->ieee80211->ext_patch_ieee80211_association_req_2 = priv->mshobj->ext_patch_ieee80211_association_req_2; + priv->ieee80211->ext_patch_ieee80211_assoc_resp_by_net_1 = priv->mshobj->ext_patch_ieee80211_assoc_resp_by_net_1; + priv->ieee80211->ext_patch_ieee80211_assoc_resp_by_net_2 = priv->mshobj->ext_patch_ieee80211_assoc_resp_by_net_2; + priv->ieee80211->ext_patch_ieee80211_rx_frame_softmac_on_auth = priv->mshobj->ext_patch_ieee80211_rx_frame_softmac_on_auth; + priv->ieee80211->ext_patch_ieee80211_rx_frame_softmac_on_deauth = priv->mshobj->ext_patch_ieee80211_rx_frame_softmac_on_deauth; + priv->ieee80211->ext_patch_ieee80211_rx_frame_softmac_on_assoc_req = priv->mshobj->ext_patch_ieee80211_rx_frame_softmac_on_assoc_req; + priv->ieee80211->ext_patch_ieee80211_rx_frame_softmac_on_assoc_rsp = priv->mshobj->ext_patch_ieee80211_rx_frame_softmac_on_assoc_rsp; + priv->ieee80211->ext_patch_ieee80211_ext_stop_scan_wq_set_channel = priv->mshobj->ext_patch_ieee80211_ext_stop_scan_wq_set_channel; + priv->ieee80211->ext_patch_ieee80211_process_probe_response_1 = priv->mshobj->ext_patch_ieee80211_process_probe_response_1; + priv->ieee80211->ext_patch_ieee80211_rx_mgt_on_probe_req = priv->mshobj->ext_patch_ieee80211_rx_mgt_on_probe_req; + priv->ieee80211->ext_patch_ieee80211_rx_mgt_update_expire = priv->mshobj->ext_patch_ieee80211_rx_mgt_update_expire; + priv->ieee80211->ext_patch_get_beacon_get_probersp = priv->mshobj->ext_patch_get_beacon_get_probersp; + priv->ieee80211->ext_patch_ieee80211_rx_on_rx = priv->mshobj->ext_patch_ieee80211_rx_on_rx; + priv->ieee80211->ext_patch_ieee80211_xmit = priv->mshobj->ext_patch_ieee80211_xmit; + priv->ieee80211->ext_patch_ieee80211_rx_frame_get_hdrlen = priv->mshobj->ext_patch_ieee80211_rx_frame_get_hdrlen; + priv->ieee80211->ext_patch_ieee80211_rx_is_valid_framectl = priv->mshobj->ext_patch_ieee80211_rx_is_valid_framectl; + priv->ieee80211->ext_patch_ieee80211_rx_process_dataframe = priv->mshobj->ext_patch_ieee80211_rx_process_dataframe; + // priv->ieee80211->ext_patch_is_duplicate_packet = priv->mshobj->ext_patch_is_duplicate_packet; + priv->ieee80211->ext_patch_ieee80211_softmac_xmit_get_rate = priv->mshobj->ext_patch_ieee80211_softmac_xmit_get_rate; + /* added by david for setting acl dynamically */ + priv->ieee80211->ext_patch_ieee80211_acl_query = priv->mshobj->ext_patch_ieee80211_acl_query; + } + +#endif // _RTL8187_EXT_PATCH_ + +#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)) +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20) + INIT_WORK(&priv->ieee80211->wmm_param_update_wq,\ + (void(*)(void*)) rtl8180_wmm_param_update,\ + priv->ieee80211); +#else + INIT_WORK(&priv->ieee80211->wmm_param_update_wq,\ + rtl8180_wmm_param_update); +#endif +#else + tq_init(&priv->ieee80211->wmm_param_update_wq,\ + (void(*)(void*)) rtl8180_wmm_param_update,\ + priv->ieee80211); +#endif + priv->ieee80211->init_wmmparam_flag = 0; + priv->ieee80211->fts = DEFAULT_FRAG_THRESHOLD; + + //priv->card_8185 = 2; + priv->phy_ver = 2; + priv->card_type = USB; +//{add for 87B + priv->ShortRetryLimit = 7; + priv->LongRetryLimit = 7; + priv->EarlyRxThreshold = 7; + + priv->TransmitConfig = + TCR_DurProcMode | //for RTL8185B, duration setting by HW + TCR_DISReqQsize | + (TCR_MXDMA_2048<ShortRetryLimit<LongRetryLimit<ReceiveConfig = + RCR_AMF | RCR_ADF | //accept management/data + RCR_ACF | //accept control frame for SW AP needs PS-poll, 2005.07.07, by rcnjko. + RCR_AB | RCR_AM | RCR_APM | //accept BC/MC/UC + //RCR_AICV | RCR_ACRC32 | //accept ICV/CRC error packet + RCR_MXDMA | // Max DMA Burst Size per Rx DMA Burst, 7: unlimited. + (priv->EarlyRxThreshold<EarlyRxThreshold == 7 ? RCR_ONLYERLPKT:0); + + priv->AcmControl = 0; +//} + priv->rf_chip = 0xff & eprom_read(dev,EPROM_RFCHIPID); + //DMESG("rf_chip:%x\n", priv->rf_chip); + if (!priv->rf_chip) + { + DMESG("Can't get rf chip ID from EEPROM"); + DMESGW("So set rf chip ID to defalut EPROM_RFCHIPID_RTL8225U"); + DMESGW("use it with care and at your own risk and"); + DMESGW("**PLEASE** REPORT SUCCESS/INSUCCESS TO Realtek"); + priv->rf_chip = EPROM_RFCHIPID_RTL8225U; + + } + + +//{put the card to detect different card here, mainly I/O processing + udev = priv->udev; + idProduct = le16_to_cpu(udev->descriptor.idProduct); + //idProduct = 0x8197; + bcdDevice = le16_to_cpu(udev->descriptor.bcdDevice); + DMESG("idProduct:0x%x, bcdDevice:0x%x", idProduct,bcdDevice); + switch (idProduct) { + case 0x8189: + case 0x8197: + case 0x8198: + /* check RF frontend chipset */ + priv->card_8187 = NIC_8187B; + priv->rf_init = rtl8225z2_rf_init; + priv->rf_set_chan = rtl8225z2_rf_set_chan; + priv->rf_set_sens = NULL; + break; + + case 0x8187: + if(bcdDevice == 0x0200){ + priv->card_8187 = NIC_8187B; + priv->rf_init = rtl8225z2_rf_init; + priv->rf_set_chan = rtl8225z2_rf_set_chan; + priv->rf_set_sens = NULL; + break; + }else{ + //0x0100 is for 8187 + //legacy 8187 NIC + //delet + ; + } + default: + /* check RF frontend chipset */ + priv->ieee80211->softmac_features |= IEEE_SOFTMAC_SINGLE_QUEUE; + priv->card_8187 = NIC_8187; + switch (priv->rf_chip) { + case EPROM_RFCHIPID_RTL8225U: + DMESG("Card reports RF frontend Realtek 8225"); + DMESGW("This driver has EXPERIMENTAL support for this chipset."); + DMESGW("use it with care and at your own risk and"); + DMESGW("**PLEASE** REPORT SUCCESS/INSUCCESS TO Realtek"); + if(rtl8225_is_V_z2(dev)){ + priv->rf_init = rtl8225z2_rf_init; + priv->rf_set_chan = rtl8225z2_rf_set_chan; + priv->rf_set_sens = NULL; + DMESG("This seems a new V2 radio"); + }else{ + priv->rf_init = rtl8225_rf_init; + priv->rf_set_chan = rtl8225_rf_set_chan; + priv->rf_set_sens = rtl8225_rf_set_sens; + DMESG("This seems a legacy 1st version radio"); + } + break; + + case EPROM_RFCHIPID_RTL8225U_VF: + priv->rf_init = rtl8225z2_rf_init; + priv->rf_set_chan = rtl8225z2_rf_set_chan; + priv->rf_set_sens = NULL; + DMESG("This seems a new V2 radio"); + break; + + default: + DMESGW("Unknown RF module %x",priv->rf_chip); + DMESGW("Exiting..."); + return -1; + } + break; + } + + priv->rf_close = rtl8225_rf_close; + priv->max_sens = RTL8225_RF_MAX_SENS; + priv->sens = RTL8225_RF_DEF_SENS; + +#ifdef ENABLE_DOT11D +#if 0 + for(i=0;i<0xFF;i++) { + if(i%16 == 0) + printk("\n[%x]: ", i/16); + printk("\t%4.4x", eprom_read(dev,i)); + } +#endif + priv->channel_plan = eprom_read(dev,EPROM_CHANNEL_PLAN) & 0xFF; + //DMESG("EPROM_CHANNEL_PLAN is %x", priv->channel_plan); + + // lzm add 081205 for Toshiba: + // For Toshiba,reading the value from EEPROM 0x6h bit[7] to determine the priority of + // channel plan to be defined. + // -If bit[7] is true, then the channel plan is defined by EEPROM but no user defined. + // -If bit[7] is false, then the channel plan is defined by user first. + // + if(priv->channel_plan & 0x80) { + DMESG("Toshiba channel plan is defined by EEPROM"); + priv->channel_plan &= 0xf; + } + else + priv->channel_plan = 0; + + //if(priv->channel_plan > COUNTRY_CODE_WORLD_WIDE_13_INDEX){ + if(priv->channel_plan > COUNTRY_CODE_GLOBAL_DOMAIN){ + DMESG("rtl8180_init:Error channel plan! Set to default.\n"); + priv->channel_plan = 0; + } + + //priv->channel_plan = 9; //Global Domain + //priv->channel_plan = 2; //ETSI + + + DMESG("Channel plan is %d ",priv->channel_plan); + + //for Toshiba card we read channel plan from ChanPlanBin + if((idProduct != 0x8197) && (idProduct != 0x8198)) + rtl8180_set_channel_map(priv->channel_plan, priv->ieee80211); +#else + int ch; + priv->channel_plan = eprom_read(dev,EPROM_CHANNEL_PLAN) & 0xff; + if(priv->channel_plan & 0x80) { + priv->channel_plan &= 0x7f; + if (ChannelPlan[priv->channel_plan].Len != 0){ + // force channel plan map + for (i=0;ichannel_plan].Len;i++) + priv->ieee80211->channel_map[ChannelPlan[priv->channel_plan].Channel[i]] = 1; + } else { + DMESG("No channels, aborting"); + return -1; + } + } else { + //default channel plan setting + if(!channels){ + DMESG("No channels, aborting"); + return -1; + } + ch=channels; + // set channels 1..14 allowed in given locale + for (i=1; i<=14; i++) { + (priv->ieee80211->channel_map)[i] = (u8)(ch & 0x01); + ch >>= 1; + } + } +#endif + + if((idProduct == 0x8197) || (idProduct == 0x8198)) { + // lzm add 081205 for Toshiba: + // 0x77h bit[0]=1: use GPIO bit[2], bit[0]=0: use GPIO bit[1] + priv->EEPROMSelectNewGPIO =((u8)((eprom_read(dev,EPROM_SELECT_GPIO) & 0xff00) >> 8)) ? true : false; + DMESG("EPROM_SELECT_GPIO:%d", priv->EEPROMSelectNewGPIO); + } else { + priv->EEPROMSelectNewGPIO = false; + } + + + if (NIC_8187 == priv->card_8187){ + hw_version =( read_nic_dword(dev, TCR) & TCR_HWVERID_MASK)>>TCR_HWVERID_SHIFT; + switch (hw_version) { + case 0x06: + //priv->card_8187_Bversion = VERSION_8187B_B; + break; + case 0x05: + priv->card_8187_Bversion = VERSION_8187_D; + break; + default: + priv->card_8187_Bversion = VERSION_8187_B; + break; + } + }else{ + hw_version = read_nic_byte(dev, 0xe1); //87B hw version reg + switch (hw_version){ + case 0x00: + priv->card_8187_Bversion = VERSION_8187B_B; + break; + case 0x01: + priv->card_8187_Bversion = VERSION_8187B_D; + break; + case 0x02: + priv->card_8187_Bversion = VERSION_8187B_E; + break; + default: + priv->card_8187_Bversion = VERSION_8187B_B; //defalt + break; + } + } + + //printk("=====hw_version:%x\n", priv->card_8187_Bversion); + priv->enable_gpio0 = 0; + + /*the eeprom type is stored in RCR register bit #6 */ + if (RCR_9356SEL & read_nic_dword(dev, RCR)){ + priv->epromtype=EPROM_93c56; + DMESG("Reported EEPROM chip is a 93c56 (2Kbit)"); + }else{ + priv->epromtype=EPROM_93c46; + DMESG("Reported EEPROM chip is a 93c46 (1Kbit)"); + } + + dev->dev_addr[0]=eprom_read(dev,MAC_ADR) & 0xff; + dev->dev_addr[1]=(eprom_read(dev,MAC_ADR) & 0xff00)>>8; + dev->dev_addr[2]=eprom_read(dev,MAC_ADR+1) & 0xff; + dev->dev_addr[3]=(eprom_read(dev,MAC_ADR+1) & 0xff00)>>8; + dev->dev_addr[4]=eprom_read(dev,MAC_ADR+2) & 0xff; + dev->dev_addr[5]=((eprom_read(dev,MAC_ADR+2) & 0xff00)>>8)+1; + + DMESG("Card MAC address is "MAC_FMT, MAC_ARG(dev->dev_addr)); + + for(i=1,j=0; i<6; i+=2,j++){ + + word = eprom_read(dev,EPROM_TXPW0 + j); + priv->chtxpwr[i]=word & 0xf; + priv->chtxpwr_ofdm[i]=(word & 0xf0)>>4; + priv->chtxpwr[i+1]=(word & 0xf00)>>8; + priv->chtxpwr_ofdm[i+1]=(word & 0xf000)>>12; + } + + for(i=1,j=0; i<4; i+=2,j++){ + + word = eprom_read(dev,EPROM_TXPW1 + j); + priv->chtxpwr[i+6]=word & 0xf; + priv->chtxpwr_ofdm[i+6]=(word & 0xf0)>>4; + priv->chtxpwr[i+6+1]=(word & 0xf00)>>8; + priv->chtxpwr_ofdm[i+6+1]=(word & 0xf000)>>12; + } + if (priv->card_8187 == NIC_8187){ + for(i=1,j=0; i<4; i+=2,j++){ + word = eprom_read(dev,EPROM_TXPW2 + j); + priv->chtxpwr[i+6+4]=word & 0xf; + priv->chtxpwr_ofdm[i+6+4]=(word & 0xf0)>>4; + priv->chtxpwr[i+6+4+1]=(word & 0xf00)>>8; + priv->chtxpwr_ofdm[i+6+4+1]=(word & 0xf000)>>12; + } + } else{ + word = eprom_read(dev, 0x1B) & 0xff; //channel 11; + priv->chtxpwr[11]=word & 0xf; + priv->chtxpwr_ofdm[11] = (word & 0xf0)>>4; + + word = eprom_read(dev, 0xA) & 0xff; //channel 12; + priv->chtxpwr[12]=word & 0xf; + priv->chtxpwr_ofdm[12] = (word & 0xf0)>>4; + + word = eprom_read(dev, 0x1c) ; //channel 13 ,14; + priv->chtxpwr[13]=word & 0xf; + priv->chtxpwr_ofdm[13] = (word & 0xf0)>>4; + priv->chtxpwr[14]=(word & 0xf00)>>8; + priv->chtxpwr_ofdm[14] = (word & 0xf000)>>12; + } + + word = eprom_read(dev,EPROM_TXPW_BASE); + priv->cck_txpwr_base = word & 0xf; + priv->ofdm_txpwr_base = (word>>4) & 0xf; + + //DMESG("PAPE from CONFIG2: %x",read_nic_byte(dev,CONFIG2)&0x7); + +#ifdef SW_ANTE_DIVERSITY + rtl8187_antenna_diversity_read(dev); +#endif + + if(rtl8187_usb_initendpoints(dev)!=0){ + DMESG("Endopoints initialization failed"); + return -ENOMEM; + } +#ifdef LED + InitSwLeds(dev); +#endif +#ifdef DEBUG_EPROM + dump_eprom(dev); +#endif + return 0; + +} + +void rtl8185_rf_pins_enable(struct net_device *dev) +{ +/* u16 tmp; + tmp = read_nic_word(dev, RFPinsEnable);*/ + write_nic_word(dev, RFPinsEnable, 0x1ff7);// | tmp); +} + + +void rtl8185_set_anaparam2(struct net_device *dev, u32 a) +{ + u8 conf3; + + rtl8180_set_mode(dev, EPROM_CMD_CONFIG); + + conf3 = read_nic_byte(dev, CONFIG3); + write_nic_byte(dev, CONFIG3, conf3 | (1<> 24)); + write_nic_byte(dev, 0x7e, ((phyw & 0x00ff0000) >> 16)); + write_nic_byte(dev, 0x7d, ((phyw & 0x0000ff00) >> 8)); + write_nic_byte(dev, 0x7c, ((phyw & 0x000000ff) )); + + //read_nic_dword(dev, PHY_ADR); +#if 0 + for(i=0;i<10;i++){ + write_nic_dword(dev, PHY_ADR, 0xffffff7f & phyw); + phyr = read_nic_byte(dev, PHY_READ); + if(phyr == (data&0xff)) break; + + } +#endif + /* this is ok to fail when we write AGC table. check for AGC table might be + * done by masking with 0x7f instead of 0xff */ + //if(phyr != (data&0xff)) DMESGW("Phy write timeout %x %x %x", phyr, data, adr); + //msdelay(1);//CPU occupany is too high. LZM 31/10/2008 +} + +u8 rtl8187_read_phy(struct net_device *dev,u8 adr, u32 data) +{ + u32 phyw; + + adr &= ~0x80; + phyw= ((data<<8) | adr); + + + // Note that, we must write 0xff7c after 0x7d-0x7f to write BB register. + write_nic_byte(dev, 0x7f, ((phyw & 0xff000000) >> 24)); + write_nic_byte(dev, 0x7e, ((phyw & 0x00ff0000) >> 16)); + write_nic_byte(dev, 0x7d, ((phyw & 0x0000ff00) >> 8)); + write_nic_byte(dev, 0x7c, ((phyw & 0x000000ff) )); + + return(read_nic_byte(dev,0x7e)); + +} + +u8 read_phy_ofdm(struct net_device *dev, u8 adr) +{ + return(rtl8187_read_phy(dev, adr, 0x000000)); +} + +u8 read_phy_cck(struct net_device *dev, u8 adr) +{ + return(rtl8187_read_phy(dev, adr, 0x10000)); +} + +inline void write_phy_ofdm (struct net_device *dev, u8 adr, u32 data) +{ + data = data & 0xff; + rtl8187_write_phy(dev, adr, data); +} + + +void write_phy_cck (struct net_device *dev, u8 adr, u32 data) +{ + data = data & 0xff; + rtl8187_write_phy(dev, adr, data | 0x10000); +} +// +// Description: Change ZEBRA's power state. +// +// Assumption: This function must be executed in PASSIVE_LEVEL. +// +// 061214, by rcnjko. +// +//#define MAX_DOZE_WAITING_TIMES_87B 1000//500 +#define MAX_DOZE_WAITING_TIMES_87B_MOD 500 + +bool SetZebraRFPowerState8187B(struct net_device *dev,RT_RF_POWER_STATE eRFPowerState) +{ + struct r8180_priv *priv = ieee80211_priv(dev); + u8 btCR9346, btConfig3; + bool bResult = true; + int i; + u16 u2bTFPC = 0; + u8 u1bTmp; + + // Set EEM0 and EEM1 in 9346CR. + btCR9346 = read_nic_byte(dev, CR9346); + write_nic_byte(dev, CR9346, (btCR9346|0xC0) ); + // Set PARM_En in Config3. + btConfig3 = read_nic_byte(dev, CONFIG3); + write_nic_byte(dev, CONFIG3, (btConfig3|CONFIG3_PARM_En) ); + // BB and RF related operations: + switch(eRFPowerState) + { + case eRfOn: +//#ifdef CONFIG_RADIO_DEBUG + DMESG("Now Radio ON!"); +//#endif + write_nic_dword(dev, ANAPARAM, ANAPARM_ON); + write_nic_dword(dev, ANAPARAM2, ANAPARM2_ON); + //write_nic_byte(dev, CONFIG4, (priv->RFProgType)); + + write_nic_byte(dev, 0x085, 0x24); // 061219, SD3 ED: for minicard CCK power leakage issue. + write_rtl8225(dev, 0x4, 0x9FF); + mdelay(1); + // + // We reset PLL to reduce power consumption about 30 mA. 2008.01.16. + // + { + u8 Reg62; + + write_nic_byte(dev, 0x61, 0x10); + Reg62 = read_nic_byte(dev, 0x62); + write_nic_byte(dev, 0x62, (Reg62 & (~BIT5)) ); + write_nic_byte(dev, 0x62, (Reg62 | BIT5) ); // Enable PLL. + } + + u1bTmp = read_nic_byte(dev, 0x24E); + write_nic_byte(dev, 0x24E, (u1bTmp & (~(BIT5|BIT6))) );// 070124 SD1 Alex: turn on CCK and OFDM. + break; + + case eRfSleep: +#ifdef CONFIG_RADIO_DEBUG + DMESG("Now Radio Sleep!"); +#endif + for(i = 0; i < MAX_DOZE_WAITING_TIMES_87B_MOD; i++) + { // Make sure TX FIFO is empty befor turn off RFE pwoer. + u2bTFPC = read_nic_word(dev, TFPC); + if(u2bTFPC == 0){ + printk("%d times TFPC: %d == 0 before doze...\n", (i+1), u2bTFPC); + break; + }else{ + printk("%d times TFPC: %d != 0 before doze!\n", (i+1), u2bTFPC); + udelay(10); + } + } + + if( i == MAX_DOZE_WAITING_TIMES_87B_MOD ){ + printk("\n\n\n SetZebraRFPowerState8187B(): %d times TFPC: %d != 0 !!!\n\n\n", MAX_DOZE_WAITING_TIMES_87B_MOD, u2bTFPC); + } + + u1bTmp = read_nic_byte(dev, 0x24E); + write_nic_byte(dev, 0x24E, (u1bTmp|BIT5|BIT6));// 070124 SD1 Alex: turn off CCK and OFDM. + + write_rtl8225(dev, 0x4, 0xDFF); // Turn off RF first to prevent BB lock up, suggested by PJ, 2006.03.03. + write_nic_byte(dev, 0x085, 0x04); // 061219, SD3 ED: for minicard CCK power leakage issue. + + //write_nic_byte(dev, CONFIG4, (priv->RFProgType|Config4_PowerOff)); + + write_nic_dword(dev, ANAPARAM, ANAPARM_OFF); + write_nic_dword(dev, ANAPARAM2, 0x72303f70); // 070126, by SD1 William. + break; + + case eRfOff: +//#ifdef CONFIG_RADIO_DEBUG + DMESG("Now Radio OFF!"); +//#endif + for(i = 0; i < MAX_DOZE_WAITING_TIMES_87B_MOD; i++) + { // Make sure TX FIFO is empty befor turn off RFE pwoer. + u2bTFPC = read_nic_word(dev, TFPC); + if(u2bTFPC == 0) { + //printk("%d times TFPC: %d == 0 before doze...\n", (i+1), u2bTFPC); + break; + }else{ + //printk("%d times TFPC: 0x%x != 0 before doze!\n", (i+1), u2bTFPC); + udelay(10); + } + } + + if( i == MAX_DOZE_WAITING_TIMES_87B_MOD){ + printk("\n\n\nSetZebraRFPowerState8187B(): %d times TFPC: 0x%x != 0 !!!\n\n\n", MAX_DOZE_WAITING_TIMES_87B_MOD, u2bTFPC); + } + + u1bTmp = read_nic_byte(dev, 0x24E); + write_nic_byte(dev, 0x24E, (u1bTmp|BIT5|BIT6));// 070124 SD1 Alex: turn off CCK and OFDM. + + write_rtl8225(dev, 0x4,0x1FF); // Turn off RF first to prevent BB lock up, suggested by PJ, 2006.03.03. + write_nic_byte(dev, 0x085, 0x04); // 061219, SD3 ED: for minicard CCK power leakage issue. + + //write_nic_byte(dev, CONFIG4, (priv->RFProgType|Config4_PowerOff)); + + write_nic_dword(dev, ANAPARAM, ANAPARM_OFF); + write_nic_dword(dev, ANAPARAM2, ANAPARM2_OFF); // 070301, SD1 William: to reduce RF off power consumption to 80 mA. + break; + + default: + bResult = false; + printk("SetZebraRFPowerState8187B(): unknow state to set: 0x%X!!!\n", eRFPowerState); + break; + } + + // Clear PARM_En in Config3. + btConfig3 &= ~(CONFIG3_PARM_En); + write_nic_byte(dev, CONFIG3, btConfig3); + // Clear EEM0 and EEM1 in 9346CR. + btCR9346 &= ~(0xC0); + write_nic_byte(dev, CR9346, btCR9346); + + if(bResult){ + // Update current RF state variable. + priv->eRFPowerState = eRFPowerState; + } + + return bResult; +} +//by amy for ps +// +// Description: Chang RF Power State. +// Note that, only MgntActSet_RF_State() is allowed to set HW_VAR_RF_STATE. +// +// Assumption:PASSIVE LEVEL. +// +bool SetRFPowerState(struct net_device *dev,RT_RF_POWER_STATE eRFPowerState) +{ + struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev); + bool bResult = false; + + //printk("---------> SetRFPowerState(): eRFPowerState(%d)\n", eRFPowerState); + if(eRFPowerState == priv->eRFPowerState) + { + //printk("<--------- SetRFPowerState(): discard the request for eRFPowerState(%d) is the same.\n", eRFPowerState); + return bResult; + } + + switch(priv->rf_chip) + { + case RF_ZEBRA2: + bResult = SetZebraRFPowerState8187B(dev, eRFPowerState); + break; + + default: + printk("SetRFPowerState8185(): unknown RFChipID: 0x%X!!!\n", priv->rf_chip); + break;; + } + //printk("<--------- SetRFPowerState(): bResult(%d)\n", bResult); + + return bResult; +} + +bool +MgntActSet_RF_State(struct net_device *dev,RT_RF_POWER_STATE StateToSet,u32 ChangeSource) +{ + struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev); + bool bActionAllowed = false; + bool bConnectBySSID = false; + RT_RF_POWER_STATE rtState; + u16 RFWaitCounter = 0; + unsigned long flag; + // printk("===>MgntActSet_RF_State(): StateToSet(%d), ChangeSource(0x%x)\n",StateToSet, ChangeSource); + // + // Prevent the race condition of RF state change. By Bruce, 2007-11-28. + // Only one thread can change the RF state at one time, and others should wait to be executed. + // +#if 1 + while(true) + { + //down(&priv->rf_state); + spin_lock_irqsave(&priv->rf_ps_lock,flag); + if(priv->RFChangeInProgress) + { + //up(&priv->rf_state); + //RT_TRACE(COMP_RF, DBG_LOUD, ("MgntActSet_RF_State(): RF Change in progress! Wait to set..StateToSet(%d).\n", StateToSet)); + spin_unlock_irqrestore(&priv->rf_ps_lock,flag); + // Set RF after the previous action is done. + while(priv->RFChangeInProgress) + { + RFWaitCounter ++; + //RT_TRACE(COMP_RF, DBG_LOUD, ("MgntActSet_RF_State(): Wait 1 ms (%d times)...\n", RFWaitCounter)); + udelay(1000); // 1 ms + + // Wait too long, return FALSE to avoid to be stuck here. + if(RFWaitCounter > 1000) // 1sec + { + DMESG("MgntActSet_RF_State(): Wait too long to set RF"); + // TODO: Reset RF state? + return false; + } + } + } + else + { + priv->RFChangeInProgress = true; +// up(&priv->rf_state); + spin_unlock_irqrestore(&priv->rf_ps_lock,flag); + break; + } + } +#endif + rtState = priv->eRFPowerState; + + switch(StateToSet) + { + case eRfOn: + // + // Turn On RF no matter the IPS setting because we need to update the RF state to Ndis under Vista, or + // the Windows does not allow the driver to perform site survey any more. By Bruce, 2007-10-02. + // + // leave last reasons and kick this reason till priv->RfOffReason = 0; + // if one reason turn radio off check if off->on reason is the same.if so turn, or reject it. + // if more than 1 reasons turn radio off we only turn on radio when all reasons turn on radio, + // so first turn on trys will reject till priv->RfOffReason = 0; + priv->RfOffReason &= (~ChangeSource); + + if(! priv->RfOffReason) + { + priv->RfOffReason = 0; + bActionAllowed = true; + + if(rtState == eRfOff && ChangeSource >=RF_CHANGE_BY_HW && !priv->bInHctTest) + { + bConnectBySSID = true; + } + } else { + ;//lzm must or TX_PENDING 12>MAX_TX_URB + //printk("Turn Radio On Reject because RfOffReason= 0x%x, ChangeSource=0x%X\n", priv->RfOffReason, ChangeSource); + } + break; + + case eRfOff: + // 070125, rcnjko: we always keep connected in AP mode. + if (priv->RfOffReason > RF_CHANGE_BY_IPS) + { + // + // 060808, Annie: + // Disconnect to current BSS when radio off. Asked by QuanTa. + // + + // + // Calling MgntDisconnect() instead of MgntActSet_802_11_DISASSOCIATE(), + // because we do NOT need to set ssid to dummy ones. + // Revised by Roger, 2007.12.04. + // +//by amy not supported + //MgntDisconnect( dev, disas_lv_ss ); + + // Clear content of bssDesc[] and bssDesc4Query[] to avoid reporting old bss to UI. + // 2007.05.28, by shien chang. + //PlatformZeroMemory( pMgntInfo->bssDesc, sizeof(RT_WLAN_BSS)*MAX_BSS_DESC ); + //pMgntInfo->NumBssDesc = 0; + //PlatformZeroMemory( pMgntInfo->bssDesc4Query, sizeof(RT_WLAN_BSS)*MAX_BSS_DESC ); + //pMgntInfo->NumBssDesc4Query = 0; + } + + + + priv->RfOffReason |= ChangeSource; + bActionAllowed = true; + //printk("Turn Radio Off RfOffReason= 0x%x, ChangeSource=0x%X\n", priv->RfOffReason, ChangeSource); + break; + + case eRfSleep: + priv->RfOffReason |= ChangeSource; + bActionAllowed = true; + break; + + default: + break; + } + + if(bActionAllowed) + { + // Config HW to the specified mode. + //printk("MgntActSet_RF_State(): Action is allowed.... StateToSet(%d), RfOffReason(%#X)\n", StateToSet, priv->RfOffReason); + SetRFPowerState(dev, StateToSet); + // Turn on RF. + if(StateToSet == eRfOn) + { + //HalEnableRx8185Dummy(dev); + if(bConnectBySSID) + { + // by amy not supported + //MgntActSet_802_11_SSID(Adapter, Adapter->MgntInfo.Ssid.Octet, Adapter->MgntInfo.Ssid.Length, TRUE ); + } + } + // Turn off RF. + else if(StateToSet == eRfOff) + { + //HalDisableRx8185Dummy(dev); + } + } + else + { + //printk("Action is rejected.... StateToSet(%d), ChangeSource(%#X), RfOffReason(%#X)\n", + // StateToSet, ChangeSource, priv->RfOffReason); + } + + // Release RF spinlock + //down(&priv->rf_state); + spin_lock_irqsave(&priv->rf_ps_lock,flag); + priv->RFChangeInProgress = false; + //up(&priv->rf_state); + spin_unlock_irqrestore(&priv->rf_ps_lock,flag); + return bActionAllowed; +} +//by amy for ps + +void rtl8180_adapter_start(struct net_device *dev) +{ + struct r8180_priv *priv = ieee80211_priv(dev); +// struct ieee80211_device *ieee = priv->ieee80211; +// u8 InitWirelessMode; +// u8 SupportedWirelessMode; +// bool bInvalidWirelessMode = false; + + + if(NIC_8187 == priv->card_8187) { + //rtl8180_rtx_disable(dev); + rtl8180_reset(dev); + + write_nic_byte(dev,0x85,0); + write_nic_byte(dev,0x91,0); + + /* light blink! */ + write_nic_byte(dev,0x85,4); + write_nic_byte(dev,0x91,1); + write_nic_byte(dev,0x90,0); + + //by lizhaoming for LED POWR ON + //LedControl8187(dev, LED_CTL_POWER_ON); + + /* + write_nic_byte(dev, CR9346, 0xC0); + //LED TYPE + write_nic_byte(dev, CONFIG1,((read_nic_byte(dev, CONFIG1)&0x3f)|0x80)); //turn on bit 5:Clkrun_mode + write_nic_byte(dev, CR9346, 0x0); // disable config register write + */ + priv->irq_mask = 0xffff; + /* + priv->dma_poll_mask = 0; + priv->dma_poll_mask|= (1<dev_addr)[0]); + write_nic_word(dev, MAC4, ((u32*)dev->dev_addr)[1] & 0xffff ); + + rtl8180_set_mode(dev, EPROM_CMD_NORMAL); + rtl8180_update_msr(dev); + + rtl8180_set_mode(dev, EPROM_CMD_CONFIG); + + write_nic_word(dev,0xf4,0xffff); + write_nic_byte(dev, + CONFIG1, (read_nic_byte(dev,CONFIG1) & 0x3f) | 0x80); + + rtl8180_set_mode(dev,EPROM_CMD_NORMAL); + + write_nic_dword(dev,INT_TIMEOUT,0); + +#ifdef DEBUG_REGISTERS + rtl8180_dump_reg(dev); +#endif + + + write_nic_byte(dev, WPA_CONFIG, 0); + + write_nic_byte(dev, RATE_FALLBACK, 0x81); + rtl8187_set_rate(dev); + + priv->rf_init(dev); + + if(priv->rf_set_sens != NULL) { + priv->rf_set_sens(dev,priv->sens); + } + + write_nic_word(dev,0x5e,1); + //mdelay(1); + write_nic_word(dev,0xfe,0x10); + // mdelay(1); + write_nic_byte(dev, TALLY_SEL, 0x80);//Set NQ retry count + write_nic_byte(dev, 0xff, 0x60); + write_nic_word(dev,0x5e,0); + + rtl8180_irq_enable(dev); + } else { + /** + * IO part migrated from Windows Driver. + */ + priv->irq_mask = 0xffff; + // Enable Config3.PARAM_En. + write_nic_byte(dev, CR9346, 0xC0); + + write_nic_byte(dev, CONFIG3, (read_nic_byte(dev, CONFIG3)| CONFIG3_PARM_En|CONFIG3_GNTSel)); + // Turn on Analog power. + // setup A/D D/A parameter for 8185 b2 + // Asked for by William, otherwise, MAC 3-wire can't work, 2006.06.27, by rcnjko. + write_nic_dword(dev, ANA_PARAM2, ANAPARM2_ASIC_ON); + write_nic_dword(dev, ANA_PARAM, ANAPARM_ASIC_ON); + write_nic_byte(dev, ANA_PARAM3, 0x00); + + //by lizhaoming for LED POWR ON + //LedControl8187(dev, LED_CTL_POWER_ON); + + {//added for reset PLL + u8 bReg62; + write_nic_byte(dev, 0x61, 0x10); + bReg62 = read_nic_byte(dev, 0x62); + write_nic_byte(dev, 0x62, bReg62&(~(0x1<<5))); + write_nic_byte(dev, 0x62, bReg62|(0x1<<5)); + } + write_nic_byte(dev, CONFIG3, (read_nic_byte(dev, CONFIG3)&(~CONFIG3_PARM_En))); + write_nic_byte(dev, CR9346, 0x00); + + //rtl8180_rtx_disable(dev); + rtl8180_reset(dev); + write_nic_byte(dev, CR9346, 0xc0); // enable config register write + priv->rf_init(dev); + // Enable tx/rx + + write_nic_byte(dev, CMD, (CR_RE|CR_TE));// Using HW_VAR_COMMAND instead of writing CMDR directly. Rewrited by Annie, 2006-04-07. + + //add this is for 8187B Rx stall problem + + rtl8180_irq_enable(dev); + + write_nic_byte_E(dev, 0x41, 0xF4); + write_nic_byte_E(dev, 0x40, 0x00); + write_nic_byte_E(dev, 0x42, 0x00); + write_nic_byte_E(dev, 0x42, 0x01); + write_nic_byte_E(dev, 0x40, 0x0F); + write_nic_byte_E(dev, 0x42, 0x00); + write_nic_byte_E(dev, 0x42, 0x01); + + // 8187B demo board MAC and AFE power saving parameters from SD1 William, 2006.07.20. + // Parameter revised by SD1 William, 2006.08.21: + // 373h -> 0x4F // Original: 0x0F + // 377h -> 0x59 // Original: 0x4F + // Victor 2006/8/21: ¬Ù¹q°Ñ¼Æ«Øijµ¥SD3 °ª§C·Å and cable link test OK¤~¥¿¦¡ release,¤£«Øij¤Ó§Ö + // 2006/9/5, Victor & ED: it is OK to use. + //if(pHalData->RegBoardType == BT_DEMO_BOARD) + //{ + // AFE. + // + // Revise the content of Reg0x372, 0x374, 0x378 and 0x37a to fix unusual electronic current + // while CTS-To-Self occurs, by DZ's request. + // Modified by Roger, 2007.06.22. + // + write_nic_byte(dev, 0x0DB, (read_nic_byte(dev, 0x0DB)|(BIT2))); + write_nic_word(dev, 0x372, 0x59FA); // 0x4FFA-> 0x59FA. + write_nic_word(dev, 0x374, 0x59D2); // 0x4FD2-> 0x59D2. + write_nic_word(dev, 0x376, 0x59D2); + write_nic_word(dev, 0x378, 0x19FA); // 0x0FFA-> 0x19FA. + write_nic_word(dev, 0x37A, 0x19FA); // 0x0FFA-> 0x19FA. + write_nic_word(dev, 0x37C, 0x00D0); + + write_nic_byte(dev, 0x061, 0x00); + + // MAC. + write_nic_byte(dev, 0x180, 0x0F); + write_nic_byte(dev, 0x183, 0x03); + // 061218, lanhsin: for victorh request + write_nic_byte(dev, 0x0DA, 0x10); + //} + + // + // 061213, rcnjko: + // Set MAC.0x24D to 0x00 to prevent cts-to-self Tx/Rx stall symptom. + // If we set MAC 0x24D to 0x08, OFDM and CCK will turn off + // if not in use, and there is a bug about this action when + // we try to send CCK CTS and OFDM data together. + // + //PlatformEFIOWrite1Byte(Adapter, 0x24D, 0x00); + // 061218, lanhsin: for victorh request + write_nic_byte(dev, 0x24D, 0x08); + + // + // 061215, rcnjko: + // Follow SD3 RTL8185B_87B_MacPhy_Register.doc v0.4. + // + write_nic_dword(dev, HSSI_PARA, 0x0600321B); + // + // 061226, rcnjko: + // Babble found in HCT 2c_simultaneous test, server with 87B might + // receive a packet size about 2xxx bytes. + // So, we restrict RMS to 2048 (0x800), while as IC default value is 0xC00. + // + write_nic_word(dev, RMS, 0x0800); + + /*****20070321 Resolve HW page bug on system logo test + u8 faketemp=read_nic_byte(dev, 0x50);*/ + } +} + +/* this configures registers for beacon tx and enables it via + * rtl8180_beacon_tx_enable(). rtl8180_beacon_tx_disable() might + * be used to stop beacon transmission + */ +#if 0 +void rtl8180_start_tx_beacon(struct net_device *dev) +{ + int i; + struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev); + u16 word; + DMESG("Enabling beacon TX"); + //write_nic_byte(dev, 0x42,0xe6);// TCR + //rtl8180_init_beacon(dev); + //set_nic_txring(dev); +// rtl8180_prepare_beacon(dev); + rtl8180_irq_disable(dev); +// rtl8180_beacon_tx_enable(dev); + rtl8180_set_mode(dev,EPROM_CMD_CONFIG); + //write_nic_byte(dev,0x9d,0x20); //DMA Poll + //write_nic_word(dev,0x7a,0); + //write_nic_word(dev,0x7a,0x8000); + + + word = read_nic_word(dev, BcnItv); + word &= ~BcnItv_BcnItv; // clear Bcn_Itv + write_nic_word(dev, BcnItv, word); + + write_nic_word(dev, AtimWnd, + read_nic_word(dev, AtimWnd) &~ AtimWnd_AtimWnd); + + word = read_nic_word(dev, BintrItv); + word &= ~BintrItv_BintrItv; + + //word |= priv->ieee80211->beacon_interval * + // ((priv->txbeaconcount > 1)?(priv->txbeaconcount-1):1); + // FIXME:FIXME check if correct ^^ worked with 0x3e8; + + write_nic_word(dev, BintrItv, word); + + //write_nic_word(dev,0x2e,0xe002); + //write_nic_dword(dev,0x30,0xb8c7832e); + for(i=0; iieee80211->beacon_cell_ssid[i]); + +// rtl8180_update_msr(dev); + + + //write_nic_byte(dev,CONFIG4,3); /* !!!!!!!!!! */ + + rtl8180_set_mode(dev, EPROM_CMD_NORMAL); + + rtl8180_irq_enable(dev); + + /* VV !!!!!!!!!! VV*/ + /* + rtl8180_set_mode(dev,EPROM_CMD_CONFIG); + write_nic_byte(dev,0x9d,0x00); + rtl8180_set_mode(dev,EPROM_CMD_NORMAL); +*/ +} +#endif +/*************************************************************************** + -------------------------------NET STUFF--------------------------- +***************************************************************************/ +static struct net_device_stats *rtl8180_stats(struct net_device *dev) +{ + struct r8180_priv *priv = ieee80211_priv(dev); + + return &priv->ieee80211->stats; +} + +int _rtl8180_up(struct net_device *dev) +{ + struct r8180_priv *priv = ieee80211_priv(dev); + //int i; + + priv->driver_upping = 1; + priv->up=1; + +#ifdef LED + if(priv->ieee80211->bHwRadioOff == false) + priv->ieee80211->ieee80211_led_contorl(dev,LED_CTL_POWER_ON); +#endif + MgntActSet_RF_State(dev, eRfOn, RF_CHANGE_BY_SW); + + rtl8180_adapter_start(dev); + rtl8180_rx_enable(dev); + rtl8180_tx_enable(dev); +//by amy for rate adaptive + timer_rate_adaptive((unsigned long)dev); +//by amy for rate adaptive + +#ifdef SW_ANTE_DIVERSITY + if(priv->bSwAntennaDiverity){ + //DMESG("SW Antenna Diversity Enable!"); + SwAntennaDiversityTimerCallback(dev); + } +#endif +#ifdef POLLING_METHOD_FOR_RADIO + if(priv->polling_timer_on == 0){//add for S3/S4 + gpio_change_polling((unsigned long)dev); + } +#endif + + ieee80211_softmac_start_protocol(priv->ieee80211); + +//by amy for ps + watch_dog_adaptive((unsigned long)dev); +//by amy for ps + + ieee80211_reset_queue(priv->ieee80211); + if(!netif_queue_stopped(dev)) + netif_start_queue(dev); + else + netif_wake_queue(dev); + +#ifndef CONFIG_SOFT_BEACON + if(NIC_8187B == priv->card_8187) + rtl8187_rx_manage_initiate(dev); +#endif + +#ifdef _RTL8187_EXT_PATCH_ + if(priv->mshobj && priv->mshobj->ext_patch_rtl8180_up ) + priv->mshobj->ext_patch_rtl8180_up(priv->mshobj); +#endif + + + priv->driver_upping = 0; + DMESG("rtl8187_open process complete"); + return 0; +} + + +int rtl8180_open(struct net_device *dev) +{ + struct r8180_priv *priv = ieee80211_priv(dev); + int ret; +//changed by lizhaoming for power on/off + if(priv->ieee80211->bHwRadioOff == false){ + DMESG("rtl8187_open process "); + down(&priv->wx_sem); + ret = rtl8180_up(dev); + up(&priv->wx_sem); + return ret; + }else{ + DMESG("rtl8187_open process failed because radio off"); + return -1; + } + +} + + +int rtl8180_up(struct net_device *dev) +{ + struct r8180_priv *priv = ieee80211_priv(dev); + + if (priv->up == 1) return -1; + + return _rtl8180_up(dev); +} + + +int rtl8180_close(struct net_device *dev) +{ + struct r8180_priv *priv = ieee80211_priv(dev); + int ret; + + if (priv->up == 0) return -1; + + down(&priv->wx_sem); + + //DMESG("rtl8187_close process"); + ret = rtl8180_down(dev); +#ifdef LED + priv->ieee80211->ieee80211_led_contorl(dev,LED_CTL_POWER_OFF); +#endif + up(&priv->wx_sem); + + return ret; + +} + +int rtl8180_down(struct net_device *dev) +{ + struct r8180_priv *priv = ieee80211_priv(dev); + + if (priv->up == 0) return -1; + + priv->up=0; + +/* FIXME */ + if (!netif_queue_stopped(dev)) + netif_stop_queue(dev); + + DMESG("rtl8180_down process"); + rtl8180_rtx_disable(dev); + rtl8180_irq_disable(dev); +//by amy for rate adaptive + del_timer_sync(&priv->rateadapter_timer); + cancel_delayed_work(&priv->ieee80211->rate_adapter_wq); +//by amy for rate adaptive + del_timer_sync(&priv->watch_dog_timer); + cancel_delayed_work(&priv->ieee80211->watch_dog_wq); + cancel_delayed_work(&priv->ieee80211->hw_dig_wq); + cancel_delayed_work(&priv->ieee80211->tx_pw_wq); + +#ifdef SW_ANTE_DIVERSITY + del_timer_sync(&priv->SwAntennaDiversityTimer); + cancel_delayed_work(&priv->ieee80211->SwAntennaWorkItem); +#endif + + ieee80211_softmac_stop_protocol(priv->ieee80211); + MgntActSet_RF_State(dev, eRfOff, RF_CHANGE_BY_SW); + //amy,081212 + memset(&(priv->ieee80211->current_network),0,sizeof(struct ieee80211_network)); + return 0; +} + +bool SetZebraRFPowerState8187B(struct net_device *dev,RT_RF_POWER_STATE eRFPowerState); + +void rtl8180_commit(struct net_device *dev) +{ + struct r8180_priv *priv = ieee80211_priv(dev); + int i; + + if (priv->up == 0) return ; + printk("==========>%s()\n", __FUNCTION__); + + /* FIXME */ + if (!netif_queue_stopped(dev)) + netif_stop_queue(dev); + +//by amy for rate adaptive + del_timer_sync(&priv->rateadapter_timer); + cancel_delayed_work(&priv->ieee80211->rate_adapter_wq); +//by amy for rate adaptive + del_timer_sync(&priv->watch_dog_timer); + cancel_delayed_work(&priv->ieee80211->watch_dog_wq); + cancel_delayed_work(&priv->ieee80211->hw_dig_wq); + cancel_delayed_work(&priv->ieee80211->tx_pw_wq); + +#ifdef SW_ANTE_DIVERSITY + del_timer_sync(&priv->SwAntennaDiversityTimer); + cancel_delayed_work(&priv->ieee80211->SwAntennaWorkItem); +#endif + ieee80211_softmac_stop_protocol(priv->ieee80211); + +#if 0 + if(priv->ieee80211->bHwRadioOff == false){ + MgntActSet_RF_State(dev, eRfOff, RF_CHANGE_BY_HW); + mdelay(10); + MgntActSet_RF_State(dev, eRfOn, RF_CHANGE_BY_HW); + } +#endif + + rtl8180_irq_disable(dev); + rtl8180_rtx_disable(dev); + + //test pending bug, john 20070815 + //initialize tx_pending + for(i=0;i<0x10;i++) atomic_set(&(priv->tx_pending[i]), 0); + + _rtl8180_up(dev); + priv->commit = 0; +} + +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)) +void rtl8180_restart(struct work_struct *work) +{ + struct r8180_priv *priv = container_of(work, struct r8180_priv, reset_wq); + struct ieee80211_device* ieee = priv->ieee80211;//for commit crash + struct net_device *dev = ieee->dev;//for commit crash +#else +void rtl8180_restart(struct net_device *dev) +{ + + struct r8180_priv *priv = ieee80211_priv(dev); +#endif + + down(&priv->wx_sem); + + rtl8180_commit(dev); + + up(&priv->wx_sem); +} + +static void r8180_set_multicast(struct net_device *dev) +{ + struct r8180_priv *priv = ieee80211_priv(dev); + short promisc; + + //down(&priv->wx_sem); + + /* FIXME FIXME */ + + promisc = (dev->flags & IFF_PROMISC) ? 1:0; + + if (promisc != priv->promisc) + // rtl8180_commit(dev); + + priv->promisc = promisc; + + //schedule_work(&priv->reset_wq); + //up(&priv->wx_sem); +} + + +int r8180_set_mac_adr(struct net_device *dev, void *mac) +{ + struct r8180_priv *priv = ieee80211_priv(dev); + struct sockaddr *addr = mac; + + down(&priv->wx_sem); + + memcpy(dev->dev_addr, addr->sa_data, ETH_ALEN); + +#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)) + schedule_work(&priv->reset_wq); +#else + schedule_task(&priv->reset_wq); +#endif + up(&priv->wx_sem); + + return 0; +} + +struct ipw_param { + u32 cmd; + u8 sta_addr[ETH_ALEN]; + union { + struct { + u8 name; + u32 value; + } wpa_param; + struct { + u32 len; + u8 reserved[32]; + u8 data[0]; + } wpa_ie; + struct{ + u32 command; + u32 reason_code; + } mlme; + struct { + u8 alg[16]; + u8 set_tx; + u32 err; + u8 idx; + u8 seq[8]; + u16 key_len; + u8 key[0]; + } crypt; + + } u; +}; + + +/* based on ipw2200 driver */ +int rtl8180_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) +{ + struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev); + struct iwreq *wrq = (struct iwreq *)rq; + int ret=-1; + +#ifdef JOHN_TKIP + u8 broadcast_addr[6] = {0xff,0xff,0xff,0xff,0xff,0xff}; + + struct ieee80211_device *ieee = priv->ieee80211; + struct ipw_param *ipw = (struct ipw_param *)wrq->u.data.pointer; + u32 key[4]; + +#endif + +#ifdef _RTL8187_EXT_PATCH_ + if(priv->mshobj && (priv->ieee80211->iw_mode == priv->ieee80211->iw_ext_mode) && priv->mshobj->ext_patch_rtl8180_ioctl) + { + // DO NOT put the belowing function in critical section, due to it uses "spin lock" + if((ret = priv->mshobj->ext_patch_rtl8180_ioctl(dev, rq, cmd)) != -EOPNOTSUPP) + return ret; + } +#endif + + down(&priv->wx_sem); + + switch (cmd) { + case RTL_IOCTL_WPA_SUPPLICANT: +#ifdef JOHN_TKIP + +//the following code is specified for ipw driver in wpa_supplicant + if( ((u32*)wrq->u.data.pointer)[0]==3 ){ + + + if( ((u32*)wrq->u.data.pointer)[7] && + ( ((u32*)wrq->u.data.pointer)[3]==0x504d4343 || + ((u32*)wrq->u.data.pointer)[3]==0x50494b54 )) {//50494b54 tkip and 504d4343 ccmp + + //enable HW security of TKIP and CCMP + write_nic_byte(dev, WPA_CONFIG, SCR_TxSecEnable | SCR_RxSecEnable ); + + //copy key from wpa_supplicant ioctl info + key[0] = ((u32*)wrq->u.data.pointer)[12]; + key[1] = ((u32*)wrq->u.data.pointer)[13]; + key[2] = ((u32*)wrq->u.data.pointer)[14]; + key[3] = ((u32*)wrq->u.data.pointer)[15]; + switch (ieee->pairwise_key_type){ + case KEY_TYPE_TKIP: + setKey( dev, + 0, //EntryNo + ipw->u.crypt.idx, //KeyIndex + KEY_TYPE_TKIP, //KeyType + (u8*)ieee->ap_mac_addr, //MacAddr + 0, //DefaultKey + key); //KeyContent + break; + + case KEY_TYPE_CCMP: + setKey( dev, + 0, //EntryNo + ipw->u.crypt.idx, //KeyIndex + KEY_TYPE_CCMP, //KeyType + (u8*)ieee->ap_mac_addr, //MacAddr + 0, //DefaultKey + key); //KeyContent + break +; + default: + printk("error on key_type: %d\n", ieee->pairwise_key_type); + break; + } + } + + //group key for broadcast + if( ((u32*)wrq->u.data.pointer)[9] ) { + + key[0] = ((u32*)wrq->u.data.pointer)[12]; + key[1] = ((u32*)wrq->u.data.pointer)[13]; + key[2] = ((u32*)wrq->u.data.pointer)[14]; + key[3] = ((u32*)wrq->u.data.pointer)[15]; + + if( ((u32*)wrq->u.data.pointer)[3]==0x50494b54 ){//50494b54 is the ASCII code of TKIP in reversed order + setKey( dev, + 1, //EntryNo + ipw->u.crypt.idx,//KeyIndex + KEY_TYPE_TKIP, //KeyType + broadcast_addr, //MacAddr + 0, //DefaultKey + key); //KeyContent + } + else if( ((u32*)wrq->u.data.pointer)[3]==0x504d4343 ){//CCMP + setKey( dev, + 1, //EntryNo + ipw->u.crypt.idx,//KeyIndex + KEY_TYPE_CCMP, //KeyType + broadcast_addr, //MacAddr + 0, //DefaultKey + key); //KeyContent + } + else if( ((u32*)wrq->u.data.pointer)[3]==0x656e6f6e ){//none + //do nothing + } + else if( ((u32*)wrq->u.data.pointer)[3]==0x504557 ){//WEP + setKey( dev, + 1, //EntryNo + ipw->u.crypt.idx,//KeyIndex + KEY_TYPE_WEP40, //KeyType + broadcast_addr, //MacAddr + 0, //DefaultKey + key); //KeyContent + } + else printk("undefine group key type: %8x\n", ((u32*)wrq->u.data.pointer)[3]); + } + + } +#endif /*JOHN_TKIP*/ + + +#ifdef JOHN_HWSEC_DEBUG + { + int i; + //john's test 0711 + printk("@@ wrq->u pointer = "); + for(i=0;iu.data.length;i++){ + if(i%10==0) printk("\n"); + printk( "%8x|", ((u32*)wrq->u.data.pointer)[i] ); + } + printk("\n"); + } +#endif /*JOHN_HWSEC_DEBUG*/ + ret = ieee80211_wpa_supplicant_ioctl(priv->ieee80211, &wrq->u.data); + break; + + default: + ret = -EOPNOTSUPP; + break; + } + + up(&priv->wx_sem); + + return ret; +} + + +struct tx_desc { + +#ifdef _LINUX_BYTEORDER_LITTLE_ENDIAN_H + + +//dword 0 +unsigned int tpktsize:12; +unsigned int rsvd0:3; +unsigned int no_encrypt:1; +unsigned int splcp:1; +unsigned int morefrag:1; +unsigned int ctsen:1; +unsigned int rtsrate:4; +unsigned int rtsen:1; +unsigned int txrate:4; +unsigned int last:1; +unsigned int first:1; +unsigned int dmaok:1; +unsigned int own:1; + +//dword 1 +unsigned short rtsdur; +unsigned short length:15; +unsigned short l_ext:1; + +//dword 2 +unsigned int bufaddr; + + +//dword 3 +unsigned short rxlen:12; +unsigned short rsvd1:3; +unsigned short miccal:1; +unsigned short dur; + +//dword 4 +unsigned int nextdescaddr; + +//dword 5 +unsigned char rtsagc; +unsigned char retrylimit; +unsigned short rtdb:1; +unsigned short noacm:1; +unsigned short pifs:1; +unsigned short rsvd2:4; +unsigned short rtsratefallback:4; +unsigned short ratefallback:5; + +//dword 6 +unsigned short delaybound; +unsigned short rsvd3:4; +unsigned short agc:8; +unsigned short antenna:1; +unsigned short spc:2; +unsigned short rsvd4:1; + +//dword 7 +unsigned char len_adjust:2; +unsigned char rsvd5:1; +unsigned char tpcdesen:1; +unsigned char tpcpolarity:2; +unsigned char tpcen:1; +unsigned char pten:1; + +unsigned char bckey:6; +unsigned char enbckey:1; +unsigned char enpmpd:1; +unsigned short fragqsz; + + +#else + +#error "please modify tx_desc to your own\n" + +#endif + + +} __attribute__((packed)); + +struct rx_desc_rtl8187b { + +#ifdef _LINUX_BYTEORDER_LITTLE_ENDIAN_H + +//dword 0 +unsigned int rxlen:12; +unsigned int icv:1; +unsigned int crc32:1; +unsigned int pwrmgt:1; +unsigned int res:1; +unsigned int bar:1; +unsigned int pam:1; +unsigned int mar:1; +unsigned int qos:1; +unsigned int rxrate:4; +unsigned int trsw:1; +unsigned int splcp:1; +unsigned int fovf:1; +unsigned int dmafail:1; +unsigned int last:1; +unsigned int first:1; +unsigned int eor:1; +unsigned int own:1; + + +//dword 1 +unsigned int tsftl; + + +//dword 2 +unsigned int tsfth; + + +//dword 3 +unsigned char sq; +unsigned char rssi:7; +unsigned char antenna:1; + +unsigned char agc; +unsigned char decrypted:1; +unsigned char wakeup:1; +unsigned char shift:1; +unsigned char rsvd0:5; + +//dword 4 +unsigned int num_mcsi:4; +unsigned int snr_long2end:6; +unsigned int cfo_bias:6; + +int pwdb_g12:8; +unsigned int fot:8; + + + + +#else + +#error "please modify tx_desc to your own\n" + +#endif + +}__attribute__((packed)); + + + +struct rx_desc_rtl8187 { + +#ifdef _LINUX_BYTEORDER_LITTLE_ENDIAN_H + +//dword 0 +unsigned int rxlen:12; +unsigned int icv:1; +unsigned int crc32:1; +unsigned int pwrmgt:1; +unsigned int res:1; +unsigned int bar:1; +unsigned int pam:1; +unsigned int mar:1; +unsigned int qos:1; +unsigned int rxrate:4; +unsigned int trsw:1; +unsigned int splcp:1; +unsigned int fovf:1; +unsigned int dmafail:1; +unsigned int last:1; +unsigned int first:1; +unsigned int eor:1; +unsigned int own:1; + +//dword 1 +unsigned char sq; +unsigned char rssi:7; +unsigned char antenna:1; + +unsigned char agc; +unsigned char decrypted:1; +unsigned char wakeup:1; +unsigned char shift:1; +unsigned char rsvd0:5; + +//dword 2 +unsigned int tsftl; + +//dword 3 +unsigned int tsfth; + + + +#else + +#error "please modify tx_desc to your own\n" + +#endif + + +}__attribute__((packed)); + + + +union rx_desc { + +struct rx_desc_rtl8187b desc_87b; +struct rx_desc_rtl8187 desc_87; + +}__attribute__((packed)); + +// +// Description: +// Perform signal smoothing for dynamic mechanism. +// This is different with PerformSignalSmoothing8187 in smoothing fomula. +// No dramatic adjustion is apply because dynamic mechanism need some degree +// of correctness. +// 2007.01.23, by shien chang. +// +void PerformUndecoratedSignalSmoothing8187(struct net_device *dev, struct ieee80211_rx_stats *stats) +{ + struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev); + bool bCckRate = rtl8180_IsWirelessBMode(rtl8180_rate2rate(stats->rate)); + + if(NIC_8187 == priv->card_8187) { + if(priv->UndecoratedSmoothedSS >= 0) { + priv->UndecoratedSmoothedSS = ((priv->UndecoratedSmoothedSS * 50) + (stats->signalstrength * 11)) / 60; + }else{ + priv->UndecoratedSmoothedSS = stats->signalstrength; + } + } else { + // Determin the current packet is CCK rate, by Bruce, 2007-04-12. + priv->bCurCCKPkt = bCckRate; + + // Tesing for SD3 DZ, by Bruce, 2007-04-11. + if(priv->UndecoratedSmoothedSS >= 0) { + priv->UndecoratedSmoothedSS = ((priv->UndecoratedSmoothedSS * 5) + (stats->signalstrength * 10)) / 6; + }else{ + priv->UndecoratedSmoothedSS = stats->signalstrength * 10; + } + + // + // Bacause the AGC parameter is not exactly correct under high power (AGC saturation), we need to record the RSSI value to be + // referenced by DoRxHighPower. It is not necessary to record this value when this packet is sent by OFDM rate. + // Advised by SD3 DZ, by Bruce, 2007-04-12. + // + if(bCckRate){ + priv->CurCCKRSSI = stats->signal; + }else{ + priv->CurCCKRSSI = 0; + } + } + //printk("Sommthing SignalSterngth (%d) => UndecoratedSmoothedSS (%d)\n", stats->signalstrength, priv->UndecoratedSmoothedSS); +} + +#ifdef THOMAS_SKB +void rtl8180_irq_rx_tasklet(struct r8180_priv *priv) +{ + int status,len,flen; + +#ifdef SW_ANTE_DIVERSITY + u8 Antenna = 0; +#endif + u32 SignalStrength = 0; + u32 quality = 0; + bool bCckRate = false; + char RX_PWDB = 0; + long RecvSignalPower=0; + struct sk_buff *skb; + struct sk_buff *skb2;//skb for check out of memory + union rx_desc *desc; + //struct urb *rx_urb = priv->rxurb_task; + struct ieee80211_hdr *hdr;//by amy + u16 fc,type; + u8 bHwError=0,bCRC=0,bICV=0; + long SignalStrengthIndex = 0; + struct ieee80211_rx_stats stats = { + .signal = 0, + .noise = -98, + .rate = 0, + //.mac_time = jiffies, + .freq = IEEE80211_24GHZ_BAND, + }; + + int *prx_inx=&priv->rx_inx; + struct urb *rx_urb=priv->rx_urb[*prx_inx]; //changed by jackson + struct net_device *dev = (struct net_device*)rx_urb->context; + //DMESG("=====>RX %x ",rx_urb->status); + + skb = priv->pp_rxskb[*prx_inx]; + status = rx_urb->status; + skb2 = dev_alloc_skb(RX_URB_SIZE); + + if (skb2 == NULL){ + printk(KERN_ALERT "No Skb For RX!/n"); + //rx_urb->transfer_buffer = skb->data; + //priv->pp_rxskb[*prx_inx] = skb; + } else { + + if(status == 0) + { + if(NIC_8187B == priv->card_8187) + { + stats.nic_type = NIC_8187B; + len = rx_urb->actual_length; + len -= sizeof (struct rx_desc_rtl8187b); + desc = (union rx_desc *)(rx_urb->transfer_buffer + len); + flen = desc->desc_87b.rxlen ; + + if( flen <= rx_urb->actual_length){ +#if 1 +#ifdef SW_ANTE_DIVERSITY + Antenna = desc->desc_87b.antenna; +#endif + stats.mac_time[0] = desc->desc_87b.tsftl; + stats.mac_time[1] = desc->desc_87b.tsfth; + + stats.signal = desc->desc_87b.rssi; + //stats.noise = desc->desc_87b.sq; + quality = desc->desc_87b.sq; + stats.rate = desc->desc_87b.rxrate; + bCckRate = rtl8180_IsWirelessBMode(rtl8180_rate2rate(stats.rate)); + + if(!bCckRate) { // OFDM rate. + if(desc->desc_87b.pwdb_g12 < -106) + SignalStrength = 0; + else + SignalStrength = desc->desc_87b.pwdb_g12 + 106; + RX_PWDB = (desc->desc_87b.pwdb_g12)/2 -42; + } else { // CCK rate. + if(desc->desc_87b.agc> 174) + SignalStrength = 0; + else + SignalStrength = 174 - desc->desc_87b.agc; + RX_PWDB = ((desc->desc_87b.agc)/2)*(-1) - 8; + } + + //lzm mod 081028 based on windows driver + //compensate SignalStrength when switch TR to SW controled + if(priv->TrSwitchState == TR_SW_TX) { + SignalStrength = SignalStrength + 54; + RX_PWDB = RX_PWDB + 27; + } + + if(SignalStrength > 100) + SignalStrength = 100; + SignalStrength = (SignalStrength * 70) / 100 + 30; + + if(SignalStrength > 50) + SignalStrength = SignalStrength + 10; + if(SignalStrength > 100) + SignalStrength = 100; + + RecvSignalPower = RX_PWDB; + //printk("SignalStrength = %d \n",SignalStrength); + bHwError = (desc->desc_87b.fovf | desc->desc_87b.icv | desc->desc_87b.crc32); + bCRC = desc->desc_87b.crc32; + bICV = desc->desc_87b.icv; + priv->wstats.qual.level = (u8)SignalStrength; + + if(!bCckRate){ + if (quality > 127) + quality = 0; + else if (quality <27) + quality = 100; + else + quality = 127 - quality; + } else { + if(quality > 64) + quality = 0; + else + quality = ((64-quality)*100)/64; + } + + + priv ->wstats.qual.qual = quality; + priv->wstats.qual.noise = 100 - priv ->wstats.qual.qual; + + stats.signalstrength = (u8)SignalStrength; + stats.signal = (u8)quality; + stats.noise = desc->desc_87b.snr_long2end; + + skb_put(skb,flen-4); + + priv->stats.rxok++; + //by amy + hdr = (struct ieee80211_hdr *)skb->data; + fc = le16_to_cpu(hdr->frame_ctl); + type = WLAN_FC_GET_TYPE(fc); + + if((IEEE80211_FTYPE_CTL != type) && + (eqMacAddr(priv->ieee80211->current_network.bssid, (fc & IEEE80211_FCTL_TODS)? hdr->addr1 : (fc & IEEE80211_FCTL_FROMDS )? hdr->addr2 : hdr->addr3)) && (!bHwError) && (!bCRC)&& (!bICV)) + { + // Perform signal smoothing for dynamic mechanism on demand. + // This is different with PerformSignalSmoothing8187 in smoothing fomula. + // No dramatic adjustion is apply because dynamic mechanism need some degree + // of correctness. 2007.01.23, by shien chang. + PerformUndecoratedSignalSmoothing8187(dev, &stats); + + //Update signal strength and realted into private RxStats for UI query. + SignalStrengthIndex = NetgearSignalStrengthTranslate(priv->LastSignalStrengthInPercent, priv->wstats.qual.level); + priv->LastSignalStrengthInPercent = SignalStrengthIndex; + priv->SignalStrength = TranslateToDbm8187((u8)SignalStrengthIndex); + priv->SignalQuality = (priv->SignalQuality*5+quality+5)/6; + priv->RecvSignalPower = (priv->RecvSignalPower * 5 + RecvSignalPower - 1) / 6; +#ifdef SW_ANTE_DIVERSITY + priv->LastRxPktAntenna = Antenna ? 1:0; + SwAntennaDiversityRxOk8185(dev, SignalStrength); +#endif + } + //by amy +#endif + if(!ieee80211_rx(priv->ieee80211,skb, &stats)) { + dev_kfree_skb_any(skb); + } + }else { + priv->stats.rxurberr++; + printk("URB Error flen:%d actual_length:%d\n", flen , rx_urb->actual_length); + dev_kfree_skb_any(skb); + } + } else { + stats.nic_type = NIC_8187; + len = rx_urb->actual_length; + len -= sizeof (struct rx_desc_rtl8187); + desc = (union rx_desc *)(rx_urb->transfer_buffer + len); + flen = desc->desc_87.rxlen ; + + if(flen <= rx_urb->actual_length){ + stats.signal = desc->desc_87.rssi; + stats.noise = desc->desc_87.sq; + stats.rate = desc->desc_87.rxrate; + stats.mac_time[0] = desc->desc_87.tsftl; + stats.mac_time[1] = desc->desc_87.tsfth; + SignalStrength = (desc->desc_87.agc&0xfe) >> 1; + if( ((stats.rate <= 22) && (stats.rate != 12) && (stats.rate != 18)) || (stats.rate == 44) )//need to translate to real rate here + bCckRate= TRUE; + if (!bCckRate) + { + if (SignalStrength > 90) SignalStrength = 90; + else if (SignalStrength < 25) SignalStrength = 25; + SignalStrength = ((90 - SignalStrength)*100)/65; + } + else + { + if (SignalStrength >95) SignalStrength = 95; + else if (SignalStrength < 30) SignalStrength = 30; + SignalStrength = ((95 - SignalStrength)*100)/65; + } + stats.signalstrength = (u8)SignalStrength; + + skb_put(skb,flen-4); + + priv->stats.rxok++; + + if(!ieee80211_rx(priv->ieee80211,skb, &stats)) + dev_kfree_skb_any(skb); + + + }else { + priv->stats.rxurberr++; + printk("URB Error flen:%d actual_length:%d\n", flen , rx_urb->actual_length); + dev_kfree_skb_any(skb); + } + } + }else{ + + //printk("RX Status Error!\n"); + priv->stats.rxstaterr++; + priv->ieee80211->stats.rx_errors++; + dev_kfree_skb_any(skb); + + } + + rx_urb->transfer_buffer = skb2->data; + + priv->pp_rxskb[*prx_inx] = skb2; + } + + if(status != -ENOENT ){ + rtl8187_rx_urbsubmit(dev,rx_urb); + } else { + priv->pp_rxskb[*prx_inx] = NULL; + dev_kfree_skb_any(skb2); + //printk("RX process %d aborted due to explicit shutdown (%x)(%d)\n ", *prx_inx, status, status); + } + + if (*prx_inx == (MAX_RX_URB -1)) + *prx_inx = 0; + else + *prx_inx = *prx_inx + 1; +} +#endif + +#ifdef THOMAS_TASKLET +void rtl8180_irq_rx_tasklet_new(struct r8180_priv *priv){ + unsigned long flags; + while( atomic_read( &priv->irt_counter ) ){ + spin_lock_irqsave(&priv->irq_lock,flags);//added by thomas + rtl8180_irq_rx_tasklet(priv); + spin_unlock_irqrestore(&priv->irq_lock,flags);//added by thomas + if(atomic_read(&priv->irt_counter) >= 1) + atomic_dec( &priv->irt_counter ); + } +} +#endif +/**************************************************************************** + ---------------------------- USB_STUFF--------------------------- +*****************************************************************************/ + +static const struct net_device_ops rtl8187_netdev_ops = { + .ndo_open = rtl8180_open, + .ndo_stop = rtl8180_close, + .ndo_tx_timeout = tx_timeout, + .ndo_do_ioctl = rtl8180_ioctl, + .ndo_set_multicast_list = r8180_set_multicast, + .ndo_set_mac_address = r8180_set_mac_adr, + .ndo_validate_addr = eth_validate_addr, + .ndo_change_mtu = eth_change_mtu, + .ndo_start_xmit = ieee80211_xmit, + .ndo_get_stats = rtl8180_stats, +}; + +#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0) +static int __devinit rtl8187_usb_probe(struct usb_interface *intf, + const struct usb_device_id *id) +#else +static void * __devinit rtl8187_usb_probe(struct usb_device *udev, + unsigned int ifnum, + const struct usb_device_id *id) +#endif +{ + struct net_device *dev = NULL; + struct r8180_priv *priv= NULL; + + +#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0) + struct usb_device *udev = interface_to_usbdev(intf); +#endif + + dev = alloc_ieee80211(sizeof(struct r8180_priv)); +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,24) + SET_MODULE_OWNER(dev); +#endif + +#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0) + usb_set_intfdata(intf, dev); + SET_NETDEV_DEV(dev, &intf->dev); +#endif + priv = ieee80211_priv(dev); +#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0) + priv->ieee80211 = netdev_priv(dev); +#else + priv->ieee80211 = (struct net_device *)dev->priv; +#endif + priv->udev=udev; +#ifdef CPU_64BIT + priv->usb_buf = kmalloc(0x200, GFP_KERNEL); + priv->usb_pool = dma_pool_create("rtl8187b", NULL, 64, 64, 0); +#endif +//lzm add for write time out test +#ifdef DEBUG_RW_REGISTER + { + int reg_index = 0; + for(reg_index = 0; reg_index <= 199; reg_index++) + { + priv->write_read_registers[reg_index].address = 0; + priv->write_read_registers[reg_index].content = 0; + priv->write_read_registers[reg_index].flag = 0; + } + priv->write_read_register_index = 0; + } +#endif + //init netdev_ops, added by falcon.... + dev->netdev_ops = &rtl8187_netdev_ops; + + dev->wireless_handlers = &r8180_wx_handlers_def; +#if WIRELESS_EXT >= 12 +#if WIRELESS_EXT < 17 + dev->get_wireless_stats = r8180_get_wireless_stats; +#endif + dev->wireless_handlers = (struct iw_handler_def *) &r8180_wx_handlers_def; +#endif + + dev->type=ARPHRD_ETHER; + dev->watchdog_timeo = HZ*3; //modified by john, 0805 + + if (dev_alloc_name(dev, ifname) < 0){ + DMESG("Oops: devname already taken! Trying wlan%%d...\n"); + ifname = "wlan%d"; + dev_alloc_name(dev, ifname); + } + + if(rtl8180_init(dev)!=0){ + DMESG("Initialization failed"); + goto fail; + } + + netif_carrier_off(dev); + netif_stop_queue(dev); + + register_netdev(dev); + + rtl8180_proc_init_one(dev); + +//by lizhaoming for Radio power on/off +#ifdef POLLING_METHOD_FOR_RADIO + if(priv->polling_timer_on == 0){//add for S3/S4 + gpio_change_polling((unsigned long)dev); + } +#endif + + DMESG("Driver probe completed"); +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) + return dev; +#else + return 0; +#endif + + +fail: + free_ieee80211(dev); + + DMESG("wlan driver load failed\n"); +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) + return NULL; +#else + return -ENODEV; +#endif + +} + +#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0) +static void __devexit rtl8187_usb_disconnect(struct usb_interface *intf) +#else +static void __devexit rtl8187_usb_disconnect(struct usb_device *udev, void *ptr) +#endif +{ + struct r8180_priv *priv = NULL; +#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0) + struct net_device *dev = usb_get_intfdata(intf); +#else + struct net_device *dev = (struct net_device *)ptr; +#endif + if(dev){ + unregister_netdev(dev); + + priv=ieee80211_priv(dev); + +//add for RF power on power off by lizhaoming 080512 +#ifdef POLLING_METHOD_FOR_RADIO + del_timer_sync(&priv->gpio_polling_timer); + cancel_delayed_work(&priv->ieee80211->GPIOChangeRFWorkItem); + priv->polling_timer_on = 0;//add for S3/S4 +#endif + MgntActSet_RF_State(dev, eRfOff, RF_CHANGE_BY_SW); + +#ifdef _RTL8187_EXT_PATCH_ + if(priv && priv->mshobj) + { + if(priv->mshobj->ext_patch_remove_proc) + priv->mshobj->ext_patch_remove_proc(priv); + priv->ieee80211->ext_patch_ieee80211_start_protocol = 0; + priv->ieee80211->ext_patch_ieee80211_stop_protocol = 0; + priv->ieee80211->ext_patch_ieee80211_probe_req_1 = 0; + priv->ieee80211->ext_patch_ieee80211_probe_req_2 = 0; + priv->ieee80211->ext_patch_ieee80211_association_req_1 = 0; + priv->ieee80211->ext_patch_ieee80211_association_req_2 = 0; + priv->ieee80211->ext_patch_ieee80211_assoc_resp_by_net_1 = 0; + priv->ieee80211->ext_patch_ieee80211_assoc_resp_by_net_2 = 0; + priv->ieee80211->ext_patch_ieee80211_rx_frame_softmac_on_auth =0; + priv->ieee80211->ext_patch_ieee80211_rx_frame_softmac_on_deauth =0; + priv->ieee80211->ext_patch_ieee80211_rx_frame_softmac_on_assoc_req = 0; + priv->ieee80211->ext_patch_ieee80211_rx_frame_softmac_on_assoc_rsp = 0; + priv->ieee80211->ext_patch_ieee80211_ext_stop_scan_wq_set_channel = 0; + priv->ieee80211->ext_patch_ieee80211_process_probe_response_1 = 0; + priv->ieee80211->ext_patch_ieee80211_rx_mgt_on_probe_req = 0; + priv->ieee80211->ext_patch_ieee80211_rx_mgt_update_expire = 0; + priv->ieee80211->ext_patch_ieee80211_rx_on_rx = 0; + priv->ieee80211->ext_patch_get_beacon_get_probersp = 0; + priv->ieee80211->ext_patch_ieee80211_xmit = 0; + priv->ieee80211->ext_patch_ieee80211_rx_frame_get_hdrlen = 0; + priv->ieee80211->ext_patch_ieee80211_rx_is_valid_framectl = 0; + priv->ieee80211->ext_patch_ieee80211_rx_process_dataframe = 0; + // priv->ieee80211->ext_patch_is_duplicate_packet = 0; + priv->ieee80211->ext_patch_ieee80211_softmac_xmit_get_rate = 0; + free_mshobj(&priv->mshobj); + } +#endif // _RTL8187_EXT_PATCH_ + + rtl8180_proc_remove_one(dev); + + rtl8180_down(dev); + priv->rf_close(dev); + + //rtl8180_rtx_disable(dev); + rtl8187_usb_deleteendpoints(dev); +#ifdef LED + DeInitSwLeds(dev); +#endif + rtl8180_irq_disable(dev); + rtl8180_reset(dev); + mdelay(10); + + } + +#ifdef CPU_64BIT + if(priv->usb_buf) + kfree(priv->usb_buf); + if(priv->usb_pool) { + dma_pool_destroy(priv->usb_pool); + priv->usb_pool = NULL; + } +#endif + free_ieee80211(dev); + DMESG("wlan driver removed"); +} + +/* fun with the built-in ieee80211 stack... */ +extern int ieee80211_crypto_init(void); +extern void ieee80211_crypto_deinit(void); +extern int ieee80211_crypto_tkip_init(void); +extern void ieee80211_crypto_tkip_exit(void); +extern int ieee80211_crypto_ccmp_init(void); +extern void ieee80211_crypto_ccmp_exit(void); +extern int ieee80211_crypto_wep_init(void); +extern void ieee80211_crypto_wep_exit(void); + +static int __init rtl8187_usb_module_init(void) +{ + int ret; + + ret = ieee80211_crypto_init(); + if (ret) { + printk(KERN_ERR "ieee80211_crypto_init() failed %d\n", ret); + return ret; + } + ret = ieee80211_crypto_tkip_init(); + if (ret) { + printk(KERN_ERR "ieee80211_crypto_tkip_init() failed %d\n", ret); + return ret; + } + ret = ieee80211_crypto_ccmp_init(); + if (ret) { + printk(KERN_ERR "ieee80211_crypto_ccmp_init() failed %d\n", ret); + return ret; + } + ret = ieee80211_crypto_wep_init(); + if (ret) { + printk(KERN_ERR "ieee80211_crypto_wep_init() failed %d\n", ret); + return ret; + } + + printk("\nLinux kernel driver for RTL8187/RTL8187B based WLAN cards\n"); + printk("Copyright (c) 2004-2008, Realsil Wlan\n"); + DMESG("Initializing module"); + DMESG("Wireless extensions version %d", WIRELESS_EXT); + rtl8180_proc_module_init(); + return usb_register(&rtl8187_usb_driver); +} + + +static void __exit rtl8187_usb_module_exit(void) +{ + usb_deregister(&rtl8187_usb_driver); + rtl8180_proc_module_remove(); + ieee80211_crypto_tkip_exit(); + ieee80211_crypto_ccmp_exit(); + ieee80211_crypto_wep_exit(); + ieee80211_crypto_deinit(); + + DMESG("Exiting\n"); +} + + +void rtl8180_try_wake_queue(struct net_device *dev, int pri) +{ + unsigned long flags; + short enough_desc; + struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev); + + spin_lock_irqsave(&priv->tx_lock,flags); + enough_desc = check_nic_enought_desc(dev,pri); + spin_unlock_irqrestore(&priv->tx_lock,flags); + + if(enough_desc) + ieee80211_wake_queue(priv->ieee80211); +} + +#ifdef JOHN_HWSEC +void EnableHWSecurityConfig8187(struct net_device *dev) +{ + u8 SECR_value = 0x0; + SECR_value = SCR_TxSecEnable | SCR_RxSecEnable; + { + write_nic_byte(dev, WPA_CONFIG, 0x7);//SECR_value | SCR_UseDK ); + } +} + +void setKey(struct net_device *dev, + u8 EntryNo, + u8 KeyIndex, + u16 KeyType, + u8 *MacAddr, + u8 DefaultKey, + u32 *KeyContent ) +{ + u32 TargetCommand = 0; + u32 TargetContent = 0; + u16 usConfig = 0; + int i; + usConfig |= BIT15 | (KeyType<<2) | (DefaultKey<<5) | KeyIndex; + + + for(i=0 ; i<6 ; i++){ + TargetCommand = i+6*EntryNo; + TargetCommand |= BIT31|BIT16; + + if(i==0){//MAC|Config + TargetContent = (u32)(*(MacAddr+0)) << 16| + (u32)(*(MacAddr+1)) << 24| + (u32)usConfig; + + write_nic_dword(dev, WCAMI, TargetContent); + write_nic_dword(dev, RWCAM, TargetCommand); + //printk("setkey cam =%8x\n", read_cam(dev, i+6*EntryNo)); + } else if(i==1){//MAC + TargetContent = (u32)(*(MacAddr+2)) | + (u32)(*(MacAddr+3)) << 8| + (u32)(*(MacAddr+4)) << 16| + (u32)(*(MacAddr+5)) << 24; + write_nic_dword(dev, WCAMI, TargetContent); + write_nic_dword(dev, RWCAM, TargetCommand); + } else { //Key Material + write_nic_dword(dev, WCAMI, (u32)(*(KeyContent+i-2)) ); + write_nic_dword(dev, RWCAM, TargetCommand); + } + } + +} +#endif + +/**************************************************************************** + --------------------------- RF power on/power off ----------------- +*****************************************************************************/ + +#ifdef POLLING_METHOD_FOR_RADIO +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)) +void GPIOChangeRFWorkItemCallBack(struct work_struct *work) +{ + //struct delayed_work *dwork = container_of(work, struct delayed_work, work); + struct ieee80211_device *ieee = container_of(work, struct ieee80211_device, GPIOChangeRFWorkItem.work); + struct net_device *dev = ieee->dev; + struct r8180_priv *priv = ieee80211_priv(dev); +#else +void GPIOChangeRFWorkItemCallBack(struct ieee80211_device *ieee) +{ + struct net_device *dev = ieee->dev; + struct r8180_priv *priv = ieee80211_priv(dev); +#endif + + //u16 tmp2byte; + u8 tmp1byte; + //u8 btPSR; + //u8 btConfig0; + RT_RF_POWER_STATE eRfPowerStateToSet; + bool bActuallySet=false; + + char *argv[3]; + static char *RadioPowerPath = "/etc/acpi/events/RadioPower.sh"; + static char *envp[] = {"HOME=/", "TERM=linux", "PATH=/usr/bin:/bin", NULL}; + +#if 0 + if(priv->up == 0)//driver stopped + { + printk("\nDo nothing..."); + goto out; + } + else +#endif + { + // We should turn off LED before polling FF51[4]. + + //Turn off LED. + //btPSR = read_nic_byte(dev, PSR); + //write_nic_byte(dev, PSR, (btPSR & ~BIT3)); + + //It need to delay 4us suggested by Jong, 2008-01-16 + //udelay(4); + + //HW radio On/Off according to the value of FF51[4](config0) + //btConfig0 = btPSR = read_nic_byte(dev, CONFIG0); + + //Turn on LED. + //write_nic_byte(dev, PSR, btPSR| BIT3); + + //eRfPowerStateToSet = (btConfig0 & BIT4) ? eRfOn : eRfOff; + + // Get RF power state to set. + //if Driver isn't stopped, we poll GPIO1 + + //set 0x91 B1= 0 // 1: for output enable; 0: otherwise. + // (William says) Note that, it will cause unstable if we set output enable 1 but not to write it. Annie, 2005-12-12. + tmp1byte = read_nic_byte(dev,GPE); + if(priv->EEPROMSelectNewGPIO == true) + tmp1byte &= ~BIT2;//for toshiba new GPIO use bit2 + else + tmp1byte &= ~BIT1; + + write_nic_byte(dev,GPE,tmp1byte); + + //read 0x92 B1(read GPIO1) + tmp1byte = read_nic_byte(dev,GPI); + + //turn on or trun off RF according to the value of GPIO1 + if(priv->EEPROMSelectNewGPIO == true) + eRfPowerStateToSet = (tmp1byte&BIT2) ? eRfOn : eRfOff; + else + eRfPowerStateToSet = (tmp1byte&BIT1) ? eRfOn : eRfOff; + + if((priv->ieee80211->bHwRadioOff == true) && (eRfPowerStateToSet == eRfOn)){ + priv->ieee80211->bHwRadioOff = false; + bActuallySet = true; + }else if((priv->ieee80211->bHwRadioOff == false) && (eRfPowerStateToSet == eRfOff)){ + priv->ieee80211->bHwRadioOff = true; + bActuallySet = true; + } + + //if(priv->wlan_first_up_flag1 == 0){ + // bActuallySet = true; + // priv->wlan_first_up_flag1 = 1; + //} + + if(bActuallySet) + { + //printk("GPIO1:%x,eRfPowerStateToSet: %x, bHwRadioOff:%x\n", + // tmp1byte,eRfPowerStateToSet,priv->ieee80211->bHwRadioOff); + + //GPIO Polling Methord Made Radio On/Off + DMESG("GPIO Polling Methord Will Turn Radio %s", + (priv->ieee80211->bHwRadioOff == true) ? "Off" : "On"); + +#ifdef LED //by lizhaoming + if(priv->ieee80211->bHwRadioOff == true){ + priv->ieee80211->ieee80211_led_contorl(dev,LED_CTL_POWER_OFF); + }else{ + if(priv->up == 1){ + priv->ieee80211->ieee80211_led_contorl(dev,LED_CTL_POWER_ON); + } + } +#endif + + MgntActSet_RF_State(dev, eRfPowerStateToSet, RF_CHANGE_BY_HW); + + /* To update the UI status for Power status changed */ + if(priv->ieee80211->bHwRadioOff == true) + argv[1] = "RFOFF"; + else{ + //if(priv->eInactivePowerState != eRfOff) + argv[1] = "RFON"; + //else + // argv[1] = "RFOFF"; + } + argv[0] = RadioPowerPath; + argv[2] = NULL; + + call_usermodehelper(RadioPowerPath,argv,envp,1); + } + + } +} +void gpio_change_polling(unsigned long data) +{ + struct r8180_priv* priv = ieee80211_priv((struct net_device *)data); + //struct net_device* dev = (struct net_device*)data; + + priv->polling_timer_on = 1;//add for S3/S4 + + if(priv->driver_upping == 0){ +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20) + queue_delayed_work(priv->ieee80211->wq,&priv->ieee80211->GPIOChangeRFWorkItem,0); +#else + queue_work(priv->ieee80211->wq,&priv->ieee80211->GPIOChangeRFWorkItem); +#endif + } + + mod_timer(&priv->gpio_polling_timer, jiffies + MSECS(IEEE80211_WATCH_DOG_TIME)); +} +#endif + +/*************************************************************************** + ------------------- module init / exit stubs ---------------- +****************************************************************************/ +module_init(rtl8187_usb_module_init); +module_exit(rtl8187_usb_module_exit); diff -Nur linux-2.6.30.5.orig/drivers/net/wireless/rtl8187b/r8187.h linux-2.6.30.5/drivers/net/wireless/rtl8187b/r8187.h --- linux-2.6.30.5.orig/drivers/net/wireless/rtl8187b/r8187.h 1970-01-01 01:00:00.000000000 +0100 +++ linux-2.6.30.5/drivers/net/wireless/rtl8187b/r8187.h 2009-08-23 19:01:04.000000000 +0200 @@ -0,0 +1,816 @@ +/* + This is part of rtl8187 OpenSource driver. + Copyright (C) Andrea Merello 2004-2005 + Released under the terms of GPL (General Public Licence) + + Parts of this driver are based on the GPL part of the + official realtek driver + + Parts of this driver are based on the rtl8180 driver skeleton + from Patric Schenke & Andres Salomon + + Parts of this driver are based on the Intel Pro Wireless 2100 GPL driver + + We want to tanks the Authors of those projects and the Ndiswrapper + project Authors. +*/ + +#ifndef R8180H +#define R8180H + + +#define RTL8187_MODULE_NAME "rtl8187" +#define DMESG(x,a...) printk(KERN_INFO RTL8187_MODULE_NAME ": " x "\n", ## a) +#define DMESGW(x,a...) printk(KERN_WARNING RTL8187_MODULE_NAME ": WW:" x "\n", ## a) +#define DMESGE(x,a...) printk(KERN_WARNING RTL8187_MODULE_NAME ": EE:" x "\n", ## a) + +#include +#include +//#include +#include +#include +#include +#include +#include +#include +//#include +#include +#include +#include +#include //for rtnl_lock() +#include +#include +#include // Necessary because we use the proc fs +#include +#include +#include +#include +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,27) +#include +#endif +#include "ieee80211/ieee80211.h" +#ifdef _RTL8187_EXT_PATCH_ +#include "msh_class.h" +#endif +#ifdef LED +#include "r8187_led.h" +#endif + +//added for HW security, john.0629 +#define FALSE 0 +#define TRUE 1 +#define MAX_KEY_LEN 61 +#define KEY_BUF_SIZE 5 + +#define BIT0 0x00000001 +#define BIT1 0x00000002 +#define BIT2 0x00000004 +#define BIT3 0x00000008 +#define BIT4 0x00000010 +#define BIT5 0x00000020 +#define BIT6 0x00000040 +#define BIT7 0x00000080 +#define BIT8 0x00000100 +#define BIT9 0x00000200 +#define BIT10 0x00000400 +#define BIT11 0x00000800 +#define BIT12 0x00001000 +#define BIT13 0x00002000 +#define BIT14 0x00004000 +#define BIT15 0x00008000 +#define BIT16 0x00010000 +#define BIT17 0x00020000 +#define BIT18 0x00040000 +#define BIT19 0x00080000 +#define BIT20 0x00100000 +#define BIT21 0x00200000 +#define BIT22 0x00400000 +#define BIT23 0x00800000 +#define BIT24 0x01000000 +#define BIT25 0x02000000 +#define BIT26 0x04000000 +#define BIT27 0x08000000 +#define BIT28 0x10000000 +#define BIT29 0x20000000 +#define BIT30 0x40000000 +#define BIT31 0x80000000 + +//8187B Security +#define RWCAM 0xA0 // Software read/write CAM config +#define WCAMI 0xA4 // Software write CAM input content +#define RCAMO 0xA8 // Output value from CAM according to 0xa0 setting +#define DCAM 0xAC // Debug CAM Interface +#define SECR 0xB0 // Security configuration register +#define AESMSK_FC 0xB2 // AES Mask register for frame control (0xB2~0xB3). Added by Annie, 2006-03-06. +#define AESMSK_SC 0x1FC // AES Mask for Sequence Control (0x1FC~0X1FD). Added by Annie, 2006-03-06. +#define AESMSK_QC 0x1CE // AES Mask register for QoS Control when computing AES MIC, default = 0x000F. (2 bytes) + +#define AESMSK_FC_DEFAULT 0xC78F // default value of AES MASK for Frame Control Field. (2 bytes) +#define AESMSK_SC_DEFAULT 0x000F // default value of AES MASK for Sequence Control Field. (2 bytes) +#define AESMSK_QC_DEFAULT 0x000F // default value of AES MASK for QoS Control Field. (2 bytes) + +#define CAM_CONTENT_COUNT 6 +#define CFG_DEFAULT_KEY BIT5 +#define CFG_VALID BIT15 + +//---------------------------------------------------------------------------- +// 8187B WPA Config Register (offset 0xb0, 1 byte) +//---------------------------------------------------------------------------- +#define SCR_UseDK 0x01 +#define SCR_TxSecEnable 0x02 +#define SCR_RxSecEnable 0x04 + +//---------------------------------------------------------------------------- +// 8187B CAM Config Setting (offset 0xb0, 1 byte) +//---------------------------------------------------------------------------- +#define CAM_VALID 0x8000 +#define CAM_NOTVALID 0x0000 +#define CAM_USEDK 0x0020 + + +#define CAM_NONE 0x0 +#define CAM_WEP40 0x01 +#define CAM_TKIP 0x02 +#define CAM_AES 0x04 +#define CAM_WEP104 0x05 + + +//#define CAM_SIZE 16 +#define TOTAL_CAM_ENTRY 16 +#define CAM_ENTRY_LEN_IN_DW 6 // 6, unit: in u4byte. Added by Annie, 2006-05-25. +#define CAM_ENTRY_LEN_IN_BYTE (CAM_ENTRY_LEN_IN_DW*sizeof(u4Byte)) // 24, unit: in u1byte. Added by Annie, 2006-05-25. + +#define CAM_CONFIG_USEDK 1 +#define CAM_CONFIG_NO_USEDK 0 + +#define CAM_WRITE 0x00010000 +#define CAM_READ 0x00000000 +#define CAM_POLLINIG 0x80000000 + +//================================================================= +//================================================================= + +#define EPROM_93c46 0 +#define EPROM_93c56 1 + +#define DEFAULT_FRAG_THRESHOLD 2342U +#define MIN_FRAG_THRESHOLD 256U +#define DEFAULT_BEACONINTERVAL 0x64U +#define DEFAULT_BEACON_ESSID "Rtl8187" + +#define DEFAULT_SSID "" +#define DEFAULT_RETRY_RTS 7 +#define DEFAULT_RETRY_DATA 7 +#define PRISM_HDR_SIZE 64 + +typedef enum _WIRELESS_MODE { + WIRELESS_MODE_UNKNOWN = 0x00, + WIRELESS_MODE_A = 0x01, + WIRELESS_MODE_B = 0x02, + WIRELESS_MODE_G = 0x04, + WIRELESS_MODE_AUTO = 0x08, +} WIRELESS_MODE; + +typedef enum _TR_SWITCH_STATE{ + TR_HW_CONTROLLED = 0, + TR_SW_TX = 1, +}TR_SWITCH_STATE, *PTR_SWITCH_STATE; + + +#define RTL_IOCTL_WPA_SUPPLICANT SIOCIWFIRSTPRIV+30 + +typedef struct buffer +{ + struct buffer *next; + u32 *buf; + +} buffer; + +typedef struct rtl_reg_debug{ + unsigned int cmd; + struct { + unsigned char type; + unsigned char addr; + unsigned char page; + unsigned char length; + } head; + unsigned char buf[0xff]; +}rtl_reg_debug; +typedef struct _CHANNEL_LIST{ + u8 Channel[MAX_CHANNEL_NUMBER + 1]; + u8 Len; +}CHANNEL_LIST, *PCHANNEL_LIST; + +#define MAX_LD_SLOT_NUM 10 +#define DEFAULT_SLOT_NUM 2 +#define KEEP_ALIVE_INTERVAL 20 // in seconds. +#define CHECK_FOR_HANG_PERIOD 2 //be equal to watchdog check time +#define DEFAULT_KEEP_ALIVE_LEVEL 1 + +typedef struct _link_detect_t +{ + u32 RxFrameNum[MAX_LD_SLOT_NUM]; // number of Rx Frame / CheckForHang_period to determine link status + u16 SlotNum; // number of CheckForHang period to determine link status, default is 2 + u16 SlotIndex; + + u32 NumTxOkInPeriod; //number of packet transmitted during CheckForHang + u32 NumRxOkInPeriod; //number of packet received during CheckForHang + + u8 IdleCount; // (KEEP_ALIVE_INTERVAL / CHECK_FOR_HANG_PERIOD) + u32 LastNumTxUnicast; + u32 LastNumRxUnicast; + + bool bBusyTraffic; //when it is set to 1, UI cann't scan at will. +}link_detect_t, *plink_detect_t; + +#if 0 + +typedef struct tx_pendingbuf +{ + struct ieee80211_txb *txb; + short ispending; + short descfrag; +} tx_pendigbuf; + +#endif + +typedef struct Stats +{ + unsigned long txrdu; +// unsigned long rxrdu; + //unsigned long rxnolast; + //unsigned long rxnodata; +// unsigned long rxreset; +// unsigned long rxwrkaround; +// unsigned long rxnopointer; + unsigned long rxok; + unsigned long rxurberr; + unsigned long rxstaterr; + unsigned long txnperr; + unsigned long txnpdrop; + unsigned long txresumed; +// unsigned long rxerr; +// unsigned long rxoverflow; +// unsigned long rxint; + unsigned long txnpokint; +// unsigned long txhpokint; +// unsigned long txhperr; +// unsigned long ints; +// unsigned long shints; + unsigned long txoverflow; +// unsigned long rxdmafail; +// unsigned long txbeacon; +// unsigned long txbeaconerr; + unsigned long txlpokint; + unsigned long txlpdrop; + unsigned long txlperr; + unsigned long txbeokint; + unsigned long txbedrop; + unsigned long txbeerr; + unsigned long txbkokint; + unsigned long txbkdrop; + unsigned long txbkerr; + unsigned long txviokint; + unsigned long txvidrop; + unsigned long txvierr; + unsigned long txvookint; + unsigned long txvodrop; + unsigned long txvoerr; + unsigned long txbeaconokint; + unsigned long txbeacondrop; + unsigned long txbeaconerr; + unsigned long txmanageokint; + unsigned long txmanagedrop; + unsigned long txmanageerr; + unsigned long txdatapkt; +} Stats; + +typedef struct ChnlAccessSetting { + u16 SIFS_Timer; + u16 DIFS_Timer; + u16 SlotTimeTimer; + u16 EIFS_Timer; + u16 CWminIndex; + u16 CWmaxIndex; +}*PCHANNEL_ACCESS_SETTING,CHANNEL_ACCESS_SETTING; + + +typedef enum _RT_RF_POWER_STATE +{ + eRfOn, + eRfSleep, + eRfOff +}RT_RF_POWER_STATE; +typedef enum _RT_PS_MODE +{ + eActive, // Active/Continuous access. + eMaxPs, // Max power save mode. + eFastPs // Fast power save mode. +}RT_PS_MODE; +// +// Three wire mode. +// +#define IC_DEFAULT_THREE_WIRE 0 +#define SW_THREE_WIRE 1 +//RTL818xB +#define SW_THREE_WIRE_BY_8051 2 +#define HW_THREE_WIRE 3 +#define HW_THREE_WIRE_BY_8051 4 +//lzm add for write time out test +typedef struct write_read_register +{ + u32 address; + u32 content; + u32 flag; +} write_read_register; +//lzm add for write time out test +typedef struct r8180_priv +{ +//lzm add for write time out test + struct write_read_register write_read_registers[200]; + u8 write_read_register_index; +//lzm add for write time out test + + struct usb_device *udev; + short epromtype; + int irq; + struct ieee80211_device *ieee80211; + + short card_8187; /* O: rtl8180, 1:rtl8185 V B/C, 2:rtl8185 V D */ + short card_8187_Bversion; /* if TCR reports card V B/C this discriminates */ + short phy_ver; /* meaningful for rtl8225 1:A 2:B 3:C */ + short enable_gpio0; + enum card_type {PCI,MINIPCI,CARDBUS,USB/*rtl8187*/}card_type; + short hw_plcp_len; + short plcp_preamble_mode; + + spinlock_t irq_lock; +// spinlock_t irq_th_lock; + spinlock_t tx_lock; +//by amy for ps + spinlock_t rf_ps_lock; +//by amy for ps + + u16 irq_mask; +// short irq_enabled; + struct net_device *dev; + short chan; + short sens; + short max_sens; + u8 chtxpwr[15]; //channels from 1 to 14, 0 not used + u8 chtxpwr_ofdm[15]; //channels from 1 to 14, 0 not used + u8 cck_txpwr_base; + u8 ofdm_txpwr_base; + u8 challow[15]; //channels from 1 to 14, 0 not used + short up; + short crcmon; //if 1 allow bad crc frame reception in monitor mode +// short prism_hdr; + +// struct timer_list scan_timer; + /*short scanpending; + short stopscan;*/ +// spinlock_t scan_lock; +// u8 active_probe; + //u8 active_scan_num; + struct semaphore wx_sem; + struct semaphore set_chan_sem; +// short hw_wep; + +// short digphy; +// short antb; +// short diversity; +// u8 cs_treshold; +// short rcr_csense; + short rf_chip; +// u32 key0[4]; + short (*rf_set_sens)(struct net_device *dev,short sens); + void (*rf_set_chan)(struct net_device *dev,short ch); + void (*rf_close)(struct net_device *dev); + void (*rf_init)(struct net_device *dev); + //short rate; + short promisc; + /*stats*/ + struct Stats stats; + struct _link_detect_t link_detect; //added on 1016.2008 + struct iw_statistics wstats; + struct proc_dir_entry *dir_dev; + + /*RX stuff*/ +// u32 *rxring; +// u32 *rxringtail; +// dma_addr_t rxringdma; + struct urb **rx_urb; +#ifdef THOMAS_BEACON + unsigned long *oldaddr; //lzm for 64bit CPU crash +#endif + +#ifdef THOMAS_TASKLET + atomic_t irt_counter;//count for irq_rx_tasklet +#endif +#ifdef JACKSON_NEW_RX + struct sk_buff **pp_rxskb; + int rx_inx; +#endif + + short tx_urb_index; + + //struct buffer *rxbuffer; + //struct buffer *rxbufferhead; + //int rxringcount; + //u16 rxbuffersize; + + //struct sk_buff *rx_skb; + + //short rx_skb_complete; + + //u32 rx_prevlen; + //atomic_t tx_lp_pending; + //atomic_t tx_np_pending; + atomic_t tx_pending[0x10];//UART_PRIORITY+1 + +#if 0 + /*TX stuff*/ + u32 *txlpring; + u32 *txhpring; + u32 *txnpring; + dma_addr_t txlpringdma; + dma_addr_t txhpringdma; + dma_addr_t txnpringdma; + u32 *txlpringtail; + u32 *txhpringtail; + u32 *txnpringtail; + u32 *txlpringhead; + u32 *txhpringhead; + u32 *txnpringhead; + struct buffer *txlpbufs; + struct buffer *txhpbufs; + struct buffer *txnpbufs; + struct buffer *txlpbufstail; + struct buffer *txhpbufstail; + struct buffer *txnpbufstail; + int txringcount; + int txbuffsize; + + //struct tx_pendingbuf txnp_pending; + struct tasklet_struct irq_tx_tasklet; +#endif + struct tasklet_struct irq_rx_tasklet; + struct urb *rxurb_task; +// u8 dma_poll_mask; + //short tx_suspend; + + /* adhoc/master mode stuff */ +#if 0 + u32 *txbeacontail; + dma_addr_t txbeaconringdma; + u32 *txbeaconring; + int txbeaconcount; +#endif +// struct ieee_tx_beacon *beacon_buf; + //char *master_essid; +// dma_addr_t beacondmabuf; + //u16 master_beaconinterval; +// u32 master_beaconsize; + //u16 beacon_interval; + + //2 Tx Related variables + u16 ShortRetryLimit; + u16 LongRetryLimit; + u32 TransmitConfig; + u8 RegCWinMin; // For turbo mode CW adaptive. Added by Annie, 2005-10-27. + + //2 Rx Related variables + u16 EarlyRxThreshold; + u32 ReceiveConfig; + u8 AcmControl; + + u8 RFProgType; + + u8 retry_data; + u8 retry_rts; + u16 rts; + +//by amy + long LastSignalStrengthInPercent; + long SignalStrength; + long SignalQuality; + u8 antenna_flag; + bool flag_beacon; +//by amy +//by amy for rate adaptive + struct timer_list rateadapter_timer; + u16 LastRetryCnt; + u16 LastRetryRate; + unsigned long LastTxokCnt; + unsigned long LastRxokCnt; + u16 CurrRetryCnt; + long RecvSignalPower; + unsigned long LastTxOKBytes; + u8 LastFailTxRate; + long LastFailTxRateSS; + u8 FailTxRateCount; + u32 LastTxThroughput; + unsigned long txokbytestotal; + //for up rate + unsigned short bTryuping; + u8 CurrTxRate; //the rate before up + u16 CurrRetryRate; + u16 TryupingCount; + u8 TryDownCountLowData; + u8 TryupingCountNoData; + + u8 CurrentOperaRate; +// by lizhaoming used for Radio on/off +#ifdef POLLING_METHOD_FOR_RADIO + struct timer_list gpio_polling_timer; + u8 polling_timer_on; + u8 wlan_first_up_flag1; +#endif +//by amy for rate adaptive +//by amy for power save + struct timer_list watch_dog_timer; + bool bInactivePs; + bool bSwRfProcessing; + RT_RF_POWER_STATE eInactivePowerState; + RT_RF_POWER_STATE eRFPowerState; + u32 RfOffReason; + bool RFChangeInProgress; + bool bInHctTest; + bool SetRFPowerStateInProgress; + //u8 RFProgType; + bool bLeisurePs; + RT_PS_MODE dot11PowerSaveMode; + u32 NumRxOkInPeriod; + u32 NumTxOkInPeriod; + u8 RegThreeWireMode; + bool ps_mode; +//by amy for power save +//by amy for DIG + bool bDigMechanism; + bool bCCKThMechanism; + u8 InitialGain; + u8 StageCCKTh; + u8 RegBModeGainStage; + u8 RegDigOfdmFaUpTh; //added by david, 2008.3.6 + u8 DIG_NumberFallbackVote; + u8 DIG_NumberUpgradeVote; + u16 CCKUpperTh; + u16 CCKLowerTh; + u32 FalseAlarmRegValue; //added by david, 2008.3.6 +//by amy for DIG +//{ added by david for high power, 2008.3.11 + int UndecoratedSmoothedSS; + bool bRegHighPowerMechanism; + bool bToUpdateTxPwr; + u8 Z2HiPwrUpperTh; + u8 Z2HiPwrLowerTh; + u8 Z2RSSIHiPwrUpperTh; + u8 Z2RSSIHiPwrLowerTh; + // Current CCK RSSI value to determine CCK high power, asked by SD3 DZ, by Bruce, 2007-04-12. + u8 CurCCKRSSI; + bool bCurCCKPkt; + u32 wMacRegRfPinsOutput; + u32 wMacRegRfPinsSelect; + TR_SWITCH_STATE TrSwitchState; +//} +//{added by david for radio on/off + u8 radion; +//} + struct ChnlAccessSetting ChannelAccessSetting; +#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0) + struct work_struct reset_wq; +#else + struct tq_struct reset_wq; +#endif + +#ifdef _RTL8187_EXT_PATCH_ + struct mshclass *mshobj; +#endif + +#ifdef LED + /* add for led controll */ + u8 EEPROMCustomerID; + RT_CID_TYPE CustomerID; + LED_8187 Gpio0Led; + LED_8187 SwLed0; + LED_8187 SwLed1; + u8 bEnableLedCtrl; + LED_STRATEGY_8187 LedStrategy; + u8 PsrValue; + struct work_struct Gpio0LedWorkItem; + struct work_struct SwLed0WorkItem; + struct work_struct SwLed1WorkItem; +#endif + u8 driver_upping; +#ifdef CPU_64BIT + u8 *usb_buf; + struct dma_pool *usb_pool; +#endif + + +#ifdef SW_ANTE_DIVERSITY + +//#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20) +// struct delayed_work SwAntennaWorkItem; +//#else +// struct work_struct SwAntennaWorkItem; +//#endif + + bool bAntennaDiversityTimerIssued; + short antb; + short diversity; + bool AutoloadFailFlag; + u16 EEPROMVersion; + u8 EEPROMAntennaDiversity; + u16 EEPROMCSThreshold; + u8 EEPROMDefaultAntennaB; + u8 EEPROMDigitalPhy; + u32 EEPROMCSMethod; + u8 EEPROMGEPRFOffState; + // For HW antenna diversity, added by Roger, 2008.01.30. + u32 AdMainAntennaRxOkCnt; // Main antenna Rx OK count. + u32 AdAuxAntennaRxOkCnt; // Aux antenna Rx OK count. + bool bHWAdSwitched; // TRUE if we has switched default antenna by HW evaluation. + u8 EEPROMSwAntennaDiversity; + bool EEPROMDefaultAntenna1; + u8 RegSwAntennaDiversityMechanism;// 0:default from EEPROM, 1: disable, 2: enable. + bool bSwAntennaDiverity; + u8 RegDefaultAntenna;// 0: default from EEPROM, 1: main, 2: aux. Added by Roger, 2007.11.05. + bool bDefaultAntenna1; + //long SignalStrength; + long Stats_SignalStrength; + //long LastSignalStrengthInPercent; // In percentange, used for smoothing, e.g. Moving Average. + //long SignalQuality; // in 0-100 index. + long Stats_SignalQuality; + //long RecvSignalPower; // in dBm. + long Stats_RecvSignalPower; + u8 LastRxPktAntenna; // +by amy 080312 Antenn which received the lasted packet. 0: Aux, 1:Main. Added by Roger, 2008.01.25. + u32 AdRxOkCnt; + long AdRxSignalStrength; // Rx signal strength for Antenna Diversity, which had been smoothing, its valid range is [0,100]. + u8 CurrAntennaIndex; // Index to current Antenna (both Tx and Rx). + u8 AdTickCount; // Times of SwAntennaDiversityTimer happened. + u8 AdCheckPeriod; // # of period SwAntennaDiversityTimer to check Rx signal strength for SW Antenna Diversity. + u8 AdMinCheckPeriod; // Min value of AdCheckPeriod. + u8 AdMaxCheckPeriod; // Max value of AdCheckPeriod. + long AdRxSsThreshold; // Signal strength threshold to switch antenna. + long AdMaxRxSsThreshold; // Max value of AdRxSsThreshold. + bool bAdSwitchedChecking; // TRUE if we shall shall check Rx signal strength for last time switching antenna. + long AdRxSsBeforeSwitched; // Rx signal strength before we swithed antenna. + struct timer_list SwAntennaDiversityTimer; +#endif + u8 commit; + +//#ifdef ENABLE_DOT11D + u8 channel_plan; +//#endif + u8 EEPROMSelectNewGPIO; +}r8180_priv; + +// for rtl8187 +// now mirging to rtl8187B +/* +typedef enum{ + LOW_PRIORITY = 0x02, + NORM_PRIORITY + } priority_t; +*/ +//for rtl8187B +typedef enum{ + BULK_PRIORITY = 0x01, + //RSVD0, + //RSVD1, + LOW_PRIORITY, + NORM_PRIORITY, + VO_PRIORITY, + VI_PRIORITY, //0x05 + BE_PRIORITY, + BK_PRIORITY, + RSVD2, + RSVD3, + BEACON_PRIORITY, //0x0A + HIGH_PRIORITY, + MANAGE_PRIORITY, + RSVD4, + RSVD5, + UART_PRIORITY //0x0F +} priority_t; + +typedef enum{ + NIC_8187 = 1, + NIC_8187B + } nic_t; + + +typedef u32 AC_CODING; +#define AC0_BE 0 // ACI: 0x00 // Best Effort +#define AC1_BK 1 // ACI: 0x01 // Background +#define AC2_VI 2 // ACI: 0x10 // Video +#define AC3_VO 3 // ACI: 0x11 // Voice +#define AC_MAX 4 // Max: define total number; Should not to be used as a real enum. + +// +// ECWmin/ECWmax field. +// Ref: WMM spec 2.2.2: WME Parameter Element, p.13. +// +typedef union _ECW{ + u8 charData; + struct + { + u8 ECWmin:4; + u8 ECWmax:4; + }f; // Field +}ECW, *PECW; + +// +// ACI/AIFSN Field. +// Ref: WMM spec 2.2.2: WME Parameter Element, p.12. +// +typedef union _ACI_AIFSN{ + u8 charData; + + struct + { + u8 AIFSN:4; + u8 ACM:1; + u8 ACI:2; + u8 Reserved:1; + }f; // Field +}ACI_AIFSN, *PACI_AIFSN; + +// +// AC Parameters Record Format. +// Ref: WMM spec 2.2.2: WME Parameter Element, p.12. +// +typedef union _AC_PARAM{ + u32 longData; + u8 charData[4]; + + struct + { + ACI_AIFSN AciAifsn; + ECW Ecw; + u16 TXOPLimit; + }f; // Field +}AC_PARAM, *PAC_PARAM; + +#ifdef JOHN_HWSEC +struct ssid_thread { + struct net_device *dev; + u8 name[IW_ESSID_MAX_SIZE + 1]; +}; +#endif + +short rtl8180_tx(struct net_device *dev,u32* skbuf, int len,priority_t priority,short morefrag,short rate); + +#ifdef JOHN_TKIP +u32 read_cam(struct net_device *dev, u8 addr); +void write_cam(struct net_device *dev, u8 addr, u32 data); +#endif +u8 read_nic_byte(struct net_device *dev, int x); +u8 read_nic_byte_E(struct net_device *dev, int x); +u32 read_nic_dword(struct net_device *dev, int x); +u16 read_nic_word(struct net_device *dev, int x) ; +void write_nic_byte(struct net_device *dev, int x,u8 y); +void write_nic_byte_E(struct net_device *dev, int x,u8 y); +void write_nic_word(struct net_device *dev, int x,u16 y); +void write_nic_dword(struct net_device *dev, int x,u32 y); +void force_pci_posting(struct net_device *dev); + +void rtl8180_rtx_disable(struct net_device *); +void rtl8180_rx_enable(struct net_device *); +void rtl8180_tx_enable(struct net_device *); + +void rtl8180_disassociate(struct net_device *dev); +//void fix_rx_fifo(struct net_device *dev); +void rtl8185_set_rf_pins_enable(struct net_device *dev,u32 a); + +void rtl8180_set_anaparam(struct net_device *dev,u32 a); +void rtl8185_set_anaparam2(struct net_device *dev,u32 a); +void rtl8180_update_msr(struct net_device *dev); +int rtl8180_down(struct net_device *dev); +int rtl8180_up(struct net_device *dev); +void rtl8180_commit(struct net_device *dev); +void rtl8180_set_chan(struct net_device *dev,short ch); +void write_phy(struct net_device *dev, u8 adr, u8 data); +void write_phy_cck(struct net_device *dev, u8 adr, u32 data); +void write_phy_ofdm(struct net_device *dev, u8 adr, u32 data); +void rtl8185_tx_antenna(struct net_device *dev, u8 ant); +void rtl8187_set_rxconf(struct net_device *dev); +bool MgntActSet_RF_State(struct net_device *dev,RT_RF_POWER_STATE StateToSet,u32 ChangeSource); +void IPSEnter(struct net_device *dev); +void IPSLeave(struct net_device *dev); +#ifdef POLLING_METHOD_FOR_RADIO +void gpio_change_polling(unsigned long data); +#endif +bool SetRFPowerState(struct net_device *dev,RT_RF_POWER_STATE eRFPowerState); +void rtl8180_patch_ieee80211_wx_sync_scan_wq(struct ieee80211_device *ieee); +#ifdef _RTL8187_EXT_PATCH_ +extern int r8180_wx_set_channel(struct net_device *dev, struct iw_request_info *info, union iwreq_data *wrqu, char *extra); +#endif +#ifdef JOHN_TKIP +void EnableHWSecurityConfig8187(struct net_device *dev); +void setKey(struct net_device *dev, u8 EntryNo, u8 KeyIndex, u16 KeyType, u8 *MacAddr, u8 DefaultKey, u32 *KeyContent ); + +#endif + +#endif diff -Nur linux-2.6.30.5.orig/drivers/net/wireless/rtl8187b/r8187_led.c linux-2.6.30.5/drivers/net/wireless/rtl8187b/r8187_led.c --- linux-2.6.30.5.orig/drivers/net/wireless/rtl8187b/r8187_led.c 1970-01-01 01:00:00.000000000 +0100 +++ linux-2.6.30.5/drivers/net/wireless/rtl8187b/r8187_led.c 2009-08-23 19:01:04.000000000 +0200 @@ -0,0 +1,1629 @@ +/*++ +Copyright (c) Realtek Semiconductor Corp. All rights reserved. + +Module Name: + r8187_led.c + +Abstract: + RTL8187 LED control functions + +Major Change History: + When Who What + ---------- --------------- ------------------------------- + 2006-09-07 Xiong Created + +Notes: + +--*/ + +/*--------------------------Include File------------------------------------*/ +#include "ieee80211/ieee80211.h" +#include "r8180_hw.h" +#include "r8187.h" +#include "r8180_93cx6.h" +#include "r8187_led.h" + +/** +* +* Initialization function for Sw Leds controll. +* +* \param dev The net device for this driver. +* \return void. +* +* Note: +* +*/ + +void +InitSwLeds( + struct net_device *dev + ) +{ + + struct r8180_priv *priv = ieee80211_priv(dev); + u16 usValue; +// printk("========>%s()\n", __FUNCTION__); + +// priv->CustomerID = RT_CID_87B_DELL; //by lizhaoming for DELL 2008.6.3 + priv->CustomerID = RT_CID_DEFAULT; //just set to default now + priv->bEnableLedCtrl = 1; + priv->PsrValue = read_nic_byte(dev, PSR); + usValue = eprom_read(dev, EEPROM_SW_REVD_OFFSET >> 1); + priv->EEPROMCustomerID = (u8)( usValue & EEPROM_CID_MASK ); + DMESG("EEPROM Customer ID: %02X", priv->EEPROMCustomerID); + + if(priv->CustomerID == RT_CID_DEFAULT) + { // If we have not yet change priv->CustomerID in register, + // we initialzie it from that of EEPROM with proper translation, 2006.07.03, by rcnjko. + switch(priv->EEPROMCustomerID) + { + case EEPROM_CID_RSVD0: + case EEPROM_CID_RSVD1: + priv->CustomerID = RT_CID_DEFAULT; + break; + + case EEPROM_CID_ALPHA0: + priv->CustomerID = RT_CID_8187_ALPHA0; + break; + + case EEPROM_CID_SERCOMM_PS: + priv->CustomerID = RT_CID_8187_SERCOMM_PS; + break; + + case EEPROM_CID_HW_LED: + priv->CustomerID = RT_CID_8187_HW_LED; + break; + + case EEPROM_CID_QMI: + priv->CustomerID = RT_CID_87B_QMI; + break; + + case EEPROM_CID_DELL: + priv->CustomerID = RT_CID_87B_DELL; + break; + + default: + // Invalid value, so, we use default value instead. + priv->CustomerID = RT_CID_DEFAULT; + break; + } + } + switch(priv->CustomerID) + { + case RT_CID_DEFAULT: + priv->LedStrategy = SW_LED_MODE0; + break; + + case RT_CID_8187_ALPHA0: + priv->LedStrategy = SW_LED_MODE1; + break; + + case RT_CID_8187_SERCOMM_PS: + priv->LedStrategy = SW_LED_MODE3; + break; + + case RT_CID_87B_QMI: + priv->LedStrategy = SW_LED_MODE4; + break; + + case RT_CID_87B_DELL: + priv->LedStrategy = SW_LED_MODE5; + break; + + case RT_CID_8187_HW_LED: + priv->LedStrategy = HW_LED; + break; + + default: + priv->LedStrategy = SW_LED_MODE0; + break; + } + + InitLed8187(dev, + &(priv->Gpio0Led), + LED_PIN_GPIO0, + Gpio0LedBlinkTimerCallback); +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20) + INIT_WORK(&priv->Gpio0LedWorkItem, + (void(*)(void*))Gpio0LedWorkItemCallback, dev); + + InitLed8187(dev, + &(priv->SwLed0), + LED_PIN_LED0, + SwLed0BlinkTimerCallback); + INIT_WORK(&priv->SwLed0WorkItem, + (void(*)(void*))SwLed0WorkItemCallback, dev); + + InitLed8187(dev, + &(priv->SwLed1), + LED_PIN_LED1, + SwLed1BlinkTimerCallback); + INIT_WORK(&priv->SwLed1WorkItem, + (void(*)(void*))SwLed1WorkItemCallback, dev); +#else +INIT_WORK(&priv->Gpio0LedWorkItem, + Gpio0LedWorkItemCallback); + + InitLed8187(dev, + &(priv->SwLed0), + LED_PIN_LED0, + SwLed0BlinkTimerCallback); + INIT_WORK(&priv->SwLed0WorkItem, + SwLed0WorkItemCallback); + + InitLed8187(dev, + &(priv->SwLed1), + LED_PIN_LED1, + SwLed1BlinkTimerCallback); + INIT_WORK(&priv->SwLed1WorkItem, + SwLed1WorkItemCallback); +#endif +} + +void +DeInitSwLeds( + struct net_device *dev + ) +{ + struct r8180_priv *priv = ieee80211_priv(dev); + +// printk("=========>%s In\n", __FUNCTION__); + DeInitLed8187(dev, &(priv->Gpio0Led)); + DeInitLed8187(dev, &(priv->SwLed0)); + DeInitLed8187(dev, &(priv->SwLed1)); +} + +void +InitLed8187( + struct net_device *dev, + PLED_8187 pLed, + LED_PIN_8187 LedPin, + void * BlinkCallBackFunc) +{ +// printk("=========>%s In\n", __FUNCTION__); + pLed->LedPin = LedPin; + + pLed->bLedOn = 0; + pLed->CurrLedState = LED_OFF; + + pLed->bLedBlinkInProgress = 0; + pLed->BlinkTimes = 0; + pLed->BlinkingLedState = LED_OFF; + + init_timer(&(pLed->BlinkTimer)); + pLed->BlinkTimer.data = (unsigned long)dev; + pLed->BlinkTimer.function = BlinkCallBackFunc; + //PlatformInitializeTimer(dev, &(pLed->BlinkTimer), BlinkCallBackFunc); +} + +void +DeInitLed8187( + struct net_device *dev, + PLED_8187 pLed) +{ + //printk("=========>%s In\n", __FUNCTION__); + //PlatformCancelTimer(dev, &(pLed->BlinkTimer)); + del_timer_sync(&(pLed->BlinkTimer)); + // We should reset bLedBlinkInProgress if we cancel the LedControlTimer, 2005.03.10, by rcnjko. + pLed->bLedBlinkInProgress = 0; +} + +void +LedControl8187( + struct net_device *dev, + LED_CTL_MODE LedAction +) +{ + struct r8180_priv *priv = ieee80211_priv(dev); +// printk("=========>%s In\n", __FUNCTION__); + if( priv->bEnableLedCtrl == 0) + return; + + + if( priv->eRFPowerState != eRfOn && + (LedAction == LED_CTL_TX || LedAction == LED_CTL_RX || + LedAction == LED_CTL_SITE_SURVEY || + LedAction == LED_CTL_LINK || + LedAction == LED_CTL_NO_LINK) ) + { + return; + } + + + switch(priv->LedStrategy) + { + case SW_LED_MODE0: + SwLedControlMode0(dev, LedAction); + break; + + case SW_LED_MODE1: + SwLedControlMode1(dev, LedAction); + break; + + case SW_LED_MODE2: + SwLedControlMode2(dev, LedAction); + break; + + case SW_LED_MODE3: + SwLedControlMode3(dev, LedAction); + break; + case SW_LED_MODE4: + SwLedControlMode4(dev, LedAction); + break; + + case SW_LED_MODE5: + SwLedControlMode5(dev, LedAction); + break; + + default: + break; + } +} + + +// +// Description: +// Implement each led action for SW_LED_MODE0. +// This is default strategy. +// +void +SwLedControlMode0( + struct net_device *dev, + LED_CTL_MODE LedAction +) +{ + struct r8180_priv *priv = ieee80211_priv(dev); + PLED_8187 pLed = &(priv->Gpio0Led); + +// printk("===+++++++++++++++======>%s In\n", __FUNCTION__); + // Decide led state + switch(LedAction) + { + case LED_CTL_TX: + case LED_CTL_RX: + if( pLed->bLedBlinkInProgress == 0 ) + { + pLed->CurrLedState = LED_BLINK_NORMAL; + pLed->BlinkTimes = 2; + // printk("===========>LED_CTL_TX/RX \n"); + } + else + { + return; + } + break; + + case LED_CTL_SITE_SURVEY: + if( pLed->bLedBlinkInProgress == 0 ) + { + pLed->CurrLedState = LED_BLINK_SLOWLY; + // pLed->BlinkTimes = 10; + //printk("===========>LED_CTL_SURVEY \n"); + } + else + { + return; + } + break; + + case LED_CTL_LINK: + // printk("===========>associate commplite LED_CTL_LINK\n"); + pLed->CurrLedState = LED_ON; + break; + + case LED_CTL_NO_LINK: + pLed->CurrLedState = LED_OFF; + break; + + case LED_CTL_POWER_ON: + // printk("===========>LED_CTL_POWER_ON\n"); + pLed->CurrLedState = LED_POWER_ON_BLINK; + break; + + case LED_CTL_POWER_OFF: + pLed->CurrLedState = LED_OFF; + break; + + default: + return; + break; + } + + // Change led state. + switch(pLed->CurrLedState) + { + case LED_ON: + if( pLed->bLedBlinkInProgress == 0 ) + { + SwLedOn(dev, pLed); + } + break; + + case LED_OFF://modified by lizhaoming 2008.6.23 + // if( pLed->bLedBlinkInProgress == 0 ) + // { + // SwLedOff(dev, pLed); + // } + + if(pLed->bLedBlinkInProgress )/////////lizhaoming + { + del_timer_sync(&(pLed->BlinkTimer)); + pLed->bLedBlinkInProgress = FALSE; + } + SwLedOff(dev, pLed); + break; + + case LED_BLINK_NORMAL: + if( pLed->bLedBlinkInProgress == 0 ) + { + pLed->bLedBlinkInProgress = 1; + if( pLed->bLedOn ) + pLed->BlinkingLedState = LED_OFF; + else + pLed->BlinkingLedState = LED_ON; + + //pLed->BlinkTimer.expires = jiffies + LED_BLINK_NORMAL_INTERVAL; + //add_timer(&(pLed->BlinkTimer)); + mod_timer(&pLed->BlinkTimer, jiffies + MSECS(LED_BLINK_NORMAL_INTERVAL)); + //PlatformSetTimer(dev, &(pLed->BlinkTimer), LED_BLINK_NORMAL_INTERVAL); + } + break; + + case LED_BLINK_SLOWLY: + if( pLed->bLedBlinkInProgress == 0 ) + { + //printk("=======>%s SLOWLY\n", __func__); + pLed->bLedBlinkInProgress = 1; + // if( pLed->bLedOn ) + pLed->BlinkingLedState = LED_OFF;//for LED_SHIN is LED on + // else + // pLed->BlinkingLedState = LED_ON; + + mod_timer(&pLed->BlinkTimer, jiffies + MSECS(LED_BLINK_SLOWLY_INTERVAL)); + } + break; + + case LED_POWER_ON_BLINK: + SwLedOn(dev, pLed); +#ifdef LED_SHIN + mdelay(100); + SwLedOff(dev, pLed); +#endif + break; + + default: + break; + } +} + +// +// Description: +// Implement each led action for SW_LED_MODE1. +// For example, this is applied by ALPHA. +// +void +SwLedControlMode1( + struct net_device *dev, + LED_CTL_MODE LedAction +) +{ + struct r8180_priv *priv = ieee80211_priv(dev); + PLED_8187 pLed0 = &(priv->SwLed0); + PLED_8187 pLed1 = &(priv->SwLed1); +// printk("=====++++++++++++++++++++++====>%s In\n", __FUNCTION__); + + switch(LedAction) + { + case LED_CTL_TX: + if( pLed0->bLedBlinkInProgress == 0 ) + { + pLed0->CurrLedState = LED_BLINK_NORMAL; + pLed0->BlinkTimes = 2; + pLed0->bLedBlinkInProgress = 1; + if( pLed0->bLedOn ) + pLed0->BlinkingLedState = LED_OFF; + else + pLed0->BlinkingLedState = LED_ON; + + //pLed0->BlinkTimer.expires = jiffies + LED_BLINK_NORMAL_INTERVAL; + //add_timer(&(pLed0->BlinkTimer)); + mod_timer(&pLed0->BlinkTimer, jiffies + MSECS(LED_BLINK_NORMAL_INTERVAL)); + //PlatformSetTimer(dev, &(pLed0->BlinkTimer), LED_BLINK_NORMAL_INTERVAL); + } + break; + + case LED_CTL_LINK: + pLed0->CurrLedState = LED_ON; + if( pLed0->bLedBlinkInProgress == 0 ) + { + SwLedOn(dev, pLed0); + } + break; + + case LED_CTL_NO_LINK: + pLed0->CurrLedState = LED_OFF; + if( pLed0->bLedBlinkInProgress == 0 ) + { + SwLedOff(dev, pLed0); + } + break; + + case LED_CTL_POWER_ON: + pLed0->CurrLedState = LED_OFF; + SwLedOff(dev, pLed0); + + pLed1->CurrLedState = LED_ON; + SwLedOn(dev, pLed1); + + break; + + case LED_CTL_POWER_OFF: + pLed0->CurrLedState = LED_OFF; + SwLedOff(dev, pLed0); + + pLed1->CurrLedState = LED_OFF; + SwLedOff(dev, pLed1); + break; + + case LED_CTL_SITE_SURVEY: + if( pLed0->bLedBlinkInProgress == 0 ) + { + pLed0->CurrLedState = LED_BLINK_SLOWLY;; + pLed0->BlinkTimes = 10; + pLed0->bLedBlinkInProgress = 1; + if( pLed0->bLedOn ) + pLed0->BlinkingLedState = LED_OFF; + else + pLed0->BlinkingLedState = LED_ON; + + //pLed0->BlinkTimer.expires = jiffies + LED_BLINK_SLOWLY_INTERVAL; + //add_timer(&(pLed0->BlinkTimer)); + mod_timer(&pLed0->BlinkTimer, jiffies + MSECS(LED_BLINK_SLOWLY_INTERVAL)); + //PlatformSetTimer(dev, &(pLed0->BlinkTimer), LED_BLINK_SLOWLY_INTERVAL); + } + break; + + default: + break; + } +} + +// +// Description: +// Implement each led action for SW_LED_MODE2, +// which is customized for AzWave 8187 minicard. +// 2006.04.03, by rcnjko. +// +void +SwLedControlMode2( + struct net_device *dev, + LED_CTL_MODE LedAction +) +{ + struct r8180_priv *priv = ieee80211_priv(dev); + PLED_8187 pLed = &(priv->Gpio0Led); + +// printk("====+++++++++++++++++++++=====>%s In\n", __FUNCTION__); + // Decide led state + switch(LedAction) + { + case LED_CTL_TX: + case LED_CTL_RX: + if( pLed->bLedBlinkInProgress == 0 ) + { + pLed->bLedBlinkInProgress = 1; + + pLed->CurrLedState = LED_BLINK_NORMAL; + pLed->BlinkTimes = 2; + + if( pLed->bLedOn ) + pLed->BlinkingLedState = LED_OFF; + else + pLed->BlinkingLedState = LED_ON; + + //pLed->BlinkTimer.expires = jiffies + LED_BLINK_NORMAL_INTERVAL; + //add_timer(&(pLed->BlinkTimer)); + mod_timer(&pLed->BlinkTimer, jiffies + MSECS(LED_BLINK_NORMAL_INTERVAL)); + //PlatformSetTimer(dev, &(pLed->BlinkTimer), LED_BLINK_NORMAL_INTERVAL); + } + break; + + case LED_CTL_SITE_SURVEY: + if( pLed->bLedBlinkInProgress == 0 ) + { + pLed->bLedBlinkInProgress = 1; + + //if( dev->MgntInfo.mAssoc || + // dev->MgntInfo.mIbss ) + //{ + pLed->CurrLedState = LED_SCAN_BLINK; + pLed->BlinkTimes = 4; + //} + //else + //{ + // pLed->CurrLedState = LED_NO_LINK_BLINK; + // pLed->BlinkTimes = 24; + //} + + if( pLed->bLedOn ) + { + pLed->BlinkingLedState = LED_OFF; + //pLed->BlinkTimer.expires = jiffies + LED_CM2_BLINK_ON_INTERVAL; + //add_timer(&(pLed->BlinkTimer)); + mod_timer(&pLed->BlinkTimer, jiffies + MSECS(LED_CM2_BLINK_ON_INTERVAL)); + //PlatformSetTimer(dev, &(pLed->BlinkTimer), LED_CM2_BLINK_ON_INTERVAL); + } + else + { + pLed->BlinkingLedState = LED_ON; + //pLed->BlinkTimer.expires = jiffies + LED_CM2_BLINK_OFF_INTERVAL; + //add_timer(&(pLed->BlinkTimer)); + mod_timer(&pLed->BlinkTimer, jiffies + MSECS(LED_CM2_BLINK_OFF_INTERVAL)); + //PlatformSetTimer(dev, &(pLed->BlinkTimer), LED_CM2_BLINK_OFF_INTERVAL); + } + } + else + { + if(pLed->CurrLedState != LED_NO_LINK_BLINK) + { + pLed->CurrLedState = LED_SCAN_BLINK; + /* + if( dev->MgntInfo.mAssoc || + dev->MgntInfo.mIbss ) + { + pLed->CurrLedState = LED_SCAN_BLINK; + } + else + { + pLed->CurrLedState = LED_NO_LINK_BLINK; + } + */ + } + } + break; + + case LED_CTL_NO_LINK: + if( pLed->bLedBlinkInProgress == 0 ) + { + pLed->bLedBlinkInProgress = 1; + + pLed->CurrLedState = LED_NO_LINK_BLINK; + pLed->BlinkTimes = 24; + + if( pLed->bLedOn ) + { + pLed->BlinkingLedState = LED_OFF; + //pLed->BlinkTimer.expires = jiffies + LED_CM2_BLINK_ON_INTERVAL; + //add_timer(&(pLed->BlinkTimer)); + mod_timer(&pLed->BlinkTimer, jiffies + MSECS(LED_CM2_BLINK_ON_INTERVAL)); + //PlatformSetTimer(dev, &(pLed->BlinkTimer), LED_CM2_BLINK_ON_INTERVAL); + } + else + { + pLed->BlinkingLedState = LED_ON; + //pLed->BlinkTimer.expires = jiffies + LED_CM2_BLINK_OFF_INTERVAL; + //add_timer(&(pLed->BlinkTimer)); + mod_timer(&pLed->BlinkTimer, jiffies + MSECS(LED_CM2_BLINK_OFF_INTERVAL)); + //PlatformSetTimer(dev, &(pLed->BlinkTimer), LED_CM2_BLINK_OFF_INTERVAL); + } + } + else + { + pLed->CurrLedState = LED_NO_LINK_BLINK; + } + break; + + case LED_CTL_LINK: + pLed->CurrLedState = LED_ON; + if( pLed->bLedBlinkInProgress == 0 ) + { + SwLedOn(dev, pLed); + } + break; + + case LED_CTL_POWER_OFF: + pLed->CurrLedState = LED_OFF; + if( pLed->bLedBlinkInProgress == 0 ) + { + SwLedOff(dev, pLed); + } + break; + + default: + break; + } +} + + +// +// Description: +// Implement each led action for SW_LED_MODE3, +// which is customized for Sercomm Printer Server case. +// 2006.04.21, by rcnjko. +// +void +SwLedControlMode3( + struct net_device *dev, + LED_CTL_MODE LedAction +) +{ + struct r8180_priv *priv = ieee80211_priv(dev); + PLED_8187 pLed = &(priv->Gpio0Led); + +// printk("=====+++++++++++++++++++====>%s In\n", __FUNCTION__); + // Decide led state + switch(LedAction) + { + case LED_CTL_TX: + case LED_CTL_RX: + if( pLed->bLedBlinkInProgress == 0 ) + { + pLed->bLedBlinkInProgress = 1; + + pLed->CurrLedState = LED_BLINK_CM3; + pLed->BlinkTimes = 2; + + if( pLed->bLedOn ) + pLed->BlinkingLedState = LED_OFF; + else + pLed->BlinkingLedState = LED_ON; + + //pLed->BlinkTimer.expires = jiffies + LED_CM3_BLINK_INTERVAL; + //add_timer(&(pLed->BlinkTimer)); + mod_timer(&pLed->BlinkTimer, jiffies + MSECS(LED_CM3_BLINK_INTERVAL)); + //PlatformSetTimer(dev, &(pLed->BlinkTimer), LED_CM3_BLINK_INTERVAL); + } + break; + + case LED_CTL_SITE_SURVEY: + if( pLed->bLedBlinkInProgress == 0 ) + { + pLed->bLedBlinkInProgress = 1; + + pLed->CurrLedState = LED_BLINK_CM3; + pLed->BlinkTimes = 10; + + if( pLed->bLedOn ) + pLed->BlinkingLedState = LED_OFF; + else + pLed->BlinkingLedState = LED_ON; + + //pLed->BlinkTimer.expires = jiffies + LED_CM3_BLINK_INTERVAL; + //add_timer(&(pLed->BlinkTimer)); + mod_timer(&pLed->BlinkTimer, jiffies + MSECS(LED_CM3_BLINK_INTERVAL)); + //PlatformSetTimer(dev, &(pLed->BlinkTimer), LED_CM3_BLINK_INTERVAL); + } + break; + + case LED_CTL_LINK: + pLed->CurrLedState = LED_ON; + if( pLed->bLedBlinkInProgress == 0 ) + { + SwLedOn(dev, pLed); + } + break; + + case LED_CTL_NO_LINK: + pLed->CurrLedState = LED_OFF; + if( pLed->bLedBlinkInProgress == 0 ) + { + SwLedOff(dev, pLed); + } + break; + + case LED_CTL_POWER_ON: + pLed->CurrLedState = LED_POWER_ON_BLINK; + SwLedOn(dev, pLed); + mdelay(100); + SwLedOff(dev, pLed); + break; + + case LED_CTL_POWER_OFF: + pLed->CurrLedState = LED_OFF; + if( pLed->bLedBlinkInProgress == 0 ) + { + SwLedOff(dev, pLed); + } + break; + + default: + break; + } +} + +// added by lizhaoming 2008.6.2 +// +// Description: +// Implement each led action for SW_LED_MODE4, +// which is customized for QMI 8187B minicard. +// 2008.04.21, by chiyokolin. +// +void +SwLedControlMode4( + struct net_device *dev, + LED_CTL_MODE LedAction + ) +{ + struct r8180_priv *priv = ieee80211_priv(dev); + PLED_8187 pLed = &(priv->Gpio0Led); + + //printk("=====+++++++++++++++++++++====>%s In\n", __FUNCTION__); + // Decide led state + switch(LedAction) + { + case LED_CTL_TX: + case LED_CTL_RX: + //if( pLed->bLedBlinkInProgress == false && !priv->bScanInProgress)//????? + if( pLed->bLedBlinkInProgress == 0) + { + pLed->bLedBlinkInProgress = 1; + + pLed->CurrLedState = LED_BLINK_NORMAL; + pLed->BlinkTimes = 2; + + if( pLed->bLedOn ) + pLed->BlinkingLedState = LED_OFF; + else + pLed->BlinkingLedState = LED_ON; + + //pLed->BlinkTimer.expires = jiffies + LED_BLINK_NORMAL_INTERVAL; + //add_timer(&(pLed->BlinkTimer)); + mod_timer(&pLed->BlinkTimer, jiffies + MSECS(LED_BLINK_NORMAL_INTERVAL)); + //PlatformSetTimer(Adapter, &(pLed->BlinkTimer), LED_BLINK_NORMAL_INTERVAL); + } + else + //printk("----->LED_CTL_RX/TX bLedBlinkInProgress\n"); + + break; + + case LED_CTL_SITE_SURVEY: + if( pLed->bLedBlinkInProgress == 0 ) + { + + pLed->bLedBlinkInProgress = 1; + //if( priv->MgntInfo.mAssoc || priv->MgntInfo.mIbss )//////////?????? + //{ + pLed->CurrLedState = LED_SCAN_BLINK; + pLed->BlinkTimes = 10; + + pLed->BlinkingLedState = LED_ON; + + //pLed->BlinkTimer.expires = jiffies + LED_BLINK_NORMAL_INTERVAL; + //add_timer(&(pLed->BlinkTimer)); + mod_timer(&pLed->BlinkTimer, jiffies + MSECS(LED_BLINK_NORMAL_INTERVAL)); + //PlatformSetTimer(Adapter, &(pLed->BlinkTimer), LED_BLINK_NORMAL_INTERVAL); + //} + //else + //{ + // pLed->CurrLedState = LED_NO_LINK_BLINK; + // pLed->BlinkTimes = 24; + // + // if( pLed->bLedOn ) + // { + // pLed->BlinkingLedState = LED_OFF; + // + // pLed->BlinkTimer.expires = jiffies + LED_CM4_BLINK_ON_INTERVAL; + // add_timer(&(pLed->BlinkTimer)); + // //PlatformSetTimer(Adapter, &(pLed->BlinkTimer), LED_CM4_BLINK_ON_INTERVAL); + // } + // else + // { + // pLed->BlinkingLedState = LED_ON; + + // pLed->BlinkTimer.expires = jiffies + LED_CM4_BLINK_OFF_INTERVAL; + // add_timer(&(pLed->BlinkTimer)); + // //PlatformSetTimer(Adapter, &(pLed->BlinkTimer), LED_CM4_BLINK_OFF_INTERVAL); + // } + //} + } + else + { + if(pLed->CurrLedState != LED_NO_LINK_BLINK) + { + //if( priv->MgntInfo.mAssoc || priv->MgntInfo.mIbss )//??????????? + //{ + //} + //else + //{ + // pLed->CurrLedState = LED_NO_LINK_BLINK; + //} + } + + //printk("----->LED_CTL_SITE_SURVEY bLedBlinkInProgress\n"); + } + break; + + case LED_CTL_NO_LINK: + if( pLed->bLedBlinkInProgress == 0 ) + { + pLed->bLedBlinkInProgress = 1; + + pLed->CurrLedState = LED_NO_LINK_BLINK; + pLed->BlinkTimes = 24; + + if( pLed->bLedOn ) + { + pLed->BlinkingLedState = LED_OFF; + + //pLed->BlinkTimer.expires = jiffies + LED_CM4_BLINK_ON_INTERVAL; + //add_timer(&(pLed->BlinkTimer)); + mod_timer(&pLed->BlinkTimer, jiffies + MSECS(LED_CM4_BLINK_ON_INTERVAL)); + //PlatformSetTimer(Adapter, &(pLed->BlinkTimer), LED_CM4_BLINK_ON_INTERVAL); + } + else + { + pLed->BlinkingLedState = LED_ON; + + //pLed->BlinkTimer.expires = jiffies + LED_CM4_BLINK_OFF_INTERVAL; + //add_timer(&(pLed->BlinkTimer)); + mod_timer(&pLed->BlinkTimer, jiffies + MSECS(LED_CM4_BLINK_OFF_INTERVAL)); + //PlatformSetTimer(Adapter, &(pLed->BlinkTimer), LED_CM4_BLINK_OFF_INTERVAL); + } + } + else + { + pLed->CurrLedState = LED_NO_LINK_BLINK; + //printk("----->LED_CTL_NO_LINK bLedBlinkInProgress\n"); + } + break; + + case LED_CTL_LINK: + pLed->CurrLedState = LED_ON; + if( pLed->bLedBlinkInProgress == 0) + { + SwLedOn(dev, pLed); + } + else + ;//printk("----->LED_CTL_LINK bLedBlinkInProgress\n"); + + break; + + case LED_CTL_POWER_OFF: + pLed->CurrLedState = LED_OFF; + if(pLed->bLedBlinkInProgress) + { + printk("----->LED_CTL_POWER_OFF bLedBlinkInProgress\n"); + + //PlatformCancelTimer(Adapter, &(pLed->BlinkTimer)); + del_timer_sync(&(pLed->BlinkTimer)); + pLed->bLedBlinkInProgress = 0; + } + SwLedOff(dev, pLed); + break; + + default: + break; + } +} + + + +//added by lizhaoming 2008.6.3 +// +// Description: +// Implement each led action for SW_LED_MODE5, +// which is customized for DELL 8187B minicard. +// 2008.04.24, by chiyokolin. +// +void +SwLedControlMode5( + struct net_device *dev, + LED_CTL_MODE LedAction + ) +{ + struct r8180_priv *priv = ieee80211_priv(dev); + PLED_8187 pLed = &(priv->Gpio0Led); + + // Decide led state + //printk("====++++++++++++++++++++++=====>%s In\n", __FUNCTION__); + switch(LedAction) + { + case LED_CTL_TX: + case LED_CTL_RX: + case LED_CTL_SITE_SURVEY: + case LED_CTL_POWER_ON: + case LED_CTL_NO_LINK: + case LED_CTL_LINK: + pLed->CurrLedState = LED_ON; + if( pLed->bLedBlinkInProgress == 0 ) + { + pLed->bLedBlinkInProgress = 1; + if(! pLed->bLedOn ) + pLed->BlinkingLedState = LED_ON; + else + break; + + //printk("====++++++++++++++++++++++=====>%s In LED:%d\n", __FUNCTION__, pLed->bLedOn); + //pLed->BlinkTimer.expires = jiffies + LED_BLINK_NORMAL_INTERVAL; + //add_timer(&(pLed->BlinkTimer)); + mod_timer(&pLed->BlinkTimer, jiffies + MSECS(LED_BLINK_NORMAL_INTERVAL)); + // SwLedOn(dev, pLed); + } + else + ;//printk("----->LED_CTL_LINK bLedBlinkInProgress\n"); + + break; + + case LED_CTL_POWER_OFF: + pLed->CurrLedState = LED_OFF; + // printk("<====++++++++++++++++++++++=====%s In LED:%d\n", __FUNCTION__, pLed->bLedOn); + if(pLed->bLedBlinkInProgress) + { + // printk("----->LED_CTL_POWER_OFF bLedBlinkInProgress\n"); + + //PlatformCancelTimer(Adapter, &(pLed->BlinkTimer)); + del_timer_sync(&(pLed->BlinkTimer)); + pLed->bLedBlinkInProgress = 0; + } + SwLedOff(dev, pLed); + break; + + default: + break; + } +} + +// +// Callback fuction of the timer, Gpio0Led.BlinkTimer. +// +void +Gpio0LedBlinkTimerCallback( + unsigned long data + ) +{ + struct net_device *dev = (struct net_device *)data; + struct r8180_priv *priv = ieee80211_priv(dev); + +// printk("=========>%s In\n", __FUNCTION__); + PlatformSwLedBlink(dev, &(priv->Gpio0Led)); +} + + + +// +// Callback fuction of the timer, SwLed0.BlinkTimer. +// +void +SwLed0BlinkTimerCallback( + unsigned long data + ) +{ + struct net_device *dev = (struct net_device *)data; + struct r8180_priv *priv = ieee80211_priv(dev); + +// printk("=========>%s In\n", __FUNCTION__); + PlatformSwLedBlink(dev, &(priv->SwLed0)); +} + + + +// +// Callback fuction of the timer, SwLed1.BlinkTimer. +// +void +SwLed1BlinkTimerCallback( + unsigned long data + ) +{ + struct net_device *dev = (struct net_device *)data; + struct r8180_priv *priv = ieee80211_priv(dev); + +// printk("=========>%s In\n", __FUNCTION__); + PlatformSwLedBlink(dev, &(priv->SwLed1)); +} + +void +PlatformSwLedBlink( + struct net_device *dev, + PLED_8187 pLed + ) +{ + struct r8180_priv *priv = ieee80211_priv(dev); + +// printk("=========>%s In\n", __FUNCTION__); + switch(pLed->LedPin) + { + case LED_PIN_GPIO0: + schedule_work(&(priv->Gpio0LedWorkItem)); + break; + + case LED_PIN_LED0: + schedule_work(&(priv->SwLed0WorkItem)); + break; + + case LED_PIN_LED1: + schedule_work(&(priv->SwLed1WorkItem)); + break; + + default: + break; + } +} + +// +// Callback fucntion of the workitem for SW LEDs. +// 2006.03.01, by rcnjko. +// + +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20) +void Gpio0LedWorkItemCallback(struct work_struct *work) +{ + struct r8180_priv *priv = container_of(work, struct r8180_priv,Gpio0LedWorkItem); + struct net_device *dev = priv->ieee80211->dev; +#else +void +Gpio0LedWorkItemCallback( + void * Context + ) +{ + struct net_device *dev = (struct net_device *)Context; + struct r8180_priv *priv = ieee80211_priv(dev); +#endif + PLED_8187 pLed = &(priv->Gpio0Led); + if (priv == NULL || dev == NULL){ +// printk("=========>%s In\n", __FUNCTION__); + //printk("ft=====================>%s()\n", __FUNCTION__); + } + +#if 0 // by lizahoming 2008.6.3 + if(priv->LedStrategy == SW_LED_MODE2) + SwLedCm2Blink(dev, pLed); + else + SwLedBlink(dev, pLed); +#endif + +#if 1 // by lizahoming 2008.6.3 + switch(priv->LedStrategy) + { + case SW_LED_MODE2: + SwLedCm2Blink(dev, pLed); + break; + case SW_LED_MODE4: + SwLedCm4Blink(dev, pLed); + break; + default: + SwLedBlink(dev, pLed); + break; + } +#endif + + //LeaveCallbackOfRtWorkItem( &(usbdevice->Gpio0LedWorkItem) ); +} + +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20) +void SwLed0WorkItemCallback(struct work_struct *work) +{ + //struct r8180_priv *priv = container_of(work, struct r8180_priv, SwLed0WorkItem); + //struct net_device *dev = priv->dev; +#else +void SwLed0WorkItemCallback(void * Context) +{ + //struct net_device *dev = (struct net_device *)Context; + //struct r8180_priv *priv = ieee80211_priv(dev); +#endif + //SwLedBlink(dev, &(priv->SwLed0)); +// printk("=========>%s In\n", __FUNCTION__); + + //LeaveCallbackOfRtWorkItem( &(usbdevice->SwLed0WorkItem) ); +} + +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20) +void SwLed1WorkItemCallback(struct work_struct *work) +{ + //struct r8180_priv *priv = container_of(work, struct r8180_priv, SwLed1WorkItem); +// struct net_device *dev = priv->dev; +#else +void +SwLed1WorkItemCallback( + void * Context + ) +{ + //struct net_device *dev = (struct net_device *)Context; + //struct r8180_priv *priv = ieee80211_priv(dev); +#endif +// printk("=========>%s In\n", __FUNCTION__); + //SwLedBlink(dev, &(priv->SwLed1)); + + //LeaveCallbackOfRtWorkItem( &(usbdevice->SwLed1WorkItem) ); +} + +// +// Implementation of LED blinking behavior. +// It toggle off LED and schedule corresponding timer if necessary. +// +void +SwLedBlink( + struct net_device *dev, + PLED_8187 pLed + ) +{ + u8 bStopBlinking = 0; + + //printk("=========>%s In state:%d\n", __FUNCTION__, pLed->CurrLedState); + // Change LED according to BlinkingLedState specified. + if( pLed->BlinkingLedState == LED_ON ) + { + SwLedOn(dev, pLed); +// printk("Blinktimes (%d): turn on\n", pLed->BlinkTimes); + } + else + { + SwLedOff(dev, pLed); +// printk("Blinktimes (%d): turn off\n", pLed->BlinkTimes); + } + + // Determine if we shall change LED state again. +//by lizhaoming for LED BLINK SLOWLY + if(pLed->CurrLedState == LED_BLINK_SLOWLY) + { + bStopBlinking = 0; + } else { + pLed->BlinkTimes--; + if( pLed->BlinkTimes == 0 ) + { + bStopBlinking = 1; + } + else + { + if( pLed->CurrLedState != LED_BLINK_NORMAL && + pLed->CurrLedState != LED_BLINK_SLOWLY && + pLed->CurrLedState != LED_BLINK_CM3 ) + { + bStopBlinking = 1; + } + } + } + + if(bStopBlinking) + { + if( pLed->CurrLedState == LED_ON && pLed->bLedOn == 0) + { + SwLedOn(dev, pLed); + } + else if(pLed->CurrLedState == LED_OFF && pLed->bLedOn == 1) + { + SwLedOff(dev, pLed); + } + + pLed->BlinkTimes = 0; + pLed->bLedBlinkInProgress = 0; + } + else + { + // Assign LED state to toggle. + if( pLed->BlinkingLedState == LED_ON ) + pLed->BlinkingLedState = LED_OFF; + else + pLed->BlinkingLedState = LED_ON; + + // Schedule a timer to toggle LED state. + switch( pLed->CurrLedState ) + { + case LED_BLINK_NORMAL: + //printk("LED_BLINK_NORMAL:Blinktimes (%d): turn off\n", pLed->BlinkTimes+1); + //pLed->BlinkTimer.expires = jiffies + LED_BLINK_NORMAL_INTERVAL; + //add_timer(&(pLed->BlinkTimer)); + mod_timer(&pLed->BlinkTimer, jiffies + MSECS(LED_BLINK_NORMAL_INTERVAL)); + //PlatformSetTimer(dev, &(pLed->BlinkTimer), LED_BLINK_NORMAL_INTERVAL); + break; + + case LED_BLINK_SLOWLY: + if( pLed->bLedOn == 1 ) + { + //printk("LED_BLINK_SLOWLY:turn off\n"); + //pLed->BlinkTimer.expires = jiffies + LED_BLINK_SLOWLY_INTERVAL+50;//for pcie mini card spec page 33, 250ms + //add_timer(&(pLed->BlinkTimer)); + mod_timer(&pLed->BlinkTimer, jiffies + MSECS(LED_BLINK_SLOWLY_INTERVAL+50)); + pLed->BlinkingLedState = LED_OFF; + } else { + //printk("LED_BLINK_SLOWLY:turn on\n"); + //pLed->BlinkTimer.expires = jiffies + 5000;//for pcie mini card spec page 33, 5s + //add_timer(&(pLed->BlinkTimer)); + mod_timer(&pLed->BlinkTimer, jiffies + MSECS(5000)); + pLed->BlinkingLedState = LED_ON; + } + break; + + case LED_BLINK_CM3: + //printk("LED_BLINK_CM3:Blinktimes (%d): turn off\n", pLed->BlinkTimes+1); + //pLed->BlinkTimer.expires = jiffies + LED_CM3_BLINK_INTERVAL; + //add_timer(&(pLed->BlinkTimer)); + mod_timer(&pLed->BlinkTimer, jiffies + MSECS(LED_CM3_BLINK_INTERVAL)); + //PlatformSetTimer(dev, &(pLed->BlinkTimer), LED_CM3_BLINK_INTERVAL); + break; + + default: + //printk("LED_BLINK_default:Blinktimes (%d): turn off\n", pLed->BlinkTimes+1); + //pLed->BlinkTimer.expires = jiffies + LED_BLINK_SLOWLY_INTERVAL; + //add_timer(&(pLed->BlinkTimer)); + mod_timer(&pLed->BlinkTimer, jiffies + MSECS(LED_BLINK_SLOWLY_INTERVAL)); + //PlatformSetTimer(dev, &(pLed->BlinkTimer), LED_BLINK_SLOWLY_INTERVAL); + break; + } + } +} + + + +// +// Implementation of LED blinking behavior for SwLedControlMode2. +// +void +SwLedCm2Blink( + struct net_device *dev, + PLED_8187 pLed + ) +{ + struct r8180_priv *priv = ieee80211_priv(dev); + //PMGNT_INFO priv = &(dev->MgntInfo); + u8 bStopBlinking = 0; + + //printk("========+++++++++++++=>%s In\n", __FUNCTION__); + //To avoid LED blinking when rf is off, add by lizhaoming 2008.6.2 + if((priv->eRFPowerState == eRfOff) && (priv->RfOffReason>RF_CHANGE_BY_IPS)) + { + SwLedOff(dev, pLed); + + //pLed->BlinkTimer.expires = jiffies + LED_CM2_BLINK_ON_INTERVAL; + //add_timer(&(pLed->BlinkTimer)); + mod_timer(&pLed->BlinkTimer, jiffies + MSECS(LED_CM2_BLINK_ON_INTERVAL)); + //PlatformSetTimer(Adapter, &(pLed->BlinkTimer), LED_CM2_BLINK_ON_INTERVAL); + //printk(" Hw/Soft Radio Off, turn off Led\n"); + return; + } + + // Change LED according to BlinkingLedState specified. + if( pLed->BlinkingLedState == LED_ON ) + { + SwLedOn(dev, pLed); + //DMESG("Blinktimes (%d): turn on\n", pLed->BlinkTimes); + } + else + { + SwLedOff(dev, pLed); + //DMESG("Blinktimes (%d): turn off\n", pLed->BlinkTimes); + } + + //Add by lizhaoming for avoid BlinkTimers <0, 2008.6.2 + if(pLed->BlinkTimes > 0) + {//by lizhaoming 2008.6.2 + // Determine if we shall change LED state again. + pLed->BlinkTimes--; + }//by lizhaoming 2008.6.2 + + switch(pLed->CurrLedState) + { + case LED_BLINK_NORMAL: + if(pLed->BlinkTimes == 0) + { + bStopBlinking = 1; + } + break; +/* CM2 scan blink and no link blind now not be supported + case LED_SCAN_BLINK: + if( (priv->mAssoc || priv->mIbss) && // Linked. + (!priv->bScanInProgress) && // Not in scan stage. + (pLed->BlinkTimes % 2 == 0)) // Even + { + bStopBlinking = 1; + } + break; + + case LED_NO_LINK_BLINK: + //Revised miniCard Ad-hoc mode "Slow Blink" by Isaiah 2006-08-03 + //if( (priv->mAssoc || priv->mIbss) ) // Linked. + if( priv->mAssoc) + { + bStopBlinking = 1; + } + else if(priv->mIbss && priv->bMediaConnect ) + { + bStopBlinking = 1; + } + break; +*/ + default: + bStopBlinking = 1; + break; + } + + if(bStopBlinking) + { +/* + if( priv->eRFPowerState != eRfOn ) + { + SwLedOff(dev, pLed); + } + else if( priv->bMediaConnect == 1 && pLed->bLedOn == 0) + { + SwLedOn(dev, pLed); + } + else if( priv->bMediaConnect == 0 && pLed->bLedOn == 1) + { + SwLedOff(dev, pLed); + } +*/ + pLed->BlinkTimes = 0; + pLed->bLedBlinkInProgress = 0; + } + else + { + // Assign LED state to toggle. + if( pLed->BlinkingLedState == LED_ON ) + pLed->BlinkingLedState = LED_OFF; + else + pLed->BlinkingLedState = LED_ON; + + // Schedule a timer to toggle LED state. + switch( pLed->CurrLedState ) + { + case LED_BLINK_NORMAL: + //pLed->BlinkTimer.expires = jiffies + LED_BLINK_NORMAL_INTERVAL; + //add_timer(&(pLed->BlinkTimer)); + mod_timer(&pLed->BlinkTimer, jiffies + MSECS(LED_BLINK_NORMAL_INTERVAL)); + //PlatformSetTimer(dev, &(pLed->BlinkTimer), LED_BLINK_NORMAL_INTERVAL); + break; + + case LED_BLINK_SLOWLY: + //pLed->BlinkTimer.expires = jiffies + LED_BLINK_SLOWLY_INTERVAL; + //add_timer(&(pLed->BlinkTimer)); + mod_timer(&pLed->BlinkTimer, jiffies + MSECS(LED_BLINK_SLOWLY_INTERVAL)); + //PlatformSetTimer(dev, &(pLed->BlinkTimer), LED_BLINK_SLOWLY_INTERVAL); + break; + + case LED_SCAN_BLINK: + case LED_NO_LINK_BLINK: + if( pLed->bLedOn ) { + //pLed->BlinkTimer.expires = jiffies + LED_CM2_BLINK_ON_INTERVAL; + //add_timer(&(pLed->BlinkTimer)); + mod_timer(&pLed->BlinkTimer, jiffies + MSECS(LED_CM2_BLINK_ON_INTERVAL)); + //PlatformSetTimer(dev, &(pLed->BlinkTimer), LED_CM2_BLINK_ON_INTERVAL); + } else { + //pLed->BlinkTimer.expires = jiffies + LED_CM2_BLINK_OFF_INTERVAL; + //add_timer(&(pLed->BlinkTimer)); + mod_timer(&pLed->BlinkTimer, jiffies + MSECS(LED_CM2_BLINK_OFF_INTERVAL)); + //PlatformSetTimer(dev, &(pLed->BlinkTimer), LED_CM2_BLINK_OFF_INTERVAL); + } + break; + + default: + //RT_ASSERT(0, ("SwLedCm2Blink(): unexpected state!\n")); + //pLed->BlinkTimer.expires = jiffies + LED_BLINK_SLOWLY_INTERVAL; + //add_timer(&(pLed->BlinkTimer)); + mod_timer(&pLed->BlinkTimer, jiffies + MSECS(LED_BLINK_SLOWLY_INTERVAL)); + //PlatformSetTimer(dev, &(pLed->BlinkTimer), LED_BLINK_SLOWLY_INTERVAL); + break; + } + } +} + +// added by lizhaoming 2008.6.2 +// +// Description: +// Implement LED blinking behavior for SW_LED_MODE4. +// +void +SwLedCm4Blink( + struct net_device *dev, + PLED_8187 pLed + ) +{ + struct r8180_priv *priv = ieee80211_priv(dev); + u8 bStopBlinking = 0; + + printk("======++++++++++++++++++======>%s In\n", __FUNCTION__); + //To avoid LED blinking when rf is off, add by Maddest 20080307 + if((priv->eRFPowerState == eRfOff) && (priv->RfOffReason>RF_CHANGE_BY_IPS)) + { + SwLedOff(dev, pLed); + + //pLed->BlinkTimer.expires = jiffies + LED_CM4_BLINK_ON_INTERVAL; + //add_timer(&(pLed->BlinkTimer)); + mod_timer(&pLed->BlinkTimer, jiffies + MSECS(LED_CM4_BLINK_ON_INTERVAL)); + //PlatformSetTimer(Adapter, &(pLed->BlinkTimer), LED_CM4_BLINK_ON_INTERVAL); + printk(" Hw/Soft Radio Off, turn off Led\n"); + return; + } + // Change LED according to BlinkingLedState specified. + if( pLed->BlinkingLedState == LED_ON ) + { + if(!pLed->bLedOn) + { + SwLedOn(dev, pLed); + } + printk("Blinktimes (%d): turn on\n", pLed->BlinkTimes); + } + else + { + SwLedOff(dev, pLed); + printk("Blinktimes (%d): turn off\n", pLed->BlinkTimes); + } + + //Add by Maddest for avoid BlinkTimers <0, 20080307; + if(pLed->BlinkTimes > 0) + { + // Determine if we shall change LED state again. + pLed->BlinkTimes--; + } + printk("pLed->CurrLedState %d pLed->BlinkTimes %d\n", pLed->CurrLedState,pLed->BlinkTimes); + switch(pLed->CurrLedState) + { + case LED_BLINK_NORMAL: + if(pLed->BlinkTimes == 0) + { + bStopBlinking = 1; + } + break; + +/* CM2 scan blink and no link blind now not be supported + case LED_SCAN_BLINK: + if( (priv->mAssoc || priv->mIbss) && // Linked.//???????????? + (!priv->bScanInProgress) && // Not in scan stage.//???????????? + (pLed->BlinkTimes % 2 == 0)) // Even + { + bStopBlinking = 1; + } + break; + + case LED_NO_LINK_BLINK: + //Revised miniCard Ad-hoc mode "Slow Blink" by Isaiah 2006-08-03 + //if( (pMgntInfo->mAssoc || pMgntInfo->mIbss) ) // Linked. + if( priv->mAssoc) //???????????? + { + bStopBlinking = 1; + } + else if(priv->mIbss && priv->bMediaConnect )//???????????? + { + bStopBlinking = 1; + } + break; +*/ + + default: + bStopBlinking = 1; + break; + } + + if(bStopBlinking) + { + /* + if( priv->eRFPowerState != eRfOn ) + { + SwLedOff(dev, pLed); + } + else if( priv->bMediaConnect == true && pLed->bLedOn == false)//???????????? + { + SwLedOn(dev, pLed); + } + else if( priv->bMediaConnect == false && pLed->bLedOn == true)//???????????? + { + SwLedOff(dev, pLed); + } + */ + + pLed->BlinkTimes = 0; + pLed->bLedBlinkInProgress = 0; + } + else + { + // Assign LED state to toggle. + if( pLed->BlinkingLedState == LED_ON ) + pLed->BlinkingLedState = LED_OFF; + else + pLed->BlinkingLedState = LED_ON; + + // Schedule a timer to toggle LED state. + switch( pLed->CurrLedState ) + { + case LED_BLINK_NORMAL: + //pLed->BlinkTimer.expires = jiffies + LED_BLINK_NORMAL_INTERVAL; + //add_timer(&(pLed->BlinkTimer)); + mod_timer(&pLed->BlinkTimer, jiffies + MSECS(LED_BLINK_NORMAL_INTERVAL)); + //PlatformSetTimer(Adapter, &(pLed->BlinkTimer), LED_BLINK_NORMAL_INTERVAL); + break; + + case LED_BLINK_SLOWLY: + //pLed->BlinkTimer.expires = jiffies + LED_BLINK_SLOWLY_INTERVAL; + //add_timer(&(pLed->BlinkTimer)); + mod_timer(&pLed->BlinkTimer, jiffies + MSECS(LED_BLINK_SLOWLY_INTERVAL)); + //PlatformSetTimer(Adapter, &(pLed->BlinkTimer), LED_BLINK_SLOWLY_INTERVAL); + break; + + case LED_SCAN_BLINK: + pLed->BlinkingLedState = LED_ON; + //pLed->BlinkTimer.expires = jiffies + LED_BLINK_NORMAL_INTERVAL; + //add_timer(&(pLed->BlinkTimer)); + mod_timer(&pLed->BlinkTimer, jiffies + MSECS(LED_BLINK_NORMAL_INTERVAL)); + //PlatformSetTimer(Adapter, &(pLed->BlinkTimer), LED_BLINK_NORMAL_INTERVAL); + + case LED_NO_LINK_BLINK: + if( pLed->bLedOn ){ + //pLed->BlinkTimer.expires = jiffies + LED_CM4_BLINK_ON_INTERVAL; + //add_timer(&(pLed->BlinkTimer)); + mod_timer(&pLed->BlinkTimer, jiffies + MSECS(LED_CM4_BLINK_ON_INTERVAL)); + //PlatformSetTimer(Adapter, &(pLed->BlinkTimer), LED_CM4_BLINK_ON_INTERVAL); + }else{ + //pLed->BlinkTimer.expires = jiffies + LED_CM4_BLINK_OFF_INTERVAL; + //add_timer(&(pLed->BlinkTimer)); + mod_timer(&pLed->BlinkTimer, jiffies + MSECS(LED_CM4_BLINK_OFF_INTERVAL)); + //PlatformSetTimer(Adapter, &(pLed->BlinkTimer), LED_CM4_BLINK_OFF_INTERVAL); + } + break; + + default: + printk("SwLedCm2Blink(): unexpected state!\n"); + //pLed->BlinkTimer.expires = jiffies + LED_BLINK_SLOWLY_INTERVAL; + //add_timer(&(pLed->BlinkTimer)); + mod_timer(&pLed->BlinkTimer, jiffies + MSECS(LED_BLINK_SLOWLY_INTERVAL)); + //PlatformSetTimer(Adapter, &(pLed->BlinkTimer), LED_BLINK_SLOWLY_INTERVAL); + break; + } + } +} + +void +SwLedOn( + struct net_device *dev, + PLED_8187 pLed +) +{ + struct r8180_priv *priv = ieee80211_priv(dev); +// printk("=========>%s(), pin:%d\n", __FUNCTION__, pLed->LedPin); + switch(pLed->LedPin) + { + case LED_PIN_GPIO0: + write_nic_byte(dev,0x0091,0x01); + write_nic_byte(dev,0x0090,0x00); // write 0 : LED on + break; + + case LED_PIN_LED0: + priv->PsrValue &= ~(0x01 << 4); + write_nic_byte(dev, PSR, priv->PsrValue); + break; + + case LED_PIN_LED1: + priv->PsrValue &= ~(0x01 << 5); + write_nic_byte(dev, PSR, priv->PsrValue); + break; + + default: + break; + } + + pLed->bLedOn = 1; +} + +void +SwLedOff( + struct net_device *dev, + PLED_8187 pLed +) +{ + struct r8180_priv *priv = ieee80211_priv(dev); + + + //printk("=========>%s(), pin:%d\n", __FUNCTION__, pLed->LedPin); + switch(pLed->LedPin) + { + case LED_PIN_GPIO0: + write_nic_byte(dev,0x0091,0x01); + write_nic_byte(dev,0x0090,0x01); // write 1 : LED off + break; + + case LED_PIN_LED0: + priv->PsrValue |= (0x01 << 4); + write_nic_byte(dev, PSR, priv->PsrValue); + break; + + case LED_PIN_LED1: + priv->PsrValue |= (0x01 << 5); + write_nic_byte(dev, PSR, priv->PsrValue); + break; + + default: + break; + } + + pLed->bLedOn = 0; +} + diff -Nur linux-2.6.30.5.orig/drivers/net/wireless/rtl8187b/r8187_led.h linux-2.6.30.5/drivers/net/wireless/rtl8187b/r8187_led.h --- linux-2.6.30.5.orig/drivers/net/wireless/rtl8187b/r8187_led.h 1970-01-01 01:00:00.000000000 +0100 +++ linux-2.6.30.5/drivers/net/wireless/rtl8187b/r8187_led.h 2009-08-23 19:01:04.000000000 +0200 @@ -0,0 +1,276 @@ +/*++ + +Copyright (c) Microsoft Corporation. All rights reserved. + +Module Name: + r8187_led.h + +Abstract: + definitions and stuctures for rtl8187 led control. + +Major Change History: + When Who What + ---------- ------ ---------------------------------------------- + 2006-09-07 Xiong Created + +Notes: + +--*/ + +#ifndef R8187_LED_H +#define R8187_LED_H + +#include +#include + + +/*--------------------------Define -------------------------------------------*/ +// +// 0x7E-0x7F is reserved for SW customization. 2006.04.21, by rcnjko. +// +// BIT[0-7] is for CustomerID where value 0x00 and 0xFF is reserved for Realtek. +#define EEPROM_SW_REVD_OFFSET 0x7E + +#define EEPROM_CID_MASK 0x00FF +#define EEPROM_CID_RSVD0 0x00 +#define EEPROM_CID_RSVD1 0xFF +#define EEPROM_CID_ALPHA0 0x01 +#define EEPROM_CID_SERCOMM_PS 0x02 +#define EEPROM_CID_HW_LED 0x03 + +#define EEPROM_CID_QMI 0x07 //Added by lizhaoming 2008.6.3 +#define EEPROM_CID_DELL 0x08 //Added by lizhaoming 2008.6.3 + +#define LED_BLINK_NORMAL_INTERVAL 100 //by lizhaoming 50 -> 100 +#define LED_BLINK_SLOWLY_INTERVAL 200 + +// Customized for AzWave, 2006.04.03, by rcnjko. +#define LED_CM2_BLINK_ON_INTERVAL 250 +#define LED_CM2_BLINK_OFF_INTERVAL 4750 +// + +// Customized for Sercomm Printer Server case, 2006.04.21, by rcnjko. +#define LED_CM3_BLINK_INTERVAL 1500 + +// by lizhaoming 2008.6.3: Customized for QMI. +// +#define LED_CM4_BLINK_ON_INTERVAL 500 +#define LED_CM4_BLINK_OFF_INTERVAL 4500 + + +/*--------------------------Define MACRO--------------------------------------*/ + + +/*------------------------------Define Struct---------------------------------*/ +typedef enum _LED_STATE_8187{ + LED_UNKNOWN = 0, + LED_ON = 1, + LED_OFF = 2, + LED_BLINK_NORMAL = 3, + LED_BLINK_SLOWLY = 4, + LED_POWER_ON_BLINK = 5, + LED_SCAN_BLINK = 6, // LED is blinking during scanning period, the # of times to blink is depend on time for scanning. + LED_NO_LINK_BLINK = 7, // LED is blinking during no link state. + LED_BLINK_CM3 = 8, // Customzied for Sercomm Printer Server case +}LED_STATE_8187; + +typedef enum _RT_CID_TYPE { + RT_CID_DEFAULT, + RT_CID_8187_ALPHA0, + RT_CID_8187_SERCOMM_PS, + RT_CID_8187_HW_LED, + + RT_CID_87B_QMI , //Added by lizhaoming 2008.6.3 + RT_CID_87B_DELL, //Added by lizhaoming 2008.6.3 + +} RT_CID_TYPE; + +typedef enum _LED_STRATEGY_8187{ + SW_LED_MODE0, // SW control 1 LED via GPIO0. It is default option. + SW_LED_MODE1, // 2 LEDs, through LED0 and LED1. For ALPHA. + SW_LED_MODE2, // SW control 1 LED via GPIO0, customized for AzWave 8187 minicard. + SW_LED_MODE3, // SW control 1 LED via GPIO0, customized for Sercomm Printer Server case. + SW_LED_MODE4, //added by lizhaoming for bluetooth 2008.6.3 + SW_LED_MODE5, //added by lizhaoming for bluetooth 2008.6.3 + HW_LED, // HW control 2 LEDs, LED0 and LED1 (there are 4 different control modes, see MAC.CONFIG1 for details.) +}LED_STRATEGY_8187, *PLED_STRATEGY_8187; + +typedef enum _LED_PIN_8187{ + LED_PIN_GPIO0, + LED_PIN_LED0, + LED_PIN_LED1 +}LED_PIN_8187; + +//by lizhaoming for LED 2008.6.23 into ieee80211.h +//typedef enum _LED_CTL_MODE { +// LED_CTL_POWER_ON, +// LED_CTL_POWER_OFF, +// LED_CTL_LINK, +// LED_CTL_NO_LINK, +// LED_CTL_TX, +// LED_CTL_RX, +// LED_CTL_SITE_SURVEY, +//} LED_CTL_MODE; + +typedef struct _LED_8187{ + LED_PIN_8187 LedPin; // Identify how to implement this SW led. + + LED_STATE_8187 CurrLedState; // Current LED state. + u8 bLedOn; // TRUE if LED is ON, FALSE if LED is OFF. + + u8 bLedBlinkInProgress; // TRUE if it is blinking, FALSE o.w.. + u32 BlinkTimes; // Number of times to toggle led state for blinking. + LED_STATE_8187 BlinkingLedState; // Next state for blinking, either LED_ON or LED_OFF are. + struct timer_list BlinkTimer; // Timer object for led blinking. +} LED_8187, *PLED_8187; + + + +/*------------------------Export global variable------------------------------*/ + + +/*------------------------------Funciton declaration--------------------------*/ +void +InitSwLeds( + struct net_device *dev + ); + +void +DeInitSwLeds( + struct net_device *dev + ); + +void +InitLed8187( + struct net_device *dev, + PLED_8187 pLed, + LED_PIN_8187 LedPin, + void * BlinkCallBackFunc); + +void +DeInitLed8187( + struct net_device *dev, + PLED_8187 pLed); + +void +LedControl8187( + struct net_device *dev, + LED_CTL_MODE LedAction +); + +void +SwLedControlMode0( + struct net_device *dev, + LED_CTL_MODE LedAction +); + +void +SwLedControlMode1( + struct net_device *dev, + LED_CTL_MODE LedAction +); + +void +SwLedControlMode2( + struct net_device *dev, + LED_CTL_MODE LedAction +); + +void +SwLedControlMode3( + struct net_device *dev, + LED_CTL_MODE LedAction +); + + +void +SwLedControlMode4( + struct net_device *dev, + LED_CTL_MODE LedAction +); + + +void +SwLedControlMode5( + struct net_device *dev, + LED_CTL_MODE LedAction +); + +void +Gpio0LedBlinkTimerCallback( + unsigned long data + ); + +void +SwLed0BlinkTimerCallback( + unsigned long data + ); + +void +SwLed1BlinkTimerCallback( + unsigned long data + ); + +void +PlatformSwLedBlink( + struct net_device *dev, + PLED_8187 pLed + ); +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20) +void +Gpio0LedWorkItemCallback( + void * Context + ); + +void +SwLed0WorkItemCallback( + void * Context + ); + +void +SwLed1WorkItemCallback( + void * Context + ); +#else +void +Gpio0LedWorkItemCallback(struct work_struct *work); + +void +SwLed0WorkItemCallback(struct work_struct *work); + +void +SwLed1WorkItemCallback(struct work_struct *work); + +#endif +void +SwLedBlink( + struct net_device *dev, + PLED_8187 pLed + ); + +void +SwLedCm2Blink( + struct net_device *dev, + PLED_8187 pLed + ); + +void +SwLedCm4Blink( + struct net_device *dev, + PLED_8187 pLed + ); + +void +SwLedOn( + struct net_device *dev, + PLED_8187 pLed +); + +void +SwLedOff( + struct net_device *dev, + PLED_8187 pLed +); + + +#endif diff -Nur linux-2.6.30.5.orig/drivers/net/wireless/rtl8187b/readme linux-2.6.30.5/drivers/net/wireless/rtl8187b/readme --- linux-2.6.30.5.orig/drivers/net/wireless/rtl8187b/readme 1970-01-01 01:00:00.000000000 +0100 +++ linux-2.6.30.5/drivers/net/wireless/rtl8187b/readme 2009-08-23 19:01:04.000000000 +0200 @@ -0,0 +1,124 @@ +rtl8187 Linux kernel driver +Released under the terms of GNU General Public Licence (GPL) +Copyright(c) Andrea Merello - 2004,2005 + +Portions of this driver are based on other projects, please see the notes +in the source files for detail. +A special thanks go to Realtek corp for their support and to David Young +------------------------------------------------------------------------------ + +This is an attempt to write somethig that can make rtl8187 usb dongle wifi card +on Linux using only opensource stuff. +The rtl8225 radio is supported. + +It's in early development stage so don't expect too much from it +(also use it at your own risk!) +This should be considered just a fragment of code.. using it on your(any) +system is at your own risk! Please note that I never supported the idea to +use it in any way, so i cannot be considered responsible in any way for +anything deriving by it usage. + +Anyway for now we have monitor mode and managed mode +basically working! This isn't necessary stable, but seems to work.. + +This driver is still under development and very far from perfect. It should work on x86, +Other archs are untested.. + +To compile the driver simply run make. + +The driver contains also the ieee80211.h and ieee80211_crypt.h from the ieee stack. +Note that for some reasons this stack is NOT the same that will be included in newer +2.6 kernel. I will try to port to this stack as soon as it will have enought features +to support 8187 cards. +Please note that you will have to make sure the two .h files are the same of the ieee +stack. +In other words when you download from the CVS this driver and the ieee80211 stack a good +idea is to copy the ieee80211.h and ieee80211_crypt.h from the ieee directory to the drv +directory + +Warning during compile are OK + +To wake up the nic run: + + ifconfig up + +(where is your network device for wlan card). + +Please note that the default interface name is wlanX. + +Please note thet this will take several seconds.. + +If you would like to set the interface name to something else you may use the +'devname=' module parameter. For example: + + insmod r8187.ko ifname=eth%d + +will set the interface name of this device to something like eth0. + +Once the nic is up it can be put in a monitor mode by running: + + iwconfig mode monitor + +and channel number may be changed by running: + + iwconfig channel XX + + +In monitor mode a choice may be made via iwpriv if the nic should pass packets +with bad crc or drop them. + +To put the nic in managed mode run: + + iwconfig mode managed + +In managed mode there is support for + + iwlist scan + +that should report the currently available networks. +Please note that in managed mode channels cannot be changed manually. + +To associate with a network + + iwconfig essid XXXXX + +where XXXXX is the network essid (name) reported by 'iwlist scan'. Please +note that essid is case sensitive. + +If your network is not broadcasting the ESSID, then you need to specify *also* +the AP MAC address + + iwconfig ap XX:XX:XX:XX:XX:XX + +The driver accepts another boolean parameter: hwseqnum +If set to 1 it lets the card HW take care of the sequence number of the TXed +frames. Altought in managed mode I can't see an important reason to use HW to +do that, when we'll start to TX beacons in master (AP) and ad-hoc modes most +probably it will be extremely useful (since most probably we will use two HW +queues). + +I'm unsure if it will work correctly on all NICs.. reports are *VERY, VERY* apreciated.. + + + WEP + === + +WEP encryption should work. For now it's done by host, not by the nic. Key can be set with: +Key can be set with + + iwconfig key 12345... + +WEP is supported via software thanks to the ipw stack. + +Shared and open authentication are supported + + IWPRIV + ====== + +This driver supports some private handlers: +-badcrc: let you choose to kill or to pass to the upper layer frames with bad crc in monitor mode +-activescan: if 0 the driver will avoid to send probe requests, sanning will be only on beacon basis + + +If you have some question/comments please feel free to write me. + diff -Nur linux-2.6.30.5.orig/drivers/platform/Kconfig linux-2.6.30.5/drivers/platform/Kconfig --- linux-2.6.30.5.orig/drivers/platform/Kconfig 2009-08-16 23:19:38.000000000 +0200 +++ linux-2.6.30.5/drivers/platform/Kconfig 2009-08-23 19:01:04.000000000 +0200 @@ -3,3 +3,7 @@ if X86 source "drivers/platform/x86/Kconfig" endif + +if MACH_LOONGSON +source "drivers/platform/loongson/Kconfig" +endif diff -Nur linux-2.6.30.5.orig/drivers/platform/loongson/ec_kb3310b/ec_bat.c linux-2.6.30.5/drivers/platform/loongson/ec_kb3310b/ec_bat.c --- linux-2.6.30.5.orig/drivers/platform/loongson/ec_kb3310b/ec_bat.c 1970-01-01 01:00:00.000000000 +0100 +++ linux-2.6.30.5/drivers/platform/loongson/ec_kb3310b/ec_bat.c 2009-08-23 19:01:04.000000000 +0200 @@ -0,0 +1,388 @@ +/* + * EC(Embedded Controller) KB3310B battery management driver on Linux + * + * Author: liujl + * Date : 2008-03-17 + * + * NOTE: The SDA0/SCL0 in KB3310B are used to communicate with the battery + * IC, Here we use DS2786 IC to handle the battery management. All the + * resources for handle battery management in KB3310B are: + * 1, one SMBus interface with port 0 + * 2, gpio40 output for charge enable + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include "ec.h" +#include "ec_misc_fn.h" + +#ifndef APM_32_BIT_SUPPORT +#define APM_32_BIT_SUPPORT 0x0002 +#endif + +/* The EC Battery device, here is his minor number. */ +#define ECBAT_MINOR_DEV MISC_DYNAMIC_MINOR + +/* + * apm threshold : percent unit. + */ +#define BAT_MAX_THRESHOLD 99 +#define BAT_MIN_THRESHOLD 5 + +/* + * This structure gets filled in by the machine specific 'get_power_status' + * implementation. Any fields which are not set default to a safe value. + */ +struct apm_pwr_info { + unsigned char ac_line_status; +#define APM_AC_OFFLINE 0 +#define APM_AC_ONLINE 1 +#define APM_AC_BACKUP 2 +#define APM_AC_UNKNOWN 0xff + + unsigned char battery_status; +#define APM_BATTERY_STATUS_HIGH 0 +#define APM_BATTERY_STATUS_LOW 1 +#define APM_BATTERY_STATUS_CRITICAL 2 +#define APM_BATTERY_STATUS_CHARGING 3 +#define APM_BATTERY_STATUS_NOT_PRESENT 4 +#define APM_BATTERY_STATUS_UNKNOWN 0xff + + unsigned char battery_flag; +#define APM_BATTERY_FLAG_HIGH (1 << 0) +#define APM_BATTERY_FLAG_LOW (1 << 1) +#define APM_BATTERY_FLAG_CRITICAL (1 << 2) +#define APM_BATTERY_FLAG_CHARGING (1 << 3) +#define APM_BATTERY_FLAG_NOT_PRESENT (1 << 7) +#define APM_BATTERY_FLAG_UNKNOWN 0xff + + int battery_life; + int time; + int units; +#define APM_UNITS_MINS 0 +#define APM_UNITS_SECS 1 +#define APM_UNITS_UNKNOWN -1 + + /* battery designed capacity */ + unsigned int bat_design_cap; + /* battery designed voltage */ + unsigned int bat_design_vol; + /* battery capacity after full charged */ + unsigned int bat_full_charged_cap; + /* battery vendor number */ + unsigned char bat_vendor; + /* battery cell count */ + unsigned char bat_cell_count; + + /* battery dynamic charge/discharge voltage */ + unsigned int bat_voltage; + /* battery dynamic charge/discharge current */ + int bat_current; + /* battery current temperature */ + unsigned int bat_temperature; +}; + +static struct task_struct *battery_tsk; + +static DEFINE_MUTEX(bat_info_lock); +struct bat_info { + unsigned int ac_in; + unsigned int bat_in; + unsigned int bat_flag; + /* we use capacity for caculating the life and time */ + unsigned int curr_bat_cap; + + /* battery designed capacity */ + unsigned int bat_design_cap; + /* battery designed voltage */ + unsigned int bat_design_vol; + /* battery capacity after full charged */ + unsigned int bat_full_charged_cap; + /* battery vendor number */ + unsigned char bat_vendor; + /* battery cell count */ + unsigned char bat_cell_count; + + /* battery dynamic charge/discharge voltage */ + unsigned int bat_voltage; + /* battery dynamic charge/discharge current */ + int bat_current; + /* battery current temperature */ + unsigned int bat_temperature; +} bat_info = { + .ac_in = APM_AC_UNKNOWN, + .bat_in = APM_BATTERY_STATUS_UNKNOWN, + .curr_bat_cap = 0, + /* fixed value */ + .bat_design_cap = 0, + .bat_full_charged_cap = 0, + .bat_design_vol = 0, + .bat_vendor = 0, + .bat_cell_count = 0, + /* rest variable */ + .bat_voltage = 0, + .bat_current = 0, + .bat_temperature = 0 +}; + +/* + * 1.4 : + * 1, 89inch basic work version. + * 2, you should set xorg.conf ServerFlag of "NoPM" to true + * 1.5 : + * 1, bat_flag is added to struct bat_info. + * 2, BAT_MIN_THRESHOLD is changed to 5%. + */ +static const char driver_version[] = VERSION; /* no spaces */ + +static struct miscdevice apm_device = { + .minor = ECBAT_MINOR_DEV, + .name = "apm_bios", + .fops = NULL +}; + +#ifdef CONFIG_PROC_FS +static int bat_proc_read(char *page, char **start, off_t off, int count, + int *eof, void *data); +static struct proc_dir_entry *bat_proc_entry; + +static int bat_proc_read(char *page, char **start, off_t off, int count, + int *eof, void *data) +{ + struct apm_pwr_info info; + char *units; + int ret; + + mutex_lock(&bat_info_lock); + info.battery_life = bat_info.curr_bat_cap; + info.ac_line_status = bat_info.ac_in; + info.battery_status = bat_info.bat_in; + info.battery_flag = bat_info.bat_flag; + info.bat_voltage = bat_info.bat_voltage; + if (bat_info.bat_current & 0x8000) + info.bat_current = 0xffff - bat_info.bat_current; + else + info.bat_current = bat_info.bat_current; + info.bat_temperature = bat_info.bat_temperature; + + /* this should be charged according to the capacity-time flow. */ + if (info.battery_status != APM_BATTERY_STATUS_NOT_PRESENT) + info.time = ((bat_info.curr_bat_cap - 3) * 54 + 142) / 60; + else + info.time = 0x00; + info.units = APM_UNITS_MINS; + + mutex_unlock(&bat_info_lock); + switch (info.units) { + default: + units = "?"; + break; + case 0: + units = "min"; + break; + case 1: + units = "sec"; + break; + } + + ret = + sprintf(page, + "%s 1.2 0x%02x 0x%02x 0x%02x 0x%02x %d%% %d %s %dmV %dmA %d\n", + driver_version, APM_32_BIT_SUPPORT, info.ac_line_status, + info.battery_status, info.battery_flag, info.battery_life, + info.time, units, info.bat_voltage, info.bat_current, + info.bat_temperature); + + ret -= off; + if (ret < off + count) + *eof = 1; + *start = page + off; + if (ret > count) + ret = count; + if (ret < 0) + ret = 0; + + return ret; +} +#endif + +static int battery_manager(void *arg) +{ + unsigned char bat_charge; + unsigned char power_flag; + unsigned char bat_status; + unsigned char charge_status; + + /* read out the fixed value */ + bat_info.bat_design_cap = (ec_read(REG_BAT_DESIGN_CAP_HIGH) << 8) + | ec_read(REG_BAT_DESIGN_CAP_LOW); + bat_info.bat_full_charged_cap = (ec_read(REG_BAT_FULLCHG_CAP_HIGH) << 8) + | ec_read(REG_BAT_FULLCHG_CAP_LOW); + bat_info.bat_design_vol = (ec_read(REG_BAT_DESIGN_VOL_HIGH) << 8) + | ec_read(REG_BAT_DESIGN_VOL_LOW); + bat_info.bat_vendor = ec_read(REG_BAT_VENDOR); + bat_info.bat_cell_count = ec_read(REG_BAT_CELL_COUNT); + if (bat_info.bat_vendor != 0) { + printk(KERN_INFO + "battery vendor(%s), cells count(%d), " + "with designed capacity(%d),designed voltage(%d)," + " full charged capacity(%d)\n", + (bat_info.bat_vendor == + FLAG_BAT_VENDOR_SANYO) ? "SANYO" : "SIMPLO", + (bat_info.bat_cell_count == FLAG_BAT_CELL_3S1P) ? 3 : 6, + bat_info.bat_design_cap, bat_info.bat_design_vol, + bat_info.bat_full_charged_cap); + } + + PRINTK_DBG(KERN_DEBUG "Battery manager thread started.\n"); + while (1) { + set_current_state(TASK_INTERRUPTIBLE); + /* schedule every 1s, it is better for changed to 1s. */ + schedule_timeout(HZ * 1); + + if (kthread_should_stop()) + break; + + mutex_lock(&bat_info_lock); + + bat_charge = ec_read(REG_BAT_CHARGE); + power_flag = ec_read(REG_BAT_POWER); + bat_status = ec_read(REG_BAT_STATUS); + charge_status = ec_read(REG_BAT_CHARGE_STATUS); + bat_info.bat_voltage = + (ec_read(REG_BAT_VOLTAGE_HIGH) << 8) | + (ec_read(REG_BAT_VOLTAGE_LOW)); + bat_info.bat_current = + (ec_read(REG_BAT_CURRENT_HIGH) << 8) | + (ec_read(REG_BAT_CURRENT_LOW)); + bat_info.bat_temperature = + (ec_read(REG_BAT_TEMPERATURE_HIGH) << 8) | + (ec_read(REG_BAT_TEMPERATURE_LOW)); + bat_info.curr_bat_cap = + (ec_read(REG_BAT_RELATIVE_CAP_HIGH) << 8) | + (ec_read(REG_BAT_RELATIVE_CAP_LOW)); + + bat_info.ac_in = + (power_flag & BIT_BAT_POWER_ACIN) ? APM_AC_ONLINE : + APM_AC_OFFLINE; + if (!(bat_status & BIT_BAT_STATUS_IN)) { + /* there is no battery inserted */ + bat_info.bat_in = APM_BATTERY_STATUS_NOT_PRESENT; + bat_info.bat_flag = APM_BATTERY_FLAG_NOT_PRESENT; + } else { + /* there is adapter inserted */ + if (bat_info.ac_in == APM_AC_ONLINE) { + /* if the battery is not fully charged */ + if (!(bat_status & BIT_BAT_STATUS_FULL)) { + bat_info.bat_in = + APM_BATTERY_STATUS_CHARGING; + bat_info.bat_flag = + APM_BATTERY_FLAG_CHARGING; + } else { + /* if the battery is fully charged */ + bat_info.bat_in = + APM_BATTERY_STATUS_HIGH; + bat_info.bat_flag = + APM_BATTERY_FLAG_HIGH; + bat_info.curr_bat_cap = 100; + } + } else { + /* if the battery is too low */ + if (bat_status & BIT_BAT_STATUS_LOW) { + bat_info.bat_in = + APM_BATTERY_STATUS_LOW; + bat_info.bat_flag = + APM_BATTERY_FLAG_LOW; + if (bat_info.curr_bat_cap <= + BAT_MIN_THRESHOLD) { + bat_info.bat_in = + APM_BATTERY_STATUS_CRITICAL; + bat_info.bat_flag = + APM_BATTERY_FLAG_CRITICAL; + } + /* we should power off the system now */ + } else { + /* assume the battery is high enough. */ + bat_info.bat_in = + APM_BATTERY_STATUS_HIGH; + bat_info.bat_flag = + APM_BATTERY_FLAG_HIGH; + } + } + } + mutex_unlock(&bat_info_lock); + } + + PRINTK_DBG(KERN_DEBUG "Battery Management thread exit.\n"); + return 0; +} + +static int __init apm_init(void) +{ + int ret; + + printk(KERN_ERR + "APM of battery on KB3310B Embedded Controller init.\n"); + + battery_tsk = kthread_create(battery_manager, NULL, "battery_manager"); + if (IS_ERR(battery_tsk)) { + ret = PTR_ERR(battery_tsk); + kthread_stop(battery_tsk); + battery_tsk = NULL; + printk(KERN_ERR "ecbat : battery management error.\n"); + return ret; + } + battery_tsk->flags |= PF_NOFREEZE; + wake_up_process(battery_tsk); + +#ifdef CONFIG_PROC_FS + bat_proc_entry = NULL; + bat_proc_entry = create_proc_entry("apm", S_IWUSR | S_IRUGO, NULL); + if (bat_proc_entry == NULL) { + printk(KERN_ERR "EC BAT : register /proc/apm failed.\n"); + return -EINVAL; + } + bat_proc_entry->read_proc = bat_proc_read; + bat_proc_entry->write_proc = NULL; + bat_proc_entry->data = NULL; +#endif + + ret = misc_register(&apm_device); + if (ret != 0) { + remove_proc_entry("apm", NULL); + kthread_stop(battery_tsk); + printk(KERN_ERR "ecbat : misc register error.\n"); + } + return ret; +} + +static void __exit apm_exit(void) +{ + misc_deregister(&apm_device); +#ifdef CONFIG_PROC_FS + remove_proc_entry("apm", NULL); +#endif + kthread_stop(battery_tsk); +} + +module_init(apm_init); +module_exit(apm_exit); + +MODULE_AUTHOR("liujl "); +MODULE_DESCRIPTION("Advanced Power Management For Kb3310"); +MODULE_LICENSE("GPL"); diff -Nur linux-2.6.30.5.orig/drivers/platform/loongson/ec_kb3310b/ec_ft.c linux-2.6.30.5/drivers/platform/loongson/ec_kb3310b/ec_ft.c --- linux-2.6.30.5.orig/drivers/platform/loongson/ec_kb3310b/ec_ft.c 1970-01-01 01:00:00.000000000 +0100 +++ linux-2.6.30.5/drivers/platform/loongson/ec_kb3310b/ec_ft.c 2009-08-23 19:01:04.000000000 +0200 @@ -0,0 +1,216 @@ +/* + * EC(Embedded Controller) KB3310B Fan and Temperature management driver on + * Linux + * + * Author: liujl + * Date : 2008-06-23 + * + * NOTE: The SDA1/SCL1 in KB3310B are used to communicate with the + * Temperature IC, Here we use ADT75 IC to handle the temperature management. + * and the Fan is controller by ADT75AZ, but the status is reflected to the + * KB3310 FANFB All the resources for handle battery management in KB3310B: + * 1, one SMBus interface with port 1 + * 2, gpio14 input alternate for FANFB + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "ec.h" +#include "ec_misc_fn.h" + +#define EC_FT_DEV "ft" +/* The EC Battery device is one of the misc device, here is his minor number. */ +#define ECFT_MINOR_DEV MISC_DYNAMIC_MINOR +#define PROC_FT_DIR "ft" + +static struct task_struct *ft_tsk; +static DEFINE_MUTEX(ft_info_lock); + +/* driver version */ +static const char driver_version[] = VERSION; + +/* fan speed divider */ +#define FAN_SPEED_DIVIDER 480000 /* (60*1000*1000/62.5/2)*/ + +/* fan status : on or off */ +#define FAN_STATUS_ON 0x01 +#define FAN_STATUS_OFF 0x00 +/* fan is not running */ +#define FAN_SPEED_NONE 0x00 +/* temperature negative or positive */ +#define TEMPERATURE_POSITIVE 0x00 +#define TEMPERATURE_NEGATIVE 0x01 +/* temperature value is zero */ +#define TEMPERATURE_NONE 0x00 +struct ft_info { + u8 fan_on; + u16 fan_speed; + u8 temperature_pn; + u8 temperature; +} ft_info = { + .fan_on = FAN_STATUS_ON, + .fan_speed = FAN_SPEED_NONE, + .temperature_pn = TEMPERATURE_POSITIVE, + .temperature = TEMPERATURE_NONE +}; + +static struct miscdevice ft_device = { + .minor = ECFT_MINOR_DEV, + .name = EC_FT_DEV, + .fops = NULL +}; + +#ifdef CONFIG_PROC_FS +static int ft_proc_read(char *page, char **start, off_t off, int count, + int *eof, void *data); +static struct proc_dir_entry *ft_proc_entry; + +static int ft_proc_read(char *page, char **start, off_t off, int count, + int *eof, void *data) +{ + struct ft_info info; + int ret; + + mutex_lock(&ft_info_lock); + info.fan_on = ft_info.fan_on; + if (info.fan_on == FAN_STATUS_ON) + info.fan_speed = ft_info.fan_speed; + else + info.fan_speed = 0x00; + info.temperature_pn = ft_info.temperature_pn; + info.temperature = ft_info.temperature; + mutex_unlock(&ft_info_lock); + + ret = + sprintf(page, "%s 0x%02x %d 0x%02x %d\n", driver_version, + info.fan_on, info.fan_speed, info.temperature_pn, + info.temperature); + + ret -= off; + if (ret < off + count) + *eof = 1; + + *start = page + off; + if (ret > count) + ret = count; + if (ret < 0) + ret = 0; + + return ret; +} +#endif + +static int ft_manager(void *arg) +{ + u8 val, reg_val; + + PRINTK_DBG(KERN_DEBUG "Fan & Temperature Management thread started.\n"); + while (1) { + set_current_state(TASK_INTERRUPTIBLE); + /* schedule every 1s */ + schedule_timeout(HZ); /* 1s */ + + if (kthread_should_stop()) + break; + + mutex_lock(&ft_info_lock); + + val = ec_read(REG_FAN_STATUS); + ft_info.fan_speed = + FAN_SPEED_DIVIDER / + (((ec_read(REG_FAN_SPEED_HIGH) & 0x0f) << 8) | + ec_read(REG_FAN_SPEED_LOW)); + reg_val = ec_read(REG_TEMPERATURE_VALUE); + + if (val) + ft_info.fan_on = FAN_STATUS_ON; + else + ft_info.fan_on = FAN_STATUS_OFF; + + if (reg_val & (1 << 7)) { + ft_info.temperature = (reg_val & 0x7f) - 128; + ft_info.temperature_pn = TEMPERATURE_NEGATIVE; + } else { + ft_info.temperature = (reg_val & 0xff); + ft_info.temperature_pn = TEMPERATURE_POSITIVE; + } + mutex_unlock(&ft_info_lock); + } + + PRINTK_DBG(KERN_DEBUG "Fan and Temperature Management thread exit.\n"); + + return 0; + +} + +static int __init ft_init(void) +{ + int ret; + + printk(KERN_INFO + "Fan and Temperature on KB3310B Embedded Controller init.\n"); + ft_tsk = kthread_create(ft_manager, NULL, "ft_manager"); + if (IS_ERR(ft_tsk)) { + ret = PTR_ERR(ft_tsk); + kthread_stop(ft_tsk); + ft_tsk = NULL; + printk(KERN_ERR "ecft : ft management error.\n"); + return ret; + } + ft_tsk->flags |= PF_NOFREEZE; + wake_up_process(ft_tsk); + +#ifdef CONFIG_PROC_FS + ft_proc_entry = NULL; + ft_proc_entry = create_proc_entry(EC_FT_DEV, S_IWUSR | S_IRUGO, NULL); + if (ft_proc_entry == NULL) { + printk(KERN_ERR "EC FT : register /proc/ft failed.\n"); + return -EINVAL; + } + ft_proc_entry->read_proc = ft_proc_read; + ft_proc_entry->write_proc = NULL; + ft_proc_entry->data = NULL; +#endif + + ret = misc_register(&ft_device); + if (ret != 0) { +#ifdef CONFIG_PROC_FS + remove_proc_entry(EC_FT_DEV, NULL); +#endif + kthread_stop(ft_tsk); + printk(KERN_ERR "ecft : fan&temperature register error.\n"); + } + + return ret; +} + +static void __exit ft_exit(void) +{ + misc_deregister(&ft_device); +#ifdef CONFIG_PROC_FS + remove_proc_entry(EC_FT_DEV, NULL); +#endif + kthread_stop(ft_tsk); +} + +module_init(ft_init); +module_exit(ft_exit); + +MODULE_AUTHOR("liujl "); +MODULE_DESCRIPTION("Advanced Fan and Temperature Management For Kb3310"); +MODULE_LICENSE("GPL"); diff -Nur linux-2.6.30.5.orig/drivers/platform/loongson/ec_kb3310b/ec.h linux-2.6.30.5/drivers/platform/loongson/ec_kb3310b/ec.h --- linux-2.6.30.5.orig/drivers/platform/loongson/ec_kb3310b/ec.h 1970-01-01 01:00:00.000000000 +0100 +++ linux-2.6.30.5/drivers/platform/loongson/ec_kb3310b/ec.h 2009-08-23 19:01:04.000000000 +0200 @@ -0,0 +1,218 @@ +/* + * EC(Embedded Controller) KB3310B misc device driver header for Linux + * Author: liujl + * Date : 2008-03-14 + * + * EC relative header file. All the EC registers should be defined here. + */ + +#include +#include +#include + +#define VERSION "1.37" + +/* + * The following registers are determined by the EC index configuration. + * 1, fill the PORT_HIGH as EC register high part. + * 2, fill the PORT_LOW as EC register low part. + * 3, fill the PORT_DATA as EC register write data or get the data from it. + */ +#define EC_IO_PORT_HIGH 0x0381 +#define EC_IO_PORT_LOW 0x0382 +#define EC_IO_PORT_DATA 0x0383 + +/* ec registers range */ +#define EC_MAX_REGADDR 0xFFFF +#define EC_MIN_REGADDR 0xF000 +/* #define EC_RAM_ADDR 0xF400 */ +#define EC_RAM_ADDR 0xF800 + +/* temperature & fan registers */ +#define REG_TEMPERATURE_VALUE 0xF458 /* current temperature value */ +#define REG_FAN_CONTROL 0xF4D2 /* fan control */ +#define BIT_FAN_CONTROL_ON (1 << 0) +#define BIT_FAN_CONTROL_OFF (0 << 0) +#define REG_FAN_STATUS 0xF4DA /* fan status */ +#define BIT_FAN_STATUS_ON (1 << 0) +#define BIT_FAN_STATUS_OFF (0 << 0) +#define REG_FAN_SPEED_HIGH 0xFE22 /* fan speed high byte */ +#define REG_FAN_SPEED_LOW 0xFE23 /* fan speed low byte */ +#define REG_FAN_SPEED_LEVEL 0xF4E4 /* fan speed level, from 1 to 5 */ + +/* battery registers */ +#define REG_BAT_DESIGN_CAP_HIGH 0xF77D /* design capacity high byte */ +#define REG_BAT_DESIGN_CAP_LOW 0xF77E /* design capacity low byte */ +#define REG_BAT_FULLCHG_CAP_HIGH 0xF780 /* full charged capacity high byte */ +#define REG_BAT_FULLCHG_CAP_LOW 0xF781 /* full charged capacity low byte */ +#define REG_BAT_DESIGN_VOL_HIGH 0xF782 /* design voltage high byte */ +#define REG_BAT_DESIGN_VOL_LOW 0xF783 /* design voltage low byte */ +#define REG_BAT_CURRENT_HIGH 0xF784 /* battery in/out current high byte */ +#define REG_BAT_CURRENT_LOW 0xF785 /* battery in/out current low byte */ +#define REG_BAT_VOLTAGE_HIGH 0xF786 /* battery current voltage high byte */ +#define REG_BAT_VOLTAGE_LOW 0xF787 /* battery current voltage low byte */ +#define REG_BAT_TEMPERATURE_HIGH 0xF788 /* battery current temperature high byte */ +#define REG_BAT_TEMPERATURE_LOW 0xF789 /* battery current temperature low byte */ +#define REG_BAT_RELATIVE_CAP_HIGH 0xF492 /* relative capacity high byte */ +#define REG_BAT_RELATIVE_CAP_LOW 0xF493 /* relative capacity low byte */ +#define REG_BAT_VENDOR 0xF4C4 /* battery vendor number */ +#define FLAG_BAT_VENDOR_SANYO 0x01 +#define FLAG_BAT_VENDOR_SIMPLO 0x02 +#define REG_BAT_CELL_COUNT 0xF4C6 /* how many cells in one battery */ +#define FLAG_BAT_CELL_3S1P 0x03 +#define FLAG_BAT_CELL_3S2P 0x06 +#define REG_BAT_CHARGE 0xF4A2 /* macroscope battery charging */ +#define FLAG_BAT_CHARGE_DISCHARGE 0x01 +#define FLAG_BAT_CHARGE_CHARGE 0x02 +#define FLAG_BAT_CHARGE_ACPOWER 0x00 +#define REG_BAT_STATUS 0xF4B0 +#define BIT_BAT_STATUS_LOW (1 << 5) +#define BIT_BAT_STATUS_DESTROY (1 << 2) +#define BIT_BAT_STATUS_FULL (1 << 1) +#define BIT_BAT_STATUS_IN (1 << 0) +#define REG_BAT_CHARGE_STATUS 0xF4B1 +#define BIT_BAT_CHARGE_STATUS_OVERTEMP (1 << 2) /* over temperature */ +#define BIT_BAT_CHARGE_STATUS_PRECHG (1 << 1) /* pre-charge the battery */ +#define REG_BAT_STATE 0xF482 +#define BIT_BAT_STATE_CHARGING (1 << 1) +#define BIT_BAT_STATE_DISCHARGING (1 << 0) +#define REG_BAT_POWER 0xF440 +#define BIT_BAT_POWER_S3 (1 << 2) /* enter s3 standby mode */ +#define BIT_BAT_POWER_ON (1 << 1) /* system is on */ +#define BIT_BAT_POWER_ACIN (1 << 0) /* adapter is inserted */ + +/* other registers */ +#define REG_AUDIO_MUTE 0xF4E7 /* audio mute : rd/wr */ +#define BIT_AUDIO_MUTE_ON (1 << 0) +#define BIT_AUDIO_MUTE_OFF (0 << 0) +#define REG_AUDIO_BEEP 0xF4D0 /* audio beep and reset : rd/wr */ +#define BIT_AUDIO_BEEP_ON (1 << 0) +#define BIT_AUDIO_BEEP_OFF (0 << 0) +#define REG_USB0_FLAG 0xF461 /* usb0 port power or not : rd/wr */ +#define BIT_USB0_FLAG_ON (1 << 0) +#define BIT_USB0_FLAG_OFF (0 << 0) +#define REG_USB1_FLAG 0xF462 /* usb1 port power or not : rd/wr */ +#define BIT_USB1_FLAG_ON (1 << 0) +#define BIT_USB1_FLAG_OFF (0 << 0) +#define REG_USB2_FLAG 0xF463 /* usb2 port power or not : rd/wr */ +#define BIT_USB2_FLAG_ON (1 << 0) +#define BIT_USB2_FLAG_OFF (0 << 0) +#define REG_CRT_DETECT 0xF4AD /* detected CRT exist or not */ +#define BIT_CRT_DETECT_PLUG (1 << 0) +#define BIT_CRT_DETECT_UNPLUG (0 << 0) +#define REG_LID_DETECT 0xF4BD /* detected LID is on or not */ +#define BIT_LID_DETECT_ON (1 << 0) +#define BIT_LID_DETECT_OFF (0 << 0) +#define REG_RESET 0xF4EC /* reset the machine auto-clear : rd/wr */ +#define BIT_RESET_ON (1 << 0) +#define BIT_RESET_OFF (0 << 0) +#define REG_LED 0xF4C8 /* light the led : rd/wr */ +#define BIT_LED_RED_POWER (1 << 0) +#define BIT_LED_ORANGE_POWER (1 << 1) +#define BIT_LED_GREEN_CHARGE (1 << 2) +#define BIT_LED_RED_CHARGE (1 << 3) +#define BIT_LED_NUMLOCK (1 << 4) +#define REG_LED_TEST 0xF4C2 /* test led mode, all led on or off */ +#define BIT_LED_TEST_IN (1 << 0) +#define BIT_LED_TEST_OUT (0 << 0) +#define REG_DISPLAY_BRIGHTNESS 0xF4F5 /* 9 stages LCD backlight brightness adjust */ +#define FLAG_DISPLAY_BRIGHTNESS_LEVEL_0 0 +#define FLAG_DISPLAY_BRIGHTNESS_LEVEL_1 1 +#define FLAG_DISPLAY_BRIGHTNESS_LEVEL_2 2 +#define FLAG_DISPLAY_BRIGHTNESS_LEVEL_3 3 +#define FLAG_DISPLAY_BRIGHTNESS_LEVEL_4 4 +#define FLAG_DISPLAY_BRIGHTNESS_LEVEL_5 5 +#define FLAG_DISPLAY_BRIGHTNESS_LEVEL_6 6 +#define FLAG_DISPLAY_BRIGHTNESS_LEVEL_7 7 +#define FLAG_DISPLAY_BRIGHTNESS_LEVEL_8 8 +#define REG_CAMERA_STATUS 0xF46A /* camera is in ON/OFF status. */ +#define BIT_CAMERA_STATUS_ON (1 << 0) +#define BIT_CAMERA_STATUS_OFF (0 << 0) +#define REG_CAMERA_CONTROL 0xF7B7 /* control camera to ON/OFF. */ +#define BIT_CAMERA_CONTROL_OFF (1 << 1) +#define BIT_CAMERA_CONTROL_ON (1 << 1) +#define REG_AUDIO_VOLUME 0xF46C /* The register to show volume level */ +#define FLAG_AUDIO_VOLUME_LEVEL_0 0 +#define FLAG_AUDIO_VOLUME_LEVEL_1 1 +#define FLAG_AUDIO_VOLUME_LEVEL_2 2 +#define FLAG_AUDIO_VOLUME_LEVEL_3 3 +#define FLAG_AUDIO_VOLUME_LEVEL_4 4 +#define FLAG_AUDIO_VOLUME_LEVEL_5 5 +#define FLAG_AUDIO_VOLUME_LEVEL_6 6 +#define FLAG_AUDIO_VOLUME_LEVEL_7 7 +#define FLAG_AUDIO_VOLUME_LEVEL_8 8 +#define FLAG_AUDIO_VOLUME_LEVEL_9 9 +#define FLAG_AUDIO_VOLUME_LEVEL_10 0x0A +#define REG_WLAN_STATUS 0xF4FA /* Wlan Status */ +#define BIT_WLAN_STATUS_ON (1 << 0) +#define BIT_WLAN_STATUS_OFF (0 << 0) +#define REG_DISPLAY_LCD 0xF79F /* Black screen Status */ +#define BIT_DISPLAY_LCD_ON (1 << 0) +#define BIT_DISPLAY_LCD_OFF (0 << 0) +#define REG_BACKLIGHT_CTRL 0xF7BD /* LCD backlight control: off/restore */ +#define BIT_BACKLIGHT_ON (1 << 0) +#define BIT_BACKLIGHT_OFF (0 << 0) + +/* SCI Event Number from EC */ +#define SCI_EVENT_NUM_LID 0x23 /* press the lid or not */ +#define SCI_EVENT_NUM_DISPLAY_TOGGLE 0x24 /* Fn+F3 for display switch */ +#define SCI_EVENT_NUM_SLEEP 0x25 /* Fn+F1 for entering sleep mode */ +#define SCI_EVENT_NUM_OVERTEMP 0x26 /* Over-temperature happened */ +#define SCI_EVENT_NUM_CRT_DETECT 0x27 /* CRT is connected */ +#define SCI_EVENT_NUM_CAMERA 0x28 /* Camera is on or off */ +#define SCI_EVENT_NUM_USB_OC2 0x29 /* USB2 Over Current occurred */ +#define SCI_EVENT_NUM_USB_OC0 0x2A /* USB0 Over Current occurred */ +#define SCI_EVENT_NUM_AC_BAT 0x2E /* ac & battery relative issue */ +#define BIT_AC_BAT_BAT_IN 0 +#define BIT_AC_BAT_AC_IN 1 +#define BIT_AC_BAT_INIT_CAP 2 +#define BIT_AC_BAT_CHARGE_MODE 3 +#define BIT_AC_BAT_STOP_CHARGE 4 +#define BIT_AC_BAT_BAT_LOW 5 +#define BIT_AC_BAT_BAT_FULL 6 +#define SCI_EVENT_NUM_DISPLAY_BRIGHTNESS 0x2D /* LCD backlight brightness adjust */ +#define SCI_EVENT_NUM_AUDIO_VOLUME 0x2F /* Volume adjust */ +#define SCI_EVENT_NUM_WLAN 0x30 /* Wlan is on or off */ +#define SCI_EVENT_NUM_AUDIO_MUTE 0x2C /* Mute is on or off */ +#define SCI_EVENT_NUM_BLACK_SCREEN 0x2B /* Black screen is on or off */ + +#define SCI_INDEX_LID 0x00 +#define SCI_INDEX_DISPLAY_TOGGLE 0x01 +#define SCI_INDEX_SLEEP 0x02 +#define SCI_INDEX_OVERTEMP 0x03 +#define SCI_INDEX_CRT_DETECT 0x04 +#define SCI_INDEX_CAMERA 0x05 +#define SCI_INDEX_USB_OC2 0x06 +#define SCI_INDEX_USB_OC0 0x07 +#define SCI_INDEX_AC_BAT 0x08 +#define SCI_INDEX_DISPLAY_BRIGHTNESS_INC 0x09 +#define SCI_INDEX_DISPLAY_BRIGHTNESS_DEC 0x0A +#define SCI_INDEX_AUDIO_VOLUME_INC 0x0B +#define SCI_INDEX_AUDIO_VOLUME_DEC 0x0C +#define SCI_INDEX_WLAN 0x0D +#define SCI_INDEX_AUDIO_MUTE 0x0E +#define SCI_INDEX_BLACK_SCREEN 0x0F + +#define SCI_MAX_EVENT_COUNT 0x10 + +/* EC access port for sci communication */ +#define EC_CMD_PORT 0x66 +#define EC_STS_PORT 0x66 +#define EC_DAT_PORT 0x62 +#define CMD_INIT_IDLE_MODE 0xdd +#define CMD_EXIT_IDLE_MODE 0xdf +#define CMD_INIT_RESET_MODE 0xd8 +#define CMD_REBOOT_SYSTEM 0x8c +#define CMD_GET_EVENT_NUM 0x84 +#define CMD_PROGRAM_PIECE 0xda + +/* #define DEBUG_PRINTK */ + +#ifdef DEBUG_PRINTK +#define PRINTK_DBG(args...) printk(args) +#else +#define PRINTK_DBG(args...) +#endif + +extern void _rdmsr(u32 addr, u32 *hi, u32 *lo); +extern void _wrmsr(u32 addr, u32 hi, u32 lo); diff -Nur linux-2.6.30.5.orig/drivers/platform/loongson/ec_kb3310b/ec_misc.c linux-2.6.30.5/drivers/platform/loongson/ec_kb3310b/ec_misc.c --- linux-2.6.30.5.orig/drivers/platform/loongson/ec_kb3310b/ec_misc.c 1970-01-01 01:00:00.000000000 +0100 +++ linux-2.6.30.5/drivers/platform/loongson/ec_kb3310b/ec_misc.c 2009-08-23 19:01:04.000000000 +0200 @@ -0,0 +1,913 @@ +/* + * EC(Embedded Controller) KB3310B misc device driver on Linux + * Author: liujl + * Date : 2008-04-20 + * + * NOTE : + * 1, The EC resources accessing and programming are supported. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include "ec.h" +#include "ec_misc.h" + +/* open for using rom protection action */ +#define EC_ROM_PROTECTION + +/* this spinlock is dedicated for ec_read & ec_write function */ +DEFINE_SPINLOCK(index_access_lock); +/* this spinlock is dedicated for 62&66 ports access */ +DEFINE_SPINLOCK(port_access_lock); +/* information used for programming */ +struct ec_info ecinfo; + +/* read a byte from EC registers throught index-io */ +unsigned char ec_read(unsigned short addr) +{ + unsigned char value; + unsigned long flags; + + spin_lock_irqsave(&index_access_lock, flags); + outb((addr & 0xff00) >> 8, EC_IO_PORT_HIGH); + outb((addr & 0x00ff), EC_IO_PORT_LOW); + value = inb(EC_IO_PORT_DATA); + spin_unlock_irqrestore(&index_access_lock, flags); + + return value; +} +EXPORT_SYMBOL_GPL(ec_read); + +/* write a byte to EC registers throught index-io */ +void ec_write(unsigned short addr, unsigned char val) +{ + unsigned long flags; + + spin_lock_irqsave(&index_access_lock, flags); + outb((addr & 0xff00) >> 8, EC_IO_PORT_HIGH); + outb((addr & 0x00ff), EC_IO_PORT_LOW); + outb(val, EC_IO_PORT_DATA); + inb(EC_IO_PORT_DATA); /* flush the write action */ + spin_unlock_irqrestore(&index_access_lock, flags); + + return; +} +EXPORT_SYMBOL_GPL(ec_write); + +/* + * ec_query_seq + * this function is used for ec command writing and corresponding status query + */ +int ec_query_seq(unsigned char cmd) +{ + int timeout; + unsigned char status; + unsigned long flags; + int ret = 0; + + spin_lock_irqsave(&port_access_lock, flags); + + /* make chip goto reset mode */ + udelay(EC_REG_DELAY); + outb(cmd, EC_CMD_PORT); + udelay(EC_REG_DELAY); + + /* check if the command is received by ec */ + timeout = EC_CMD_TIMEOUT; + status = inb(EC_STS_PORT); + while (timeout--) { + if (status & (1 << 1)) { + status = inb(EC_STS_PORT); + udelay(EC_REG_DELAY); + continue; + } + break; + } + + if (timeout <= 0) { + printk(KERN_ERR "EC QUERY SEQ : deadable error : timeout...\n"); + ret = -EINVAL; + } else { + PRINTK_DBG(KERN_INFO + "(%x/%d)ec issued command %d status : 0x%x\n", + timeout, EC_CMD_TIMEOUT - timeout, cmd, status); + } + + spin_unlock_irqrestore(&port_access_lock, flags); + + return ret; +} +EXPORT_SYMBOL_GPL(ec_query_seq); + +/* enable the chip reset mode */ +static int ec_init_reset_mode(void) +{ + int timeout; + unsigned char status = 0; + int ret = 0; + + /* make chip goto reset mode */ + ret = ec_query_seq(CMD_INIT_RESET_MODE); + if (ret < 0) { + printk(KERN_ERR "ec init reset mode failed.\n"); + goto out; + } + + /* make the action take active */ + timeout = EC_CMD_TIMEOUT; + status = ec_read(REG_POWER_MODE) & FLAG_RESET_MODE; + while (timeout--) { + if (status) { + udelay(EC_REG_DELAY); + break; + } + status = ec_read(REG_POWER_MODE) & FLAG_RESET_MODE; + udelay(EC_REG_DELAY); + } + if (timeout <= 0) { + printk(KERN_ERR "ec rom fixup : can't check reset status.\n"); + ret = -EINVAL; + } else { + PRINTK_DBG(KERN_INFO "(%d/%d)reset 0xf710 : 0x%x\n", timeout, + EC_CMD_TIMEOUT - timeout, status); + } + + /* set MCU to reset mode */ + udelay(EC_REG_DELAY); + status = ec_read(REG_PXCFG); + status |= (1 << 0); + ec_write(REG_PXCFG, status); + udelay(EC_REG_DELAY); + + /* disable FWH/LPC */ + udelay(EC_REG_DELAY); + status = ec_read(REG_LPCCFG); + status &= ~(1 << 7); + ec_write(REG_LPCCFG, status); + udelay(EC_REG_DELAY); + + PRINTK_DBG(KERN_INFO "entering reset mode ok..............\n"); + + out: + return ret; +} + +/* make ec exit from reset mode */ +static void ec_exit_reset_mode(void) +{ + unsigned char regval; + + udelay(EC_REG_DELAY); + regval = ec_read(REG_LPCCFG); + regval |= (1 << 7); + ec_write(REG_LPCCFG, regval); + regval = ec_read(REG_PXCFG); + regval &= ~(1 << 0); + ec_write(REG_PXCFG, regval); + PRINTK_DBG(KERN_INFO "exit reset mode ok..................\n"); + + return; +} + +/* make ec disable WDD */ +static void ec_disable_WDD(void) +{ + unsigned char status; + + udelay(EC_REG_DELAY); + status = ec_read(REG_WDTCFG); + ec_write(REG_WDTPF, 0x03); + ec_write(REG_WDTCFG, (status & 0x80) | 0x48); + PRINTK_DBG(KERN_INFO "Disable WDD ok..................\n"); + + return; +} + +/* make ec enable WDD */ +static void ec_enable_WDD(void) +{ + unsigned char status; + + udelay(EC_REG_DELAY); + status = ec_read(REG_WDTCFG); + ec_write(REG_WDT, 0x28); /* set WDT 5sec(0x28) */ + ec_write(REG_WDTCFG, (status & 0x80) | 0x03); + PRINTK_DBG(KERN_INFO "Enable WDD ok..................\n"); + + return; +} + +/* make ec goto idle mode */ +static int ec_init_idle_mode(void) +{ + int timeout; + unsigned char status = 0; + int ret = 0; + + ec_query_seq(CMD_INIT_IDLE_MODE); + + /* make the action take active */ + timeout = EC_CMD_TIMEOUT; + status = ec_read(REG_POWER_MODE) & FLAG_IDLE_MODE; + while (timeout--) { + if (status) { + udelay(EC_REG_DELAY); + break; + } + status = ec_read(REG_POWER_MODE) & FLAG_IDLE_MODE; + udelay(EC_REG_DELAY); + } + if (timeout <= 0) { + printk(KERN_ERR "ec rom fixup : can't check out the status.\n"); + ret = -EINVAL; + } else { + PRINTK_DBG(KERN_INFO "(%d/%d)0xf710 : 0x%x\n", timeout, + EC_CMD_TIMEOUT - timeout, ec_read(REG_POWER_MODE)); + } + + PRINTK_DBG(KERN_INFO "entering idle mode ok...................\n"); + + return ret; +} + +/* make ec exit from idle mode */ +static int ec_exit_idle_mode(void) +{ + + ec_query_seq(CMD_EXIT_IDLE_MODE); + + PRINTK_DBG(KERN_INFO "exit idle mode ok...................\n"); + + return 0; +} + +static int ec_instruction_cycle(void) +{ + unsigned long timeout; + int ret = 0; + + timeout = EC_FLASH_TIMEOUT; + while (timeout-- >= 0) { + if (!(ec_read(REG_XBISPICFG) & SPICFG_SPI_BUSY)) + break; + } + if (timeout <= 0) { + printk(KERN_ERR + "EC_INSTRUCTION_CYCLE : timeout for check flag.\n"); + ret = -EINVAL; + goto out; + } + + out: + return ret; +} + +/* To see if the ec is in busy state or not. */ +static inline int ec_flash_busy(unsigned long timeout) +{ + /* assurance the first command be going to rom */ + if (ec_instruction_cycle() < 0) + return EC_STATE_BUSY; +#if 1 + timeout = timeout / EC_MAX_DELAY_UNIT; + while (timeout-- > 0) { + /* check the rom's status of busy flag */ + ec_write(REG_XBISPICMD, SPICMD_READ_STATUS); + if (ec_instruction_cycle() < 0) + return EC_STATE_BUSY; + if ((ec_read(REG_XBISPIDAT) & 0x01) == 0x00) + return EC_STATE_IDLE; + udelay(EC_MAX_DELAY_UNIT); + } + if (timeout <= 0) { + printk(KERN_ERR + "EC_FLASH_BUSY : timeout for check rom flag.\n"); + return EC_STATE_BUSY; + } +#else + /* check the rom's status of busy flag */ + ec_write(REG_XBISPICMD, SPICMD_READ_STATUS); + if (ec_instruction_cycle() < 0) + return EC_STATE_BUSY; + + timeout = timeout / EC_MAX_DELAY_UNIT; + while (timeout-- > 0) { + if ((ec_read(REG_XBISPIDAT) & 0x01) == 0x00) + return EC_STATE_IDLE; + udelay(EC_MAX_DELAY_UNIT); + } + if (timeout <= 0) { + printk(KERN_ERR + "EC_FLASH_BUSY : timeout for check rom flag.\n"); + return EC_STATE_BUSY; + } +#endif + + return EC_STATE_IDLE; +} + +static int rom_instruction_cycle(unsigned char cmd) +{ + unsigned long timeout = 0; + + switch (cmd) { + case SPICMD_READ_STATUS: + case SPICMD_WRITE_ENABLE: + case SPICMD_WRITE_DISABLE: + case SPICMD_READ_BYTE: + case SPICMD_HIGH_SPEED_READ: + timeout = 0; + break; + case SPICMD_WRITE_STATUS: + timeout = 300 * 1000; + break; + case SPICMD_BYTE_PROGRAM: + timeout = 5 * 1000; + break; + case SPICMD_SST_SEC_ERASE: + case SPICMD_SEC_ERASE: + timeout = 1000 * 1000; + break; + case SPICMD_SST_BLK_ERASE: + case SPICMD_BLK_ERASE: + timeout = 3 * 1000 * 1000; + break; + case SPICMD_SST_CHIP_ERASE: + case SPICMD_CHIP_ERASE: + timeout = 20 * 1000 * 1000; + break; + default: + timeout = EC_SPICMD_STANDARD_TIMEOUT; + } + if (timeout == 0) + return ec_instruction_cycle(); + if (timeout < EC_SPICMD_STANDARD_TIMEOUT) + timeout = EC_SPICMD_STANDARD_TIMEOUT; + + return ec_flash_busy(timeout); +} + +/* delay for start/stop action */ +static void delay_spi(int n) +{ + while (n--) + inb(EC_IO_PORT_HIGH); +} + +/* start the action to spi rom function */ +static void ec_start_spi(void) +{ + unsigned char val; + + delay_spi(SPI_FINISH_WAIT_TIME); + val = ec_read(REG_XBISPICFG) | SPICFG_EN_SPICMD | SPICFG_AUTO_CHECK; + ec_write(REG_XBISPICFG, val); + delay_spi(SPI_FINISH_WAIT_TIME); +} + +/* stop the action to spi rom function */ +static void ec_stop_spi(void) +{ + unsigned char val; + + delay_spi(SPI_FINISH_WAIT_TIME); + val = + ec_read(REG_XBISPICFG) & (~(SPICFG_EN_SPICMD | SPICFG_AUTO_CHECK)); + ec_write(REG_XBISPICFG, val); + delay_spi(SPI_FINISH_WAIT_TIME); +} + +/* read one byte from xbi interface */ +static int ec_read_byte(unsigned int addr, unsigned char *byte) +{ + int ret = 0; + + /* enable spicmd writing. */ + ec_start_spi(); + + /* enable write spi flash */ + ec_write(REG_XBISPICMD, SPICMD_WRITE_ENABLE); + if (rom_instruction_cycle(SPICMD_WRITE_ENABLE) == EC_STATE_BUSY) { + printk(KERN_ERR "EC_READ_BYTE : SPICMD_WRITE_ENABLE failed.\n"); + ret = -EINVAL; + goto out; + } + + /* write the address */ + ec_write(REG_XBISPIA2, (addr & 0xff0000) >> 16); + ec_write(REG_XBISPIA1, (addr & 0x00ff00) >> 8); + ec_write(REG_XBISPIA0, (addr & 0x0000ff) >> 0); + /* start action */ + ec_write(REG_XBISPICMD, SPICMD_HIGH_SPEED_READ); + if (rom_instruction_cycle(SPICMD_HIGH_SPEED_READ) == EC_STATE_BUSY) { + printk(KERN_ERR + "EC_READ_BYTE : SPICMD_HIGH_SPEED_READ failed.\n"); + ret = -EINVAL; + goto out; + } + + *byte = ec_read(REG_XBISPIDAT); + + out: + /* disable spicmd writing. */ + ec_stop_spi(); + + return ret; +} + +/* write one byte to ec rom */ +static int ec_write_byte(unsigned int addr, unsigned char byte) +{ + int ret = 0; + + /* enable spicmd writing. */ + ec_start_spi(); + + /* enable write spi flash */ + ec_write(REG_XBISPICMD, SPICMD_WRITE_ENABLE); + if (rom_instruction_cycle(SPICMD_WRITE_ENABLE) == EC_STATE_BUSY) { + printk(KERN_ERR + "EC_WRITE_BYTE : SPICMD_WRITE_ENABLE failed.\n"); + ret = -EINVAL; + goto out; + } + + /* write the address */ + ec_write(REG_XBISPIA2, (addr & 0xff0000) >> 16); + ec_write(REG_XBISPIA1, (addr & 0x00ff00) >> 8); + ec_write(REG_XBISPIA0, (addr & 0x0000ff) >> 0); + ec_write(REG_XBISPIDAT, byte); + /* start action */ + ec_write(REG_XBISPICMD, SPICMD_BYTE_PROGRAM); + if (rom_instruction_cycle(SPICMD_BYTE_PROGRAM) == EC_STATE_BUSY) { + printk(KERN_ERR + "EC_WRITE_BYTE : SPICMD_BYTE_PROGRAM failed.\n"); + ret = -EINVAL; + goto out; + } + + out: + /* disable spicmd writing. */ + ec_stop_spi(); + + return ret; +} + +/* unprotect SPI ROM */ +/* EC_ROM_unprotect function code */ +static int EC_ROM_unprotect(void) +{ + unsigned char status; + + /* enable write spi flash */ + ec_write(REG_XBISPICMD, SPICMD_WRITE_ENABLE); + if (rom_instruction_cycle(SPICMD_WRITE_ENABLE) == EC_STATE_BUSY) { + printk(KERN_ERR + "EC_UNIT_ERASE : SPICMD_WRITE_ENABLE failed.\n"); + return 1; + } + + /* unprotect the status register of rom */ + ec_write(REG_XBISPICMD, SPICMD_READ_STATUS); + if (rom_instruction_cycle(SPICMD_READ_STATUS) == EC_STATE_BUSY) { + printk(KERN_ERR "EC_UNIT_ERASE : SPICMD_READ_STATUS failed.\n"); + return 1; + } + status = ec_read(REG_XBISPIDAT); + ec_write(REG_XBISPIDAT, status & 0x02); + if (ec_instruction_cycle() < 0) { + printk(KERN_ERR "EC_UNIT_ERASE : write status value failed.\n"); + return 1; + } + + ec_write(REG_XBISPICMD, SPICMD_WRITE_STATUS); + if (rom_instruction_cycle(SPICMD_WRITE_STATUS) == EC_STATE_BUSY) { + printk(KERN_ERR + "EC_UNIT_ERASE : SPICMD_WRITE_STATUS failed.\n"); + return 1; + } + + /* enable write spi flash */ + ec_write(REG_XBISPICMD, SPICMD_WRITE_ENABLE); + if (rom_instruction_cycle(SPICMD_WRITE_ENABLE) == EC_STATE_BUSY) { + printk(KERN_ERR + "EC_UNIT_ERASE : SPICMD_WRITE_ENABLE failed.\n"); + return 1; + } + + return 0; +} + +/* erase one block or chip or sector as needed */ +static int ec_unit_erase(unsigned char erase_cmd, unsigned int addr) +{ + unsigned char status; + int ret = 0, i = 0; + int unprotect_count = 3; + int check_flag = 0; + + /* enable spicmd writing. */ + ec_start_spi(); + +#ifdef EC_ROM_PROTECTION + /* added for re-check SPICMD_READ_STATUS */ + while (unprotect_count-- > 0) { + if (EC_ROM_unprotect()) { + ret = -EINVAL; + goto out; + } + + /* first time:500ms --> 5.5sec -->10.5sec */ + for (i = 0; i < ((2 - unprotect_count) * 100 + 10); i++) + udelay(50000); + ec_write(REG_XBISPICMD, SPICMD_READ_STATUS); + if (rom_instruction_cycle(SPICMD_READ_STATUS) + == EC_STATE_BUSY) { + printk(KERN_ERR + "EC_PROGRAM_ROM : SPICMD_READ_STATUS failed.\n"); + } else { + status = ec_read(REG_XBISPIDAT); + PRINTK_DBG(KERN_INFO "Read unprotect status : 0x%x\n", + status); + if ((status & 0x1C) == 0x00) { + PRINTK_DBG(KERN_INFO + "Read unprotect status OK1 : 0x%x\n", + status & 0x1C); + check_flag = 1; + break; + } + } + } + + if (!check_flag) { + printk(KERN_INFO "SPI ROM unprotect fail.\n"); + return 1; + } +#endif + + /* block address fill */ + if (erase_cmd == SPICMD_BLK_ERASE) { + ec_write(REG_XBISPIA2, (addr & 0x00ff0000) >> 16); + ec_write(REG_XBISPIA1, (addr & 0x0000ff00) >> 8); + ec_write(REG_XBISPIA0, (addr & 0x000000ff) >> 0); + } + + /* erase the whole chip first */ + ec_write(REG_XBISPICMD, erase_cmd); + if (rom_instruction_cycle(erase_cmd) == EC_STATE_BUSY) { + printk(KERN_ERR "EC_UNIT_ERASE : erase failed.\n"); + ret = -EINVAL; + goto out; + } + + out: + /* disable spicmd writing. */ + ec_stop_spi(); + + return ret; +} + +/* update the whole rom content with H/W mode + * PLEASE USING ec_unit_erase() FIRSTLY + */ +static int ec_program_rom(struct ec_info *info, int flag) +{ + unsigned int addr = 0; + unsigned long size = 0; + unsigned char *ptr = NULL; + unsigned char data; + unsigned char val = 0; + int ret = 0; + int i, j; + unsigned char status; + + /* modify for program serial No. + * set IE_START_ADDR & use idle mode, + * disable WDD + */ + if (flag == PROGRAM_FLAG_ROM) { + ret = ec_init_reset_mode(); + addr = info->start_addr + EC_START_ADDR; + PRINTK_DBG(KERN_INFO "PROGRAM_FLAG_ROM..............\n"); + } else if (flag == PROGRAM_FLAG_IE) { + ret = ec_init_idle_mode(); + ec_disable_WDD(); + addr = info->start_addr + IE_START_ADDR; + PRINTK_DBG(KERN_INFO "PROGRAM_FLAG_IE..............\n"); + } else { + return 0; + } + + if (ret < 0) { + if (flag == PROGRAM_FLAG_IE) + ec_enable_WDD(); + return ret; + } + + size = info->size; + ptr = info->buf; + PRINTK_DBG(KERN_INFO "starting update ec ROM..............\n"); + + ret = ec_unit_erase(SPICMD_BLK_ERASE, addr); + if (ret) { + printk(KERN_ERR "program ec : erase block failed.\n"); + goto out; + } + PRINTK_DBG(KERN_ERR "program ec : erase block OK.\n"); + + i = 0; + while (i < size) { + data = *(ptr + i); + ec_write_byte(addr, data); + ec_read_byte(addr, &val); + if (val != data) { + ec_write_byte(addr, data); + ec_read_byte(addr, &val); + if (val != data) { + printk(KERN_INFO + "EC : Second flash program failed at:\t"); + printk(KERN_INFO + "addr : 0x%x, source : 0x%x, dest: 0x%x\n", + addr, data, val); + printk(KERN_INFO "This should not happen... STOP\n"); + break; + } + } + i++; + addr++; + } + +#ifdef EC_ROM_PROTECTION + /* we should start spi access firstly */ + ec_start_spi(); + + /* enable write spi flash */ + ec_write(REG_XBISPICMD, SPICMD_WRITE_ENABLE); + if (rom_instruction_cycle(SPICMD_WRITE_ENABLE) == EC_STATE_BUSY) { + printk(KERN_ERR + "EC_PROGRAM_ROM : SPICMD_WRITE_ENABLE failed.\n"); + goto out1; + } + + /* protect the status register of rom */ + ec_write(REG_XBISPICMD, SPICMD_READ_STATUS); + if (rom_instruction_cycle(SPICMD_READ_STATUS) == EC_STATE_BUSY) { + printk(KERN_ERR + "EC_PROGRAM_ROM : SPICMD_READ_STATUS failed.\n"); + goto out1; + } + status = ec_read(REG_XBISPIDAT); + + ec_write(REG_XBISPIDAT, status | 0x1C); + if (ec_instruction_cycle() < 0) { + printk(KERN_ERR + "EC_PROGRAM_ROM : write status value failed.\n"); + goto out1; + } + + ec_write(REG_XBISPICMD, SPICMD_WRITE_STATUS); + if (rom_instruction_cycle(SPICMD_WRITE_STATUS) == EC_STATE_BUSY) { + printk(KERN_ERR + "EC_PROGRAM_ROM : SPICMD_WRITE_STATUS failed.\n"); + goto out1; + } +#endif + + /* disable the write action to spi rom */ + ec_write(REG_XBISPICMD, SPICMD_WRITE_DISABLE); + if (rom_instruction_cycle(SPICMD_WRITE_DISABLE) == EC_STATE_BUSY) { + printk(KERN_ERR + "EC_PROGRAM_ROM : SPICMD_WRITE_DISABLE failed.\n"); + goto out1; + } + + out1: + /* we should stop spi access firstly */ + ec_stop_spi(); + out: + /* for security */ + for (j = 0; j < 2000; j++) + udelay(1000); + + /* modify for program serial No. + * after program No exit idle mode + * and enable WDD + */ + if (flag == PROGRAM_FLAG_ROM) { + /* exit from the reset mode */ + ec_exit_reset_mode(); + } else { + /* ec exit from idle mode */ + ret = ec_exit_idle_mode(); + ec_enable_WDD(); + if (ret < 0) + return ret; + } + + return 0; +} + +/* ioctl */ +static int misc_ioctl(struct inode *inode, struct file *filp, u_int cmd, + u_long arg) +{ + void __user *ptr = (void __user *)arg; + struct ec_reg *ecreg = (struct ec_reg *)(filp->private_data); + int ret = 0; + + switch (cmd) { + case IOCTL_RDREG: + ret = copy_from_user(ecreg, ptr, sizeof(struct ec_reg)); + if (ret) { + printk(KERN_ERR "reg read : copy from user error.\n"); + return -EFAULT; + } + if ((ecreg->addr > EC_MAX_REGADDR) + || (ecreg->addr < EC_MIN_REGADDR)) { + printk(KERN_ERR + "reg read : out of register address range.\n"); + return -EINVAL; + } + ecreg->val = ec_read(ecreg->addr); + ret = copy_to_user(ptr, ecreg, sizeof(struct ec_reg)); + if (ret) { + printk(KERN_ERR "reg read : copy to user error.\n"); + return -EFAULT; + } + break; + case IOCTL_WRREG: + ret = copy_from_user(ecreg, ptr, sizeof(struct ec_reg)); + if (ret) { + printk(KERN_ERR "reg write : copy from user error.\n"); + return -EFAULT; + } + if ((ecreg->addr > EC_MAX_REGADDR) + || (ecreg->addr < EC_MIN_REGADDR)) { + printk(KERN_ERR + "reg write : out of register address range.\n"); + return -EINVAL; + } + ec_write(ecreg->addr, ecreg->val); + break; + case IOCTL_READ_EC: + ret = copy_from_user(ecreg, ptr, sizeof(struct ec_reg)); + if (ret) { + printk(KERN_ERR "spi read : copy from user error.\n"); + return -EFAULT; + } + if ((ecreg->addr > EC_RAM_ADDR) + && (ecreg->addr < EC_MAX_REGADDR)) { + printk(KERN_ERR + "spi read : out of register address range.\n"); + return -EINVAL; + } + ec_read_byte(ecreg->addr, &(ecreg->val)); + ret = copy_to_user(ptr, ecreg, sizeof(struct ec_reg)); + if (ret) { + printk(KERN_ERR "spi read : copy to user error.\n"); + return -EFAULT; + } + break; + case IOCTL_PROGRAM_IE: + ecinfo.start_addr = EC_START_ADDR; + ecinfo.size = EC_CONTENT_MAX_SIZE; + ecinfo.buf = (u8 *) kmalloc(ecinfo.size, GFP_KERNEL); + if (ecinfo.buf == NULL) { + printk(KERN_ERR "program ie : kmalloc failed.\n"); + return -ENOMEM; + } + ret = copy_from_user(ecinfo.buf, (u8 *) ptr, ecinfo.size); + if (ret) { + printk(KERN_ERR "program ie : copy from user error.\n"); + kfree(ecinfo.buf); + ecinfo.buf = NULL; + return -EFAULT; + } + + /* use ec_program_rom to write serial No */ + ec_program_rom(&ecinfo, PROGRAM_FLAG_IE); + + kfree(ecinfo.buf); + ecinfo.buf = NULL; + break; + case IOCTL_PROGRAM_EC: + ecinfo.start_addr = EC_START_ADDR; + if (get_user((ecinfo.size), (u32 *) ptr)) { + printk(KERN_ERR "program ec : get user error.\n"); + return -EFAULT; + } + if ((ecinfo.size) > EC_CONTENT_MAX_SIZE) { + printk(KERN_ERR "program ec : size out of limited.\n"); + return -EINVAL; + } + ecinfo.buf = (u8 *) kmalloc(ecinfo.size, GFP_KERNEL); + if (ecinfo.buf == NULL) { + printk(KERN_ERR "program ec : kmalloc failed.\n"); + return -ENOMEM; + } + ret = copy_from_user(ecinfo.buf, ((u8 *) ptr + 4), ecinfo.size); + if (ret) { + printk(KERN_ERR "program ec : copy from user error.\n"); + kfree(ecinfo.buf); + ecinfo.buf = NULL; + return -EFAULT; + } + + ec_program_rom(&ecinfo, PROGRAM_FLAG_ROM); + + kfree(ecinfo.buf); + ecinfo.buf = NULL; + break; + + default: + break; + } + + return 0; +} + +static long misc_compat_ioctl(struct file *file, unsigned int cmd, + unsigned long arg) +{ + return misc_ioctl(file->f_dentry->d_inode, file, cmd, arg); +} + +static int misc_open(struct inode *inode, struct file *filp) +{ + struct ec_reg *ecreg = NULL; + ecreg = kmalloc(sizeof(struct ec_reg), GFP_KERNEL); + if (ecreg) + filp->private_data = ecreg; + + return ecreg ? 0 : -ENOMEM; +} + +static int misc_release(struct inode *inode, struct file *filp) +{ + struct ec_reg *ecreg = (struct ec_reg *)(filp->private_data); + + filp->private_data = NULL; + kfree(ecreg); + + return 0; +} + +static const struct file_operations ecmisc_fops = { + .open = misc_open, + .release = misc_release, + .read = NULL, + .write = NULL, +#ifdef CONFIG_64BIT + .compat_ioctl = misc_compat_ioctl, +#else + .ioctl = misc_ioctl, +#endif +}; + +static struct miscdevice ecmisc_device = { + .minor = ECMISC_MINOR_DEV, + .name = EC_MISC_DEV, + .fops = &ecmisc_fops +}; + +static int __init ecmisc_init(void) +{ + int ret; + + printk(KERN_INFO "EC misc device init.\n"); + ret = misc_register(&ecmisc_device); + + return ret; +} + +static void __exit ecmisc_exit(void) +{ + printk(KERN_INFO "EC misc device exit.\n"); + misc_deregister(&ecmisc_device); +} + +module_init(ecmisc_init); +module_exit(ecmisc_exit); + +MODULE_AUTHOR("liujl "); +MODULE_DESCRIPTION("KB3310 resources misc Management"); +MODULE_LICENSE("GPL"); diff -Nur linux-2.6.30.5.orig/drivers/platform/loongson/ec_kb3310b/ec_misc_fn.h linux-2.6.30.5/drivers/platform/loongson/ec_kb3310b/ec_misc_fn.h --- linux-2.6.30.5.orig/drivers/platform/loongson/ec_kb3310b/ec_misc_fn.h 1970-01-01 01:00:00.000000000 +0100 +++ linux-2.6.30.5/drivers/platform/loongson/ec_kb3310b/ec_misc_fn.h 2009-08-23 19:01:04.000000000 +0200 @@ -0,0 +1,16 @@ + +/* + * EC(Embedded Controller) KB3310B misc device export functions header file + * + * Author: liujl + * Date : 2009-03-16 + * + * EC relative export header file. + */ + +/* the general ec index-io port read action */ +extern unsigned char ec_read(unsigned short addr); +/* the general ec index-io port write action */ +extern void ec_write(unsigned short addr, unsigned char val); +/* query sequence of 62/66 port access routine */ +extern int ec_query_seq(unsigned char cmd); diff -Nur linux-2.6.30.5.orig/drivers/platform/loongson/ec_kb3310b/ec_misc.h linux-2.6.30.5/drivers/platform/loongson/ec_kb3310b/ec_misc.h --- linux-2.6.30.5.orig/drivers/platform/loongson/ec_kb3310b/ec_misc.h 1970-01-01 01:00:00.000000000 +0100 +++ linux-2.6.30.5/drivers/platform/loongson/ec_kb3310b/ec_misc.h 2009-08-23 19:01:04.000000000 +0200 @@ -0,0 +1,191 @@ +/* + * EC(Embedded Controller) KB3310B Misc device driver header file in linux + * Author : liujl + * Date : 2008-04-20 + * + * NOTE : + * 1, The application layer for reading, writing ec registers and code + * program are supported. + */ + +/* ec delay time 500us for register and status access */ +#define EC_REG_DELAY 500 /* unit : us */ + +/* version burned address */ +#define VER_ADDR 0xf7a1 +#define VER_MAX_SIZE 7 +#define EC_ROM_MAX_SIZE 0x10000 + +/* ec internal register */ +#define REG_POWER_MODE 0xF710 +#define FLAG_NORMAL_MODE 0x00 +#define FLAG_IDLE_MODE 0x01 +#define FLAG_RESET_MODE 0x02 + +/* ec update program flag */ +#define PROGRAM_FLAG_NONE 0x00 +#define PROGRAM_FLAG_IE 0x01 +#define PROGRAM_FLAG_ROM 0x02 + +/* XBI relative registers */ +#define REG_XBISEG0 0xFEA0 +#define REG_XBISEG1 0xFEA1 +#define REG_XBIRSV2 0xFEA2 +#define REG_XBIRSV3 0xFEA3 +#define REG_XBIRSV4 0xFEA4 +#define REG_XBICFG 0xFEA5 +#define REG_XBICS 0xFEA6 +#define REG_XBIWE 0xFEA7 +#define REG_XBISPIA0 0xFEA8 +#define REG_XBISPIA1 0xFEA9 +#define REG_XBISPIA2 0xFEAA +#define REG_XBISPIDAT 0xFEAB +#define REG_XBISPICMD 0xFEAC +#define REG_XBISPICFG 0xFEAD +#define REG_XBISPIDATR 0xFEAE +#define REG_XBISPICFG2 0xFEAF + +/* commands definition for REG_XBISPICMD */ +#define SPICMD_WRITE_STATUS 0x01 +#define SPICMD_BYTE_PROGRAM 0x02 +#define SPICMD_READ_BYTE 0x03 +#define SPICMD_WRITE_DISABLE 0x04 +#define SPICMD_READ_STATUS 0x05 +#define SPICMD_WRITE_ENABLE 0x06 +#define SPICMD_HIGH_SPEED_READ 0x0B +#define SPICMD_POWER_DOWN 0xB9 +#define SPICMD_SST_EWSR 0x50 +#define SPICMD_SST_SEC_ERASE 0x20 +#define SPICMD_SST_BLK_ERASE 0x52 +#define SPICMD_SST_CHIP_ERASE 0x60 +#define SPICMD_FRDO 0x3B +#define SPICMD_SEC_ERASE 0xD7 +#define SPICMD_BLK_ERASE 0xD8 +#define SPICMD_CHIP_ERASE 0xC7 + +/* bits definition for REG_XBISPICFG */ +#define SPICFG_AUTO_CHECK 0x01 +#define SPICFG_SPI_BUSY 0x02 +#define SPICFG_DUMMY_READ 0x04 +#define SPICFG_EN_SPICMD 0x08 +#define SPICFG_LOW_SPICS 0x10 +#define SPICFG_EN_SHORT_READ 0x20 +#define SPICFG_EN_OFFSET_READ 0x40 +#define SPICFG_EN_FAST_READ 0x80 + +/* SMBUS relative register block according to the EC datasheet. */ +#define REG_SMBTCRC 0xff92 +#define REG_SMBPIN 0xff93 +#define REG_SMBCFG 0xff94 +#define REG_SMBEN 0xff95 +#define REG_SMBPF 0xff96 +#define REG_SMBRCRC 0xff97 +#define REG_SMBPRTCL 0xff98 +#define REG_SMBSTS 0xff99 +#define REG_SMBADR 0xff9a +#define REG_SMBCMD 0xff9b +#define REG_SMBDAT_START 0xff9c +#define REG_SMBDAT_END 0xffa3 +#define SMBDAT_SIZE 8 +#define REG_SMBRSA 0xffa4 +#define REG_SMBCNT 0xffbc +#define REG_SMBAADR 0xffbd +#define REG_SMBADAT0 0xffbe +#define REG_SMBADAT1 0xffbf + +/* watchdog timer registers */ +#define REG_WDTCFG 0xfe80 +#define REG_WDTPF 0xfe81 +#define REG_WDT 0xfe82 + +/* lpc configure register */ +#define REG_LPCCFG 0xfe95 + +/* 8051 reg */ +#define REG_PXCFG 0xff14 + +/* Fan register in KB3310 */ +#define REG_ECFAN_SPEED_LEVEL 0xf4e4 +#define REG_ECFAN_SWITCH 0xf4d2 + +/* the ec flash rom id number */ +#define EC_ROM_PRODUCT_ID_SPANSION 0x01 +#define EC_ROM_PRODUCT_ID_MXIC 0xC2 +#define EC_ROM_PRODUCT_ID_AMIC 0x37 +#define EC_ROM_PRODUCT_ID_EONIC 0x1C + +/* Ec misc device name */ +#define EC_MISC_DEV "ec_misc" + +/* Ec misc device minor number */ +#define ECMISC_MINOR_DEV MISC_DYNAMIC_MINOR + +#define EC_IOC_MAGIC 'E' +/* misc ioctl operations */ +#define IOCTL_RDREG _IOR(EC_IOC_MAGIC, 1, int) +#define IOCTL_WRREG _IOW(EC_IOC_MAGIC, 2, int) +#define IOCTL_READ_EC _IOR(EC_IOC_MAGIC, 3, int) +#define IOCTL_PROGRAM_IE _IOW(EC_IOC_MAGIC, 4, int) +#define IOCTL_PROGRAM_EC _IOW(EC_IOC_MAGIC, 5, int) + +/* start address for programming of EC content or IE */ +/* ec running code start address */ +#define EC_START_ADDR 0x00000000 +/* ec information element storing address */ +#define IE_START_ADDR 0x00020000 + +/* EC state */ +#define EC_STATE_IDLE 0x00 /* ec in idle state */ +#define EC_STATE_BUSY 0x01 /* ec in busy state */ + +/* timeout value for programming */ +#define EC_FLASH_TIMEOUT 0x1000 /* ec program timeout */ +/* command checkout timeout including cmd to port or state flag check */ +#define EC_CMD_TIMEOUT 0x1000 +#define EC_SPICMD_STANDARD_TIMEOUT (4 * 1000) /* unit : us */ +#define EC_MAX_DELAY_UNIT (10) /* every time for polling */ +#define SPI_FINISH_WAIT_TIME 10 +/* EC content max size */ +#define EC_CONTENT_MAX_SIZE (64 * 1024) +#define IE_CONTENT_MAX_SIZE (0x100000 - IE_START_ADDR) + +/* + * piece structure : + * ------------------------------ + * | 1byte | 3 bytes | 28 bytes | + * | flag | addr | data | + * ------------------------------ + * flag : + * bit0 : '1' for first piece, '0' for other + * addr : + * address for EC to burn the data to(rom address) + * data : + * data which we should burn to the ec rom + * + * NOTE: + * so far max size should be 256B, or we should change the address-1 value. + * piece is used for IE program + */ +#define PIECE_SIZE (32 - 1 - 3) +#define FIRST_PIECE_YES 1 +#define FIRST_PIECE_NO 0 +/* piece program status reg from ec firmware */ +#define PIECE_STATUS_REG 0xF77C +/* piece program status reg done flag */ +#define PIECE_STATUS_PROGRAM_DONE 0x80 +/* piece program status reg error flag */ +#define PIECE_STATUS_PROGRAM_ERROR 0x40 +/* 32bytes should be stored here */ +#define PIECE_START_ADDR 0xF800 + +/* the register operation access struct */ +struct ec_reg { + u32 addr; /* the address of kb3310 registers */ + u8 val; /* the register value */ +}; + +struct ec_info { + u32 start_addr; + u32 size; + u8 *buf; +}; diff -Nur linux-2.6.30.5.orig/drivers/platform/loongson/ec_kb3310b/ec_sci.c linux-2.6.30.5/drivers/platform/loongson/ec_kb3310b/ec_sci.c --- linux-2.6.30.5.orig/drivers/platform/loongson/ec_kb3310b/ec_sci.c 1970-01-01 01:00:00.000000000 +0100 +++ linux-2.6.30.5/drivers/platform/loongson/ec_kb3310b/ec_sci.c 2009-08-23 19:01:04.000000000 +0200 @@ -0,0 +1,1026 @@ +/* + * EC(Embedded Controller) KB3310B SCI EVENT management driver on Linux + * Author : liujl + * Date : 2008-10-22 + * + * NOTE : Until now, I have no idea for setting the interrupt to edge sensitive + * mode, amd's help should be needed for handling this problem + * So, I assume that the interrupt width is 120us + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include "ec.h" +#include "ec_misc_fn.h" + +/* inode information */ +#define EC_SCI_MINOR_DEV MISC_DYNAMIC_MINOR +#define EC_SCI_DEV "sci" +#define SCI_IRQ_NUM 0x0A +#define CS5536_GPIO_SIZE 256 + +/* ec delay time 500us for register and status access */ +/* unit : us */ +#define EC_REG_DELAY 300 + +struct ec_sci_reg { + u32 addr; + u8 val; +}; +struct ec_sci_reg ecreg; + +struct sci_device { + /* the sci number get from ec */ + unsigned char sci_number; + + /* sci count */ + unsigned char sci_num_array[SCI_MAX_EVENT_COUNT]; + + /* irq relative */ + unsigned char irq; + unsigned char irq_data; + + /* device name */ + unsigned char name[10]; + + /* gpio base registers and length */ + unsigned long gpio_base; + unsigned long gpio_size; + + /* lock & wait_queue */ + wait_queue_head_t wq; + spinlock_t lock; + + /* storage initial value of sci status register + * sci_init_value[0] as brightness + * sci_init_value[1] as volume + */ + unsigned char sci_init_value[2]; +}; +struct sci_device *sci_device; + +#ifdef CONFIG_PROC_FS +static ssize_t sci_proc_read(struct file *file, char *buf, size_t len, + loff_t *ppos); +static ssize_t sci_proc_write(struct file *file, const char *buf, size_t len, + loff_t *ppos); +static unsigned int sci_poll(struct file *fp, poll_table *wait); +static struct proc_dir_entry *sci_proc_entry; +static const struct file_operations sci_proc_fops = { + .read = sci_proc_read, + .poll = sci_poll, + .write = sci_proc_write, +}; + +#define SCI_ACTION_COUNT 15 +#define SCI_ACTION_WIDTH 14 +char sci_action[SCI_ACTION_COUNT][SCI_ACTION_WIDTH] = { + "DISPLAY : LCD", + "DISPLAY : CRT", + "DISPLAY : ALL", + "DISPLAY : CHG", + "AUDIO : CHG", + "MACHINE : OFF", + "MACHINE : RES", + "CAMERA : ON", + "CAMERA : OFF", + "LCDLED : ON", + "LCDLED : OFF", + "LCDBL : ON", + "LCDBL : OFF", + "NONE", + "NONE" +}; + +static enum { + CMD_DISPLAY_LCD = 0, + CMD_DISPLAY_CRT, + CMD_DISPLAY_ALL, + CMD_DISPLAY_CHANGE_BRIGHTNESS, + CMD_AUDIO_CHANGE_VOLUME, + CMD_MACHINE_OFF, + CMD_MACHINE_RESET, + CMD_CAMERA_ON, + CMD_CAMERA_OFF, + CMD_LCDLED_PWRON, + CMD_LCDLED_PWROFF, + CMD_LCDBL_ON, + CMD_LCDBL_OFF, + CMD_NONE +} sci_cmd; + +#endif + +static void sci_display_lcd(void) +{ + unsigned char value; + + outb(0x21, 0x3c4); + value = inb(0x3c5); + value |= (1 << 7); + outb(0x21, 0x3c4); + outb(value, 0x3c5); + + outb(0x31, 0x3c4); + value = inb(0x3c5); + value = (value & 0xf8) | 0x01; + outb(0x31, 0x3c4); + outb(value, 0x3c5); + + return; +} + +static void sci_display_crt(void) +{ + unsigned char value; + + outb(0x21, 0x3c4); + value = inb(0x3c5); + value &= ~(1 << 7); + outb(0x21, 0x3c4); + outb(value, 0x3c5); + + outb(0x31, 0x3c4); + value = inb(0x3c5); + value = (value & 0xf8) | 0x02; + outb(0x31, 0x3c4); + outb(value, 0x3c5); + + return; +} + +static void sci_display_all(void) +{ + unsigned char value; + + outb(0x21, 0x3c4); + value = inb(0x3c5); + value &= ~(1 << 7); + outb(0x21, 0x3c4); + outb(value, 0x3c5); + + outb(0x31, 0x3c4); + value = inb(0x3c5); + value = (value & 0xf8) | 0x03; + outb(0x31, 0x3c4); + outb(value, 0x3c5); + + return; +} + +static void sci_lcd_op(unsigned char flag) +{ + unsigned char value; + + /* default display crt */ + outb(0x21, 0x3c4); + value = inb(0x3c5); + value &= ~(1 << 7); + outb(0x21, 0x3c4); + outb(value, 0x3c5); + + if (flag == CMD_LCDLED_PWRON) { + /* open lcd output */ + outb(0x31, 0x3c4); + value = inb(0x3c5); + value = (value & 0xf8) | 0x03; + outb(0x31, 0x3c4); + outb(value, 0x3c5); + } else if (flag == CMD_LCDLED_PWROFF) { + /* close lcd output */ + outb(0x31, 0x3c4); + value = inb(0x3c5); + value = (value & 0xf8) | 0x02; + outb(0x31, 0x3c4); + outb(value, 0x3c5); + } else if (flag == CMD_LCDBL_ON) + /* LCD backlight on */ + ec_write(REG_BACKLIGHT_CTRL, BIT_BACKLIGHT_ON); + else if (flag == CMD_LCDBL_OFF) + /* LCD backlight off */ + ec_write(REG_BACKLIGHT_CTRL, BIT_BACKLIGHT_OFF); + + return; +} + +static void sci_display_change_brightness(void) +{ + ec_write(REG_DISPLAY_BRIGHTNESS, FLAG_DISPLAY_BRIGHTNESS_LEVEL_4); + return; +} + +static void sci_audio_change_volume(void) +{ + ec_write(REG_AUDIO_VOLUME, FLAG_AUDIO_VOLUME_LEVEL_5); + return; +} + +static void sci_camera_on_off(void) +{ + unsigned char val; + val = ec_read(REG_CAMERA_CONTROL); + ec_write(REG_CAMERA_CONTROL, val | (1 << 1)); + return; +} + +static void sci_machine_off(void) +{ +#ifdef CONFIG_64BIT + /* cpu-gpio0 output low */ + *((unsigned int *)(0xffffffffbfe0011c)) &= ~0x00000001; + /* cpu-gpio0 as output */ + *((unsigned int *)(0xffffffffbfe00120)) &= ~0x00000001; +#else + /* cpu-gpio0 output low */ + *((unsigned int *)(0xbfe0011c)) &= ~0x00000001; + /* cpu-gpio0 as output */ + *((unsigned int *)(0xbfe00120)) &= ~0x00000001; +#endif /* end ifdef CONFIG_64BIT */ + return; +} + +static void sci_machine_reset(void) +{ + ec_write(REG_RESET, BIT_RESET_ON); + return; +} + +/* static const char driver_version[] = "1.0"; */ +static const char driver_version[] = VERSION; + +#ifdef CONFIG_PROC_FS +#define PROC_BUF_SIZE 128 +unsigned char proc_buf[PROC_BUF_SIZE]; + +/* + * sci_proc_read : + * read information from sci device and suppied to upper layer + * The format is as following : + * driver_version 1.0 + * DISPLAY BRIGHTNESS INCREASE + * DISPLAY BRIGHTNESS DECREASE + * AUDIO VOLUME INCREASE + * AUDIO VOLUME DECREASE + * MUTE 0x00 close, 0x01 open + * WLAN 0x00 close, 0x01 open + * LID 0x00 close, 0x01 open + * DISPLAY TOGGLE + * BLACK SCREEN + * SLEEP + * OVER TEMPERATURE + * CRT DETECT + * CAMERA 0x00 close, 0x01 open + * USB OC2 + * USB OC0 + * BAT IN + * AC IN + * INIT CAP + * CHARGE MODE + * STOP CHARGE + * BAT LOW + * BAT FULL + */ +static ssize_t sci_proc_read(struct file *file, char *buf, size_t len, + loff_t *ppos) +{ + unsigned char event[SCI_MAX_EVENT_COUNT]; + int ret = 0; + int i; + int count = 0; + DECLARE_WAITQUEUE(wait, current); + + PRINTK_DBG("0 irq_data %d\n", sci_device->irq_data); + + if (sci_device->irq_data == 0) { + add_wait_queue(&(sci_device->wq), &wait); + + while (!sci_device->irq_data) { + set_current_state(TASK_INTERRUPTIBLE); + schedule(); + } + remove_wait_queue(&(sci_device->wq), &wait); + } + + PRINTK_DBG("1 irq_data %d\n", sci_device->irq_data); + __set_current_state(TASK_RUNNING); + + for (i = 0; i < SCI_MAX_EVENT_COUNT; i++) + event[i] = sci_device->sci_num_array[i]; + + ret = sprintf(proc_buf, + "%s 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x " + "0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x " + "0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x\n", + driver_version, event[SCI_INDEX_DISPLAY_BRIGHTNESS_INC], + event[SCI_INDEX_DISPLAY_BRIGHTNESS_DEC], + event[SCI_INDEX_AUDIO_VOLUME_INC], + event[SCI_INDEX_AUDIO_VOLUME_DEC], + event[SCI_INDEX_AUDIO_MUTE], event[SCI_INDEX_WLAN], + event[SCI_INDEX_LID], event[SCI_INDEX_DISPLAY_TOGGLE], + event[SCI_INDEX_BLACK_SCREEN], event[SCI_INDEX_SLEEP], + event[SCI_INDEX_OVERTEMP], event[SCI_INDEX_CRT_DETECT], + event[SCI_INDEX_CAMERA], event[SCI_INDEX_USB_OC2], + event[SCI_INDEX_USB_OC0], + (event[SCI_INDEX_AC_BAT] & 0x01) >> BIT_AC_BAT_BAT_IN, + (event[SCI_INDEX_AC_BAT] & 0x02) >> BIT_AC_BAT_AC_IN, + (event[SCI_INDEX_AC_BAT] & 0x04) >> BIT_AC_BAT_INIT_CAP, + (event[SCI_INDEX_AC_BAT] & 0x08) >> + BIT_AC_BAT_CHARGE_MODE, + (event[SCI_INDEX_AC_BAT] & 0x10) >> + BIT_AC_BAT_STOP_CHARGE, + (event[SCI_INDEX_AC_BAT] & 0x20) >> BIT_AC_BAT_BAT_LOW, + (event[SCI_INDEX_AC_BAT] & 0x40) >> BIT_AC_BAT_BAT_FULL); + + count = strlen(proc_buf); + sci_device->irq_data = 0; + + if (len < count) + return -ENOMEM; + if (PROC_BUF_SIZE < count) + return -ENOMEM; + + if (copy_to_user(buf, proc_buf, count)) + return -EFAULT; + + return count; +} + +/* + * sci_proc_write : + * get the upper layer's action and take action. + */ +static ssize_t sci_proc_write(struct file *file, const char *buf, size_t len, + loff_t *ppos) +{ + int i; + + if (len > PROC_BUF_SIZE) + return -ENOMEM; + if (copy_from_user(proc_buf, buf, len)) + return -EFAULT; + proc_buf[len] = '\0'; + + PRINTK_DBG("proc_buf : %s\n", proc_buf); + for (i = 0; i < SCI_ACTION_COUNT; i++) { + if (strncmp(proc_buf, sci_action[i], strlen(sci_action[i])) == + 0) { + sci_cmd = i; + break; + } + } + if (i == SCI_ACTION_COUNT) + sci_cmd = CMD_NONE; + PRINTK_DBG("sci_cmd: %d\n", sci_cmd); + switch (sci_cmd) { + case CMD_DISPLAY_LCD: + sci_display_lcd(); + PRINTK_DBG(KERN_DEBUG "CMD_DISPLAY_LCD"); + break; + case CMD_DISPLAY_CRT: + sci_display_crt(); + PRINTK_DBG(KERN_DEBUG "CMD_DISPLAY_CRT"); + break; + case CMD_DISPLAY_ALL: + sci_display_all(); + PRINTK_DBG(KERN_DEBUG "CMD_DISPLAY_ALL"); + break; + case CMD_DISPLAY_CHANGE_BRIGHTNESS: + sci_display_change_brightness(); + PRINTK_DBG(KERN_DEBUG "CMD_DISPLAY_CHANGE_BRIGHTNESS"); + break; + case CMD_AUDIO_CHANGE_VOLUME: + sci_audio_change_volume(); + PRINTK_DBG(KERN_DEBUG "CMD_AUDIO_CHANGE_VOLUME"); + break; + case CMD_MACHINE_OFF: + sci_machine_off(); + PRINTK_DBG(KERN_DEBUG "CMD_MACHINE_OFF"); + break; + case CMD_MACHINE_RESET: + sci_machine_reset(); + PRINTK_DBG(KERN_DEBUG "CMD_MACHINE_RESET"); + break; + case CMD_CAMERA_ON: + sci_camera_on_off(); + PRINTK_DBG(KERN_DEBUG "CMD_CAMERA_ON"); + break; + case CMD_CAMERA_OFF: + sci_camera_on_off(); + PRINTK_DBG(KERN_DEBUG "CMD_CAMERA_OFF"); + break; + case CMD_LCDLED_PWRON: + sci_lcd_op(CMD_LCDLED_PWRON); + PRINTK_DBG(KERN_DEBUG "CMD_LCDLED_PWRON"); + break; + case CMD_LCDLED_PWROFF: + sci_lcd_op(CMD_LCDLED_PWROFF); + PRINTK_DBG(KERN_DEBUG "CMD_LCDLED_PWROFF"); + break; + case CMD_LCDBL_ON: + sci_lcd_op(CMD_LCDBL_ON); + PRINTK_DBG(KERN_DEBUG "CMD_LCDBL_ON"); + break; + case CMD_LCDBL_OFF: + sci_lcd_op(CMD_LCDBL_OFF); + PRINTK_DBG(KERN_DEBUG "CMD_LCDBL_OFF"); + break; + default: + printk(KERN_ERR "EC SCI : Not supported cmd.\n"); + return -EINVAL; + } + + return len; +} +#endif + +/* + * sci_query_event_num : + * using query command to ec to get the proper event number + */ +static int sci_query_event_num(void) +{ + int ret = 0; + + ret = ec_query_seq(CMD_GET_EVENT_NUM); + return ret; +} + +/* + * sci_get_event_num : + * get sci event number from ec + * NOTE : this routine must follow the sci_query_event_num + * function in the interrupt + */ +int sci_get_event_num(void) +{ + int timeout = 100; + unsigned char value; + unsigned char status; + + udelay(EC_REG_DELAY); + status = inb(EC_STS_PORT); + udelay(EC_REG_DELAY); + while (timeout--) { + if (!(status & (1 << 0))) { + status = inb(EC_STS_PORT); + udelay(EC_REG_DELAY); + continue; + } + break; + } + if (timeout <= 0) { + PRINTK_DBG("fixup sci : get event number timeout.\n"); + return -EINVAL; + } + value = inb(EC_DAT_PORT); + udelay(EC_REG_DELAY); + + return value; +} +EXPORT_SYMBOL(sci_get_event_num); + +/* + * sci_parse_num : + * parse the event number routine, and store all the information + * to the sci_num_array[] for upper layer using + */ +static int sci_parse_num(struct sci_device *sci_device) +{ + unsigned char val; + + sci_device->sci_num_array[SCI_INDEX_DISPLAY_TOGGLE] = 0x0; + sci_device->sci_num_array[SCI_INDEX_SLEEP] = 0x0; + sci_device->sci_num_array[SCI_INDEX_DISPLAY_BRIGHTNESS_DEC] = 0; + sci_device->sci_num_array[SCI_INDEX_DISPLAY_BRIGHTNESS_INC] = 0; + sci_device->sci_num_array[SCI_INDEX_AUDIO_VOLUME_INC] = 0; + sci_device->sci_num_array[SCI_INDEX_AUDIO_VOLUME_DEC] = 0; + + sci_device->sci_num_array[SCI_INDEX_CAMERA] = 0x0; + sci_device->sci_num_array[SCI_INDEX_WLAN] = ec_read(REG_WLAN_STATUS); + sci_device->sci_num_array[SCI_INDEX_AUDIO_MUTE] = + ec_read(REG_AUDIO_MUTE); + sci_device->sci_num_array[SCI_INDEX_BLACK_SCREEN] = + ec_read(REG_DISPLAY_LCD); + sci_device->sci_num_array[SCI_INDEX_CRT_DETECT] = + ec_read(REG_CRT_DETECT); + if (ec_read(REG_BAT_POWER) & BIT_BAT_POWER_ACIN) { + sci_device->sci_num_array[SCI_INDEX_AC_BAT] |= + 1 << BIT_AC_BAT_AC_IN; + } else { + sci_device->sci_num_array[SCI_INDEX_AC_BAT] &= + ~(1 << BIT_AC_BAT_AC_IN); + } + + switch (sci_device->sci_number) { + case SCI_EVENT_NUM_LID: + sci_device->sci_num_array[SCI_INDEX_LID] = + ec_read(REG_LID_DETECT); + break; + case SCI_EVENT_NUM_DISPLAY_TOGGLE: + sci_device->sci_num_array[SCI_INDEX_DISPLAY_TOGGLE] = 0x01; + break; + case SCI_EVENT_NUM_SLEEP: + sci_device->sci_num_array[SCI_INDEX_SLEEP] = 0x01; + break; + case SCI_EVENT_NUM_OVERTEMP: + sci_device->sci_num_array[SCI_INDEX_OVERTEMP] = + (ec_read(REG_BAT_CHARGE_STATUS) & + BIT_BAT_CHARGE_STATUS_OVERTEMP) >> 2; + break; + case SCI_EVENT_NUM_CRT_DETECT: + sci_device->sci_num_array[SCI_INDEX_CRT_DETECT] = + ec_read(REG_CRT_DETECT); + break; + case SCI_EVENT_NUM_CAMERA: + sci_device->sci_num_array[SCI_INDEX_CAMERA] = 0x1; + break; + case SCI_EVENT_NUM_USB_OC2: + sci_device->sci_num_array[SCI_INDEX_USB_OC2] = + ec_read(REG_USB2_FLAG); + break; + case SCI_EVENT_NUM_USB_OC0: + sci_device->sci_num_array[SCI_INDEX_USB_OC0] = + ec_read(REG_USB0_FLAG); + break; + case SCI_EVENT_NUM_AC_BAT: + if (ec_read(REG_BAT_STATUS) & BIT_BAT_STATUS_IN) { + sci_device->sci_num_array[SCI_INDEX_AC_BAT] |= + 1 << BIT_AC_BAT_BAT_IN; + } else { + sci_device->sci_num_array[SCI_INDEX_AC_BAT] &= + ~(1 << BIT_AC_BAT_BAT_IN); + } + + if (ec_read(REG_BAT_POWER) & BIT_BAT_POWER_ACIN) { + sci_device->sci_num_array[SCI_INDEX_AC_BAT] |= + 1 << BIT_AC_BAT_AC_IN; + } else { + sci_device->sci_num_array[SCI_INDEX_AC_BAT] &= + ~(1 << BIT_AC_BAT_AC_IN); + } + + /* init_bat_cap will not be included here. */ + + if (ec_read(REG_BAT_CHARGE_STATUS) & + BIT_BAT_CHARGE_STATUS_PRECHG) { + sci_device->sci_num_array[SCI_INDEX_AC_BAT] |= + 1 << BIT_AC_BAT_CHARGE_MODE; + } else { + sci_device->sci_num_array[SCI_INDEX_AC_BAT] &= + ~(1 << BIT_AC_BAT_CHARGE_MODE); + } + + if (ec_read(REG_BAT_STATE) & BIT_BAT_STATE_DISCHARGING) { + sci_device->sci_num_array[SCI_INDEX_AC_BAT] |= + 1 << BIT_AC_BAT_STOP_CHARGE; + } else { + sci_device->sci_num_array[SCI_INDEX_AC_BAT] &= + ~(1 << BIT_AC_BAT_STOP_CHARGE); + } + + if (ec_read(REG_BAT_STATUS) & BIT_BAT_STATUS_LOW) { + sci_device->sci_num_array[SCI_INDEX_AC_BAT] |= + 1 << BIT_AC_BAT_BAT_LOW; + } else { + sci_device->sci_num_array[SCI_INDEX_AC_BAT] &= + ~(1 << BIT_AC_BAT_BAT_LOW); + } + + if (ec_read(REG_BAT_STATUS) & BIT_BAT_STATUS_FULL) { + sci_device->sci_num_array[SCI_INDEX_AC_BAT] |= + 1 << BIT_AC_BAT_BAT_FULL; + } else { + sci_device->sci_num_array[SCI_INDEX_AC_BAT] &= + ~(1 << BIT_AC_BAT_BAT_FULL); + } + break; + case SCI_EVENT_NUM_DISPLAY_BRIGHTNESS: + val = ec_read(REG_DISPLAY_BRIGHTNESS); + if ((val == 0x00) || (val < sci_device->sci_init_value[0])) { + sci_device-> + sci_num_array[SCI_INDEX_DISPLAY_BRIGHTNESS_DEC] = 1; + sci_device->sci_init_value[0] = val; + } else if ((val == 0x08) + || (val > sci_device->sci_init_value[0])) { + sci_device-> + sci_num_array[SCI_INDEX_DISPLAY_BRIGHTNESS_INC] = 1; + sci_device->sci_init_value[0] = val; + } + break; + case SCI_EVENT_NUM_AUDIO_VOLUME: + val = ec_read(REG_AUDIO_VOLUME); + if ((val == 0x00) || (val < sci_device->sci_init_value[1])) { + sci_device->sci_num_array[SCI_INDEX_AUDIO_VOLUME_DEC] = + 1; + sci_device->sci_init_value[1] = val; + } else if ((val == 0x0a) + || (val > sci_device->sci_init_value[1])) { + sci_device->sci_num_array[SCI_INDEX_AUDIO_VOLUME_INC] = + 1; + sci_device->sci_init_value[1] = val; + } + break; + case SCI_EVENT_NUM_WLAN: + sci_device->sci_num_array[SCI_INDEX_WLAN] = + ec_read(REG_WLAN_STATUS); + break; + case SCI_EVENT_NUM_AUDIO_MUTE: + sci_device->sci_num_array[SCI_INDEX_AUDIO_MUTE] = + ec_read(REG_AUDIO_MUTE); + break; + case SCI_EVENT_NUM_BLACK_SCREEN: + sci_device->sci_num_array[SCI_INDEX_BLACK_SCREEN] = + ec_read(REG_DISPLAY_LCD); + break; + + default: + PRINTK_DBG(KERN_ERR "EC SCI : not supported SCI NUMBER.\n"); + return -EINVAL; + break; + } + + return 0; +} + +/* + * sci_int_routine : sci main interrupt routine + * we will do the query and get event number together + * so the interrupt routine should be longer than 120us + * now at least 3ms elpase for it. + */ +static irqreturn_t sci_int_routine(int irq, void *dev_id) +{ + int ret; + + if (sci_device->irq != irq) { + PRINTK_DBG(KERN_ERR "EC SCI :spurious irq.\n"); + return IRQ_NONE; + } + + /* query the event number */ + ret = sci_query_event_num(); + if (ret < 0) { + PRINTK_DBG("ret 1: %d\n", ret); + return IRQ_NONE; + } + + ret = sci_get_event_num(); + if (ret < 0) { + PRINTK_DBG("ret 2: %d\n", ret); + return IRQ_NONE; + } + sci_device->sci_number = ret; + + PRINTK_DBG(KERN_INFO "sci_number :0x%x\n", sci_device->sci_number); + + /* parse the event number and wake the queue */ + if ((sci_device->sci_number != 0x00) + && (sci_device->sci_number != 0xff)) { + ret = sci_parse_num(sci_device); + PRINTK_DBG("ret 3: %d\n", ret); + if (!ret) + sci_device->irq_data = 1; + else + sci_device->irq_data = 0; + + wake_up_interruptible(&(sci_device->wq)); + PRINTK_DBG("interrupitble\n"); + } + + return IRQ_HANDLED; +} + +static int sci_open(struct inode *inode, struct file *filp) +{ + PRINTK_DBG(KERN_INFO "SCI : open ok.\n"); + return 0; +} + +static int sci_release(struct inode *inode, struct file *filp) +{ + PRINTK_DBG(KERN_INFO "SCI : close ok.\n"); + return 0; +} + +/* + * sci_poll : poll routine for upper layer using + */ +static unsigned int sci_poll(struct file *fp, poll_table * wait) +{ + int mask = 0; + + /* printk("current task %p\n", current); */ + poll_wait(fp, &(sci_device->wq), wait); + if (sci_device->irq_data) { + /* printk("current task 1 %p\n", current); */ + mask = POLLIN | POLLRDNORM; + } + + return mask; +} + +static int sci_ioctl(struct inode *inode, struct file *filp, unsigned long cmd, + unsigned long arg) +{ + void __user *ptr = (void __user *)arg; + int ret = 0; + + switch (cmd) { +/* case IOCTL_GET_INIT_STATE : */ + case 1: + ret = copy_from_user(&ecreg, ptr, sizeof(struct ec_sci_reg)); + if (ret) { + printk(KERN_ERR "read from user error.\n"); + return -EFAULT; + } + if (ecreg.addr < 0xf400 || ecreg.addr > 0xffff) + return -EINVAL; + ecreg.val = ec_read(ecreg.addr); + ret = copy_to_user(ptr, &ecreg, sizeof(struct ec_sci_reg)); + if (ret) { + printk(KERN_ERR "reg read : copy to user error.\n"); + return -EFAULT; + } + break; + default: + break; + } + + return 0; +} + +static long sci_compat_ioctl(struct file *file, unsigned int cmd, + unsigned long arg) +{ + return sci_ioctl(file->f_dentry->d_inode, file, cmd, arg); +} + +static const struct file_operations sci_fops = { +#ifdef CONFIG_64BIT + .compat_ioctl = sci_compat_ioctl, +#else + .ioclt = sci_ioctl, +#endif + .open = sci_open, + .poll = sci_poll, + .release = sci_release, +}; + +static struct miscdevice sci_dev = { + .minor = EC_SCI_MINOR_DEV, + .name = EC_SCI_DEV, + .fops = &sci_fops +}; + +static struct pci_device_id sci_pci_tbl[] = { + {PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_CS5536_ISA)}, + {} +}; + +MODULE_DEVICE_TABLE(pci, sci_pci_tbl); + +/* + * sci_low_level_init : + * config and init some msr and gpio register properly. + */ +static int sci_low_level_init(struct sci_device *scidev) +{ + u32 hi, lo; + u32 gpio_base = scidev->gpio_base; + int ret = 0; + unsigned long flags; + + /* filter the former kb3310 interrupt for security */ + ret = sci_query_event_num(); + if (ret) { + PRINTK_DBG(KERN_ERR + "sci low level init query event num failed.\n"); + return ret; + } + + /* for filtering next number interrupt */ + udelay(10000); + + /* set gpio native registers and msrs for GPIO27 SCI EVENT PIN + * gpio : + * input, pull-up, no-invert, event-count and value 0, + * no-filter, no edge mode + * gpio27 map to Virtual gpio0 + * msr : + * no primary and lpc + * Unrestricted Z input to IG10 from Virtual gpio 0. + */ + local_irq_save(flags); + _rdmsr(0x80000024, &hi, &lo); + lo &= ~(1 << 10); + _wrmsr(0x80000024, hi, lo); + _rdmsr(0x80000025, &hi, &lo); + lo &= ~(1 << 10); + _wrmsr(0x80000025, hi, lo); + _rdmsr(0x80000023, &hi, &lo); + lo |= (0x0a << 0); + _wrmsr(0x80000023, hi, lo); + local_irq_restore(flags); + + /* set gpio27 as sci interrupt : + * input, pull-up, no-fliter, no-negedge, invert + * the sci event is just about 120us + */ + asm(".set noreorder\n"); + /* input enable */ + outl(0x00000800, (gpio_base | 0xA0)); + /* revert the input */ + outl(0x00000800, (gpio_base | 0xA4)); + /* event-int enable */ + outl(0x00000800, (gpio_base | 0xB8)); + asm(".set reorder\n"); + + return 0; +} + +/* + * sci_pci_init : + * pci init routine + */ +static int __devinit sci_pci_init(struct pci_dev *pdev, + const struct pci_device_id *ent) +{ + u32 gpio_base; + int ret = -EIO; + int i; + + /* init the sci device */ + sci_device = kmalloc(sizeof(struct sci_device), GFP_KERNEL); + if (sci_device == NULL) { + PRINTK_DBG(KERN_ERR + "EC SCI : get memory for sci_device failed.\n"); + return -ENOMEM; + } + init_waitqueue_head(&(sci_device->wq)); + spin_lock_init(&sci_device->lock); + sci_device->irq = SCI_IRQ_NUM; + sci_device->irq_data = 0x00; + sci_device->sci_number = 0x00; + strcpy(sci_device->name, EC_SCI_DEV); + + sci_device->sci_init_value[0] = ec_read(REG_DISPLAY_BRIGHTNESS); + sci_device->sci_init_value[1] = ec_read(REG_AUDIO_VOLUME); + + for (i = 0; i < SCI_MAX_EVENT_COUNT; i++) + sci_device->sci_num_array[i] = 0x00; + + /* enable pci device and get the GPIO resources */ + ret = pci_enable_device(pdev); + if (ret) { + PRINTK_DBG(KERN_ERR "EC SCI : enable pci device failed.\n"); + ret = -ENODEV; + goto out_pdev; + } + + gpio_base = 0x0000; + gpio_base = pci_resource_start(pdev, 1); + gpio_base &= ~0x0003; + if (gpio_base == 0x0000) { + PRINTK_DBG(KERN_ERR "EC SCI : get resource failed.\n"); + ret = -ENODEV; + goto out_resource; + } + if (request_region(gpio_base, CS5536_GPIO_SIZE, EC_SCI_DEV) == NULL) { + PRINTK_DBG(KERN_ERR + "EC SCI : base 0x%x, length 0x%x already in use.\n", + gpio_base, CS5536_GPIO_SIZE); + goto out_resource; + } + sci_device->gpio_base = gpio_base; + sci_device->gpio_size = CS5536_GPIO_SIZE; + + /* init the relative gpio and msrs */ + ret = sci_low_level_init(sci_device); + if (ret < 0) { + printk(KERN_ERR "EC SCI : low level init failed.\n"); + goto out_irq; + } + + /* alloc the interrupt for sci not pci */ + ret = + request_irq(sci_device->irq, sci_int_routine, IRQF_SHARED, + sci_device->name, sci_device); + if (ret) { + printk(KERN_ERR "EC SCI : request irq %d failed.\n", + sci_device->irq); + ret = -EFAULT; + goto out_irq; + } + + /* register the misc device */ + ret = misc_register(&sci_dev); + if (ret != 0) { + printk(KERN_ERR "EC SCI : misc register failed.\n"); + ret = -EFAULT; + goto out_misc; + } + + ret = 0; + PRINTK_DBG(KERN_INFO "sci probe ok...\n"); + goto out; + + out_misc: + free_irq(sci_device->irq, sci_device); + out_irq: + release_region(sci_device->gpio_base, sci_device->gpio_size); + out_resource: + pci_disable_device(pdev); + out_pdev: + kfree(sci_device); + out: + return ret; +} + +static void __devexit sci_pci_remove(struct pci_dev *pdev) +{ + misc_deregister(&sci_dev); + free_irq(sci_device->irq, sci_device); + release_region(sci_device->gpio_base, sci_device->gpio_size); + pci_disable_device(pdev); + kfree(sci_device); + + return; +} + +static struct pci_driver sci_driver = { + .name = EC_SCI_DEV, + .id_table = sci_pci_tbl, + .probe = sci_pci_init, + .remove = __devexit_p(sci_pci_remove), +}; + +static int __init sci_init(void) +{ + int ret = 0; + +#ifdef CONFIG_PROC_FS + sci_proc_entry = NULL; + sci_proc_entry = create_proc_entry(EC_SCI_DEV, S_IWUSR | S_IRUGO, NULL); + if (sci_proc_entry == NULL) { + printk(KERN_ERR "EC SCI : register /proc/sci failed.\n"); + return -EINVAL; + } + sci_proc_entry->proc_fops = &sci_proc_fops; +#endif + + ret = pci_register_driver(&sci_driver); + if (ret) { + printk(KERN_ERR "EC SCI : registrer pci driver error.\n"); +#ifdef CONFIG_PROC_FS + remove_proc_entry(EC_SCI_DEV, NULL); +#endif + return ret; + } + + printk(KERN_INFO + "SCI event handler on KB3310B Embedded Controller init.\n"); + + return ret; +} + +static void __exit sci_exit(void) +{ +#ifdef CONFIG_PROC_FS + remove_proc_entry(EC_SCI_DEV, NULL); +#endif + pci_unregister_driver(&sci_driver); + printk(KERN_INFO + "SCI event handler on KB3310B Embedded Controller exit.\n"); + + return; +} + +module_init(sci_init); +module_exit(sci_exit); + +MODULE_AUTHOR("liujl "); +MODULE_DESCRIPTION("SCI Event Management for KB3310"); +MODULE_LICENSE("GPL"); diff -Nur linux-2.6.30.5.orig/drivers/platform/loongson/ec_kb3310b/io_msr_debug.c linux-2.6.30.5/drivers/platform/loongson/ec_kb3310b/io_msr_debug.c --- linux-2.6.30.5.orig/drivers/platform/loongson/ec_kb3310b/io_msr_debug.c 1970-01-01 01:00:00.000000000 +0100 +++ linux-2.6.30.5/drivers/platform/loongson/ec_kb3310b/io_msr_debug.c 2009-08-23 19:01:04.000000000 +0200 @@ -0,0 +1,198 @@ +/* + * Debug IO and MSR resources driver on Linux + * + * Author: liujl + * huangw + * Date : 2009-03-03 + * + * NOTE : + * 1, The IO and the MSR resources accessing read/write are supported. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include "ec.h" + +struct io_msr_reg { + u32 addr; /* the address of IO and MSR registers */ + u8 val; /* the register value for IO */ + u32 hi; /* the register value for MSR's high part */ + u32 lo; /* the register value for MSR's low part */ +}; + +#define IOCTL_RDMSR _IOR('F', 5, int) +#define IOCTL_WRMSR _IOR('F', 6, int) +#define IOCTL_RDIO _IOR('F', 7, int) +#define IOCTL_WRIO _IOR('F', 8, int) + +/* ec io space range */ +#define IO_MAX_ADDR 0xBFD0FFFF +#define IO_MIN_ADDR 0xBFD00000 + +static int io_msr_ioctl(struct inode *inode, struct file *filp, u_int cmd, + u_long arg) +{ + void __user *ptr = (void __user *)arg; + struct io_msr_reg *iomsrreg = (struct io_msr_reg *)(filp->private_data); + int ret = 0; + + switch (cmd) { + case IOCTL_RDIO: + ret = copy_from_user(iomsrreg, ptr, sizeof(struct io_msr_reg)); + if (ret) { + printk(KERN_ERR "IO read : copy from user error.\n"); + return -EFAULT; + } + + if (iomsrreg->addr > IO_MAX_ADDR + || iomsrreg->addr < IO_MIN_ADDR) { + printk(KERN_ERR "IO read : out of IO address range.\n"); + return -EINVAL; + } +#ifdef CONFIG_64BIT + iomsrreg->val = + *((unsigned char *)(iomsrreg-> + addr | 0xffffffff00000000)); +#else + iomsrreg->val = *((unsigned char *)(iomsrreg->addr)); +#endif + ret = copy_to_user(ptr, iomsrreg, sizeof(struct io_msr_reg)); + if (ret) { + printk(KERN_ERR "IO read : copy to user error.\n"); + return -EFAULT; + } + break; + case IOCTL_WRIO: + ret = copy_from_user(iomsrreg, ptr, sizeof(struct io_msr_reg)); + if (ret) { + printk(KERN_ERR "IO write : copy from user error.\n"); + return -EFAULT; + } + + if (iomsrreg->addr > IO_MAX_ADDR + || iomsrreg->addr < IO_MIN_ADDR) { + printk(KERN_ERR + "IO write : out of IO address range.\n"); + return -EINVAL; + } +#ifdef CONFIG_64BIT + *((unsigned char *)(iomsrreg->addr | 0xffffffff00000000)) = + iomsrreg->val; +#else + *((unsigned char *)(iomsrreg->addr)) = iomsrreg->val; +#endif + break; + case IOCTL_RDMSR: + ret = copy_from_user(iomsrreg, ptr, sizeof(struct io_msr_reg)); + if (ret) { + printk(KERN_ERR "MSR read : copy from user error.\n"); + return -EFAULT; + } + _rdmsr(iomsrreg->addr, &(iomsrreg->hi), &(iomsrreg->lo)); + ret = copy_to_user(ptr, iomsrreg, sizeof(struct io_msr_reg)); + if (ret) { + printk(KERN_ERR "MSR read : copy to user error.\n"); + return -EFAULT; + } + break; + case IOCTL_WRMSR: + ret = copy_from_user(iomsrreg, ptr, sizeof(struct io_msr_reg)); + if (ret) { + printk(KERN_ERR "MSR write : copy from user error.\n"); + return -EFAULT; + } + _wrmsr(iomsrreg->addr, iomsrreg->hi, iomsrreg->lo); + break; + + default: + break; + } + + return 0; +} + +static long io_msr_compat_ioctl(struct file *file, unsigned int cmd, + unsigned long arg) +{ + return io_msr_ioctl(file->f_dentry->d_inode, file, cmd, arg); +} + +static int io_msr_open(struct inode *inode, struct file *filp) +{ + struct io_msr_reg *iomsrreg = NULL; + iomsrreg = kmalloc(sizeof(struct io_msr_reg), GFP_KERNEL); + if (iomsrreg) + filp->private_data = iomsrreg; + + return iomsrreg ? 0 : -ENOMEM; +} + +static int io_msr_release(struct inode *inode, struct file *filp) +{ + struct io_msr_reg *iomsrreg = (struct io_msr_reg *)(filp->private_data); + + filp->private_data = NULL; + kfree(iomsrreg); + + return 0; +} + +static const struct file_operations io_msr_fops = { + .open = io_msr_open, + .release = io_msr_release, + .read = NULL, + .write = NULL, +#ifdef CONFIG_64BIT + .compat_ioctl = io_msr_compat_ioctl, +#else + .ioctl = io_msr_ioctl, +#endif +}; + +static struct miscdevice io_msr_device = { + .minor = MISC_DYNAMIC_MINOR, + .name = "io_msr_dev", + .fops = &io_msr_fops +}; + +static int __init io_msr_init(void) +{ + int ret; + + printk(KERN_INFO "IO and MSR read/write device init.\n"); + ret = misc_register(&io_msr_device); + + return ret; +} + +static void __exit io_msr_exit(void) +{ + printk(KERN_INFO "IO and MSR read/write device exit.\n"); + misc_deregister(&io_msr_device); +} + +module_init(io_msr_init); +module_exit(io_msr_exit); + +MODULE_AUTHOR("liujl "); +MODULE_DESCRIPTION("IO and MSR resources debug"); +MODULE_LICENSE("GPL"); diff -Nur linux-2.6.30.5.orig/drivers/platform/loongson/ec_kb3310b/Makefile linux-2.6.30.5/drivers/platform/loongson/ec_kb3310b/Makefile --- linux-2.6.30.5.orig/drivers/platform/loongson/ec_kb3310b/Makefile 1970-01-01 01:00:00.000000000 +0100 +++ linux-2.6.30.5/drivers/platform/loongson/ec_kb3310b/Makefile 2009-08-23 19:01:04.000000000 +0200 @@ -0,0 +1,14 @@ +# +# Embedded Controller(kb3310b) Driver for Yeeloong laptop +# + +obj-$(CONFIG_EC_KB3310B) += ec_miscd.o ec_batd.o ec_ftd.o ec_scid.o + +ec_miscd-objs := ec_misc.o +ec_batd-objs := ec_bat.o +ec_ftd-objs := ec_ft.o +ec_scid-objs := ec_sci.o + +obj-$(CONFIG_EC_KB3310B_DEBUG) += io_msr_debugd.o + +io_msr_debugd-objs := io_msr_debug.o diff -Nur linux-2.6.30.5.orig/drivers/platform/loongson/Kconfig linux-2.6.30.5/drivers/platform/loongson/Kconfig --- linux-2.6.30.5.orig/drivers/platform/loongson/Kconfig 1970-01-01 01:00:00.000000000 +0100 +++ linux-2.6.30.5/drivers/platform/loongson/Kconfig 2009-08-23 19:01:04.000000000 +0200 @@ -0,0 +1,68 @@ +# +# Loongson Platform Specific Drivers +# + +menuconfig LOONGSON_PLATFORM_DEVICES + bool "Loongson Platform Specific Device Drivers" + default y + ---help--- + Say Y here to get to see options for device drivers for various + loongson platforms, including vendor-specific laptop extension drivers. + This option alone does not add any kernel code. + + If you say N, all options in this submenu will be skipped and disabled. + +if LOONGSON_PLATFORM_DEVICES + +config EC_KB3310B + tristate "Embedded Controller: Kb3310b support" + depends on LEMOTE_YEELOONG2F + default y + ---help--- + This is a driver for yeeloong laptops. It adds the kb3310b support: + i.e. battery management, fan & temperature mangement, sci event + management and ec rom flushing. + + This driver is orignally written by Liu junliang + and maintained by huangwei currently. + + The original git repository is: http://dev.lemote.com/code/ec_module + +config EC_KB3310B_DEBUG + tristate "Embedded Controller: Kb3310b debug support" + depends on EC_KB3310B + default n + ---help--- + This is a driver for yeeloong laptops. It adds the kb3310b debug + support. + + This driver is orignally written by Liu junliang + and maintained by huangwei currently. + + The original git repository is: http://dev.lemote.com/code/ec_module + +config PMON_FLASH + tristate "MTD map driver for flushing PMON in Linux" + depends on MTD && MTD_PARTITIONS + default y + ---help--- + This is a driver for flushing the bootloader(pmon) of + fuloong2e,fuloong2f,yeeloong2f in Linux. + + Here is a basic usage: + + 1. load necessary modules + + $ modprobe mtd + $ modprobe mtdblock + $ modprobe pmon_flashd + + 2. read the flash + + $ dd if=/dev/mtdblock0 of=pmon.bin + + 3. write the falsh + + $ dd if=pmon.bin of=/dev/mtdblock0 + +endif # LOONGSON_PLATFORM_DEVICES diff -Nur linux-2.6.30.5.orig/drivers/platform/loongson/Makefile linux-2.6.30.5/drivers/platform/loongson/Makefile --- linux-2.6.30.5.orig/drivers/platform/loongson/Makefile 1970-01-01 01:00:00.000000000 +0100 +++ linux-2.6.30.5/drivers/platform/loongson/Makefile 2009-08-23 19:01:04.000000000 +0200 @@ -0,0 +1,6 @@ +# +# loongson platform specific drivers +# + +obj-$(CONFIG_EC_KB3310B) += ec_kb3310b/ +obj-$(CONFIG_PMON_FLASH) += pmon_flash/ diff -Nur linux-2.6.30.5.orig/drivers/platform/loongson/pmon_flash/Makefile linux-2.6.30.5/drivers/platform/loongson/pmon_flash/Makefile --- linux-2.6.30.5.orig/drivers/platform/loongson/pmon_flash/Makefile 1970-01-01 01:00:00.000000000 +0100 +++ linux-2.6.30.5/drivers/platform/loongson/pmon_flash/Makefile 2009-08-23 19:01:04.000000000 +0200 @@ -0,0 +1,7 @@ +# +# MTD map driver for flushing pmon flash +# + +obj-$(CONFIG_PMON_FLASH) += pmon_flashd.o + +pmon_flashd-objs := pmon_flash.o diff -Nur linux-2.6.30.5.orig/drivers/platform/loongson/pmon_flash/pmon_flash.c linux-2.6.30.5/drivers/platform/loongson/pmon_flash/pmon_flash.c --- linux-2.6.30.5.orig/drivers/platform/loongson/pmon_flash/pmon_flash.c 1970-01-01 01:00:00.000000000 +0100 +++ linux-2.6.30.5/drivers/platform/loongson/pmon_flash/pmon_flash.c 2009-08-23 19:01:04.000000000 +0200 @@ -0,0 +1,85 @@ +/* + * Copyright www.lemote.com + * + * 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. + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#define FLASH_PHYS_ADDR 0x1fc00000 +#define FLASH_SIZE 0x080000 + +#define FLASH_PARTITION0_ADDR 0x00000000 +#define FLASH_PARTITION0_SIZE 0x00080000 + +struct map_info flash_map = { + .name = "flash device", + .size = FLASH_SIZE, + .bankwidth = 1, +}; + +struct mtd_partition flash_parts[] = { + { + .name = "Bootloader", + .offset = FLASH_PARTITION0_ADDR, + .size = FLASH_PARTITION0_SIZE}, +}; + +#define PARTITION_COUNT ARRAY_SIZE(flash_parts) + +static struct mtd_info *mymtd; + +int __init init_flash(void) +{ + printk(KERN_NOTICE "Flash flash device: %x at %x\n", + FLASH_SIZE, FLASH_PHYS_ADDR); + + flash_map.phys = FLASH_PHYS_ADDR; + flash_map.virt = ioremap(FLASH_PHYS_ADDR, FLASH_SIZE); + + if (!flash_map.virt) { + printk(KERN_NOTICE "Failed to ioremap\n"); + return -EIO; + } + + simple_map_init(&flash_map); + + mymtd = do_map_probe("cfi_probe", &flash_map); + if (mymtd) { + add_mtd_partitions(mymtd, flash_parts, PARTITION_COUNT); + printk(KERN_NOTICE "pmon flash device initialized\n"); + return 0; + } + + iounmap((void *)flash_map.virt); + return -ENXIO; +} + +static void __exit cleanup_flash(void) +{ + if (mymtd) { + del_mtd_partitions(mymtd); + map_destroy(mymtd); + } + if (flash_map.virt) { + iounmap((void *)flash_map.virt); + flash_map.virt = 0; + } +} + +module_init(init_flash); +module_exit(cleanup_flash); + +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("Yanhua"); +MODULE_DESCRIPTION("MTD map driver for pmon programming module"); diff -Nur linux-2.6.30.5.orig/drivers/platform/Makefile linux-2.6.30.5/drivers/platform/Makefile --- linux-2.6.30.5.orig/drivers/platform/Makefile 2009-08-16 23:19:38.000000000 +0200 +++ linux-2.6.30.5/drivers/platform/Makefile 2009-08-23 19:01:04.000000000 +0200 @@ -3,3 +3,4 @@ # obj-$(CONFIG_X86) += x86/ +obj-$(CONFIG_MACH_LOONGSON) += loongson/ diff -Nur linux-2.6.30.5.orig/drivers/rtc/rtc-cmos.c linux-2.6.30.5/drivers/rtc/rtc-cmos.c --- linux-2.6.30.5.orig/drivers/rtc/rtc-cmos.c 2009-08-16 23:19:38.000000000 +0200 +++ linux-2.6.30.5/drivers/rtc/rtc-cmos.c 2009-08-23 19:01:04.000000000 +0200 @@ -691,7 +691,8 @@ */ #if defined(CONFIG_ATARI) address_space = 64; -#elif defined(__i386__) || defined(__x86_64__) || defined(__arm__) || defined(__sparc__) +#elif defined(__i386__) || defined(__x86_64__) || defined(__arm__) \ + || defined(__sparc__) || defined(__mips__) address_space = 128; #else #warning Assuming 128 bytes of RTC+NVRAM address space, not 64 bytes. @@ -756,9 +757,8 @@ /* FIXME teach the alarm code how to handle binary mode; * doesn't know 12-hour mode either. */ - if (is_valid_irq(rtc_irq) && - (!(rtc_control & RTC_24H) || (rtc_control & (RTC_DM_BINARY)))) { - dev_dbg(dev, "only 24-hr BCD mode supported\n"); + if (is_valid_irq(rtc_irq) && !(rtc_control & RTC_24H)) { + dev_dbg(dev, "only 24-hr supported\n"); retval = -ENXIO; goto cleanup1; } diff -Nur linux-2.6.30.5.orig/drivers/video/Kconfig linux-2.6.30.5/drivers/video/Kconfig --- linux-2.6.30.5.orig/drivers/video/Kconfig 2009-08-16 23:19:38.000000000 +0200 +++ linux-2.6.30.5/drivers/video/Kconfig 2009-08-23 19:01:04.000000000 +0200 @@ -1930,6 +1930,28 @@ Turn on debugging messages. Note that you can set/unset at run time through sysfs +config FB_SM7XX + tristate "Silicon Motion SM7XX Frame Buffer Support" + depends on FB + select FB_CFB_FILLRECT + select FB_CFB_COPYAREA + select FB_CFB_IMAGEBLIT + help + Frame Buffer driver for the Silicon Motion SM7XX serial graphic card. + +config FB_SM7XX_ACCEL + bool "Siliconmotion Acceleration functions (EXPERIMENTAL)" + depends on FB_SM7XX && EXPERIMENTAL + help + This will compile the Trident frame buffer device with + acceleration functions. + +config FB_SM7XX_DUALHEAD + bool "Siliconmotion dualhead support (EXPERIMENTAL)" + depends on FB_SM7XX && EXPERIMENTAL + help + This will enable the dualhead support of SM7XX + config FB_SM501 tristate "Silicon Motion SM501 framebuffer support" depends on FB && MFD_SM501 diff -Nur linux-2.6.30.5.orig/drivers/video/Makefile linux-2.6.30.5/drivers/video/Makefile --- linux-2.6.30.5.orig/drivers/video/Makefile 2009-08-16 23:19:38.000000000 +0200 +++ linux-2.6.30.5/drivers/video/Makefile 2009-08-23 19:01:04.000000000 +0200 @@ -70,6 +70,7 @@ obj-$(CONFIG_FB_TCX) += tcx.o sbuslib.o obj-$(CONFIG_FB_LEO) += leo.o sbuslib.o obj-$(CONFIG_FB_SGIVW) += sgivwfb.o +obj-$(CONFIG_FB_SM7XX) += sm7xx/ obj-$(CONFIG_FB_ACORN) += acornfb.o obj-$(CONFIG_FB_ATARI) += atafb.o c2p_iplan2.o atafb_mfb.o \ atafb_iplan2p2.o atafb_iplan2p4.o atafb_iplan2p8.o diff -Nur linux-2.6.30.5.orig/drivers/video/sm7xx/Makefile linux-2.6.30.5/drivers/video/sm7xx/Makefile --- linux-2.6.30.5.orig/drivers/video/sm7xx/Makefile 1970-01-01 01:00:00.000000000 +0100 +++ linux-2.6.30.5/drivers/video/sm7xx/Makefile 2009-08-23 19:01:04.000000000 +0200 @@ -0,0 +1,3 @@ +obj-$(CONFIG_FB_SM7XX) += sm7xx.o + +sm7xx-y := smtcfb.o diff -Nur linux-2.6.30.5.orig/drivers/video/sm7xx/smtc2d.c linux-2.6.30.5/drivers/video/sm7xx/smtc2d.c --- linux-2.6.30.5.orig/drivers/video/sm7xx/smtc2d.c 1970-01-01 01:00:00.000000000 +0100 +++ linux-2.6.30.5/drivers/video/sm7xx/smtc2d.c 2009-08-23 19:01:04.000000000 +0200 @@ -0,0 +1,979 @@ +/* + * smtc2d.c -- Silicon Motion SM7xx 2D drawing engine functions. + * + * Copyright (C) 2006 Silicon Motion Technology Corp. + * Author: Boyod boyod.yang@siliconmotion.com.cn + * + * Copyright (C) 2009 Lemote, Inc. & Institute of Computing Technology + * Author: Wu Zhangjin, wuzj@lemote.com + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file COPYING in the main directory of this archive for + * more details. + * + * Version 0.10.26192.21.01 + * - Add PowerPC support + * - Add 2D support for Lynx - + * Verified on 2.6.19.2 + * Boyod.yang + */ + +unsigned char smtc_de_busy; + +void SMTC_write2Dreg(unsigned long nOffset, unsigned long nData) +{ + writel(nData, smtc_2DBaseAddress + nOffset); +} + +unsigned long SMTC_read2Dreg(unsigned long nOffset) +{ + return readl(smtc_2DBaseAddress + nOffset); +} + +void SMTC_write2Ddataport(unsigned long nOffset, unsigned long nData) +{ + writel(nData, smtc_2Ddataport + nOffset); +} + +/********************************************************************** + * + * deInit + * + * Purpose + * Drawing engine initialization. + * + **********************************************************************/ + +void deInit(unsigned int nModeWidth, unsigned int nModeHeight, + unsigned int bpp) +{ + /* Get current power configuration. */ + unsigned char clock; + clock = smtc_seqr(0x21); + + /* initialize global 'mutex lock' variable */ + smtc_de_busy = 0; + + /* Enable 2D Drawing Engine */ + smtc_seqw(0x21, clock & 0xF8); + + SMTC_write2Dreg(DE_CLIP_TL, + FIELD_VALUE(0, DE_CLIP_TL, TOP, 0) | + FIELD_SET(0, DE_CLIP_TL, STATUS, DISABLE) | + FIELD_SET(0, DE_CLIP_TL, INHIBIT, OUTSIDE) | + FIELD_VALUE(0, DE_CLIP_TL, LEFT, 0)); + + if (bpp >= 24) { + SMTC_write2Dreg(DE_PITCH, + FIELD_VALUE(0, DE_PITCH, DESTINATION, + nModeWidth * 3) | FIELD_VALUE(0, + DE_PITCH, + SOURCE, + nModeWidth + * 3)); + } else { + SMTC_write2Dreg(DE_PITCH, + FIELD_VALUE(0, DE_PITCH, DESTINATION, + nModeWidth) | FIELD_VALUE(0, + DE_PITCH, + SOURCE, + nModeWidth)); + } + + SMTC_write2Dreg(DE_WINDOW_WIDTH, + FIELD_VALUE(0, DE_WINDOW_WIDTH, DESTINATION, + nModeWidth) | FIELD_VALUE(0, + DE_WINDOW_WIDTH, + SOURCE, + nModeWidth)); + + switch (bpp) { + case 8: + SMTC_write2Dreg(DE_STRETCH_FORMAT, + FIELD_SET(0, DE_STRETCH_FORMAT, PATTERN_XY, + NORMAL) | FIELD_VALUE(0, + DE_STRETCH_FORMAT, + PATTERN_Y, + 0) | + FIELD_VALUE(0, DE_STRETCH_FORMAT, PATTERN_X, + 0) | FIELD_SET(0, DE_STRETCH_FORMAT, + PIXEL_FORMAT, + 8) | FIELD_SET(0, + DE_STRETCH_FORMAT, + ADDRESSING, + XY) | + FIELD_VALUE(0, DE_STRETCH_FORMAT, + SOURCE_HEIGHT, 3)); + break; + case 24: + SMTC_write2Dreg(DE_STRETCH_FORMAT, + FIELD_SET(0, DE_STRETCH_FORMAT, PATTERN_XY, + NORMAL) | FIELD_VALUE(0, + DE_STRETCH_FORMAT, + PATTERN_Y, + 0) | + FIELD_VALUE(0, DE_STRETCH_FORMAT, PATTERN_X, + 0) | FIELD_SET(0, DE_STRETCH_FORMAT, + PIXEL_FORMAT, + 24) | FIELD_SET(0, + DE_STRETCH_FORMAT, + ADDRESSING, + XY) | + FIELD_VALUE(0, DE_STRETCH_FORMAT, + SOURCE_HEIGHT, 3)); + break; + case 16: + default: + SMTC_write2Dreg(DE_STRETCH_FORMAT, + FIELD_SET(0, DE_STRETCH_FORMAT, PATTERN_XY, + NORMAL) | FIELD_VALUE(0, + DE_STRETCH_FORMAT, + PATTERN_Y, + 0) | + FIELD_VALUE(0, DE_STRETCH_FORMAT, PATTERN_X, + 0) | FIELD_SET(0, DE_STRETCH_FORMAT, + PIXEL_FORMAT, + 16) | FIELD_SET(0, + DE_STRETCH_FORMAT, + ADDRESSING, + XY) | + FIELD_VALUE(0, DE_STRETCH_FORMAT, + SOURCE_HEIGHT, 3)); + break; + } + + SMTC_write2Dreg(DE_MASKS, + FIELD_VALUE(0, DE_MASKS, BYTE_MASK, 0xFFFF) | + FIELD_VALUE(0, DE_MASKS, BIT_MASK, 0xFFFF)); + SMTC_write2Dreg(DE_COLOR_COMPARE_MASK, + FIELD_VALUE(0, DE_COLOR_COMPARE_MASK, MASKS, \ + 0xFFFFFF)); + SMTC_write2Dreg(DE_COLOR_COMPARE, + FIELD_VALUE(0, DE_COLOR_COMPARE, COLOR, 0xFFFFFF)); +} + +void deVerticalLine(unsigned long dst_base, + unsigned long dst_pitch, + unsigned long nX, + unsigned long nY, + unsigned long dst_height, unsigned long nColor) +{ + deWaitForNotBusy(); + + SMTC_write2Dreg(DE_WINDOW_DESTINATION_BASE, + FIELD_VALUE(0, DE_WINDOW_DESTINATION_BASE, ADDRESS, + dst_base)); + + SMTC_write2Dreg(DE_PITCH, + FIELD_VALUE(0, DE_PITCH, DESTINATION, dst_pitch) | + FIELD_VALUE(0, DE_PITCH, SOURCE, dst_pitch)); + + SMTC_write2Dreg(DE_WINDOW_WIDTH, + FIELD_VALUE(0, DE_WINDOW_WIDTH, DESTINATION, + dst_pitch) | FIELD_VALUE(0, DE_WINDOW_WIDTH, + SOURCE, + dst_pitch)); + + SMTC_write2Dreg(DE_FOREGROUND, + FIELD_VALUE(0, DE_FOREGROUND, COLOR, nColor)); + + SMTC_write2Dreg(DE_DESTINATION, + FIELD_SET(0, DE_DESTINATION, WRAP, DISABLE) | + FIELD_VALUE(0, DE_DESTINATION, X, nX) | + FIELD_VALUE(0, DE_DESTINATION, Y, nY)); + + SMTC_write2Dreg(DE_DIMENSION, + FIELD_VALUE(0, DE_DIMENSION, X, 1) | + FIELD_VALUE(0, DE_DIMENSION, Y_ET, dst_height)); + + SMTC_write2Dreg(DE_CONTROL, + FIELD_SET(0, DE_CONTROL, STATUS, START) | + FIELD_SET(0, DE_CONTROL, DIRECTION, LEFT_TO_RIGHT) | + FIELD_SET(0, DE_CONTROL, MAJOR, Y) | + FIELD_SET(0, DE_CONTROL, STEP_X, NEGATIVE) | + FIELD_SET(0, DE_CONTROL, STEP_Y, POSITIVE) | + FIELD_SET(0, DE_CONTROL, LAST_PIXEL, OFF) | + FIELD_SET(0, DE_CONTROL, COMMAND, SHORT_STROKE) | + FIELD_SET(0, DE_CONTROL, ROP_SELECT, ROP2) | + FIELD_VALUE(0, DE_CONTROL, ROP, 0x0C)); + + smtc_de_busy = 1; +} + +void deHorizontalLine(unsigned long dst_base, + unsigned long dst_pitch, + unsigned long nX, + unsigned long nY, + unsigned long dst_width, unsigned long nColor) +{ + deWaitForNotBusy(); + + SMTC_write2Dreg(DE_WINDOW_DESTINATION_BASE, + FIELD_VALUE(0, DE_WINDOW_DESTINATION_BASE, ADDRESS, + dst_base)); + + SMTC_write2Dreg(DE_PITCH, + FIELD_VALUE(0, DE_PITCH, DESTINATION, dst_pitch) | + FIELD_VALUE(0, DE_PITCH, SOURCE, dst_pitch)); + + SMTC_write2Dreg(DE_WINDOW_WIDTH, + FIELD_VALUE(0, DE_WINDOW_WIDTH, DESTINATION, + dst_pitch) | FIELD_VALUE(0, DE_WINDOW_WIDTH, + SOURCE, + dst_pitch)); + SMTC_write2Dreg(DE_FOREGROUND, + FIELD_VALUE(0, DE_FOREGROUND, COLOR, nColor)); + SMTC_write2Dreg(DE_DESTINATION, + FIELD_SET(0, DE_DESTINATION, WRAP, + DISABLE) | FIELD_VALUE(0, DE_DESTINATION, X, + nX) | FIELD_VALUE(0, + DE_DESTINATION, + Y, + nY)); + SMTC_write2Dreg(DE_DIMENSION, + FIELD_VALUE(0, DE_DIMENSION, X, + dst_width) | FIELD_VALUE(0, DE_DIMENSION, + Y_ET, 1)); + SMTC_write2Dreg(DE_CONTROL, + FIELD_SET(0, DE_CONTROL, STATUS, START) | FIELD_SET(0, + DE_CONTROL, + DIRECTION, + RIGHT_TO_LEFT) + | FIELD_SET(0, DE_CONTROL, MAJOR, X) | FIELD_SET(0, + DE_CONTROL, + STEP_X, + POSITIVE) + | FIELD_SET(0, DE_CONTROL, STEP_Y, + NEGATIVE) | FIELD_SET(0, DE_CONTROL, + LAST_PIXEL, + OFF) | FIELD_SET(0, + DE_CONTROL, + COMMAND, + SHORT_STROKE) + | FIELD_SET(0, DE_CONTROL, ROP_SELECT, + ROP2) | FIELD_VALUE(0, DE_CONTROL, ROP, + 0x0C)); + + smtc_de_busy = 1; +} + +void deLine(unsigned long dst_base, + unsigned long dst_pitch, + unsigned long nX1, + unsigned long nY1, + unsigned long nX2, unsigned long nY2, unsigned long nColor) +{ + unsigned long nCommand = + FIELD_SET(0, DE_CONTROL, STATUS, START) | + FIELD_SET(0, DE_CONTROL, DIRECTION, LEFT_TO_RIGHT) | + FIELD_SET(0, DE_CONTROL, MAJOR, X) | + FIELD_SET(0, DE_CONTROL, STEP_X, POSITIVE) | + FIELD_SET(0, DE_CONTROL, STEP_Y, POSITIVE) | + FIELD_SET(0, DE_CONTROL, LAST_PIXEL, OFF) | + FIELD_SET(0, DE_CONTROL, ROP_SELECT, ROP2) | + FIELD_VALUE(0, DE_CONTROL, ROP, 0x0C); + unsigned long DeltaX; + unsigned long DeltaY; + + /* Calculate delta X */ + if (nX1 <= nX2) + DeltaX = nX2 - nX1; + else { + DeltaX = nX1 - nX2; + nCommand = FIELD_SET(nCommand, DE_CONTROL, STEP_X, NEGATIVE); + } + + /* Calculate delta Y */ + if (nY1 <= nY2) + DeltaY = nY2 - nY1; + else { + DeltaY = nY1 - nY2; + nCommand = FIELD_SET(nCommand, DE_CONTROL, STEP_Y, NEGATIVE); + } + + /* Determine the major axis */ + if (DeltaX < DeltaY) + nCommand = FIELD_SET(nCommand, DE_CONTROL, MAJOR, Y); + + /* Vertical line? */ + if (nX1 == nX2) + deVerticalLine(dst_base, dst_pitch, nX1, nY1, DeltaY, nColor); + + /* Horizontal line? */ + else if (nY1 == nY2) + deHorizontalLine(dst_base, dst_pitch, nX1, nY1, \ + DeltaX, nColor); + + /* Diagonal line? */ + else if (DeltaX == DeltaY) { + deWaitForNotBusy(); + + SMTC_write2Dreg(DE_WINDOW_DESTINATION_BASE, + FIELD_VALUE(0, DE_WINDOW_DESTINATION_BASE, + ADDRESS, dst_base)); + + SMTC_write2Dreg(DE_PITCH, + FIELD_VALUE(0, DE_PITCH, DESTINATION, + dst_pitch) | FIELD_VALUE(0, + DE_PITCH, + SOURCE, + dst_pitch)); + + SMTC_write2Dreg(DE_WINDOW_WIDTH, + FIELD_VALUE(0, DE_WINDOW_WIDTH, DESTINATION, + dst_pitch) | FIELD_VALUE(0, + DE_WINDOW_WIDTH, + SOURCE, + dst_pitch)); + + SMTC_write2Dreg(DE_FOREGROUND, + FIELD_VALUE(0, DE_FOREGROUND, COLOR, nColor)); + + SMTC_write2Dreg(DE_DESTINATION, + FIELD_SET(0, DE_DESTINATION, WRAP, DISABLE) | + FIELD_VALUE(0, DE_DESTINATION, X, 1) | + FIELD_VALUE(0, DE_DESTINATION, Y, nY1)); + + SMTC_write2Dreg(DE_DIMENSION, + FIELD_VALUE(0, DE_DIMENSION, X, 1) | + FIELD_VALUE(0, DE_DIMENSION, Y_ET, DeltaX)); + + SMTC_write2Dreg(DE_CONTROL, + FIELD_SET(nCommand, DE_CONTROL, COMMAND, + SHORT_STROKE)); + } + + /* Generic line */ + else { + unsigned int k1, k2, et, w; + if (DeltaX < DeltaY) { + k1 = 2 * DeltaX; + et = k1 - DeltaY; + k2 = et - DeltaY; + w = DeltaY + 1; + } else { + k1 = 2 * DeltaY; + et = k1 - DeltaX; + k2 = et - DeltaX; + w = DeltaX + 1; + } + + deWaitForNotBusy(); + + SMTC_write2Dreg(DE_WINDOW_DESTINATION_BASE, + FIELD_VALUE(0, DE_WINDOW_DESTINATION_BASE, + ADDRESS, dst_base)); + + SMTC_write2Dreg(DE_PITCH, + FIELD_VALUE(0, DE_PITCH, DESTINATION, + dst_pitch) | FIELD_VALUE(0, + DE_PITCH, + SOURCE, + dst_pitch)); + + SMTC_write2Dreg(DE_WINDOW_WIDTH, + FIELD_VALUE(0, DE_WINDOW_WIDTH, DESTINATION, + dst_pitch) | FIELD_VALUE(0, + DE_WINDOW_WIDTH, + SOURCE, + dst_pitch)); + + SMTC_write2Dreg(DE_FOREGROUND, + FIELD_VALUE(0, DE_FOREGROUND, COLOR, nColor)); + + SMTC_write2Dreg(DE_SOURCE, + FIELD_SET(0, DE_SOURCE, WRAP, DISABLE) | + FIELD_VALUE(0, DE_SOURCE, X_K1, k1) | + FIELD_VALUE(0, DE_SOURCE, Y_K2, k2)); + + SMTC_write2Dreg(DE_DESTINATION, + FIELD_SET(0, DE_DESTINATION, WRAP, DISABLE) | + FIELD_VALUE(0, DE_DESTINATION, X, nX1) | + FIELD_VALUE(0, DE_DESTINATION, Y, nY1)); + + SMTC_write2Dreg(DE_DIMENSION, + FIELD_VALUE(0, DE_DIMENSION, X, w) | + FIELD_VALUE(0, DE_DIMENSION, Y_ET, et)); + + SMTC_write2Dreg(DE_CONTROL, + FIELD_SET(nCommand, DE_CONTROL, COMMAND, + LINE_DRAW)); + } + + smtc_de_busy = 1; +} + +void deFillRect(unsigned long dst_base, + unsigned long dst_pitch, + unsigned long dst_X, + unsigned long dst_Y, + unsigned long dst_width, + unsigned long dst_height, unsigned long nColor) +{ + deWaitForNotBusy(); + + SMTC_write2Dreg(DE_WINDOW_DESTINATION_BASE, + FIELD_VALUE(0, DE_WINDOW_DESTINATION_BASE, ADDRESS, + dst_base)); + + if (dst_pitch) { + SMTC_write2Dreg(DE_PITCH, + FIELD_VALUE(0, DE_PITCH, DESTINATION, + dst_pitch) | FIELD_VALUE(0, + DE_PITCH, + SOURCE, + dst_pitch)); + + SMTC_write2Dreg(DE_WINDOW_WIDTH, + FIELD_VALUE(0, DE_WINDOW_WIDTH, DESTINATION, + dst_pitch) | FIELD_VALUE(0, + DE_WINDOW_WIDTH, + SOURCE, + dst_pitch)); + } + + SMTC_write2Dreg(DE_FOREGROUND, + FIELD_VALUE(0, DE_FOREGROUND, COLOR, nColor)); + + SMTC_write2Dreg(DE_DESTINATION, + FIELD_SET(0, DE_DESTINATION, WRAP, DISABLE) | + FIELD_VALUE(0, DE_DESTINATION, X, dst_X) | + FIELD_VALUE(0, DE_DESTINATION, Y, dst_Y)); + + SMTC_write2Dreg(DE_DIMENSION, + FIELD_VALUE(0, DE_DIMENSION, X, dst_width) | + FIELD_VALUE(0, DE_DIMENSION, Y_ET, dst_height)); + + SMTC_write2Dreg(DE_CONTROL, + FIELD_SET(0, DE_CONTROL, STATUS, START) | + FIELD_SET(0, DE_CONTROL, DIRECTION, LEFT_TO_RIGHT) | + FIELD_SET(0, DE_CONTROL, LAST_PIXEL, OFF) | + FIELD_SET(0, DE_CONTROL, COMMAND, RECTANGLE_FILL) | + FIELD_SET(0, DE_CONTROL, ROP_SELECT, ROP2) | + FIELD_VALUE(0, DE_CONTROL, ROP, 0x0C)); + + smtc_de_busy = 1; +} + +/********************************************************************** + * + * deRotatePattern + * + * Purpose + * Rotate the given pattern if necessary + * + * Parameters + * [in] + * pPattern - Pointer to DE_SURFACE structure containing + * pattern attributes + * patternX - X position (0-7) of pattern origin + * patternY - Y position (0-7) of pattern origin + * + * [out] + * pattern_dstaddr - Pointer to pre-allocated buffer containing + * rotated pattern + * + **********************************************************************/ +void deRotatePattern(unsigned char *pattern_dstaddr, + unsigned long pattern_src_addr, + unsigned long pattern_BPP, + unsigned long pattern_stride, int patternX, int patternY) +{ + unsigned int i; + unsigned long pattern[PATTERN_WIDTH * PATTERN_HEIGHT]; + unsigned int x, y; + unsigned char *pjPatByte; + + if (pattern_dstaddr != NULL) { + deWaitForNotBusy(); + + if (patternX || patternY) { + /* Rotate pattern */ + pjPatByte = (unsigned char *)pattern; + + switch (pattern_BPP) { + case 8: + { + for (y = 0; y < 8; y++) { + unsigned char *pjBuffer = + pattern_dstaddr + + ((patternY + y) & 7) * 8; + for (x = 0; x < 8; x++) { + pjBuffer[(patternX + + x) & 7] = + pjPatByte[x]; + } + pjPatByte += pattern_stride; + } + break; + } + + case 16: + { + for (y = 0; y < 8; y++) { + unsigned short *pjBuffer = + (unsigned short *) + pattern_dstaddr + + ((patternY + y) & 7) * 8; + for (x = 0; x < 8; x++) { + pjBuffer[(patternX + + x) & 7] = + ((unsigned short *) + pjPatByte)[x]; + } + pjPatByte += pattern_stride; + } + break; + } + + case 32: + { + for (y = 0; y < 8; y++) { + unsigned long *pjBuffer = + (unsigned long *) + pattern_dstaddr + + ((patternY + y) & 7) * 8; + for (x = 0; x < 8; x++) { + pjBuffer[(patternX + + x) & 7] = + ((unsigned long *) + pjPatByte)[x]; + } + pjPatByte += pattern_stride; + } + break; + } + } + } else { + /*Don't rotate,just copy pattern into pattern_dstaddr*/ + for (i = 0; i < (pattern_BPP * 2); i++) { + ((unsigned long *)pattern_dstaddr)[i] = + pattern[i]; + } + } + + } +} + +/********************************************************************** + * + * deCopy + * + * Purpose + * Copy a rectangular area of the source surface to a destination surface + * + * Remarks + * Source bitmap must have the same color depth (BPP) as the destination + * bitmap. + * +**********************************************************************/ +void deCopy(unsigned long dst_base, + unsigned long dst_pitch, + unsigned long dst_BPP, + unsigned long dst_X, + unsigned long dst_Y, + unsigned long dst_width, + unsigned long dst_height, + unsigned long src_base, + unsigned long src_pitch, + unsigned long src_X, + unsigned long src_Y, pTransparent pTransp, unsigned char nROP2) +{ + unsigned long nDirection = 0; + unsigned long nTransparent = 0; + /* Direction of ROP2 operation: + * 1 = Left to Right, + * (-1) = Right to Left + */ + unsigned long opSign = 1; + /* xWidth is in pixels */ + unsigned long xWidth = 192 / (dst_BPP / 8); + unsigned long de_ctrl = 0; + + deWaitForNotBusy(); + + SMTC_write2Dreg(DE_WINDOW_DESTINATION_BASE, + FIELD_VALUE(0, DE_WINDOW_DESTINATION_BASE, ADDRESS, + dst_base)); + + SMTC_write2Dreg(DE_WINDOW_SOURCE_BASE, + FIELD_VALUE(0, DE_WINDOW_SOURCE_BASE, ADDRESS, + src_base)); + + if (dst_pitch && src_pitch) { + SMTC_write2Dreg(DE_PITCH, + FIELD_VALUE(0, DE_PITCH, DESTINATION, + dst_pitch) | FIELD_VALUE(0, + DE_PITCH, + SOURCE, + src_pitch)); + + SMTC_write2Dreg(DE_WINDOW_WIDTH, + FIELD_VALUE(0, DE_WINDOW_WIDTH, DESTINATION, + dst_pitch) | FIELD_VALUE(0, + DE_WINDOW_WIDTH, + SOURCE, + src_pitch)); + } + + /* Set transparent bits if necessary */ + if (pTransp != NULL) { + nTransparent = + pTransp->match | pTransp->select | pTransp->control; + + /* Set color compare register */ + SMTC_write2Dreg(DE_COLOR_COMPARE, + FIELD_VALUE(0, DE_COLOR_COMPARE, COLOR, + pTransp->color)); + } + + /* Determine direction of operation */ + if (src_Y < dst_Y) { + /* +----------+ + |S | + | +----------+ + | | | | + | | | | + +---|------+ | + | D | + +----------+ */ + + nDirection = BOTTOM_TO_TOP; + } else if (src_Y > dst_Y) { + /* +----------+ + |D | + | +----------+ + | | | | + | | | | + +---|------+ | + | S | + +----------+ */ + + nDirection = TOP_TO_BOTTOM; + } else { + /* src_Y == dst_Y */ + + if (src_X <= dst_X) { + /* +------+---+------+ + |S | | D| + | | | | + | | | | + | | | | + +------+---+------+ */ + + nDirection = RIGHT_TO_LEFT; + } else { + /* src_X > dst_X */ + + /* +------+---+------+ + |D | | S| + | | | | + | | | | + | | | | + +------+---+------+ */ + + nDirection = LEFT_TO_RIGHT; + } + } + + if ((nDirection == BOTTOM_TO_TOP) || (nDirection == RIGHT_TO_LEFT)) { + src_X += dst_width - 1; + src_Y += dst_height - 1; + dst_X += dst_width - 1; + dst_Y += dst_height - 1; + opSign = (-1); + } + + if (dst_BPP >= 24) { + src_X *= 3; + src_Y *= 3; + dst_X *= 3; + dst_Y *= 3; + dst_width *= 3; + if ((nDirection == BOTTOM_TO_TOP) + || (nDirection == RIGHT_TO_LEFT)) { + src_X += 2; + dst_X += 2; + } + } + + /* Workaround for 192 byte hw bug */ + if ((nROP2 != 0x0C) && ((dst_width * (dst_BPP / 8)) >= 192)) { + /* + * Perform the ROP2 operation in chunks of (xWidth * + * dst_height) + */ + while (1) { + deWaitForNotBusy(); + + SMTC_write2Dreg(DE_SOURCE, + FIELD_SET(0, DE_SOURCE, WRAP, DISABLE) | + FIELD_VALUE(0, DE_SOURCE, X_K1, src_X) | + FIELD_VALUE(0, DE_SOURCE, Y_K2, src_Y)); + + SMTC_write2Dreg(DE_DESTINATION, + FIELD_SET(0, DE_DESTINATION, WRAP, + DISABLE) | FIELD_VALUE(0, + DE_DESTINATION, + X, + dst_X) + | FIELD_VALUE(0, DE_DESTINATION, Y, + dst_Y)); + + SMTC_write2Dreg(DE_DIMENSION, + FIELD_VALUE(0, DE_DIMENSION, X, + xWidth) | FIELD_VALUE(0, + DE_DIMENSION, + Y_ET, + dst_height)); + + de_ctrl = + FIELD_VALUE(0, DE_CONTROL, ROP, + nROP2) | nTransparent | FIELD_SET(0, + DE_CONTROL, + ROP_SELECT, + ROP2) + | FIELD_SET(0, DE_CONTROL, COMMAND, + BITBLT) | ((nDirection == + 1) ? FIELD_SET(0, + DE_CONTROL, + DIRECTION, + RIGHT_TO_LEFT) + : FIELD_SET(0, DE_CONTROL, + DIRECTION, + LEFT_TO_RIGHT)) | + FIELD_SET(0, DE_CONTROL, STATUS, START); + + SMTC_write2Dreg(DE_CONTROL, de_ctrl); + + src_X += (opSign * xWidth); + dst_X += (opSign * xWidth); + dst_width -= xWidth; + + if (dst_width <= 0) { + /* ROP2 operation is complete */ + break; + } + + if (xWidth > dst_width) + xWidth = dst_width; + } + } else { + deWaitForNotBusy(); + SMTC_write2Dreg(DE_SOURCE, + FIELD_SET(0, DE_SOURCE, WRAP, DISABLE) | + FIELD_VALUE(0, DE_SOURCE, X_K1, src_X) | + FIELD_VALUE(0, DE_SOURCE, Y_K2, src_Y)); + + SMTC_write2Dreg(DE_DESTINATION, + FIELD_SET(0, DE_DESTINATION, WRAP, DISABLE) | + FIELD_VALUE(0, DE_DESTINATION, X, dst_X) | + FIELD_VALUE(0, DE_DESTINATION, Y, dst_Y)); + + SMTC_write2Dreg(DE_DIMENSION, + FIELD_VALUE(0, DE_DIMENSION, X, dst_width) | + FIELD_VALUE(0, DE_DIMENSION, Y_ET, dst_height)); + + de_ctrl = FIELD_VALUE(0, DE_CONTROL, ROP, nROP2) | + nTransparent | + FIELD_SET(0, DE_CONTROL, ROP_SELECT, ROP2) | + FIELD_SET(0, DE_CONTROL, COMMAND, BITBLT) | + ((nDirection == 1) ? FIELD_SET(0, DE_CONTROL, DIRECTION, + RIGHT_TO_LEFT) + : FIELD_SET(0, DE_CONTROL, DIRECTION, + LEFT_TO_RIGHT)) | FIELD_SET(0, DE_CONTROL, + STATUS, START); + SMTC_write2Dreg(DE_CONTROL, de_ctrl); + } + + smtc_de_busy = 1; +} + +/* + * This function sets the pixel format that will apply to the 2D Engine. + */ +void deSetPixelFormat(unsigned long bpp) +{ + unsigned long de_format; + + de_format = SMTC_read2Dreg(DE_STRETCH_FORMAT); + + switch (bpp) { + case 8: + de_format = + FIELD_SET(de_format, DE_STRETCH_FORMAT, PIXEL_FORMAT, 8); + break; + default: + case 16: + de_format = + FIELD_SET(de_format, DE_STRETCH_FORMAT, PIXEL_FORMAT, 16); + break; + case 32: + de_format = + FIELD_SET(de_format, DE_STRETCH_FORMAT, PIXEL_FORMAT, 32); + break; + } + + SMTC_write2Dreg(DE_STRETCH_FORMAT, de_format); +} + +/* + * System memory to Video memory monochrome expansion. + * + * Source is monochrome image in system memory. This function expands the + * monochrome data to color image in video memory. + */ + +long deSystemMem2VideoMemMonoBlt(const char *pSrcbuf, + long srcDelta, + unsigned long startBit, + unsigned long dBase, + unsigned long dPitch, + unsigned long bpp, + unsigned long dx, unsigned long dy, + unsigned long width, unsigned long height, + unsigned long fColor, + unsigned long bColor, + unsigned long rop2) { + unsigned long bytePerPixel; + unsigned long ulBytesPerScan; + unsigned long ul4BytesPerScan; + unsigned long ulBytesRemain; + unsigned long de_ctrl = 0; + unsigned char ajRemain[4]; + long i, j; + + bytePerPixel = bpp / 8; + + /* Just make sure the start bit is within legal range */ + startBit &= 7; + + ulBytesPerScan = (width + startBit + 7) / 8; + ul4BytesPerScan = ulBytesPerScan & ~3; + ulBytesRemain = ulBytesPerScan & 3; + + if (smtc_de_busy) + deWaitForNotBusy(); + + /* + * 2D Source Base. Use 0 for HOST Blt. + */ + + SMTC_write2Dreg(DE_WINDOW_SOURCE_BASE, 0); + + /* + * 2D Destination Base. + * + * It is an address offset (128 bit aligned) from the beginning of + * frame buffer. + */ + + SMTC_write2Dreg(DE_WINDOW_DESTINATION_BASE, dBase); + + if (dPitch) { + + /* + * Program pitch (distance between the 1st points of two + * adjacent lines). + * + * Note that input pitch is BYTE value, but the 2D Pitch + * register uses pixel values. Need Byte to pixel convertion. + */ + + SMTC_write2Dreg(DE_PITCH, + FIELD_VALUE(0, DE_PITCH, DESTINATION, + dPitch / + bytePerPixel) | FIELD_VALUE(0, + DE_PITCH, + SOURCE, + dPitch / + bytePerPixel)); + + /* Screen Window width in Pixels. + * + * 2D engine uses this value to calculate the linear address in + * frame buffer for a given point. + */ + + SMTC_write2Dreg(DE_WINDOW_WIDTH, + FIELD_VALUE(0, DE_WINDOW_WIDTH, DESTINATION, + (dPitch / + bytePerPixel)) | FIELD_VALUE(0, + DE_WINDOW_WIDTH, + SOURCE, + (dPitch + / + bytePerPixel))); + } + /* Note: For 2D Source in Host Write, only X_K1 field is needed, and + * Y_K2 field is not used. For mono bitmap, use startBit for X_K1. + */ + + SMTC_write2Dreg(DE_SOURCE, + FIELD_SET(0, DE_SOURCE, WRAP, DISABLE) | + FIELD_VALUE(0, DE_SOURCE, X_K1, startBit) | + FIELD_VALUE(0, DE_SOURCE, Y_K2, 0)); + + SMTC_write2Dreg(DE_DESTINATION, + FIELD_SET(0, DE_DESTINATION, WRAP, DISABLE) | + FIELD_VALUE(0, DE_DESTINATION, X, dx) | + FIELD_VALUE(0, DE_DESTINATION, Y, dy)); + + SMTC_write2Dreg(DE_DIMENSION, + FIELD_VALUE(0, DE_DIMENSION, X, width) | + FIELD_VALUE(0, DE_DIMENSION, Y_ET, height)); + + SMTC_write2Dreg(DE_FOREGROUND, fColor); + SMTC_write2Dreg(DE_BACKGROUND, bColor); + + if (bpp) + deSetPixelFormat(bpp); + /* Set the pixel format of the destination */ + + de_ctrl = FIELD_VALUE(0, DE_CONTROL, ROP, rop2) | + FIELD_SET(0, DE_CONTROL, ROP_SELECT, ROP2) | + FIELD_SET(0, DE_CONTROL, COMMAND, HOST_WRITE) | + FIELD_SET(0, DE_CONTROL, HOST, MONO) | + FIELD_SET(0, DE_CONTROL, STATUS, START); + + SMTC_write2Dreg(DE_CONTROL, de_ctrl | deGetTransparency()); + + /* Write MONO data (line by line) to 2D Engine data port */ + for (i = 0; i < height; i++) { + /* For each line, send the data in chunks of 4 bytes */ + for (j = 0; j < (ul4BytesPerScan / 4); j++) + SMTC_write2Ddataport(0, + *(unsigned long *)(pSrcbuf + + (j * 4))); + + if (ulBytesRemain) { + memcpy(ajRemain, pSrcbuf + ul4BytesPerScan, + ulBytesRemain); + SMTC_write2Ddataport(0, *(unsigned long *)ajRemain); + } + + pSrcbuf += srcDelta; + } + smtc_de_busy = 1; + + return 0; +} + +/* + * This function gets the transparency status from DE_CONTROL register. + * It returns a double word with the transparent fields properly set, + * while other fields are 0. + */ +unsigned long deGetTransparency(void) +{ + unsigned long de_ctrl; + + de_ctrl = SMTC_read2Dreg(DE_CONTROL); + + de_ctrl &= + FIELD_MASK(DE_CONTROL_TRANSPARENCY_MATCH) | + FIELD_MASK(DE_CONTROL_TRANSPARENCY_SELECT) | + FIELD_MASK(DE_CONTROL_TRANSPARENCY); + + return de_ctrl; +} diff -Nur linux-2.6.30.5.orig/drivers/video/sm7xx/smtc2d.h linux-2.6.30.5/drivers/video/sm7xx/smtc2d.h --- linux-2.6.30.5.orig/drivers/video/sm7xx/smtc2d.h 1970-01-01 01:00:00.000000000 +0100 +++ linux-2.6.30.5/drivers/video/sm7xx/smtc2d.h 2009-08-23 19:01:04.000000000 +0200 @@ -0,0 +1,530 @@ +/* + * smtc2d.h -- Silicon Motion SM7xx 2D drawing engine functions. + * + * Copyright (C) 2006 Silicon Motion Technology Corp. + * Author: Ge Wang, gewang@siliconmotion.com + * + * Copyright (C) 2009 Lemote, Inc. & Institute of Computing Technology + * Author: Wu Zhangjin, wuzj@lemote.com + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file COPYING in the main directory of this archive for + * more details. + */ + +#ifndef NULL +#define NULL 0 +#endif + +/* Internal macros */ + +#define _F_START(f) (0 ? f) +#define _F_END(f) (1 ? f) +#define _F_SIZE(f) (1 + _F_END(f) - _F_START(f)) +#define _F_MASK(f) (((1ULL << _F_SIZE(f)) - 1) << _F_START(f)) +#define _F_NORMALIZE(v, f) (((v) & _F_MASK(f)) >> _F_START(f)) +#define _F_DENORMALIZE(v, f) (((v) << _F_START(f)) & _F_MASK(f)) + +/* Global macros */ + +#define FIELD_GET(x, reg, field) \ +( \ + _F_NORMALIZE((x), reg ## _ ## field) \ +) + +#define FIELD_SET(x, reg, field, value) \ +( \ + (x & ~_F_MASK(reg ## _ ## field)) \ + | _F_DENORMALIZE(reg ## _ ## field ## _ ## value, reg ## _ ## field) \ +) + +#define FIELD_VALUE(x, reg, field, value) \ +( \ + (x & ~_F_MASK(reg ## _ ## field)) \ + | _F_DENORMALIZE(value, reg ## _ ## field) \ +) + +#define FIELD_CLEAR(reg, field) \ +( \ + ~_F_MASK(reg ## _ ## field) \ +) + +/* Field Macros */ + +#define FIELD_START(field) (0 ? field) +#define FIELD_END(field) (1 ? field) +#define FIELD_SIZE(field) \ + (1 + FIELD_END(field) - FIELD_START(field)) + +#define FIELD_MASK(field) \ + (((1 << (FIELD_SIZE(field)-1)) \ + | ((1 << (FIELD_SIZE(field)-1)) - 1)) \ + << FIELD_START(field)) + +#define FIELD_NORMALIZE(reg, field) \ + (((reg) & FIELD_MASK(field)) >> FIELD_START(field)) + +#define FIELD_DENORMALIZE(field, value) \ + (((value) << FIELD_START(field)) & FIELD_MASK(field)) + +#define FIELD_INIT(reg, field, value) \ + FIELD_DENORMALIZE(reg ## _ ## field, \ + reg ## _ ## field ## _ ## value) + +#define FIELD_INIT_VAL(reg, field, value) \ + (FIELD_DENORMALIZE(reg ## _ ## field, value)) + +#define FIELD_VAL_SET(x, r, f, v) ({ \ + x = (x & ~FIELD_MASK(r ## _ ## f)) \ + | FIELD_DENORMALIZE(r ## _ ## f, r ## _ ## f ## _ ## v) \ +}) + +#define RGB(r, g, b) ((unsigned long)(((r) << 16) | ((g) << 8) | (b))) + +/* Transparent info definition */ +typedef struct { + unsigned long match; /* Matching pixel is OPAQUE/TRANSPARENT */ + unsigned long select; /* Transparency controlled by SRC/DST */ + unsigned long control; /* ENABLE/DISABLE transparency */ + unsigned long color; /* Transparent color */ +} Transparent, *pTransparent; + +#define PIXEL_DEPTH_1_BP 0 /* 1 bit per pixel */ +#define PIXEL_DEPTH_8_BPP 1 /* 8 bits per pixel */ +#define PIXEL_DEPTH_16_BPP 2 /* 16 bits per pixel */ +#define PIXEL_DEPTH_32_BPP 3 /* 32 bits per pixel */ +#define PIXEL_DEPTH_YUV422 8 /* 16 bits per pixel YUV422 */ +#define PIXEL_DEPTH_YUV420 9 /* 16 bits per pixel YUV420 */ + +#define PATTERN_WIDTH 8 +#define PATTERN_HEIGHT 8 + +#define TOP_TO_BOTTOM 0 +#define BOTTOM_TO_TOP 1 +#define RIGHT_TO_LEFT BOTTOM_TO_TOP +#define LEFT_TO_RIGHT TOP_TO_BOTTOM + +/* Constants used in Transparent structure */ +#define MATCH_OPAQUE 0x00000000 +#define MATCH_TRANSPARENT 0x00000400 +#define SOURCE 0x00000000 +#define DESTINATION 0x00000200 + +/* 2D registers. */ + +#define DE_SOURCE 0x000000 +#define DE_SOURCE_WRAP 31 : 31 +#define DE_SOURCE_WRAP_DISABLE 0 +#define DE_SOURCE_WRAP_ENABLE 1 +#define DE_SOURCE_X_K1 29 : 16 +#define DE_SOURCE_Y_K2 15 : 0 + +#define DE_DESTINATION 0x000004 +#define DE_DESTINATION_WRAP 31 : 31 +#define DE_DESTINATION_WRAP_DISABLE 0 +#define DE_DESTINATION_WRAP_ENABLE 1 +#define DE_DESTINATION_X 28 : 16 +#define DE_DESTINATION_Y 15 : 0 + +#define DE_DIMENSION 0x000008 +#define DE_DIMENSION_X 28 : 16 +#define DE_DIMENSION_Y_ET 15 : 0 + +#define DE_CONTROL 0x00000C +#define DE_CONTROL_STATUS 31 : 31 +#define DE_CONTROL_STATUS_STOP 0 +#define DE_CONTROL_STATUS_START 1 +#define DE_CONTROL_PATTERN 30 : 30 +#define DE_CONTROL_PATTERN_MONO 0 +#define DE_CONTROL_PATTERN_COLOR 1 +#define DE_CONTROL_UPDATE_DESTINATION_X 29 : 29 +#define DE_CONTROL_UPDATE_DESTINATION_X_DISABLE 0 +#define DE_CONTROL_UPDATE_DESTINATION_X_ENABLE 1 +#define DE_CONTROL_QUICK_START 28 : 28 +#define DE_CONTROL_QUICK_START_DISABLE 0 +#define DE_CONTROL_QUICK_START_ENABLE 1 +#define DE_CONTROL_DIRECTION 27 : 27 +#define DE_CONTROL_DIRECTION_LEFT_TO_RIGHT 0 +#define DE_CONTROL_DIRECTION_RIGHT_TO_LEFT 1 +#define DE_CONTROL_MAJOR 26 : 26 +#define DE_CONTROL_MAJOR_X 0 +#define DE_CONTROL_MAJOR_Y 1 +#define DE_CONTROL_STEP_X 25 : 25 +#define DE_CONTROL_STEP_X_POSITIVE 1 +#define DE_CONTROL_STEP_X_NEGATIVE 0 +#define DE_CONTROL_STEP_Y 24 : 24 +#define DE_CONTROL_STEP_Y_POSITIVE 1 +#define DE_CONTROL_STEP_Y_NEGATIVE 0 +#define DE_CONTROL_STRETCH 23 : 23 +#define DE_CONTROL_STRETCH_DISABLE 0 +#define DE_CONTROL_STRETCH_ENABLE 1 +#define DE_CONTROL_HOST 22 : 22 +#define DE_CONTROL_HOST_COLOR 0 +#define DE_CONTROL_HOST_MONO 1 +#define DE_CONTROL_LAST_PIXEL 21 : 21 +#define DE_CONTROL_LAST_PIXEL_OFF 0 +#define DE_CONTROL_LAST_PIXEL_ON 1 +#define DE_CONTROL_COMMAND 20 : 16 +#define DE_CONTROL_COMMAND_BITBLT 0 +#define DE_CONTROL_COMMAND_RECTANGLE_FILL 1 +#define DE_CONTROL_COMMAND_DE_TILE 2 +#define DE_CONTROL_COMMAND_TRAPEZOID_FILL 3 +#define DE_CONTROL_COMMAND_ALPHA_BLEND 4 +#define DE_CONTROL_COMMAND_RLE_STRIP 5 +#define DE_CONTROL_COMMAND_SHORT_STROKE 6 +#define DE_CONTROL_COMMAND_LINE_DRAW 7 +#define DE_CONTROL_COMMAND_HOST_WRITE 8 +#define DE_CONTROL_COMMAND_HOST_READ 9 +#define DE_CONTROL_COMMAND_HOST_WRITE_BOTTOM_UP 10 +#define DE_CONTROL_COMMAND_ROTATE 11 +#define DE_CONTROL_COMMAND_FONT 12 +#define DE_CONTROL_COMMAND_TEXTURE_LOAD 15 +#define DE_CONTROL_ROP_SELECT 15 : 15 +#define DE_CONTROL_ROP_SELECT_ROP3 0 +#define DE_CONTROL_ROP_SELECT_ROP2 1 +#define DE_CONTROL_ROP2_SOURCE 14 : 14 +#define DE_CONTROL_ROP2_SOURCE_BITMAP 0 +#define DE_CONTROL_ROP2_SOURCE_PATTERN 1 +#define DE_CONTROL_MONO_DATA 13 : 12 +#define DE_CONTROL_MONO_DATA_NOT_PACKED 0 +#define DE_CONTROL_MONO_DATA_8_PACKED 1 +#define DE_CONTROL_MONO_DATA_16_PACKED 2 +#define DE_CONTROL_MONO_DATA_32_PACKED 3 +#define DE_CONTROL_REPEAT_ROTATE 11 : 11 +#define DE_CONTROL_REPEAT_ROTATE_DISABLE 0 +#define DE_CONTROL_REPEAT_ROTATE_ENABLE 1 +#define DE_CONTROL_TRANSPARENCY_MATCH 10 : 10 +#define DE_CONTROL_TRANSPARENCY_MATCH_OPAQUE 0 +#define DE_CONTROL_TRANSPARENCY_MATCH_TRANSPARENT 1 +#define DE_CONTROL_TRANSPARENCY_SELECT 9 : 9 +#define DE_CONTROL_TRANSPARENCY_SELECT_SOURCE 0 +#define DE_CONTROL_TRANSPARENCY_SELECT_DESTINATION 1 +#define DE_CONTROL_TRANSPARENCY 8 : 8 +#define DE_CONTROL_TRANSPARENCY_DISABLE 0 +#define DE_CONTROL_TRANSPARENCY_ENABLE 1 +#define DE_CONTROL_ROP 7 : 0 + +/* Pseudo fields. */ + +#define DE_CONTROL_SHORT_STROKE_DIR 27 : 24 +#define DE_CONTROL_SHORT_STROKE_DIR_225 0 +#define DE_CONTROL_SHORT_STROKE_DIR_135 1 +#define DE_CONTROL_SHORT_STROKE_DIR_315 2 +#define DE_CONTROL_SHORT_STROKE_DIR_45 3 +#define DE_CONTROL_SHORT_STROKE_DIR_270 4 +#define DE_CONTROL_SHORT_STROKE_DIR_90 5 +#define DE_CONTROL_SHORT_STROKE_DIR_180 8 +#define DE_CONTROL_SHORT_STROKE_DIR_0 10 +#define DE_CONTROL_ROTATION 25 : 24 +#define DE_CONTROL_ROTATION_0 0 +#define DE_CONTROL_ROTATION_270 1 +#define DE_CONTROL_ROTATION_90 2 +#define DE_CONTROL_ROTATION_180 3 + +#define DE_PITCH 0x000010 +#define DE_PITCH_DESTINATION 28 : 16 +#define DE_PITCH_SOURCE 12 : 0 + +#define DE_FOREGROUND 0x000014 +#define DE_FOREGROUND_COLOR 31 : 0 + +#define DE_BACKGROUND 0x000018 +#define DE_BACKGROUND_COLOR 31 : 0 + +#define DE_STRETCH_FORMAT 0x00001C +#define DE_STRETCH_FORMAT_PATTERN_XY 30 : 30 +#define DE_STRETCH_FORMAT_PATTERN_XY_NORMAL 0 +#define DE_STRETCH_FORMAT_PATTERN_XY_OVERWRITE 1 +#define DE_STRETCH_FORMAT_PATTERN_Y 29 : 27 +#define DE_STRETCH_FORMAT_PATTERN_X 25 : 23 +#define DE_STRETCH_FORMAT_PIXEL_FORMAT 21 : 20 +#define DE_STRETCH_FORMAT_PIXEL_FORMAT_8 0 +#define DE_STRETCH_FORMAT_PIXEL_FORMAT_16 1 +#define DE_STRETCH_FORMAT_PIXEL_FORMAT_24 3 +#define DE_STRETCH_FORMAT_PIXEL_FORMAT_32 2 +#define DE_STRETCH_FORMAT_ADDRESSING 19 : 16 +#define DE_STRETCH_FORMAT_ADDRESSING_XY 0 +#define DE_STRETCH_FORMAT_ADDRESSING_LINEAR 15 +#define DE_STRETCH_FORMAT_SOURCE_HEIGHT 11 : 0 + +#define DE_COLOR_COMPARE 0x000020 +#define DE_COLOR_COMPARE_COLOR 23 : 0 + +#define DE_COLOR_COMPARE_MASK 0x000024 +#define DE_COLOR_COMPARE_MASK_MASKS 23 : 0 + +#define DE_MASKS 0x000028 +#define DE_MASKS_BYTE_MASK 31 : 16 +#define DE_MASKS_BIT_MASK 15 : 0 + +#define DE_CLIP_TL 0x00002C +#define DE_CLIP_TL_TOP 31 : 16 +#define DE_CLIP_TL_STATUS 13 : 13 +#define DE_CLIP_TL_STATUS_DISABLE 0 +#define DE_CLIP_TL_STATUS_ENABLE 1 +#define DE_CLIP_TL_INHIBIT 12 : 12 +#define DE_CLIP_TL_INHIBIT_OUTSIDE 0 +#define DE_CLIP_TL_INHIBIT_INSIDE 1 +#define DE_CLIP_TL_LEFT 11 : 0 + +#define DE_CLIP_BR 0x000030 +#define DE_CLIP_BR_BOTTOM 31 : 16 +#define DE_CLIP_BR_RIGHT 12 : 0 + +#define DE_MONO_PATTERN_LOW 0x000034 +#define DE_MONO_PATTERN_LOW_PATTERN 31 : 0 + +#define DE_MONO_PATTERN_HIGH 0x000038 +#define DE_MONO_PATTERN_HIGH_PATTERN 31 : 0 + +#define DE_WINDOW_WIDTH 0x00003C +#define DE_WINDOW_WIDTH_DESTINATION 28 : 16 +#define DE_WINDOW_WIDTH_SOURCE 12 : 0 + +#define DE_WINDOW_SOURCE_BASE 0x000040 +#define DE_WINDOW_SOURCE_BASE_EXT 27 : 27 +#define DE_WINDOW_SOURCE_BASE_EXT_LOCAL 0 +#define DE_WINDOW_SOURCE_BASE_EXT_EXTERNAL 1 +#define DE_WINDOW_SOURCE_BASE_CS 26 : 26 +#define DE_WINDOW_SOURCE_BASE_CS_0 0 +#define DE_WINDOW_SOURCE_BASE_CS_1 1 +#define DE_WINDOW_SOURCE_BASE_ADDRESS 25 : 0 + +#define DE_WINDOW_DESTINATION_BASE 0x000044 +#define DE_WINDOW_DESTINATION_BASE_EXT 27 : 27 +#define DE_WINDOW_DESTINATION_BASE_EXT_LOCAL 0 +#define DE_WINDOW_DESTINATION_BASE_EXT_EXTERNAL 1 +#define DE_WINDOW_DESTINATION_BASE_CS 26 : 26 +#define DE_WINDOW_DESTINATION_BASE_CS_0 0 +#define DE_WINDOW_DESTINATION_BASE_CS_1 1 +#define DE_WINDOW_DESTINATION_BASE_ADDRESS 25 : 0 + +#define DE_ALPHA 0x000048 +#define DE_ALPHA_VALUE 7 : 0 + +#define DE_WRAP 0x00004C +#define DE_WRAP_X 31 : 16 +#define DE_WRAP_Y 15 : 0 + +#define DE_STATUS 0x000050 +#define DE_STATUS_CSC 1 : 1 +#define DE_STATUS_CSC_CLEAR 0 +#define DE_STATUS_CSC_NOT_ACTIVE 0 +#define DE_STATUS_CSC_ACTIVE 1 +#define DE_STATUS_2D 0 : 0 +#define DE_STATUS_2D_CLEAR 0 +#define DE_STATUS_2D_NOT_ACTIVE 0 +#define DE_STATUS_2D_ACTIVE 1 + +/* Color Space Conversion registers. */ + +#define CSC_Y_SOURCE_BASE 0x0000C8 +#define CSC_Y_SOURCE_BASE_EXT 27 : 27 +#define CSC_Y_SOURCE_BASE_EXT_LOCAL 0 +#define CSC_Y_SOURCE_BASE_EXT_EXTERNAL 1 +#define CSC_Y_SOURCE_BASE_CS 26 : 26 +#define CSC_Y_SOURCE_BASE_CS_0 0 +#define CSC_Y_SOURCE_BASE_CS_1 1 +#define CSC_Y_SOURCE_BASE_ADDRESS 25 : 0 + +#define CSC_CONSTANTS 0x0000CC +#define CSC_CONSTANTS_Y 31 : 24 +#define CSC_CONSTANTS_R 23 : 16 +#define CSC_CONSTANTS_G 15 : 8 +#define CSC_CONSTANTS_B 7 : 0 + +#define CSC_Y_SOURCE_X 0x0000D0 +#define CSC_Y_SOURCE_X_INTEGER 26 : 16 +#define CSC_Y_SOURCE_X_FRACTION 15 : 3 + +#define CSC_Y_SOURCE_Y 0x0000D4 +#define CSC_Y_SOURCE_Y_INTEGER 27 : 16 +#define CSC_Y_SOURCE_Y_FRACTION 15 : 3 + +#define CSC_U_SOURCE_BASE 0x0000D8 +#define CSC_U_SOURCE_BASE_EXT 27 : 27 +#define CSC_U_SOURCE_BASE_EXT_LOCAL 0 +#define CSC_U_SOURCE_BASE_EXT_EXTERNAL 1 +#define CSC_U_SOURCE_BASE_CS 26 : 26 +#define CSC_U_SOURCE_BASE_CS_0 0 +#define CSC_U_SOURCE_BASE_CS_1 1 +#define CSC_U_SOURCE_BASE_ADDRESS 25 : 0 + +#define CSC_V_SOURCE_BASE 0x0000DC +#define CSC_V_SOURCE_BASE_EXT 27 : 27 +#define CSC_V_SOURCE_BASE_EXT_LOCAL 0 +#define CSC_V_SOURCE_BASE_EXT_EXTERNAL 1 +#define CSC_V_SOURCE_BASE_CS 26 : 26 +#define CSC_V_SOURCE_BASE_CS_0 0 +#define CSC_V_SOURCE_BASE_CS_1 1 +#define CSC_V_SOURCE_BASE_ADDRESS 25 : 0 + +#define CSC_SOURCE_DIMENSION 0x0000E0 +#define CSC_SOURCE_DIMENSION_X 31 : 16 +#define CSC_SOURCE_DIMENSION_Y 15 : 0 + +#define CSC_SOURCE_PITCH 0x0000E4 +#define CSC_SOURCE_PITCH_Y 31 : 16 +#define CSC_SOURCE_PITCH_UV 15 : 0 + +#define CSC_DESTINATION 0x0000E8 +#define CSC_DESTINATION_WRAP 31 : 31 +#define CSC_DESTINATION_WRAP_DISABLE 0 +#define CSC_DESTINATION_WRAP_ENABLE 1 +#define CSC_DESTINATION_X 27 : 16 +#define CSC_DESTINATION_Y 11 : 0 + +#define CSC_DESTINATION_DIMENSION 0x0000EC +#define CSC_DESTINATION_DIMENSION_X 31 : 16 +#define CSC_DESTINATION_DIMENSION_Y 15 : 0 + +#define CSC_DESTINATION_PITCH 0x0000F0 +#define CSC_DESTINATION_PITCH_X 31 : 16 +#define CSC_DESTINATION_PITCH_Y 15 : 0 + +#define CSC_SCALE_FACTOR 0x0000F4 +#define CSC_SCALE_FACTOR_HORIZONTAL 31 : 16 +#define CSC_SCALE_FACTOR_VERTICAL 15 : 0 + +#define CSC_DESTINATION_BASE 0x0000F8 +#define CSC_DESTINATION_BASE_EXT 27 : 27 +#define CSC_DESTINATION_BASE_EXT_LOCAL 0 +#define CSC_DESTINATION_BASE_EXT_EXTERNAL 1 +#define CSC_DESTINATION_BASE_CS 26 : 26 +#define CSC_DESTINATION_BASE_CS_0 0 +#define CSC_DESTINATION_BASE_CS_1 1 +#define CSC_DESTINATION_BASE_ADDRESS 25 : 0 + +#define CSC_CONTROL 0x0000FC +#define CSC_CONTROL_STATUS 31 : 31 +#define CSC_CONTROL_STATUS_STOP 0 +#define CSC_CONTROL_STATUS_START 1 +#define CSC_CONTROL_SOURCE_FORMAT 30 : 28 +#define CSC_CONTROL_SOURCE_FORMAT_YUV422 0 +#define CSC_CONTROL_SOURCE_FORMAT_YUV420I 1 +#define CSC_CONTROL_SOURCE_FORMAT_YUV420 2 +#define CSC_CONTROL_SOURCE_FORMAT_YVU9 3 +#define CSC_CONTROL_SOURCE_FORMAT_IYU1 4 +#define CSC_CONTROL_SOURCE_FORMAT_IYU2 5 +#define CSC_CONTROL_SOURCE_FORMAT_RGB565 6 +#define CSC_CONTROL_SOURCE_FORMAT_RGB8888 7 +#define CSC_CONTROL_DESTINATION_FORMAT 27 : 26 +#define CSC_CONTROL_DESTINATION_FORMAT_RGB565 0 +#define CSC_CONTROL_DESTINATION_FORMAT_RGB8888 1 +#define CSC_CONTROL_HORIZONTAL_FILTER 25 : 25 +#define CSC_CONTROL_HORIZONTAL_FILTER_DISABLE 0 +#define CSC_CONTROL_HORIZONTAL_FILTER_ENABLE 1 +#define CSC_CONTROL_VERTICAL_FILTER 24 : 24 +#define CSC_CONTROL_VERTICAL_FILTER_DISABLE 0 +#define CSC_CONTROL_VERTICAL_FILTER_ENABLE 1 +#define CSC_CONTROL_BYTE_ORDER 23 : 23 +#define CSC_CONTROL_BYTE_ORDER_YUYV 0 +#define CSC_CONTROL_BYTE_ORDER_UYVY 1 + +#define DE_DATA_PORT_501 0x110000 +#define DE_DATA_PORT_712 0x400000 +#define DE_DATA_PORT_722 0x6000 + +/* point to virtual Memory Map IO starting address */ +extern char *smtc_RegBaseAddress; +/* point to virtual video memory starting address */ +extern char *smtc_VRAMBaseAddress; +extern unsigned char smtc_de_busy; + +extern unsigned long memRead32(unsigned long nOffset); +extern void memWrite32(unsigned long nOffset, unsigned long nData); +extern unsigned long SMTC_read2Dreg(unsigned long nOffset); + +/* 2D functions */ +extern void deInit(unsigned int nModeWidth, unsigned int nModeHeight, + unsigned int bpp); + +extern void deWaitForNotBusy(void); + +extern void deVerticalLine(unsigned long dst_base, + unsigned long dst_pitch, + unsigned long nX, + unsigned long nY, + unsigned long dst_height, + unsigned long nColor); + +extern void deHorizontalLine(unsigned long dst_base, + unsigned long dst_pitch, + unsigned long nX, + unsigned long nY, + unsigned long dst_width, + unsigned long nColor); + +extern void deLine(unsigned long dst_base, + unsigned long dst_pitch, + unsigned long nX1, + unsigned long nY1, + unsigned long nX2, + unsigned long nY2, + unsigned long nColor); + +extern void deFillRect(unsigned long dst_base, + unsigned long dst_pitch, + unsigned long dst_X, + unsigned long dst_Y, + unsigned long dst_width, + unsigned long dst_height, + unsigned long nColor); + +extern void deRotatePattern(unsigned char *pattern_dstaddr, + unsigned long pattern_src_addr, + unsigned long pattern_BPP, + unsigned long pattern_stride, + int patternX, + int patternY); + +extern void deCopy(unsigned long dst_base, + unsigned long dst_pitch, + unsigned long dst_BPP, + unsigned long dst_X, + unsigned long dst_Y, + unsigned long dst_width, + unsigned long dst_height, + unsigned long src_base, + unsigned long src_pitch, + unsigned long src_X, + unsigned long src_Y, + pTransparent pTransp, + unsigned char nROP2); + +/* + * System memory to Video memory monochrome expansion. + * + * Source is monochrome image in system memory. This function expands the + * monochrome data to color image in video memory. + * + * @pSrcbuf: pointer to start of source buffer in system memory + * @srcDelta: Pitch value (in bytes) of the source buffer, +ive means top + * down and -ive mean button up + * @startBit: Mono data can start at any bit in a byte, this value should + * be 0 to 7 + * @dBase: Address of destination : offset in frame buffer + * @dPitch: Pitch value of destination surface in BYTE + * @bpp: Color depth of destination surface + * @dx, dy: Starting coordinate of destination surface + * @width, height: width and height of rectange in pixel value + * @fColor,bColor: Foreground, Background color (corresponding to a 1, 0 in + * the monochrome data) + * @rop2: ROP value + */ + +extern long deSystemMem2VideoMemMonoBlt( + const char *pSrcbuf, + long srcDelta, + unsigned long startBit, + unsigned long dBase, + unsigned long dPitch, + unsigned long bpp, + unsigned long dx, unsigned long dy, + unsigned long width, unsigned long height, + unsigned long fColor, + unsigned long bColor, + unsigned long rop2); + +extern unsigned long deGetTransparency(void); +extern void deSetPixelFormat(unsigned long bpp); diff -Nur linux-2.6.30.5.orig/drivers/video/sm7xx/smtcfb.c linux-2.6.30.5/drivers/video/sm7xx/smtcfb.c --- linux-2.6.30.5.orig/drivers/video/sm7xx/smtcfb.c 1970-01-01 01:00:00.000000000 +0100 +++ linux-2.6.30.5/drivers/video/sm7xx/smtcfb.c 2009-08-23 19:01:04.000000000 +0200 @@ -0,0 +1,1138 @@ +/* + * smtcfb.c -- Silicon Motion SM7xx frame buffer device + * + * Copyright (C) 2006 Silicon Motion Technology Corp. + * Authors: Ge Wang, gewang@siliconmotion.com + * Boyod boyod.yang@siliconmotion.com.cn + * + * Copyright (C) 2009 Lemote, Inc. & Institute of Computing Technology + * Author: Wu Zhangjin, wuzj@lemote.com + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file COPYING in the main directory of this archive for + * more details. + * + * Version 0.10.26192.21.01 + * - Add PowerPC/Big endian support + * - Add 2D support for Lynx + * - Verified on2.6.19.2 Boyod.yang + * + * Version 0.09.2621.00.01 + * - Only support Linux Kernel's version 2.6.21. + * Boyod.yang + * + * Version 0.09 + * - Only support Linux Kernel's version 2.6.12. + * Boyod.yang + */ + +#ifndef __KERNEL__ +#define __KERNEL__ +#endif + +#include +#include +#include +#include +#include +#include + +#ifdef CONFIG_PM +#include +#endif + +struct screen_info smtc_screen_info; + +#include "smtcfb.h" +#include "smtc2d.h" + +#ifdef DEBUG +#define smdbg(format, arg...) printk(KERN_DEBUG format , ## arg) +#else +#define smdbg(format, arg...) +#endif + +/* +* Private structure +*/ +struct smtcfb_info { + /* + * The following is a pointer to be passed into the + * functions below. The modules outside the main + * voyager.c driver have no knowledge as to what + * is within this structure. + */ + struct fb_info fb; + struct display_switch *dispsw; + struct pci_dev *dev; + signed int currcon; + + struct { + u8 red, green, blue; + } palette[NR_RGB]; + + u_int palette_size; +}; + +struct par_info { + /* + * Hardware + */ + u16 chipID; + unsigned char __iomem *m_pMMIO; + char __iomem *m_pLFB; + char *m_pDPR; + char *m_pVPR; + char *m_pCPR; + + u_int width; + u_int height; + u_int hz; + u_long BaseAddressInVRAM; + u8 chipRevID; +}; + +struct vesa_mode_table { + char mode_index[15]; + u16 lfb_width; + u16 lfb_height; + u16 lfb_depth; +}; + +static struct vesa_mode_table vesa_mode[] = { + {"640x480x8", 640, 480, 8}, + {"800x480x8", 800, 480, 8}, + {"800x600x8", 800, 600, 8}, + {"1024x768x8", 1024, 768, 8}, + {"1280x1024x8", 1280, 1024, 8}, + + {"640x480x16", 640, 480, 16}, + {"800x480x16", 800, 480, 16}, + {"800x600x16", 800, 600, 16}, + {"1024x768x16", 1024, 768, 16}, + {"1280x1024x16", 1280, 1024, 16}, + + {"640x480x24", 640, 480, 24}, + {"800x480x24", 800, 480, 24}, + {"800x600x24", 800, 600, 24}, + {"1024x768x24", 1024, 768, 24}, + {"1280x1024x24", 1280, 1024, 24}, +}; + +char __iomem *smtc_RegBaseAddress; /* Memory Map IO starting address */ +char __iomem *smtc_VRAMBaseAddress; /* video memory starting address */ + +char *smtc_2DBaseAddress; /* 2D engine starting address */ +char *smtc_2Ddataport; /* 2D data port offset */ +short smtc_2Dacceleration; + +static u32 colreg[17]; +static struct par_info hw; /* hardware information */ + +#if defined(CONFIG_FB_SM7XX_DUALHEAD) + +static u32 colreg2[17]; +/* hardware information for second display (CRT) */ +static struct par_info hw2; +/* fb_info for second display (CRT) */ +struct smtcfb_info smtcfb_info2; + +#endif /* CONFIG_FB_SM501_DUALHEAD */ + +u16 smtc_ChipIDs[] = { + 0x710, + 0x712, + 0x720 +}; + +int sm712be_flag; + +#define numSMTCchipIDs (sizeof(smtc_ChipIDs) / sizeof(u16)) + +void deWaitForNotBusy(void) +{ + unsigned long i = 0x1000000; + while (i--) { + if ((smtc_seqr(0x16) & 0x18) == 0x10) + break; + } + smtc_de_busy = 0; +} + +static void sm712_set_timing(struct smtcfb_info *sfb, + struct par_info *ppar_info) +{ + int i = 0, j = 0; + u32 m_nScreenStride; + + smdbg("\nppar_info->width = %d ppar_info->height = %d" + "sfb->fb.var.bits_per_pixel = %d ppar_info->hz = %d\n", + ppar_info->width, ppar_info->height, + sfb->fb.var.bits_per_pixel, ppar_info->hz); + + for (j = 0; j < numVGAModes; j++) { + if (VGAMode[j].mmSizeX == ppar_info->width && + VGAMode[j].mmSizeY == ppar_info->height && + VGAMode[j].bpp == sfb->fb.var.bits_per_pixel && + VGAMode[j].hz == ppar_info->hz) { + + smdbg("\nVGAMode[j].mmSizeX = %d VGAMode[j].mmSizeY =" + "%d VGAMode[j].bpp = %d" + "VGAMode[j].hz=%d\n", + VGAMode[j].mmSizeX, VGAMode[j].mmSizeY, + VGAMode[j].bpp, VGAMode[j].hz); + + smdbg("VGAMode index=%d\n", j); + + smtc_mmiowb(0x0, 0x3c6); + + smtc_seqw(0, 0x1); + + smtc_mmiowb(VGAMode[j].Init_MISC, 0x3c2); + + /* init SEQ register SR00 - SR04 */ + for (i = 0; i < SIZE_SR00_SR04; i++) + smtc_seqw(i, VGAMode[j].Init_SR00_SR04[i]); + + /* init SEQ register SR10 - SR24 */ + for (i = 0; i < SIZE_SR10_SR24; i++) + smtc_seqw(i + 0x10, + VGAMode[j].Init_SR10_SR24[i]); + + /* init SEQ register SR30 - SR75 */ + for (i = 0; i < SIZE_SR30_SR75; i++) + if (((i + 0x30) != 0x62) \ + && ((i + 0x30) != 0x6a) \ + && ((i + 0x30) != 0x6b)) + smtc_seqw(i + 0x30, + VGAMode[j].Init_SR30_SR75[i]); + + /* init SEQ register SR80 - SR93 */ + for (i = 0; i < SIZE_SR80_SR93; i++) + smtc_seqw(i + 0x80, + VGAMode[j].Init_SR80_SR93[i]); + + /* init SEQ register SRA0 - SRAF */ + for (i = 0; i < SIZE_SRA0_SRAF; i++) + smtc_seqw(i + 0xa0, + VGAMode[j].Init_SRA0_SRAF[i]); + + /* init Graphic register GR00 - GR08 */ + for (i = 0; i < SIZE_GR00_GR08; i++) + smtc_grphw(i, VGAMode[j].Init_GR00_GR08[i]); + + /* init Attribute register AR00 - AR14 */ + for (i = 0; i < SIZE_AR00_AR14; i++) + smtc_attrw(i, VGAMode[j].Init_AR00_AR14[i]); + + /* init CRTC register CR00 - CR18 */ + for (i = 0; i < SIZE_CR00_CR18; i++) + smtc_crtcw(i, VGAMode[j].Init_CR00_CR18[i]); + + /* init CRTC register CR30 - CR4D */ + for (i = 0; i < SIZE_CR30_CR4D; i++) + smtc_crtcw(i + 0x30, + VGAMode[j].Init_CR30_CR4D[i]); + + /* init CRTC register CR90 - CRA7 */ + for (i = 0; i < SIZE_CR90_CRA7; i++) + smtc_crtcw(i + 0x90, + VGAMode[j].Init_CR90_CRA7[i]); + } + } + smtc_mmiowb(0x67, 0x3c2); + + /* set VPR registers */ + writel(0x0, ppar_info->m_pVPR + 0x0C); + writel(0x0, ppar_info->m_pVPR + 0x40); + + /* set data width */ + m_nScreenStride = + (ppar_info->width * sfb->fb.var.bits_per_pixel) / 64; + switch (sfb->fb.var.bits_per_pixel) { + case 8: + writel(0x0, ppar_info->m_pVPR + 0x0); + break; + case 16: + writel(0x00020000, ppar_info->m_pVPR + 0x0); + break; + case 24: + writel(0x00040000, ppar_info->m_pVPR + 0x0); + break; + case 32: + writel(0x00030000, ppar_info->m_pVPR + 0x0); + break; + } + writel((u32) (((m_nScreenStride + 2) << 16) | m_nScreenStride), + ppar_info->m_pVPR + 0x10); + +} + +static void sm712_setpalette(int regno, unsigned red, unsigned green, + unsigned blue, struct fb_info *info) +{ + struct par_info *cur_par = (struct par_info *)info->par; + + if (cur_par->BaseAddressInVRAM) + /* + * second display palette for dual head. Enable CRT RAM, 6-bit + * RAM + */ + smtc_seqw(0x66, (smtc_seqr(0x66) & 0xC3) | 0x20); + else + /* primary display palette. Enable LCD RAM only, 6-bit RAM */ + smtc_seqw(0x66, (smtc_seqr(0x66) & 0xC3) | 0x10); + smtc_mmiowb(regno, dac_reg); + smtc_mmiowb(red >> 10, dac_val); + smtc_mmiowb(green >> 10, dac_val); + smtc_mmiowb(blue >> 10, dac_val); +} + +static void smtc_set_timing(struct smtcfb_info *sfb, struct par_info + *ppar_info) +{ + switch (ppar_info->chipID) { + case 0x710: + case 0x712: + case 0x720: + sm712_set_timing(sfb, ppar_info); + break; + } +} + +static struct fb_var_screeninfo smtcfb_var = { + .xres = 1024, + .yres = 600, + .xres_virtual = 1024, + .yres_virtual = 600, + .bits_per_pixel = 16, + .red = {16, 8, 0}, + .green = {8, 8, 0}, + .blue = {0, 8, 0}, + .activate = FB_ACTIVATE_NOW, + .height = -1, + .width = -1, + .vmode = FB_VMODE_NONINTERLACED, +}; + +static struct fb_fix_screeninfo smtcfb_fix = { + .id = "sm712fb", + .type = FB_TYPE_PACKED_PIXELS, + .visual = FB_VISUAL_TRUECOLOR, + .line_length = 800 * 3, + .accel = FB_ACCEL_SMI_LYNX, +}; + +/* chan_to_field + * + * convert a colour value into a field position + * + * from pxafb.c + */ + +static inline unsigned int chan_to_field(unsigned int chan, + struct fb_bitfield *bf) +{ + chan &= 0xffff; + chan >>= 16 - bf->length; + return chan << bf->offset; +} + +static int smtc_setcolreg(unsigned regno, unsigned red, unsigned green, + unsigned blue, unsigned trans, struct fb_info *info) +{ + struct smtcfb_info *sfb = (struct smtcfb_info *)info; + u32 val; + + if (regno > 255) + return 1; + + switch (sfb->fb.fix.visual) { + case FB_VISUAL_DIRECTCOLOR: + case FB_VISUAL_TRUECOLOR: + /* + * 16/32 bit true-colour, use pseuo-palette for 16 base color + */ + if (regno < 16) { + if (sfb->fb.var.bits_per_pixel == 16) { + u32 *pal = sfb->fb.pseudo_palette; + val = chan_to_field(red, &sfb->fb.var.red); + val |= chan_to_field(green, \ + &sfb->fb.var.green); + val |= chan_to_field(blue, &sfb->fb.var.blue); +#ifdef __BIG_ENDIAN + pal[regno] = + ((red & 0xf800) >> 8) | + ((green & 0xe000) >> 13) | + ((green & 0x1c00) << 3) | + ((blue & 0xf800) >> 3); +#else + pal[regno] = val; +#endif + } else { + u32 *pal = sfb->fb.pseudo_palette; + val = chan_to_field(red, &sfb->fb.var.red); + val |= chan_to_field(green, \ + &sfb->fb.var.green); + val |= chan_to_field(blue, &sfb->fb.var.blue); +#ifdef __BIG_ENDIAN + val = + (val & 0xff00ff00 >> 8) | + (val & 0x00ff00ff << 8); +#endif + pal[regno] = val; + } + } + break; + + case FB_VISUAL_PSEUDOCOLOR: + /* color depth 8 bit */ + sm712_setpalette(regno, red, green, blue, info); + break; + + default: + return 1; /* unknown type */ + } + + return 0; + +} + +#ifdef __BIG_ENDIAN +static ssize_t smtcfb_read(struct fb_info *info, char __user * buf, size_t + count, loff_t *ppos) +{ + unsigned long p = *ppos; + + u32 *buffer, *dst; + u32 __iomem *src; + int c, i, cnt = 0, err = 0; + unsigned long total_size; + + if (!info || !info->screen_base) + return -ENODEV; + + if (info->state != FBINFO_STATE_RUNNING) + return -EPERM; + + total_size = info->screen_size; + + if (total_size == 0) + total_size = info->fix.smem_len; + + if (p >= total_size) + return 0; + + if (count >= total_size) + count = total_size; + + if (count + p > total_size) + count = total_size - p; + + buffer = kmalloc((count > PAGE_SIZE) ? PAGE_SIZE : count, GFP_KERNEL); + if (!buffer) + return -ENOMEM; + + src = (u32 __iomem *) (info->screen_base + p); + + if (info->fbops->fb_sync) + info->fbops->fb_sync(info); + + while (count) { + c = (count > PAGE_SIZE) ? PAGE_SIZE : count; + dst = buffer; + for (i = c >> 2; i--;) { + *dst = fb_readl(src++); + *dst = + (*dst & 0xff00ff00 >> 8) | + (*dst & 0x00ff00ff << 8); + dst++; + } + if (c & 3) { + u8 *dst8 = (u8 *) dst; + u8 __iomem *src8 = (u8 __iomem *) src; + + for (i = c & 3; i--;) { + if (i & 1) { + *dst8++ = fb_readb(++src8); + } else { + *dst8++ = fb_readb(--src8); + src8 += 2; + } + } + src = (u32 __iomem *) src8; + } + + if (copy_to_user(buf, buffer, c)) { + err = -EFAULT; + break; + } + *ppos += c; + buf += c; + cnt += c; + count -= c; + } + + kfree(buffer); + + return (err) ? err : cnt; +} + +static ssize_t +smtcfb_write(struct fb_info *info, const char __user *buf, size_t count, + loff_t *ppos) +{ + unsigned long p = *ppos; + + u32 *buffer, *src; + u32 __iomem *dst; + int c, i, cnt = 0, err = 0; + unsigned long total_size; + + if (!info || !info->screen_base) + return -ENODEV; + + if (info->state != FBINFO_STATE_RUNNING) + return -EPERM; + + total_size = info->screen_size; + + if (total_size == 0) + total_size = info->fix.smem_len; + + if (p > total_size) + return -EFBIG; + + if (count > total_size) { + err = -EFBIG; + count = total_size; + } + + if (count + p > total_size) { + if (!err) + err = -ENOSPC; + + count = total_size - p; + } + + buffer = kmalloc((count > PAGE_SIZE) ? PAGE_SIZE : count, GFP_KERNEL); + if (!buffer) + return -ENOMEM; + + dst = (u32 __iomem *) (info->screen_base + p); + + if (info->fbops->fb_sync) + info->fbops->fb_sync(info); + + while (count) { + c = (count > PAGE_SIZE) ? PAGE_SIZE : count; + src = buffer; + + if (copy_from_user(src, buf, c)) { + err = -EFAULT; + break; + } + + for (i = c >> 2; i--;) { + fb_writel((*src & 0xff00ff00 >> 8) | + (*src & 0x00ff00ff << 8), dst++); + src++; + } + if (c & 3) { + u8 *src8 = (u8 *) src; + u8 __iomem *dst8 = (u8 __iomem *) dst; + + for (i = c & 3; i--;) { + if (i & 1) { + fb_writeb(*src8++, ++dst8); + } else { + fb_writeb(*src8++, --dst8); + dst8 += 2; + } + } + dst = (u32 __iomem *) dst8; + } + + *ppos += c; + buf += c; + cnt += c; + count -= c; + } + + kfree(buffer); + + return (cnt) ? cnt : err; +} +#endif /* ! __BIG_ENDIAN */ + +#include "smtc2d.c" + +void smtcfb_copyarea(struct fb_info *info, const struct fb_copyarea *area) +{ + struct par_info *p = (struct par_info *)info->par; + + if (smtc_2Dacceleration) { + if (!area->width || !area->height) + return; + + deCopy(p->BaseAddressInVRAM, 0, info->var.bits_per_pixel, + area->dx, area->dy, area->width, area->height, + p->BaseAddressInVRAM, 0, area->sx, area->sy, 0, 0xC); + + } else + cfb_copyarea(info, area); +} + +void smtcfb_fillrect(struct fb_info *info, const struct fb_fillrect *rect) +{ + struct par_info *p = (struct par_info *)info->par; + + if (smtc_2Dacceleration) { + if (!rect->width || !rect->height) + return; + if (info->var.bits_per_pixel >= 24) + deFillRect(p->BaseAddressInVRAM, 0, rect->dx * 3, + rect->dy * 3, rect->width * 3, rect->height, + rect->color); + else + deFillRect(p->BaseAddressInVRAM, 0, rect->dx, rect->dy, + rect->width, rect->height, rect->color); + } else + cfb_fillrect(info, rect); +} + +void smtcfb_imageblit(struct fb_info *info, const struct fb_image *image) +{ + struct par_info *p = (struct par_info *)info->par; + u32 bg_col = 0, fg_col = 0; + + if ((smtc_2Dacceleration) && (image->depth == 1)) { + if (smtc_de_busy) + deWaitForNotBusy(); + + switch (info->var.bits_per_pixel) { + case 8: + bg_col = image->bg_color; + fg_col = image->fg_color; + break; + case 16: + bg_col = + ((u32 *) (info->pseudo_palette))[image->bg_color]; + fg_col = + ((u32 *) (info->pseudo_palette))[image->fg_color]; + break; + case 32: + bg_col = + ((u32 *) (info->pseudo_palette))[image->bg_color]; + fg_col = + ((u32 *) (info->pseudo_palette))[image->fg_color]; + break; + } + + deSystemMem2VideoMemMonoBlt( + image->data, + image->width / 8, + 0, + p->BaseAddressInVRAM, + 0, + 0, + image->dx, image->dy, + image->width, image->height, + fg_col, bg_col, + 0x0C); + + } else + cfb_imageblit(info, image); +} + +static struct fb_ops smtcfb_ops = { + .owner = THIS_MODULE, + .fb_setcolreg = smtc_setcolreg, + .fb_fillrect = smtcfb_fillrect, + .fb_imageblit = smtcfb_imageblit, + .fb_copyarea = smtcfb_copyarea, +#ifdef __BIG_ENDIAN + .fb_read = smtcfb_read, + .fb_write = smtcfb_write, +#endif + +}; + +void smtcfb_setmode(struct smtcfb_info *sfb) +{ + switch (sfb->fb.var.bits_per_pixel) { + case 32: + sfb->fb.fix.visual = FB_VISUAL_TRUECOLOR; + sfb->fb.fix.line_length = sfb->fb.var.xres * 4; + sfb->fb.var.red.length = 8; + sfb->fb.var.green.length = 8; + sfb->fb.var.blue.length = 8; + sfb->fb.var.red.offset = 16; + sfb->fb.var.green.offset = 8; + sfb->fb.var.blue.offset = 0; + + break; + case 8: + sfb->fb.fix.visual = FB_VISUAL_PSEUDOCOLOR; + sfb->fb.fix.line_length = sfb->fb.var.xres; + sfb->fb.var.red.offset = 5; + sfb->fb.var.red.length = 3; + sfb->fb.var.green.offset = 2; + sfb->fb.var.green.length = 3; + sfb->fb.var.blue.offset = 0; + sfb->fb.var.blue.length = 2; + break; + case 24: + sfb->fb.fix.visual = FB_VISUAL_TRUECOLOR; + sfb->fb.fix.line_length = sfb->fb.var.xres * 3; + sfb->fb.var.red.length = 8; + sfb->fb.var.green.length = 8; + sfb->fb.var.blue.length = 8; + + sfb->fb.var.red.offset = 16; + sfb->fb.var.green.offset = 8; + sfb->fb.var.blue.offset = 0; + + break; + case 16: + default: + sfb->fb.fix.visual = FB_VISUAL_TRUECOLOR; + sfb->fb.fix.line_length = sfb->fb.var.xres * 2; + + sfb->fb.var.red.length = 5; + sfb->fb.var.green.length = 6; + sfb->fb.var.blue.length = 5; + + sfb->fb.var.red.offset = 11; + sfb->fb.var.green.offset = 5; + sfb->fb.var.blue.offset = 0; + + break; + } + + hw.width = sfb->fb.var.xres; + hw.height = sfb->fb.var.yres; + hw.hz = 60; + smtc_set_timing(sfb, &hw); + if (smtc_2Dacceleration) { + printk("2D acceleration enabled!\n"); + /* Init smtc drawing engine */ + deInit(sfb->fb.var.xres, sfb->fb.var.yres, + sfb->fb.var.bits_per_pixel); + } +} + +#if defined(CONFIG_FB_SM7XX_DUALHEAD) +void smtc_head2_init(struct smtcfb_info *sfb) +{ + smtcfb_info2 = *sfb; + smtcfb_info2.fb.pseudo_palette = &colreg2; + smtcfb_info2.fb.par = &hw2; + sprintf(smtcfb_info2.fb.fix.id, "sm%Xfb2", hw.chipID); + hw2.chipID = hw.chipID; + hw2.chipRevID = hw.chipRevID; + hw2.width = smtcfb_info2.fb.var.xres; + hw2.height = smtcfb_info2.fb.var.yres; + hw2.hz = 60; + hw2.m_pMMIO = smtc_RegBaseAddress; + + /*hard code 2nd head starting from half VRAM size postion */ + hw2.BaseAddressInVRAM = smtcfb_info2.fb.fix.smem_len / 2; + + hw2.m_pLFB = smtc_VRAMBaseAddress + hw2.BaseAddressInVRAM; + smtcfb_info2.fb.screen_base = hw2.m_pLFB; + + writel(hw2.BaseAddressInVRAM >> 3, hw2.m_pVPR + 0x10); +} +#endif + +/* + * Alloc struct smtcfb_info and assign the default value + */ +static struct smtcfb_info *__devinit smtc_alloc_fb_info(struct pci_dev *dev, + char *name) +{ + struct smtcfb_info *sfb; + + sfb = kmalloc(sizeof(struct smtcfb_info), GFP_KERNEL); + + if (!sfb) + return NULL; + + memset(sfb, 0, sizeof(struct smtcfb_info)); + + sfb->currcon = -1; + sfb->dev = dev; + + /*** Init sfb->fb with default value ***/ + sfb->fb.flags = FBINFO_FLAG_DEFAULT; + sfb->fb.fbops = &smtcfb_ops; + sfb->fb.var = smtcfb_var; + sfb->fb.fix = smtcfb_fix; + + strcpy(sfb->fb.fix.id, name); + + sfb->fb.fix.type = FB_TYPE_PACKED_PIXELS; + sfb->fb.fix.type_aux = 0; + sfb->fb.fix.xpanstep = 0; + sfb->fb.fix.ypanstep = 0; + sfb->fb.fix.ywrapstep = 0; + sfb->fb.fix.accel = FB_ACCEL_SMI_LYNX; + + sfb->fb.var.nonstd = 0; + sfb->fb.var.activate = FB_ACTIVATE_NOW; + sfb->fb.var.height = -1; + sfb->fb.var.width = -1; + /* text mode acceleration */ + sfb->fb.var.accel_flags = FB_ACCELF_TEXT; + sfb->fb.var.vmode = FB_VMODE_NONINTERLACED; + sfb->fb.par = &hw; + sfb->fb.pseudo_palette = colreg; + + return sfb; +} + +/* + * Unmap in the memory mapped IO registers + */ + +static void __devinit smtc_unmap_mmio(struct smtcfb_info *sfb) +{ + if (sfb && smtc_RegBaseAddress) + smtc_RegBaseAddress = NULL; +} + +/* + * Map in the screen memory + */ + +static int __devinit smtc_map_smem(struct smtcfb_info *sfb, + struct pci_dev *dev, u_long smem_len) +{ + if (sfb->fb.var.bits_per_pixel == 32) { +#ifdef __BIG_ENDIAN + sfb->fb.fix.smem_start = pci_resource_start(dev, 0) + + 0x800000; +#else + sfb->fb.fix.smem_start = pci_resource_start(dev, 0); +#endif + } else { + sfb->fb.fix.smem_start = pci_resource_start(dev, 0); + } + + sfb->fb.fix.smem_len = smem_len; + + sfb->fb.screen_base = smtc_VRAMBaseAddress; + + if (!sfb->fb.screen_base) { + printk(KERN_INFO "%s: unable to map screen memory\n", + sfb->fb.fix.id); + return -ENOMEM; + } + + return 0; +} + +/* + * Unmap in the screen memory + * + */ +static void __devinit smtc_unmap_smem(struct smtcfb_info *sfb) +{ + if (sfb && sfb->fb.screen_base) { + iounmap(sfb->fb.screen_base); + sfb->fb.screen_base = NULL; + } +} + +/* + * We need to wake up the LynxEM+, and make sure its in linear memory mode. + */ +static inline void __devinit sm7xx_init_hw(void) +{ + outb_p(0x18, 0x3c4); + outb_p(0x11, 0x3c5); +} + +static void __devinit smtc_free_fb_info(struct smtcfb_info *sfb) +{ + if (sfb) { + fb_alloc_cmap(&sfb->fb.cmap, 0, 0); + kfree(sfb); + } +} + +static int __init smtcfb_init(void) +{ + struct smtcfb_info *sfb; + u_long smem_size = 0x00800000; /* default 8MB */ + char name[16]; + int err, i = 0; + unsigned long pFramebufferPhysical; + struct pci_dev *pdev = NULL; + + printk(KERN_INFO + "Silicon Motion display driver " SMTC_LINUX_FB_VERSION "\n"); + + /* init the global variable */ + smtc_2Dacceleration = 0; /* default no 2D acceleration */ + + do { + pdev = pci_get_device(0x126f, smtc_ChipIDs[i], pdev); + if (pdev == NULL) { + i++; + } else { + hw.chipID = smtc_ChipIDs[i]; + break; + } + } while (i < numSMTCchipIDs); + + err = pci_enable_device(pdev); /* enable SMTC chip */ + + if (err) + return err; + + err = -ENOMEM; + + sprintf(name, "sm%Xfb", hw.chipID); + + sfb = smtc_alloc_fb_info(pdev, name); + + if (!sfb) + goto failed; + + sm7xx_init_hw(); + + /*get mode parameter from smtc_screen_info */ + if (smtc_screen_info.lfb_width != 0) { + sfb->fb.var.xres = smtc_screen_info.lfb_width; + sfb->fb.var.yres = smtc_screen_info.lfb_height; + sfb->fb.var.bits_per_pixel = smtc_screen_info.lfb_depth; + } else { + /* default resolution 1024x600 16bit mode */ + sfb->fb.var.xres = SCREEN_X_RES; + sfb->fb.var.yres = SCREEN_Y_RES; + sfb->fb.var.bits_per_pixel = SCREEN_BPP; + } + + smdbg("\nsfb->fb.var.bits_per_pixel = %d sm712be_flag = %d\n", + sfb->fb.var.bits_per_pixel, sm712be_flag); +#ifdef __BIG_ENDIAN + if (sm712be_flag == 1 && sfb->fb.var.bits_per_pixel == 24) + sfb->fb.var.bits_per_pixel = (smtc_screen_info.lfb_depth = 32); +#endif + /* Map address and memory detection */ + pFramebufferPhysical = pci_resource_start(pdev, 0); + pci_read_config_byte(pdev, PCI_REVISION_ID, &hw.chipRevID); + + switch (hw.chipID) { + case 0x710: + case 0x712: + sfb->fb.fix.mmio_start = pFramebufferPhysical + 0x00400000; + sfb->fb.fix.mmio_len = 0x00400000; + smem_size = SM712_VIDEOMEMORYSIZE; +#ifdef __BIG_ENDIAN + hw.m_pLFB = (smtc_VRAMBaseAddress = + ioremap(pFramebufferPhysical, 0x00c00000)); +#else + hw.m_pLFB = (smtc_VRAMBaseAddress = + ioremap(pFramebufferPhysical, 0x00800000)); +#endif + hw.m_pMMIO = (smtc_RegBaseAddress = + smtc_VRAMBaseAddress + 0x00700000); + smtc_2DBaseAddress = (hw.m_pDPR = + smtc_VRAMBaseAddress + 0x00408000); + smtc_2Ddataport = smtc_VRAMBaseAddress + DE_DATA_PORT_712; + hw.m_pVPR = hw.m_pLFB + 0x0040c000; + if (sfb->fb.var.bits_per_pixel == 32) { +#ifdef __BIG_ENDIAN + smtc_VRAMBaseAddress += 0x800000; + hw.m_pLFB += 0x800000; + printk(KERN_INFO + "\nsmtc_VRAMBaseAddress=%p hw.m_pLFB=%p\n", + smtc_VRAMBaseAddress, hw.m_pLFB); +#endif + } + if (!smtc_RegBaseAddress) { + + printk(KERN_INFO + "%s: unable to map memory mapped IO\n", + sfb->fb.fix.id); + + return -ENOMEM; + } + + /* set MCLK = 14.31818 * (0x16 / 0x2) */ + smtc_seqw(0x6a, 0x16); + smtc_seqw(0x6b, 0x02); + smtc_seqw(0x62, 0x3e); + /* enable PCI burst */ + smtc_seqw(0x17, 0x20); + /* enabel word swap */ + if (sfb->fb.var.bits_per_pixel == 32) { +#ifdef __BIG_ENDIAN + smtc_seqw(0x17, 0x30); +#endif + } +#ifdef CONFIG_FB_SM7XX_ACCEL + smtc_2Dacceleration = 1; +#endif + + break; + + case 0x720: + sfb->fb.fix.mmio_start = pFramebufferPhysical; + sfb->fb.fix.mmio_len = 0x00200000; + smem_size = SM722_VIDEOMEMORYSIZE; + smtc_2DBaseAddress = (hw.m_pDPR = + ioremap(pFramebufferPhysical, 0x00a00000)); + hw.m_pLFB = (smtc_VRAMBaseAddress = + smtc_2DBaseAddress + 0x00200000); + hw.m_pMMIO = (smtc_RegBaseAddress = + smtc_2DBaseAddress + 0x000c0000); + smtc_2Ddataport = smtc_2DBaseAddress + DE_DATA_PORT_722; + hw.m_pVPR = smtc_2DBaseAddress + 0x800; + + smtc_seqw(0x62, 0xff); + smtc_seqw(0x6a, 0x0d); + smtc_seqw(0x6b, 0x02); + smtc_2Dacceleration = 0; + break; + default: + printk(KERN_INFO + "No valid Silicon Motion display chip was detected!\n"); + + smtc_free_fb_info(sfb); + return err; + } + + /* can support 32 bpp */ + if (15 == sfb->fb.var.bits_per_pixel) + sfb->fb.var.bits_per_pixel = 16; + + sfb->fb.var.xres_virtual = sfb->fb.var.xres; + + sfb->fb.var.yres_virtual = sfb->fb.var.yres; + err = smtc_map_smem(sfb, pdev, smem_size); + if (err) + goto failed; + + smtcfb_setmode(sfb); + /* Primary display starting from 0 postion */ + hw.BaseAddressInVRAM = 0; + sfb->fb.par = &hw; + + mutex_init(&sfb->fb.lock); + mutex_init(&sfb->fb.mm_lock); + + err = register_framebuffer(&sfb->fb); + if (err < 0) + goto failed; + + printk(KERN_INFO "Silicon Motion SM%X Rev%X primary display mode" + "%dx%d-%d Init Complete.\n", hw.chipID, hw.chipRevID, + sfb->fb.var.xres, sfb->fb.var.yres, + sfb->fb.var.bits_per_pixel); + +#if defined(CONFIG_FB_SM7XX_DUALHEAD) + smtc_head2_init(sfb); + err = register_framebuffer(&smtcfb_info2.fb); + + /* if second head display fails, also fails the primary display */ + if (err < 0) { + printk(KERN_INFO + "Silicon Motion, Inc. second head init fail\n"); + goto failed; + } + + printk(KERN_INFO "Silicon Motion SM%X Rev%X secondary display mode" + "%dx%d-%d Init Complete.\n", hw.chipID, hw.chipRevID, + hw2.width, hw2.height, + smtcfb_info2.fb.var.bits_per_pixel); +#endif + + return 0; + + failed: + printk(KERN_INFO "Silicon Motion, Inc. primary display init fail\n"); + + smtc_unmap_smem(sfb); + smtc_unmap_mmio(sfb); + smtc_free_fb_info(sfb); + + return err; +} + +static void __exit smtcfb_exit(void) +{ +} + +module_init(smtcfb_init); +module_exit(smtcfb_exit); + +/* + * sm712be_setup - process command line options + * @options: string of options + * Returns zero. + * + */ +static int __init sm712be_setup(char *options) +{ + sm712be_flag = 0; + if (!options || !*options) { + smdbg("\n No sm712be parameter\n"); + return -EINVAL; + } + if (strstr(options, "enable") != NULL) + sm712be_flag = 1; + + smdbg("\nsm712be_setup = %s sm712be_flag = %d\n", options, + sm712be_flag); + + return 0; +} + +__setup("sm712be=", sm712be_setup); + +/* + * sm712vga_setup - process command line options, get vga parameter + * @options: string of options + * Returns zero. + * + */ +static int __init sm712vga_setup(char *options) +{ + int index; + sm712be_flag = 0; + + if (!options || !*options) { + smdbg("\n No vga parameter\n"); + return -EINVAL; + } + + smtc_screen_info.lfb_width = 0; + smtc_screen_info.lfb_height = 0; + smtc_screen_info.lfb_depth = 0; + + smdbg("\nsm712vga_setup = %s\n", options); + + for (index = 0; + index < (sizeof(vesa_mode) / sizeof(struct vesa_mode_table)); + index++) { + if (strstr(options, vesa_mode[index].mode_index)) { + smtc_screen_info.lfb_width = vesa_mode[index].lfb_width; + smtc_screen_info.lfb_height = + vesa_mode[index].lfb_height; + smtc_screen_info.lfb_depth = vesa_mode[index].lfb_depth; + return 0; + } + } + + return -1; +} + +__setup("vga=", sm712vga_setup); + +MODULE_AUTHOR("Siliconmotion "); +MODULE_DESCRIPTION("Framebuffer driver for SMI Graphic Cards"); +MODULE_LICENSE("GPL"); diff -Nur linux-2.6.30.5.orig/drivers/video/sm7xx/smtcfb.h linux-2.6.30.5/drivers/video/sm7xx/smtcfb.h --- linux-2.6.30.5.orig/drivers/video/sm7xx/smtcfb.h 1970-01-01 01:00:00.000000000 +0100 +++ linux-2.6.30.5/drivers/video/sm7xx/smtcfb.h 2009-08-23 19:01:04.000000000 +0200 @@ -0,0 +1,793 @@ +/* + * smtcfb.h -- Silicon Motion SM7xx frame buffer device + * + * Copyright (C) 2006 Silicon Motion Technology Corp. + * Authors: Ge Wang, gewang@siliconmotion.com + * Boyod boyod.yang@siliconmotion.com.cn + * + * Copyright (C) 2009 Lemote, Inc. & Institute of Computing Technology + * Author: Wu Zhangjin, wuzj@lemote.com + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file COPYING in the main directory of this archive for + * more details. + */ + +#define SMTC_LINUX_FB_VERSION "version 0.11.2619.21.01 July 27, 2008" + +#define NR_PALETTE 256 +#define NR_RGB 2 + +#define FB_ACCEL_SMI_LYNX 88 + +#ifdef __BIG_ENDIAN +#define PC_VGA 0 +#else +#define PC_VGA 1 +#endif + +#define SCREEN_X_RES 1024 +#define SCREEN_Y_RES 600 +#define SCREEN_BPP 16 + +#ifndef FIELD_OFFSET +#define FIELD_OFSFET(type, field) \ + ((unsigned long) (PUCHAR) & (((type *)0)->field)) +#endif + +/*Assume SM712 graphics chip has 4MB VRAM */ +#define SM712_VIDEOMEMORYSIZE 0x00400000 +/*Assume SM722 graphics chip has 8MB VRAM */ +#define SM722_VIDEOMEMORYSIZE 0x00800000 + +#define dac_reg (0x3c8) +#define dac_val (0x3c9) + +extern char *smtc_RegBaseAddress; +#define smtc_mmiowb(dat, reg) writeb(dat, smtc_RegBaseAddress + reg) +#define smtc_mmioww(dat, reg) writew(dat, smtc_RegBaseAddress + reg) +#define smtc_mmiowl(dat, reg) writel(dat, smtc_RegBaseAddress + reg) + +#define smtc_mmiorb(reg) readb(smtc_RegBaseAddress + reg) +#define smtc_mmiorw(reg) readw(smtc_RegBaseAddress + reg) +#define smtc_mmiorl(reg) readl(smtc_RegBaseAddress + reg) + +#define SIZE_SR00_SR04 (0x04 - 0x00 + 1) +#define SIZE_SR10_SR24 (0x24 - 0x10 + 1) +#define SIZE_SR30_SR75 (0x75 - 0x30 + 1) +#define SIZE_SR80_SR93 (0x93 - 0x80 + 1) +#define SIZE_SRA0_SRAF (0xAF - 0xA0 + 1) +#define SIZE_GR00_GR08 (0x08 - 0x00 + 1) +#define SIZE_AR00_AR14 (0x14 - 0x00 + 1) +#define SIZE_CR00_CR18 (0x18 - 0x00 + 1) +#define SIZE_CR30_CR4D (0x4D - 0x30 + 1) +#define SIZE_CR90_CRA7 (0xA7 - 0x90 + 1) +#define SIZE_VPR (0x6C + 1) +#define SIZE_DPR (0x44 + 1) + +static inline void smtc_crtcw(int reg, int val) +{ + smtc_mmiowb(reg, 0x3d4); + smtc_mmiowb(val, 0x3d5); +} + +static inline unsigned int smtc_crtcr(int reg) +{ + smtc_mmiowb(reg, 0x3d4); + return smtc_mmiorb(0x3d5); +} + +static inline void smtc_grphw(int reg, int val) +{ + smtc_mmiowb(reg, 0x3ce); + smtc_mmiowb(val, 0x3cf); +} + +static inline unsigned int smtc_grphr(int reg) +{ + smtc_mmiowb(reg, 0x3ce); + return smtc_mmiorb(0x3cf); +} + +static inline void smtc_attrw(int reg, int val) +{ + smtc_mmiorb(0x3da); + smtc_mmiowb(reg, 0x3c0); + smtc_mmiorb(0x3c1); + smtc_mmiowb(val, 0x3c0); +} + +static inline void smtc_seqw(int reg, int val) +{ + smtc_mmiowb(reg, 0x3c4); + smtc_mmiowb(val, 0x3c5); +} + +static inline unsigned int smtc_seqr(int reg) +{ + smtc_mmiowb(reg, 0x3c4); + return smtc_mmiorb(0x3c5); +} + +/* The next structure holds all information relevant for a specific video mode. + */ + +struct ModeInit { + int mmSizeX; + int mmSizeY; + int bpp; + int hz; + unsigned char Init_MISC; + unsigned char Init_SR00_SR04[SIZE_SR00_SR04]; + unsigned char Init_SR10_SR24[SIZE_SR10_SR24]; + unsigned char Init_SR30_SR75[SIZE_SR30_SR75]; + unsigned char Init_SR80_SR93[SIZE_SR80_SR93]; + unsigned char Init_SRA0_SRAF[SIZE_SRA0_SRAF]; + unsigned char Init_GR00_GR08[SIZE_GR00_GR08]; + unsigned char Init_AR00_AR14[SIZE_AR00_AR14]; + unsigned char Init_CR00_CR18[SIZE_CR00_CR18]; + unsigned char Init_CR30_CR4D[SIZE_CR30_CR4D]; + unsigned char Init_CR90_CRA7[SIZE_CR90_CRA7]; +}; + +/********************************************************************** + SM712 Mode table. + **********************************************************************/ +struct ModeInit VGAMode[] = { + { + /* mode#0: 640 x 480 16Bpp 60Hz */ + 640, 480, 16, 60, + /* Init_MISC */ + 0xE3, + { /* Init_SR0_SR4 */ + 0x03, 0x01, 0x0F, 0x00, 0x0E, + }, + { /* Init_SR10_SR24 */ + 0xFF, 0xBE, 0xEF, 0xFF, 0x00, 0x0E, 0x17, 0x2C, + 0x99, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xC4, 0x30, 0x02, 0x01, 0x01, + }, + { /* Init_SR30_SR75 */ + 0x32, 0x03, 0xA0, 0x09, 0xC0, 0x32, 0x32, 0x32, + 0x32, 0x32, 0x32, 0x32, 0x00, 0x00, 0x03, 0xFF, + 0x00, 0xFC, 0x00, 0x00, 0x20, 0x18, 0x00, 0xFC, + 0x20, 0x0C, 0x44, 0x20, 0x00, 0x32, 0x32, 0x32, + 0x04, 0x24, 0x63, 0x4F, 0x52, 0x0B, 0xDF, 0xEA, + 0x04, 0x50, 0x19, 0x32, 0x32, 0x00, 0x00, 0x32, + 0x01, 0x80, 0x7E, 0x1A, 0x1A, 0x00, 0x00, 0x00, + 0x50, 0x03, 0x74, 0x14, 0x07, 0x82, 0x07, 0x04, + 0x00, 0x45, 0x30, 0x30, 0x40, 0x30, + }, + { /* Init_SR80_SR93 */ + 0xFF, 0x07, 0x00, 0x6F, 0x7F, 0x7F, 0xFF, 0x32, + 0xF7, 0x00, 0x00, 0x00, 0xEF, 0xFF, 0x32, 0x32, + 0x00, 0x00, 0x00, 0x00, + }, + { /* Init_SRA0_SRAF */ + 0x00, 0xFF, 0xBF, 0xFF, 0xFF, 0xED, 0xED, 0xED, + 0x7B, 0xFF, 0xFF, 0xFF, 0xBF, 0xEF, 0xFF, 0xDF, + }, + { /* Init_GR00_GR08 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x05, 0x0F, + 0xFF, + }, + { /* Init_AR00_AR14 */ + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, + 0x41, 0x00, 0x0F, 0x00, 0x00, + }, + { /* Init_CR00_CR18 */ + 0x5F, 0x4F, 0x4F, 0x00, 0x53, 0x1F, 0x0B, 0x3E, + 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xEA, 0x0C, 0xDF, 0x50, 0x40, 0xDF, 0x00, 0xE3, + 0xFF, + }, + { /* Init_CR30_CR4D */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x55, 0x03, 0x20, + 0x00, 0x00, 0x00, 0x40, 0x00, 0xE7, 0xFF, 0xFD, + 0x5F, 0x4F, 0x00, 0x54, 0x00, 0x0B, 0xDF, 0x00, + 0xEA, 0x0C, 0x2E, 0x00, 0x4F, 0xDF, + }, + { /* Init_CR90_CRA7 */ + 0x56, 0xDD, 0x5E, 0xEA, 0x87, 0x44, 0x8F, 0x55, + 0x0A, 0x8F, 0x55, 0x0A, 0x00, 0x00, 0x18, 0x00, + 0x11, 0x10, 0x0B, 0x0A, 0x0A, 0x0A, 0x0A, 0x00, + }, + }, + { + /* mode#1: 640 x 480 24Bpp 60Hz */ + 640, 480, 24, 60, + /* Init_MISC */ + 0xE3, + { /* Init_SR0_SR4 */ + 0x03, 0x01, 0x0F, 0x00, 0x0E, + }, + { /* Init_SR10_SR24 */ + 0xFF, 0xBE, 0xEF, 0xFF, 0x00, 0x0E, 0x17, 0x2C, + 0x99, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xC4, 0x30, 0x02, 0x01, 0x01, + }, + { /* Init_SR30_SR75 */ + 0x32, 0x03, 0xA0, 0x09, 0xC0, 0x32, 0x32, 0x32, + 0x32, 0x32, 0x32, 0x32, 0x00, 0x00, 0x03, 0xFF, + 0x00, 0xFC, 0x00, 0x00, 0x20, 0x18, 0x00, 0xFC, + 0x20, 0x0C, 0x44, 0x20, 0x00, 0x32, 0x32, 0x32, + 0x04, 0x24, 0x63, 0x4F, 0x52, 0x0B, 0xDF, 0xEA, + 0x04, 0x50, 0x19, 0x32, 0x32, 0x00, 0x00, 0x32, + 0x01, 0x80, 0x7E, 0x1A, 0x1A, 0x00, 0x00, 0x00, + 0x50, 0x03, 0x74, 0x14, 0x07, 0x82, 0x07, 0x04, + 0x00, 0x45, 0x30, 0x30, 0x40, 0x30, + }, + { /* Init_SR80_SR93 */ + 0xFF, 0x07, 0x00, 0x6F, 0x7F, 0x7F, 0xFF, 0x32, + 0xF7, 0x00, 0x00, 0x00, 0xEF, 0xFF, 0x32, 0x32, + 0x00, 0x00, 0x00, 0x00, + }, + { /* Init_SRA0_SRAF */ + 0x00, 0xFF, 0xBF, 0xFF, 0xFF, 0xED, 0xED, 0xED, + 0x7B, 0xFF, 0xFF, 0xFF, 0xBF, 0xEF, 0xFF, 0xDF, + }, + { /* Init_GR00_GR08 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x05, 0x0F, + 0xFF, + }, + { /* Init_AR00_AR14 */ + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, + 0x41, 0x00, 0x0F, 0x00, 0x00, + }, + { /* Init_CR00_CR18 */ + 0x5F, 0x4F, 0x4F, 0x00, 0x53, 0x1F, 0x0B, 0x3E, + 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xEA, 0x0C, 0xDF, 0x50, 0x40, 0xDF, 0x00, 0xE3, + 0xFF, + }, + { /* Init_CR30_CR4D */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x55, 0x03, 0x20, + 0x00, 0x00, 0x00, 0x40, 0x00, 0xE7, 0xFF, 0xFD, + 0x5F, 0x4F, 0x00, 0x54, 0x00, 0x0B, 0xDF, 0x00, + 0xEA, 0x0C, 0x2E, 0x00, 0x4F, 0xDF, + }, + { /* Init_CR90_CRA7 */ + 0x56, 0xDD, 0x5E, 0xEA, 0x87, 0x44, 0x8F, 0x55, + 0x0A, 0x8F, 0x55, 0x0A, 0x00, 0x00, 0x18, 0x00, + 0x11, 0x10, 0x0B, 0x0A, 0x0A, 0x0A, 0x0A, 0x00, + }, + }, + { + /* mode#0: 640 x 480 32Bpp 60Hz */ + 640, 480, 32, 60, + /* Init_MISC */ + 0xE3, + { /* Init_SR0_SR4 */ + 0x03, 0x01, 0x0F, 0x00, 0x0E, + }, + { /* Init_SR10_SR24 */ + 0xFF, 0xBE, 0xEF, 0xFF, 0x00, 0x0E, 0x17, 0x2C, + 0x99, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xC4, 0x30, 0x02, 0x01, 0x01, + }, + { /* Init_SR30_SR75 */ + 0x32, 0x03, 0xA0, 0x09, 0xC0, 0x32, 0x32, 0x32, + 0x32, 0x32, 0x32, 0x32, 0x00, 0x00, 0x03, 0xFF, + 0x00, 0xFC, 0x00, 0x00, 0x20, 0x18, 0x00, 0xFC, + 0x20, 0x0C, 0x44, 0x20, 0x00, 0x32, 0x32, 0x32, + 0x04, 0x24, 0x63, 0x4F, 0x52, 0x0B, 0xDF, 0xEA, + 0x04, 0x50, 0x19, 0x32, 0x32, 0x00, 0x00, 0x32, + 0x01, 0x80, 0x7E, 0x1A, 0x1A, 0x00, 0x00, 0x00, + 0x50, 0x03, 0x74, 0x14, 0x07, 0x82, 0x07, 0x04, + 0x00, 0x45, 0x30, 0x30, 0x40, 0x30, + }, + { /* Init_SR80_SR93 */ + 0xFF, 0x07, 0x00, 0x6F, 0x7F, 0x7F, 0xFF, 0x32, + 0xF7, 0x00, 0x00, 0x00, 0xEF, 0xFF, 0x32, 0x32, + 0x00, 0x00, 0x00, 0x00, + }, + { /* Init_SRA0_SRAF */ + 0x00, 0xFF, 0xBF, 0xFF, 0xFF, 0xED, 0xED, 0xED, + 0x7B, 0xFF, 0xFF, 0xFF, 0xBF, 0xEF, 0xFF, 0xDF, + }, + { /* Init_GR00_GR08 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x05, 0x0F, + 0xFF, + }, + { /* Init_AR00_AR14 */ + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, + 0x41, 0x00, 0x0F, 0x00, 0x00, + }, + { /* Init_CR00_CR18 */ + 0x5F, 0x4F, 0x4F, 0x00, 0x53, 0x1F, 0x0B, 0x3E, + 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xEA, 0x0C, 0xDF, 0x50, 0x40, 0xDF, 0x00, 0xE3, + 0xFF, + }, + { /* Init_CR30_CR4D */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x55, 0x03, 0x20, + 0x00, 0x00, 0x00, 0x40, 0x00, 0xE7, 0xFF, 0xFD, + 0x5F, 0x4F, 0x00, 0x54, 0x00, 0x0B, 0xDF, 0x00, + 0xEA, 0x0C, 0x2E, 0x00, 0x4F, 0xDF, + }, + { /* Init_CR90_CRA7 */ + 0x56, 0xDD, 0x5E, 0xEA, 0x87, 0x44, 0x8F, 0x55, + 0x0A, 0x8F, 0x55, 0x0A, 0x00, 0x00, 0x18, 0x00, + 0x11, 0x10, 0x0B, 0x0A, 0x0A, 0x0A, 0x0A, 0x00, + }, + }, + + { /* mode#2: 800 x 600 16Bpp 60Hz */ + 800, 600, 16, 60, + /* Init_MISC */ + 0x2B, + { /* Init_SR0_SR4 */ + 0x03, 0x01, 0x0F, 0x03, 0x0E, + }, + { /* Init_SR10_SR24 */ + 0xFF, 0xBE, 0xEE, 0xFF, 0x00, 0x0E, 0x17, 0x2C, + 0x99, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xC4, 0x30, 0x02, 0x01, 0x01, + }, + { /* Init_SR30_SR75 */ + 0x34, 0x03, 0x20, 0x09, 0xC0, 0x24, 0x24, 0x24, + 0x24, 0x24, 0x24, 0x24, 0x00, 0x00, 0x03, 0xFF, + 0x00, 0xFC, 0x00, 0x00, 0x20, 0x38, 0x00, 0xFC, + 0x20, 0x0C, 0x44, 0x20, 0x00, 0x24, 0x24, 0x24, + 0x04, 0x48, 0x83, 0x63, 0x68, 0x72, 0x57, 0x58, + 0x04, 0x55, 0x59, 0x24, 0x24, 0x00, 0x00, 0x24, + 0x01, 0x80, 0x7A, 0x1A, 0x1A, 0x00, 0x00, 0x00, + 0x50, 0x03, 0x74, 0x14, 0x1C, 0x85, 0x35, 0x13, + 0x02, 0x45, 0x30, 0x35, 0x40, 0x20, + }, + { /* Init_SR80_SR93 */ + 0x00, 0x00, 0x00, 0x6F, 0x7F, 0x7F, 0xFF, 0x24, + 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x24, 0x24, + 0x00, 0x00, 0x00, 0x00, + }, + { /* Init_SRA0_SRAF */ + 0x00, 0xFF, 0xBF, 0xFF, 0xFF, 0xED, 0xED, 0xED, + 0x7B, 0xFF, 0xFF, 0xFF, 0xBF, 0xEF, 0xBF, 0xDF, + }, + { /* Init_GR00_GR08 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x05, 0x0F, + 0xFF, + }, + { /* Init_AR00_AR14 */ + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, + 0x41, 0x00, 0x0F, 0x00, 0x00, + }, + { /* Init_CR00_CR18 */ + 0x7F, 0x63, 0x63, 0x00, 0x68, 0x18, 0x72, 0xF0, + 0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x58, 0x0C, 0x57, 0x64, 0x40, 0x57, 0x00, 0xE3, + 0xFF, + }, + { /* Init_CR30_CR4D */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x33, 0x03, 0x20, + 0x00, 0x00, 0x00, 0x40, 0x00, 0xE7, 0xBF, 0xFD, + 0x7F, 0x63, 0x00, 0x69, 0x18, 0x72, 0x57, 0x00, + 0x58, 0x0C, 0xE0, 0x20, 0x63, 0x57, + }, + { /* Init_CR90_CRA7 */ + 0x56, 0x4B, 0x5E, 0x55, 0x86, 0x9D, 0x8E, 0xAA, + 0xDB, 0x2A, 0xDF, 0x33, 0x00, 0x00, 0x18, 0x00, + 0x20, 0x1F, 0x1A, 0x19, 0x0F, 0x0F, 0x0F, 0x00, + }, + }, + { /* mode#3: 800 x 600 24Bpp 60Hz */ + 800, 600, 24, 60, + 0x2B, + { /* Init_SR0_SR4 */ + 0x03, 0x01, 0x0F, 0x03, 0x0E, + }, + { /* Init_SR10_SR24 */ + 0xFF, 0xBE, 0xEE, 0xFF, 0x00, 0x0E, 0x17, 0x2C, + 0x99, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xC4, 0x30, 0x02, 0x01, 0x01, + }, + { /* Init_SR30_SR75 */ + 0x36, 0x03, 0x20, 0x09, 0xC0, 0x36, 0x36, 0x36, + 0x36, 0x36, 0x36, 0x36, 0x00, 0x00, 0x03, 0xFF, + 0x00, 0xFC, 0x00, 0x00, 0x20, 0x18, 0x00, 0xFC, + 0x20, 0x0C, 0x44, 0x20, 0x00, 0x36, 0x36, 0x36, + 0x04, 0x48, 0x83, 0x63, 0x68, 0x72, 0x57, 0x58, + 0x04, 0x55, 0x59, 0x36, 0x36, 0x00, 0x00, 0x36, + 0x01, 0x80, 0x7E, 0x1A, 0x1A, 0x00, 0x00, 0x00, + 0x50, 0x03, 0x74, 0x14, 0x1C, 0x85, 0x35, 0x13, + 0x02, 0x45, 0x30, 0x30, 0x40, 0x20, + }, + { /* Init_SR80_SR93 */ + 0xFF, 0x07, 0x00, 0x6F, 0x7F, 0x7F, 0xFF, 0x36, + 0xF7, 0x00, 0x00, 0x00, 0xEF, 0xFF, 0x36, 0x36, + 0x00, 0x00, 0x00, 0x00, + }, + { /* Init_SRA0_SRAF */ + 0x00, 0xFF, 0xBF, 0xFF, 0xFF, 0xED, 0xED, 0xED, + 0x7B, 0xFF, 0xFF, 0xFF, 0xBF, 0xEF, 0xBF, 0xDF, + }, + { /* Init_GR00_GR08 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x05, 0x0F, + 0xFF, + }, + { /* Init_AR00_AR14 */ + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, + 0x41, 0x00, 0x0F, 0x00, 0x00, + }, + { /* Init_CR00_CR18 */ + 0x7F, 0x63, 0x63, 0x00, 0x68, 0x18, 0x72, 0xF0, + 0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x58, 0x0C, 0x57, 0x64, 0x40, 0x57, 0x00, 0xE3, + 0xFF, + }, + { /* Init_CR30_CR4D */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x33, 0x03, 0x20, + 0x00, 0x00, 0x00, 0x40, 0x00, 0xE7, 0xBF, 0xFD, + 0x7F, 0x63, 0x00, 0x69, 0x18, 0x72, 0x57, 0x00, + 0x58, 0x0C, 0xE0, 0x20, 0x63, 0x57, + }, + { /* Init_CR90_CRA7 */ + 0x56, 0x4B, 0x5E, 0x55, 0x86, 0x9D, 0x8E, 0xAA, + 0xDB, 0x2A, 0xDF, 0x33, 0x00, 0x00, 0x18, 0x00, + 0x20, 0x1F, 0x1A, 0x19, 0x0F, 0x0F, 0x0F, 0x00, + }, + }, + { /* mode#7: 800 x 600 32Bpp 60Hz */ + 800, 600, 32, 60, + /* Init_MISC */ + 0x2B, + { /* Init_SR0_SR4 */ + 0x03, 0x01, 0x0F, 0x03, 0x0E, + }, + { /* Init_SR10_SR24 */ + 0xFF, 0xBE, 0xEE, 0xFF, 0x00, 0x0E, 0x17, 0x2C, + 0x99, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xC4, 0x30, 0x02, 0x01, 0x01, + }, + { /* Init_SR30_SR75 */ + 0x34, 0x03, 0x20, 0x09, 0xC0, 0x24, 0x24, 0x24, + 0x24, 0x24, 0x24, 0x24, 0x00, 0x00, 0x03, 0xFF, + 0x00, 0xFC, 0x00, 0x00, 0x20, 0x38, 0x00, 0xFC, + 0x20, 0x0C, 0x44, 0x20, 0x00, 0x24, 0x24, 0x24, + 0x04, 0x48, 0x83, 0x63, 0x68, 0x72, 0x57, 0x58, + 0x04, 0x55, 0x59, 0x24, 0x24, 0x00, 0x00, 0x24, + 0x01, 0x80, 0x7A, 0x1A, 0x1A, 0x00, 0x00, 0x00, + 0x50, 0x03, 0x74, 0x14, 0x1C, 0x85, 0x35, 0x13, + 0x02, 0x45, 0x30, 0x35, 0x40, 0x20, + }, + { /* Init_SR80_SR93 */ + 0x00, 0x00, 0x00, 0x6F, 0x7F, 0x7F, 0xFF, 0x24, + 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x24, 0x24, + 0x00, 0x00, 0x00, 0x00, + }, + { /* Init_SRA0_SRAF */ + 0x00, 0xFF, 0xBF, 0xFF, 0xFF, 0xED, 0xED, 0xED, + 0x7B, 0xFF, 0xFF, 0xFF, 0xBF, 0xEF, 0xBF, 0xDF, + }, + { /* Init_GR00_GR08 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x05, 0x0F, + 0xFF, + }, + { /* Init_AR00_AR14 */ + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, + 0x41, 0x00, 0x0F, 0x00, 0x00, + }, + { /* Init_CR00_CR18 */ + 0x7F, 0x63, 0x63, 0x00, 0x68, 0x18, 0x72, 0xF0, + 0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x58, 0x0C, 0x57, 0x64, 0x40, 0x57, 0x00, 0xE3, + 0xFF, + }, + { /* Init_CR30_CR4D */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x33, 0x03, 0x20, + 0x00, 0x00, 0x00, 0x40, 0x00, 0xE7, 0xBF, 0xFD, + 0x7F, 0x63, 0x00, 0x69, 0x18, 0x72, 0x57, 0x00, + 0x58, 0x0C, 0xE0, 0x20, 0x63, 0x57, + }, + { /* Init_CR90_CRA7 */ + 0x56, 0x4B, 0x5E, 0x55, 0x86, 0x9D, 0x8E, 0xAA, + 0xDB, 0x2A, 0xDF, 0x33, 0x00, 0x00, 0x18, 0x00, + 0x20, 0x1F, 0x1A, 0x19, 0x0F, 0x0F, 0x0F, 0x00, + }, + }, + /* We use 1024x768 table to light 1024x600 panel for lemote */ + { /* mode#4: 1024 x 600 16Bpp 60Hz */ + 1024, 600, 16, 60, + /* Init_MISC */ + 0xEB, + { /* Init_SR0_SR4 */ + 0x03, 0x01, 0x0F, 0x00, 0x0E, + }, + { /* Init_SR10_SR24 */ + 0xC8, 0x40, 0x14, 0x60, 0x00, 0x0A, 0x17, 0x20, + 0x51, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xC4, 0x30, 0x02, 0x00, 0x01, + }, + { /* Init_SR30_SR75 */ + 0x22, 0x03, 0x24, 0x09, 0xC0, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x00, 0x00, 0x03, 0xFF, + 0x00, 0xFC, 0x00, 0x00, 0x20, 0x18, 0x00, 0xFC, + 0x20, 0x0C, 0x44, 0x20, 0x00, 0x22, 0x22, 0x22, + 0x06, 0x68, 0xA7, 0x7F, 0x83, 0x24, 0xFF, 0x03, + 0x00, 0x60, 0x59, 0x22, 0x22, 0x00, 0x00, 0x22, + 0x01, 0x80, 0x7A, 0x1A, 0x1A, 0x00, 0x00, 0x00, + 0x50, 0x03, 0x16, 0x02, 0x0D, 0x82, 0x09, 0x02, + 0x04, 0x45, 0x3F, 0x30, 0x40, 0x20, + }, + { /* Init_SR80_SR93 */ + 0xFF, 0x07, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x3A, + 0xF7, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x3A, 0x3A, + 0x00, 0x00, 0x00, 0x00, + }, + { /* Init_SRA0_SRAF */ + 0x00, 0xFB, 0x9F, 0x01, 0x00, 0xED, 0xED, 0xED, + 0x7B, 0xFB, 0xFF, 0xFF, 0x97, 0xEF, 0xBF, 0xDF, + }, + { /* Init_GR00_GR08 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x05, 0x0F, + 0xFF, + }, + { /* Init_AR00_AR14 */ + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, + 0x41, 0x00, 0x0F, 0x00, 0x00, + }, + { /* Init_CR00_CR18 */ + 0xA3, 0x7F, 0x7F, 0x00, 0x85, 0x16, 0x24, 0xF5, + 0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x03, 0x09, 0xFF, 0x80, 0x40, 0xFF, 0x00, 0xE3, + 0xFF, + }, + { /* Init_CR30_CR4D */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x02, 0x20, + 0x00, 0x00, 0x00, 0x40, 0x00, 0xFF, 0xBF, 0xFF, + 0xA3, 0x7F, 0x00, 0x82, 0x0b, 0x6f, 0x57, 0x00, + 0x5c, 0x0f, 0xE0, 0xe0, 0x7F, 0x57, + }, + { /* Init_CR90_CRA7 */ + 0x55, 0xD9, 0x5D, 0xE1, 0x86, 0x1B, 0x8E, 0x26, + 0xDA, 0x8D, 0xDE, 0x94, 0x00, 0x00, 0x18, 0x00, + 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x15, 0x03, + }, + }, + { /* mode#5: 1024 x 768 24Bpp 60Hz */ + 1024, 768, 24, 60, + /* Init_MISC */ + 0xEB, + { /* Init_SR0_SR4 */ + 0x03, 0x01, 0x0F, 0x03, 0x0E, + }, + { /* Init_SR10_SR24 */ + 0xF3, 0xB6, 0xC0, 0xDD, 0x00, 0x0E, 0x17, 0x2C, + 0x99, 0x02, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xC4, 0x30, 0x02, 0x01, 0x01, + }, + { /* Init_SR30_SR75 */ + 0x38, 0x03, 0x20, 0x09, 0xC0, 0x3A, 0x3A, 0x3A, + 0x3A, 0x3A, 0x3A, 0x3A, 0x00, 0x00, 0x03, 0xFF, + 0x00, 0xFC, 0x00, 0x00, 0x20, 0x18, 0x00, 0xFC, + 0x20, 0x0C, 0x44, 0x20, 0x00, 0x00, 0x00, 0x3A, + 0x06, 0x68, 0xA7, 0x7F, 0x83, 0x24, 0xFF, 0x03, + 0x00, 0x60, 0x59, 0x3A, 0x3A, 0x00, 0x00, 0x3A, + 0x01, 0x80, 0x7E, 0x1A, 0x1A, 0x00, 0x00, 0x00, + 0x50, 0x03, 0x74, 0x14, 0x3B, 0x0D, 0x09, 0x02, + 0x04, 0x45, 0x30, 0x30, 0x40, 0x20, + }, + { /* Init_SR80_SR93 */ + 0xFF, 0x07, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x3A, + 0xF7, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x3A, 0x3A, + 0x00, 0x00, 0x00, 0x00, + }, + { /* Init_SRA0_SRAF */ + 0x00, 0xFB, 0x9F, 0x01, 0x00, 0xED, 0xED, 0xED, + 0x7B, 0xFB, 0xFF, 0xFF, 0x97, 0xEF, 0xBF, 0xDF, + }, + { /* Init_GR00_GR08 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x05, 0x0F, + 0xFF, + }, + { /* Init_AR00_AR14 */ + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, + 0x41, 0x00, 0x0F, 0x00, 0x00, + }, + { /* Init_CR00_CR18 */ + 0xA3, 0x7F, 0x7F, 0x00, 0x85, 0x16, 0x24, 0xF5, + 0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x03, 0x09, 0xFF, 0x80, 0x40, 0xFF, 0x00, 0xE3, + 0xFF, + }, + { /* Init_CR30_CR4D */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x02, 0x20, + 0x00, 0x00, 0x00, 0x40, 0x00, 0xFF, 0xBF, 0xFF, + 0xA3, 0x7F, 0x00, 0x86, 0x15, 0x24, 0xFF, 0x00, + 0x01, 0x07, 0xE5, 0x20, 0x7F, 0xFF, + }, + { /* Init_CR90_CRA7 */ + 0x55, 0xD9, 0x5D, 0xE1, 0x86, 0x1B, 0x8E, 0x26, + 0xDA, 0x8D, 0xDE, 0x94, 0x00, 0x00, 0x18, 0x00, + 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x15, 0x03, + }, + }, + { /* mode#4: 1024 x 768 32Bpp 60Hz */ + 1024, 768, 32, 60, + /* Init_MISC */ + 0xEB, + { /* Init_SR0_SR4 */ + 0x03, 0x01, 0x0F, 0x03, 0x0E, + }, + { /* Init_SR10_SR24 */ + 0xF3, 0xB6, 0xC0, 0xDD, 0x00, 0x0E, 0x17, 0x2C, + 0x99, 0x02, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xC4, 0x32, 0x02, 0x01, 0x01, + }, + { /* Init_SR30_SR75 */ + 0x38, 0x03, 0x20, 0x09, 0xC0, 0x3A, 0x3A, 0x3A, + 0x3A, 0x3A, 0x3A, 0x3A, 0x00, 0x00, 0x03, 0xFF, + 0x00, 0xFC, 0x00, 0x00, 0x20, 0x18, 0x00, 0xFC, + 0x20, 0x0C, 0x44, 0x20, 0x00, 0x00, 0x00, 0x3A, + 0x06, 0x68, 0xA7, 0x7F, 0x83, 0x24, 0xFF, 0x03, + 0x00, 0x60, 0x59, 0x3A, 0x3A, 0x00, 0x00, 0x3A, + 0x01, 0x80, 0x7E, 0x1A, 0x1A, 0x00, 0x00, 0x00, + 0x50, 0x03, 0x74, 0x14, 0x3B, 0x0D, 0x09, 0x02, + 0x04, 0x45, 0x30, 0x30, 0x40, 0x20, + }, + { /* Init_SR80_SR93 */ + 0xFF, 0x07, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x3A, + 0xF7, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x3A, 0x3A, + 0x00, 0x00, 0x00, 0x00, + }, + { /* Init_SRA0_SRAF */ + 0x00, 0xFB, 0x9F, 0x01, 0x00, 0xED, 0xED, 0xED, + 0x7B, 0xFB, 0xFF, 0xFF, 0x97, 0xEF, 0xBF, 0xDF, + }, + { /* Init_GR00_GR08 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x05, 0x0F, + 0xFF, + }, + { /* Init_AR00_AR14 */ + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, + 0x41, 0x00, 0x0F, 0x00, 0x00, + }, + { /* Init_CR00_CR18 */ + 0xA3, 0x7F, 0x7F, 0x00, 0x85, 0x16, 0x24, 0xF5, + 0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x03, 0x09, 0xFF, 0x80, 0x40, 0xFF, 0x00, 0xE3, + 0xFF, + }, + { /* Init_CR30_CR4D */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x02, 0x20, + 0x00, 0x00, 0x00, 0x40, 0x00, 0xFF, 0xBF, 0xFF, + 0xA3, 0x7F, 0x00, 0x86, 0x15, 0x24, 0xFF, 0x00, + 0x01, 0x07, 0xE5, 0x20, 0x7F, 0xFF, + }, + { /* Init_CR90_CRA7 */ + 0x55, 0xD9, 0x5D, 0xE1, 0x86, 0x1B, 0x8E, 0x26, + 0xDA, 0x8D, 0xDE, 0x94, 0x00, 0x00, 0x18, 0x00, + 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x15, 0x03, + }, + }, + { /* mode#6: 320 x 240 16Bpp 60Hz */ + 320, 240, 16, 60, + /* Init_MISC */ + 0xEB, + { /* Init_SR0_SR4 */ + 0x03, 0x01, 0x0F, 0x03, 0x0E, + }, + { /* Init_SR10_SR24 */ + 0xF3, 0xB6, 0xC0, 0xDD, 0x00, 0x0E, 0x17, 0x2C, + 0x99, 0x02, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xC4, 0x32, 0x02, 0x01, 0x01, + }, + { /* Init_SR30_SR75 */ + 0x38, 0x03, 0x20, 0x09, 0xC0, 0x3A, 0x3A, 0x3A, + 0x3A, 0x3A, 0x3A, 0x3A, 0x00, 0x00, 0x03, 0xFF, + 0x00, 0xFC, 0x00, 0x00, 0x20, 0x18, 0x00, 0xFC, + 0x20, 0x0C, 0x44, 0x20, 0x00, 0x00, 0x00, 0x3A, + 0x06, 0x68, 0xA7, 0x7F, 0x83, 0x24, 0xFF, 0x03, + 0x00, 0x60, 0x59, 0x3A, 0x3A, 0x00, 0x00, 0x3A, + 0x01, 0x80, 0x7E, 0x1A, 0x1A, 0x00, 0x00, 0x00, + 0x50, 0x03, 0x74, 0x14, 0x08, 0x43, 0x08, 0x43, + 0x04, 0x45, 0x30, 0x30, 0x40, 0x20, + }, + { /* Init_SR80_SR93 */ + 0xFF, 0x07, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x3A, + 0xF7, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x3A, 0x3A, + 0x00, 0x00, 0x00, 0x00, + }, + { /* Init_SRA0_SRAF */ + 0x00, 0xFB, 0x9F, 0x01, 0x00, 0xED, 0xED, 0xED, + 0x7B, 0xFB, 0xFF, 0xFF, 0x97, 0xEF, 0xBF, 0xDF, + }, + { /* Init_GR00_GR08 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x05, 0x0F, + 0xFF, + }, + { /* Init_AR00_AR14 */ + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, + 0x41, 0x00, 0x0F, 0x00, 0x00, + }, + { /* Init_CR00_CR18 */ + 0xA3, 0x7F, 0x7F, 0x00, 0x85, 0x16, 0x24, 0xF5, + 0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x03, 0x09, 0xFF, 0x80, 0x40, 0xFF, 0x00, 0xE3, + 0xFF, + }, + { /* Init_CR30_CR4D */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x02, 0x20, + 0x00, 0x00, 0x30, 0x40, 0x00, 0xFF, 0xBF, 0xFF, + 0x2E, 0x27, 0x00, 0x2b, 0x0c, 0x0F, 0xEF, 0x00, + 0xFe, 0x0f, 0x01, 0xC0, 0x27, 0xEF, + }, + { /* Init_CR90_CRA7 */ + 0x55, 0xD9, 0x5D, 0xE1, 0x86, 0x1B, 0x8E, 0x26, + 0xDA, 0x8D, 0xDE, 0x94, 0x00, 0x00, 0x18, 0x00, + 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x15, 0x03, + }, + }, + + { /* mode#8: 320 x 240 32Bpp 60Hz */ + 320, 240, 32, 60, + /* Init_MISC */ + 0xEB, + { /* Init_SR0_SR4 */ + 0x03, 0x01, 0x0F, 0x03, 0x0E, + }, + { /* Init_SR10_SR24 */ + 0xF3, 0xB6, 0xC0, 0xDD, 0x00, 0x0E, 0x17, 0x2C, + 0x99, 0x02, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xC4, 0x32, 0x02, 0x01, 0x01, + }, + { /* Init_SR30_SR75 */ + 0x38, 0x03, 0x20, 0x09, 0xC0, 0x3A, 0x3A, 0x3A, + 0x3A, 0x3A, 0x3A, 0x3A, 0x00, 0x00, 0x03, 0xFF, + 0x00, 0xFC, 0x00, 0x00, 0x20, 0x18, 0x00, 0xFC, + 0x20, 0x0C, 0x44, 0x20, 0x00, 0x00, 0x00, 0x3A, + 0x06, 0x68, 0xA7, 0x7F, 0x83, 0x24, 0xFF, 0x03, + 0x00, 0x60, 0x59, 0x3A, 0x3A, 0x00, 0x00, 0x3A, + 0x01, 0x80, 0x7E, 0x1A, 0x1A, 0x00, 0x00, 0x00, + 0x50, 0x03, 0x74, 0x14, 0x08, 0x43, 0x08, 0x43, + 0x04, 0x45, 0x30, 0x30, 0x40, 0x20, + }, + { /* Init_SR80_SR93 */ + 0xFF, 0x07, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x3A, + 0xF7, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x3A, 0x3A, + 0x00, 0x00, 0x00, 0x00, + }, + { /* Init_SRA0_SRAF */ + 0x00, 0xFB, 0x9F, 0x01, 0x00, 0xED, 0xED, 0xED, + 0x7B, 0xFB, 0xFF, 0xFF, 0x97, 0xEF, 0xBF, 0xDF, + }, + { /* Init_GR00_GR08 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x05, 0x0F, + 0xFF, + }, + { /* Init_AR00_AR14 */ + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, + 0x41, 0x00, 0x0F, 0x00, 0x00, + }, + { /* Init_CR00_CR18 */ + 0xA3, 0x7F, 0x7F, 0x00, 0x85, 0x16, 0x24, 0xF5, + 0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x03, 0x09, 0xFF, 0x80, 0x40, 0xFF, 0x00, 0xE3, + 0xFF, + }, + { /* Init_CR30_CR4D */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x02, 0x20, + 0x00, 0x00, 0x30, 0x40, 0x00, 0xFF, 0xBF, 0xFF, + 0x2E, 0x27, 0x00, 0x2b, 0x0c, 0x0F, 0xEF, 0x00, + 0xFe, 0x0f, 0x01, 0xC0, 0x27, 0xEF, + }, + { /* Init_CR90_CRA7 */ + 0x55, 0xD9, 0x5D, 0xE1, 0x86, 0x1B, 0x8E, 0x26, + 0xDA, 0x8D, 0xDE, 0x94, 0x00, 0x00, 0x18, 0x00, + 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x15, 0x03, + }, + }, +}; + +#define numVGAModes (sizeof(VGAMode) / sizeof(struct ModeInit)) diff -Nur linux-2.6.30.5.orig/include/linux/fb.h linux-2.6.30.5/include/linux/fb.h --- linux-2.6.30.5.orig/include/linux/fb.h 2009-08-16 23:19:38.000000000 +0200 +++ linux-2.6.30.5/include/linux/fb.h 2009-08-23 19:01:04.000000000 +0200 @@ -814,6 +814,7 @@ int node; int flags; struct mutex lock; /* Lock for open/release/ioctl funcs */ + struct mutex mm_lock; /* Lock for fb_mmap and smem_* fields */ struct fb_var_screeninfo var; /* Current var */ struct fb_fix_screeninfo fix; /* Current fix */ struct fb_monspecs monspecs; /* Current Monitor specs */ diff -Nur linux-2.6.30.5.orig/sound/core/pcm_native.c linux-2.6.30.5/sound/core/pcm_native.c --- linux-2.6.30.5.orig/sound/core/pcm_native.c 2009-08-16 23:19:38.000000000 +0200 +++ linux-2.6.30.5/sound/core/pcm_native.c 2009-08-23 19:01:04.000000000 +0200 @@ -3091,7 +3091,11 @@ return VM_FAULT_SIGBUS; } else { vaddr = runtime->dma_area + offset; +#if defined(__mips__) && defined(CONFIG_DMA_NONCOHERENT) + page = virt_to_page(CAC_ADDR(vaddr)); +#else page = virt_to_page(vaddr); +#endif } get_page(page); vmf->page = page; @@ -3206,6 +3210,11 @@ if (PCM_RUNTIME_CHECK(substream)) return -ENXIO; +#if defined(__mips__) && defined(CONFIG_DMA_NONCOHERENT) + /* all mmap using uncached mode */ + area->vm_page_prot = pgprot_noncached(area->vm_page_prot); + area->vm_flags |= (VM_RESERVED | VM_IO); +#endif offset = area->vm_pgoff << PAGE_SHIFT; switch (offset) { case SNDRV_PCM_MMAP_OFFSET_STATUS: diff -Nur linux-2.6.30.5.orig/sound/core/sgbuf.c linux-2.6.30.5/sound/core/sgbuf.c --- linux-2.6.30.5.orig/sound/core/sgbuf.c 2009-08-16 23:19:38.000000000 +0200 +++ linux-2.6.30.5/sound/core/sgbuf.c 2009-08-23 19:01:04.000000000 +0200 @@ -114,7 +114,11 @@ if (!i) table->addr |= chunk; /* mark head */ table++; +#if defined(__mips__) && defined(CONFIG_DMA_NONCOHERENT) + *pgtable++ = virt_to_page(CAC_ADDR(tmpb.area)); +#else *pgtable++ = virt_to_page(tmpb.area); +#endif tmpb.area += PAGE_SIZE; tmpb.addr += PAGE_SIZE; } @@ -125,7 +129,12 @@ } sgbuf->size = size; +#if defined(__mips__) && defined(CONFIG_DMA_NONCOHERENT) + dmab->area = vmap(sgbuf->page_table, sgbuf->pages, \ + VM_MAP | VM_IO, pgprot_noncached(PAGE_KERNEL)); +#else dmab->area = vmap(sgbuf->page_table, sgbuf->pages, VM_MAP, PAGE_KERNEL); +#endif if (! dmab->area) goto _failed; if (res_size) diff -Nur linux-2.6.30.5.orig/sound/pci/Kconfig linux-2.6.30.5/sound/pci/Kconfig --- linux-2.6.30.5.orig/sound/pci/Kconfig 2009-08-16 23:19:38.000000000 +0200 +++ linux-2.6.30.5/sound/pci/Kconfig 2009-08-23 19:01:04.000000000 +0200 @@ -259,7 +259,6 @@ config SND_CS5535AUDIO tristate "CS5535/CS5536 Audio" - depends on X86 && !X86_64 select SND_PCM select SND_AC97_CODEC help